diff --git a/Help/command/LINK_OPTIONS_LINKER.txt b/Help/command/LINK_OPTIONS_LINKER.txt
new file mode 100644
index 0000000000000000000000000000000000000000..76927bef1163507c65a851c8f8a846b1f625c182
--- /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 c827d7053a69c15aa936f7bb0a16645742fb9394..821198d92b2ac4ccf13a953df113852cfe039b81 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 489f9814d8bbb25390ce37a2b152a6bbd29ae015..8f47180a9535c50a21e97de7802e01a575b28032 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 edfff6cc0a971745916de991d0abbad80dd4f71a..fde1aab14cd359108c7358d245a898adc52e89c9 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 87e7c402c735323c9582d2896c84358ce8113b66..e40dab2e5d0e89192a2dfa119ce53f55fbe8a7f7 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 0000000000000000000000000000000000000000..0e52282b5567b685bdbfb6624d657f5131e3f980
--- /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 0000000000000000000000000000000000000000..faf14815cd6aeb16897d52b848f2fb0b637766c8
--- /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 250a8f4818f7762636bacf4415440d344376cf01..f9495682180e090efe188cb99c116e237264bade 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 da1fc80d41c8704a4046ae695543556bcc4f8c78..76502dca7515bdaacc94fe1af66befb128e33d02 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 cfabe6523a6aa58d54d3dbef1a262a7e1ce4b7b9..6b64e58065d60013c0b25a737e331a6a4b618b9a 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 7ce1adb9dac8b1f8fed7490ada0edf50117cb6e9..1653b55f0477947d0a42581dac9540421a06fe95 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 2c83fb8fce311a2e6ccec82ab29ff6c614a588b6..03b7e08b941cd467431ed55cc94898dca63f0347 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 a3ef2bc681058efcf21345efae6d2baf1aff7d84..9f4c8d17fcdbc4cbbc5ea1007cabec9777cde000 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 b42ba2be8e1e861c3abc31c8cfcf7da3393a639b..8fa4c08e2ba8fc430ff4b8a662385583528d729a 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 7548754d3fe7aa4167450a086131202b4be6ff30..5726b64948010bf7cbda5e03aff55200563c03b6 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 a6ca2c2b880fcec3682ed89d016a04a9750d57f8..63a033135fc1ae3e2c8463417467259ffe792d50 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 d5a57ee1cfd0afb064ef3fc1f708883efb833f0b..4f8b90b13b8187e4bda8eb1a2f4af6a1d6c6107b 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 0da7050ba5f896742dd5f65707a5c89997a313a3..5cdedeb457595207c92f98c15d88443b7f1922ae 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 c55a048a53bafec42a2d683bde82f8c922b96deb..7f643d920fa121dd8448380c1af2c15af7488a1a 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 8d0e6d698529f28b52438ed1a462d9f383a7be61..047de43f0007d89a720bbcaa9243df1703ec9366 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 14196b71dcdde45f859c828e92ed87eb013703b9..4c1ac5be622fd1fceec217bc728091aad39c60b9 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 9b25c0b252196515e4c01705611c0dab2fcff0a1..2247dd085ecb8165c780e74cec1d896977ec6621 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 fbd2841e33d59647f1646a66c63269042e6f8e68..6367695b9ceee094a6828d379751e47761cc3a5b 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 3361f8f709aaea2b413213adfb83791645bc05d4..a1d7ca1dced12f739d1329a2875aec3edacd968a 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 2d4f7e5917081346d8bcc961c44f6a14e9a2826b..a854be9962abeaed8315f2c24a020101310a2e2b 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 de1cee2988e74a37515f4fffb352eeacc5b214d0..c8597cda71a0eb1ad563e6da2fc7391d471c7174 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 0cde8f2e60f521fc016a95419d49ec15f47612d2..d76bb66bd35a608f76973663ad4ac52abb66ed95 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 4b3912af3d23beaa8833662ff892fed5cc06ad90..aef4abf173b43b097382087d000cc040594d4aaa 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 ee9aac26a9b54bf60ba3b55db6638c8c87f923bd..f712e2b5fa1d369ce826378b4c9f210e739c5881 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 f8e1c9e5641b730d6220ee8b04f2b0cdc3b3cd01..48b936eb6da003d3e902ee61bfbf60536028cc99 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 f5418a5fc2d9c708c0f79465d5fa06473d22c063..41e55a593dbcac6ab8620ab1165bfa1ba7467515 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 0000000000000000000000000000000000000000..d0ef8de8522c2eeadf3c9b76d940fe14d385b2a2
--- /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 0000000000000000000000000000000000000000..7316ef52b9d67c32ee5711d21c8d5dd3aad10456
--- /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 0000000000000000000000000000000000000000..d0ef8de8522c2eeadf3c9b76d940fe14d385b2a2
--- /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 0000000000000000000000000000000000000000..34dcc675686265e1edafe987fff4d53855030171
--- /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 0000000000000000000000000000000000000000..bebd6c736737a557ff69c7d29e7a596b79363953
--- /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 0000000000000000000000000000000000000000..42b286d2da599e46c8ef1819aa75362cdac4cbaf
--- /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 9edff3b86bcf9459fb9327470294f04c5a04847a..4f5df724e4c375d9b0d7a9ac73f7012a51e18017 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 0000000000000000000000000000000000000000..d00491fd7e5bb6fa28c517a0bb32b8b506539d4d
--- /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 0000000000000000000000000000000000000000..02d09f316a79ac8a00368253a79bcc5a5db09a68
--- /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 0000000000000000000000000000000000000000..324893ddf2b5d7f879c7765f37ab406e8e7710c5
--- /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 0000000000000000000000000000000000000000..8baa313fd1f5fa0416b6343ac131a8a617d99329
--- /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 0000000000000000000000000000000000000000..d0ef8de8522c2eeadf3c9b76d940fe14d385b2a2
--- /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 0000000000000000000000000000000000000000..d0ef8de8522c2eeadf3c9b76d940fe14d385b2a2
--- /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 0000000000000000000000000000000000000000..1af8f13a32965d477d2bba470331f7b116ab6946
--- /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 0000000000000000000000000000000000000000..b3448679df28a84e406bc9d03c624c4eed2d4e98
--- /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 81bad940031a11330884248efebc80690a10fb0d..121a0ce615fa8a533620bf289eb0417d5eb3a05f 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 0000000000000000000000000000000000000000..d00491fd7e5bb6fa28c517a0bb32b8b506539d4d
--- /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 0000000000000000000000000000000000000000..bffd80a0097409d4fcd4ded7c7a41092395c3798
--- /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 0000000000000000000000000000000000000000..b0adf19369c270b5bde2c861dd6f1123408aebc3
--- /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 0000000000000000000000000000000000000000..8baa313fd1f5fa0416b6343ac131a8a617d99329
--- /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;
+}