diff options
25 files changed, 187 insertions, 15 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index c9a38fc..8ccd7f6 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -301,6 +301,7 @@ Properties on Targets /prop_tgt/SOVERSION /prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG /prop_tgt/STATIC_LIBRARY_FLAGS + /prop_tgt/STATIC_LIBRARY_OPTIONS /prop_tgt/SUFFIX /prop_tgt/TYPE /prop_tgt/VERSION diff --git a/Help/prop_tgt/LINK_FLAGS.rst b/Help/prop_tgt/LINK_FLAGS.rst index 3a344e6..92cd3c0 100644 --- a/Help/prop_tgt/LINK_FLAGS.rst +++ b/Help/prop_tgt/LINK_FLAGS.rst @@ -3,11 +3,12 @@ LINK_FLAGS Additional flags to use when linking this target if it is a shared library, module library, or an executable. Static libraries need to use -:prop_tgt:`STATIC_LIBRARY_FLAGS`. +:prop_tgt:`STATIC_LIBRARY_OPTIONS` or :prop_tgt:`STATIC_LIBRARY_FLAGS` +properties. -The LINK_FLAGS property, managed as a string, can be used to add extra flags -to the link step of a target. :prop_tgt:`LINK_FLAGS_<CONFIG>` will add to the -configuration ``<CONFIG>``, for example, ``DEBUG``, ``RELEASE``, +The ``LINK_FLAGS`` property, managed as a string, can be used to add extra +flags to the link step of a target. :prop_tgt:`LINK_FLAGS_<CONFIG>` will add +to the configuration ``<CONFIG>``, for example, ``DEBUG``, ``RELEASE``, ``MINSIZEREL``, ``RELWITHDEBINFO``, ... .. note:: diff --git a/Help/prop_tgt/LINK_FLAGS_CONFIG.rst b/Help/prop_tgt/LINK_FLAGS_CONFIG.rst index c30ecf1..e3918ca 100644 --- a/Help/prop_tgt/LINK_FLAGS_CONFIG.rst +++ b/Help/prop_tgt/LINK_FLAGS_CONFIG.rst @@ -1,7 +1,8 @@ LINK_FLAGS_<CONFIG> ------------------- -Per-configuration linker flags for a shared library, module or executable target. +Per-configuration linker flags for a shared library, module or executable +target. This is the configuration-specific version of :prop_tgt:`LINK_FLAGS`. diff --git a/Help/prop_tgt/LINK_OPTIONS.rst b/Help/prop_tgt/LINK_OPTIONS.rst index c5263a2..bd5e937 100644 --- a/Help/prop_tgt/LINK_OPTIONS.rst +++ b/Help/prop_tgt/LINK_OPTIONS.rst @@ -1,7 +1,10 @@ LINK_OPTIONS ------------ -List of options to use when linking this target. +List of options to use for the link step of shared library, module +and executable targets. Targets that are static libraries need to use +the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property. + This property holds a :ref:`;-list <CMake Language Lists>` of options specified so far for its target. Use the :command:`target_link_options` diff --git a/Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst b/Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst index c91b1ae..66e0e8b 100644 --- a/Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst +++ b/Help/prop_tgt/STATIC_LIBRARY_FLAGS.rst @@ -2,11 +2,16 @@ STATIC_LIBRARY_FLAGS -------------------- Archiver (or MSVC librarian) flags for a static library target. -Targets that are shared libraries, modules, or executables can use -the :prop_tgt:`LINK_OPTIONS` or :prop_tgt:`LINK_FLAGS` target property. +Targets that are shared libraries, modules, or executables need to use +the :prop_tgt:`LINK_OPTIONS` or :prop_tgt:`LINK_FLAGS` target properties. -The STATIC_LIBRARY_FLAGS property, managed as a string, can be used to add +The ``STATIC_LIBRARY_FLAGS`` property, managed as a string, can be used to add extra flags to the link step of a static library target. :prop_tgt:`STATIC_LIBRARY_FLAGS_<CONFIG>` will add to the configuration ``<CONFIG>``, for example, ``DEBUG``, ``RELEASE``, ``MINSIZEREL``, ``RELWITHDEBINFO``, ... + +.. note:: + + This property has been superseded by :prop_tgt:`STATIC_LIBRARY_OPTIONS` + property. diff --git a/Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst b/Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst index b867ac4..5b97941 100644 --- a/Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst +++ b/Help/prop_tgt/STATIC_LIBRARY_FLAGS_CONFIG.rst @@ -1,6 +1,12 @@ STATIC_LIBRARY_FLAGS_<CONFIG> ----------------------------- -Per-configuration archiver (or MSVC librarian) flags for a static library target. +Per-configuration archiver (or MSVC librarian) flags for a static library +target. This is the configuration-specific version of :prop_tgt:`STATIC_LIBRARY_FLAGS`. + +.. note:: + + This property has been superseded by :prop_tgt:`STATIC_LIBRARY_OPTIONS` + property. diff --git a/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst new file mode 100644 index 0000000..6e03185 --- /dev/null +++ b/Help/prop_tgt/STATIC_LIBRARY_OPTIONS.rst @@ -0,0 +1,20 @@ +STATIC_LIBRARY_OPTIONS +---------------------- + +Archiver (or MSVC librarian) flags for a static library target. +Targets that are shared libraries, modules, or executables need to use +the :prop_tgt:`LINK_OPTIONS` target property. + +This property holds a :ref:`;-list <CMake Language Lists>` of options +specified so far for its target. Use :command:`set_target_properties` or +:command:`set_property` commands to set its content. + +Contents of ``STATIC_LIBRARY_OPTIONS`` may use "generator expressions" with the +syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual +for available expressions. See the :manual:`cmake-buildsystem(7)` manual +for more on defining buildsystem properties. + +.. note:: + + This property must be used in preference to :prop_tgt:`STATIC_LIBRARY_FLAGS` + property. diff --git a/Help/release/dev/STATIC_LIBRARY_OPTIONS.rst b/Help/release/dev/STATIC_LIBRARY_OPTIONS.rst new file mode 100644 index 0000000..087dc76 --- /dev/null +++ b/Help/release/dev/STATIC_LIBRARY_OPTIONS.rst @@ -0,0 +1,4 @@ +STATIC_LIBRARY_OPTIONS +---------------------- + +* static library targets gained new :prop_tgt:`STATIC_LIBRARY_OPTIONS` property. diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 1548374..0b3a945 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -3018,6 +3018,47 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result, } namespace { +void processStaticLibraryLinkOptions( + cmGeneratorTarget const* tgt, + const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, + std::vector<std::string>& options, + std::unordered_set<std::string>& uniqueOptions, + cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config, + std::string const& language) +{ + processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker, + config, false, "static library link options", + language, OptionsParse::Shell); +} +} + +void cmGeneratorTarget::GetStaticLibraryLinkOptions( + std::vector<std::string>& result, const std::string& config, + const std::string& language) const +{ + std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries; + std::unordered_set<std::string> uniqueOptions; + + cmGeneratorExpressionDAGChecker dagChecker( + this->GetName(), "STATIC_LIBRARY_OPTIONS", nullptr, nullptr); + + if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) { + std::vector<std::string> options; + cmGeneratorExpression ge; + cmSystemTools::ExpandListArgument(linkOptions, options); + for (const auto& option : options) { + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(option); + entries.push_back( + new cmGeneratorTarget::TargetPropertyEntry(std::move(cge))); + } + } + processStaticLibraryLinkOptions(this, entries, result, uniqueOptions, + &dagChecker, config, language); + + cmDeleteAll(entries); +} + +namespace { void processLinkDepends( cmGeneratorTarget const* tgt, const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries, diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 6c1f931..1030d91 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -424,6 +424,9 @@ public: void GetLinkOptions(std::vector<std::string>& result, const std::string& config, const std::string& language) const; + void GetStaticLibraryLinkOptions(std::vector<std::string>& result, + const std::string& config, + const std::string& language) const; void GetLinkDepends(std::vector<std::string>& result, const std::string& config, diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 042ce41..164ffb0 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1844,7 +1844,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, if (gtgt->GetType() == cmStateEnums::OBJECT_LIBRARY || gtgt->GetType() == cmStateEnums::STATIC_LIBRARY) { this->CurrentLocalGenerator->GetStaticLibraryFlags( - extraLinkOptions, cmSystemTools::UpperCase(configName), gtgt); + extraLinkOptions, cmSystemTools::UpperCase(configName), llang, gtgt); } else { const char* targetLinkFlags = gtgt->GetProperty("LINK_FLAGS"); if (targetLinkFlags) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 5e6ce1a..75b7f23 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -979,6 +979,7 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags, std::string const& config, + std::string const& linkLanguage, cmGeneratorTarget* target) { this->AppendFlags( @@ -992,6 +993,11 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags, std::string name = "STATIC_LIBRARY_FLAGS_" + config; this->AppendFlags(flags, target->GetProperty(name)); } + + std::vector<std::string> options; + target->GetStaticLibraryLinkOptions(options, config, linkLanguage); + // STATIC_LIBRARY_OPTIONS are escaped. + this->AppendCompileOptions(flags, options); } void cmLocalGenerator::GetTargetFlags( @@ -1009,7 +1015,7 @@ void cmLocalGenerator::GetTargetFlags( switch (target->GetType()) { case cmStateEnums::STATIC_LIBRARY: - this->GetStaticLibraryFlags(linkFlags, buildType, target); + this->GetStaticLibraryFlags(linkFlags, buildType, linkLanguage, target); break; case cmStateEnums::MODULE_LIBRARY: libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS"; diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 52f0396..a00302c 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -323,6 +323,7 @@ public: /** Fill out the static linker flags for the given target. */ void GetStaticLibraryFlags(std::string& flags, std::string const& config, + std::string const& linkLanguage, cmGeneratorTarget* target); /** Fill out these strings for the given target. Libraries to link, diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index b35b116..93e515b 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1038,7 +1038,9 @@ void cmLocalVisualStudio7Generator::OutputBuildTool( } } std::string libflags; - this->GetStaticLibraryFlags(libflags, configTypeUpper, target); + this->GetStaticLibraryFlags(libflags, configTypeUpper, + target->GetLinkerLanguage(configName), + target); if (!libflags.empty()) { fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n"; } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 571e74b..2c565b8 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -148,7 +148,7 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules() std::string extraFlags; this->LocalGenerator->GetStaticLibraryFlags( - extraFlags, cmSystemTools::UpperCase(this->ConfigName), + extraFlags, cmSystemTools::UpperCase(this->ConfigName), linkLanguage, this->GeneratorTarget); this->WriteLibraryRules(linkRuleVar, extraFlags, false); } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 4e15354..4597bc6 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -3065,9 +3065,14 @@ void cmVisualStudio10TargetGenerator::WriteLibOptions( this->GeneratorTarget->GetType() != cmStateEnums::OBJECT_LIBRARY) { return; } + + const std::string& linkLanguage = + this->GeneratorTarget->GetLinkClosure(config)->LinkerLanguage; + std::string libflags; this->LocalGenerator->GetStaticLibraryFlags( - libflags, cmSystemTools::UpperCase(config), this->GeneratorTarget); + libflags, cmSystemTools::UpperCase(config), linkLanguage, + this->GeneratorTarget); if (!libflags.empty()) { Elem e2(e1, "Lib"); cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator; diff --git a/Tests/RunCMake/LinkStatic/LinkOptionsLib.c b/Tests/RunCMake/LinkStatic/LinkOptionsLib.c new file mode 100644 index 0000000..9bbd24c --- /dev/null +++ b/Tests/RunCMake/LinkStatic/LinkOptionsLib.c @@ -0,0 +1,7 @@ +#if defined(_WIN32) +__declspec(dllexport) +#endif + int flags_lib(void) +{ + return 0; +} diff --git a/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake b/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake index 0d29492..d3a8afb 100644 --- a/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake +++ b/Tests/RunCMake/LinkStatic/RunCMakeTest.cmake @@ -1,3 +1,30 @@ include(RunCMake) run_cmake(LINK_SEARCH_STATIC) + + +macro(run_cmake_target test subtest target) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN}) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_NO_CLEAN) +endmacro() + +if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel") + # Intel compiler does not reject bad flags or objects! + set(RunCMake_TEST_OUTPUT_MERGE TRUE) + if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release) + endif() + + run_cmake(STATIC_LIBRARY_OPTIONS) + + run_cmake_target(STATIC_LIBRARY_OPTIONS basic StaticLinkOptions) + run_cmake_target(STATIC_LIBRARY_OPTIONS genex StaticLinkOptions_genex --config Release) + run_cmake_target(STATIC_LIBRARY_OPTIONS shared SharedLinkOptions) + + unset(RunCMake_TEST_OPTIONS) + unset(RunCMake_TEST_OUTPUT_MERGE) +endif() diff --git a/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-basic-check.cmake b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-basic-check.cmake new file mode 100644 index 0000000..858ce06 --- /dev/null +++ b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-basic-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "BADFLAG") + set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG'.") +endif() diff --git a/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-basic-result.txt b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-basic-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-basic-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-genex-check.cmake b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-genex-check.cmake new file mode 100644 index 0000000..a686de9 --- /dev/null +++ b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-genex-check.cmake @@ -0,0 +1,7 @@ + +if (NOT actual_stdout MATCHES "BADFLAG_RELEASE") + set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_RELEASE'.") +endif() +if (actual_stdout MATCHES "SHELL:") + string (APPEND RunCMake_TEST_FAILED "\nFound unexpected prefix 'SHELL:'.") +endif() diff --git a/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-genex-result.txt b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-genex-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-genex-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-shared-check.cmake b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-shared-check.cmake new file mode 100644 index 0000000..8c1e96e --- /dev/null +++ b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-shared-check.cmake @@ -0,0 +1,4 @@ + +if (actual_stdout MATCHES "BADFLAG") + string (APPEND RunCMake_TEST_FAILED "\nFound unexpected flag 'BADFLAG'.") +endif() diff --git a/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-shared-result.txt b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-shared-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS-shared-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS.cmake b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS.cmake new file mode 100644 index 0000000..587af1d --- /dev/null +++ b/Tests/RunCMake/LinkStatic/STATIC_LIBRARY_OPTIONS.cmake @@ -0,0 +1,21 @@ + +enable_language(C) + +set(obj "${CMAKE_C_OUTPUT_EXTENSION}") +if(BORLAND) + set(pre -) +endif() + +add_library(StaticLinkOptions STATIC LinkOptionsLib.c) +set_property(TARGET StaticLinkOptions PROPERTY STATIC_LIBRARY_OPTIONS ${pre}BADFLAG${obj}) + +# static library with generator expression +add_library(StaticLinkOptions_genex STATIC LinkOptionsLib.c) +set_property(TARGET StaticLinkOptions_genex PROPERTY STATIC_LIBRARY_OPTIONS + $<$<CONFIG:Release>:${pre}BADFLAG_RELEASE${obj}> + "SHELL:" # produces no options + ) + +# shared library do not use property STATIC_LIBRARY_OPTIONS +add_library(SharedLinkOptions SHARED LinkOptionsLib.c) +set_property(TARGET SharedLinkOptions PROPERTY STATIC_LIBRARY_OPTIONS ${pre}BADFLAG${obj}) |