summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Chevrier <marc.chevrier@gmail.com>2018-04-24 15:01:01 (GMT)
committerMarc Chevrier <marc.chevrier@gmail.com>2018-06-06 15:22:39 (GMT)
commitc1f5a44b28047cde74e2fb10e8d68e314272f699 (patch)
tree6124b73331c13c92480b5352045686758d3df86f
parent8e28d2630a60475dad715162a1802d301ada35bd (diff)
downloadCMake-c1f5a44b28047cde74e2fb10e8d68e314272f699.zip
CMake-c1f5a44b28047cde74e2fb10e8d68e314272f699.tar.gz
CMake-c1f5a44b28047cde74e2fb10e8d68e314272f699.tar.bz2
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
-rw-r--r--Help/command/OPTIONS_SHELL.txt (renamed from Help/command/COMPILE_OPTIONS_SHELL.txt)2
-rw-r--r--Help/command/add_compile_options.rst2
-rw-r--r--Help/command/add_link_options.rst24
-rw-r--r--Help/command/target_compile_options.rst2
-rw-r--r--Help/command/target_link_libraries.rst3
-rw-r--r--Help/command/target_link_options.rst40
-rw-r--r--Help/manual/cmake-commands.7.rst2
-rw-r--r--Help/manual/cmake-properties.7.rst3
-rw-r--r--Help/prop_dir/LINK_OPTIONS.rst16
-rw-r--r--Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst9
-rw-r--r--Help/prop_tgt/LINK_FLAGS.rst8
-rw-r--r--Help/prop_tgt/LINK_FLAGS_CONFIG.rst4
-rw-r--r--Help/prop_tgt/LINK_OPTIONS.rst21
-rw-r--r--Help/release/dev/LINK_OPTIONS.rst11
-rw-r--r--Source/CMakeLists.txt4
-rw-r--r--Source/cmAddLinkOptionsCommand.cxx20
-rw-r--r--Source/cmAddLinkOptionsCommand.h31
-rw-r--r--Source/cmCommands.cxx5
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx6
-rw-r--r--Source/cmExportBuildFileGenerator.cxx3
-rw-r--r--Source/cmExportInstallFileGenerator.cxx3
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h3
-rw-r--r--Source/cmGeneratorTarget.cxx81
-rw-r--r--Source/cmGeneratorTarget.h6
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx4
-rw-r--r--Source/cmLocalGenerator.cxx8
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx7
-rw-r--r--Source/cmMakefile.cxx15
-rw-r--r--Source/cmMakefile.h3
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx4
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx8
-rw-r--r--Source/cmMakefileTargetGenerator.cxx8
-rw-r--r--Source/cmMakefileTargetGenerator.h2
-rw-r--r--Source/cmState.cxx2
-rw-r--r--Source/cmStateDirectory.cxx52
-rw-r--r--Source/cmStateDirectory.h7
-rw-r--r--Source/cmStatePrivate.h4
-rw-r--r--Source/cmStateSnapshot.cxx7
-rw-r--r--Source/cmTarget.cxx77
-rw-r--r--Source/cmTarget.h6
-rw-r--r--Source/cmTargetLinkOptionsCommand.cxx41
-rw-r--r--Source/cmTargetLinkOptionsCommand.h41
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx5
-rw-r--r--Tests/CMakeCommands/add_link_options/CMakeLists.txt20
-rw-r--r--Tests/CMakeCommands/add_link_options/LinkOptionsExe.c4
-rw-r--r--Tests/CMakeCommands/target_link_options/CMakeLists.txt19
-rw-r--r--Tests/CMakeCommands/target_link_options/LinkOptionsLib.c7
-rw-r--r--Tests/CMakeLists.txt3
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt10
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt5
-rw-r--r--Tests/ExportImport/Import/A/imp_testLinkOptions.cpp8
-rw-r--r--Tests/RunCMake/AndroidMK/AndroidMK.cmake6
-rw-r--r--Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt8
-rw-r--r--Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt8
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/add_link_options/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake7
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake7
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake7
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS.cmake17
-rw-r--r--Tests/RunCMake/add_link_options/LinkOptionsExe.c4
-rw-r--r--Tests/RunCMake/add_link_options/LinkOptionsLib.c7
-rw-r--r--Tests/RunCMake/add_link_options/RunCMakeTest.cmake28
-rw-r--r--Tests/RunCMake/set_property/LINK_OPTIONS-stdout.txt2
-rw-r--r--Tests/RunCMake/set_property/LINK_OPTIONS.cmake3
-rw-r--r--Tests/RunCMake/set_property/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/target_link_options/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-check.cmake7
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-check.cmake7
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-check.cmake7
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-check.cmake7
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake39
-rw-r--r--Tests/RunCMake/target_link_options/LinkOptionsExe.c4
-rw-r--r--Tests/RunCMake/target_link_options/LinkOptionsLib.c7
-rw-r--r--Tests/RunCMake/target_link_options/RunCMakeTest.cmake62
84 files changed, 921 insertions, 34 deletions
diff --git a/Help/command/COMPILE_OPTIONS_SHELL.txt b/Help/command/OPTIONS_SHELL.txt
index a1316c8..530c012 100644
--- a/Help/command/COMPILE_OPTIONS_SHELL.txt
+++ b/Help/command/OPTIONS_SHELL.txt
@@ -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
diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst
index c445608..350a1c0 100644
--- a/Help/command/add_compile_options.rst
+++ b/Help/command/add_compile_options.rst
@@ -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
diff --git a/Help/command/add_link_options.rst b/Help/command/add_link_options.rst
new file mode 100644
index 0000000..c827d70
--- /dev/null
+++ b/Help/command/add_link_options.rst
@@ -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
diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst
index 194d008..88b7f15 100644
--- a/Help/command/target_compile_options.rst
+++ b/Help/command/target_compile_options.rst
@@ -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
diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst
index 6379730..edf38cf 100644
--- a/Help/command/target_link_libraries.rst
+++ b/Help/command/target_link_libraries.rst
@@ -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.
diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst
new file mode 100644
index 0000000..489f981
--- /dev/null
+++ b/Help/command/target_link_options.rst
@@ -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
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 408a3a0..753647d 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -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
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 9f9c53f..db900e8 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -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
diff --git a/Help/prop_dir/LINK_OPTIONS.rst b/Help/prop_dir/LINK_OPTIONS.rst
new file mode 100644
index 0000000..04b9e08
--- /dev/null
+++ b/Help/prop_dir/LINK_OPTIONS.rst
@@ -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.
diff --git a/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
new file mode 100644
index 0000000..c293b98
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
@@ -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
diff --git a/Help/prop_tgt/LINK_FLAGS.rst b/Help/prop_tgt/LINK_FLAGS.rst
index b09e7c1..e0b72b5 100644
--- a/Help/prop_tgt/LINK_FLAGS.rst
+++ b/Help/prop_tgt/LINK_FLAGS.rst
@@ -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.
diff --git a/Help/prop_tgt/LINK_FLAGS_CONFIG.rst b/Help/prop_tgt/LINK_FLAGS_CONFIG.rst
index ba7adc8..1f2910b 100644
--- a/Help/prop_tgt/LINK_FLAGS_CONFIG.rst
+++ b/Help/prop_tgt/LINK_FLAGS_CONFIG.rst
@@ -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.
diff --git a/Help/prop_tgt/LINK_OPTIONS.rst b/Help/prop_tgt/LINK_OPTIONS.rst
new file mode 100644
index 0000000..c5263a2
--- /dev/null
+++ b/Help/prop_tgt/LINK_OPTIONS.rst
@@ -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.
diff --git a/Help/release/dev/LINK_OPTIONS.rst b/Help/release/dev/LINK_OPTIONS.rst
new file mode 100644
index 0000000..87e7c40
--- /dev/null
+++ b/Help/release/dev/LINK_OPTIONS.rst
@@ -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
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 30bef74..6623ba4 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -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
diff --git a/Source/cmAddLinkOptionsCommand.cxx b/Source/cmAddLinkOptionsCommand.cxx
new file mode 100644
index 0000000..10ebd12
--- /dev/null
+++ b/Source/cmAddLinkOptionsCommand.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;
+}
diff --git a/Source/cmAddLinkOptionsCommand.h b/Source/cmAddLinkOptionsCommand.h
new file mode 100644
index 0000000..30fff00
--- /dev/null
+++ b/Source/cmAddLinkOptionsCommand.h
@@ -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
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index dc9318e..15fbd40 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -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);
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index 0ceac85..bb370c4 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -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";
}
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 47636cd..9f2e01d 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -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);
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 02686f3..1db76ac 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -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)) {
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index a3a8f69..cfe31f1 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -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)
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index b223c5e..f5418a5 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -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()) {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 2132b15..aa36823 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -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;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 47741f9..b461598 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -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.
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a3f4a8f..072b958 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -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;
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 3460289..4b0b66d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -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);
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 3c7a4cf..a9b0b78 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -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.
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index a7c8df5..616a37f 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -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
{
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 9ffffc2..82f4683 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -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(
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 8a08789..036acc7 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -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 =
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 8cbddd9..08fcd8f 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -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()
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 4e6849a..4d1c9ec 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -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();
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index a57be4d..dcf6ea0 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -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();
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 85e6366..6eac8e2 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -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) {
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index 79bb369..bc96cc9 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -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,
diff --git a/Source/cmStatePrivate.h b/Source/cmStatePrivate.h
index f36ee37..7177221 100644
--- a/Source/cmStatePrivate.h
+++ b/Source/cmStatePrivate.h
@@ -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;
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 8f5f58c..ec428a6 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -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");
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 1868816..1a6e1d1 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -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;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 3abb47e..5f0b33c 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -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;
diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx
new file mode 100644
index 0000000..f0f13fd
--- /dev/null
+++ b/Source/cmTargetLinkOptionsCommand.cxx
@@ -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.
+}
diff --git a/Source/cmTargetLinkOptionsCommand.h b/Source/cmTargetLinkOptionsCommand.h
new file mode 100644
index 0000000..a1fc9fc
--- /dev/null
+++ b/Source/cmTargetLinkOptionsCommand.h
@@ -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
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 1768c57..549c8af 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -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) {
diff --git a/Tests/CMakeCommands/add_link_options/CMakeLists.txt b/Tests/CMakeCommands/add_link_options/CMakeLists.txt
new file mode 100644
index 0000000..bb7dcbb
--- /dev/null
+++ b/Tests/CMakeCommands/add_link_options/CMakeLists.txt
@@ -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()
diff --git a/Tests/CMakeCommands/add_link_options/LinkOptionsExe.c b/Tests/CMakeCommands/add_link_options/LinkOptionsExe.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/CMakeCommands/add_link_options/LinkOptionsExe.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/CMakeCommands/target_link_options/CMakeLists.txt b/Tests/CMakeCommands/target_link_options/CMakeLists.txt
new file mode 100644
index 0000000..c66cd37
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_options/CMakeLists.txt
@@ -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()
diff --git a/Tests/CMakeCommands/target_link_options/LinkOptionsLib.c b/Tests/CMakeCommands/target_link_options/LinkOptionsLib.c
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_options/LinkOptionsLib.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ int flags_lib(void)
+{
+ return 0;
+}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 886e392..aa72d44 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -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)
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 0f1a556..a1c4993 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -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)
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 39a89dc..f8eb721 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -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")
diff --git a/Tests/ExportImport/Import/A/imp_testLinkOptions.cpp b/Tests/ExportImport/Import/A/imp_testLinkOptions.cpp
new file mode 100644
index 0000000..2b18b2e
--- /dev/null
+++ b/Tests/ExportImport/Import/A/imp_testLinkOptions.cpp
@@ -0,0 +1,8 @@
+
+#include "testSharedLibRequired.h"
+
+int foo()
+{
+ TestSharedLibRequired req;
+ return req.foo();
+}
diff --git a/Tests/RunCMake/AndroidMK/AndroidMK.cmake b/Tests/RunCMake/AndroidMK/AndroidMK.cmake
index 3fbb2cf..9137f2b 100644
--- a/Tests/RunCMake/AndroidMK/AndroidMK.cmake
+++ b/Tests/RunCMake/AndroidMK/AndroidMK.cmake
@@ -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)
diff --git a/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt b/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt
index bbf67a5..a0e5044 100644
--- a/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt
+++ b/Tests/RunCMake/AndroidMK/expectedBuildAndroidMK.txt
@@ -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.*
diff --git a/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt b/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt
index 3515fb9..28b1c21 100644
--- a/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt
+++ b/Tests/RunCMake/AndroidMK/expectedInstallAndroidMK.txt
@@ -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.*
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index bb46144..daf3940 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -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)
diff --git a/Tests/RunCMake/add_link_options/CMakeLists.txt b/Tests/RunCMake/add_link_options/CMakeLists.txt
new file mode 100644
index 0000000..14ef56e
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.11)
+
+project(${RunCMake_TEST} LANGUAGES NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
new file mode 100644
index 0000000..4a22d7e
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.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()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-result.txt b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
new file mode 100644
index 0000000..d695761
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
@@ -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()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-result.txt b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
new file mode 100644
index 0000000..eaac8e3
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
@@ -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()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-result.txt b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS.cmake
new file mode 100644
index 0000000..802ff4f
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS.cmake
@@ -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)
diff --git a/Tests/RunCMake/add_link_options/LinkOptionsExe.c b/Tests/RunCMake/add_link_options/LinkOptionsExe.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LinkOptionsExe.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/add_link_options/LinkOptionsLib.c b/Tests/RunCMake/add_link_options/LinkOptionsLib.c
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LinkOptionsLib.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ int flags_lib(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
new file mode 100644
index 0000000..9edff3b
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
@@ -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()
diff --git a/Tests/RunCMake/set_property/LINK_OPTIONS-stdout.txt b/Tests/RunCMake/set_property/LINK_OPTIONS-stdout.txt
new file mode 100644
index 0000000..033792a
--- /dev/null
+++ b/Tests/RunCMake/set_property/LINK_OPTIONS-stdout.txt
@@ -0,0 +1,2 @@
+-- Target LINK_OPTIONS is 'a;b;c;d;;e'
+-- Directory LINK_OPTIONS is 'a;b;c;d;;e'
diff --git a/Tests/RunCMake/set_property/LINK_OPTIONS.cmake b/Tests/RunCMake/set_property/LINK_OPTIONS.cmake
new file mode 100644
index 0000000..6daf41b
--- /dev/null
+++ b/Tests/RunCMake/set_property/LINK_OPTIONS.cmake
@@ -0,0 +1,3 @@
+include(Common.cmake)
+test_target_property(LINK_OPTIONS)
+test_directory_property(LINK_OPTIONS)
diff --git a/Tests/RunCMake/set_property/RunCMakeTest.cmake b/Tests/RunCMake/set_property/RunCMakeTest.cmake
index b966e89..77da703 100644
--- a/Tests/RunCMake/set_property/RunCMakeTest.cmake
+++ b/Tests/RunCMake/set_property/RunCMakeTest.cmake
@@ -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)
diff --git a/Tests/RunCMake/target_link_options/CMakeLists.txt b/Tests/RunCMake/target_link_options/CMakeLists.txt
new file mode 100644
index 0000000..14ef56e
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.11)
+
+project(${RunCMake_TEST} LANGUAGES NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-check.cmake
new file mode 100644
index 0000000..7799506
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-check.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()
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-check.cmake
new file mode 100644
index 0000000..a686de9
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-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/target_link_options/LINK_OPTIONS-exe-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-check.cmake
new file mode 100644
index 0000000..6c5ffdb
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-check.cmake
@@ -0,0 +1,4 @@
+
+if (NOT actual_stdout MATCHES "BADFLAG_INTERFACE")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_INTERFACE'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-check.cmake
new file mode 100644
index 0000000..a686de9
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-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/target_link_options/LINK_OPTIONS-mod-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-check.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-check.cmake
new file mode 100644
index 0000000..a686de9
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-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/target_link_options/LINK_OPTIONS-shared-result.txt b/Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake
new file mode 100644
index 0000000..f17195d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake
@@ -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}>)
diff --git a/Tests/RunCMake/target_link_options/LinkOptionsExe.c b/Tests/RunCMake/target_link_options/LinkOptionsExe.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LinkOptionsExe.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/target_link_options/LinkOptionsLib.c b/Tests/RunCMake/target_link_options/LinkOptionsLib.c
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LinkOptionsLib.c
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ int flags_lib(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
new file mode 100644
index 0000000..81bad94
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
@@ -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()