mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-26 04:09:35 +03:00
LINK_OPTIONS: Add new family of properties
This family enable to manage link flags Three new properties: * directory property: LINK_OPTIONS * target properties: LINK_OPTIONS and INTERFACE_LINK_OPTIONS Two new commands * add_link_options(): to populate directory property * target_link_options(): to populate target properties Fixes: #16543
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
The final set of compile options used for a target is constructed by
|
||||
The final set of compile or link options used for a target is constructed by
|
||||
accumulating options from the current target and the usage requirements of
|
||||
it dependencies. The set of options is de-duplicated to avoid repetition.
|
||||
While beneficial for individual options, the de-duplication step can break
|
||||
@@ -22,4 +22,4 @@ 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.
|
||||
|
||||
.. include:: COMPILE_OPTIONS_SHELL.txt
|
||||
.. include:: OPTIONS_SHELL.txt
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
add_link_options
|
||||
----------------
|
||||
|
||||
Adds options to the link of targets.
|
||||
|
||||
::
|
||||
|
||||
add_link_options(<option> ...)
|
||||
|
||||
Adds options to the linker command line for targets in the current
|
||||
directory and below that are added after this command is invoked.
|
||||
See documentation of the :prop_dir:`directory <LINK_OPTIONS>` and
|
||||
:prop_tgt:`target <LINK_OPTIONS>` ``LINK_OPTIONS`` properties.
|
||||
|
||||
This command can be used to add any options, but alternative command
|
||||
exist to add libraries (:command:`target_link_libraries` or
|
||||
:command:`link_libraries`).
|
||||
|
||||
Arguments to ``add_link_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.
|
||||
|
||||
.. include:: OPTIONS_SHELL.txt
|
||||
@@ -39,4 +39,4 @@ 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.
|
||||
|
||||
.. include:: COMPILE_OPTIONS_SHELL.txt
|
||||
.. include:: OPTIONS_SHELL.txt
|
||||
|
||||
@@ -70,7 +70,8 @@ Each ``<item>`` may be:
|
||||
|
||||
Link flags specified here are inserted into the link command in the same
|
||||
place as the link libraries. This might not be correct, depending on
|
||||
the linker. Use the :prop_tgt:`LINK_FLAGS` target property to add link
|
||||
the linker. Use the :prop_tgt:`LINK_OPTIONS` target property or
|
||||
:command:`target_link_options` command to add link
|
||||
flags explicitly. The flags will then be placed at the toolchain-defined
|
||||
flag position in the link command.
|
||||
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
target_link_options
|
||||
-------------------
|
||||
|
||||
Add link options to a target.
|
||||
|
||||
::
|
||||
|
||||
target_link_options(<target> [BEFORE]
|
||||
<INTERFACE|PUBLIC|PRIVATE> [items1...]
|
||||
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
|
||||
|
||||
Specify link options to use when linking a given target. The
|
||||
named ``<target>`` must have been created by a command such as
|
||||
:command:`add_executable` or :command:`add_library` and must not be an
|
||||
:ref:`ALIAS target <Alias Targets>`.
|
||||
|
||||
If ``BEFORE`` is specified, the content will be prepended to the property
|
||||
instead of being appended.
|
||||
|
||||
This command can be used to add any options, but
|
||||
alternative commands exist to add libraries
|
||||
(:command:`target_link_libraries` and :command:`link_libraries`).
|
||||
See documentation of the :prop_dir:`directory <LINK_OPTIONS>` and
|
||||
:prop_tgt:`target <LINK_OPTIONS>` ``LINK_OPTIONS`` properties.
|
||||
|
||||
The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to
|
||||
specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC``
|
||||
items will populate the :prop_tgt:`LINK_OPTIONS` property of
|
||||
``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the
|
||||
:prop_tgt:`INTERFACE_LINK_OPTIONS` property of ``<target>``.
|
||||
(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.)
|
||||
The following arguments specify compile options. Repeated calls for the same
|
||||
``<target>`` append items in the order called.
|
||||
|
||||
Arguments to ``target_link_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.
|
||||
|
||||
.. include:: OPTIONS_SHELL.txt
|
||||
@@ -78,6 +78,7 @@ These commands are available only in CMake projects.
|
||||
/command/add_dependencies
|
||||
/command/add_executable
|
||||
/command/add_library
|
||||
/command/add_link_options
|
||||
/command/add_subdirectory
|
||||
/command/add_test
|
||||
/command/aux_source_directory
|
||||
@@ -111,6 +112,7 @@ These commands are available only in CMake projects.
|
||||
/command/target_compile_options
|
||||
/command/target_include_directories
|
||||
/command/target_link_libraries
|
||||
/command/target_link_options
|
||||
/command/target_sources
|
||||
/command/try_compile
|
||||
/command/try_run
|
||||
|
||||
@@ -77,6 +77,7 @@ Properties on Directories
|
||||
/prop_dir/INTERPROCEDURAL_OPTIMIZATION
|
||||
/prop_dir/LABELS
|
||||
/prop_dir/LINK_DIRECTORIES
|
||||
/prop_dir/LINK_OPTIONS
|
||||
/prop_dir/LISTFILE_STACK
|
||||
/prop_dir/MACROS
|
||||
/prop_dir/PARENT_DIRECTORY
|
||||
@@ -225,6 +226,7 @@ Properties on Targets
|
||||
/prop_tgt/INTERFACE_COMPILE_OPTIONS
|
||||
/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
|
||||
/prop_tgt/INTERFACE_LINK_LIBRARIES
|
||||
/prop_tgt/INTERFACE_LINK_OPTIONS
|
||||
/prop_tgt/INTERFACE_POSITION_INDEPENDENT_CODE
|
||||
/prop_tgt/INTERFACE_SOURCES
|
||||
/prop_tgt/INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
|
||||
@@ -254,6 +256,7 @@ Properties on Targets
|
||||
/prop_tgt/LINK_INTERFACE_MULTIPLICITY_CONFIG
|
||||
/prop_tgt/LINK_INTERFACE_MULTIPLICITY
|
||||
/prop_tgt/LINK_LIBRARIES
|
||||
/prop_tgt/LINK_OPTIONS
|
||||
/prop_tgt/LINK_SEARCH_END_STATIC
|
||||
/prop_tgt/LINK_SEARCH_START_STATIC
|
||||
/prop_tgt/LINK_WHAT_YOU_USE
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
LINK_OPTIONS
|
||||
------------
|
||||
|
||||
List of options to use for the link step.
|
||||
|
||||
This property holds a :ref:`;-list <CMake Language Lists>` of options
|
||||
given so far to the :command:`add_link_options` command.
|
||||
|
||||
This property is used to initialize the :prop_tgt:`LINK_OPTIONS` target
|
||||
property when a target is created, which is used by the generators to set
|
||||
the options for the compiler.
|
||||
|
||||
Contents of ``LINK_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.
|
||||
@@ -0,0 +1,9 @@
|
||||
INTERFACE_LINK_OPTIONS
|
||||
----------------------
|
||||
|
||||
.. |property_name| replace:: link options
|
||||
.. |command_name| replace:: :command:`target_link_options`
|
||||
.. |PROPERTY_INTERFACE_NAME| replace:: ``INTERFACE_LINK_OPTIONS``
|
||||
.. |PROPERTY_LINK| replace:: :prop_tgt:`LINK_OPTIONS`
|
||||
.. |PROPERTY_GENEX| replace:: ``$<TARGET_PROPERTY:foo,INTERFACE_LINK_OPTIONS>``
|
||||
.. include:: INTERFACE_BUILD_PROPERTY.txt
|
||||
@@ -3,7 +3,11 @@ LINK_FLAGS
|
||||
|
||||
Additional flags to use when linking this target.
|
||||
|
||||
The LINK_FLAGS property can be used to add extra flags to the link
|
||||
step of a target. :prop_tgt:`LINK_FLAGS_<CONFIG>` will add to the
|
||||
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::
|
||||
|
||||
This property has been superseded by :prop_tgt:`LINK_OPTIONS` property.
|
||||
|
||||
@@ -4,3 +4,7 @@ LINK_FLAGS_<CONFIG>
|
||||
Per-configuration linker flags for a target.
|
||||
|
||||
This is the configuration-specific version of LINK_FLAGS.
|
||||
|
||||
.. note::
|
||||
|
||||
This property has been superseded by :prop_tgt:`LINK_OPTIONS` property.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
LINK_OPTIONS
|
||||
------------
|
||||
|
||||
List of options to use when linking this target.
|
||||
|
||||
This property holds a :ref:`;-list <CMake Language Lists>` of options
|
||||
specified so far for its target. Use the :command:`target_link_options`
|
||||
command to append more options.
|
||||
|
||||
This property is initialized by the :prop_dir:`LINK_OPTIONS` directory
|
||||
property when a target is created, and is used by the generators to set
|
||||
the options for the compiler.
|
||||
|
||||
Contents of ``LINK_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:`LINK_FLAGS` property.
|
||||
@@ -0,0 +1,11 @@
|
||||
LINK_OPTIONS
|
||||
------------
|
||||
|
||||
* CMake gained new capabilities to manage link step:
|
||||
|
||||
* :prop_dir:`LINK_OPTIONS` directory property
|
||||
* :prop_tgt:`LINK_OPTIONS` and :prop_tgt:`INTERFACE_LINK_OPTIONS` target
|
||||
properties
|
||||
* :command:`add_link_options` command to add link options in the current
|
||||
directory
|
||||
* :command:`target_link_options` command to add link options to targets
|
||||
@@ -379,6 +379,8 @@ set(SRCS
|
||||
cmAddCompileDefinitionsCommand.h
|
||||
cmAddCompileOptionsCommand.cxx
|
||||
cmAddCompileOptionsCommand.h
|
||||
cmAddLinkOptionsCommand.cxx
|
||||
cmAddLinkOptionsCommand.h
|
||||
cmAddCustomCommandCommand.cxx
|
||||
cmAddCustomCommandCommand.h
|
||||
cmAddCustomTargetCommand.cxx
|
||||
@@ -574,6 +576,8 @@ set(SRCS
|
||||
cmTargetCompileOptionsCommand.h
|
||||
cmTargetIncludeDirectoriesCommand.cxx
|
||||
cmTargetIncludeDirectoriesCommand.h
|
||||
cmTargetLinkOptionsCommand.cxx
|
||||
cmTargetLinkOptionsCommand.h
|
||||
cmTargetLinkLibrariesCommand.cxx
|
||||
cmTargetLinkLibrariesCommand.h
|
||||
cmTargetPropCommandBase.cxx
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmAddLinkOptionsCommand.h"
|
||||
|
||||
#include "cmMakefile.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
|
||||
bool cmAddLinkOptionsCommand::InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus&)
|
||||
{
|
||||
if (args.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (std::string const& i : args) {
|
||||
this->Makefile->AddLinkOption(i);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmAddLinkOptionsCommand_h
|
||||
#define cmAddLinkOptionsCommand_h
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmCommand.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
|
||||
class cmAddLinkOptionsCommand : public cmCommand
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
cmCommand* Clone() override { return new cmAddLinkOptionsCommand; }
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -82,6 +82,7 @@
|
||||
|
||||
#if defined(CMAKE_BUILD_WITH_CMAKE)
|
||||
# include "cmAddCompileOptionsCommand.h"
|
||||
# include "cmAddLinkOptionsCommand.h"
|
||||
# include "cmAuxSourceDirectoryCommand.h"
|
||||
# include "cmBuildNameCommand.h"
|
||||
# include "cmCMakeHostSystemInformationCommand.h"
|
||||
@@ -100,6 +101,7 @@
|
||||
# include "cmRemoveDefinitionsCommand.h"
|
||||
# include "cmSourceGroupCommand.h"
|
||||
# include "cmSubdirDependsCommand.h"
|
||||
# include "cmTargetLinkOptionsCommand.h"
|
||||
# include "cmUseMangledMesaCommand.h"
|
||||
# include "cmUtilitySourceCommand.h"
|
||||
# include "cmVariableRequiresCommand.h"
|
||||
@@ -272,7 +274,10 @@ void GetProjectCommands(cmState* state)
|
||||
state->AddBuiltinCommand("include_external_msproject",
|
||||
new cmIncludeExternalMSProjectCommand);
|
||||
state->AddBuiltinCommand("install_programs", new cmInstallProgramsCommand);
|
||||
state->AddBuiltinCommand("add_link_options", new cmAddLinkOptionsCommand);
|
||||
state->AddBuiltinCommand("link_libraries", new cmLinkLibrariesCommand);
|
||||
state->AddBuiltinCommand("target_link_options",
|
||||
new cmTargetLinkOptionsCommand);
|
||||
state->AddBuiltinCommand("load_cache", new cmLoadCacheCommand);
|
||||
state->AddBuiltinCommand("qt_wrap_cpp", new cmQTWrapCPPCommand);
|
||||
state->AddBuiltinCommand("qt_wrap_ui", new cmQTWrapUICommand);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmGeneratorExpression.h"
|
||||
#include "cmGeneratorExpressionDAGChecker.h"
|
||||
#include "cmGeneratorTarget.h"
|
||||
@@ -169,6 +170,11 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
|
||||
end = "\\\n";
|
||||
}
|
||||
os << "\n";
|
||||
} else if (property.first == "INTERFACE_LINK_OPTIONS") {
|
||||
os << "LOCAL_EXPORT_LDFLAGS := ";
|
||||
std::vector<std::string> linkFlagsList;
|
||||
cmSystemTools::ExpandListArgument(property.second, linkFlagsList);
|
||||
os << cmJoin(linkFlagsList, " ") << "\n";
|
||||
} else {
|
||||
os << "# " << property.first << " " << (property.second) << "\n";
|
||||
}
|
||||
|
||||
@@ -95,6 +95,9 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gte,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gte,
|
||||
cmGeneratorExpression::BuildInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", gte,
|
||||
properties);
|
||||
|
||||
|
||||
@@ -103,6 +103,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
|
||||
this->PopulateInterfaceProperty("INTERFACE_COMPILE_FEATURES", gt,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
this->PopulateInterfaceProperty("INTERFACE_LINK_OPTIONS", gt,
|
||||
cmGeneratorExpression::InstallInterface,
|
||||
properties, missingTargets);
|
||||
|
||||
std::string errorMessage;
|
||||
if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
|
||||
|
||||
@@ -25,7 +25,8 @@ struct cmGeneratorExpressionContext;
|
||||
SELECT(F, EvaluatingCompileOptions, COMPILE_OPTIONS) \
|
||||
SELECT(F, EvaluatingAutoUicOptions, AUTOUIC_OPTIONS) \
|
||||
SELECT(F, EvaluatingSources, SOURCES) \
|
||||
SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES)
|
||||
SELECT(F, EvaluatingCompileFeatures, COMPILE_FEATURES) \
|
||||
SELECT(F, EvaluatingLinkOptions, LINK_OPTIONS)
|
||||
|
||||
#define CM_FOR_EACH_TRANSITIVE_PROPERTY(F) \
|
||||
CM_FOR_EACH_TRANSITIVE_PROPERTY_IMPL(F, CM_SELECT_BOTH)
|
||||
|
||||
@@ -102,6 +102,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
|
||||
, DebugCompileOptionsDone(false)
|
||||
, DebugCompileFeaturesDone(false)
|
||||
, DebugCompileDefinitionsDone(false)
|
||||
, DebugLinkOptionsDone(false)
|
||||
, DebugSourcesDone(false)
|
||||
, LinkImplementationLanguageIsContextDependent(true)
|
||||
, UtilityItemsDone(false)
|
||||
@@ -128,6 +129,10 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
|
||||
t->GetCompileDefinitionsBacktraces(),
|
||||
this->CompileDefinitionsEntries);
|
||||
|
||||
CreatePropertyGeneratorExpressions(t->GetLinkOptionsEntries(),
|
||||
t->GetLinkOptionsBacktraces(),
|
||||
this->LinkOptionsEntries);
|
||||
|
||||
CreatePropertyGeneratorExpressions(t->GetSourceEntries(),
|
||||
t->GetSourceBacktraces(),
|
||||
this->SourceEntries, true);
|
||||
@@ -145,6 +150,7 @@ cmGeneratorTarget::~cmGeneratorTarget()
|
||||
cmDeleteAll(this->CompileOptionsEntries);
|
||||
cmDeleteAll(this->CompileFeaturesEntries);
|
||||
cmDeleteAll(this->CompileDefinitionsEntries);
|
||||
cmDeleteAll(this->LinkOptionsEntries);
|
||||
cmDeleteAll(this->SourceEntries);
|
||||
cmDeleteAll(this->LinkInformation);
|
||||
}
|
||||
@@ -2633,7 +2639,7 @@ enum class OptionsParse
|
||||
Shell
|
||||
};
|
||||
|
||||
static void processCompileOptionsInternal(
|
||||
static void processOptionsInternal(
|
||||
cmGeneratorTarget const* tgt,
|
||||
const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
|
||||
std::vector<std::string>& options,
|
||||
@@ -2665,7 +2671,7 @@ static void processCompileOptionsInternal(
|
||||
if (!usedOptions.empty()) {
|
||||
tgt->GetLocalGenerator()->GetCMakeInstance()->IssueMessage(
|
||||
cmake::LOG,
|
||||
std::string("Used compile ") + logName + std::string(" for target ") +
|
||||
std::string("Used ") + logName + std::string(" for target ") +
|
||||
tgt->GetName() + ":\n" + usedOptions,
|
||||
entry->ge->GetBacktrace());
|
||||
}
|
||||
@@ -2680,9 +2686,9 @@ static void processCompileOptions(
|
||||
cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
|
||||
bool debugOptions, std::string const& language)
|
||||
{
|
||||
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
|
||||
dagChecker, config, debugOptions, "options",
|
||||
language, OptionsParse::Shell);
|
||||
processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
|
||||
config, debugOptions, "compile options", language,
|
||||
OptionsParse::Shell);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
|
||||
@@ -2734,9 +2740,9 @@ static void processCompileFeatures(
|
||||
cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
|
||||
bool debugOptions)
|
||||
{
|
||||
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
|
||||
dagChecker, config, debugOptions, "features",
|
||||
std::string(), OptionsParse::None);
|
||||
processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
|
||||
config, debugOptions, "compile features",
|
||||
std::string(), OptionsParse::None);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
|
||||
@@ -2784,9 +2790,9 @@ static void processCompileDefinitions(
|
||||
cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
|
||||
bool debugOptions, std::string const& language)
|
||||
{
|
||||
processCompileOptionsInternal(tgt, entries, options, uniqueOptions,
|
||||
dagChecker, config, debugOptions,
|
||||
"definitions", language, OptionsParse::None);
|
||||
processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
|
||||
config, debugOptions, "compile definitions", language,
|
||||
OptionsParse::None);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetCompileDefinitions(
|
||||
@@ -2855,6 +2861,59 @@ void cmGeneratorTarget::GetCompileDefinitions(
|
||||
cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
|
||||
}
|
||||
|
||||
static void processLinkOptions(
|
||||
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,
|
||||
bool debugOptions, std::string const& language)
|
||||
{
|
||||
processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
|
||||
config, debugOptions, "link options", language,
|
||||
OptionsParse::Shell);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
|
||||
const std::string& config,
|
||||
const std::string& language) const
|
||||
{
|
||||
std::unordered_set<std::string> uniqueOptions;
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(this->GetName(), "LINK_OPTIONS",
|
||||
nullptr, nullptr);
|
||||
|
||||
std::vector<std::string> debugProperties;
|
||||
const char* debugProp =
|
||||
this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES");
|
||||
if (debugProp) {
|
||||
cmSystemTools::ExpandListArgument(debugProp, debugProperties);
|
||||
}
|
||||
|
||||
bool debugOptions = !this->DebugLinkOptionsDone &&
|
||||
std::find(debugProperties.begin(), debugProperties.end(),
|
||||
"LINK_OPTIONS") != debugProperties.end();
|
||||
|
||||
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
|
||||
this->DebugLinkOptionsDone = true;
|
||||
}
|
||||
|
||||
processLinkOptions(this, this->LinkOptionsEntries, result, uniqueOptions,
|
||||
&dagChecker, config, debugOptions, language);
|
||||
|
||||
std::vector<cmGeneratorTarget::TargetPropertyEntry*>
|
||||
linkInterfaceLinkOptionsEntries;
|
||||
|
||||
AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS",
|
||||
linkInterfaceLinkOptionsEntries);
|
||||
|
||||
processLinkOptions(this, linkInterfaceLinkOptionsEntries, result,
|
||||
uniqueOptions, &dagChecker, config, debugOptions,
|
||||
language);
|
||||
|
||||
cmDeleteAll(linkInterfaceLinkOptionsEntries);
|
||||
}
|
||||
|
||||
void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const
|
||||
{
|
||||
if (this->IsImported()) {
|
||||
|
||||
@@ -418,6 +418,10 @@ public:
|
||||
const std::string& config,
|
||||
const std::string& language) const;
|
||||
|
||||
void GetLinkOptions(std::vector<std::string>& result,
|
||||
const std::string& config,
|
||||
const std::string& language) const;
|
||||
|
||||
bool IsSystemIncludeDirectory(const std::string& dir,
|
||||
const std::string& config,
|
||||
const std::string& language) const;
|
||||
@@ -803,6 +807,7 @@ private:
|
||||
std::vector<TargetPropertyEntry*> CompileOptionsEntries;
|
||||
std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
|
||||
std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
|
||||
std::vector<TargetPropertyEntry*> LinkOptionsEntries;
|
||||
std::vector<TargetPropertyEntry*> SourceEntries;
|
||||
mutable std::set<std::string> LinkImplicitNullProperties;
|
||||
|
||||
@@ -851,6 +856,7 @@ private:
|
||||
mutable bool DebugCompileOptionsDone;
|
||||
mutable bool DebugCompileFeaturesDone;
|
||||
mutable bool DebugCompileDefinitionsDone;
|
||||
mutable bool DebugLinkOptionsDone;
|
||||
mutable bool DebugSourcesDone;
|
||||
mutable bool LinkImplementationLanguageIsContextDependent;
|
||||
mutable bool UtilityItemsDone;
|
||||
|
||||
@@ -1817,6 +1817,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
|
||||
this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, linkFlags);
|
||||
}
|
||||
}
|
||||
std::vector<std::string> opts;
|
||||
gtgt->GetLinkOptions(opts, configName, llang);
|
||||
// LINK_OPTIONS are escaped.
|
||||
this->CurrentLocalGenerator->AppendCompileOptions(extraLinkOptions, opts);
|
||||
}
|
||||
|
||||
// Set target-specific architectures.
|
||||
|
||||
@@ -1042,6 +1042,10 @@ void cmLocalGenerator::GetTargetFlags(
|
||||
linkFlags += " ";
|
||||
}
|
||||
}
|
||||
std::vector<std::string> opts;
|
||||
target->GetLinkOptions(opts, config, linkLanguage);
|
||||
// LINK_OPTIONS are escaped.
|
||||
this->AppendCompileOptions(linkFlags, opts);
|
||||
if (pcli) {
|
||||
this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
|
||||
frameworkPath, linkPath);
|
||||
@@ -1113,6 +1117,10 @@ void cmLocalGenerator::GetTargetFlags(
|
||||
linkFlags += " ";
|
||||
}
|
||||
}
|
||||
std::vector<std::string> opts;
|
||||
target->GetLinkOptions(opts, config, linkLanguage);
|
||||
// LINK_OPTIONS are escaped.
|
||||
this->AppendCompileOptions(linkFlags, opts);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -977,6 +977,13 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
|
||||
extraLinkOptions += " ";
|
||||
extraLinkOptions += targetLinkFlags;
|
||||
}
|
||||
|
||||
std::vector<std::string> opts;
|
||||
target->GetLinkOptions(opts, configName,
|
||||
target->GetLinkerLanguage(configName));
|
||||
// LINK_OPTIONS are escaped.
|
||||
this->AppendCompileOptions(extraLinkOptions, opts);
|
||||
|
||||
Options linkOptions(this, Options::Linker);
|
||||
if (this->FortranProject) {
|
||||
linkOptions.AddTable(cmLocalVisualStudio7GeneratorFortranLinkFlagTable);
|
||||
|
||||
@@ -216,6 +216,16 @@ cmBacktraceRange cmMakefile::GetCompileDefinitionsBacktraces() const
|
||||
.GetCompileDefinitionsEntryBacktraces();
|
||||
}
|
||||
|
||||
cmStringRange cmMakefile::GetLinkOptionsEntries() const
|
||||
{
|
||||
return this->StateSnapshot.GetDirectory().GetLinkOptionsEntries();
|
||||
}
|
||||
|
||||
cmBacktraceRange cmMakefile::GetLinkOptionsBacktraces() const
|
||||
{
|
||||
return this->StateSnapshot.GetDirectory().GetLinkOptionsEntryBacktraces();
|
||||
}
|
||||
|
||||
cmListFileBacktrace cmMakefile::GetBacktrace() const
|
||||
{
|
||||
return this->Backtrace;
|
||||
@@ -1205,6 +1215,11 @@ void cmMakefile::AddCompileOption(std::string const& option)
|
||||
this->AppendProperty("COMPILE_OPTIONS", option.c_str());
|
||||
}
|
||||
|
||||
void cmMakefile::AddLinkOption(std::string const& option)
|
||||
{
|
||||
this->AppendProperty("LINK_OPTIONS", option.c_str());
|
||||
}
|
||||
|
||||
bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
|
||||
{
|
||||
// Create a regular expression to match valid definitions.
|
||||
|
||||
@@ -171,6 +171,7 @@ public:
|
||||
void RemoveDefineFlag(std::string const& definition);
|
||||
void AddCompileDefinition(std::string const& definition);
|
||||
void AddCompileOption(std::string const& option);
|
||||
void AddLinkOption(std::string const& option);
|
||||
|
||||
/** Create a new imported target with the name and type given. */
|
||||
cmTarget* AddImportedTarget(const std::string& name,
|
||||
@@ -788,6 +789,8 @@ public:
|
||||
cmBacktraceRange GetCompileOptionsBacktraces() const;
|
||||
cmStringRange GetCompileDefinitionsEntries() const;
|
||||
cmBacktraceRange GetCompileDefinitionsBacktraces() const;
|
||||
cmStringRange GetLinkOptionsEntries() const;
|
||||
cmBacktraceRange GetLinkOptionsBacktraces() const;
|
||||
|
||||
std::set<std::string> const& GetSystemIncludeDirectories() const
|
||||
{
|
||||
|
||||
@@ -154,7 +154,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
|
||||
linkLanguage, this->ConfigName);
|
||||
|
||||
// Add target-specific linker flags.
|
||||
this->GetTargetLinkFlags(linkFlags);
|
||||
this->GetTargetLinkFlags(linkFlags, linkLanguage);
|
||||
|
||||
// Construct a list of files associated with this executable that
|
||||
// may need to be cleaned.
|
||||
@@ -432,7 +432,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
|
||||
linkLanguage, this->ConfigName);
|
||||
|
||||
// Add target-specific linker flags.
|
||||
this->GetTargetLinkFlags(linkFlags);
|
||||
this->GetTargetLinkFlags(linkFlags, linkLanguage);
|
||||
|
||||
{
|
||||
std::unique_ptr<cmLinkLineComputer> linkLineComputer(
|
||||
|
||||
@@ -181,7 +181,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
|
||||
linkRuleVar += "_CREATE_SHARED_LIBRARY";
|
||||
|
||||
std::string extraFlags;
|
||||
this->GetTargetLinkFlags(extraFlags);
|
||||
this->GetTargetLinkFlags(extraFlags, linkLanguage);
|
||||
this->LocalGenerator->AddConfigVariableFlags(
|
||||
extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
|
||||
|
||||
@@ -222,7 +222,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
|
||||
linkRuleVar += "_CREATE_SHARED_MODULE";
|
||||
|
||||
std::string extraFlags;
|
||||
this->GetTargetLinkFlags(extraFlags);
|
||||
this->GetTargetLinkFlags(extraFlags, linkLanguage);
|
||||
this->LocalGenerator->AddConfigVariableFlags(
|
||||
extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
|
||||
|
||||
@@ -245,7 +245,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
|
||||
linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
|
||||
|
||||
std::string extraFlags;
|
||||
this->GetTargetLinkFlags(extraFlags);
|
||||
this->GetTargetLinkFlags(extraFlags, linkLanguage);
|
||||
this->LocalGenerator->AddConfigVariableFlags(
|
||||
extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
|
||||
|
||||
@@ -271,7 +271,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
|
||||
|
||||
// Create set of linking flags.
|
||||
std::string linkFlags;
|
||||
this->GetTargetLinkFlags(linkFlags);
|
||||
this->GetTargetLinkFlags(linkFlags, linkLanguage);
|
||||
|
||||
// Get the name of the device object to generate.
|
||||
std::string const targetOutputReal =
|
||||
|
||||
@@ -82,7 +82,8 @@ cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
|
||||
return result;
|
||||
}
|
||||
|
||||
void cmMakefileTargetGenerator::GetTargetLinkFlags(std::string& flags)
|
||||
void cmMakefileTargetGenerator::GetTargetLinkFlags(
|
||||
std::string& flags, const std::string& linkLanguage)
|
||||
{
|
||||
this->LocalGenerator->AppendFlags(
|
||||
flags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
|
||||
@@ -91,6 +92,11 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(std::string& flags)
|
||||
linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
|
||||
this->LocalGenerator->AppendFlags(
|
||||
flags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
|
||||
|
||||
std::vector<std::string> opts;
|
||||
this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage);
|
||||
// LINK_OPTIONS are escaped.
|
||||
this->LocalGenerator->AppendCompileOptions(flags, opts);
|
||||
}
|
||||
|
||||
void cmMakefileTargetGenerator::CreateRuleFile()
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
|
||||
|
||||
protected:
|
||||
void GetTargetLinkFlags(std::string& flags);
|
||||
void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage);
|
||||
|
||||
// create the file and directory etc
|
||||
void CreateRuleFile();
|
||||
|
||||
@@ -280,6 +280,8 @@ cmStateSnapshot cmState::Reset()
|
||||
it->CompileDefinitionsBacktraces.clear();
|
||||
it->CompileOptions.clear();
|
||||
it->CompileOptionsBacktraces.clear();
|
||||
it->LinkOptions.clear();
|
||||
it->LinkOptionsBacktraces.clear();
|
||||
it->DirectoryEnd = pos;
|
||||
it->NormalTargetNames.clear();
|
||||
it->Properties.clear();
|
||||
|
||||
@@ -360,6 +360,42 @@ void cmStateDirectory::ClearCompileOptions()
|
||||
this->Snapshot_.Position->CompileOptionsPosition);
|
||||
}
|
||||
|
||||
cmStringRange cmStateDirectory::GetLinkOptionsEntries() const
|
||||
{
|
||||
return GetPropertyContent(this->DirectoryState->LinkOptions,
|
||||
this->Snapshot_.Position->LinkOptionsPosition);
|
||||
}
|
||||
|
||||
cmBacktraceRange cmStateDirectory::GetLinkOptionsEntryBacktraces() const
|
||||
{
|
||||
return GetPropertyBacktraces(this->DirectoryState->LinkOptions,
|
||||
this->DirectoryState->LinkOptionsBacktraces,
|
||||
this->Snapshot_.Position->LinkOptionsPosition);
|
||||
}
|
||||
|
||||
void cmStateDirectory::AppendLinkOptionsEntry(const std::string& vec,
|
||||
const cmListFileBacktrace& lfbt)
|
||||
{
|
||||
AppendEntry(this->DirectoryState->LinkOptions,
|
||||
this->DirectoryState->LinkOptionsBacktraces,
|
||||
this->Snapshot_.Position->LinkOptionsPosition, vec, lfbt);
|
||||
}
|
||||
|
||||
void cmStateDirectory::SetLinkOptions(const std::string& vec,
|
||||
const cmListFileBacktrace& lfbt)
|
||||
{
|
||||
SetContent(this->DirectoryState->LinkOptions,
|
||||
this->DirectoryState->LinkOptionsBacktraces,
|
||||
this->Snapshot_.Position->LinkOptionsPosition, vec, lfbt);
|
||||
}
|
||||
|
||||
void cmStateDirectory::ClearLinkOptions()
|
||||
{
|
||||
ClearContent(this->DirectoryState->LinkOptions,
|
||||
this->DirectoryState->LinkOptionsBacktraces,
|
||||
this->Snapshot_.Position->LinkOptionsPosition);
|
||||
}
|
||||
|
||||
void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
|
||||
cmListFileBacktrace const& lfbt)
|
||||
{
|
||||
@@ -387,6 +423,14 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
|
||||
this->SetCompileDefinitions(value, lfbt);
|
||||
return;
|
||||
}
|
||||
if (prop == "LINK_OPTIONS") {
|
||||
if (!value) {
|
||||
this->ClearLinkOptions();
|
||||
return;
|
||||
}
|
||||
this->SetLinkOptions(value, lfbt);
|
||||
return;
|
||||
}
|
||||
|
||||
this->DirectoryState->Properties.SetProperty(prop, value);
|
||||
}
|
||||
@@ -407,6 +451,10 @@ void cmStateDirectory::AppendProperty(const std::string& prop,
|
||||
this->AppendCompileDefinitionsEntry(value, lfbt);
|
||||
return;
|
||||
}
|
||||
if (prop == "LINK_OPTIONS") {
|
||||
this->AppendLinkOptionsEntry(value, lfbt);
|
||||
return;
|
||||
}
|
||||
|
||||
this->DirectoryState->Properties.AppendProperty(prop, value, asString);
|
||||
}
|
||||
@@ -490,6 +538,10 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
|
||||
output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
|
||||
return output.c_str();
|
||||
}
|
||||
if (prop == "LINK_OPTIONS") {
|
||||
output = cmJoin(this->GetLinkOptionsEntries(), ";");
|
||||
return output.c_str();
|
||||
}
|
||||
|
||||
const char* retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
|
||||
if (!retVal && chain) {
|
||||
|
||||
@@ -58,6 +58,13 @@ public:
|
||||
cmListFileBacktrace const& lfbt);
|
||||
void ClearCompileOptions();
|
||||
|
||||
cmStringRange GetLinkOptionsEntries() const;
|
||||
cmBacktraceRange GetLinkOptionsEntryBacktraces() const;
|
||||
void AppendLinkOptionsEntry(std::string const& vec,
|
||||
cmListFileBacktrace const& lfbt);
|
||||
void SetLinkOptions(std::string const& vec, cmListFileBacktrace const& lfbt);
|
||||
void ClearLinkOptions();
|
||||
|
||||
void SetProperty(const std::string& prop, const char* value,
|
||||
cmListFileBacktrace const& lfbt);
|
||||
void AppendProperty(const std::string& prop, const char* value,
|
||||
|
||||
@@ -42,6 +42,7 @@ struct cmStateDetail::SnapshotDataType
|
||||
std::vector<std::string>::size_type IncludeDirectoryPosition;
|
||||
std::vector<std::string>::size_type CompileDefinitionsPosition;
|
||||
std::vector<std::string>::size_type CompileOptionsPosition;
|
||||
std::vector<std::string>::size_type LinkOptionsPosition;
|
||||
};
|
||||
|
||||
struct cmStateDetail::PolicyStackEntry : public cmPolicies::PolicyMap
|
||||
@@ -84,6 +85,9 @@ struct cmStateDetail::BuildsystemDirectoryStateType
|
||||
std::vector<std::string> CompileOptions;
|
||||
std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
|
||||
|
||||
std::vector<std::string> LinkOptions;
|
||||
std::vector<cmListFileBacktrace> LinkOptionsBacktraces;
|
||||
|
||||
std::vector<std::string> NormalTargetNames;
|
||||
|
||||
std::string ProjectName;
|
||||
|
||||
@@ -390,6 +390,13 @@ void cmStateSnapshot::InitializeFromParent()
|
||||
this->Position->BuildSystemDirectory->CompileOptionsBacktraces,
|
||||
this->Position->CompileOptionsPosition);
|
||||
|
||||
InitializeContentFromParent(
|
||||
parent->BuildSystemDirectory->LinkOptions,
|
||||
this->Position->BuildSystemDirectory->LinkOptions,
|
||||
parent->BuildSystemDirectory->LinkOptionsBacktraces,
|
||||
this->Position->BuildSystemDirectory->LinkOptionsBacktraces,
|
||||
this->Position->LinkOptionsPosition);
|
||||
|
||||
const char* include_regex =
|
||||
parent->BuildSystemDirectory->Properties.GetPropertyValue(
|
||||
"INCLUDE_REGULAR_EXPRESSION");
|
||||
|
||||
+71
-6
@@ -166,6 +166,8 @@ public:
|
||||
std::vector<cmListFileBacktrace> CompileDefinitionsBacktraces;
|
||||
std::vector<std::string> SourceEntries;
|
||||
std::vector<cmListFileBacktrace> SourceBacktraces;
|
||||
std::vector<std::string> LinkOptionsEntries;
|
||||
std::vector<cmListFileBacktrace> LinkOptionsBacktraces;
|
||||
std::vector<std::string> LinkImplementationPropertyEntries;
|
||||
std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
|
||||
};
|
||||
@@ -343,17 +345,29 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
|
||||
this->SystemIncludeDirectories.insert(parentSystemIncludes.begin(),
|
||||
parentSystemIncludes.end());
|
||||
|
||||
const cmStringRange parentOptions =
|
||||
const cmStringRange parentCompileOptions =
|
||||
this->Makefile->GetCompileOptionsEntries();
|
||||
const cmBacktraceRange parentOptionsBts =
|
||||
const cmBacktraceRange parentCompileOptionsBts =
|
||||
this->Makefile->GetCompileOptionsBacktraces();
|
||||
|
||||
this->Internal->CompileOptionsEntries.insert(
|
||||
this->Internal->CompileOptionsEntries.end(), parentOptions.begin(),
|
||||
parentOptions.end());
|
||||
this->Internal->CompileOptionsEntries.end(),
|
||||
parentCompileOptions.begin(), parentCompileOptions.end());
|
||||
this->Internal->CompileOptionsBacktraces.insert(
|
||||
this->Internal->CompileOptionsBacktraces.end(), parentOptionsBts.begin(),
|
||||
parentOptionsBts.end());
|
||||
this->Internal->CompileOptionsBacktraces.end(),
|
||||
parentCompileOptionsBts.begin(), parentCompileOptionsBts.end());
|
||||
|
||||
const cmStringRange parentLinkOptions =
|
||||
this->Makefile->GetLinkOptionsEntries();
|
||||
const cmBacktraceRange parentLinkOptionsBts =
|
||||
this->Makefile->GetLinkOptionsBacktraces();
|
||||
|
||||
this->Internal->LinkOptionsEntries.insert(
|
||||
this->Internal->LinkOptionsEntries.end(), parentLinkOptions.begin(),
|
||||
parentLinkOptions.end());
|
||||
this->Internal->LinkOptionsBacktraces.insert(
|
||||
this->Internal->LinkOptionsBacktraces.end(),
|
||||
parentLinkOptionsBts.begin(), parentLinkOptionsBts.end());
|
||||
}
|
||||
|
||||
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
|
||||
@@ -822,6 +836,16 @@ cmBacktraceRange cmTarget::GetSourceBacktraces() const
|
||||
return cmMakeRange(this->Internal->SourceBacktraces);
|
||||
}
|
||||
|
||||
cmStringRange cmTarget::GetLinkOptionsEntries() const
|
||||
{
|
||||
return cmMakeRange(this->Internal->LinkOptionsEntries);
|
||||
}
|
||||
|
||||
cmBacktraceRange cmTarget::GetLinkOptionsBacktraces() const
|
||||
{
|
||||
return cmMakeRange(this->Internal->LinkOptionsBacktraces);
|
||||
}
|
||||
|
||||
cmStringRange cmTarget::GetLinkImplementationEntries() const
|
||||
{
|
||||
return cmMakeRange(this->Internal->LinkImplementationPropertyEntries);
|
||||
@@ -847,6 +871,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
|
||||
MAKE_STATIC_PROP(EXPORT_NAME);
|
||||
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
|
||||
MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
|
||||
MAKE_STATIC_PROP(LINK_OPTIONS);
|
||||
MAKE_STATIC_PROP(LINK_LIBRARIES);
|
||||
MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
|
||||
MAKE_STATIC_PROP(NAME);
|
||||
@@ -925,6 +950,14 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
|
||||
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
|
||||
this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == propLINK_OPTIONS) {
|
||||
this->Internal->LinkOptionsEntries.clear();
|
||||
this->Internal->LinkOptionsBacktraces.clear();
|
||||
if (value) {
|
||||
this->Internal->LinkOptionsEntries.push_back(value);
|
||||
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
|
||||
this->Internal->LinkOptionsBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == propLINK_LIBRARIES) {
|
||||
this->Internal->LinkImplementationPropertyEntries.clear();
|
||||
this->Internal->LinkImplementationPropertyBacktraces.clear();
|
||||
@@ -1030,6 +1063,12 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
|
||||
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
|
||||
this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == "LINK_OPTIONS") {
|
||||
if (value && *value) {
|
||||
this->Internal->LinkOptionsEntries.push_back(value);
|
||||
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
|
||||
this->Internal->LinkOptionsBacktraces.push_back(lfbt);
|
||||
}
|
||||
} else if (prop == "LINK_LIBRARIES") {
|
||||
if (value && *value) {
|
||||
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
|
||||
@@ -1111,6 +1150,21 @@ void cmTarget::InsertCompileDefinition(std::string const& entry,
|
||||
this->Internal->CompileDefinitionsBacktraces.push_back(bt);
|
||||
}
|
||||
|
||||
void cmTarget::InsertLinkOption(std::string const& entry,
|
||||
cmListFileBacktrace const& bt, bool before)
|
||||
{
|
||||
std::vector<std::string>::iterator position = before
|
||||
? this->Internal->LinkOptionsEntries.begin()
|
||||
: this->Internal->LinkOptionsEntries.end();
|
||||
|
||||
std::vector<cmListFileBacktrace>::iterator btPosition = before
|
||||
? this->Internal->LinkOptionsBacktraces.begin()
|
||||
: this->Internal->LinkOptionsBacktraces.end();
|
||||
|
||||
this->Internal->LinkOptionsEntries.insert(position, entry);
|
||||
this->Internal->LinkOptionsBacktraces.insert(btPosition, bt);
|
||||
}
|
||||
|
||||
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
|
||||
const char* value,
|
||||
cmMakefile* context,
|
||||
@@ -1230,6 +1284,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
|
||||
MAKE_STATIC_PROP(COMPILE_FEATURES);
|
||||
MAKE_STATIC_PROP(COMPILE_OPTIONS);
|
||||
MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
|
||||
MAKE_STATIC_PROP(LINK_OPTIONS);
|
||||
MAKE_STATIC_PROP(IMPORTED);
|
||||
MAKE_STATIC_PROP(IMPORTED_GLOBAL);
|
||||
MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
|
||||
@@ -1245,6 +1300,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
|
||||
specialProps.insert(propCOMPILE_FEATURES);
|
||||
specialProps.insert(propCOMPILE_OPTIONS);
|
||||
specialProps.insert(propCOMPILE_DEFINITIONS);
|
||||
specialProps.insert(propLINK_OPTIONS);
|
||||
specialProps.insert(propIMPORTED);
|
||||
specialProps.insert(propIMPORTED_GLOBAL);
|
||||
specialProps.insert(propMANUALLY_ADDED_DEPENDENCIES);
|
||||
@@ -1303,6 +1359,15 @@ const char* cmTarget::GetProperty(const std::string& prop) const
|
||||
output = cmJoin(this->Internal->CompileDefinitionsEntries, ";");
|
||||
return output.c_str();
|
||||
}
|
||||
if (prop == propLINK_OPTIONS) {
|
||||
if (this->Internal->LinkOptionsEntries.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static std::string output;
|
||||
output = cmJoin(this->Internal->LinkOptionsEntries, ";");
|
||||
return output.c_str();
|
||||
}
|
||||
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
|
||||
if (this->Utilities.empty()) {
|
||||
return nullptr;
|
||||
|
||||
@@ -239,6 +239,8 @@ public:
|
||||
cmListFileBacktrace const& bt, bool before = false);
|
||||
void InsertCompileDefinition(std::string const& entry,
|
||||
cmListFileBacktrace const& bt);
|
||||
void InsertLinkOption(std::string const& entry,
|
||||
cmListFileBacktrace const& bt, bool before = false);
|
||||
|
||||
void AppendBuildInterfaceIncludes();
|
||||
|
||||
@@ -265,6 +267,10 @@ public:
|
||||
|
||||
cmStringRange GetSourceEntries() const;
|
||||
cmBacktraceRange GetSourceBacktraces() const;
|
||||
|
||||
cmStringRange GetLinkOptionsEntries() const;
|
||||
cmBacktraceRange GetLinkOptionsBacktraces() const;
|
||||
|
||||
cmStringRange GetLinkImplementationEntries() const;
|
||||
cmBacktraceRange GetLinkImplementationBacktraces() const;
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmTargetLinkOptionsCommand.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmListFileCache.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmTarget.h"
|
||||
#include "cmake.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
|
||||
bool cmTargetLinkOptionsCommand::InitialPass(
|
||||
std::vector<std::string> const& args, cmExecutionStatus&)
|
||||
{
|
||||
return this->HandleArguments(args, "LINK_OPTIONS", PROCESS_BEFORE);
|
||||
}
|
||||
|
||||
void cmTargetLinkOptionsCommand::HandleMissingTarget(const std::string& name)
|
||||
{
|
||||
std::ostringstream e;
|
||||
e << "Cannot specify link options for target \"" << name
|
||||
<< "\" which is not built by this project.";
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
|
||||
}
|
||||
|
||||
std::string cmTargetLinkOptionsCommand::Join(
|
||||
const std::vector<std::string>& content)
|
||||
{
|
||||
return cmJoin(content, ";");
|
||||
}
|
||||
|
||||
bool cmTargetLinkOptionsCommand::HandleDirectContent(
|
||||
cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
|
||||
{
|
||||
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
|
||||
tgt->InsertLinkOption(this->Join(content), lfbt);
|
||||
return true; // Successfully handled.
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmTargetLinkOptionsCommand_h
|
||||
#define cmTargetLinkOptionsCommand_h
|
||||
|
||||
#include "cmConfigure.h" // IWYU pragma: keep
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmTargetPropCommandBase.h"
|
||||
|
||||
class cmCommand;
|
||||
class cmExecutionStatus;
|
||||
class cmTarget;
|
||||
|
||||
class cmTargetLinkOptionsCommand : public cmTargetPropCommandBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
cmCommand* Clone() override { return new cmTargetLinkOptionsCommand; }
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status) override;
|
||||
|
||||
private:
|
||||
void HandleMissingTarget(const std::string& name) override;
|
||||
|
||||
bool HandleDirectContent(cmTarget* tgt,
|
||||
const std::vector<std::string>& content,
|
||||
bool prepend, bool system) override;
|
||||
std::string Join(const std::vector<std::string>& content) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -3234,6 +3234,11 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
|
||||
flags += flagsConfig;
|
||||
}
|
||||
|
||||
std::vector<std::string> opts;
|
||||
this->GeneratorTarget->GetLinkOptions(opts, config, linkLanguage);
|
||||
// LINK_OPTIONS are escaped.
|
||||
this->LocalGenerator->AppendCompileOptions(flags, opts);
|
||||
|
||||
cmComputeLinkInformation* pcli =
|
||||
this->GeneratorTarget->GetLinkInformation(config);
|
||||
if (!pcli) {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
project(add_link_options LANGUAGES C)
|
||||
|
||||
|
||||
add_link_options(-LINK_FLAG)
|
||||
|
||||
add_executable(add_link_options EXCLUDE_FROM_ALL LinkOptionsExe.c)
|
||||
|
||||
get_target_property(result add_link_options LINK_OPTIONS)
|
||||
if (NOT result MATCHES "-LINK_FLAG")
|
||||
message(SEND_ERROR "add_link_options not populated the LINK_OPTIONS target property")
|
||||
endif()
|
||||
|
||||
|
||||
add_library(imp UNKNOWN IMPORTED)
|
||||
get_target_property(result imp LINK_OPTIONS)
|
||||
if (result)
|
||||
message(FATAL_ERROR "add_link_options populated the LINK_OPTIONS target property")
|
||||
endif()
|
||||
@@ -0,0 +1,4 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
project(target_link_options LANGUAGES C)
|
||||
|
||||
add_library(target_link_options SHARED LinkOptionsLib.c)
|
||||
# Test no items
|
||||
target_link_options(target_link_options PRIVATE)
|
||||
|
||||
add_library(target_link_options_2 SHARED EXCLUDE_FROM_ALL LinkOptionsLib.c)
|
||||
target_link_options(target_link_options_2 PRIVATE -PRIVATE_FLAG INTERFACE -INTERFACE_FLAG)
|
||||
get_target_property(result target_link_options_2 LINK_OPTIONS)
|
||||
if (NOT result MATCHES "-PRIVATE_FLAG")
|
||||
message(SEND_ERROR "target_link_options not populated the LINK_OPTIONS target property")
|
||||
endif()
|
||||
get_target_property(result target_link_options_2 INTERFACE_LINK_OPTIONS)
|
||||
if (NOT result MATCHES "-INTERFACE_FLAG")
|
||||
message(SEND_ERROR "target_link_options not populated the INTERFACE_LINK_OPTIONS target property")
|
||||
endif()
|
||||
@@ -0,0 +1,7 @@
|
||||
#if defined(_WIN32)
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int flags_lib(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -2840,6 +2840,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
|
||||
ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions)
|
||||
ADD_TEST_MACRO(CMakeCommands.target_compile_options target_compile_options)
|
||||
|
||||
ADD_TEST_MACRO(CMakeCommands.add_link_options)
|
||||
ADD_TEST_MACRO(CMakeCommands.target_link_options)
|
||||
|
||||
# The cmake server-mode test requires python for a simple client.
|
||||
find_package(PythonInterp QUIET)
|
||||
if(PYTHON_EXECUTABLE)
|
||||
|
||||
@@ -597,3 +597,13 @@ install(
|
||||
)
|
||||
install(DIRECTORY $<1:include/abs>$<0:/wrong> DESTINATION $<1:include>$<0:/wrong>)
|
||||
install(EXPORT expAbs NAMESPACE expAbs_ DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/expAbs)
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# test export of INTERFACE_LINK_OPTIONS
|
||||
add_library(testLinkOptions INTERFACE)
|
||||
target_link_options(testLinkOptions INTERFACE INTERFACE_FLAG)
|
||||
|
||||
install(TARGETS testLinkOptions
|
||||
EXPORT RequiredExp DESTINATION lib)
|
||||
export(TARGETS testLinkOptions NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake)
|
||||
|
||||
@@ -472,3 +472,8 @@ if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREA
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# check that imported libraries have the expected INTERFACE_LINK_OPTIONS property
|
||||
checkForProperty(bld_testLinkOptions "INTERFACE_LINK_OPTIONS" "INTERFACE_FLAG")
|
||||
checkForProperty(Req::testLinkOptions "INTERFACE_LINK_OPTIONS" "INTERFACE_FLAG")
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
|
||||
#include "testSharedLibRequired.h"
|
||||
|
||||
int foo()
|
||||
{
|
||||
TestSharedLibRequired req;
|
||||
return req.foo();
|
||||
}
|
||||
@@ -5,7 +5,9 @@ add_library(car foo.cxx)
|
||||
add_library(bar bar.c)
|
||||
add_library(dog foo.cxx)
|
||||
target_link_libraries(foo PRIVATE car bar dog debug -lm)
|
||||
export(TARGETS bar dog car foo ANDROID_MK
|
||||
add_library(foo2 foo.cxx)
|
||||
target_link_options(foo2 INTERFACE -lm)
|
||||
export(TARGETS bar dog car foo foo2 ANDROID_MK
|
||||
${build_BINARY_DIR}/Android.mk)
|
||||
install(TARGETS bar dog car foo DESTINATION lib EXPORT myexp)
|
||||
install(TARGETS bar dog car foo foo2 DESTINATION lib EXPORT myexp)
|
||||
install(EXPORT_ANDROID_MK myexp DESTINATION share/ndk-modules)
|
||||
|
||||
@@ -24,3 +24,11 @@ LOCAL_STATIC_LIBRARIES.*car bar dog
|
||||
LOCAL_EXPORT_LDLIBS := -lm
|
||||
LOCAL_HAS_CPP := true
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
.*
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*foo2
|
||||
LOCAL_SRC_FILES.*.*foo2.*
|
||||
LOCAL_CPP_FEATURES.*rtti exceptions
|
||||
LOCAL_EXPORT_LDFLAGS := -lm
|
||||
LOCAL_HAS_CPP := true
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
|
||||
@@ -26,3 +26,11 @@ LOCAL_STATIC_LIBRARIES.*car bar dog
|
||||
LOCAL_EXPORT_LDLIBS := -lm
|
||||
LOCAL_HAS_CPP := true
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
|
||||
include.*CLEAR_VARS.*
|
||||
LOCAL_MODULE.*foo2
|
||||
LOCAL_SRC_FILES.*_IMPORT_PREFIX\)/lib.*foo2.*
|
||||
LOCAL_CPP_FEATURES.*rtti exceptions
|
||||
LOCAL_EXPORT_LDFLAGS := -lm
|
||||
LOCAL_HAS_CPP := true
|
||||
include.*PREBUILT_STATIC_LIBRARY.*
|
||||
|
||||
@@ -332,6 +332,8 @@ endif()
|
||||
add_RunCMake_test(File_Generate)
|
||||
add_RunCMake_test(ExportWithoutLanguage)
|
||||
add_RunCMake_test(target_link_libraries)
|
||||
add_RunCMake_test(add_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
|
||||
add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
|
||||
|
||||
add_RunCMake_test(target_compile_features)
|
||||
add_RunCMake_test(CheckModules)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
project(${RunCMake_TEST} LANGUAGES NONE)
|
||||
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
if (NOT actual_stdout MATCHES "BADFLAG_EXECUTABLE_RELEASE")
|
||||
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_EXECUTABLE_RELEASE'.")
|
||||
endif()
|
||||
if (actual_stdout MATCHES "BADFLAG_(SHARED|MODULE)_RELEASE")
|
||||
set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|MODULE)_RELEASE'.")
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
if (NOT actual_stdout MATCHES "BADFLAG_MODULE_RELEASE")
|
||||
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_MODULE_RELEASE'.")
|
||||
endif()
|
||||
if (actual_stdout MATCHES "BADFLAG_(SHARED|EXECUTABLE)_RELEASE")
|
||||
set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|EXECUTABLE)_RELEASE'.")
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
if (NOT actual_stdout MATCHES "BADFLAG_SHARED_RELEASE")
|
||||
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_SHARED_RELEASE'.")
|
||||
endif()
|
||||
if (actual_stdout MATCHES "BADFLAG_(MODULE|EXECUTABLE)_RELEASE")
|
||||
set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(MODULE|EXECUTABLE)_RELEASE'.")
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
enable_language(C)
|
||||
|
||||
set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
|
||||
if(BORLAND)
|
||||
set(pre -)
|
||||
endif()
|
||||
|
||||
add_link_options($<$<AND:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>,$<CONFIG:Release>>:${pre}BADFLAG_SHARED_RELEASE${obj}>)
|
||||
add_link_options($<$<AND:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>,$<CONFIG:Release>>:${pre}BADFLAG_MODULE_RELEASE${obj}>)
|
||||
add_link_options($<$<AND:$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>,$<CONFIG:Release>>:${pre}BADFLAG_EXECUTABLE_RELEASE${obj}>)
|
||||
|
||||
add_library(LinkOptions_shared SHARED LinkOptionsLib.c)
|
||||
|
||||
add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
|
||||
|
||||
add_executable(LinkOptions_exe LinkOptionsExe.c)
|
||||
@@ -0,0 +1,4 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#if defined(_WIN32)
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int flags_lib(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
include(RunCMake)
|
||||
|
||||
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(LINK_OPTIONS)
|
||||
|
||||
run_cmake_target(LINK_OPTIONS shared LinkOptions_shared --config Release)
|
||||
run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
|
||||
run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
|
||||
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
unset(RunCMake_TEST_OUTPUT_MERGE)
|
||||
endif()
|
||||
@@ -0,0 +1,2 @@
|
||||
-- Target LINK_OPTIONS is 'a;b;c;d;;e'
|
||||
-- Directory LINK_OPTIONS is 'a;b;c;d;;e'
|
||||
@@ -0,0 +1,3 @@
|
||||
include(Common.cmake)
|
||||
test_target_property(LINK_OPTIONS)
|
||||
test_directory_property(LINK_OPTIONS)
|
||||
@@ -5,6 +5,7 @@ run_cmake(COMPILE_FEATURES)
|
||||
run_cmake(COMPILE_OPTIONS)
|
||||
run_cmake(IMPORTED_GLOBAL)
|
||||
run_cmake(INCLUDE_DIRECTORIES)
|
||||
run_cmake(LINK_OPTIONS)
|
||||
run_cmake(LINK_LIBRARIES)
|
||||
run_cmake(SOURCES)
|
||||
run_cmake(TYPE)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
project(${RunCMake_TEST} LANGUAGES NONE)
|
||||
|
||||
include(${RunCMake_TEST}.cmake)
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
if (NOT actual_stdout MATCHES "BADFLAG_PRIVATE")
|
||||
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_PRIVATE'.")
|
||||
endif()
|
||||
if (actual_stdout MATCHES "BADFLAG_INTERFACE")
|
||||
string (APPEND RunCMake_TEST_FAILED "\nFound unexpected 'BADFLAG_INTERFACE'.")
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -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()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
if (NOT actual_stdout MATCHES "BADFLAG_INTERFACE")
|
||||
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_INTERFACE'.")
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -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()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -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()
|
||||
@@ -0,0 +1 @@
|
||||
.*
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
enable_language(C)
|
||||
|
||||
set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
|
||||
if(BORLAND)
|
||||
set(pre -)
|
||||
endif()
|
||||
|
||||
# basic configuration
|
||||
add_library(LinkOptions SHARED LinkOptionsLib.c)
|
||||
target_link_options(LinkOptions
|
||||
PRIVATE ${pre}BADFLAG_PRIVATE${obj}
|
||||
INTERFACE ${pre}BADFLAG_INTERFACE${obj})
|
||||
|
||||
|
||||
# INTERFACE_LINK_OPTIONS
|
||||
add_library(LinkOptions_producer SHARED LinkOptionsLib.c)
|
||||
target_link_options(LinkOptions_producer
|
||||
INTERFACE ${pre}BADFLAG_INTERFACE${obj})
|
||||
|
||||
add_executable(LinkOptions_consumer LinkOptionsExe.c)
|
||||
target_link_libraries(LinkOptions_consumer PRIVATE LinkOptions_producer)
|
||||
|
||||
|
||||
# shared library with generator expression
|
||||
add_library(LinkOptions_shared SHARED LinkOptionsLib.c)
|
||||
target_link_options(LinkOptions_shared PRIVATE $<$<CONFIG:Release>:${pre}BADFLAG_RELEASE${obj}>
|
||||
"SHELL:" # produces no options
|
||||
)
|
||||
|
||||
|
||||
# module library with generator expression
|
||||
add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
|
||||
target_link_options(LinkOptions_mod PRIVATE $<$<CONFIG:Release>:${pre}BADFLAG_RELEASE${obj}>)
|
||||
|
||||
|
||||
# executable with generator expression
|
||||
add_executable(LinkOptions_exe LinkOptionsExe.c)
|
||||
target_link_options(LinkOptions_exe PRIVATE $<$<CONFIG:Release>:${pre}BADFLAG_RELEASE${obj}>)
|
||||
@@ -0,0 +1,4 @@
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#if defined(_WIN32)
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int flags_lib(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
include(RunCMake)
|
||||
|
||||
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(LINK_OPTIONS)
|
||||
|
||||
run_cmake_target(LINK_OPTIONS basic LinkOptions)
|
||||
run_cmake_target(LINK_OPTIONS interface LinkOptions_consumer)
|
||||
run_cmake_target(LINK_OPTIONS shared LinkOptions_shared --config Release)
|
||||
run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
|
||||
run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
|
||||
|
||||
unset(RunCMake_TEST_OPTIONS)
|
||||
unset(RunCMake_TEST_OUTPUT_MERGE)
|
||||
endif()
|
||||
|
||||
|
||||
# include(RunCMake)
|
||||
|
||||
# macro(run_cmake_build test)
|
||||
# run_cmake(${test})
|
||||
|
||||
# set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
|
||||
# set(RunCMake_TEST_NO_CLEAN 1)
|
||||
# run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . ${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)
|
||||
|
||||
# run_cmake_build(LINK_OPTIONS)
|
||||
# run_cmake_build(INTERFACE_LINK_OPTIONS)
|
||||
|
||||
# if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
|
||||
# set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
|
||||
# endif()
|
||||
# run_cmake_build(LINK_OPTIONS_shared --config Release)
|
||||
# run_cmake_build(LINK_OPTIONS_mod --config Release)
|
||||
# run_cmake_build(LINK_OPTIONS_exe --config Release)
|
||||
# unset(RunCMake_TEST_OPTIONS)
|
||||
|
||||
# unset(RunCMake_TEST_OUTPUT_MERGE)
|
||||
# endif()
|
||||
Reference in New Issue
Block a user