From e218db1a903972eade0b0a58d1cd3a054942433a Mon Sep 17 00:00:00 2001 From: Rob Raguet-Schofield Date: Fri, 20 Oct 2023 14:25:59 -0600 Subject: Unity: Enable UNITY_BUILD for OBJC and OBJCXX files --- Help/prop_tgt/UNITY_BUILD.rst | 22 ++++++++++++++---- Help/release/dev/unity-build-objc.rst | 5 ++++ Source/cmLocalGenerator.cxx | 15 +++++++++--- Tests/RunCMake/CMakeLists.txt | 2 +- Tests/RunCMake/UnityBuild/RunCMakeTest.cmake | 7 ++++++ .../unitybuild_c_and_cxx_and_objc_and_objcxx.cmake | 25 ++++++++++++++++++++ Tests/RunCMake/UnityBuild/unitybuild_objc.cmake | 12 ++++++++++ .../UnityBuild/unitybuild_objc_group.cmake | 27 ++++++++++++++++++++++ Tests/RunCMake/UnityBuild/unitybuild_objcxx.cmake | 12 ++++++++++ .../UnityBuild/unitybuild_objcxx_group.cmake | 27 ++++++++++++++++++++++ 10 files changed, 145 insertions(+), 9 deletions(-) create mode 100644 Help/release/dev/unity-build-objc.rst create mode 100644 Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_and_objc_and_objcxx.cmake create mode 100644 Tests/RunCMake/UnityBuild/unitybuild_objc.cmake create mode 100644 Tests/RunCMake/UnityBuild/unitybuild_objc_group.cmake create mode 100644 Tests/RunCMake/UnityBuild/unitybuild_objcxx.cmake create mode 100644 Tests/RunCMake/UnityBuild/unitybuild_objcxx_group.cmake diff --git a/Help/prop_tgt/UNITY_BUILD.rst b/Help/prop_tgt/UNITY_BUILD.rst index f827a20..52f4714 100644 --- a/Help/prop_tgt/UNITY_BUILD.rst +++ b/Help/prop_tgt/UNITY_BUILD.rst @@ -30,11 +30,23 @@ values: If no explicit :prop_tgt:`UNITY_BUILD_MODE` has been specified, CMake will default to ``BATCH``. -Unity builds are not currently supported for all languages. CMake version -|release| supports combining ``C`` and ``CXX`` source files. For targets that -mix source files from more than one language, CMake will separate the languages -such that each generated unity source file only contains sources for a single -language. +Unity builds are supported for the following languages: + +``C`` + .. versionadded:: 3.16 + +``CXX`` + .. versionadded:: 3.16 + +``OBJC`` + .. versionadded:: 3.29 + +``OBJCXX`` + .. versionadded:: 3.29 + +For targets that mix source files from more than one language, CMake +separates the languages such that each generated unity source file only +contains sources for a single language. This property is initialized by the value of the :variable:`CMAKE_UNITY_BUILD` variable when a target is created. diff --git a/Help/release/dev/unity-build-objc.rst b/Help/release/dev/unity-build-objc.rst new file mode 100644 index 0000000..ce6460b --- /dev/null +++ b/Help/release/dev/unity-build-objc.rst @@ -0,0 +1,5 @@ +unity-build-objc +---------------- + +* The :prop_tgt:`UNITY_BUILD` target property now supports the + Objective C (``OBJC``) and Objective C++ (``OBJCXX``) languages. diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 76e36ab..be18c29 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -3063,8 +3063,17 @@ cmLocalGenerator::AddUnityFilesModeAuto( chunk = std::min(itemsLeft, batchSize); - std::string filename = cmStrCat(filename_base, "unity_", batch, - (lang == "C") ? "_c.c" : "_cxx.cxx"); + std::string extension; + if (lang == "C") { + extension = "_c.c"; + } else if (lang == "CXX") { + extension = "_cxx.cxx"; + } else if (lang == "OBJC") { + extension = "_m.m"; + } else if (lang == "OBJCXX") { + extension = "_mm.mm"; + } + std::string filename = cmStrCat(filename_base, "unity_", batch, extension); auto const begin = filtered_sources.begin() + batch * batchSize; auto const end = begin + chunk; unity_files.emplace_back(this->WriteUnitySource( @@ -3155,7 +3164,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target) cmValue afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE"); cmValue unityMode = target->GetProperty("UNITY_BUILD_MODE"); - for (std::string lang : { "C", "CXX" }) { + for (std::string lang : { "C", "CXX", "OBJC", "OBJCXX" }) { std::vector filtered_sources; std::copy_if(unitySources.begin(), unitySources.end(), std::back_inserter(filtered_sources), diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 5a23b8b..78d4585 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -1064,7 +1064,7 @@ add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} -DCMAKE_C_SIMULATE_ID=${CMAKE_C_SIMULATE_ID} -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}) -add_RunCMake_test("UnityBuild") +add_RunCMake_test(UnityBuild -DCMake_TEST_OBJC=${CMake_TEST_OBJC}) add_RunCMake_test(CMakePresets -DPython_EXECUTABLE=${Python_EXECUTABLE} -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA} diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake index e3643c0..0ec8c42 100644 --- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake @@ -14,6 +14,13 @@ run_cmake(unitybuild_cxx) run_cmake(unitybuild_cxx_group) run_cmake(unitybuild_c_and_cxx) run_cmake(unitybuild_c_and_cxx_group) +if(CMake_TEST_OBJC) + run_cmake(unitybuild_objc) + run_cmake(unitybuild_objc_group) + run_cmake(unitybuild_objcxx) + run_cmake(unitybuild_objcxx_group) + run_cmake(unitybuild_c_and_cxx_and_objc_and_objcxx) +endif() run_cmake(unitybuild_batchsize) run_cmake(unitybuild_default_batchsize) run_cmake(unitybuild_skip) diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_and_objc_and_objcxx.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_and_objc_and_objcxx.cmake new file mode 100644 index 0000000..096a86b --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_and_objc_and_objcxx.cmake @@ -0,0 +1,25 @@ +project(unitybuild_c_and_cxx_and_objc_and_objcxx C CXX OBJC OBJCXX) + +set(srcs "") +foreach(s RANGE 1 8) + set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c") + file(WRITE "${src_c}" "int s${s}(void) { return 0; }\n") + + set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx") + file(WRITE "${src_cxx}" "int s${s}(void) { return 0; }\n") + + set(src_objc "${CMAKE_CURRENT_BINARY_DIR}/s${s}.m") + file(WRITE "${src_objc}" "int s${s}(void) { return 0; }\n") + + set(src_objcxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.mm") + file(WRITE "${src_objcxx}" "int s${s}(void) { return 0; }\n") + + list(APPEND srcs "${src_c}") + list(APPEND srcs "${src_cxx}") + list(APPEND srcs "${src_objc}") + list(APPEND srcs "${src_objcxx}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON) diff --git a/Tests/RunCMake/UnityBuild/unitybuild_objc.cmake b/Tests/RunCMake/UnityBuild/unitybuild_objc.cmake new file mode 100644 index 0000000..cc88d98 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_objc.cmake @@ -0,0 +1,12 @@ +project(unitybuild_objc OBJC) + +set(srcs "") +foreach(s RANGE 1 8) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.m") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON) diff --git a/Tests/RunCMake/UnityBuild/unitybuild_objc_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_objc_group.cmake new file mode 100644 index 0000000..384c98a --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_objc_group.cmake @@ -0,0 +1,27 @@ +project(unitybuild_objc_group OBJC) + +set(srcs "") +foreach(s RANGE 1 4) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.m") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +foreach(s RANGE 1 2) + set(src "${CMAKE_CURRENT_BINARY_DIR}/odr${s}.m") + file(WRITE "${src}" "namespace odr { int s${s}(void) { return 0; } }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_MODE GROUP + ) + +set_source_files_properties(s1.m s2.m odr1.m + PROPERTIES UNITY_GROUP "a" + ) +set_source_files_properties(s3.m s4.m odr2.m + PROPERTIES UNITY_GROUP "b" + ) diff --git a/Tests/RunCMake/UnityBuild/unitybuild_objcxx.cmake b/Tests/RunCMake/UnityBuild/unitybuild_objcxx.cmake new file mode 100644 index 0000000..fd0f743 --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_objcxx.cmake @@ -0,0 +1,12 @@ +project(unitybuild_objcxx OBJCXX) + +set(srcs "") +foreach(s RANGE 1 8) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.mm") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON) diff --git a/Tests/RunCMake/UnityBuild/unitybuild_objcxx_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_objcxx_group.cmake new file mode 100644 index 0000000..517703e --- /dev/null +++ b/Tests/RunCMake/UnityBuild/unitybuild_objcxx_group.cmake @@ -0,0 +1,27 @@ +project(unitybuild_objcxx_group OBJCXX) + +set(srcs "") +foreach(s RANGE 1 4) + set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.mm") + file(WRITE "${src}" "int s${s}(void) { return 0; }\n") + list(APPEND srcs "${src}") +endforeach() + +foreach(s RANGE 1 2) + set(src "${CMAKE_CURRENT_BINARY_DIR}/odr${s}.mm") + file(WRITE "${src}" "namespace odr { int s${s}(void) { return 0; } }\n") + list(APPEND srcs "${src}") +endforeach() + +add_library(tgt SHARED ${srcs}) + +set_target_properties(tgt PROPERTIES UNITY_BUILD ON + UNITY_BUILD_MODE GROUP + ) + +set_source_files_properties(s1.mm s2.mm odr1.mm + PROPERTIES UNITY_GROUP "a" + ) +set_source_files_properties(s3.mm s4.mm odr2.mm + PROPERTIES UNITY_GROUP "b" + ) -- cgit v0.12