[Cmake-commits] CMake branch, master, updated. v3.11.3-937-g812eaa4

Kitware Robot kwrobot at kitware.com
Fri Jun 8 09:45:07 EDT 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, master has been updated
       via  812eaa465ca026ff0413f8c78b41edccd7eefdc7 (commit)
       via  e9f2a29fee7fb67d6a3eafa396f4f630795a99ec (commit)
       via  c984bf668bb46aa335c61d54c3fe62ef3fae20a9 (commit)
       via  e446d71d31bfb7f089f2576d8e2a5c93d6ee5312 (commit)
       via  66ea1a3795f76ce921bc48f82ff228bcceed4524 (commit)
       via  c1f5a44b28047cde74e2fb10e8d68e314272f699 (commit)
       via  8e28d2630a60475dad715162a1802d301ada35bd (commit)
      from  4d1a643481e5fb1dd780c18124c1c6bf3d6e0e23 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=812eaa465ca026ff0413f8c78b41edccd7eefdc7
commit 812eaa465ca026ff0413f8c78b41edccd7eefdc7
Merge: e9f2a29 66ea1a3
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Jun 8 13:37:35 2018 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Fri Jun 8 09:37:48 2018 -0400

    Merge topic 'LINK_OPTIONS'
    
    66ea1a3795 LINK_OPTIONS: Add support of "LINKER:" prefix
    c1f5a44b28 LINK_OPTIONS: Add new family of properties
    8e28d2630a Makefile generator: link flags management refactoring
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Acked-by: Alex Turbov <i.zaufi at gmail.com>
    Merge-request: !2033


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e9f2a29fee7fb67d6a3eafa396f4f630795a99ec
commit e9f2a29fee7fb67d6a3eafa396f4f630795a99ec
Merge: 4d1a643 c984bf6
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Jun 8 09:35:10 2018 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Fri Jun 8 09:35:10 2018 -0400

    Merge branch 'release-3.12'


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=66ea1a3795f76ce921bc48f82ff228bcceed4524
commit 66ea1a3795f76ce921bc48f82ff228bcceed4524
Author:     Marc Chevrier <marc.chevrier at gmail.com>
AuthorDate: Mon Apr 30 18:56:25 2018 +0200
Commit:     Marc Chevrier <marc.chevrier at gmail.com>
CommitDate: Wed Jun 6 17:22:41 2018 +0200

    LINK_OPTIONS: Add support of "LINKER:" prefix

diff --git a/Help/command/LINK_OPTIONS_LINKER.txt b/Help/command/LINK_OPTIONS_LINKER.txt
new file mode 100644
index 0000000..76927be
--- /dev/null
+++ b/Help/command/LINK_OPTIONS_LINKER.txt
@@ -0,0 +1,10 @@
+To pass options to the linker tool, each compiler driver has is own syntax.
+The ``LINKER:`` prefix can be used to specify, in a portable way, options
+to pass to the linker tool. The ``LINKER:`` prefix is replaced by the required
+driver option and the rest of the option string defines linker arguments using
+``,`` as separator. These arguments will be formatted according to the
+:variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG` and
+:variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP` variables.
+
+For example, ``"LINKER:-z,defs"`` becomes ``-Xlinker -z -Xlinker defs`` for
+``Clang`` and ``-Wl,-z,defs`` for ``GNU GCC``.
diff --git a/Help/command/add_link_options.rst b/Help/command/add_link_options.rst
index c827d70..821198d 100644
--- a/Help/command/add_link_options.rst
+++ b/Help/command/add_link_options.rst
@@ -7,12 +7,12 @@ 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
+Adds options to the link step 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
+This command can be used to add any options, but alternative commands
 exist to add libraries (:command:`target_link_libraries` or
 :command:`link_libraries`).
 
@@ -21,4 +21,6 @@ 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:: LINK_OPTIONS_LINKER.txt
+
 .. include:: OPTIONS_SHELL.txt
diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst
index 489f981..8f47180 100644
--- a/Help/command/target_link_options.rst
+++ b/Help/command/target_link_options.rst
@@ -29,7 +29,7 @@ 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
+The following arguments specify link options.  Repeated calls for the same
 ``<target>`` append items in the order called.
 
 Arguments to ``target_link_options`` may use "generator expressions"
@@ -37,4 +37,6 @@ 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:: LINK_OPTIONS_LINKER.txt
+
 .. include:: OPTIONS_SHELL.txt
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index edfff6c..fde1aab 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -460,6 +460,8 @@ Variables for Languages
    /variable/CMAKE_LANG_LIBRARY_ARCHITECTURE
    /variable/CMAKE_LANG_LINKER_PREFERENCE
    /variable/CMAKE_LANG_LINKER_PREFERENCE_PROPAGATES
+   /variable/CMAKE_LANG_LINKER_WRAPPER_FLAG
+   /variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP
    /variable/CMAKE_LANG_LINK_EXECUTABLE
    /variable/CMAKE_LANG_OUTPUT_EXTENSION
    /variable/CMAKE_LANG_PLATFORM_ID
diff --git a/Help/release/dev/LINK_OPTIONS.rst b/Help/release/dev/LINK_OPTIONS.rst
index 87e7c40..e40dab2 100644
--- a/Help/release/dev/LINK_OPTIONS.rst
+++ b/Help/release/dev/LINK_OPTIONS.rst
@@ -3,9 +3,9 @@ LINK_OPTIONS
 
 * CMake gained new capabilities to manage link step:
 
-  * :prop_dir:`LINK_OPTIONS` directory property
+  * :prop_dir:`LINK_OPTIONS` directory property.
   * :prop_tgt:`LINK_OPTIONS` and :prop_tgt:`INTERFACE_LINK_OPTIONS` target
-    properties
+    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
+    directory.
+  * :command:`target_link_options` command to add link options to targets.
diff --git a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
new file mode 100644
index 0000000..0e52282
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
@@ -0,0 +1,39 @@
+CMAKE_<LANG>_LINKER_WRAPPER_FLAG
+--------------------------------
+
+Defines the syntax of compiler driver option to pass options to the linker
+tool. It will be used to translate the ``LINKER:`` prefix in the link options
+(see :command:`add_link_options` and :command:`target_link_options`).
+
+This variable holds a :ref:`;-list <CMake Language Lists>` of tokens.
+If a space (i.e. " ") is specified as last token, flag and ``LINKER:``
+arguments will be specified as separate arguments to the compiler driver.
+The :variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP` variable can be specified
+to manage concatenation of arguments.
+
+For example, for ``Clang`` we have:
+
+.. code-block:: cmake
+
+  set (CMAKE_C_LINKER_WRAPPER_FLAG "-Xlinker" " ")
+
+Specifying ``"LINKER:-z defs"`` will be transformed in
+``-Xlinker -z -Xlinker defs``.
+
+For ``GNU GCC``:
+
+.. code-block:: cmake
+
+  set (CMAKE_C_LINKER_WRAPPER_FLAG "-Wl,")
+  set (CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
+
+Specifying ``"LINKER:-z defs"`` will be transformed in ``-Wl,-z,defs``.
+
+And for ``SunPro``:
+
+.. code-block:: cmake
+
+  set (CMAKE_C_LINKER_WRAPPER_FLAG "-Qoption" "ld" " ")
+  set (CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
+
+Specifying ``"LINKER:-z defs"`` will be transformed in ``-Qoption ld -z,defs``.
diff --git a/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
new file mode 100644
index 0000000..faf1481
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
@@ -0,0 +1,9 @@
+CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP
+------------------------------------
+
+This variable is used with :variable:`CMAKE_<LANG>_LINKER_WRAPPER_FLAG`
+variable to format ``LINKER:`` prefix in the link options
+(see :command:`add_link_options` and :command:`target_link_options`).
+
+When specified, arguments of the ``LINKER:`` prefix will be concatenated using
+this value as separator.
diff --git a/Modules/Compiler/ARMCC.cmake b/Modules/Compiler/ARMCC.cmake
index 250a8f4..f949568 100644
--- a/Modules/Compiler/ARMCC.cmake
+++ b/Modules/Compiler/ARMCC.cmake
@@ -34,4 +34,6 @@ macro(__compiler_armcc lang)
   set(CMAKE_${lang}_CREATE_STATIC_LIBRARY  "<CMAKE_AR> --create -cr <TARGET> <LINK_FLAGS> <OBJECTS>")
 
   set(CMAKE_DEPFILE_FLAGS_${lang} "--depend=<DEPFILE> --depend_single_line --no_depend_system_headers")
+
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
 endmacro()
diff --git a/Modules/Compiler/Absoft-Fortran.cmake b/Modules/Compiler/Absoft-Fortran.cmake
index da1fc80..76502dc 100644
--- a/Modules/Compiler/Absoft-Fortran.cmake
+++ b/Modules/Compiler/Absoft-Fortran.cmake
@@ -8,3 +8,4 @@ set(CMAKE_Fortran_MODPATH_FLAG "-p")
 set(CMAKE_Fortran_VERBOSE_FLAG "-v")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree")
+set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-X")
diff --git a/Modules/Compiler/Bruce-C.cmake b/Modules/Compiler/Bruce-C.cmake
index cfabe65..6b64e58 100644
--- a/Modules/Compiler/Bruce-C.cmake
+++ b/Modules/Compiler/Bruce-C.cmake
@@ -5,3 +5,5 @@ string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -g")
 string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -DNDEBUG")
 string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -DNDEBUG")
 string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -g -DNDEBUG")
+
+set(CMAKE_C_LINKER_WRAPPER_FLAG "-X")
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index 7ce1adb..1653b55 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -30,6 +30,8 @@ else()
       set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "--target=")
       set(CMAKE_${lang}_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "--gcc-toolchain=")
     endif()
+    set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
+    set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP)
 
     set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
     set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
diff --git a/Modules/Compiler/G95-Fortran.cmake b/Modules/Compiler/G95-Fortran.cmake
index 2c83fb8..03b7e08 100644
--- a/Modules/Compiler/G95-Fortran.cmake
+++ b/Modules/Compiler/G95-Fortran.cmake
@@ -7,3 +7,5 @@ set(CMAKE_Fortran_MODDIR_FLAG "-fmod=")
 set(CMAKE_Fortran_VERBOSE_FLAG "-v")
 set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
 set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
+set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
+set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index a3ef2bc..9f4c8d1 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -24,6 +24,9 @@ macro(__compiler_gnu lang)
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
   set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "--sysroot=")
 
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
+
   # Older versions of gcc (< 4.5) contain a bug causing them to report a missing
   # header file as a warning if depfiles are enabled, causing check_header_file
   # tests to always succeed.  Work around this by disabling dependency tracking
diff --git a/Modules/Compiler/HP-C.cmake b/Modules/Compiler/HP-C.cmake
index b42ba2b..8fa4c08 100644
--- a/Modules/Compiler/HP-C.cmake
+++ b/Modules/Compiler/HP-C.cmake
@@ -2,3 +2,6 @@ set(CMAKE_C_VERBOSE_FLAG "-v")
 
 set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+
+set(CMAKE_C_LINKER_WRAPPER_FLAG "-Wl,")
+set(CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
diff --git a/Modules/Compiler/HP-CXX.cmake b/Modules/Compiler/HP-CXX.cmake
index 7548754..5726b64 100644
--- a/Modules/Compiler/HP-CXX.cmake
+++ b/Modules/Compiler/HP-CXX.cmake
@@ -3,6 +3,9 @@ set(CMAKE_CXX_VERBOSE_FLAG "-v")
 set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 
+set(CMAKE_CXX_LINKER_WRAPPER_FLAG "-Wl,")
+set(CMAKE_CXX_LINKER_WRAPPER_FLAG_SEP ",")
+
 # HP aCC since version 3.80 supports the flag +hpxstd98 to get ANSI C++98
 # template support. It is known that version 6.25 doesn't need that flag.
 # Current assumption: the flag is needed for every version from 3.80 to 4
diff --git a/Modules/Compiler/HP-Fortran.cmake b/Modules/Compiler/HP-Fortran.cmake
index a6ca2c2..63a0331 100644
--- a/Modules/Compiler/HP-Fortran.cmake
+++ b/Modules/Compiler/HP-Fortran.cmake
@@ -4,3 +4,6 @@ set(CMAKE_Fortran_FORMAT_FREE_FLAG "+source=free")
 
 set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
+
+set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
+set(CMAKE_Fortran_LINKER_WRAPPER_FLAG ",")
diff --git a/Modules/Compiler/PGI.cmake b/Modules/Compiler/PGI.cmake
index d5a57ee..4f8b90b 100644
--- a/Modules/Compiler/PGI.cmake
+++ b/Modules/Compiler/PGI.cmake
@@ -25,6 +25,9 @@ macro(__compiler_pgi lang)
     string(APPEND CMAKE_${lang}_FLAGS_INIT " -Bdynamic")
   endif()
 
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG ",")
+
   set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
   if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le AND (NOT CMAKE_HOST_WIN32 OR CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 16.3))
     set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake
index 0da7050..5cdedeb 100644
--- a/Modules/Compiler/QCC.cmake
+++ b/Modules/Compiler/QCC.cmake
@@ -13,6 +13,9 @@ macro(__compiler_qcc lang)
   set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,")
   set(CMAKE_DEPFILE_FLAGS_${lang} "-Wc,-MD,<DEPFILE>,-MT,<OBJECT>,-MF,<DEPFILE>")
 
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
+
   set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE NO)
   set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
 
diff --git a/Modules/Compiler/SCO.cmake b/Modules/Compiler/SCO.cmake
index c55a048..7f643d9 100644
--- a/Modules/Compiler/SCO.cmake
+++ b/Modules/Compiler/SCO.cmake
@@ -15,4 +15,7 @@ macro(__compiler_sco lang)
   set(CMAKE_${lang}_COMPILE_OPTIONS_DLL -belf)
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-Kpic -belf")
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-belf -Wl,-Bexport")
+
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
 endmacro()
diff --git a/Modules/Compiler/SunPro-C.cmake b/Modules/Compiler/SunPro-C.cmake
index 8d0e6d6..047de43 100644
--- a/Modules/Compiler/SunPro-C.cmake
+++ b/Modules/Compiler/SunPro-C.cmake
@@ -29,6 +29,9 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
   set(CMAKE_${type}_LINK_DYNAMIC_C_FLAGS "-Bdynamic")
 endforeach()
 
+set(CMAKE_C_LINKER_WRAPPER_FLAG "-Qoption" "ld" " ")
+set(CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
+
 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 5.13)
   set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c89")
   set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=c89")
diff --git a/Modules/Compiler/SunPro-CXX.cmake b/Modules/Compiler/SunPro-CXX.cmake
index 14196b7..4c1ac5b 100644
--- a/Modules/Compiler/SunPro-CXX.cmake
+++ b/Modules/Compiler/SunPro-CXX.cmake
@@ -29,6 +29,9 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
   set(CMAKE_${type}_LINK_DYNAMIC_CXX_FLAGS "-Bdynamic")
 endforeach()
 
+set(CMAKE_CXX_LINKER_WRAPPER_FLAG "-Qoption" "ld" " ")
+set(CMAKE_CXX_LINKER_WRAPPER_FLAG_SEP ",")
+
 set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
 set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
 
diff --git a/Modules/Compiler/SunPro-Fortran.cmake b/Modules/Compiler/SunPro-Fortran.cmake
index 9b25c0b..2247dd0 100644
--- a/Modules/Compiler/SunPro-Fortran.cmake
+++ b/Modules/Compiler/SunPro-Fortran.cmake
@@ -18,6 +18,9 @@ string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO_INIT " -g -xO2 -DNDEBUG")
 set(CMAKE_Fortran_MODDIR_FLAG "-moddir=")
 set(CMAKE_Fortran_MODPATH_FLAG "-M")
 
+set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Qoption" "ld" " ")
+set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")
+
 set(CMAKE_Fortran_PREPROCESS_SOURCE
   "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -F -fpp <SOURCE> -o <PREPROCESSED_SOURCE>")
 
diff --git a/Modules/Compiler/TinyCC-C.cmake b/Modules/Compiler/TinyCC-C.cmake
index fbd2841..6367695 100644
--- a/Modules/Compiler/TinyCC-C.cmake
+++ b/Modules/Compiler/TinyCC-C.cmake
@@ -6,3 +6,6 @@ string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -g")
 string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -DNDEBUG")
 string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -DNDEBUG")
 string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -g -DNDEBUG")
+
+set(CMAKE_C_LINKER_WRAPPER_FLAG "-Wl,")
+set(CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake
index 3361f8f..a1d7ca1 100644
--- a/Modules/Compiler/XL.cmake
+++ b/Modules/Compiler/XL.cmake
@@ -23,6 +23,9 @@ macro(__compiler_xl lang)
   set(CMAKE_${lang}_RESPONSE_FILE_FLAG "-qoptfile=")
   set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-qoptfile=")
 
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
+
   string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g")
   string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O")
   string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -O")
diff --git a/Modules/Platform/Apple-Intel.cmake b/Modules/Platform/Apple-Intel.cmake
index 2d4f7e5..a854be9 100644
--- a/Modules/Platform/Apple-Intel.cmake
+++ b/Modules/Platform/Apple-Intel.cmake
@@ -10,6 +10,9 @@ macro(__apple_compiler_intel lang)
   set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names")
   set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names")
 
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
+
   if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0)
     set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
   endif()
diff --git a/Modules/Platform/Generic-ADSP-C.cmake b/Modules/Platform/Generic-ADSP-C.cmake
index de1cee2..c8597cd 100644
--- a/Modules/Platform/Generic-ADSP-C.cmake
+++ b/Modules/Platform/Generic-ADSP-C.cmake
@@ -9,6 +9,9 @@ string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " ")
 string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " ")
 string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " ")
 
+set(CMAKE_C_LINKER_WRAPPER_FLAG "-flags-link" " ")
+set(CMAKE_C_LINKER_WRAPPER_FLAG_SEP ",")
+
 set(CMAKE_C_CREATE_STATIC_LIBRARY
     "<CMAKE_C_COMPILER> -build-lib -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -o <TARGET> <CMAKE_C_LINK_FLAGS> <OBJECTS>")
 
@@ -17,4 +20,3 @@ set(CMAKE_C_LINK_EXECUTABLE
 
 set(CMAKE_C_CREATE_SHARED_LIBRARY)
 set(CMAKE_C_CREATE_MODULE_LIBRARY)
-
diff --git a/Modules/Platform/Generic-ADSP-CXX.cmake b/Modules/Platform/Generic-ADSP-CXX.cmake
index 0cde8f2..d76bb66 100644
--- a/Modules/Platform/Generic-ADSP-CXX.cmake
+++ b/Modules/Platform/Generic-ADSP-CXX.cmake
@@ -7,6 +7,9 @@ string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " ")
 string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " ")
 string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " ")
 
+set(CMAKE_CXX_LINKER_WRAPPER_FLAG "-flags-link" " ")
+set(CMAKE_CXX_LINKER_WRAPPER_FLAG_SEP ",")
+
 set(CMAKE_CXX_CREATE_STATIC_LIBRARY
      "<CMAKE_CXX_COMPILER> -build-lib -proc ${ADSP_PROCESSOR} -si-revision ${ADSP_PROCESSOR_SILICIUM_REVISION} -o <TARGET> <CMAKE_CXX_LINK_FLAGS> <OBJECTS>")
 
@@ -15,4 +18,3 @@ set(CMAKE_CXX_LINK_EXECUTABLE
 
 set(CMAKE_CXX_CREATE_SHARED_LIBRARY)
 set(CMAKE_CXX_CREATE_MODULE_LIBRARY)
-
diff --git a/Modules/Platform/Generic-SDCC-C.cmake b/Modules/Platform/Generic-SDCC-C.cmake
index 4b3912a..aef4abf 100644
--- a/Modules/Platform/Generic-SDCC-C.cmake
+++ b/Modules/Platform/Generic-SDCC-C.cmake
@@ -37,6 +37,8 @@ if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_INIT)
   set (CMAKE_EXE_LINKER_FLAGS_INIT --model-small)
 endif()
 
+set(CMAKE_C_LINKER_WRAPPER_FLAG "-Wl" ",")
+
 # compile a C file into an object file
 set(CMAKE_C_COMPILE_OBJECT  "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
 
@@ -51,4 +53,3 @@ set(CMAKE_C_CREATE_STATIC_LIBRARY
 # not supported by sdcc
 set(CMAKE_C_CREATE_SHARED_LIBRARY "")
 set(CMAKE_C_CREATE_MODULE_LIBRARY "")
-
diff --git a/Modules/Platform/Linux-Intel.cmake b/Modules/Platform/Linux-Intel.cmake
index ee9aac2..f712e2b 100644
--- a/Modules/Platform/Linux-Intel.cmake
+++ b/Modules/Platform/Linux-Intel.cmake
@@ -30,6 +30,9 @@ macro(__linux_compiler_intel lang)
   # executables that use dlopen but do not set ENABLE_EXPORTS.
   set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-rdynamic")
 
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
+  set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
+
   set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
 
   if(XIAR)
diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake
index f8e1c9e..48b936e 100644
--- a/Modules/Platform/Windows-Embarcadero.cmake
+++ b/Modules/Platform/Windows-Embarcadero.cmake
@@ -76,6 +76,8 @@ macro(__embarcadero_language lang)
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "${_tD}") # ... while this is a space separated string.
   set(CMAKE_${lang}_USE_RESPONSE_FILE_FOR_INCLUDES 1)
 
+  set (CMAKE_${lang}_LINKER_WRAPPER_FLAG "-l")
+
   # compile a source file into an object file
   # place <DEFINES> outside the response file because Borland refuses
   # to parse quotes from the response file.
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index f5418a5..41e55a5 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -2861,7 +2861,8 @@ void cmGeneratorTarget::GetCompileDefinitions(
   cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
 }
 
-static void processLinkOptions(
+namespace {
+void processLinkOptions(
   cmGeneratorTarget const* tgt,
   const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
   std::vector<std::string>& options,
@@ -2873,6 +2874,7 @@ static void processLinkOptions(
                          config, debugOptions, "link options", language,
                          OptionsParse::Shell);
 }
+}
 
 void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
                                        const std::string& config,
@@ -2912,6 +2914,98 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
                      language);
 
   cmDeleteAll(linkInterfaceLinkOptionsEntries);
+
+  // Last step: replace "LINKER:" prefixed elements by
+  // actual linker wrapper
+  const std::string wrapper(this->Makefile->GetSafeDefinition(
+    "CMAKE_" + language + "_LINKER_WRAPPER_FLAG"));
+  std::vector<std::string> wrapperFlag;
+  cmSystemTools::ExpandListArgument(wrapper, wrapperFlag);
+  const std::string wrapperSep(this->Makefile->GetSafeDefinition(
+    "CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP"));
+  bool concatFlagAndArgs = true;
+  if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
+    concatFlagAndArgs = false;
+    wrapperFlag.pop_back();
+  }
+
+  const std::string LINKER{ "LINKER:" };
+  const std::string SHELL{ "SHELL:" };
+  const std::string LINKER_SHELL = LINKER + SHELL;
+
+  std::vector<std::string>::iterator entry;
+  while ((entry = std::find_if(result.begin(), result.end(),
+                               [&LINKER](const std::string& item) -> bool {
+                                 return item.compare(0, LINKER.length(),
+                                                     LINKER) == 0;
+                               })) != result.end()) {
+    std::vector<std::string> linkerOptions;
+    if (entry->compare(0, LINKER_SHELL.length(), LINKER_SHELL) == 0) {
+      cmSystemTools::ParseUnixCommandLine(
+        entry->c_str() + LINKER_SHELL.length(), linkerOptions);
+    } else {
+      linkerOptions =
+        cmSystemTools::tokenize(entry->substr(LINKER.length()), ",");
+    }
+    entry = result.erase(entry);
+
+    if (linkerOptions.empty() ||
+        (linkerOptions.size() == 1 && linkerOptions.front().empty())) {
+      continue;
+    }
+
+    // for now, raise an error if prefix SHELL: is part of arguments
+    if (std::find_if(linkerOptions.begin(), linkerOptions.end(),
+                     [&SHELL](const std::string& item) -> bool {
+                       return item.find(SHELL) != std::string::npos;
+                     }) != linkerOptions.end()) {
+      this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+        cmake::FATAL_ERROR,
+        "'SHELL:' prefix is not supported as part of 'LINKER:' arguments.",
+        this->GetBacktrace());
+      return;
+    }
+
+    if (wrapperFlag.empty()) {
+      // nothing specified, insert elements as is
+      result.insert(entry, linkerOptions.begin(), linkerOptions.end());
+    } else {
+      std::vector<std::string> options;
+
+      if (!wrapperSep.empty()) {
+        if (concatFlagAndArgs) {
+          // insert flag elements except last one
+          options.insert(options.end(), wrapperFlag.begin(),
+                         wrapperFlag.end() - 1);
+          // concatenate last flag element and all LINKER list values
+          // in one option
+          options.push_back(wrapperFlag.back() +
+                            cmJoin(linkerOptions, wrapperSep));
+        } else {
+          options.insert(options.end(), wrapperFlag.begin(),
+                         wrapperFlag.end());
+          // concatenate all LINKER list values in one option
+          options.push_back(cmJoin(linkerOptions, wrapperSep));
+        }
+      } else {
+        // prefix each element of LINKER list with wrapper
+        if (concatFlagAndArgs) {
+          std::transform(
+            linkerOptions.begin(), linkerOptions.end(), linkerOptions.begin(),
+            [&wrapperFlag](const std::string& value) -> std::string {
+              return wrapperFlag.back() + value;
+            });
+        }
+        for (const auto& value : linkerOptions) {
+          options.insert(options.end(), wrapperFlag.begin(),
+                         concatFlagAndArgs ? wrapperFlag.end() - 1
+                                           : wrapperFlag.end());
+          options.push_back(value);
+        }
+      }
+      result.insert(entry, options.begin(), options.end());
+    }
+  }
 }
 
 void cmGeneratorTarget::ComputeTargetManifest(const std::string& config) const
diff --git a/Tests/RunCMake/add_link_options/LINKER_SHELL_expansion-build-check.cmake b/Tests/RunCMake/add_link_options/LINKER_SHELL_expansion-build-check.cmake
new file mode 100644
index 0000000..d0ef8de
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINKER_SHELL_expansion-build-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/LINKER_SHELL_expansion.cmake b/Tests/RunCMake/add_link_options/LINKER_SHELL_expansion.cmake
new file mode 100644
index 0000000..7316ef5
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINKER_SHELL_expansion.cmake
@@ -0,0 +1,4 @@
+
+set (LINKER_OPTION "LINKER:SHELL:-foo bar")
+
+include ("LINKER_expansion-list.cmake")
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion-build-check.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion-build-check.cmake
new file mode 100644
index 0000000..d0ef8de
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion-build-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake
new file mode 100644
index 0000000..34dcc67
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake
@@ -0,0 +1,36 @@
+
+enable_language(C)
+
+add_executable(dump dump.c)
+
+add_link_options("${LINKER_OPTION}")
+
+# ensure no temp file will be used
+string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+
+add_library(example SHARED LinkOptionsLib.c)
+# use LAUNCH facility to dump linker command
+set_property(TARGET example PROPERTY RULE_LAUNCH_LINK "\"${CMAKE_CURRENT_BINARY_DIR}/dump${CMAKE_EXECUTABLE_SUFFIX}\"")
+
+add_dependencies (example dump)
+
+# generate reference for LINKER flag
+if (CMAKE_C_LINKER_WRAPPER_FLAG)
+  set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
+  list(GET linker_flag -1 linker_space)
+  if (linker_space STREQUAL " ")
+    list(REMOVE_AT linker_flag -1)
+  else()
+    set(linker_space)
+  endif()
+  list (JOIN linker_flag " " linker_flag)
+  if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
+    string (APPEND  linker_flag "${linker_space}" "-foo${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}bar")
+  else()
+    set (linker_flag "${linker_flag}${linker_space}-foo ${linker_flag}${linker_space}bar")
+  endif()
+else()
+  set(linker_flag "-foo bar")
+endif()
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
new file mode 100644
index 0000000..bebd6c7
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
@@ -0,0 +1,15 @@
+
+if (actual_stdout MATCHES "(LINKER|SHELL):")
+  set (RunCMake_TEST_FAILED "LINKER: prefix was not expanded.")
+  return()
+endif()
+
+if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/LINKER.txt")
+  set (RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/LINKER.txt: Reference file not found.")
+  return()
+endif()
+file(READ "${RunCMake_TEST_BINARY_DIR}/LINKER.txt" linker_flag)
+
+if (NOT actual_stdout MATCHES "${linker_flag}")
+  set (RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
+endif()
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion.cmake
new file mode 100644
index 0000000..42b286d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion.cmake
@@ -0,0 +1,4 @@
+
+set (LINKER_OPTION "LINKER:-foo,bar")
+
+include ("LINKER_expansion-list.cmake")
diff --git a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
index 9edff3b..4f5df72 100644
--- a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
@@ -26,3 +26,13 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
   unset(RunCMake_TEST_OPTIONS)
   unset(RunCMake_TEST_OUTPUT_MERGE)
 endif()
+
+run_cmake(bad_SHELL_usage)
+
+if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)")
+  run_cmake(LINKER_expansion)
+  run_cmake_target(LINKER_expansion build all)
+
+  run_cmake(LINKER_SHELL_expansion)
+  run_cmake_target(LINKER_SHELL_expansion build all)
+endif()
diff --git a/Tests/RunCMake/add_link_options/bad_SHELL_usage-result.txt b/Tests/RunCMake/add_link_options/bad_SHELL_usage-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/bad_SHELL_usage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/add_link_options/bad_SHELL_usage-stderr.txt b/Tests/RunCMake/add_link_options/bad_SHELL_usage-stderr.txt
new file mode 100644
index 0000000..02d09f3
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/bad_SHELL_usage-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at bad_SHELL_usage.cmake:6 \(add_library\):
+  'SHELL:' prefix is not supported as part of 'LINKER:' arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:5 \(include\)
diff --git a/Tests/RunCMake/add_link_options/bad_SHELL_usage.cmake b/Tests/RunCMake/add_link_options/bad_SHELL_usage.cmake
new file mode 100644
index 0000000..324893d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/bad_SHELL_usage.cmake
@@ -0,0 +1,6 @@
+
+enable_language(C)
+
+add_link_options("LINKER:-foo,SHELL:-bar")
+
+add_library(example SHARED LinkOptionsLib.c)
diff --git a/Tests/RunCMake/add_link_options/dump.c b/Tests/RunCMake/add_link_options/dump.c
new file mode 100644
index 0000000..8baa313
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/dump.c
@@ -0,0 +1,13 @@
+
+#include "stdio.h"
+
+int main(int argc, char* argv[])
+{
+  int i;
+
+  for (i = 1; i < argc; i++)
+    printf("%s ", argv[i]);
+  printf("\n");
+
+  return 0;
+}
diff --git a/Tests/RunCMake/target_link_options/LINKER_expansion-LINKER-check.cmake b/Tests/RunCMake/target_link_options/LINKER_expansion-LINKER-check.cmake
new file mode 100644
index 0000000..d0ef8de
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINKER_expansion-LINKER-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/LINKER_expansion-LINKER_SHELL-check.cmake b/Tests/RunCMake/target_link_options/LINKER_expansion-LINKER_SHELL-check.cmake
new file mode 100644
index 0000000..d0ef8de
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINKER_expansion-LINKER_SHELL-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/LINKER_expansion-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/LINKER_expansion-validation.cmake b/Tests/RunCMake/target_link_options/LINKER_expansion-validation.cmake
new file mode 100644
index 0000000..1af8f13
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINKER_expansion-validation.cmake
@@ -0,0 +1,15 @@
+
+if (actual_stdout MATCHES "LINKER:")
+  set (RunCMake_TEST_FAILED "LINKER: prefix was not expanded.")
+  return()
+endif()
+
+if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/LINKER.txt")
+  set (RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/LINKER.txt: Reference file not found.")
+  return()
+endif()
+file(READ "${RunCMake_TEST_BINARY_DIR}/LINKER.txt" linker_flag)
+
+if (NOT actual_stdout MATCHES "${linker_flag}")
+  set (RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/LINKER_expansion.cmake b/Tests/RunCMake/target_link_options/LINKER_expansion.cmake
new file mode 100644
index 0000000..b344867
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/LINKER_expansion.cmake
@@ -0,0 +1,49 @@
+
+enable_language(C)
+
+add_executable(dump dump.c)
+
+# ensure no temp file will be used
+string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
+
+
+# Use LINKER alone
+add_library(linker SHARED LinkOptionsLib.c)
+target_link_options(linker PRIVATE "LINKER:-foo,bar")
+
+# use LAUNCH facility to dump linker command
+set_property(TARGET linker PROPERTY RULE_LAUNCH_LINK "\"${CMAKE_CURRENT_BINARY_DIR}/dump${CMAKE_EXECUTABLE_SUFFIX}\"")
+
+add_dependencies (linker dump)
+
+
+# Use LINKER with SHELL
+add_library(linker_shell SHARED LinkOptionsLib.c)
+target_link_options(linker_shell PRIVATE "LINKER:SHELL:-foo bar")
+
+# use LAUNCH facility to dump linker command
+set_property(TARGET linker_shell PROPERTY RULE_LAUNCH_LINK "\"${CMAKE_CURRENT_BINARY_DIR}/dump${CMAKE_EXECUTABLE_SUFFIX}\"")
+
+add_dependencies (linker_shell dump)
+
+
+# generate reference for LINKER flag
+if (CMAKE_C_LINKER_WRAPPER_FLAG)
+  set(linker_flag ${CMAKE_C_LINKER_WRAPPER_FLAG})
+  list(GET linker_flag -1 linker_space)
+  if (linker_space STREQUAL " ")
+    list(REMOVE_AT linker_flag -1)
+  else()
+    set(linker_space)
+  endif()
+  list (JOIN linker_flag " " linker_flag)
+  if (CMAKE_C_LINKER_WRAPPER_FLAG_SEP)
+    string (APPEND  linker_flag "${linker_space}" "-foo${CMAKE_C_LINKER_WRAPPER_FLAG_SEP}bar")
+  else()
+    set (linker_flag "${linker_flag}${linker_space}-foo ${linker_flag}${linker_space}bar")
+  endif()
+else()
+  set(linker_flag "-foo bar")
+endif()
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/LINKER.txt" "${linker_flag}")
diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
index 81bad94..121a0ce 100644
--- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
@@ -29,34 +29,11 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
   unset(RunCMake_TEST_OUTPUT_MERGE)
 endif()
 
+run_cmake(bad_SHELL_usage)
 
-# include(RunCMake)
+if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)")
+  run_cmake(LINKER_expansion)
 
-# 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()
+  run_cmake_target(LINKER_expansion LINKER linker)
+  run_cmake_target(LINKER_expansion LINKER_SHELL linker_shell)
+endif()
diff --git a/Tests/RunCMake/target_link_options/bad_SHELL_usage-result.txt b/Tests/RunCMake/target_link_options/bad_SHELL_usage-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/bad_SHELL_usage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_link_options/bad_SHELL_usage-stderr.txt b/Tests/RunCMake/target_link_options/bad_SHELL_usage-stderr.txt
new file mode 100644
index 0000000..bffd80a
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/bad_SHELL_usage-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at bad_SHELL_usage.cmake:4 \(add_library\):
+  'SHELL:' prefix is not supported as part of 'LINKER:' arguments.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:5 \(include\)
diff --git a/Tests/RunCMake/target_link_options/bad_SHELL_usage.cmake b/Tests/RunCMake/target_link_options/bad_SHELL_usage.cmake
new file mode 100644
index 0000000..b0adf19
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/bad_SHELL_usage.cmake
@@ -0,0 +1,5 @@
+
+enable_language(C)
+
+add_library(example SHARED LinkOptionsLib.c)
+target_link_options(example PRIVATE "LINKER:-foo,SHELL:-bar")
diff --git a/Tests/RunCMake/target_link_options/dump.c b/Tests/RunCMake/target_link_options/dump.c
new file mode 100644
index 0000000..8baa313
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/dump.c
@@ -0,0 +1,13 @@
+
+#include "stdio.h"
+
+int main(int argc, char* argv[])
+{
+  int i;
+
+  for (i = 1; i < argc; i++)
+    printf("%s ", argv[i]);
+  printf("\n");
+
+  return 0;
+}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c1f5a44b28047cde74e2fb10e8d68e314272f699
commit c1f5a44b28047cde74e2fb10e8d68e314272f699
Author:     Marc Chevrier <marc.chevrier at gmail.com>
AuthorDate: Tue Apr 24 17:01:01 2018 +0200
Commit:     Marc Chevrier <marc.chevrier at gmail.com>
CommitDate: Wed Jun 6 17:22:39 2018 +0200

    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

diff --git a/Help/command/COMPILE_OPTIONS_SHELL.txt b/Help/command/OPTIONS_SHELL.txt
similarity index 88%
rename from Help/command/COMPILE_OPTIONS_SHELL.txt
rename to 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_compile_options.rst b/Help/command/target_link_options.rst
similarity index 56%
copy from Help/command/target_compile_options.rst
copy to Help/command/target_link_options.rst
index 194d008..489f981 100644
--- a/Help/command/target_compile_options.rst
+++ b/Help/command/target_link_options.rst
@@ -1,15 +1,15 @@
-target_compile_options
-----------------------
+target_link_options
+-------------------
 
-Add compile options to a target.
+Add link options to a target.
 
 ::
 
-  target_compile_options(<target> [BEFORE]
+  target_link_options(<target> [BEFORE]
     <INTERFACE|PUBLIC|PRIVATE> [items1...]
     [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
 
-Specify compile options to use when compiling a given target.  The
+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>`.
@@ -18,25 +18,23 @@ 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 preprocessor definitions
-(:command:`target_compile_definitions` and :command:`add_compile_definitions`)
-or include directories (:command:`target_include_directories` and
-:command:`include_directories`).  See documentation of the
-:prop_dir:`directory <COMPILE_OPTIONS>` and
-:prop_tgt:`target <COMPILE_OPTIONS>` ``COMPILE_OPTIONS`` properties.
+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:`COMPILE_OPTIONS` property of
+items will populate the :prop_tgt:`LINK_OPTIONS` property of
 ``<target>``.  ``PUBLIC`` and ``INTERFACE`` items will populate the
-:prop_tgt:`INTERFACE_COMPILE_OPTIONS` property of ``<target>``.
+: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_compile_options`` may use "generator expressions"
+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:: COMPILE_OPTIONS_SHELL.txt
+.. 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()

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8e28d2630a60475dad715162a1802d301ada35bd
commit 8e28d2630a60475dad715162a1802d301ada35bd
Author:     Marc Chevrier <marc.chevrier at gmail.com>
AuthorDate: Thu Apr 26 10:11:50 2018 +0200
Commit:     Marc Chevrier <marc.chevrier at gmail.com>
CommitDate: Wed Jun 6 17:02:33 2018 +0200

    Makefile generator: link flags management refactoring

diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 1e59f44..9ffffc2 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -154,12 +154,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
                                              linkLanguage, this->ConfigName);
 
   // Add target-specific linker flags.
-  this->LocalGenerator->AppendFlags(
-    linkFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-  std::string linkFlagsConfig = "LINK_FLAGS_";
-  linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
-  this->LocalGenerator->AppendFlags(
-    linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
+  this->GetTargetLinkFlags(linkFlags);
 
   // Construct a list of files associated with this executable that
   // may need to be cleaned.
@@ -437,12 +432,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
                                              linkLanguage, this->ConfigName);
 
   // Add target-specific linker flags.
-  this->LocalGenerator->AppendFlags(
-    linkFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-  std::string linkFlagsConfig = "LINK_FLAGS_";
-  linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
-  this->LocalGenerator->AppendFlags(
-    linkFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
+  this->GetTargetLinkFlags(linkFlags);
 
   {
     std::unique_ptr<cmLinkLineComputer> linkLineComputer(
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index c538992..8a08789 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -137,10 +137,7 @@ void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
     this->GeneratorTarget->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS");
   if (hasCUDA && resolveDeviceSymbols) {
     std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
-    std::string extraFlags;
-    this->LocalGenerator->AppendFlags(
-      extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-    this->WriteDeviceLibraryRules(linkRuleVar, extraFlags, false);
+    this->WriteDeviceLibraryRules(linkRuleVar, false);
   }
 
   std::string linkLanguage =
@@ -173,10 +170,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
                  cuda_lang) != closure->Languages.end());
     if (hasCUDA) {
       std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
-      std::string extraFlags;
-      this->LocalGenerator->AppendFlags(
-        extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-      this->WriteDeviceLibraryRules(linkRuleVar, extraFlags, relink);
+      this->WriteDeviceLibraryRules(linkRuleVar, relink);
     }
   }
 
@@ -187,13 +181,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
   linkRuleVar += "_CREATE_SHARED_LIBRARY";
 
   std::string extraFlags;
-  this->LocalGenerator->AppendFlags(
-    extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-  std::string linkFlagsConfig = "LINK_FLAGS_";
-  linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
-  this->LocalGenerator->AppendFlags(
-    extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
-
+  this->GetTargetLinkFlags(extraFlags);
   this->LocalGenerator->AddConfigVariableFlags(
     extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
 
@@ -223,10 +211,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
                  cuda_lang) != closure->Languages.end());
     if (hasCUDA) {
       std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
-      std::string extraFlags;
-      this->LocalGenerator->AppendFlags(
-        extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-      this->WriteDeviceLibraryRules(linkRuleVar, extraFlags, relink);
+      this->WriteDeviceLibraryRules(linkRuleVar, relink);
     }
   }
 
@@ -237,12 +222,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
   linkRuleVar += "_CREATE_SHARED_MODULE";
 
   std::string extraFlags;
-  this->LocalGenerator->AppendFlags(
-    extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-  std::string linkFlagsConfig = "LINK_FLAGS_";
-  linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
-  this->LocalGenerator->AppendFlags(
-    extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
+  this->GetTargetLinkFlags(extraFlags);
   this->LocalGenerator->AddConfigVariableFlags(
     extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
 
@@ -265,12 +245,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
   linkRuleVar += "_CREATE_MACOSX_FRAMEWORK";
 
   std::string extraFlags;
-  this->LocalGenerator->AppendFlags(
-    extraFlags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
-  std::string linkFlagsConfig = "LINK_FLAGS_";
-  linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
-  this->LocalGenerator->AppendFlags(
-    extraFlags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
+  this->GetTargetLinkFlags(extraFlags);
   this->LocalGenerator->AddConfigVariableFlags(
     extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
 
@@ -278,7 +253,7 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
 }
 
 void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
-  const std::string& linkRuleVar, const std::string& extraFlags, bool relink)
+  const std::string& linkRuleVar, bool relink)
 {
 #ifdef CMAKE_BUILD_WITH_CMAKE
   // TODO: Merge the methods that call this method to avoid
@@ -296,7 +271,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
 
   // Create set of linking flags.
   std::string linkFlags;
-  this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
+  this->GetTargetLinkFlags(linkFlags);
 
   // Get the name of the device object to generate.
   std::string const targetOutputReal =
@@ -458,7 +433,6 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
   this->WriteTargetDriverRule(targetOutputReal, relink);
 #else
   static_cast<void>(linkRuleVar);
-  static_cast<void>(extraFlags);
   static_cast<void>(relink);
 #endif
 }
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index 02fa029..35e4327 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -27,8 +27,7 @@ protected:
   void WriteSharedLibraryRules(bool relink);
   void WriteModuleLibraryRules(bool relink);
 
-  void WriteDeviceLibraryRules(const std::string& linkRule,
-                               const std::string& extraFlags, bool relink);
+  void WriteDeviceLibraryRules(const std::string& linkRule, bool relink);
   void WriteLibraryRules(const std::string& linkRule,
                          const std::string& extraFlags, bool relink);
   // MacOSX Framework support methods
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 1f65f08..8cbddd9 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -82,6 +82,17 @@ cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
   return result;
 }
 
+void cmMakefileTargetGenerator::GetTargetLinkFlags(std::string& flags)
+{
+  this->LocalGenerator->AppendFlags(
+    flags, this->GeneratorTarget->GetProperty("LINK_FLAGS"));
+
+  std::string linkFlagsConfig = "LINK_FLAGS_";
+  linkFlagsConfig += cmSystemTools::UpperCase(this->ConfigName);
+  this->LocalGenerator->AppendFlags(
+    flags, this->GeneratorTarget->GetProperty(linkFlagsConfig));
+}
+
 void cmMakefileTargetGenerator::CreateRuleFile()
 {
   // Create a directory for this target.
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 7af3cf3..4e6849a 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -52,6 +52,8 @@ public:
   cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
 
 protected:
+  void GetTargetLinkFlags(std::string& flags);
+
   // create the file and directory etc
   void CreateRuleFile();
 

-----------------------------------------------------------------------

Summary of changes:
 Help/command/LINK_OPTIONS_LINKER.txt               |   10 ++
 ...COMPILE_OPTIONS_SHELL.txt => OPTIONS_SHELL.txt} |    2 +-
 Help/command/add_compile_options.rst               |    2 +-
 Help/command/add_link_options.rst                  |   26 +++
 Help/command/target_compile_options.rst            |    2 +-
 Help/command/target_link_libraries.rst             |    3 +-
 ...compile_options.rst => target_link_options.rst} |   32 ++--
 Help/manual/cmake-commands.7.rst                   |    2 +
 Help/manual/cmake-properties.7.rst                 |    3 +
 Help/manual/cmake-variables.7.rst                  |    2 +
 Help/prop_dir/LINK_OPTIONS.rst                     |   16 ++
 Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst           |    9 +
 Help/prop_tgt/LINK_FLAGS.rst                       |    8 +-
 Help/prop_tgt/LINK_FLAGS_CONFIG.rst                |    4 +
 Help/prop_tgt/LINK_OPTIONS.rst                     |   21 +++
 Help/release/dev/LINK_OPTIONS.rst                  |   11 ++
 Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst   |   39 +++++
 .../CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst         |    9 +
 Modules/Compiler/ARMCC.cmake                       |    2 +
 Modules/Compiler/Absoft-Fortran.cmake              |    1 +
 Modules/Compiler/Bruce-C.cmake                     |    2 +
 Modules/Compiler/Clang.cmake                       |    2 +
 Modules/Compiler/G95-Fortran.cmake                 |    2 +
 Modules/Compiler/GNU.cmake                         |    3 +
 Modules/Compiler/HP-C.cmake                        |    3 +
 Modules/Compiler/HP-CXX.cmake                      |    3 +
 Modules/Compiler/HP-Fortran.cmake                  |    3 +
 Modules/Compiler/PGI.cmake                         |    3 +
 Modules/Compiler/QCC.cmake                         |    3 +
 Modules/Compiler/SCO.cmake                         |    3 +
 Modules/Compiler/SunPro-C.cmake                    |    3 +
 Modules/Compiler/SunPro-CXX.cmake                  |    3 +
 Modules/Compiler/SunPro-Fortran.cmake              |    3 +
 Modules/Compiler/TinyCC-C.cmake                    |    3 +
 Modules/Compiler/XL.cmake                          |    3 +
 Modules/Platform/Apple-Intel.cmake                 |    3 +
 Modules/Platform/Generic-ADSP-C.cmake              |    4 +-
 Modules/Platform/Generic-ADSP-CXX.cmake            |    4 +-
 Modules/Platform/Generic-SDCC-C.cmake              |    3 +-
 Modules/Platform/Linux-Intel.cmake                 |    3 +
 Modules/Platform/Windows-Embarcadero.cmake         |    2 +
 Source/CMakeLists.txt                              |    4 +
 Source/cmAddLinkOptionsCommand.cxx                 |   20 +++
 Source/cmAddLinkOptionsCommand.h                   |   31 ++++
 Source/cmCommands.cxx                              |    5 +
 Source/cmExportBuildAndroidMKGenerator.cxx         |    6 +
 Source/cmExportBuildFileGenerator.cxx              |    3 +
 Source/cmExportInstallFileGenerator.cxx            |    3 +
 Source/cmGeneratorExpressionDAGChecker.h           |    3 +-
 Source/cmGeneratorTarget.cxx                       |  175 ++++++++++++++++++--
 Source/cmGeneratorTarget.h                         |    6 +
 Source/cmGlobalXCodeGenerator.cxx                  |    4 +
 Source/cmLocalGenerator.cxx                        |    8 +
 Source/cmLocalVisualStudio7Generator.cxx           |    7 +
 Source/cmMakefile.cxx                              |   15 ++
 Source/cmMakefile.h                                |    3 +
 Source/cmMakefileExecutableTargetGenerator.cxx     |   14 +-
 Source/cmMakefileLibraryTargetGenerator.cxx        |   42 +----
 Source/cmMakefileLibraryTargetGenerator.h          |    3 +-
 Source/cmMakefileTargetGenerator.cxx               |   17 ++
 Source/cmMakefileTargetGenerator.h                 |    2 +
 Source/cmState.cxx                                 |    2 +
 Source/cmStateDirectory.cxx                        |   52 ++++++
 Source/cmStateDirectory.h                          |    7 +
 Source/cmStatePrivate.h                            |    4 +
 Source/cmStateSnapshot.cxx                         |    7 +
 Source/cmTarget.cxx                                |   77 ++++++++-
 Source/cmTarget.h                                  |    6 +
 Source/cmTargetLinkOptionsCommand.cxx              |   41 +++++
 Source/cmTargetLinkOptionsCommand.h                |   41 +++++
 Source/cmVisualStudio10TargetGenerator.cxx         |    5 +
 .../CMakeCommands/add_link_options/CMakeLists.txt  |   20 +++
 .../add_link_options/LinkOptionsExe.c}             |    0
 .../target_link_options/CMakeLists.txt             |   19 +++
 .../target_link_options/LinkOptionsLib.c           |    7 +
 Tests/CMakeLists.txt                               |    3 +
 Tests/ExportImport/Export/CMakeLists.txt           |   10 ++
 Tests/ExportImport/Import/A/CMakeLists.txt         |    5 +
 .../ExportImport/Import/A/imp_testLinkOptions.cpp  |    8 +
 Tests/RunCMake/AndroidMK/AndroidMK.cmake           |    6 +-
 .../RunCMake/AndroidMK/expectedBuildAndroidMK.txt  |    8 +
 .../AndroidMK/expectedInstallAndroidMK.txt         |    8 +
 Tests/RunCMake/CMakeLists.txt                      |    2 +
 Tests/RunCMake/add_link_options/CMakeLists.txt     |    5 +
 .../LINKER_SHELL_expansion-build-check.cmake       |    2 +
 .../add_link_options/LINKER_SHELL_expansion.cmake  |    4 +
 .../LINKER_expansion-build-check.cmake             |    2 +
 .../add_link_options/LINKER_expansion-list.cmake   |   36 ++++
 .../LINKER_expansion-validation.cmake              |   15 ++
 .../add_link_options/LINKER_expansion.cmake        |    4 +
 .../add_link_options/LINK_OPTIONS-exe-check.cmake  |    7 +
 .../LINK_OPTIONS-exe-result.txt}                   |    0
 .../add_link_options/LINK_OPTIONS-mod-check.cmake  |    7 +
 .../LINK_OPTIONS-mod-result.txt}                   |    0
 .../LINK_OPTIONS-shared-check.cmake                |    7 +
 .../LINK_OPTIONS-shared-result.txt}                |    0
 Tests/RunCMake/add_link_options/LINK_OPTIONS.cmake |   17 ++
 .../add_link_options/LinkOptionsExe.c}             |    0
 Tests/RunCMake/add_link_options/LinkOptionsLib.c   |    7 +
 Tests/RunCMake/add_link_options/RunCMakeTest.cmake |   38 +++++
 .../bad_SHELL_usage-result.txt}                    |    0
 .../add_link_options/bad_SHELL_usage-stderr.txt    |    4 +
 .../add_link_options/bad_SHELL_usage.cmake         |    6 +
 Tests/RunCMake/add_link_options/dump.c             |   13 ++
 .../RunCMake/set_property/LINK_OPTIONS-stdout.txt  |    2 +
 Tests/RunCMake/set_property/LINK_OPTIONS.cmake     |    3 +
 Tests/RunCMake/set_property/RunCMakeTest.cmake     |    1 +
 Tests/RunCMake/target_link_options/CMakeLists.txt  |    5 +
 .../LINKER_expansion-LINKER-check.cmake            |    2 +
 .../LINKER_expansion-LINKER_SHELL-check.cmake      |    2 +
 .../LINKER_expansion-validation.cmake              |   15 ++
 .../target_link_options/LINKER_expansion.cmake     |   49 ++++++
 .../LINK_OPTIONS-basic-check.cmake                 |    7 +
 .../LINK_OPTIONS-basic-result.txt}                 |    0
 .../LINK_OPTIONS-exe-check.cmake                   |    7 +
 .../LINK_OPTIONS-exe-result.txt}                   |    0
 .../LINK_OPTIONS-interface-check.cmake             |    4 +
 .../LINK_OPTIONS-interface-result.txt}             |    0
 .../LINK_OPTIONS-mod-check.cmake                   |    7 +
 .../LINK_OPTIONS-mod-result.txt}                   |    0
 .../LINK_OPTIONS-shared-check.cmake                |    7 +
 .../LINK_OPTIONS-shared-result.txt}                |    0
 .../target_link_options/LINK_OPTIONS.cmake         |   39 +++++
 .../target_link_options/LinkOptionsExe.c}          |    0
 .../RunCMake/target_link_options/LinkOptionsLib.c  |    7 +
 .../target_link_options/RunCMakeTest.cmake         |   39 +++++
 .../bad_SHELL_usage-result.txt}                    |    0
 .../target_link_options/bad_SHELL_usage-stderr.txt |    4 +
 .../target_link_options/bad_SHELL_usage.cmake      |    5 +
 Tests/RunCMake/target_link_options/dump.c          |   13 ++
 130 files changed, 1273 insertions(+), 93 deletions(-)
 create mode 100644 Help/command/LINK_OPTIONS_LINKER.txt
 rename Help/command/{COMPILE_OPTIONS_SHELL.txt => OPTIONS_SHELL.txt} (88%)
 create mode 100644 Help/command/add_link_options.rst
 copy Help/command/{target_compile_options.rst => target_link_options.rst} (52%)
 create mode 100644 Help/prop_dir/LINK_OPTIONS.rst
 create mode 100644 Help/prop_tgt/INTERFACE_LINK_OPTIONS.rst
 create mode 100644 Help/prop_tgt/LINK_OPTIONS.rst
 create mode 100644 Help/release/dev/LINK_OPTIONS.rst
 create mode 100644 Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG.rst
 create mode 100644 Help/variable/CMAKE_LANG_LINKER_WRAPPER_FLAG_SEP.rst
 create mode 100644 Source/cmAddLinkOptionsCommand.cxx
 create mode 100644 Source/cmAddLinkOptionsCommand.h
 create mode 100644 Source/cmTargetLinkOptionsCommand.cxx
 create mode 100644 Source/cmTargetLinkOptionsCommand.h
 create mode 100644 Tests/CMakeCommands/add_link_options/CMakeLists.txt
 copy Tests/{CMakeOnly/LinkInterfaceLoop/main.c => CMakeCommands/add_link_options/LinkOptionsExe.c} (100%)
 create mode 100644 Tests/CMakeCommands/target_link_options/CMakeLists.txt
 create mode 100644 Tests/CMakeCommands/target_link_options/LinkOptionsLib.c
 create mode 100644 Tests/ExportImport/Import/A/imp_testLinkOptions.cpp
 create mode 100644 Tests/RunCMake/add_link_options/CMakeLists.txt
 create mode 100644 Tests/RunCMake/add_link_options/LINKER_SHELL_expansion-build-check.cmake
 create mode 100644 Tests/RunCMake/add_link_options/LINKER_SHELL_expansion.cmake
 create mode 100644 Tests/RunCMake/add_link_options/LINKER_expansion-build-check.cmake
 create mode 100644 Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake
 create mode 100644 Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
 create mode 100644 Tests/RunCMake/add_link_options/LINKER_expansion.cmake
 create mode 100644 Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => add_link_options/LINK_OPTIONS-exe-result.txt} (100%)
 create mode 100644 Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => add_link_options/LINK_OPTIONS-mod-result.txt} (100%)
 create mode 100644 Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => add_link_options/LINK_OPTIONS-shared-result.txt} (100%)
 create mode 100644 Tests/RunCMake/add_link_options/LINK_OPTIONS.cmake
 copy Tests/{CMakeOnly/LinkInterfaceLoop/main.c => RunCMake/add_link_options/LinkOptionsExe.c} (100%)
 create mode 100644 Tests/RunCMake/add_link_options/LinkOptionsLib.c
 create mode 100644 Tests/RunCMake/add_link_options/RunCMakeTest.cmake
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => add_link_options/bad_SHELL_usage-result.txt} (100%)
 create mode 100644 Tests/RunCMake/add_link_options/bad_SHELL_usage-stderr.txt
 create mode 100644 Tests/RunCMake/add_link_options/bad_SHELL_usage.cmake
 create mode 100644 Tests/RunCMake/add_link_options/dump.c
 create mode 100644 Tests/RunCMake/set_property/LINK_OPTIONS-stdout.txt
 create mode 100644 Tests/RunCMake/set_property/LINK_OPTIONS.cmake
 create mode 100644 Tests/RunCMake/target_link_options/CMakeLists.txt
 create mode 100644 Tests/RunCMake/target_link_options/LINKER_expansion-LINKER-check.cmake
 create mode 100644 Tests/RunCMake/target_link_options/LINKER_expansion-LINKER_SHELL-check.cmake
 create mode 100644 Tests/RunCMake/target_link_options/LINKER_expansion-validation.cmake
 create mode 100644 Tests/RunCMake/target_link_options/LINKER_expansion.cmake
 create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS-basic-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => target_link_options/LINK_OPTIONS-basic-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS-exe-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => target_link_options/LINK_OPTIONS-exe-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS-interface-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => target_link_options/LINK_OPTIONS-interface-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS-mod-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => target_link_options/LINK_OPTIONS-mod-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS-shared-check.cmake
 copy Tests/RunCMake/{GenerateExportHeader/GEH-build-stderr.txt => target_link_options/LINK_OPTIONS-shared-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_link_options/LINK_OPTIONS.cmake
 copy Tests/{CMakeOnly/LinkInterfaceLoop/main.c => RunCMake/target_link_options/LinkOptionsExe.c} (100%)
 create mode 100644 Tests/RunCMake/target_link_options/LinkOptionsLib.c
 create mode 100644 Tests/RunCMake/target_link_options/RunCMakeTest.cmake
 copy Tests/RunCMake/{Android/BadSYSROOT-result.txt => target_link_options/bad_SHELL_usage-result.txt} (100%)
 create mode 100644 Tests/RunCMake/target_link_options/bad_SHELL_usage-stderr.txt
 create mode 100644 Tests/RunCMake/target_link_options/bad_SHELL_usage.cmake
 create mode 100644 Tests/RunCMake/target_link_options/dump.c


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list