diff options
67 files changed, 796 insertions, 581 deletions
diff --git a/Help/command/option.rst b/Help/command/option.rst index 02b8dac..464ad44 100644 --- a/Help/command/option.rst +++ b/Help/command/option.rst @@ -1,16 +1,18 @@ option ------ -Provide an option that the user can optionally select. +Provide a boolean option that the user can optionally select. .. code-block:: cmake option(<variable> "<help_text>" [value]) -Provides an option for the user to select as ``ON`` or ``OFF``. -If no initial ``<value>`` is provided, ``OFF`` is used. +If no initial ``<value>`` is provided, boolean ``OFF`` is the default value. If ``<variable>`` is already set as a normal or cache variable, then the command does nothing (see policy :policy:`CMP0077`). -If you have options that depend on the values of other options, see +For options that depend on the values of other options, see the module help for :module:`CMakeDependentOption`. + +In CMake project mode, a boolean cache variable is created with the option +value. In CMake script mode, a boolean variable is set with the option value. diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst index 47e8e13..a77b615 100644 --- a/Help/cpack_gen/archive.rst +++ b/Help/cpack_gen/archive.rst @@ -49,6 +49,8 @@ Variables specific to CPack Archive generator Package file name without extension. The extension is determined from the archive format (see list above) and automatically appended to the file name. + Note that ``<component>`` is all uppercase in the variable name. + The default is ``<CPACK_PACKAGE_FILE_NAME>[-<component>]``, with spaces replaced by '-'. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index c871b1b..f53af37 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -1044,6 +1044,10 @@ which is just the string ``tgt``. Full path to the ``tgt`` binary file. + Note that ``tgt`` is not added as a dependency of the target this + expression is evaluated on, unless the expression is being used in + :command:`add_custom_command` or :command:`add_custom_target`. + .. genex:: $<TARGET_FILE_BASE_NAME:tgt> .. versionadded:: 3.15 @@ -1370,229 +1374,237 @@ Output-Related Expressions .. versionadded:: 3.24 - Manage how libraries are specified during the link step. - This expression may be used to specify how to link libraries in a target. - For example: + Specify a set of libraries to link to a target, along with a ``feature`` + which provides details about *how* they should be linked. For example: .. code-block:: cmake add_library(lib1 STATIC ...) add_library(lib2 ...) - target_link_libraries(lib2 PRIVATE "$<LINK_LIBRARY:load_archive,lib1>") - - This specify to use the ``lib1`` target with feature ``load_archive`` for - linking target ``lib2``. The feature must have be defined by - :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` variable or, if - :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is false, - by :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable. + target_link_libraries(lib2 PRIVATE "$<LINK_LIBRARY:WHOLE_ARCHIVE,lib1>") - .. note:: - - The evaluation of this generator expression will use, for the following - variables, the values defined at the level of the creation of the target: + This specifies that ``lib2`` should link to ``lib1`` and use the + ``WHOLE_ARCHIVE`` feature when doing so. - * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` - * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` - * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` - * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` + Feature names are case-sensitive and may only contain letters, numbers and + underscores. Feature names defined in all uppercase are reserved for CMake's + own built-in features. The pre-defined built-in library features are: - This expression can only be used to specify link libraries (i.e. part of - :command:`link_libraries` or :command:`target_link_libraries` commands and - :prop_tgt:`LINK_LIBRARIES` or :prop_tgt:`INTERFACE_LINK_LIBRARIES` target - properties). - - .. note:: - - If this expression appears in the :prop_tgt:`INTERFACE_LINK_LIBRARIES` - property of a target, it will be included in the imported target generated - by :command:`install(EXPORT)` command. It is the responsibility of the - environment consuming this import to define the link feature used by this - expression. - - The ``library-list`` argument can hold CMake targets or external libraries. - Any CMake target of type :ref:`OBJECT <Object Libraries>` or - :ref:`INTERFACE <Interface Libraries>` will be ignored by this expression and - will be handled in the standard way. - - Each target or external library involved in the link step must have only one - kind of feature (the absence of feature is also incompatible with any - feature). For example: - - .. code-block:: cmake - - add_library(lib1 ...) + .. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt - add_library(lib2 ...) - target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature1,lib1>") + Built-in and custom library features are defined in terms of the following + variables: + + * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` + * :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` + * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` + * :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` + + The value used for each of these variables is the value as set at the end of + the directory scope in which the target was created. The usage is as follows: + + 1. If the language-specific + :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` variable + is true, the ``feature`` must be defined by the corresponding + :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` variable. + 2. If no language-specific ``feature`` is supported, then the + :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` variable must be + true and the ``feature`` must be defined by the corresponding + :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable. + + The following limitations should be noted: + + * The ``library-list`` can specify CMake targets or libraries. + Any CMake target of type :ref:`OBJECT <Object Libraries>` + or :ref:`INTERFACE <Interface Libraries>` will ignore the feature aspect + of the expression and instead be linked in the standard way. + + * The ``$<LINK_LIBRARY:...>`` generator expression can only be used to + specify link libraries. In practice, this means it can appear in the + :prop_tgt:`LINK_LIBRARIES` and :prop_tgt:`INTERFACE_LINK_LIBRARIES` + target properties, and be specified in :command:`target_link_libraries` + and :command:`link_libraries` commands. + + * If a ``$<LINK_LIBRARY:...>`` generator expression appears in the + :prop_tgt:`INTERFACE_LINK_LIBRARIES` property of a target, it will be + included in the imported target generated by a :command:`install(EXPORT)` + command. It is the responsibility of the environment consuming this + import to define the link feature used by this expression. + + * Each target or library involved in the link step must have at most only + one kind of library feature. The absence of a feature is also incompatible + with all other features. For example: - add_library(lib3 ...) - target_link_libraries(lib3 PRIVATE lib1 lib2) - # an error will be raised here because lib1 has two different features + .. code-block:: cmake - To resolve such incompatibilities, the :prop_tgt:`LINK_LIBRARY_OVERRIDE` - and :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties can be - used. + add_library(lib1 ...) + add_library(lib2 ...) + add_library(lib3 ...) - .. note:: + # lib1 will be associated with feature1 + target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature1,lib1>") - This expression does not guarantee that the list of specified libraries - will be kept grouped. So, to manage constructs like ``start-group`` and - ``end-group``, as supported by ``GNU ld``, the :genex:`LINK_GROUP` - generator expression can be used. + # lib1 is being linked with no feature here. This conflicts with the + # use of feature1 in the line above and would result in an error. + target_link_libraries(lib3 PRIVATE lib1 lib2) - CMake pre-defines some features of general interest: + Where it isn't possible to use the same feature throughout a build for a + given target or library, the :prop_tgt:`LINK_LIBRARY_OVERRIDE` and + :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties can be + used to resolve such incompatibilities. - .. include:: ../variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt + * The ``$<LINK_LIBRARY:...>`` generator expression does not guarantee + that the list of specified targets and libraries will be kept grouped + together. To manage constructs like ``--start-group`` and ``--end-group``, + as supported by the GNU ``ld`` linker, use the :genex:`LINK_GROUP` + generator expression instead. .. genex:: $<LINK_GROUP:feature,library-list> .. versionadded:: 3.24 - Manage the grouping of libraries during the link step. - This expression may be used to specify how to keep groups of libraries during - the link of a target. - For example: + Specify a group of libraries to link to a target, along with a ``feature`` + which defines how that group should be linked. For example: .. code-block:: cmake add_library(lib1 STATIC ...) add_library(lib2 ...) - target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>") + target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:RESCAN,lib1,external>") - This specify to use the ``lib1`` target and ``external`` library with the - group feature ``cross_refs`` for linking target ``lib2``. The feature must - have be defined by :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` - variable or, if :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` - is false, by :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable. + This specifies that ``lib2`` should link to ``lib1`` and ``external``, and + that both of those two libraries should be included on the linker command + line according to the definition of the ``RESCAN`` feature. - .. note:: + Feature names are case-sensitive and may only contain letters, numbers and + underscores. Feature names defined in all uppercase are reserved for CMake's + own built-in features. Currently, there is only one pre-defined built-in + group feature: - The evaluation of this generator expression will use, for the following - variables, the values defined at the level of the creation of the target: + .. include:: ../variable/LINK_GROUP_PREDEFINED_FEATURES.txt - * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` - * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` - * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` - * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` + Built-in and custom group features are defined in terms of the following + variables: - This expression can only be used to specify link libraries (i.e. part of - :command:`link_libraries` or :command:`target_link_libraries` commands and - :prop_tgt:`LINK_LIBRARIES` or :prop_tgt:`INTERFACE_LINK_LIBRARIES` target - properties). + * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` + * :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` + * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` + * :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` - .. note:: + The value used for each of these variables is the value as set at the end of + the directory scope in which the target was created. The usage is as follows: - If this expression appears in the :prop_tgt:`INTERFACE_LINK_LIBRARIES` - property of a target, it will be included in the imported target generated - by :command:`install(EXPORT)` command. It is the responsibility of the - environment consuming this import to define the link feature used by this - expression. + 1. If the language-specific + :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable + is true, the ``feature`` must be defined by the corresponding + :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable. + 2. If no language-specific ``feature`` is supported, then the + :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable must be + true and the ``feature`` must be defined by the corresponding + :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable. - The ``library-list`` argument can hold CMake targets or external libraries. - Any CMake target of type :ref:`OBJECT <Object Libraries>` or - :ref:`INTERFACE <Interface Libraries>` will be ignored by this expression and - will be handled in the standard way. + The ``LINK_GROUP`` generator expression is compatible with the + :genex:`LINK_LIBRARY` generator expression. The libraries involved in a + group can be specified using the :genex:`LINK_LIBRARY` generator expression. - .. note:: - - This expression is compatible with the :genex:`LINK_LIBRARY` generator - expression. The libraries involved in a group can be specified using the - :genex:`LINK_LIBRARY` generator expression. - - Each target or external library involved in the link step can be part of - different groups as far as these groups use the same feature, so mixing - different group features for the same target or library is forbidden. The - different groups will be part of the link step. + Each target or external library involved in the link step is allowed to be + part of multiple groups, but only if all the groups involved specify the + same ``feature``. Such groups will not be merged on the linker command line, + the individual groups will still be preserved. Mixing different group + features for the same target or library is forbidden. .. code-block:: cmake add_library(lib1 ...) add_library(lib2 ...) - add_library(lib3 ...) - target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>") - add_library(lib4 ...) + add_library(lib5 ...) + + target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>") target_link_libraries(lib4 PRIVATE "$<LINK_GROUP:feature1,lib1,lib3>") - # lib4 will be linked with the groups {lib1,lib2} and {lib1,lib3} + # lib4 will be linked with the groups {lib1,lib2} and {lib1,lib3}. + # Both groups specify the same feature, so this is fine. - add_library(lib5 ...) target_link_libraries(lib5 PRIVATE "$<LINK_GROUP:feature2,lib1,lib3>") - # an error will be raised here because lib1 is part of two groups with - # different features + # An error will be raised here because both lib1 and lib3 are part of two + # groups with different features. When a target or an external library is involved in the link step as part of - a group and also as standalone, any occurrence of the standalone link item - will be replaced by the group or groups it belong to. + a group and also as not part of any group, any occurrence of the non-group + link item will be replaced by the groups it belongs to. .. code-block:: cmake add_library(lib1 ...) add_library(lib2 ...) - add_library(lib3 ...) + add_library(lib4 ...) + target_link_libraries(lib3 PUBLIC lib1) - add_library(lib4 ...) target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>") # lib4 will only be linked with lib3 and the group {lib1,lib2} - This example will be "re-written" by CMake in the following form: + Because ``lib1`` is part of the group defined for ``lib4``, that group then + gets applied back to the use of ``lib1`` for ``lib3``. The end result will + be as though the linking relationship for ``lib3`` had been specified as: .. code-block:: cmake - add_library(lib1 ...) - add_library(lib2 ...) - - add_library(lib3 ...) target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>") - add_library(lib4 ...) - target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>") - # lib4 will only be linked with lib3 and the group {lib1,lib2} - - Be aware that the precedence of the group over the standalone link item can - result in some circular dependency between groups, which will raise an - error because circular dependencies are not allowed for groups. + Be aware that the precedence of the group over the non-group link item can + result in circular dependencies between groups. If this occurs, a fatal + error is raised because circular dependencies are not allowed for groups. .. code-block:: cmake add_library(lib1A ...) add_library(lib1B ...) - add_library(lib2A ...) add_library(lib2B ...) + add_library(lib3 ...) + # Non-group linking relationships, these are non-circular so far target_link_libraries(lib1A PUBLIC lib2A) target_link_libraries(lib2B PUBLIC lib1B) - add_library(lib ...) - target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:feat,lib1A,lib1B>" - "$<LINK_GROUP:feat,lib2A,lib2B>") + # The addition of these groups creates circular dependencies + target_link_libraries(lib3 PRIVATE + "$<LINK_GROUP:feat,lib1A,lib1B>" + "$<LINK_GROUP:feat,lib2A,lib2B>" + ) - This example will be "re-written" by CMake in the following form: + Because of the groups defined for ``lib3``, the linking relationships for + ``lib1A`` and ``lib2B`` effectively get expanded to the equivalent of: .. code-block:: cmake - add_library(lib1A ...) - add_library(lib1B ...) - - add_library(lib2A ...) - add_library(lib2B ...) - target_link_libraries(lib1A PUBLIC "$<LINK_GROUP:feat,lib2A,lib2B>") target_link_libraries(lib2B PUBLIC "$<LINK_GROUP:feat,lib1A,lib1B>") - add_library(lib ...) - target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:feat,lib1A,lib1B>" - "$<LINK_GROUP:feat,lib2A,lib2B>") + This creates a circular dependency between groups: + ``lib1A --> lib2B --> lib1A``. - So, we have a circular dependency between groups ``{lib1A,lib1B}`` and - ``{lib2A,lib2B}``. + The following limitations should also be noted: - CMake pre-defines some features of general interest: + * The ``library-list`` can specify CMake targets or libraries. + Any CMake target of type :ref:`OBJECT <Object Libraries>` + or :ref:`INTERFACE <Interface Libraries>` will ignore the feature aspect + of the expression and instead be linked in the standard way. - .. include:: ../variable/LINK_GROUP_PREDEFINED_FEATURES.txt + * The ``$<LINK_GROUP:...>`` generator expression can only be used to + specify link libraries. In practice, this means it can appear in the + :prop_tgt:`LINK_LIBRARIES` and :prop_tgt:`INTERFACE_LINK_LIBRARIES` + target properties, and be specified in :command:`target_link_libraries` + and :command:`link_libraries` commands. + + * If a ``$<LINK_GROUP:...>`` generator expression appears in the + :prop_tgt:`INTERFACE_LINK_LIBRARIES` property of a target, it will be + included in the imported target generated by a :command:`install(EXPORT)` + command. It is the responsibility of the environment consuming this + import to define the link feature used by this expression. .. genex:: $<INSTALL_INTERFACE:...> diff --git a/Help/policy/CMP0131.rst b/Help/policy/CMP0131.rst index e85b8ab..d5430e4 100644 --- a/Help/policy/CMP0131.rst +++ b/Help/policy/CMP0131.rst @@ -20,7 +20,7 @@ account for this change. The ``OLD`` behavior for this policy is to use :prop_tgt:`LINK_LIBRARIES` content guarded by :genex:`$<LINK_ONLY:...>` even for non-linking -usage requirements. The ``NEW`` behavior for this policy is to to use +usage requirements. The ``NEW`` behavior for this policy is to use the guarded content only for link dependencies. This policy was introduced in CMake version 3.24. Use the diff --git a/Help/prop_tgt/LINK_LIBRARIES.rst b/Help/prop_tgt/LINK_LIBRARIES.rst index ae5334a..b5c1d89 100644 --- a/Help/prop_tgt/LINK_LIBRARIES.rst +++ b/Help/prop_tgt/LINK_LIBRARIES.rst @@ -14,10 +14,13 @@ followed by indirect dependencies from the transitive closure of the direct dependencies' :prop_tgt:`INTERFACE_LINK_LIBRARIES` properties. See policy :policy:`CMP0022`. -Contents of ``LINK_LIBRARIES`` 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. +Contents of ``LINK_LIBRARIES`` may use +:manual:`generator expressions <cmake-generator-expressions(7)>` with the +syntax ``$<...>``. Policy :policy:`CMP0131` affects the behavior of the +:genex:`LINK_ONLY` generator expression for this property. + +See the :manual:`cmake-buildsystem(7)` manual for more on defining +buildsystem properties. .. include:: LINK_LIBRARIES_INDIRECTION.txt diff --git a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst index 81a2a4a..916a7c6 100644 --- a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst +++ b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE.rst @@ -3,52 +3,63 @@ LINK_LIBRARY_OVERRIDE .. versionadded:: 3.24 -To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator -expression, this property offers the possibility to override, per ``link-item`` -(``CMake`` target or external library) involved in the link step, any defined -features with a new one. +Override the library features associated with libraries from +:genex:`LINK_LIBRARY` generator expressions. This can be used to resolve +incompatible library features that result from specifying different features +for the same library in different :genex:`LINK_LIBRARY` generator expressions. -This property takes a :ref:`;-list <CMake Language Lists>` of override -declarations which have the following format: - -:: +This property supports overriding multiple libraries and features. It expects +a :ref:`semicolon-separated list <CMake Language Lists>`, where each list item +has the following form:: feature[,link-item]* -For the list of ``link-item`` (``CMake`` target or external library) specified, -the feature ``feature`` will be used in place of any declared feature. For -example: +For each comma-separated ``link-item``, any existing library feature associated +with it will be ignored for the target this property is set on. The item +will instead be associated with the specified ``feature``. Each ``link-item`` +can be anything that would be accepted as part of a ``library-list`` in a +:genex:`LINK_LIBRARY` generator expression. .. code-block:: cmake add_library(lib1 ...) - target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") - add_library(lib2 ...) - target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") - add_library(lib3 ...) + + target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") + target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") target_link_libraries(lib3 PRIVATE lib1 lib2) - # Here, lib1 has two different features which prevents to link lib3 - # So, define LINK_LIBRARY_OVERRIDE property to ensure correct link + + # lib1 is associated with both feature2 and no feature. Without any override, + # this would result in a fatal error at generation time for lib3. + # Define an override to resolve the incompatible feature associations. set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE "feature2,lib1,external") - # The lib1 and external will be used with FEATURE2 to link lib3 -It is also possible to override any feature with the pre-defined feature -``DEFAULT`` to get the standard behavior (i.e. no feature): + # lib1 and external will now be associated with feature2 instead when linking lib3 + +It is also possible to override any feature with the pre-defined ``DEFAULT`` +library feature. This effectively discards any feature for that link item, +for that target only (``lib3`` in this example): .. code-block:: cmake - set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE "DEFAULT,lib1" - "feature2,external") - # The lib1 will be used without any feature and external will use feature2 to link lib3 + # When linking lib3, discard any library feature for lib1, and use feature2 for external + set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE + "DEFAULT,lib1" + "feature2,external" + ) + +The above example also demonstrates how to specify different feature overrides +for different link items. See the :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` +target property for an alternative way of overriding library features for +individual libraries, which may be simpler in some cases. If both properties +are defined and specify an override for the same link item, +:prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` takes precedence over +``LINK_LIBRARY_OVERRIDE``. Contents of ``LINK_LIBRARY_OVERRIDE`` may use :manual:`generator expressions <cmake-generator-expressions(7)>`. -See also :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target property for -a per linked target oriented approach to override features. - -For more information about features, see -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` -and :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. +For more information about library features, see the +:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` and +:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. diff --git a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst index 112f614..4d3dd4f 100644 --- a/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst +++ b/Help/prop_tgt/LINK_LIBRARY_OVERRIDE_LIBRARY.rst @@ -3,43 +3,49 @@ LINK_LIBRARY_OVERRIDE_<LIBRARY> .. versionadded:: 3.24 -To resolve incompatible features introduced by :genex:`LINK_LIBRARY` generator -expression, this property offers the possibility to override, for a -``link-item`` (``CMake`` target or external library) involved in the link step, -any defined features with a new one. +Override the library feature associated with ``<LIBRARY>`` from +:genex:`LINK_LIBRARY` generator expressions. This can be used to resolve +incompatible library features that result from specifying different features +for ``<LIBRARY>`` in different :genex:`LINK_LIBRARY` generator expressions. -This property takes a ``feature`` name which will be applied to the -``link-item`` specified by ``<LIBRARY>`` suffix property. For example: +When set on a target, this property holds a single library feature name, which +will be applied to ``<LIBRARY>`` when linking that target. .. code-block:: cmake add_library(lib1 ...) - target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") - add_library(lib2 ...) - target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") - add_library(lib3 ...) + + target_link_libraries(lib1 PUBLIC "$<LINK_LIBRARY:feature1,external>") + target_link_libraries(lib2 PUBLIC "$<LINK_LIBRARY:feature2,lib1>") target_link_libraries(lib3 PRIVATE lib1 lib2) - # Here, lib1 has two different features which prevents to link lib3 - # So, define LINK_LIBRARY_OVERRIDE_lib1 property to ensure correct link + + # lib1 is associated with both feature2 and no feature. Without any override, + # this would result in a fatal error at generation time for lib3. + # Define an override to resolve the incompatible feature associations. set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE_lib1 feature2) - # The lib1 will be used with feature2 to link lib3 -It is also possible to override any feature with the pre-defined feature -``DEFAULT`` to get the standard behavior (i.e. no feature): + # lib1 will now be associated with feature2 instead when linking lib3 + +It is also possible to override any feature with the pre-defined ``DEFAULT`` +library feature. This effectively discards any feature for that link item, +for that target only (``lib3`` in this example): .. code-block:: cmake + # When linking lib3, discard any library feature for lib1 set_property(TARGET lib3 PROPERTY LINK_LIBRARY_OVERRIDE_lib1 DEFAULT) - # The lib1 will be used without any feature to link lib3 + +See the :prop_tgt:`LINK_LIBRARY_OVERRIDE` target property for an alternative +way of overriding library features for multiple libraries at once. If both +properties are defined and specify an override for the same link item, +``LINK_LIBRARY_OVERRIDE_<LIBRARY>`` takes precedence over +:prop_tgt:`LINK_LIBRARY_OVERRIDE`. Contents of ``LINK_LIBRARY_OVERRIDE_<LIBRARY>`` may use :manual:`generator expressions <cmake-generator-expressions(7)>`. -This property takes precedence over :prop_tgt:`LINK_LIBRARY_OVERRIDE` -target property. - -For more information about features, see -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` -and :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. +For more information about library features, see the +:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` and +:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variables. diff --git a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst index f2ef843..7c929d0 100644 --- a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE.rst @@ -3,25 +3,14 @@ CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``<FEATURE>`` and the linker language -``<LANG>``, the expression expected by the linker when libraries are specified -using :genex:`LINK_GROUP` generator expression. +This variable defines how to link a group of libraries for the specified +``<FEATURE>`` when a :genex:`LINK_GROUP` generator expression is used and +the link language for the target is ``<LANG>``. +For this variable to have any effect, the associated +:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable +must be set to true. -.. note:: - - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. - -See also the associated variable -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable for the definition of -features independent from the link language. +The :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variable should be defined +instead for features that are independent of the link language. .. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst index 533eee7..b314c5a 100644 --- a/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst +++ b/Help/variable/CMAKE_LANG_LINK_GROUP_USING_FEATURE_SUPPORTED.rst @@ -3,11 +3,12 @@ CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED .. versionadded:: 3.24 -Set to ``TRUE`` if the ``<FEATURE>``, as defined by variable -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`, is supported for the -linker language ``<LANG>``. - -.. note:: - - This variable is evaluated before the more generic variable - :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED`. +This variable specifies whether the ``<FEATURE>`` is supported for the link +language ``<LANG>``. If this variable is true, then the ``<FEATURE>`` must +be defined by :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>`, and the +more generic :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` and +:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>` variables are not used. + +If ``CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED`` is false or is not +set, then the :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` variable +will determine whether ``<FEATURE>`` is deemed to be supported. diff --git a/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst b/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst index 220ae99..39fcff8 100644 --- a/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LANG_LINK_LIBRARY_USING_FEATURE.rst @@ -3,25 +3,14 @@ CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``<FEATURE>`` and the linker language -``<LANG>``, the expression expected by the linker when libraries are specified -using :genex:`LINK_LIBRARY` generator expression. +This variable defines how to link a library or framework for the specified +``<FEATURE>`` when a :genex:`LINK_LIBRARY` generator expression is used and +the link language for the target is ``<LANG>``. +For this variable to have any effect, the associated +:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` variable +must be set to true. -.. note:: - - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. - -See also the associated variable -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable for the definition of -features independent from the link language. +The :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>` variable should be defined +instead for features that are independent of the link language. .. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst index 692c099..90b7f8b 100644 --- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.rst @@ -3,31 +3,20 @@ CMAKE_LINK_GROUP_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``<FEATURE>``, the expression expected -by the linker when libraries are specified using :genex:`LINK_GROUP` generator -expression. +This variable defines how to link a group of libraries for the specified +``<FEATURE>`` when a :genex:`LINK_GROUP` generator expression is used. +Both of the following conditions must be met for this variable to have any +effect: -.. note:: +* The associated :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` + variable must be set to true. - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. +* There is no language-specific definition for the same ``<FEATURE>``. + This means :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` + cannot be true for the link language used by the target for which the + :genex:`LINK_GROUP` generator expression is evaluated. -See also the associated variable -:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable for the definition -of features dependent from the link language. - -This variable will be used by :genex:`LINK_GROUP` generator expression if, -for the linker language, the variable -:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is not defined -and the variable :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is -``TRUE``.. +The :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>` variable should be +defined instead for features that are dependent on the link language. .. include:: CMAKE_LINK_GROUP_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt index ecd9cb5..23ea157 100644 --- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt +++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE.txt @@ -1,17 +1,24 @@ +Feature names are case-sensitive and may only contain letters, numbers +and underscores. Feature names defined in all uppercase are reserved for +CMake's own built-in features (see `Predefined Features`_ further below). -It must contain two elements. + +Feature Definitions +^^^^^^^^^^^^^^^^^^^ + +A group feature definition is a list that contains exactly two elements: :: <PREFIX> <SUFFIX> -``<PREFIX>`` and ``<SUFFIX>`` will be used to encapsulate the list of -libraries. +On the linker command line, ``<PREFIX>`` will precede the list of libraries +in the group and ``<SUFFIX>`` will follow after. -For the elements of this variable, the ``LINKER:`` prefix can be used: +For the elements of this variable, the ``LINKER:`` prefix can be used. - .. include:: ../command/LINK_OPTIONS_LINKER.txt - :start-line: 3 +.. include:: ../command/LINK_OPTIONS_LINKER.txt + :start-line: 3 Examples ^^^^^^^^ @@ -19,36 +26,53 @@ Examples Solving cross-references between two static libraries """"""""""""""""""""""""""""""""""""""""""""""""""""" -A common need is the capability to search repeatedly in a group of static -libraries until no new undefined references are created. This capability is -offered by different environments but with a specific syntax: +A project may define two or more static libraries which have circular +dependencies between them. In order for the linker to resolve all symbols +at link time, it may need to search repeatedly among the libraries until no +new undefined references are created. Different linkers use different syntax +for achieving this. The following example shows how this may be implemented +for some linkers. Note that this is for illustration purposes only. +Projects should use the built-in ``RESCAN`` group feature instead +(see `Predefined Features`_), which provides a more complete and more robust +implementation of this functionality. .. code-block:: cmake set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE) - if(CMAKE_C_COMPILER_ID STREQUAL "GNU" - AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(CMAKE_C_LINK_GROUP_USING_cross_refs "LINKER:--start-group" - "LINKER:--end-group") - elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro" - AND CMAKE_SYSTEM_NAME STREQUAL "SunOS") - set(CMAKE_C_LINK_GROUP_USING_cross_refs "LINKER:-z,rescan-start" - "LINKER:-z,rescan-end") + if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(CMAKE_C_LINK_GROUP_USING_cross_refs + "LINKER:--start-group" + "LINKER:--end-group" + ) + elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro" AND CMAKE_SYSTEM_NAME STREQUAL "SunOS") + set(CMAKE_C_LINK_GROUP_USING_cross_refs + "LINKER:-z,rescan-start" + "LINKER:-z,rescan-end" + ) else() # feature not yet supported for the other environments set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED FALSE) endif() add_library(lib1 STATIC ...) + add_library(lib2 SHARED ...) - add_library(lib3 SHARED ...) if(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED) - target_link_libraries(lib3 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>") + target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>") else() - target_link_libraries(lib3 PRIVATE lib1 external) + target_link_libraries(lib2 PRIVATE lib1 external) endif() -CMake will generate the following link expressions: +CMake will generate the following linker command line fragments when linking +``lib2``: * ``GNU``: ``-Wl,--start-group /path/to/lib1.a -lexternal -Wl,--end-group`` * ``SunPro``: ``-Wl,-z,rescan-start /path/to/lib1.a -lexternal -Wl,-z,rescan-end`` + + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +The following built-in group features are pre-defined by CMake: + +.. include:: LINK_GROUP_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst index 318892f..8b4ee6e 100644 --- a/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst +++ b/Help/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED.rst @@ -3,11 +3,10 @@ CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED .. versionadded:: 3.24 -Set to ``TRUE`` if the ``<FEATURE>``, as defined by variable -:variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`, is supported regardless the -linker language. +This variable specifies whether the ``<FEATURE>`` is supported regardless of +the link language. If this variable is true, then the ``<FEATURE>`` must +be defined by :variable:`CMAKE_LINK_GROUP_USING_<FEATURE>`. -.. note:: - - This variable is evaluated if, and only if, the variable - :variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is not defined. +Note that this variable has no effect if +:variable:`CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED` is true for +the link language of the target. diff --git a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst index 9f1cede..c652733 100644 --- a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst +++ b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.rst @@ -3,31 +3,17 @@ CMAKE_LINK_LIBRARY_USING_<FEATURE> .. versionadded:: 3.24 -This variable defines, for the specified ``FEATURE``, the expression expected -by the linker, regardless the linker language, when libraries are specified -using :genex:`LINK_LIBRARY` generator expression. +This variable defines how to link a library or framework for the specified +``<FEATURE>`` when a :genex:`LINK_LIBRARY` generator expression is used. +Both of the following conditions must be met for this variable to have any +effect: -.. note:: +* The associated :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` + variable must be set to true. - * Feature names can contain Latin letters, digits and undercores. - * Feature names defined in all uppercase are reserved to CMake. - -See also the associated variable -:variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` and -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>` variable for the -definition of features dependent from the link language. - -This variable will be used by :genex:`LINK_LIBRARY` generator expression if, -for the linker language, the variable -:variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is not defined -and the variable :variable:`CMAKE_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` is -``TRUE``. +* There is no language-specific definition for the same ``<FEATURE>``. + This means :variable:`CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED` + cannot be true for the link language used by the target for which the + :genex:`LINK_LIBRARY` generator expression is evaluated. .. include:: CMAKE_LINK_LIBRARY_USING_FEATURE.txt - -Predefined Features -^^^^^^^^^^^^^^^^^^^ - -CMake pre-defines some features of general interest: - -.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt index ec293d3..4b13b7c 100644 --- a/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt +++ b/Help/variable/CMAKE_LINK_LIBRARY_USING_FEATURE.txt @@ -1,39 +1,58 @@ +Feature names are case-sensitive and may only contain letters, numbers +and underscores. Feature names defined in all uppercase are reserved for +CMake's own built-in features (see `Predefined Features`_ further below). -It can contain one or three elements. -:: - - [<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>] +Feature Definitions +^^^^^^^^^^^^^^^^^^^ -When ``<PREFIX>`` and/or ``<SUFFIX>`` are specified, they encapsulate the list -of libraries. +A library feature definition is a list that contains one or three elements: -.. note:: +:: - Even if ``<PREFIX>`` and ``<SUFFIX>`` are specified, there is not guarantee - that the list of specified libraries, as part of :genex:`LINK_LIBRARY` - generator expression, will be kept grouped. So, constructs like - ``start-group`` and ``end-group``, as supported by ``GNU ld``, cannot be - used. + [<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>] -``<LIBRARY_EXPRESSION>`` is used to specify the decoration for each -library. For that purpose, the patterns ``<LIBRARY>``, ``<LINK_ITEM>``, and -``<LIB_ITEM>`` are available: +When ``<PREFIX>`` and ``<SUFFIX>`` are specified, they precede and follow +respectively the whole list of libraries specified in the +:genex:`LINK_LIBRARY` expression, not each library item individually. +There is no guarantee that the list of specified libraries will be kept +grouped together though, so the ``<PREFIX>`` and ``<SUFFIX>`` may appear +more than once if the library list is reorganized by CMake to satisfy other +constraints. This means constructs like ``--start-group`` and ``--end-group``, +as supported by the GNU ``ld`` linker, cannot be used in this way. The +:genex:`LINK_GROUP` generator expression should be used instead for such +constructs. + +``<LIBRARY_EXPRESSION>`` is used to specify the pattern for constructing the +corresponding fragment on the linker command line for each library. +The following placeholders can be used in the expression: + +* ``<LIBRARY>`` is expanded to the full path to the library for CMake targets, + or to a platform-specific value based on the item otherwise (the same as + ``<LINK_ITEM>`` on Windows, or the library base name for other platforms). +* ``<LINK_ITEM>`` is expanded to how the library would normally be linked on + the linker command line. +* ``<LIB_ITEM>`` is expanded to the full path to the library for CMake targets, + or the item itself exactly as specified in the ``<LIBRARY_EXPRESSION>`` + otherwise. + +In addition to the above, it is possible to have one pattern for paths +(CMake targets and external libraries specified with file paths) and another +for other items specified by name only. The ``PATH{}`` and ``NAME{}`` wrappers +can be used to provide the expansion for those two cases, respectively. +When wrappers are used, both must be present. For example: -* ``<LIBRARY>`` is expanded to the library as computed by CMake. -* ``<LINK_ITEM>`` is expanded to the same expression as if the library was - specified in the standard way. -* ``<LIB_ITEM>`` is equivalent to ``<LIBRARY>`` for CMake targets and is - expanded to the item specified by the user for external libraries. +.. code-block:: cmake -Moreover, it is possible to have different decorations for paths (CMake targets -and external libraries specified with absolute paths) and other items specified -by name. For that purpose, ``PATH{}`` and ``NAME{}`` wrappers can be used. + set(CMAKE_LINK_LIBRARY_USING_weak_library + "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}" + ) -For all three elements of this variable, the ``LINKER:`` prefix can be used: +For all three elements of this variable (``<PREFIX>``, ``<LIBRARY_EXPRESSION>``, +and ``<SUFFIX>``), the ``LINKER:`` prefix can be used. - .. include:: ../command/LINK_OPTIONS_LINKER.txt - :start-line: 3 +.. include:: ../command/LINK_OPTIONS_LINKER.txt + :start-line: 3 Examples ^^^^^^^^ @@ -41,19 +60,24 @@ Examples Loading a whole static library """""""""""""""""""""""""""""" -A common need is the capability to load a whole static library. This capability -is offered by various environments but with a specific syntax: +A common need is to prevent the linker from discarding any symbols from a +static library. Different linkers use different syntax for achieving this. +The following example shows how this may be implemented for some linkers. +Note that this is for illustration purposes only. Projects should use the +built-in ``WHOLE_ARCHIVE`` feature instead (see `Predefined Features`_), which +provides a more complete and more robust implementation of this functionality. .. code-block:: cmake set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE) if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang") set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>") - elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" - AND CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(CMAKE_C_LINK_LIBRARY_USING_load_archive "LINKER:--push-state,--whole-archive" - "<LINK_ITEM>" - "LINKER:--pop-state") + elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(CMAKE_C_LINK_LIBRARY_USING_load_archive + "LINKER:--push-state,--whole-archive" + "<LINK_ITEM>" + "LINKER:--pop-state" + ) elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>") else() @@ -62,41 +86,45 @@ is offered by various environments but with a specific syntax: endif() add_library(lib1 STATIC ...) - add_library(lib2 SHARED ...) + if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED) + # The -force_load Apple linker option requires a file name + set(external_lib + "$<IF:$<LINK_LANG_AND_ID:C,AppleClang>,libexternal.a,external>" + ) target_link_libraries(lib2 PRIVATE - "$<LINK_LIBRARY:load_archive,lib1,$<IF:$<LINK_LANG_AND_ID:C,Clang>,libexternal.a,external>>") + "$<LINK_LIBRARY:load_archive,lib1,${external_lib}>" + ) else() target_link_libraries(lib2 PRIVATE lib1 external) endif() CMake will generate the following link expressions: -* ``Clang``: ``-force_load /path/to/lib1.a -force_load libexternal.a`` -* ``GNU``: ``-Wl,--whole-archive /path/to/lib1.a -lexternal -Wl,--no-whole-archive`` +* ``AppleClang``: ``-force_load /path/to/lib1.a -force_load libexternal.a`` +* ``GNU``: ``-Wl,--push-state,--whole-archive /path/to/lib1.a -lexternal -Wl,--pop-state`` * ``MSVC``: ``/WHOLEARCHIVE:/path/to/lib1.lib /WHOLEARCHIVE:external.lib`` -CMake will ensure, when possible, that ``<PREFIX>`` and ``<SUFFIX>`` are -not repeated for each library. - -In case of ``Clang``, the pattern ``<LIB_ITEM>`` is used because we need to -specify the library as defined by the user, not the name computed by CMake -(in that case ``external``). - Linking a library as weak """"""""""""""""""""""""" -On MacOS, it is possible to link a library in weak mode (the library and all -references are marked as weak imports), but different flags must be used for a -library specified by path and by name. This constraint by be solved by using -``PATH{}`` and ``NAME{}`` wrappers: +On macOS, it is possible to link a library in weak mode (the library and all +references are marked as weak imports). Different flags must be used for a +library specified by file path compared to one specified by name. +This constraint can be solved using ``PATH{}`` and ``NAME{}`` wrappers. +Again, the following example shows how this may be implemented for some +linkers, but it is for illustration purposes only. Projects should use the +built-in ``WEAK_FRAMEWORK`` or ``WEAK_LIBRARY`` features instead (see +`Predefined Features`_), which provide more complete and more robust +implementations of this functionality. .. code-block:: cmake if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang") set(CMAKE_LINK_LIBRARY_USING_weak_library - "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}") + "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}" + ) set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE) endif() @@ -108,5 +136,15 @@ library specified by path and by name. This constraint by be solved by using target_link_libraries(main PRIVATE lib external) endif() -CMake will generate the following link expression: -``-weak_library /path/to/lib -Xlinker -weak-lexternal`` +CMake will generate the following linker command line fragment when linking +``main`` using the ``AppleClang`` toolchain: + +``-weak_library /path/to/lib -Xlinker -weak-lexternal``. + + +Predefined Features +^^^^^^^^^^^^^^^^^^^ + +The following built-in library features are pre-defined by CMake: + +.. include:: LINK_LIBRARY_PREDEFINED_FEATURES.txt diff --git a/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt b/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt index 5f1a11b..557886e 100644 --- a/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt +++ b/Help/variable/LINK_GROUP_PREDEFINED_FEATURES.txt @@ -1,22 +1,22 @@ -**Circular references with static libraries** - -Some linkers are one-pass only so to handle circular references between -static libraries, the following feature can be used: - ``RESCAN`` - The specified static libraries are searched repeatedly until no - new undefined references are created. Normally, an static library is searched - only once in the order that it is specified on the command line. If a symbol - in that library is needed to resolve an undefined symbol referred to by an - object in an library that appears later on the command line, the linker would - not be able to resolve that reference. By grouping the static libraries, they - all be searched repeatedly until all possible references are resolved (use - linker options ``--start-group`` and ``--end-group`` or, on ``SunOS``, - ``-z rescan-start`` and ``-z rescan-end``). + Some linkers are single-pass only. For such linkers, circular references + between libraries typically result in unresolved symbols. This feature + instructs the linker to search the specified static libraries repeatedly + until no new undefined references are created. + + Normally, a static library is searched only once in the order that it is + specified on the command line. If a symbol in that library is needed to + resolve an undefined symbol referred to by an object in a library that + appears later on the command line, the linker would not be able to resolve + that reference. By grouping the static libraries with the ``RESCAN`` + feature, they will all be searched repeatedly until all possible references + are resolved. This will use linker options like ``--start-group`` and + ``--end-group``, or on SunOS, ``-z rescan-start`` and ``-z rescan-end``. Using this feature has a significant performance cost. It is best to use it only when there are unavoidable circular references between two or more static libraries. - This feature is available on ``Linux``, ``BSD``, and ``SunOS`` target - platforms as well as ``Windows`` when ``GNU`` toolchain is used. + This feature is available when using toolchains that target Linux, BSD, and + SunOS. It can also be used when targeting Windows platforms if the GNU + toolchain is used. diff --git a/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt index e4fa0ed8..8ae6c57 100644 --- a/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt +++ b/Help/variable/LINK_LIBRARY_PREDEFINED_FEATURES.txt @@ -1,88 +1,96 @@ -**Features available in all environments** - ``DEFAULT`` - This feature enables default link expression. This is mainly - useful with :prop_tgt:`LINK_LIBRARY_OVERRIDE` and + This feature corresponds to standard linking, essentially equivalent to + using no feature at all. It is typically only used with the + :prop_tgt:`LINK_LIBRARY_OVERRIDE` and :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties. -**Features available for a subset of environments** - ``WHOLE_ARCHIVE`` - Force load of all members in a static library. - - Target platforms supported: all ``Apple`` variants, ``Linux``, all ``BSD`` - variants, ``SunOS``, ``Windows``, ``CYGWIN``, and ``MSYS``. - - Platform-specific notes: - - * On Apple platforms, the library must be specified as a CMake target name, a - library file name (such as ``libfoo.a``), or a library file path (such as - ``/path/to/libfoo.a``). It cannot be specified as a plain library name - (such as ``foo``, where ``foo`` is not CMake target), due to a limitation - in the Apple linker. - * On Windows platforms, for ``MSVC`` or MSVC-like toolchains, the version - must be greater than ``1900``. - -**Features available in Apple environments** - -It is assumed that the linker used is the one provided by `XCode` or is -compatible with it. - -Framework support + Force inclusion of all members of a static library. This feature is only + supported for the following platforms, with limitations as noted: + + * Linux. + * All BSD variants. + * SunOS. + * All Apple variants. The library must be specified as a CMake target name, + a library file name (such as ``libfoo.a``), or a library file path (such as + ``/path/to/libfoo.a``). Due to a limitation of the Apple linker, it + cannot be specified as a plain library name like ``foo``, where ``foo`` + is not a CMake target. + * Windows. When using a MSVC or MSVC-like toolchain, the MSVC version must + be greater than 1900. + * Cygwin. + * MSYS. ``FRAMEWORK`` - This option tells the linker to search for the specified - framework (use linker option ``-framework``). -``NEEDED_FRAMEWORK`` - This is the same as the ``FRAMEWORK`` feature but means - to really link with the framework even if no symbols are used from it (use - linker option ``-needed_framework``). -``REEXPORT_FRAMEWORK`` - This is the same as the ``FRAMEWORK`` feature but - also specifies that all symbols in that framework should be available to - clients linking to the library being created (use linker option - ``-reexport_framework``). -``WEAK_FRAMEWORK`` - This is the same as the ``FRAMEWORK`` feature but forces - the framework and all references to it to be marked as weak imports (use - linker option ``-weak_framework``). + This option tells the linker to search for the specified framework using + the ``-framework`` linker option. It can only be used on Apple platforms, + and only with a linker that understands the option used (i.e. the linker + provided with Xcode, or one compatible with it). + + The framework can be specified as a CMake framework target, a bare framework + name, or a file path. If a target is given, that target must have the + :prop_tgt:`FRAMEWORK` target property set to true. For a file path, if it + contains a directory part, that directory will be added as a framework + search path. + + .. code-block:: cmake + + add_library(lib SHARED ...) + target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:FRAMEWORK,/path/to/my_framework>") + + # The constructed linker command line will contain: + # -F/path/to -framework my_framework + + File paths must conform to one of the following patterns (``*`` is a + wildcard, and optional parts are shown as ``[...]``): + + * ``[/path/to/]FwName[.framework]`` + * ``[/path/to/]FwName.framework/FwName`` + * ``[/path/to/]FwName.framework/Versions/*/FwName`` + + Note that CMake recognizes and automatically handles framework targets, + even without using the ``$<LINK_LIBRARY:FRAMEWORK,...>`` expression. + The generator expression can still be used with a CMake target if the + project wants to be explicit about it, but it is not required to do so. + The linker command line may have some differences between using the + generator expression or not, but the final result should be the same. + On the other hand, if a file path is given, CMake will recognize some paths + automatically, but not all cases. The project may want to use + ``$<LINK_LIBRARY:FRAMEWORK,...>`` for file paths so that the expected + behavior is clear. -Features for framework linking have a special handling in CMake: the -framework can be specified as a CMake framework target or file path. In the -first case, the target must have the :prop_tgt:`FRAMEWORK` target property set -as ``TRUE`` to enable framework handling. In the later case, if the path -includes a directory part, this one will be specified as framework search path -at link step. - -.. code-block:: cmake - - add_library(lib SHARED ...) - target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:NEEDED_FRAMEWORK,/path/to/my_framework>") - - # at link step we will have: - # -F/path/to -needed_framework my_framework - -.. note:: - - The expected formats for the file path, with optional parts specified as - ``()?``, are: +``NEEDED_FRAMEWORK`` + This is similar to the ``FRAMEWORK`` feature, except it forces the linker + to link with the framework even if no symbols are used from it. It uses + the ``-needed_framework`` option and has the same linker constraints as + ``FRAMEWORK``. - * (/path/to/)?FwName(.framework)? - * (/path/to/)?FwName.framework/FwName - * (/path/to/)?FwName.framework/Versions/\*/FwName +``REEXPORT_FRAMEWORK`` + This is similar to the ``FRAMEWORK`` feature, except it tells the linker + that the framework should be available to clients linking to the library + being created. It uses the ``-reexport_framework`` option and has the + same linker constraints as ``FRAMEWORK``. -Library support +``WEAK_FRAMEWORK`` + This is similar to the ``FRAMEWORK`` feature, except it forces the linker + to mark the framework and all references to it as weak imports. It uses + the ``-weak_framework`` option and has the same linker constraints as + ``FRAMEWORK``. ``NEEDED_LIBRARY`` - This is the same as specifying a link item (target or - library) but means to really link with the item even if no symbols are used - from it (use linker option ``-needed_library`` or ``-needed-l``). + This is similar to the ``NEEDED_FRAMEWORK`` feature, except it is for use + with non-framework targets or libraries (Apple platforms only). + It uses the ``-needed_library`` or ``-needed-l`` option as appropriate, + and has the same linker constraints as ``NEEDED_FRAMEWORK``. + ``REEXPORT_LIBRARY`` - This is the same as specifying a link item (target or - library) but also specifies that all symbols in that item should be available - to clients linking to the library being created (use linker option - ``-reexport_library`` or ``-reexport-l``). + This is similar to the ``REEXPORT_FRAMEWORK`` feature, except it is for use + with non-framework targets or libraries (Apple platforms only). + It uses the ``-reexport_library`` or ``-reexport-l`` option as appropriate, + and has the same linker constraints as ``REEXPORT_FRAMEWORK``. + ``WEAK_LIBRARY`` - This is the same as specifying a link item (target or - library) but forces the item and all references to it to be marked as weak - imports (use linker option ``-weak_library`` or ``-weak-l``). + This is similar to the ``WEAK_FRAMEWORK`` feature, except it is for use + with non-framework targets or libraries (Apple platforms only). + It uses the ``-weak_library`` or ``-weak-l`` option as appropriate, + and has the same linker constraints as ``WEAK_FRAMEWORK``. diff --git a/Modules/Compiler/NVHPC.cmake b/Modules/Compiler/NVHPC.cmake index 21d0665..957dacd 100644 --- a/Modules/Compiler/NVHPC.cmake +++ b/Modules/Compiler/NVHPC.cmake @@ -13,5 +13,5 @@ include(Compiler/PGI) macro(__compiler_nvhpc lang) # Logic specific to NVHPC. set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ") - set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "--Werror all-warnings") + set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror all-warnings") endmacro() diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index 892df90..33509ac 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -30,6 +30,11 @@ if(CMAKE_CUDA_HOST_COMPILER AND NOT CMAKE_GENERATOR MATCHES "Visual Studio") endif() if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) + # Starting in 10.2, nvcc supported treating all warnings as errors + set(CMAKE_CUDA_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror all-warnings") +endif() + +if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) # The -MD flag was only added to nvcc in 10.2 so # before that we had to invoke the compiler twice # to get header dependency information diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake index 91dcba5..b4f4d71 100644 --- a/Modules/FindICU.cmake +++ b/Modules/FindICU.cmake @@ -254,13 +254,6 @@ function(_ICU_FIND) set("${component_found}" ON) set("${component_found_compat}" ON) list(APPEND ICU_LIBRARY "${${component_cache}}") - endif() - mark_as_advanced("${component_found}") - mark_as_advanced("${component_found_compat}") - set("${component_cache}" "${${component_cache}}" PARENT_SCOPE) - set("${component_found}" "${${component_found}}" PARENT_SCOPE) - set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE) - if(component_found OR component_found_compat) if (ICU_FIND_REQUIRED_${component}) list(APPEND ICU_LIBS_FOUND "${component} (required): ${${component_cache}}") else() @@ -274,6 +267,11 @@ function(_ICU_FIND) list(APPEND ICU_LIBS_NOTFOUND "${component} (optional)") endif() endif() + mark_as_advanced("${component_found}") + mark_as_advanced("${component_found_compat}") + set("${component_cache}" "${${component_cache}}" PARENT_SCOPE) + set("${component_found}" "${${component_found}}" PARENT_SCOPE) + set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE) endforeach() set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE) set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE) diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake index ecfb7f9..d19624e 100644 --- a/Modules/FindOpenMP.cmake +++ b/Modules/FindOpenMP.cmake @@ -243,6 +243,23 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR) file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n") + # For LCC we should additionally alanyze -print-search-dirs output + # to check for additional implicit_dirs. + # Note: This won't work if CMP0129 policy is set to OLD! + if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "LCC") + execute_process( + COMMAND ${CMAKE_${LANG}_COMPILER} -print-search-dirs + OUTPUT_VARIABLE output_lines + COMMAND_ERROR_IS_FATAL ANY + ERROR_QUIET) + if("${output_lines}" MATCHES ".*\nlibraries:[ \t]+(.*:)\n.*") + string(REPLACE ":" ";" implicit_dirs_addon "${CMAKE_MATCH_1}") + list(PREPEND OpenMP_${LANG}_IMPLICIT_LINK_DIRS ${implicit_dirs_addon}) + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + " Extended OpenMP library search paths: [${implicit_dirs}]\n") + endif() + endif() + unset(_OPENMP_LIB_NAMES) foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES) get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY) diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake index a80758d..b14349f 100644 --- a/Modules/FindRuby.cmake +++ b/Modules/FindRuby.cmake @@ -369,56 +369,17 @@ if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR) set(Ruby_VERSION_MAJOR 1) set(Ruby_VERSION_MINOR 9) endif() - # check whether we found 2.0.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?0") + # check whether we found 2.[0-7].x + if(${Ruby_EXECUTABLE} MATCHES "ruby2") set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 0) + string(REGEX_REPLACE ${Ruby_EXECUTABLE} "ruby2\\.?([0-7])" "\\1" Ruby_VERSION_MINOR) endif() - # check whether we found 2.1.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?1") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 1) - endif() - # check whether we found 2.2.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?2") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 2) - endif() - # check whether we found 2.3.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?3") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 3) - endif() - # check whether we found 2.4.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?4") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 4) - endif() - # check whether we found 2.5.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?5") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 5) - endif() - # check whether we found 2.6.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?6") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 6) - endif() - # check whether we found 2.7.x - if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?7") - set(Ruby_VERSION_MAJOR 2) - set(Ruby_VERSION_MINOR 7) - endif() - # check whether we found 3.0.x - if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?0") - set(Ruby_VERSION_MAJOR 3) - set(Ruby_VERSION_MINOR 0) - endif() - # check whether we found 3.1.x - if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?1") + # check whether we found 3.[0-1].x + if(${Ruby_EXECUTABLE} MATCHES "ruby3") set(Ruby_VERSION_MAJOR 3) - set(Ruby_VERSION_MINOR 1) + string(REGEX_REPLACE ${Ruby_EXECUTABLE} "ruby3\\.?([0-1])" "\\1" Ruby_VERSION_MINOR) endif() + endif() if(Ruby_VERSION_MAJOR) diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index ec88a37..ac2478b 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -103,9 +103,9 @@ foreach(lang C CXX Fortran OBJC OBJCXX) set(CMAKE_${lang}_CREATE_MACOSX_FRAMEWORK "<CMAKE_${lang}_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>") -# Set default framework search path flag for languages known to use a -# preprocessor that may find headers in frameworks. -set(CMAKE_${lang}_FRAMEWORK_SEARCH_FLAG -F) + # Set default framework search path flag for languages known to use a + # preprocessor that may find headers in frameworks. + set(CMAKE_${lang}_FRAMEWORK_SEARCH_FLAG -F) endforeach() # Defines LINK_LIBRARY features for frameworks @@ -122,13 +122,13 @@ set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK "LINKER:-weak_framework,<LIBRARY>") set(CMAKE_LINK_LIBRARY_USING_WEAK_FRAMEWORK_SUPPORTED TRUE) # Defines LINK_LIBRARY features for libraries -set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY "PATH{LINKER:-needed_library <LIBRARY>}NAME{LINKER:-needed-l<LIB_ITEM>}") +set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY "PATH{LINKER:-needed_library <LIBRARY>}NAME{LINKER:-needed-l<LIBRARY>}") set(CMAKE_LINK_LIBRARY_USING_NEEDED_LIBRARY_SUPPORTED TRUE) -set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY "PATH{LINKER:-reexport_library <LIBRARY>}NAME{LINKER:-reexport-l<LIB_ITEM>}") +set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY "PATH{LINKER:-reexport_library <LIBRARY>}NAME{LINKER:-reexport-l<LIBRARY>}") set(CMAKE_LINK_LIBRARY_USING_REEXPORT_LIBRARY_SUPPORTED TRUE) -set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY "PATH{LINKER:-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}") +set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY "PATH{LINKER:-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIBRARY>}") set(CMAKE_LINK_LIBRARY_USING_WEAK_LIBRARY_SUPPORTED TRUE) # Defines LINK_LIBRARY feature to Force loading of all members of an archive diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 52c9d90..4fdb6fb 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 24) -set(CMake_VERSION_PATCH 20220630) +set(CMake_VERSION_PATCH 20220706) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index e156e3d..850b7a3 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -549,6 +549,17 @@ bool cmComputeLinkInformation::Compute() if (linkEntry.Kind == cmComputeLinkDepends::LinkEntry::Group) { const auto& groupFeature = this->GetGroupFeature(linkEntry.Feature); if (groupFeature.Supported) { + if (linkEntry.Item.Value == "</LINK_GROUP>" && + currentFeature != nullptr) { + // emit feature suffix, if any + if (!currentFeature->Suffix.empty()) { + this->Items.emplace_back( + BT<std::string>{ currentFeature->Suffix, + this->Items.back().Value.Backtrace }, + ItemIsPath::No); + } + currentFeature = nullptr; + } this->Items.emplace_back( BT<std::string>{ linkEntry.Item.Value == "<LINK_GROUP>" ? groupFeature.Prefix diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 7d05347..1cfe29c 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -3113,6 +3113,7 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args, return false; } + // Arguments that are allowed to be empty lists. Keep entries sorted! const std::vector<std::string> LIST_ARGS = { "DIRECTORIES", "EXECUTABLES", @@ -3402,8 +3403,13 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args, return false; } + // Arguments that are allowed to be empty lists. Keep entries sorted! const std::vector<std::string> LIST_ARGS = { - "OUTPUT", "FORMAT", "COMPRESSION", "COMPRESSION_LEVEL", "MTIME", "PATHS" + "MTIME", // "MTIME" should not be in this list because it requires one + // value, but it has long been accidentally accepted without + // one and treated as if an empty value were given. + // Fixing this would require a policy. + "PATHS", // "PATHS" is here only so we can issue a custom error below. }; auto kwbegin = keywordsMissingValues.cbegin(); auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS); @@ -3530,8 +3536,8 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args, return false; } - const std::vector<std::string> LIST_ARGS = { "INPUT", "DESTINATION", - "PATTERNS" }; + // Arguments that are allowed to be empty lists. Keep entries sorted! + const std::vector<std::string> LIST_ARGS = { "PATTERNS" }; auto kwbegin = keywordsMissingValues.cbegin(); auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS); if (kwend != kwbegin) { diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index b08cddb..d773fdf 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -2763,8 +2763,18 @@ struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirNameTag> return std::string(); } - return target->GetAppBundleDirectory(context->Config, - cmGeneratorTarget::BundleDirLevel); + auto level = cmGeneratorTarget::BundleDirLevel; + auto config = context->Config; + if (target->IsAppBundleOnApple()) { + return target->GetAppBundleDirectory(config, level); + } + if (target->IsFrameworkOnApple()) { + return target->GetFrameworkDirectory(config, level); + } + if (target->IsCFBundleOnApple()) { + return target->GetCFBundleDirectory(config, level); + } + return std::string(); } }; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 384096d..d2ded37 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -431,7 +431,7 @@ if(BUILD_TESTING) if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])") ADD_TEST_MACRO(CSharpOnly CSharpOnly) - if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + if(NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") ADD_TEST_MACRO(CSharpLinkToCxx CSharpLinkToCxx) ADD_TEST_MACRO(CSharpLinkFromCxx CSharpLinkFromCxx) endif() @@ -2123,7 +2123,7 @@ if(BUILD_TESTING) if(MSVC AND NOT MSVC_VERSION LESS 1310 AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio 9 " OR CMAKE_SIZEOF_VOID_P EQUAL 4) - AND (NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + AND (NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") ) ADD_TEST_MACRO(VSMASM VSMASM) endif() @@ -2135,7 +2135,7 @@ if(BUILD_TESTING) if(NOT "${CMAKE_GENERATOR}" MATCHES "Visual Studio 9 " AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v90" - AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") ADD_TEST_MACRO(VSWindowsFormsResx VSWindowsFormsResx) ADD_TEST_MACRO(VSManagedCustomCommand) endif() diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake index dbcf4b8..fe57d56 100644 --- a/Tests/RunCMake/AutoExportDll/AutoExport.cmake +++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake @@ -7,7 +7,7 @@ set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1) add_library(autoexport SHARED hello.cxx world.cxx foo.c $<TARGET_OBJECTS:objlib>) add_library(autoexport3 SHARED cppCLI.cxx) if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600 - AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") set_property(TARGET autoexport3 PROPERTY COMMON_LANGUAGE_RUNTIME "") endif() @@ -17,7 +17,7 @@ if(MSVC) add_library(autoexport_for_exec SHARED hello2.c) target_link_libraries(autoexport_for_exec say) if(NOT MSVC_VERSION VERSION_LESS 1600 AND - NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") enable_language(ASM_MASM) target_sources(autoexport PRIVATE nop.asm) set_property(SOURCE nop.asm PROPERTY COMPILE_FLAGS /safeseh) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index bbf8ddc..9549af9 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -372,7 +372,8 @@ add_RunCMake_test(TargetProperties) add_RunCMake_test(ToolchainFile) add_RunCMake_test(find_dependency) add_RunCMake_test(CompileDefinitions) -add_RunCMake_test(CompileWarningAsError) +add_RunCMake_test(CompileWarningAsError -DCMake_TEST_CUDA=${CMake_TEST_CUDA}) +set_property(TEST RunCMake.CompileWarningAsError APPEND PROPERTY LABELS "CUDA") add_RunCMake_test(CompileFeatures -DCMake_NO_C_STANDARD=${CMake_NO_C_STANDARD} -DCMake_NO_CXX_STANDARD=${CMake_NO_CXX_STANDARD}) add_RunCMake_test(Policy) add_RunCMake_test(PolicyScope) @@ -968,7 +969,7 @@ endif() if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|9[0-9])") add_RunCMake_test(CSharpCustomCommand) - if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64") + if(NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64") add_RunCMake_test(CSharpReferenceImport) endif() endif() diff --git a/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake b/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake index a532f72..392c921 100644 --- a/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompileWarningAsError/RunCMakeTest.cmake @@ -1,13 +1,22 @@ include(RunCMake) -function(run_compile_warn test) - set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) +function(run_compile_warn test lang extension) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}_${lang}-build) set(RunCMake_TEST_OUTPUT_MERGE 1) - run_cmake_with_options(${test} ${ARGN}) + run_cmake_with_options(${test}_${lang} "-DLANGUAGE=${lang}" "-DEXTENSION=${extension}" ${ARGN}) set(RunCMake_TEST_NO_CLEAN 1) - run_cmake_command(${test}-Build ${CMAKE_COMMAND} --build . ${verbose_args}) + run_cmake_command(${test}_${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args}) endfunction() -run_compile_warn(WerrorOn) -run_compile_warn(WerrorOff) -run_compile_warn(WerrorOnIgnore "--compile-no-warning-as-error") +set(langs C CXX) +set(exts c cxx) +if(CMake_TEST_CUDA) + list(APPEND langs CUDA) + list(APPEND exts cu) +endif() + +foreach(lang ext IN ZIP_LISTS langs exts) + run_compile_warn(WerrorOn ${lang} ${ext}) + run_compile_warn(WerrorOff ${lang} ${ext}) + run_compile_warn(WerrorOnIgnore ${lang} ${ext} "--compile-no-warning-as-error") +endforeach() diff --git a/Tests/RunCMake/CompileWarningAsError/WarningAsErrorOptions.cmake b/Tests/RunCMake/CompileWarningAsError/WarningAsErrorOptions.cmake index ccc6cc5..d8770e1 100644 --- a/Tests/RunCMake/CompileWarningAsError/WarningAsErrorOptions.cmake +++ b/Tests/RunCMake/CompileWarningAsError/WarningAsErrorOptions.cmake @@ -1,18 +1,29 @@ # add compile options to warning_options to ensure unused-function throws a warning # if warning_options is NOT DEFINED, assume compiler doesn't support warning as error -macro(get_warning_options warning_options) - if (CMAKE_CXX_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang|XLClang|IBMClang|LCC|NVCC|IntelLLVM)$") +macro(get_warning_options warning_options lang) + if (CMAKE_${lang}_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang|XLClang|IBMClang|LCC|IntelLLVM|NVHPC)$") set(${warning_options} "-Wall") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" - OR (CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND CMAKE_CXX_SIMULATE_ID MATCHES "MSVC")) + elseif (CMAKE_${lang}_COMPILER_ID STREQUAL "MSVC" + OR (CMAKE_${lang}_COMPILER_ID STREQUAL "Intel" AND CMAKE_${lang}_SIMULATE_ID MATCHES "MSVC")) set(${warning_options} "-W4") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") + elseif (CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA" + AND CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) + if(CMAKE_${lang}_SIMULATE_ID MATCHES "MSVC") + set(${warning_options} "-Xcompiler=-W4") + else() + set(${warning_options} "-Xcompiler=-Wall") + endif() + elseif (CMAKE_${lang}_COMPILER_ID STREQUAL "Intel") set(${warning_options} "-w3") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "XL") + elseif (CMAKE_${lang}_COMPILER_ID STREQUAL "XL") set(${warning_options} "-qinfo=all") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") - set(${warning_options} "+w;+w2") - elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Fujitsu") + elseif (CMAKE_${lang}_COMPILER_ID STREQUAL "SunPro") + if(lang STREQUAL CXX) + set(${warning_options} "+w;+w2") + else() + set(${warning_options} "") + endif() + elseif (CMAKE_${lang}_COMPILER_ID STREQUAL "Fujitsu") set(${warning_options} "SHELL:-w 8") endif() endmacro() diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOff.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOff.cmake index b05d65e..0af60f0 100644 --- a/Tests/RunCMake/CompileWarningAsError/WerrorOff.cmake +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOff.cmake @@ -1,8 +1,8 @@ -enable_language(CXX) +enable_language(${LANGUAGE}) include(WarningAsErrorOptions.cmake) -get_warning_options(warning_options) +get_warning_options(warning_options ${LANGUAGE}) -add_executable(WerrorOff warn.cxx) +add_executable(WerrorOff warn.${EXTENSION}) target_compile_options(WerrorOff PUBLIC "${warning_options}") set_target_properties(WerrorOff PROPERTIES COMPILE_WARNING_AS_ERROR OFF) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOff_C.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOff_C.cmake new file mode 100644 index 0000000..35c02aa --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOff_C.cmake @@ -0,0 +1 @@ +include(WerrorOff.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOff_CUDA.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOff_CUDA.cmake new file mode 100644 index 0000000..35c02aa --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOff_CUDA.cmake @@ -0,0 +1 @@ +include(WerrorOff.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOff_CXX.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOff_CXX.cmake new file mode 100644 index 0000000..35c02aa --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOff_CXX.cmake @@ -0,0 +1 @@ +include(WerrorOff.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOn.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOn.cmake index 4310333..c3f6526 100644 --- a/Tests/RunCMake/CompileWarningAsError/WerrorOn.cmake +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOn.cmake @@ -1,13 +1,13 @@ -enable_language(CXX) +enable_language(${LANGUAGE}) include(WarningAsErrorOptions.cmake) -get_warning_options(warning_options) +get_warning_options(warning_options ${LANGUAGE}) if (DEFINED warning_options) - add_executable(WerrorOn warn.cxx) + add_executable(WerrorOn warn.${EXTENSION}) target_compile_options(WerrorOn PUBLIC "${warning_options}") set_target_properties(WerrorOn PROPERTIES COMPILE_WARNING_AS_ERROR ON) else() - # if no werror option is set for the environment, use err.cxx so that build fails as expected - add_executable(WerrorOn err.cxx) + # if no werror option is set for the environment, use err so that build fails as expected + add_executable(WerrorOn err.${EXTENSION}) endif() diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore.cmake index 1f7ccdb..847bd78 100644 --- a/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore.cmake +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore.cmake @@ -1,8 +1,8 @@ -enable_language(CXX) +enable_language(${LANGUAGE}) include(WarningAsErrorOptions.cmake) -get_warning_options(warning_options) +get_warning_options(warning_options ${LANGUAGE}) -add_executable(WerrorOn warn.cxx) +add_executable(WerrorOn warn.${EXTENSION}) target_compile_options(WerrorOn PUBLIC "${warning_options}") set_target_properties(WerrorOn PROPERTIES COMPILE_WARNING_AS_ERROR ON) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_C.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_C.cmake new file mode 100644 index 0000000..ebb9e0e --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_C.cmake @@ -0,0 +1 @@ +include(WerrorOnIgnore.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_CUDA.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_CUDA.cmake new file mode 100644 index 0000000..ebb9e0e --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_CUDA.cmake @@ -0,0 +1 @@ +include(WerrorOnIgnore.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_CXX.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_CXX.cmake new file mode 100644 index 0000000..ebb9e0e --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOnIgnore_CXX.cmake @@ -0,0 +1 @@ +include(WerrorOnIgnore.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOn-Build-result.txt b/Tests/RunCMake/CompileWarningAsError/WerrorOn_C-Build-result.txt index d197c91..d197c91 100644 --- a/Tests/RunCMake/CompileWarningAsError/WerrorOn-Build-result.txt +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOn_C-Build-result.txt diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOn_C.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOn_C.cmake new file mode 100644 index 0000000..a00edb8 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOn_C.cmake @@ -0,0 +1 @@ +include(WerrorOn.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOn_CUDA-Build-result.txt b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CUDA-Build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CUDA-Build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOn_CUDA.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CUDA.cmake new file mode 100644 index 0000000..a00edb8 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CUDA.cmake @@ -0,0 +1 @@ +include(WerrorOn.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOn_CXX-Build-result.txt b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CXX-Build-result.txt new file mode 100644 index 0000000..d197c91 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CXX-Build-result.txt @@ -0,0 +1 @@ +[^0] diff --git a/Tests/RunCMake/CompileWarningAsError/WerrorOn_CXX.cmake b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CXX.cmake new file mode 100644 index 0000000..a00edb8 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/WerrorOn_CXX.cmake @@ -0,0 +1 @@ +include(WerrorOn.cmake) diff --git a/Tests/RunCMake/CompileWarningAsError/err.c b/Tests/RunCMake/CompileWarningAsError/err.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/err.c diff --git a/Tests/RunCMake/CompileWarningAsError/err.cu b/Tests/RunCMake/CompileWarningAsError/err.cu new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/err.cu diff --git a/Tests/RunCMake/CompileWarningAsError/warn.c b/Tests/RunCMake/CompileWarningAsError/warn.c new file mode 100644 index 0000000..cd0c2ba --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/warn.c @@ -0,0 +1,25 @@ +static void unused_function(); + +#ifdef __SUNPRO_C +KandR(x) int x; +{ + return x; +} +#endif + +#ifdef __SUNPRO_CC +struct A +{ + virtual ~A() throw(); +}; +struct B : public A +{ + virtual ~B() throw(int); +}; +#endif + +int main(int argc, char* argv[]) +{ + unsigned int unused_sign_conversion = -1; + return 1; +} diff --git a/Tests/RunCMake/CompileWarningAsError/warn.cu b/Tests/RunCMake/CompileWarningAsError/warn.cu new file mode 100644 index 0000000..22b8db8 --- /dev/null +++ b/Tests/RunCMake/CompileWarningAsError/warn.cu @@ -0,0 +1 @@ +#include "warn.c" diff --git a/Tests/RunCMake/CompileWarningAsError/warn.cxx b/Tests/RunCMake/CompileWarningAsError/warn.cxx index 64a245a..22b8db8 100644 --- a/Tests/RunCMake/CompileWarningAsError/warn.cxx +++ b/Tests/RunCMake/CompileWarningAsError/warn.cxx @@ -1,17 +1 @@ -static void unused_function(); - -#ifdef __SUNPRO_CC -struct A -{ - virtual ~A() throw(); -}; -struct B : public A -{ - virtual ~B() throw(int); -}; -#endif - -int main(int unused_argument, char* []) -{ - return 1; -} +#include "warn.c" diff --git a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake index 3908f42..dad0dd3 100644 --- a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake @@ -13,6 +13,9 @@ run_cmake(zip) # Extracting only selected files or directories run_cmake(zip-filtered) +run_cmake(create-missing-args) +run_cmake(extract-missing-args) + run_cmake(unsupported-format) run_cmake(zip-with-bad-compression) run_cmake(7zip-with-bad-compression) diff --git a/Tests/RunCMake/File_Archive/create-missing-args-result.txt b/Tests/RunCMake/File_Archive/create-missing-args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Archive/create-missing-args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Archive/create-missing-args-stderr.txt b/Tests/RunCMake/File_Archive/create-missing-args-stderr.txt new file mode 100644 index 0000000..ecfe401 --- /dev/null +++ b/Tests/RunCMake/File_Archive/create-missing-args-stderr.txt @@ -0,0 +1,9 @@ +^CMake Error at create-missing-args.cmake:[0-9]+ \(file\): + file Keywords missing values: + + OUTPUT + FORMAT + COMPRESSION + COMPRESSION_LEVEL +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/File_Archive/create-missing-args.cmake b/Tests/RunCMake/File_Archive/create-missing-args.cmake new file mode 100644 index 0000000..a0c84d2 --- /dev/null +++ b/Tests/RunCMake/File_Archive/create-missing-args.cmake @@ -0,0 +1,8 @@ +file(ARCHIVE_CREATE + OUTPUT # missing output path + FORMAT # missing output format + COMPRESSION # missing compression type + COMPRESSION_LEVEL # missing compression level + MTIME # missing modification time + PATHS # no paths + ) diff --git a/Tests/RunCMake/File_Archive/extract-missing-args-result.txt b/Tests/RunCMake/File_Archive/extract-missing-args-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Archive/extract-missing-args-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt b/Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt new file mode 100644 index 0000000..96c779f --- /dev/null +++ b/Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt @@ -0,0 +1,7 @@ +^CMake Error at extract-missing-args.cmake:[0-9]+ \(file\): + file Keywords missing values: + + INPUT + DESTINATION +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/File_Archive/extract-missing-args.cmake b/Tests/RunCMake/File_Archive/extract-missing-args.cmake new file mode 100644 index 0000000..21c5d99 --- /dev/null +++ b/Tests/RunCMake/File_Archive/extract-missing-args.cmake @@ -0,0 +1,5 @@ +file(ARCHIVE_EXTRACT + INPUT # missing input + DESTINATION # missing destination + PATTERNS # no patterns + ) diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake index f479dcf..661ae3f 100644 --- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake @@ -24,6 +24,27 @@ endif() # We need a real pkg-config to run the test for get_variable. find_package(PkgConfig) if (PKG_CONFIG_FOUND) + string(FIND "${CMAKE_CURRENT_BINARY_DIR}" " " IS_SPACES_IN_PATH) + if(IS_SPACES_IN_PATH GREATER -1) + string(REPLACE " " "\\ " ESCAPED_ROOT "${CMAKE_CURRENT_BINARY_DIR}") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_spaces.pc" " +libdir=${ESCAPED_ROOT} +Name: test_spaces.pc +Version: 0.0 +Description: test spaces +Libs: -L\${libdir} +") + set(PKG_CONFIG_PATH_SAVED "$ENV{PKG_CONFIG_PATH}") + set(ENV{PKG_CONFIG_PATH} "${CMAKE_CURRENT_BINARY_DIR}") + execute_process(COMMAND "${PKG_CONFIG_EXECUTABLE}" --libs test_spaces + ERROR_QUIET COMMAND_ERROR_IS_FATAL ANY + OUTPUT_VARIABLE test_spaces_LIBS) + set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH_SAVED}") + string(STRIP "${test_spaces_LIBS}" test_spaces_LIBS_STRIPPED) + if(NOT "${test_spaces_LIBS_STRIPPED}" STREQUAL "-L${ESCAPED_ROOT}") + set(PKG_CONFIG_DONT_SUPPORT_SPACES_IN_PATH TRUE) + endif() + endif() run_cmake(FindPkgConfig_GET_VARIABLE) run_cmake(FindPkgConfig_GET_VARIABLE_PREFIX_PATH) run_cmake(FindPkgConfig_GET_VARIABLE_PKGCONFIG_PATH) @@ -32,5 +53,7 @@ if (PKG_CONFIG_FOUND) run_cmake(FindPkgConfig_VERSION_OPERATORS) run_cmake(FindPkgConfig_GET_MATCHING_MODULE_NAME) run_cmake(FindPkgConfig_empty_target) - run_cmake(FindPkgConfig_LIBRARY_PATH) + if(NOT PKG_CONFIG_DONT_SUPPORT_SPACES_IN_PATH) + run_cmake(FindPkgConfig_LIBRARY_PATH) + endif() endif () diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake index 148baac..a79fcaf 100644 --- a/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake +++ b/Tests/RunCMake/GenEx-TARGET_FILE/RunCMakeTest.cmake @@ -2,6 +2,9 @@ include(RunCMake) run_cmake(TARGET_FILE-recursion) run_cmake(OUTPUT_NAME-recursion) +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + run_cmake(TARGET_BUNDLE_DIR_NAME) +endif() run_cmake(TARGET_FILE_DIR-dependency) run_cmake(TARGET_FILE_DIR-no-dependency) run_cmake(TARGET_FILE_PREFIX-imported-target) diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME-check.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME-check.cmake new file mode 100644 index 0000000..6e62ce3 --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME-check.cmake @@ -0,0 +1 @@ +include ("${RunCMake_TEST_BINARY_DIR}/TARGET_BUNDLE_DIR_NAME-generated.cmake") diff --git a/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME.cmake b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME.cmake new file mode 100644 index 0000000..23db8fd --- /dev/null +++ b/Tests/RunCMake/GenEx-TARGET_FILE/TARGET_BUNDLE_DIR_NAME.cmake @@ -0,0 +1,33 @@ +enable_language(C) + +set(GENERATE_CONTENT [[ +macro (check_value test_msg value expected) + if (NOT "${value}" STREQUAL "${expected}") + string (APPEND RunCMake_TEST_FAILED "${test_msg}: actual result:\n [${value}]\nbut expected:\n [${expected}]\n") + endif() +endmacro() +]]) + +add_library(test-lib MODULE empty.c) +set_target_properties(test-lib PROPERTIES BUNDLE TRUE) + +add_library(test-fw empty.c) +set_target_properties(test-fw PROPERTIES FRAMEWORK TRUE) + +add_executable(test-app MACOSX_BUNDLE empty.c) + +add_executable(test-app-custom MACOSX_BUNDLE empty.c) +set_target_properties(test-app-custom PROPERTIES BUNDLE_EXTENSION custom) + +string(APPEND GENERATE_CONTENT [[ +check_value("TARGET_BUNDLE_DIR_NAME library" "$<TARGET_BUNDLE_DIR_NAME:test-lib>" "test-lib.bundle") +check_value("TARGET_BUNDLE_DIR_NAME framework" "$<TARGET_BUNDLE_DIR_NAME:test-fw>" "test-fw.framework") +check_value("TARGET_BUNDLE_DIR_NAME app" "$<TARGET_BUNDLE_DIR_NAME:test-app>" "test-app.app") +check_value("TARGET_BUNDLE_DIR_NAME custom" "$<TARGET_BUNDLE_DIR_NAME:test-app-custom>" "test-app-custom.custom") +]]) + +file( + GENERATE + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/TARGET_BUNDLE_DIR_NAME-generated.cmake" + CONTENT "${GENERATE_CONTENT}" +) diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-with-LINK_LIBRARY2-check.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-with-LINK_LIBRARY2-check.cmake new file mode 100644 index 0000000..b6cabf5 --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-with-LINK_LIBRARY2-check.cmake @@ -0,0 +1,4 @@ + +if (NOT actual_stdout MATCHES "(/|-)-START_GROUP\"? +\"?(/|-)-PREFIX_LIBRARY\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base1${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-LIBFLAG.*${LINK_SHARED_LIBRARY_PREFIX}base2${LINK_SHARED_LIBRARY_SUFFIX}\"? +\"?(/|-)-SUFFIX_LIBRARY\"? +\"?(/|-)-END_GROUP") + set (RunCMake_TEST_FAILED "Not found expected '--START_GROUP --PREFIX_LIBRARY --LIBFLAG<base1> --LIBFLAG<base2> --END_GROUP'.") +endif() diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-with-LINK_LIBRARY2-result.txt b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-with-LINK_LIBRARY2-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP-with-LINK_LIBRARY2-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake index 31eb7e2..fea2f91 100644 --- a/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake +++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/LINK_GROUP.cmake @@ -20,6 +20,9 @@ set(CMAKE_C_LINK_GROUP_USING_feat1_SUPPORTED TRUE) set(CMAKE_C_LINK_LIBRARY_USING_feat1 "--LIBFLAG<LIBRARY>") set(CMAKE_C_LINK_LIBRARY_USING_feat1_SUPPORTED TRUE) +set(CMAKE_C_LINK_LIBRARY_USING_feat2 "--PREFIX_LIBRARY" "--LIBFLAG<LIBRARY>" "--SUFFIX_LIBRARY") +set(CMAKE_C_LINK_LIBRARY_USING_feat2_SUPPORTED TRUE) + set(CMAKE_C_LINK_GROUP_USING_feat2 "--START_GROUP" "--END_GROUP") set(CMAKE_LINK_GROUP_USING_feat2 "--START_GROUP" "--END_GROUP") set(CMAKE_LINK_GROUP_USING_feat2_SUPPORTED TRUE) @@ -53,6 +56,9 @@ target_link_libraries(LinkGroup_group-and-single PRIVATE "$<LINK_GROUP:feat1,bas add_library(LinkGroup_with-LINK_LIBRARY SHARED lib.c) target_link_libraries(LinkGroup_with-LINK_LIBRARY PRIVATE "$<LINK_GROUP:feat1,$<LINK_LIBRARY:feat1,base1>,base2>") +add_library(LinkGroup_with-LINK_LIBRARY2 SHARED lib.c) +target_link_libraries(LinkGroup_with-LINK_LIBRARY2 PRIVATE "$<LINK_GROUP:feat1,$<LINK_LIBRARY:feat2,base1,base2>>") + add_library(LinkGroup_with-LINK_LIBRARY_OVERRIDE SHARED lib.c) target_link_libraries(LinkGroup_with-LINK_LIBRARY_OVERRIDE PRIVATE "$<LINK_GROUP:feat1,$<LINK_LIBRARY:feat1,base1,base3>,base2>") diff --git a/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake index c1d74d0..3ebe269 100644 --- a/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_link_libraries-LINK_GROUP/RunCMakeTest.cmake @@ -46,6 +46,7 @@ if ((RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Xcode" run_cmake_target(LINK_GROUP multiple-groups LinkGroup_multiple-groups) run_cmake_target(LINK_GROUP group-and-single LinkGroup_group-and-single) run_cmake_target(LINK_GROUP with-LINK_LIBRARY LinkGroup_with-LINK_LIBRARY) + run_cmake_target(LINK_GROUP with-LINK_LIBRARY2 LinkGroup_with-LINK_LIBRARY2) run_cmake_target(LINK_GROUP with-LINK_LIBRARY_OVERRIDE LinkGroup_with-LINK_LIBRARY_OVERRIDE) run_cmake(imported-target) |