static library: add property STATIC_LIBRARY_OPTIONS

issue: #18251
This commit is contained in:
Marc Chevrier
2018-08-15 15:20:18 +02:00
parent 349f8bfb25
commit 974de0e199
25 changed files with 187 additions and 15 deletions

View File

@@ -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

View File

@@ -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::

View File

@@ -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`.

View File

@@ -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`

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -0,0 +1,4 @@
STATIC_LIBRARY_OPTIONS
----------------------
* static library targets gained new :prop_tgt:`STATIC_LIBRARY_OPTIONS` property.

View File

@@ -3017,6 +3017,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,

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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";

View File

@@ -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,

View File

@@ -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";
}

View File

@@ -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);
}

View File

@@ -3055,9 +3055,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;

View File

@@ -0,0 +1,7 @@
#if defined(_WIN32)
__declspec(dllexport)
#endif
int flags_lib(void)
{
return 0;
}

View File

@@ -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()

View File

@@ -0,0 +1,4 @@
if (NOT actual_stdout MATCHES "BADFLAG")
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG'.")
endif()

View File

@@ -0,0 +1 @@
.*

View File

@@ -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()

View File

@@ -0,0 +1 @@
.*

View File

@@ -0,0 +1,4 @@
if (actual_stdout MATCHES "BADFLAG")
string (APPEND RunCMake_TEST_FAILED "\nFound unexpected flag 'BADFLAG'.")
endif()

View File

@@ -0,0 +1 @@
.*

View File

@@ -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})