diff options
234 files changed, 2460 insertions, 144 deletions
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/COMPILE_OPTIONS_SHELL.txt b/Help/command/OPTIONS_SHELL.txt index a1316c8..530c012 100644 --- a/Help/command/COMPILE_OPTIONS_SHELL.txt +++ b/Help/command/OPTIONS_SHELL.txt @@ -1,4 +1,4 @@ -The final set of compile options used for a target is constructed by +The final set of compile or link options used for a target is constructed by accumulating options from the current target and the usage requirements of it dependencies. The set of options is de-duplicated to avoid repetition. While beneficial for individual options, the de-duplication step can break diff --git a/Help/command/add_compile_options.rst b/Help/command/add_compile_options.rst index c445608..350a1c0 100644 --- a/Help/command/add_compile_options.rst +++ b/Help/command/add_compile_options.rst @@ -22,4 +22,4 @@ the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. -.. include:: COMPILE_OPTIONS_SHELL.txt +.. include:: OPTIONS_SHELL.txt diff --git a/Help/command/add_link_options.rst b/Help/command/add_link_options.rst new file mode 100644 index 0000000..821198d --- /dev/null +++ b/Help/command/add_link_options.rst @@ -0,0 +1,26 @@ +add_link_options +---------------- + +Adds options to the link of targets. + +:: + + add_link_options(<option> ...) + +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 commands +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:: LINK_OPTIONS_LINKER.txt + +.. include:: OPTIONS_SHELL.txt diff --git a/Help/command/install.rst b/Help/command/install.rst index 6cea996..08cbc56 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -427,6 +427,10 @@ example, the code will print a message during installation. +The contents of ``SCRIPT`` or ``CODE`` may use "generator expressions" with +the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` +manual for available expressions. + Installing Exports ^^^^^^^^^^^^^^^^^^ diff --git a/Help/command/list.rst b/Help/command/list.rst index 589e572..ad2c428 100644 --- a/Help/command/list.rst +++ b/Help/command/list.rst @@ -28,7 +28,7 @@ Synopsis `Ordering`_ list(`REVERSE`_ <list>) - list(`SORT`_ <list>) + list(`SORT`_ <list> [...]) Introduction ^^^^^^^^^^^^ @@ -253,7 +253,23 @@ Reverses the contents of the list in-place. :: - list(SORT <list>) - + list(SORT <list> [COMPARE <compare>] [CASE <case>] [ORDER <order>]) Sorts the list in-place alphabetically. +Use the option ``<compare>`` to select the compare type for sorting. +The ``<compare>`` option may be one of: + +* ``STRING``: Sorts a list of strings alphabetically. +* ``FILE_BASENAME``: Sort a list of pathnames of files by their basenames. + +Use the option ``<case>`` to select a case sensitive or case insensitive sort mode. +The ``<case>`` option may be one of: + +* ``SENSITIVE``: Sorts the list alphabetically. +* ``INSENSITIVE``: Sorts the list alphabetically in descending order. + +Use the option ``<order>`` to select a case sensitive or case insensitive sort mode. +The ``<order>`` option may be one of: + +* ``ASCENDING``: Sorts the list in ascending order. +* ``DESCENDING``: Sorts the list in descending order. diff --git a/Help/command/target_compile_options.rst b/Help/command/target_compile_options.rst index 194d008..88b7f15 100644 --- a/Help/command/target_compile_options.rst +++ b/Help/command/target_compile_options.rst @@ -39,4 +39,4 @@ with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. See the :manual:`cmake-buildsystem(7)` manual for more on defining buildsystem properties. -.. include:: COMPILE_OPTIONS_SHELL.txt +.. include:: OPTIONS_SHELL.txt diff --git a/Help/command/target_link_libraries.rst b/Help/command/target_link_libraries.rst index 6379730..edf38cf 100644 --- a/Help/command/target_link_libraries.rst +++ b/Help/command/target_link_libraries.rst @@ -70,7 +70,8 @@ Each ``<item>`` may be: Link flags specified here are inserted into the link command in the same place as the link libraries. This might not be correct, depending on - the linker. Use the :prop_tgt:`LINK_FLAGS` target property to add link + the linker. Use the :prop_tgt:`LINK_OPTIONS` target property or + :command:`target_link_options` command to add link flags explicitly. The flags will then be placed at the toolchain-defined flag position in the link command. diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst new file mode 100644 index 0000000..8f47180 --- /dev/null +++ b/Help/command/target_link_options.rst @@ -0,0 +1,42 @@ +target_link_options +------------------- + +Add link options to a target. + +:: + + target_link_options(<target> [BEFORE] + <INTERFACE|PUBLIC|PRIVATE> [items1...] + [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]) + +Specify link options to use when linking a given target. The +named ``<target>`` must have been created by a command such as +:command:`add_executable` or :command:`add_library` and must not be an +:ref:`ALIAS target <Alias Targets>`. + +If ``BEFORE`` is specified, the content will be prepended to the property +instead of being appended. + +This command can be used to add any options, but +alternative commands exist to add libraries +(:command:`target_link_libraries` and :command:`link_libraries`). +See documentation of the :prop_dir:`directory <LINK_OPTIONS>` and +:prop_tgt:`target <LINK_OPTIONS>` ``LINK_OPTIONS`` properties. + +The ``INTERFACE``, ``PUBLIC`` and ``PRIVATE`` keywords are required to +specify the scope of the following arguments. ``PRIVATE`` and ``PUBLIC`` +items will populate the :prop_tgt:`LINK_OPTIONS` property of +``<target>``. ``PUBLIC`` and ``INTERFACE`` items will populate the +:prop_tgt:`INTERFACE_LINK_OPTIONS` property of ``<target>``. +(:ref:`IMPORTED targets <Imported Targets>` only support ``INTERFACE`` items.) +The following arguments specify link options. Repeated calls for the same +``<target>`` append items in the order called. + +Arguments to ``target_link_options`` may use "generator expressions" +with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` +manual for available expressions. See the :manual:`cmake-buildsystem(7)` +manual for more on defining buildsystem properties. + +.. include:: LINK_OPTIONS_LINKER.txt + +.. include:: OPTIONS_SHELL.txt diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst index a4f5196..5dd8d86 100644 --- a/Help/command/target_sources.rst +++ b/Help/command/target_sources.rst @@ -9,7 +9,9 @@ Add sources to a target. <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]) -Specify sources to use when compiling a given target. The +Specify sources to use when compiling a given target. Relative +source file paths are interpreted as being relative to the current +source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`). 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>`. @@ -27,3 +29,6 @@ Arguments to ``target_sources`` 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. + +See also the :policy:`CMP0076` policy for older behavior related to the +handling of relative source file paths. 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-policies.7.rst b/Help/manual/cmake-policies.7.rst index 631f75b..6179a7c 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -51,6 +51,14 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used to determine whether to report an error on use of deprecated macros or functions. +Policies Introduced by CMake 3.13 +================================= + +.. toctree:: + :maxdepth: 1 + + CMP0076: target_sources() command converts relative paths to absolute. </policy/CMP0076> + Policies Introduced by CMake 3.12 ================================= 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/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/policy/CMP0076.rst b/Help/policy/CMP0076.rst new file mode 100644 index 0000000..dd25f80 --- /dev/null +++ b/Help/policy/CMP0076.rst @@ -0,0 +1,26 @@ +CMP0076 +------- + +The :command:`target_sources` command converts relative paths to absolute. + +In CMake 3.13 and above, the :command:`target_sources` command now converts +relative source file paths to absolute paths in the following cases: + +* Source files are added to the target's :prop_tgt:`INTERFACE_SOURCES` + property. +* The target's :prop_tgt:`SOURCE_DIR` property differs from + :variable:`CMAKE_CURRENT_SOURCE_DIR`. + +A path that begins with a generator expression is always left unmodified. + +This policy provides compatibility with projects that have not been updated +to expect this behavior. The ``OLD`` behavior for this policy is to leave +all relative source file paths unmodified. The ``NEW`` behavior of this +policy is to convert relative paths to absolute according to above rules. + +This policy was introduced in CMake version 3.13. CMake version +|release| warns when the policy is not set and uses ``OLD`` behavior. +Use the :command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` +explicitly. + +.. include:: DEPRECATED.txt 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/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst new file mode 100644 index 0000000..e4cc01e --- /dev/null +++ b/Help/release/dev/0-sample-topic.rst @@ -0,0 +1,7 @@ +0-sample-topic +-------------- + +* This is a sample release note for the change in a topic. + Developers should add similar notes for each topic branch + making a noteworthy change. Each document should be named + and titled to match the topic name to avoid merge conflicts. diff --git a/Help/release/dev/LINK_OPTIONS.rst b/Help/release/dev/LINK_OPTIONS.rst new file mode 100644 index 0000000..e40dab2 --- /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/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst b/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst new file mode 100644 index 0000000..2a2721f --- /dev/null +++ b/Help/release/dev/UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES.rst @@ -0,0 +1,5 @@ +UseSWIG-USE_TARGET_INCLUDE_DIRECTORIES +-------------------------------------- + +* Module ``UseSWIG`` gains capability to manage target property + :prop_tgt:`INCLUDE_DIRECTORIES` for ``SWIG`` compilation. diff --git a/Help/release/dev/install-code-script-genex.rst b/Help/release/dev/install-code-script-genex.rst new file mode 100644 index 0000000..6532e7b --- /dev/null +++ b/Help/release/dev/install-code-script-genex.rst @@ -0,0 +1,5 @@ +install-code-script-genex +------------------------- + +* The :command:`install(CODE)` and :command:`install(SCRIPT)` commands + learned to support generator expressions. diff --git a/Help/release/dev/list_sort.rst b/Help/release/dev/list_sort.rst new file mode 100644 index 0000000..8971b78 --- /dev/null +++ b/Help/release/dev/list_sort.rst @@ -0,0 +1,5 @@ +list_sort +--------- + +* The :command:`list(SORT)` command gained options to control the + comparison operation used to order the entries. diff --git a/Help/release/dev/subdirectory-sources.rst b/Help/release/dev/subdirectory-sources.rst new file mode 100644 index 0000000..880b321 --- /dev/null +++ b/Help/release/dev/subdirectory-sources.rst @@ -0,0 +1,8 @@ +subdirectory-sources +-------------------- + +* The :command:`target_sources` command now interprets relative source file + paths as relative to the current source directory. This simplifies + incrementally building up a target's sources from subdirectories. The + :policy:`CMP0076` policy was added to provide backward compatibility with + the old behavior where required. diff --git a/Help/release/index.rst b/Help/release/index.rst index 4b32eab..4c9e96a 100644 --- a/Help/release/index.rst +++ b/Help/release/index.rst @@ -7,6 +7,8 @@ CMake Release Notes This file should include the adjacent "dev.txt" file in development versions but not in release versions. +.. include:: dev.txt + Releases ======== 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/FindCURL.cmake b/Modules/FindCURL.cmake index e66ae92..a549765 100644 --- a/Modules/FindCURL.cmake +++ b/Modules/FindCURL.cmake @@ -10,7 +10,7 @@ # IMPORTED Targets # ^^^^^^^^^^^^^^^^ # -# This module defines :prop_tgt:`IMPORTED` target ``CURL::CURL``, if +# This module defines :prop_tgt:`IMPORTED` target ``CURL::libcurl``, if # curl has been found. # # Result Variables @@ -67,9 +67,9 @@ if(CURL_FOUND) set(CURL_LIBRARIES ${CURL_LIBRARY}) set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) - if(NOT TARGET CURL::CURL) - add_library(CURL::CURL UNKNOWN IMPORTED) - set_target_properties(CURL::CURL PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}") - set_property(TARGET CURL::CURL APPEND PROPERTY IMPORTED_LOCATION "${CURL_LIBRARY}") + if(NOT TARGET CURL::libcurl) + add_library(CURL::libcurl UNKNOWN IMPORTED) + set_target_properties(CURL::libcurl PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CURL_INCLUDE_DIRS}") + set_property(TARGET CURL::libcurl APPEND PROPERTY IMPORTED_LOCATION "${CURL_LIBRARY}") endif() endif() 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/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake index 7127b8f..851101b 100644 --- a/Modules/UseSWIG.cmake +++ b/Modules/UseSWIG.cmake @@ -96,6 +96,13 @@ ensure generated files will receive the required settings. :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and :prop_sf:`COMPILE_OPTIONS`. +``USE_TARGET_INCLUDE_DIRECTORIES`` + If set to ``TRUE``, contents of target property + :prop_tgt:`INCLUDE_DIRECTORIES` will be forwarded to ``SWIG`` compiler. + If set to ``FALSE`` target property :prop_tgt:`INCLUDE_DIRECTORIES` will be + ignored. If not set, target property ``SWIG_USE_TARGT_INCLUDE_DIRECTORIES`` + will be considered. + ``GENERATED_INCLUDE_DIRECTORIES``, ``GENERATED_COMPILE_DEFINITIONS`` and ``GENERATED_COMPILE_OPTIONS`` Add custom flags to the C/C++ generated source. They will fill, respectively, properties :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and @@ -127,6 +134,13 @@ input files. set_property(TARGET mymod PROPERTY SWIG_COMPILE_DEFINITIONS MY_DEF1 MY_DEF2) set_property(TARGET mymod PROPERTY SWIG_COMPILE_OPTIONS -bla -blb) +``SWIG_USE_TARGET_INCLUDE_DIRECTORIES`` + If set to ``TRUE``, contents of target property + :prop_tgt:`INCLUDE_DIRECTORIES` will be forwarded to ``SWIG`` compiler. + If set to ``FALSE`` or not defined, target property + :prop_tgt:`INCLUDE_DIRECTORIES` will be ignored. This behavior can be + overridden by specifying source property ``USE_TARGET_INCLUDE_DIRECTORIES``. + ``SWIG_GENERATED_INCLUDE_DIRECTORIES``, ``SWIG_GENERATED_COMPILE_DEFINITIONS`` and ``SWIG_GENERATED_COMPILE_OPTIONS`` These properties will populate, respectively, properties :prop_sf:`INCLUDE_DIRECTORIES`, :prop_sf:`COMPILE_DEFINITIONS` and @@ -310,6 +324,14 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile) endif() set (property "$<TARGET_PROPERTY:${name},SWIG_INCLUDE_DIRECTORIES>") list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:$<TARGET_GENEX_EVAL:${name},${property}>,$<SEMICOLON>-I>>") + set (property "$<TARGET_PROPERTY:${name},INCLUDE_DIRECTORIES>") + get_source_file_property(use_target_include_dirs "${infile}" USE_TARGET_INCLUDE_DIRECTORIES) + if (use_target_include_dirs) + list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-I$<JOIN:${property},$<SEMICOLON>-I>>") + elseif(use_target_include_dirs STREQUAL "NOTFOUND") + # not defined at source level, rely on target level + list (APPEND swig_source_file_flags "$<$<AND:$<BOOL:$<TARGET_PROPERTY:${name},SWIG_USE_TARGET_INCLUDE_DIRECTORIES>>,$<BOOL:${property}>>:-I$<JOIN:${property},$<SEMICOLON>-I>>") + endif() set (property "$<TARGET_PROPERTY:${name},SWIG_COMPILE_DEFINITIONS>") list (APPEND swig_source_file_flags "$<$<BOOL:${property}>:-D$<JOIN:$<TARGET_GENEX_EVAL:${name},${property}>,$<SEMICOLON>-D>>") 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/CMakeVersion.cmake b/Source/CMakeVersion.cmake index f27f677..1689874 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 12) -set(CMake_VERSION_PATCH 0) -set(CMake_VERSION_RC 1) +set(CMake_VERSION_PATCH 20180619) +#set(CMake_VERSION_RC 1) 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/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 13a18e2..db34077 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -34,6 +34,9 @@ struct cmFindProgramHelper // Current names under consideration. std::vector<std::string> Names; + // Current name with extension under consideration. + std::string TestNameExt; + // Current full path under consideration. std::string TestPath; @@ -43,6 +46,19 @@ struct cmFindProgramHelper this->Names.clear(); this->AddName(name); } + bool CheckCompoundNames() + { + for (std::string const& n : this->Names) { + // Only perform search relative to current directory if the file name + // contains a directory separator. + if (n.find('/') != std::string::npos) { + if (this->CheckDirectoryForName("", n)) { + return true; + } + } + } + return false; + } bool CheckDirectory(std::string const& path) { for (std::string const& n : this->Names) { @@ -55,14 +71,16 @@ struct cmFindProgramHelper bool CheckDirectoryForName(std::string const& path, std::string const& name) { for (std::string const& ext : this->Extensions) { - this->TestPath = path; - this->TestPath += name; if (!ext.empty() && cmSystemTools::StringEndsWith(name, ext.c_str())) { continue; } - this->TestPath += ext; + this->TestNameExt = name; + this->TestNameExt += ext; + this->TestPath = + cmSystemTools::CollapseCombinedPath(path, this->TestNameExt); + if (cmSystemTools::FileExists(this->TestPath, true)) { - this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath); + this->BestPath = this->TestPath; return true; } } @@ -145,8 +163,8 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir() helper.AddName(n); } - // Check for the names themselves (e.g. absolute paths). - if (helper.CheckDirectory(std::string())) { + // Check for the names themselves if they contain a directory separator. + if (helper.CheckCompoundNames()) { return helper.BestPath; } @@ -168,8 +186,8 @@ std::string cmFindProgramCommand::FindNormalProgramDirsPerName() // Switch to searching for this name. helper.SetName(n); - // Check for the name by itself (e.g. an absolute path). - if (helper.CheckDirectory(std::string())) { + // Check for the names themselves if they contain a directory separator. + if (helper.CheckCompoundNames()) { return helper.BestPath; } 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..41e55a5 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,153 @@ void cmGeneratorTarget::GetCompileDefinitions( cmDeleteAll(linkInterfaceCompileDefinitionsEntries); } +namespace { +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); + + // 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 { 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 58888c3..dae4592 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/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index f7e6e44..3a90f4c 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmInstallScriptGenerator.h" +#include "cmGeneratorExpression.h" #include "cmScriptGenerator.h" #include <ostream> @@ -16,24 +17,47 @@ cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script, , Script(script) , Code(code) { + // We need per-config actions if the script has generator expressions. + if (cmGeneratorExpression::Find(Script) != std::string::npos) { + this->ActionsPerConfig = true; + } } cmInstallScriptGenerator::~cmInstallScriptGenerator() { } -void cmInstallScriptGenerator::GenerateScript(std::ostream& os) +void cmInstallScriptGenerator::Compute(cmLocalGenerator* lg) { - Indent indent; - std::string component_test = - this->CreateComponentTest(this->Component.c_str(), this->ExcludeFromAll); - os << indent << "if(" << component_test << ")\n"; + this->LocalGenerator = lg; +} +void cmInstallScriptGenerator::AddScriptInstallRule(std::ostream& os, + Indent indent, + std::string const& script) +{ if (this->Code) { - os << indent.Next() << this->Script << "\n"; + os << indent.Next() << script << "\n"; + } else { + os << indent.Next() << "include(\"" << script << "\")\n"; + } +} + +void cmInstallScriptGenerator::GenerateScriptActions(std::ostream& os, + Indent indent) +{ + if (this->ActionsPerConfig) { + this->cmInstallGenerator::GenerateScriptActions(os, indent); } else { - os << indent.Next() << "include(\"" << this->Script << "\")\n"; + this->AddScriptInstallRule(os, indent, this->Script); } +} - os << indent << "endif()\n\n"; +void cmInstallScriptGenerator::GenerateScriptForConfig( + std::ostream& os, const std::string& config, Indent indent) +{ + cmGeneratorExpression ge; + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(this->Script); + this->AddScriptInstallRule(os, indent, + cge->Evaluate(this->LocalGenerator, config)); } diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h index fe0f7c6..534bc1d 100644 --- a/Source/cmInstallScriptGenerator.h +++ b/Source/cmInstallScriptGenerator.h @@ -6,10 +6,13 @@ #include "cmConfigure.h" // IWYU pragma: keep #include "cmInstallGenerator.h" +#include "cmScriptGenerator.h" #include <iosfwd> #include <string> +class cmLocalGenerator; + /** \class cmInstallScriptGenerator * \brief Generate target installation rules. */ @@ -20,10 +23,18 @@ public: const char* component, bool exclude_from_all); ~cmInstallScriptGenerator() override; + void Compute(cmLocalGenerator* lg) override; + protected: - void GenerateScript(std::ostream& os) override; + void GenerateScriptActions(std::ostream& os, Indent indent) override; + void GenerateScriptForConfig(std::ostream& os, const std::string& config, + Indent indent) override; + void AddScriptInstallRule(std::ostream& os, Indent indent, + std::string const& script); + std::string Script; bool Code; + cmLocalGenerator* LocalGenerator; }; #endif diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index 1ac2cc2..ba0c843 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -963,14 +963,193 @@ bool cmListCommand::HandleTransformCommand( return true; } +class cmStringSorter +{ +public: + enum class Order + { + UNINITIALIZED, + ASCENDING, + DESCENDING, + }; + + enum class Compare + { + UNINITIALIZED, + STRING, + FILE_BASENAME, + }; + enum class CaseSensitivity + { + UNINITIALIZED, + SENSITIVE, + INSENSITIVE, + }; + +protected: + typedef std::string (*StringFilter)(const std::string& in); + StringFilter GetCompareFilter(Compare compare) + { + return (compare == Compare::FILE_BASENAME) ? cmSystemTools::GetFilenameName + : nullptr; + } + + StringFilter GetCaseFilter(CaseSensitivity sensitivity) + { + return (sensitivity == CaseSensitivity::INSENSITIVE) + ? cmSystemTools::LowerCase + : nullptr; + } + +public: + cmStringSorter(Compare compare, CaseSensitivity caseSensitivity, + Order desc = Order::ASCENDING) + : filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) } + , descending(desc == Order::DESCENDING) + { + } + + std::string ApplyFilter(const std::string& argument) + { + std::string result = argument; + for (auto filter : filters) { + if (filter != nullptr) { + result = filter(result); + } + } + return result; + } + + bool operator()(const std::string& a, const std::string& b) + { + std::string af = ApplyFilter(a); + std::string bf = ApplyFilter(b); + bool result; + if (descending) { + result = bf < af; + } else { + result = af < bf; + } + return result; + } + +protected: + StringFilter filters[2] = { nullptr, nullptr }; + bool descending; +}; + bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) { assert(args.size() >= 2); - if (args.size() > 2) { - this->SetError("sub-command SORT only takes one argument."); + if (args.size() > 8) { + this->SetError("sub-command SORT only takes up to six arguments."); return false; } + auto sortCompare = cmStringSorter::Compare::UNINITIALIZED; + auto sortCaseSensitivity = cmStringSorter::CaseSensitivity::UNINITIALIZED; + auto sortOrder = cmStringSorter::Order::UNINITIALIZED; + + size_t argumentIndex = 2; + const std::string messageHint = "sub-command SORT "; + + while (argumentIndex < args.size()) { + const std::string option = args[argumentIndex++]; + if (option == "COMPARE") { + if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) { + std::string error = messageHint + "option \"" + option + + "\" has been specified multiple times."; + this->SetError(error); + return false; + } + if (argumentIndex < args.size()) { + const std::string argument = args[argumentIndex++]; + if (argument == "STRING") { + sortCompare = cmStringSorter::Compare::STRING; + } else if (argument == "FILE_BASENAME") { + sortCompare = cmStringSorter::Compare::FILE_BASENAME; + } else { + std::string error = messageHint + "value \"" + argument + + "\" for option \"" + option + "\" is invalid."; + this->SetError(error); + return false; + } + } else { + std::string error = + messageHint + "missing argument for option \"" + option + "\"."; + this->SetError(error); + return false; + } + } else if (option == "CASE") { + if (sortCaseSensitivity != + cmStringSorter::CaseSensitivity::UNINITIALIZED) { + std::string error = messageHint + "option \"" + option + + "\" has been specified multiple times."; + this->SetError(error); + return false; + } + if (argumentIndex < args.size()) { + const std::string argument = args[argumentIndex++]; + if (argument == "SENSITIVE") { + sortCaseSensitivity = cmStringSorter::CaseSensitivity::SENSITIVE; + } else if (argument == "INSENSITIVE") { + sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE; + } else { + std::string error = messageHint + "value \"" + argument + + "\" for option \"" + option + "\" is invalid."; + this->SetError(error); + return false; + } + } else { + std::string error = + messageHint + "missing argument for option \"" + option + "\"."; + this->SetError(error); + return false; + } + } else if (option == "ORDER") { + + if (sortOrder != cmStringSorter::Order::UNINITIALIZED) { + std::string error = messageHint + "option \"" + option + + "\" has been specified multiple times."; + this->SetError(error); + return false; + } + if (argumentIndex < args.size()) { + const std::string argument = args[argumentIndex++]; + if (argument == "ASCENDING") { + sortOrder = cmStringSorter::Order::ASCENDING; + } else if (argument == "DESCENDING") { + sortOrder = cmStringSorter::Order::DESCENDING; + } else { + std::string error = messageHint + "value \"" + argument + + "\" for option \"" + option + "\" is invalid."; + this->SetError(error); + return false; + } + } else { + std::string error = + messageHint + "missing argument for option \"" + option + "\"."; + this->SetError(error); + return false; + } + } else { + std::string error = + messageHint + "option \"" + option + "\" is unknown."; + this->SetError(error); + return false; + } + } + // set Default Values if Option is not given + if (sortCompare == cmStringSorter::Compare::UNINITIALIZED) { + sortCompare = cmStringSorter::Compare::STRING; + } + if (sortCaseSensitivity == cmStringSorter::CaseSensitivity::UNINITIALIZED) { + sortCaseSensitivity = cmStringSorter::CaseSensitivity::SENSITIVE; + } + if (sortOrder == cmStringSorter::Order::UNINITIALIZED) { + sortOrder = cmStringSorter::Order::ASCENDING; + } + const std::string& listName = args[1]; // expand the variable std::vector<std::string> varArgsExpanded; @@ -979,7 +1158,14 @@ bool cmListCommand::HandleSortCommand(std::vector<std::string> const& args) return false; } - std::sort(varArgsExpanded.begin(), varArgsExpanded.end()); + if ((sortCompare == cmStringSorter::Compare::STRING) && + (sortCaseSensitivity == cmStringSorter::CaseSensitivity::SENSITIVE) && + (sortOrder == cmStringSorter::Order::ASCENDING)) { + std::sort(varArgsExpanded.begin(), varArgsExpanded.end()); + } else { + cmStringSorter sorter(sortCompare, sortCaseSensitivity, sortOrder); + std::sort(varArgsExpanded.begin(), varArgsExpanded.end(), sorter); + } std::string value = cmJoin(varArgsExpanded, ";"); this->Makefile->AddDefinition(listName, value.c_str()); 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 1e59f44..82f4683 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, linkLanguage); // 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, linkLanguage); { std::unique_ptr<cmLinkLineComputer> linkLineComputer( diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index c538992..036acc7 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, linkLanguage); 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, linkLanguage); 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, linkLanguage); 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, linkLanguage); // 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..08fcd8f 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -82,6 +82,23 @@ cmMakefileTargetGenerator* cmMakefileTargetGenerator::New( return result; } +void cmMakefileTargetGenerator::GetTargetLinkFlags( + std::string& flags, const std::string& linkLanguage) +{ + 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)); + + std::vector<std::string> opts; + this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage); + // LINK_OPTIONS are escaped. + this->LocalGenerator->AppendCompileOptions(flags, opts); +} + void cmMakefileTargetGenerator::CreateRuleFile() { // Create a directory for this target. diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 7af3cf3..4d1c9ec 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, const std::string& linkLanguage); + // create the file and directory etc void CreateRuleFile(); diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 3fe0c84..1732ad6 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -223,7 +223,10 @@ class cmMakefile; 12, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0075, \ "Include file check macros honor CMAKE_REQUIRED_LIBRARIES.", 3, 12, \ - 0, cmPolicies::WARN) + 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0076, \ + "target_sources() command converts relative paths to absolute.", 3, \ + 13, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ @@ -248,7 +251,8 @@ class cmMakefile; F(CMP0065) \ F(CMP0068) \ F(CMP0069) \ - F(CMP0073) + F(CMP0073) \ + F(CMP0076) /** \class cmPolicies * \brief Handles changes in CMake behavior and policies 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/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index 3dd3748..62e323c 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -2,10 +2,14 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmTargetSourcesCommand.h" +#include <cstring> #include <sstream> #include "cmAlgorithms.h" +#include "cmGeneratorExpression.h" #include "cmMakefile.h" +#include "cmPolicies.h" +#include "cmSystemTools.h" #include "cmTarget.h" #include "cmake.h" @@ -17,6 +21,14 @@ bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args, return this->HandleArguments(args, "SOURCES"); } +void cmTargetSourcesCommand::HandleInterfaceContent( + cmTarget* tgt, const std::vector<std::string>& content, bool prepend, + bool system) +{ + cmTargetPropCommandBase::HandleInterfaceContent( + tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system); +} + void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name) { std::ostringstream e; @@ -35,6 +47,79 @@ std::string cmTargetSourcesCommand::Join( bool cmTargetSourcesCommand::HandleDirectContent( cmTarget* tgt, const std::vector<std::string>& content, bool, bool) { - tgt->AppendProperty("SOURCES", this->Join(content).c_str()); + tgt->AppendProperty( + "SOURCES", + this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str()); return true; // Successfully handled. } + +std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent( + cmTarget* tgt, const std::vector<std::string>& content, + bool isInterfaceContent) +{ + // Skip conversion in case old behavior has been explictly requested + if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076) == + cmPolicies::OLD) { + return content; + } + + bool changedPath = false; + std::vector<std::string> absoluteContent; + absoluteContent.reserve(content.size()); + for (std::string const& src : content) { + std::string absoluteSrc; + if (cmSystemTools::FileIsFullPath(src) || + cmGeneratorExpression::Find(src) == 0 || + (!isInterfaceContent && + strcmp(this->Makefile->GetCurrentSourceDirectory(), + tgt->GetMakefile()->GetCurrentSourceDirectory()) == 0)) { + absoluteSrc = src; + } else { + changedPath = true; + absoluteSrc = this->Makefile->GetCurrentSourceDirectory(); + absoluteSrc += "/"; + absoluteSrc += src; + } + absoluteContent.push_back(absoluteSrc); + } + + if (!changedPath) { + return content; + } + + bool issueMessage = true; + bool useAbsoluteContent = false; + std::ostringstream e; + switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076)) { + case cmPolicies::WARN: + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0076) << "\n"; + break; + case cmPolicies::OLD: + issueMessage = false; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + this->Makefile->IssueMessage( + cmake::FATAL_ERROR, + cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0076)); + break; + case cmPolicies::NEW: { + issueMessage = false; + useAbsoluteContent = true; + break; + } + } + + if (issueMessage) { + if (isInterfaceContent) { + e << "An interface source of target \"" << tgt->GetName() + << "\" has a relative path."; + } else { + e << "A private source from a directory other than that of target \"" + << tgt->GetName() << "\" has a relative path."; + } + this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str()); + } + + return useAbsoluteContent ? absoluteContent : content; +} diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h index ea8776a..b01e3ca 100644 --- a/Source/cmTargetSourcesCommand.h +++ b/Source/cmTargetSourcesCommand.h @@ -29,6 +29,11 @@ public: bool InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) override; +protected: + void HandleInterfaceContent(cmTarget* tgt, + const std::vector<std::string>& content, + bool prepend, bool system) override; + private: void HandleMissingTarget(const std::string& name) override; @@ -37,6 +42,10 @@ private: bool prepend, bool system) override; std::string Join(const std::vector<std::string>& content) override; + + std::vector<std::string> ConvertToAbsoluteContent( + cmTarget* tgt, const std::vector<std::string>& content, + bool isInterfaceContent); }; #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/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index cfe62b4..7545ec7 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -3495,7 +3495,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() // Chip Model Name this->ChipID.ModelName = - this->ExtractValueFromCpuInfoFile(buffer, "model name").c_str(); + this->ExtractValueFromCpuInfoFile(buffer, "model name"); // L1 Cache size // Different architectures may show different names for the caches. @@ -4613,7 +4613,7 @@ std::string SystemInformationImplementation::ExtractValueFromSysCtl( std::string SystemInformationImplementation::RunProcess( std::vector<const char*> args) { - std::string buffer = ""; + std::string buffer; // Run the application kwsysProcess* gp = kwsysProcess_New(); @@ -4668,11 +4668,7 @@ std::string SystemInformationImplementation::RunProcess( std::string SystemInformationImplementation::ParseValueFromKStat( const char* arguments) { - std::vector<const char*> args; - args.clear(); - args.push_back("kstat"); - args.push_back("-p"); - + std::vector<std::string> args_string; std::string command = arguments; size_t start = std::string::npos; size_t pos = command.find(' ', 0); @@ -4691,35 +4687,35 @@ std::string SystemInformationImplementation::ParseValueFromKStat( } if (!inQuotes) { - std::string arg = command.substr(start + 1, pos - start - 1); + args_string.push_back(command.substr(start + 1, pos - start - 1)); + std::string& arg = args_string.back(); // Remove the quotes if any - size_t quotes = arg.find('"'); - while (quotes != std::string::npos) { - arg.erase(quotes, 1); - quotes = arg.find('"'); - } - args.push_back(arg.c_str()); + arg.erase(std::remove(arg.begin(), arg.end(), '"'), arg.end()); start = pos; } pos = command.find(' ', pos + 1); } - std::string lastArg = command.substr(start + 1, command.size() - start - 1); - args.push_back(lastArg.c_str()); + args_string.push_back(command.substr(start + 1, command.size() - start - 1)); + std::vector<const char*> args; + args.reserve(3 + args_string.size()); + args.push_back("kstat"); + args.push_back("-p"); + for (size_t i = 0; i < args_string.size(); ++i) { + args.push_back(args_string[i].c_str()); + } args.push_back(KWSYS_NULLPTR); std::string buffer = this->RunProcess(args); - std::string value = ""; + std::string value; for (size_t i = buffer.size() - 1; i > 0; i--) { if (buffer[i] == ' ' || buffer[i] == '\t') { break; } if (buffer[i] != '\n' && buffer[i] != '\r') { - std::string val = value; - value = buffer[i]; - value += val; + value.insert(0u, 1, buffer[i]); } } return value; diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 0079da2..b87b6b5 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -686,7 +686,7 @@ public: for (iterator i = this->begin(); i != this->end(); ++i) { # if defined(_WIN32) const std::string s = Encoding::ToNarrow(*i); - kwsysUnPutEnv(s.c_str()); + kwsysUnPutEnv(s); # else kwsysUnPutEnv(*i); # endif @@ -1973,7 +1973,7 @@ std::string SystemTools::ConvertToUnixOutputPath(const std::string& path) } // escape spaces and () in the path if (ret.find_first_of(" ") != std::string::npos) { - std::string result = ""; + std::string result; char lastch = 1; for (const char* ch = ret.c_str(); *ch != '\0'; ++ch) { // if it is already escaped then don't try to escape it again @@ -3140,7 +3140,7 @@ void SystemTools::AddTranslationPath(const std::string& a, void SystemTools::AddKeepPath(const std::string& dir) { std::string cdir; - Realpath(SystemTools::CollapseFullPath(dir).c_str(), cdir); + Realpath(SystemTools::CollapseFullPath(dir), cdir); SystemTools::AddTranslationPath(cdir, dir); } diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx index 0385a3d..ef87436 100644 --- a/Source/kwsys/testCommandLineArguments.cxx +++ b/Source/kwsys/testCommandLineArguments.cxx @@ -77,7 +77,7 @@ int testCommandLineArguments(int argc, char* argv[]) int some_int_variable = 10; double some_double_variable = 10.10; char* some_string_variable = KWSYS_NULLPTR; - std::string some_stl_string_variable = ""; + std::string some_stl_string_variable; bool some_bool_variable = false; bool some_bool_variable1 = false; bool bool_arg1 = false; diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx index e6f9701..0477d59 100644 --- a/Source/kwsys/testSystemTools.cxx +++ b/Source/kwsys/testSystemTools.cxx @@ -206,7 +206,7 @@ static bool CheckFileOperations() res = false; } - if (!kwsys::SystemTools::Touch(testNewFile.c_str(), true)) { + if (!kwsys::SystemTools::Touch(testNewFile, true)) { std::cerr << "Problem with Touch for: " << testNewFile << std::endl; res = false; } @@ -415,7 +415,7 @@ static bool CheckFileOperations() res = false; } - kwsys::SystemTools::Touch(testNewFile.c_str(), true); + kwsys::SystemTools::Touch(testNewFile, true); if (!kwsys::SystemTools::RemoveADirectory(testNewDir)) { std::cerr << "Problem with RemoveADirectory for: " << testNewDir << std::endl; @@ -806,7 +806,7 @@ static bool CheckFind() const std::string testFindFile(TEST_SYSTEMTOOLS_BINARY_DIR "/" + testFindFileName); - if (!kwsys::SystemTools::Touch(testFindFile.c_str(), true)) { + if (!kwsys::SystemTools::Touch(testFindFile, true)) { std::cerr << "Problem with Touch for: " << testFindFile << std::endl; // abort here as the existence of the file only makes the test meaningful return false; 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/CMakeCommands/target_sources/CMakeLists.txt b/Tests/CMakeCommands/target_sources/CMakeLists.txt new file mode 100644 index 0000000..ab14855 --- /dev/null +++ b/Tests/CMakeCommands/target_sources/CMakeLists.txt @@ -0,0 +1,36 @@ + +cmake_minimum_required(VERSION 3.12) +cmake_policy(SET CMP0076 NEW) + +project(target_sources) + +add_library(target_sources_lib) +target_compile_definitions(target_sources_lib PRIVATE "-DIS_LIB") +add_subdirectory(subdir) + +set(subdir_fullpath "${CMAKE_CURRENT_LIST_DIR}/subdir") + +get_property(target_sources_lib_property TARGET target_sources_lib PROPERTY SOURCES) +if (NOT "$<1:${subdir_fullpath}/subdir_empty_1.cpp>" IN_LIST target_sources_lib_property) + message(SEND_ERROR "target_sources_lib: Generator expression to absolute sub directory file not found") +endif() +if (NOT "$<1:${subdir_fullpath}/../empty_1.cpp>" IN_LIST target_sources_lib_property) + message(SEND_ERROR "target_sources_lib: Generator expression to absolute main directory file not found") +endif() +if (NOT "${subdir_fullpath}/subdir_empty_2.cpp" IN_LIST target_sources_lib_property) + message(SEND_ERROR "target_sources_lib: Relative sub directory file not converted to absolute") +endif() +if (NOT "$<1:empty_2.cpp>" IN_LIST target_sources_lib_property) + message(SEND_ERROR "target_sources_lib: Generator expression to relative main directory file not found") +endif() +if (NOT "${subdir_fullpath}/../empty_3.cpp" IN_LIST target_sources_lib_property) + message(SEND_ERROR "target_sources_lib: Relative main directory file not converted to absolute") +endif() + +add_executable(target_sources main.cpp) +target_link_libraries(target_sources target_sources_lib) + +get_property(target_sources_property TARGET target_sources PROPERTY SOURCES) +if (NOT "main.cpp" IN_LIST target_sources_property) + message(SEND_ERROR "target_sources: Relative main directory file converted to absolute") +endif() diff --git a/Tests/CMakeCommands/target_sources/empty_1.cpp b/Tests/CMakeCommands/target_sources/empty_1.cpp new file mode 100644 index 0000000..01e5b07 --- /dev/null +++ b/Tests/CMakeCommands/target_sources/empty_1.cpp @@ -0,0 +1,21 @@ +#ifdef IS_LIB + +# ifdef _WIN32 +__declspec(dllexport) +# endif + int internal_empty_1() +{ + return 0; +} + +#else + +# ifdef _WIN32 +__declspec(dllexport) +# endif + int empty_1() +{ + return 0; +} + +#endif diff --git a/Tests/CMakeCommands/target_sources/empty_2.cpp b/Tests/CMakeCommands/target_sources/empty_2.cpp new file mode 100644 index 0000000..48ae8bb --- /dev/null +++ b/Tests/CMakeCommands/target_sources/empty_2.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty_2() +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_sources/empty_3.cpp b/Tests/CMakeCommands/target_sources/empty_3.cpp new file mode 100644 index 0000000..bd3a6d1 --- /dev/null +++ b/Tests/CMakeCommands/target_sources/empty_3.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty_3() +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_sources/main.cpp b/Tests/CMakeCommands/target_sources/main.cpp new file mode 100644 index 0000000..622771c --- /dev/null +++ b/Tests/CMakeCommands/target_sources/main.cpp @@ -0,0 +1,16 @@ +#include <iostream> + +int empty_1(); +int subdir_empty_1(); +int subdir_empty_2(); + +int main() +{ + int e1 = empty_1(); + int se1 = subdir_empty_1(); + int se2 = subdir_empty_2(); + + std::cout << e1 << " " << se1 << " " << se2 << std::endl; + + return 0; +} diff --git a/Tests/CMakeCommands/target_sources/subdir/CMakeLists.txt b/Tests/CMakeCommands/target_sources/subdir/CMakeLists.txt new file mode 100644 index 0000000..f749f1d --- /dev/null +++ b/Tests/CMakeCommands/target_sources/subdir/CMakeLists.txt @@ -0,0 +1,6 @@ + +target_sources(target_sources_lib PUBLIC $<1:${CMAKE_CURRENT_LIST_DIR}/subdir_empty_1.cpp> + $<1:${CMAKE_CURRENT_LIST_DIR}/../empty_1.cpp> + subdir_empty_2.cpp + PRIVATE $<1:empty_2.cpp> + ../empty_3.cpp) diff --git a/Tests/CMakeCommands/target_sources/subdir/subdir_empty_1.cpp b/Tests/CMakeCommands/target_sources/subdir/subdir_empty_1.cpp new file mode 100644 index 0000000..3c61321 --- /dev/null +++ b/Tests/CMakeCommands/target_sources/subdir/subdir_empty_1.cpp @@ -0,0 +1,21 @@ +#ifdef IS_LIB + +# ifdef _WIN32 +__declspec(dllexport) +# endif + int internal_subdir_empty_1() +{ + return 0; +} + +#else + +# ifdef _WIN32 +__declspec(dllexport) +# endif + int subdir_empty_1() +{ + return 0; +} + +#endif diff --git a/Tests/CMakeCommands/target_sources/subdir/subdir_empty_2.cpp b/Tests/CMakeCommands/target_sources/subdir/subdir_empty_2.cpp new file mode 100644 index 0000000..47fa736 --- /dev/null +++ b/Tests/CMakeCommands/target_sources/subdir/subdir_empty_2.cpp @@ -0,0 +1,21 @@ +#ifdef IS_LIB + +# ifdef _WIN32 +__declspec(dllexport) +# endif + int internal_subdir_empty_2() +{ + return 0; +} + +#else + +# ifdef _WIN32 +__declspec(dllexport) +# endif + int subdir_empty_2() +{ + return 0; +} + +#endif diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 886e392..9aed3ba 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2839,6 +2839,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories) ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions) ADD_TEST_MACRO(CMakeCommands.target_compile_options target_compile_options) + ADD_TEST_MACRO(CMakeCommands.target_sources target_sources) + + 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) 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/FindCURL/Test/CMakeLists.txt b/Tests/FindCURL/Test/CMakeLists.txt index f0e5568..c3c719b 100644 --- a/Tests/FindCURL/Test/CMakeLists.txt +++ b/Tests/FindCURL/Test/CMakeLists.txt @@ -7,7 +7,7 @@ find_package(CURL REQUIRED) add_definitions(-DCMAKE_EXPECTED_CURL_VERSION="${CURL_VERSION_STRING}") add_executable(test_tgt main.c) -target_link_libraries(test_tgt CURL::CURL) +target_link_libraries(test_tgt CURL::libcurl) add_test(NAME test_tgt COMMAND test_tgt) add_executable(test_var main.c) 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/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt index 5af6fcd..6c861fa 100644 --- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt +++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt @@ -24,6 +24,7 @@ \* CMP0068 \* CMP0069 \* CMP0073 + \* CMP0076 Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt b/Tests/RunCMake/TargetSources/CMP0076-OLD-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/list/SORT-TooManyArguments-result.txt +++ b/Tests/RunCMake/TargetSources/CMP0076-OLD-result.txt diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt b/Tests/RunCMake/TargetSources/CMP0076-OLD-stderr.txt index d47dd4d..d47dd4d 100644 --- a/Tests/RunCMake/TargetSources/RelativePathInInterface-stderr.txt +++ b/Tests/RunCMake/TargetSources/CMP0076-OLD-stderr.txt diff --git a/Tests/RunCMake/TargetSources/CMP0076-OLD.cmake b/Tests/RunCMake/TargetSources/CMP0076-OLD.cmake new file mode 100644 index 0000000..4d8c268 --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0076-OLD.cmake @@ -0,0 +1,10 @@ +cmake_policy(SET CMP0076 OLD) + +add_library(iface INTERFACE) +target_sources(iface INTERFACE empty_1.cpp) + +get_property(iface_sources TARGET iface PROPERTY INTERFACE_SOURCES) +message(STATUS "iface: ${iface_sources}") + +add_executable(main main.cpp) +target_link_libraries(main iface) diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt b/Tests/RunCMake/TargetSources/CMP0076-WARN-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/TargetSources/RelativePathInInterface-result.txt +++ b/Tests/RunCMake/TargetSources/CMP0076-WARN-result.txt diff --git a/Tests/RunCMake/TargetSources/CMP0076-WARN-stderr.txt b/Tests/RunCMake/TargetSources/CMP0076-WARN-stderr.txt new file mode 100644 index 0000000..217c762 --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0076-WARN-stderr.txt @@ -0,0 +1,21 @@ +CMake Warning \(dev\) at CMP0076-WARN/CMakeLists.txt:2 \(target_sources\): + Policy CMP0076 is not set: target_sources\(\) command converts relative paths + to absolute. Run "cmake --help-policy CMP0076" for policy details. Use + the cmake_policy command to set the policy and suppress this warning. + + An interface source of target "publiclib" has a relative path. +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Warning \(dev\) at CMP0076-WARN/CMakeLists.txt:2 \(target_sources\): + Policy CMP0076 is not set: target_sources\(\) command converts relative paths + to absolute. Run "cmake --help-policy CMP0076" for policy details. Use + the cmake_policy command to set the policy and suppress this warning. + + A private source from a directory other than that of target "publiclib" has + a relative path. +This warning is for project developers. Use -Wno-dev to suppress it. + +CMake Error in CMakeLists.txt: + Target "publiclib" contains relative path in its INTERFACE_SOURCES: + + "CMP0076-WARN/subdir_empty_1.cpp" diff --git a/Tests/RunCMake/TargetSources/CMP0076-WARN.cmake b/Tests/RunCMake/TargetSources/CMP0076-WARN.cmake new file mode 100644 index 0000000..2e07331 --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0076-WARN.cmake @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.12) + +add_library(publiclib) + +add_subdirectory(CMP0076-WARN) + +add_executable(main main.cpp) +target_link_libraries(main publiclib) diff --git a/Tests/RunCMake/TargetSources/CMP0076-WARN/CMakeLists.txt b/Tests/RunCMake/TargetSources/CMP0076-WARN/CMakeLists.txt new file mode 100644 index 0000000..f9c7d6d --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0076-WARN/CMakeLists.txt @@ -0,0 +1,3 @@ + +target_sources(publiclib INTERFACE CMP0076-WARN/subdir_empty_1.cpp + PRIVATE empty_1.cpp) diff --git a/Tests/RunCMake/TargetSources/CMP0076-WARN/subdir_empty_1.cpp b/Tests/RunCMake/TargetSources/CMP0076-WARN/subdir_empty_1.cpp new file mode 100644 index 0000000..11ec041 --- /dev/null +++ b/Tests/RunCMake/TargetSources/CMP0076-WARN/subdir_empty_1.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface-stdout.txt b/Tests/RunCMake/TargetSources/RelativePathInInterface-stdout.txt new file mode 100644 index 0000000..4581d8a --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInInterface-stdout.txt @@ -0,0 +1 @@ +-- iface: .*Tests/RunCMake/TargetSources/empty_1.cpp diff --git a/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake b/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake index 8bb6149..0d3e9a4 100644 --- a/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake +++ b/Tests/RunCMake/TargetSources/RelativePathInInterface.cmake @@ -1,6 +1,10 @@ +cmake_policy(SET CMP0076 NEW) add_library(iface INTERFACE) target_sources(iface INTERFACE empty_1.cpp) +get_property(iface_sources TARGET iface PROPERTY INTERFACE_SOURCES) +message(STATUS "iface: ${iface_sources}") + add_executable(main main.cpp) target_link_libraries(main iface) diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx-stdout.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx-stdout.txt new file mode 100644 index 0000000..7f48082 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx-stdout.txt @@ -0,0 +1 @@ +-- genexlib: \$<1:.*Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/subdir_empty_1.cpp>;\$<1:.*Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/../empty_1.cpp>;\$<1:empty_2.cpp> diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx.cmake b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx.cmake new file mode 100644 index 0000000..1cdc2a7 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx.cmake @@ -0,0 +1,10 @@ +cmake_policy(SET CMP0076 NEW) + +add_library(genexlib) +add_subdirectory(RelativePathInSubdirGenEx) + +get_property(genexlib_sources TARGET genexlib PROPERTY SOURCES) +message(STATUS "genexlib: ${genexlib_sources}") + +add_executable(genexmain main.cpp) +target_link_libraries(genexmain genexlib) diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/CMakeLists.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/CMakeLists.txt new file mode 100644 index 0000000..3bcf454 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/CMakeLists.txt @@ -0,0 +1,4 @@ + +target_sources(genexlib PUBLIC $<1:${CMAKE_CURRENT_LIST_DIR}/subdir_empty_1.cpp> + $<1:${CMAKE_CURRENT_LIST_DIR}/../empty_1.cpp> + PRIVATE $<1:empty_2.cpp>) diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/subdir_empty_1.cpp b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/subdir_empty_1.cpp new file mode 100644 index 0000000..11ec041 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirGenEx/subdir_empty_1.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude-stdout.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude-stdout.txt new file mode 100644 index 0000000..aa4851f --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude-stdout.txt @@ -0,0 +1 @@ +-- privatelib: .*Tests/RunCMake/TargetSources/RelativePathInSubdirInclude/subdir_empty_1.cpp;empty_1.cpp diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude.cmake b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude.cmake new file mode 100644 index 0000000..4acbeca --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude.cmake @@ -0,0 +1,8 @@ +cmake_policy(SET CMP0076 NEW) + +add_library(privatelib) + +include("RelativePathInSubdirInclude/CMakeLists.txt") + +get_property(privatelib_sources TARGET privatelib PROPERTY SOURCES) +message(STATUS "privatelib: ${privatelib_sources}") diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude/CMakeLists.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude/CMakeLists.txt new file mode 100644 index 0000000..3dcb135 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude/CMakeLists.txt @@ -0,0 +1,3 @@ + +target_sources(privatelib PRIVATE "${CMAKE_CURRENT_LIST_DIR}/subdir_empty_1.cpp" + empty_1.cpp) diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude/subdir_empty_1.cpp b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude/subdir_empty_1.cpp new file mode 100644 index 0000000..11ec041 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInclude/subdir_empty_1.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface-stdout.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface-stdout.txt new file mode 100644 index 0000000..5990a05 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface-stdout.txt @@ -0,0 +1 @@ +-- iface: .*Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_1.cpp;.*Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_2.cpp;.*Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/../empty_1.cpp;.*Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/../empty_2.cpp diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface.cmake b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface.cmake new file mode 100644 index 0000000..3652b4f --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface.cmake @@ -0,0 +1,11 @@ +cmake_policy(SET CMP0076 NEW) + +add_library(iface INTERFACE) + +add_subdirectory(RelativePathInSubdirInterface) + +get_property(iface_sources TARGET iface PROPERTY INTERFACE_SOURCES) +message(STATUS "iface: ${iface_sources}") + +add_executable(main main.cpp) +target_link_libraries(main iface) diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/CMakeLists.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/CMakeLists.txt new file mode 100644 index 0000000..02e6966 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/CMakeLists.txt @@ -0,0 +1,5 @@ + +target_sources(iface INTERFACE subdir_empty_1.cpp + "${CMAKE_CURRENT_LIST_DIR}/subdir_empty_2.cpp" + ../empty_1.cpp + "${CMAKE_CURRENT_LIST_DIR}/../empty_2.cpp") diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_1.cpp b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_1.cpp new file mode 100644 index 0000000..11ec041 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_1.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_2.cpp b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_2.cpp new file mode 100644 index 0000000..11ec041 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirInterface/subdir_empty_2.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate-stdout.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate-stdout.txt new file mode 100644 index 0000000..fa5bcbf --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate-stdout.txt @@ -0,0 +1 @@ +-- privatelib: .*Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_1.cpp;.*Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_2.cpp;.*Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/../empty_1.cpp;.*Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/../empty_2.cpp diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate.cmake b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate.cmake new file mode 100644 index 0000000..d0d3dc4 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate.cmake @@ -0,0 +1,8 @@ +cmake_policy(SET CMP0076 NEW) + +add_library(privatelib) + +add_subdirectory(RelativePathInSubdirPrivate) + +get_property(privatelib_sources TARGET privatelib PROPERTY SOURCES) +message(STATUS "privatelib: ${privatelib_sources}") diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/CMakeLists.txt b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/CMakeLists.txt new file mode 100644 index 0000000..56ee853 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/CMakeLists.txt @@ -0,0 +1,5 @@ + +target_sources(privatelib PRIVATE subdir_empty_1.cpp + "${CMAKE_CURRENT_LIST_DIR}/subdir_empty_2.cpp" + ../empty_1.cpp + "${CMAKE_CURRENT_LIST_DIR}/../empty_2.cpp") diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_1.cpp b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_1.cpp new file mode 100644 index 0000000..11ec041 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_1.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_2.cpp b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_2.cpp new file mode 100644 index 0000000..11ec041 --- /dev/null +++ b/Tests/RunCMake/TargetSources/RelativePathInSubdirPrivate/subdir_empty_2.cpp @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int empty() +{ + return 0; +} diff --git a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake index 36d01de..bee8c4e 100644 --- a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake +++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake @@ -6,5 +6,11 @@ endif() run_cmake(OriginDebug) run_cmake(CMP0026-LOCATION) +run_cmake(CMP0076-OLD) +run_cmake(CMP0076-WARN) run_cmake(RelativePathInInterface) +run_cmake(RelativePathInSubdirGenEx) +run_cmake(RelativePathInSubdirInterface) +run_cmake(RelativePathInSubdirPrivate) +run_cmake(RelativePathInSubdirInclude) run_cmake(ExportBuild) 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/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/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..4f5df72 --- /dev/null +++ b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake @@ -0,0 +1,38 @@ + +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() + +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/find_program/RelAndAbsPath-stdout.txt b/Tests/RunCMake/find_program/RelAndAbsPath-stdout.txt new file mode 100644 index 0000000..cb3c99f --- /dev/null +++ b/Tests/RunCMake/find_program/RelAndAbsPath-stdout.txt @@ -0,0 +1,6 @@ +-- PROG_ABS='PROG_ABS-NOTFOUND' +-- PROG_ABS_NPD='PROG_ABS_NPD-NOTFOUND' +-- PROG_CWD='PROG_CWD-NOTFOUND' +-- PROG_CWD_NPD='PROG_CWD_NPD-NOTFOUND' +-- PROG_CWD_DOT='[^']*/Tests/RunCMake/find_program/testCWD' +-- PROG_CWD_DOT_NPD='[^']*/Tests/RunCMake/find_program/testCWD' diff --git a/Tests/RunCMake/find_program/RelAndAbsPath.cmake b/Tests/RunCMake/find_program/RelAndAbsPath.cmake new file mode 100644 index 0000000..9a42c5e --- /dev/null +++ b/Tests/RunCMake/find_program/RelAndAbsPath.cmake @@ -0,0 +1,63 @@ +# testNoSuchFile should only be found if the file absolute path is +# incorrectly prepended with the search path. + +function(strip_windows_path_prefix p outvar) + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + string(REGEX REPLACE "^.:" "" p "${p}") + endif() + set(${outvar} "${p}" PARENT_SCOPE) +endfunction() + +strip_windows_path_prefix("${CMAKE_CURRENT_SOURCE_DIR}" srcdir) + +file(MAKE_DIRECTORY "tmp${srcdir}") +configure_file(testCWD "tmp${srcdir}/testNoSuchFile" COPYONLY) + +find_program(PROG_ABS + NAMES "${srcdir}/testNoSuchFile" + PATHS "${CMAKE_CURRENT_BINARY_DIR}/tmp" + NO_DEFAULT_PATH + ) +message(STATUS "PROG_ABS='${PROG_ABS}'") + +find_program(PROG_ABS_NPD + NAMES "${srcdir}/testNoSuchFile" + PATHS "${CMAKE_CURRENT_BINARY_DIR}/tmp" + NAMES_PER_DIR + NO_DEFAULT_PATH + ) +message(STATUS "PROG_ABS_NPD='${PROG_ABS_NPD}'") + +# ./testCWD should not be found without '.' being in the path list. + +configure_file(testCWD testCWD COPYONLY) + +find_program(PROG_CWD + NAMES testCWD + NO_DEFAULT_PATH + ) +message(STATUS "PROG_CWD='${PROG_CWD}'") + +find_program(PROG_CWD_NPD + NAMES testCWD + NAMES_PER_DIR + NO_DEFAULT_PATH + ) +message(STATUS "PROG_CWD_NPD='${PROG_CWD_NPD}'") + +# Confirm that adding '.' to path does locate ./testCWD. + +find_program(PROG_CWD_DOT + NAMES testCWD + PATHS . + NO_DEFAULT_PATH + ) +message(STATUS "PROG_CWD_DOT='${PROG_CWD_DOT}'") + +find_program(PROG_CWD_DOT_NPD + NAMES testCWD + PATHS . + NAMES_PER_DIR + NO_DEFAULT_PATH + ) +message(STATUS "PROG_CWD_DOT_NPD='${PROG_CWD_DOT_NPD}'") diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake index 89307c1..6903f05 100644 --- a/Tests/RunCMake/find_program/RunCMakeTest.cmake +++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake @@ -3,6 +3,7 @@ include(RunCMake) run_cmake(EnvAndHints) run_cmake(DirsPerName) run_cmake(NamesPerDir) +run_cmake(RelAndAbsPath) if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN)$") run_cmake(WindowsCom) diff --git a/Tests/RunCMake/find_program/testCWD b/Tests/RunCMake/find_program/testCWD new file mode 100755 index 0000000..1a24852 --- /dev/null +++ b/Tests/RunCMake/find_program/testCWD @@ -0,0 +1 @@ +#!/bin/sh diff --git a/Tests/RunCMake/install/CODE-genex-bad-result.txt b/Tests/RunCMake/install/CODE-genex-bad-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/CODE-genex-bad-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/CODE-genex-bad-stderr.txt b/Tests/RunCMake/install/CODE-genex-bad-stderr.txt new file mode 100644 index 0000000..9844158 --- /dev/null +++ b/Tests/RunCMake/install/CODE-genex-bad-stderr.txt @@ -0,0 +1,6 @@ +CMake Error: + Error evaluating generator expression: + + \$<NOTAGENEX> + + Expression did not evaluate to a known generator expression diff --git a/Tests/RunCMake/install/CODE-genex-bad.cmake b/Tests/RunCMake/install/CODE-genex-bad.cmake new file mode 100644 index 0000000..1663b39 --- /dev/null +++ b/Tests/RunCMake/install/CODE-genex-bad.cmake @@ -0,0 +1 @@ +install(CODE "message(\"$<NOTAGENEX>\")") diff --git a/Tests/RunCMake/install/CODE-genex-check.cmake b/Tests/RunCMake/install/CODE-genex-check.cmake new file mode 100644 index 0000000..422c532 --- /dev/null +++ b/Tests/RunCMake/install/CODE-genex-check.cmake @@ -0,0 +1,7 @@ +execute_process(COMMAND ${CMAKE_COMMAND} -P ${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake + OUTPUT_VARIABLE out ERROR_VARIABLE err) +if(NOT out MATCHES "-- Install configuration: .*-- codegenexlib") + string(REGEX REPLACE "\n" "\n " out " ${out}") + string(APPEND RunCMake_TEST_FAILED + "\"-- codegenexlib\" was not found:\n${out}") +endif() diff --git a/Tests/RunCMake/install/CODE-genex.cmake b/Tests/RunCMake/install/CODE-genex.cmake new file mode 100644 index 0000000..3b8513d --- /dev/null +++ b/Tests/RunCMake/install/CODE-genex.cmake @@ -0,0 +1,2 @@ +add_library( codegenexlib INTERFACE ) +install(CODE "message( STATUS \"$<TARGET_PROPERTY:codegenexlib,NAME>\")") diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index f004ce9..f0c02d8 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -65,6 +65,8 @@ run_cmake(CMP0062-NEW) run_cmake(CMP0062-WARN) run_cmake(TARGETS-NAMELINK_COMPONENT-bad-all) run_cmake(TARGETS-NAMELINK_COMPONENT-bad-exc) +run_cmake(CODE-genex) +run_cmake(CODE-genex-bad) if(NOT RunCMake_GENERATOR STREQUAL "Xcode" OR NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]") run_install_test(FILES-TARGET_OBJECTS) diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake index bdc23a4..a8a0b57 100644 --- a/Tests/RunCMake/list/RunCMakeTest.cmake +++ b/Tests/RunCMake/list/RunCMakeTest.cmake @@ -20,7 +20,6 @@ run_cmake(JOIN-TooManyArguments) run_cmake(LENGTH-TooManyArguments) run_cmake(REMOVE_DUPLICATES-TooManyArguments) run_cmake(REVERSE-TooManyArguments) -run_cmake(SORT-TooManyArguments) run_cmake(SUBLIST-TooManyArguments) run_cmake(FILTER-NotList) @@ -84,3 +83,16 @@ run_cmake(TRANSFORM-GENEX_STRIP) run_cmake(TRANSFORM-APPEND) run_cmake(TRANSFORM-PREPEND) run_cmake(TRANSFORM-REPLACE) + +# argument tests +run_cmake(SORT-WrongOption) +run_cmake(SORT-BadCaseOption) +run_cmake(SORT-BadCompareOption) +run_cmake(SORT-BadOrderOption) +run_cmake(SORT-DuplicateOrderOption) +run_cmake(SORT-DuplicateCompareOption) +run_cmake(SORT-DuplicateCaseOption) +run_cmake(SORT-NoCaseOption) + +# Successful tests +run_cmake(SORT) diff --git a/Tests/RunCMake/list/SORT-BadCaseOption-result.txt b/Tests/RunCMake/list/SORT-BadCaseOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadCaseOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-BadCaseOption-stderr.txt b/Tests/RunCMake/list/SORT-BadCaseOption-stderr.txt new file mode 100644 index 0000000..87dd502 --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadCaseOption-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at SORT-BadCaseOption.cmake:1 \(list\): + list sub-command SORT value "BAD_CASE_OPTION" for option "CASE" is invalid. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-BadCaseOption.cmake b/Tests/RunCMake/list/SORT-BadCaseOption.cmake new file mode 100644 index 0000000..ac5c102 --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadCaseOption.cmake @@ -0,0 +1 @@ +list(SORT mylist CASE BAD_CASE_OPTION) diff --git a/Tests/RunCMake/list/SORT-BadCompareOption-result.txt b/Tests/RunCMake/list/SORT-BadCompareOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadCompareOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-BadCompareOption-stderr.txt b/Tests/RunCMake/list/SORT-BadCompareOption-stderr.txt new file mode 100644 index 0000000..51b4de2 --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadCompareOption-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at SORT-BadCompareOption.cmake:1 \(list\): + list sub-command SORT value "BAD_COMPARE_OPTION" for option "COMPARE" is + invalid. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-BadCompareOption.cmake b/Tests/RunCMake/list/SORT-BadCompareOption.cmake new file mode 100644 index 0000000..d5c632e --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadCompareOption.cmake @@ -0,0 +1 @@ +list(SORT mylist COMPARE BAD_COMPARE_OPTION) diff --git a/Tests/RunCMake/list/SORT-BadOrderOption-result.txt b/Tests/RunCMake/list/SORT-BadOrderOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadOrderOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-BadOrderOption-stderr.txt b/Tests/RunCMake/list/SORT-BadOrderOption-stderr.txt new file mode 100644 index 0000000..7984e5c --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadOrderOption-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at SORT-BadOrderOption.cmake:1 \(list\): + list sub-command SORT value "BAD_ODER_OPTION" for option "ORDER" is + invalid. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-BadOrderOption.cmake b/Tests/RunCMake/list/SORT-BadOrderOption.cmake new file mode 100644 index 0000000..e232197 --- /dev/null +++ b/Tests/RunCMake/list/SORT-BadOrderOption.cmake @@ -0,0 +1 @@ +list(SORT mylist ORDER BAD_ODER_OPTION) diff --git a/Tests/RunCMake/list/SORT-DuplicateCaseOption-result.txt b/Tests/RunCMake/list/SORT-DuplicateCaseOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateCaseOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-DuplicateCaseOption-stderr.txt b/Tests/RunCMake/list/SORT-DuplicateCaseOption-stderr.txt new file mode 100644 index 0000000..b893f50 --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateCaseOption-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at SORT-DuplicateCaseOption.cmake:2 \(list\): + list sub-command SORT option "CASE" has been specified multiple times. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-DuplicateCaseOption.cmake b/Tests/RunCMake/list/SORT-DuplicateCaseOption.cmake new file mode 100644 index 0000000..ba52b24 --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateCaseOption.cmake @@ -0,0 +1,2 @@ +set (mylist a b c) +list(SORT mylist CASE INSENSITIVE CASE INSENSITIVE ) diff --git a/Tests/RunCMake/list/SORT-DuplicateCompareOption-result.txt b/Tests/RunCMake/list/SORT-DuplicateCompareOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateCompareOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-DuplicateCompareOption-stderr.txt b/Tests/RunCMake/list/SORT-DuplicateCompareOption-stderr.txt new file mode 100644 index 0000000..83624be --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateCompareOption-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at SORT-DuplicateCompareOption.cmake:2 \(list\): + list sub-command SORT option "COMPARE" has been specified multiple times. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-DuplicateCompareOption.cmake b/Tests/RunCMake/list/SORT-DuplicateCompareOption.cmake new file mode 100644 index 0000000..fd2e31d --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateCompareOption.cmake @@ -0,0 +1,2 @@ +set (mylist a b c) +list(SORT mylist COMPARE STRING COMPARE STRING) diff --git a/Tests/RunCMake/list/SORT-DuplicateOrderOption-result.txt b/Tests/RunCMake/list/SORT-DuplicateOrderOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateOrderOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-DuplicateOrderOption-stderr.txt b/Tests/RunCMake/list/SORT-DuplicateOrderOption-stderr.txt new file mode 100644 index 0000000..9e95178 --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateOrderOption-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at SORT-DuplicateOrderOption.cmake:2 \(list\): + list sub-command SORT option "ORDER" has been specified multiple times. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-DuplicateOrderOption.cmake b/Tests/RunCMake/list/SORT-DuplicateOrderOption.cmake new file mode 100644 index 0000000..26d9c7d --- /dev/null +++ b/Tests/RunCMake/list/SORT-DuplicateOrderOption.cmake @@ -0,0 +1,2 @@ +set (mylist a b c) +list(SORT mylist ORDER ASCENDING ORDER ASCENDING) diff --git a/Tests/RunCMake/list/SORT-NoCaseOption-result.txt b/Tests/RunCMake/list/SORT-NoCaseOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-NoCaseOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-NoCaseOption-stderr.txt b/Tests/RunCMake/list/SORT-NoCaseOption-stderr.txt new file mode 100644 index 0000000..5c63e77 --- /dev/null +++ b/Tests/RunCMake/list/SORT-NoCaseOption-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at SORT-NoCaseOption.cmake:1 \(list\): + list sub-command SORT missing argument for option "CASE". +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-NoCaseOption.cmake b/Tests/RunCMake/list/SORT-NoCaseOption.cmake new file mode 100644 index 0000000..57cc429 --- /dev/null +++ b/Tests/RunCMake/list/SORT-NoCaseOption.cmake @@ -0,0 +1 @@ +list(SORT mylist CASE) diff --git a/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt b/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt deleted file mode 100644 index d3fad60..0000000 --- a/Tests/RunCMake/list/SORT-TooManyArguments-stderr.txt +++ /dev/null @@ -1,4 +0,0 @@ -^CMake Error at SORT-TooManyArguments.cmake:1 \(list\): - list sub-command SORT only takes one argument. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-WrongOption-result.txt b/Tests/RunCMake/list/SORT-WrongOption-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/list/SORT-WrongOption-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/list/SORT-WrongOption-stderr.txt b/Tests/RunCMake/list/SORT-WrongOption-stderr.txt new file mode 100644 index 0000000..597cb29 --- /dev/null +++ b/Tests/RunCMake/list/SORT-WrongOption-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at SORT-WrongOption.cmake:1 \(list\): + list sub-command SORT option "one_too_many" is unknown. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/list/SORT-TooManyArguments.cmake b/Tests/RunCMake/list/SORT-WrongOption.cmake index 81b195d..81b195d 100644 --- a/Tests/RunCMake/list/SORT-TooManyArguments.cmake +++ b/Tests/RunCMake/list/SORT-WrongOption.cmake diff --git a/Tests/RunCMake/list/SORT.cmake b/Tests/RunCMake/list/SORT.cmake new file mode 100644 index 0000000..4a9e064 --- /dev/null +++ b/Tests/RunCMake/list/SORT.cmake @@ -0,0 +1,114 @@ +set(source_unsorted + c/B.h + a/c.h + B/a.h + ) + +## Test with default options +set(expected + B/a.h + a/c.h + c/B.h + ) +set(list ${source_unsorted}) +list(SORT list) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE STRING)") +endif () + + +## Test CASE INSENSITIVE ORDER ASCENDING COMPARE STRING +set(expected + a/c.h + B/a.h + c/B.h + ) +set(list ${source_unsorted}) +list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE STRING) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE STRING)") +endif () + +## Test CASE INSENSITIVE ORDER DESCENDING COMPARE STRING +set(expected + c/B.h + B/a.h + a/c.h + ) +set(list ${source_unsorted}) +list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE STRING) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE STRING)") +endif () + +## Test CASE SENSITIVE ORDER ASCENDING COMPARE STRING +set(expected + B/a.h + a/c.h + c/B.h + ) +set(list ${source_unsorted}) +list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE STRING) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE STRING)") +endif () + +## Test CASE SENSITIVE ORDER DESCENDING COMPARE STRING +set(expected + c/B.h + a/c.h + B/a.h + ) +set(list ${source_unsorted}) +list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE STRING) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE STRING)") +endif () + +## Test CASE INSENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME +set(expected + B/a.h + c/B.h + a/c.h + ) +set(list ${source_unsorted}) +list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)") +endif () + +## Test CASE INSENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME +set(expected + a/c.h + c/B.h + B/a.h + ) +set(list ${source_unsorted}) +list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE INSENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)") +endif () + +## Test CASE SENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME +set(expected + c/B.h + B/a.h + a/c.h + ) +set(list ${source_unsorted}) +list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)") +endif () + +## Test CASE SENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME +set(expected + a/c.h + B/a.h + c/B.h + ) +set(list ${source_unsorted}) +list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME) +if (NOT expected STREQUAL list) + message(FATAL_ERROR "wrong sort result with command list(SORT list CASE SENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)") +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/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/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..121a0ce --- /dev/null +++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake @@ -0,0 +1,39 @@ + +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() + +run_cmake(bad_SHELL_usage) + +if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)") + run_cmake(LINKER_expansion) + + 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; +} diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt index cc29b77..4c3d901 100644 --- a/Tests/UseSWIG/CMakeLists.txt +++ b/Tests/UseSWIG/CMakeLists.txt @@ -88,3 +88,14 @@ add_test(NAME UseSWIG.ModuleVersion2 COMMAND --build-options ${build_options} --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) + + +add_test(NAME UseSWIG.UseTargetINCLUDE_DIRECTORIES COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES" + "${CMake_BINARY_DIR}/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES" + ${build_generator_args} + --build-project TestModuleVersion2 + --build-options ${build_options} + ) diff --git a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt new file mode 100644 index 0000000..3e266c3 --- /dev/null +++ b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.1) + +project(TestUseTargetINCLUDE_DIRECTORIES CXX) + +include(CTest) + +find_package(SWIG REQUIRED) +include(${SWIG_USE_FILE}) + +find_package(Python3 REQUIRED COMPONENTS Interpreter Development) + +unset(CMAKE_SWIG_FLAGS) + +set_property(SOURCE "example.i" PROPERTY CPLUSPLUS ON) +set_property(SOURCE "example.i" PROPERTY COMPILE_OPTIONS -includeall) + +swig_add_library(example1 + LANGUAGE python + OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/example1" + SOURCES example.i ../example.cxx) +set_target_properties (example1 PROPERTIES + INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/.." + SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE + OUTPUT_NAME example1 + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example1") +target_link_libraries(example1 PRIVATE Python3::Python) + + +# Check that source property override target property +set_property(SOURCE "example.i" PROPERTY USE_TARGET_INCLUDE_DIRECTORIES TRUE) + +swig_add_library(example2 + LANGUAGE python + OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/example2" + SOURCES example.i ../example.cxx) +set_target_properties (example2 PROPERTIES + INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/.." + SWIG_USE_TARGET_INCLUDE_DIRECTORIES FALSE + OUTPUT_NAME example2 + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/example2") +target_link_libraries(example2 PRIVATE Python3::Python) diff --git a/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i new file mode 100644 index 0000000..fbdf724 --- /dev/null +++ b/Tests/UseSWIG/UseTargetINCLUDE_DIRECTORIES/example.i @@ -0,0 +1,9 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" |