diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 16004b425b..7ab7867f81 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -578,6 +578,7 @@ Properties on Source Files /prop_sf/GENERATED /prop_sf/HEADER_FILE_ONLY /prop_sf/INCLUDE_DIRECTORIES + /prop_sf/INSTALL_OBJECT_NAME /prop_sf/KEEP_EXTENSION /prop_sf/LABELS /prop_sf/LANGUAGE diff --git a/Help/prop_sf/INSTALL_OBJECT_NAME.rst b/Help/prop_sf/INSTALL_OBJECT_NAME.rst new file mode 100644 index 0000000000..d99ebb49b8 --- /dev/null +++ b/Help/prop_sf/INSTALL_OBJECT_NAME.rst @@ -0,0 +1,25 @@ +INSTALL_OBJECT_NAME +------------------- + +.. versionadded:: 4.2 + +Set the installed object name (without the object extension) of the source +file. An empty string value disables custom object naming. The value must be a +relative path, and may not include special directory components (e.g., +``..``). + +Note that the object name may not be used as-is in +:prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` strategies, but instead changed as +the strategy requires to fulfill its goals. + +This property supports +:manual:`generator expressions `. + +.. note:: + No collision resistance within a target is performed by CMake. When using + this property, collisions must be avoided in the project code. CMake has a + number of source files it generates that also create object files that may + collide with a given custom name. These include: + * Generated PCH source files (``cmake_pch``) + * Generated Unity compilation files (``unity_``) + * Qt autogen sources (``moc_compilations.cpp``) diff --git a/Help/prop_sf/OBJECT_NAME.rst b/Help/prop_sf/OBJECT_NAME.rst index d3c09599c4..35ae985ac5 100644 --- a/Help/prop_sf/OBJECT_NAME.rst +++ b/Help/prop_sf/OBJECT_NAME.rst @@ -12,6 +12,9 @@ Note that the object name may not be used as-is in :prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` strategies, but instead changed as the strategy requires to fulfill its goals. +When installing objects, the :prop_sf:`INSTALL_OBJECT_NAME` property takes +precedence. + This property supports :manual:`generator expressions `, but does not allow for context-sensitive (i.e., configuration-dependent) expressions. diff --git a/Help/prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION.rst b/Help/prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION.rst index 1e9edfaa04..9f55496d6f 100644 --- a/Help/prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION.rst +++ b/Help/prop_tgt/INSTALL_OBJECT_ONLY_USE_DESTINATION.rst @@ -11,7 +11,9 @@ When installing object files, CMake automatically adds conflicts. Use this property to suppress these components. Note that when using a single install prefix for multiple configurations (whether via multi-config generators or separate build trees), the destination must use -``$`` to avoid conflicts. +``$`` to avoid conflicts. Alternatively, the +:prop_sf:`INSTALL_OBJECT_NAME` may be used to avoid configuration-based +conflicts. This property is initialized by the value of :variable:`CMAKE_INSTALL_OBJECT_ONLY_USE_DESTINATION` when the target is diff --git a/Help/release/dev/object-name-properties.rst b/Help/release/dev/object-name-properties.rst index fce7114290..8aaa169d8c 100644 --- a/Help/release/dev/object-name-properties.rst +++ b/Help/release/dev/object-name-properties.rst @@ -3,3 +3,6 @@ object-name-properties * The :prop_sf:`OBJECT_NAME` source file property may be used to control object names of source files. + +* The :prop_sf:`INSTALL_OBJECT_NAME` source file property may be used to + control names of installed object files. diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index 5e0d81d317..4a7d78b21e 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx @@ -129,5 +129,7 @@ void cmLocalCommonGenerator::ComputeObjectFilenames( force = false; si.second.LongLoc.Update(this->GetObjectFileNameWithoutTarget( *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force)); + this->FillCustomInstallObjectLocations(*sf, config, custom_ext, + si.second.InstallLongLoc); } } diff --git a/Source/cmLocalFastbuildGenerator.cxx b/Source/cmLocalFastbuildGenerator.cxx index 46ad852a08..fc4916051b 100644 --- a/Source/cmLocalFastbuildGenerator.cxx +++ b/Source/cmLocalFastbuildGenerator.cxx @@ -66,6 +66,8 @@ void cmLocalFastbuildGenerator::ComputeObjectFilenames( cmSourceFile const* sf = si.first; si.second.LongLoc = this->GetObjectFileNameWithoutTarget(*sf, gt->ObjectDirectory); + this->FillCustomInstallObjectLocations(*sf, config, nullptr, + si.second.InstallLongLoc); } } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 641de76781..ec9cd1a8ca 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -45,6 +45,7 @@ #include "cmList.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmObjectLocation.h" #include "cmRange.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" @@ -4326,6 +4327,105 @@ std::string cmLocalGenerator::GetCustomObjectFileName( return std::string{}; } +std::string cmLocalGenerator::GetCustomInstallObjectFileName( + cmSourceFile const& source, std::string const& config, + char const* custom_ext) const +{ + if (auto objName = source.GetProperty("INSTALL_OBJECT_NAME")) { + cmGeneratorExpression ge(*this->GetCMakeInstance()); + auto cge = ge.Parse(objName); + static std::string const INVALID_GENEX = + "_cmake_invalid_object_name_genex"; + static std::string const INVALID_VALUE = + "_cmake_invalid_object_name_value"; + + if (!cge) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("The \"INSTALL_OBJECT_NAME\" property for\n ", + source.GetFullPath(), + "\nis not a valid generator expression (", objName, ").")); + return INVALID_GENEX; + } + if (cge->GetHadHeadSensitiveCondition()) { + // Not reachable; all target-sensitive genexes actually fail to parse. + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("The \"INSTALL_OBJECT_NAME\" property for\n ", + source.GetFullPath(), + "\ncontains a condition that queries the consuming target " + "which is not supported (", + objName, ").")); + return INVALID_GENEX; + } + if (cge->GetHadLinkLanguageSensitiveCondition()) { + // Not reachable; all target-sensitive genexes actually fail to parse. + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("The \"INSTALL_OBJECT_NAME\" property for\n ", + source.GetFullPath(), + "\ncontains a condition that queries the link language " + "which is not supported (", + objName, ").")); + return INVALID_GENEX; + } + + auto objNameValue = cge->Evaluate(this, config); + + // Skip if it evaluates to empty. + if (!objNameValue.empty()) { + cmCMakePath objNamePath = objNameValue; + // Verify that it is a relative path. + if (objNamePath.IsAbsolute()) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat( + "The \"INSTALL_OBJECT_NAME\" property for\n ", + source.GetFullPath(), + "\nresolves to an absolute path which is not supported:\n ", + objNameValue)); + return INVALID_VALUE; + } + auto isInvalidComponent = [](cmCMakePath const& component) -> bool { + return component == ".."_s; + }; + // Verify that it contains no `..` components. + if (std::any_of(objNamePath.begin(), objNamePath.end(), + isInvalidComponent)) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("The \"INSTALL_OBJECT_NAME\" property for\n ", + source.GetFullPath(), "\ncontains an invalid component (", + objNameValue, ").")); + return INVALID_VALUE; + } + + if (custom_ext) { + objNameValue += custom_ext; + } else { + objNameValue += + this->GetGlobalGenerator()->GetLanguageOutputExtension(source); + } + + return objNameValue; + } + } + + return std::string{}; +} + +void cmLocalGenerator::FillCustomInstallObjectLocations( + cmSourceFile const& source, std::string const& config, + char const* custom_ext, + std::map& mapping) const +{ + auto installLoc = + this->GetCustomInstallObjectFileName(source, config, custom_ext); + if (!installLoc.empty()) { + mapping[config] = installLoc; + } +} + std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( cmSourceFile const& source, std::string const& dir_max, bool* hasSourceExtension, char const* customOutputExtension, diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 5c6ef83b20..55491ddeb9 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -37,6 +37,7 @@ class cmImplicitDependsList; class cmLinkLineComputer; class cmLinkLineDeviceComputer; class cmMakefile; +struct cmObjectLocation; struct cmObjectLocations; class cmRulePlaceholderExpander; class cmSourceFile; @@ -453,6 +454,13 @@ public: virtual std::string ComputeShortTargetDirectory( cmGeneratorTarget const* gt) const; std::string GetCustomObjectFileName(cmSourceFile const& source) const; + std::string GetCustomInstallObjectFileName(cmSourceFile const& source, + std::string const& config, + char const* custom_ext) const; + void FillCustomInstallObjectLocations( + cmSourceFile const& source, std::string const& config, + char const* custom_ext, + std::map& mapping) const; /** * Generate a macOS application bundle Info.plist file. diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx index 4f5f828a92..0833e17af1 100644 --- a/Source/cmLocalGhsMultiGenerator.cxx +++ b/Source/cmLocalGhsMultiGenerator.cxx @@ -100,5 +100,7 @@ void cmLocalGhsMultiGenerator::ComputeObjectFilenames( } si.second.ShortLoc.emplace(shortObjectName); si.second.LongLoc.Update(longObjectName); + this->FillCustomInstallObjectLocations(*sf, config, nullptr, + si.second.InstallLongLoc); } } diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 763d7210aa..c45a957976 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx @@ -104,6 +104,8 @@ void cmLocalVisualStudioGenerator::ComputeObjectFilenames( } si.second.ShortLoc.emplace(shortObjectName); si.second.LongLoc.Update(longObjectName); + this->FillCustomInstallObjectLocations(*sf, config, custom_ext, + si.second.InstallLongLoc); } } diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index 4f026a6f56..52a602e48c 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx @@ -142,6 +142,7 @@ void cmLocalXCodeGenerator::ComputeObjectFilenames( } si.second.ShortLoc.emplace(shortObjectName); si.second.LongLoc.Update(longObjectName); + this->FillCustomInstallObjectLocations(*sf, config, ".o", si.second.InstallLongLoc); } } diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 92e9d5b3be..cb2a6717fb 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -570,6 +570,7 @@ if(XCODE_VERSION) set(ObjectLibrary_ARGS -DXCODE_VERSION=${XCODE_VERSION}) endif() add_RunCMake_test(ObjectLibrary) +add_RunCMake_test(INSTALL_OBJECT_NAME) add_RunCMake_test(OBJECT_NAME) add_RunCMake_test(ParseImplicitIncludeInfo) add_RunCMake_test(ParseImplicitLinkInfo) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/CMakeLists.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/CMakeLists.txt new file mode 100644 index 0000000000..c89e9088dc --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(${RunCMake_TEST} C) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-DisableOnEmpty.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-DisableOnEmpty.cmake new file mode 100644 index 0000000000..57f13bb621 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-DisableOnEmpty.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-GeneratorExpression.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-GeneratorExpression.cmake new file mode 100644 index 0000000000..57f13bb621 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-GeneratorExpression.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-GeneratorExpressionContextSensitive.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-GeneratorExpressionContextSensitive.cmake new file mode 100644 index 0000000000..57f13bb621 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-GeneratorExpressionContextSensitive.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ObjectLibrary.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ObjectLibrary.cmake new file mode 100644 index 0000000000..57f13bb621 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ObjectLibrary.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ShortInstallStrategy.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ShortInstallStrategy.cmake new file mode 100644 index 0000000000..57f13bb621 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ShortInstallStrategy.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ShortStrategy.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ShortStrategy.cmake new file mode 100644 index 0000000000..57f13bb621 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume-ShortStrategy.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume.cmake new file mode 100644 index 0000000000..a8de7786c5 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Consume.cmake @@ -0,0 +1,7 @@ +find_package(ION CONFIG REQUIRED) + +add_executable(main main.c) +target_link_libraries(main PRIVATE ION::objlib) + +enable_testing() +add_test(NAME run COMMAND main) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/DisableOnEmpty-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/DisableOnEmpty-install-check.cmake new file mode 100644 index 0000000000..b9c9a4214b --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/DisableOnEmpty-install-check.cmake @@ -0,0 +1,5 @@ +set(ext_suffix ".c") +if (RunCMake_GENERATOR MATCHES "(Visual Studio|Xcode)") + set(ext_suffix "") +endif () +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/lib${ext_suffix}${CMAKE_C_OUTPUT_EXTENSION}") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/DisableOnEmpty.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/DisableOnEmpty.cmake new file mode 100644 index 0000000000..c1e0707210 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/DisableOnEmpty.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "$<$:objlib_lib.c>") +install(TARGETS objlib EXPORT exp OBJECTS DESTINATION "lib/objlib") +install(EXPORT exp DESTINATION lib/cmake/ION FILE ion-config.cmake NAMESPACE ION::) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpression-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpression-install-check.cmake new file mode 100644 index 0000000000..b6ec47661a --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpression-install-check.cmake @@ -0,0 +1 @@ +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/1/objlib_lib.c${CMAKE_C_OUTPUT_EXTENSION}") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpression.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpression.cmake new file mode 100644 index 0000000000..f58a64e356 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpression.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "$/objlib_lib.c") +install(TARGETS objlib EXPORT exp OBJECTS DESTINATION "lib/objlib") +install(EXPORT exp DESTINATION lib/cmake/ION FILE ion-config.cmake NAMESPACE ION::) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpressionContextSensitive-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpressionContextSensitive-install-check.cmake new file mode 100644 index 0000000000..d2f4b99fa4 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpressionContextSensitive-install-check.cmake @@ -0,0 +1 @@ +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/objlib_lib_debug.c${CMAKE_C_OUTPUT_EXTENSION}") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpressionContextSensitive.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpressionContextSensitive.cmake new file mode 100644 index 0000000000..89451374c1 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/GeneratorExpressionContextSensitive.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "objlib_lib_$>.c") +install(TARGETS objlib EXPORT exp OBJECTS DESTINATION "lib/objlib") +install(EXPORT exp DESTINATION lib/cmake/ION FILE ion-config.cmake NAMESPACE ION::) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/Inspect.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/Inspect.cmake new file mode 100644 index 0000000000..ec74ed8e36 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/Inspect.cmake @@ -0,0 +1,10 @@ +enable_language(C) + +set(info "") + +# Forward information about the C++ compile features. +string(APPEND info "\ +set(CMAKE_C_OUTPUT_EXTENSION \"${CMAKE_C_OUTPUT_EXTENSION}\") +") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression-result.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression-stderr.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression-stderr.txt new file mode 100644 index 0000000000..d769100a22 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression-stderr.txt @@ -0,0 +1,9 @@ +CMake Error: + Error evaluating generator expression: + + \$ + + Expression did not evaluate to a known generator expression + + +CMake Generate step failed. Build files cannot be regenerated correctly. diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression.cmake new file mode 100644 index 0000000000..159ab299f6 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/InvalidGeneratorExpression.cmake @@ -0,0 +1,2 @@ +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "$") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute-result.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute-stderr.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute-stderr.txt new file mode 100644 index 0000000000..8811297b08 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute-stderr.txt @@ -0,0 +1,11 @@ +CMake Error in CMakeLists.txt: + The "INSTALL_OBJECT_NAME" property for + + .*/Tests/RunCMake/INSTALL_OBJECT_NAME/lib.c + + resolves to an absolute path which is not supported: + + .*/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute-build/lib.c + + +CMake Generate step failed. Build files cannot be regenerated correctly. diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute.cmake new file mode 100644 index 0000000000..44eeb3d0aa --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoAbsolute.cmake @@ -0,0 +1,2 @@ +add_library(static STATIC lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "${CMAKE_BINARY_DIR}/lib.c") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot-result.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot-stderr.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot-stderr.txt new file mode 100644 index 0000000000..e76315b60a --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot-stderr.txt @@ -0,0 +1,9 @@ +CMake Error in CMakeLists.txt: + The "INSTALL_OBJECT_NAME" property for + + .*/Tests/RunCMake/INSTALL_OBJECT_NAME/lib.c + + contains an invalid component \(subdir/\.\./sibling/lib.c\). + + +CMake Generate step failed. Build files cannot be regenerated correctly. diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot.cmake new file mode 100644 index 0000000000..1c98222d34 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/NoDotDot.cmake @@ -0,0 +1,2 @@ +add_library(static STATIC lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "subdir/../sibling/lib.c") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/ObjectLibrary-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/ObjectLibrary-install-check.cmake new file mode 100644 index 0000000000..792efa1858 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/ObjectLibrary-install-check.cmake @@ -0,0 +1 @@ +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/objlib_lib.c${CMAKE_C_OUTPUT_EXTENSION}") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/ObjectLibrary.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/ObjectLibrary.cmake new file mode 100644 index 0000000000..69bcf132ef --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/ObjectLibrary.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY FULL CACHE STRING "" FORCE) + +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "objlib_lib.c") +install(TARGETS objlib EXPORT exp OBJECTS DESTINATION "lib/objlib") +install(EXPORT exp DESTINATION lib/cmake/ION FILE ion-config.cmake NAMESPACE ION::) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/RunCMakeTest.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/RunCMakeTest.cmake new file mode 100644 index 0000000000..9e223df2c5 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/RunCMakeTest.cmake @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 3.16) + +include(RunCMake) + +# This test does installation of `OBJECT` libraries which does not work with +# multi-arch compilation under Xcode. +if (RunCMake_GENERATOR STREQUAL "Xcode" AND "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]") + return () +endif () + +function(run_install_test case) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE:STRING=Debug "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/fake_install") + run_cmake(${case}) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug) + set(prefix "${RunCMake_TEST_BINARY_DIR}/real_install") + run_cmake_command(${case}-install ${CMAKE_COMMAND} --install . --config Debug --prefix "${prefix}") + + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Consume-${case}-build) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE:STRING=Debug "-DCMAKE_PREFIX_PATH:PATH=${prefix}") + run_cmake(Consume-${case} "-DCMAKE_PREFIX_PATH=${prefix}") + run_cmake_command(Consume-${case}-build ${CMAKE_COMMAND} --build . --config Debug) + run_cmake_command(Consume-${case}-test ${CMAKE_CTEST_COMMAND} -C Debug) +endfunction() + +function (check_installed_object path) + if (NOT EXISTS "${path}") + list(APPEND RunCMake_TEST_FAILED + "Could not find installed object at '${path}'") + endif () + set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE) +endfunction () + +run_cmake(Inspect) +include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake") + +run_cmake(NoAbsolute) +run_cmake(NoDotDot) +run_cmake(InvalidGeneratorExpression) +run_cmake(UnsupportedGeneratorExpressionHeadTarget) +run_cmake(UnsupportedGeneratorExpressionLinkLanguage) + +run_install_test(ObjectLibrary) +run_install_test(DisableOnEmpty) +if (RunCMake_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)") + run_install_test(ShortInstallStrategy) +endif () +run_install_test(GeneratorExpression) +run_install_test(GeneratorExpressionContextSensitive) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortInstallStrategy-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortInstallStrategy-install-check.cmake new file mode 100644 index 0000000000..ce06a88a8c --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortInstallStrategy-install-check.cmake @@ -0,0 +1 @@ +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/d33a1361${CMAKE_C_OUTPUT_EXTENSION}") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortInstallStrategy.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortInstallStrategy.cmake new file mode 100644 index 0000000000..878ab7f7f0 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortInstallStrategy.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INSTALL_OBJECT_NAME_STRATEGY SHORT) + +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "objlib_lib.c") +install(TARGETS objlib EXPORT exp OBJECTS DESTINATION "lib/objlib") +install(EXPORT exp DESTINATION lib/cmake/ION FILE ion-config.cmake NAMESPACE ION::) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortStrategy-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortStrategy-install-check.cmake new file mode 100644 index 0000000000..792efa1858 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortStrategy-install-check.cmake @@ -0,0 +1 @@ +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/objlib_lib.c${CMAKE_C_OUTPUT_EXTENSION}") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortStrategy.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortStrategy.cmake new file mode 100644 index 0000000000..02d274014b --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/ShortStrategy.cmake @@ -0,0 +1,6 @@ +set(CMAKE_INTERMEDIATE_DIR_STRATEGY SHORT CACHE STRING "" FORCE) + +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "objlib_lib.c") +install(TARGETS objlib EXPORT exp OBJECTS DESTINATION "lib/objlib") +install(EXPORT exp DESTINATION lib/cmake/ION FILE ion-config.cmake NAMESPACE ION::) diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget-result.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget-stderr.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget-stderr.txt new file mode 100644 index 0000000000..2ea9efddda --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget-stderr.txt @@ -0,0 +1,12 @@ +CMake Error: + Error evaluating generator expression: + + \$ + + \$ may only be used with binary targets. It may not + be used with add_custom_command or add_custom_target. Specify the target + to read a property from using the \$ signature + instead. + + +CMake Generate step failed. Build files cannot be regenerated correctly. diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget.cmake new file mode 100644 index 0000000000..92fdaa44a0 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionHeadTarget.cmake @@ -0,0 +1,2 @@ +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "$/objlib_lib.c") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage-result.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage-stderr.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage-stderr.txt new file mode 100644 index 0000000000..73afc33771 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage-stderr.txt @@ -0,0 +1,10 @@ +CMake Error: + Error evaluating generator expression: + + \$ + + \$ may only be used with binary targets to specify link + libraries, link directories, link options and link depends. + + +CMake Generate step failed. Build files cannot be regenerated correctly. diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage.cmake new file mode 100644 index 0000000000..bbdeb38d90 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/UnsupportedGeneratorExpressionLinkLanguage.cmake @@ -0,0 +1,2 @@ +add_library(objlib OBJECT lib.c) +set_property(SOURCE lib.c PROPERTY INSTALL_OBJECT_NAME "$/objlib_lib.c") diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/lib.c b/Tests/RunCMake/INSTALL_OBJECT_NAME/lib.c new file mode 100644 index 0000000000..a482372785 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/lib.c @@ -0,0 +1,4 @@ +int f(int a) +{ + return a; +} diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME/main.c b/Tests/RunCMake/INSTALL_OBJECT_NAME/main.c new file mode 100644 index 0000000000..934bcbc278 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME/main.c @@ -0,0 +1,6 @@ +int f(int a); + +int main(void) +{ + return f(0); +}