Merge topic 'xcframework-plist-cache' da330bcf88 macOS: Cache parsed xcframework plist content Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !11076
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst index 52ce7f4..5984117 100644 --- a/Help/command/foreach.rst +++ b/Help/command/foreach.rst
@@ -58,7 +58,8 @@ The ``<items>`` following the ``ITEMS`` keyword are processed as in the first variant of the ``foreach`` command. The forms ``LISTS A`` and ``ITEMS ${A}`` are -equivalent. +equivalent. If no ``<lists>`` or ``<items>`` are given, the body +of the loop will never be executed (i.e., it is processed as empty). The following example shows how the ``LISTS`` option is processed: @@ -97,13 +98,18 @@ command iterates over each list simultaneously setting the iteration variables as follows: -- if the only ``loop_var`` given, then it sets a series of +- if a single ``loop_var`` is given, then it sets a series of ``loop_var_N`` variables to the current item from the corresponding list; -- if multiple variable names passed, their count should match - the lists variables count; -- if any of the lists are shorter, the corresponding iteration - variable is not defined for the current iteration. +- if multiple variable names are passed, it sets each variable to the + current item from the corresponding list. The number of iteration + variables must match the number of list variables. + +If no ``<lists>`` are given, the body of the loop will never be executed +(i.e., it is processed as empty). + +The following example shows how the ``ZIP_LISTS`` option is +processed: .. noqa: spellcheck off
diff --git a/Help/dev/README.rst b/Help/dev/README.rst index 2a2d32d..84766a6 100644 --- a/Help/dev/README.rst +++ b/Help/dev/README.rst
@@ -40,11 +40,13 @@ * The `CMake Documentation Guide`_. * The `CMake Testing Guide`_. * The `CMake Experimental Features Guide`_. +* The `CMake Debugging Guide`_. .. _`CMake Source Code Guide`: source.rst .. _`CMake Documentation Guide`: documentation.rst .. _`CMake Testing Guide`: testing.rst .. _`CMake Experimental Features Guide`: experimental.rst +.. _`CMake Debugging Guide`: debug.rst Maintainer Documentation ========================
diff --git a/Help/dev/debug.rst b/Help/dev/debug.rst new file mode 100644 index 0000000..ded270f --- /dev/null +++ b/Help/dev/debug.rst
@@ -0,0 +1,197 @@ +CMake Debugging Guide +********************* + +This guide explains how to attach a debugger to CMake's unit testing framework. +We'll focus on using **GDB** on Linux for both command-line and IDE debugging. +See documentation on `CMake Development`_ for more information. + +.. _`CMake Development`: README.rst + +Linux: Using GDB +================ + +On Linux, the GNU Debugger (**GDB**) is the standard tool for debugging the +CMake test suite. The core process involves launching the ``cmake`` executable +from within GDB with a specific set of arguments that configure and run the +desired test. + +GDB Configuration +----------------- + +For effective debugging, GDB must be configured to handle child processes +correctly, which CMake tests often create. A good practice is to use a local +``.gdbinit`` file in your build directory. This keeps CMake-specific settings +separate from your global configuration. + +**1. Enable Local .gdbinit Files (One-Time Setup)** + +To allow GDB to automatically load configuration from your build directory, +add the following line to your global GDB initialization file at +``$HOME/.gdbinit``. This is a one-time setup that makes future projects easier +to manage. + +.. code-block:: text + + set auto-load local-gdbinit on + +**2. Create a Project-Specific .gdbinit** + +Next, create a ``.gdbinit`` file inside your CMake **build directory**. +This file will contain settings specific to debugging CMake. +To make this easier, you can symlink the template file provided in the CMake +source tree: + +.. code-block:: bash + + # Navigate to your build directory + cd /path/to/your/cmake/build + + # Create a symlink to the template + ln -s $cmake_srcdir/Utilities/gdb/gdbinit-template .gdbinit + +The template contains the essential settings for debugging CMake tests: + +.. code-block:: gdb + + # Allows GDB to follow child processes + set follow-fork-mode child + + # Allows the parent process continue in parallel + set non-stop on + +Debugging from the Command Line +------------------------------- + +To start debugging, first cd to the build directory. Then, launch the +``cmake`` executable using ``gdb --args``, which passes the necessary test +configuration arguments directly to CMake. + +.. note:: + + To get the launch command, run ``ctest -R "RunCMake.$TESTNAME" -VV -N`` + + +The following example runs the ``InstallPackageInfo`` test. + +.. code-block:: bash + + # Define paths to your CMake source and build directories + CMAKE_SOURCE_DIR="$HOME/cmake" + CMAKE_BUILD_DIR="$CMAKE_SOURCE_DIR/build" + + # Define the specific test to run + TEST_NAME="InstallPackageInfo" + + # Navigate to the build directory + cd "$CMAKE_BUILD_DIR" + + # Launch GDB with the appropriate arguments for the test + gdb --args ./bin/cmake \ + "-DCMAKE_MODULE_PATH=$CMAKE_SOURCE_DIR/Tests/RunCMake" \ + "-DRunCMake_GENERATOR=Ninja" \ + "-DRunCMake_SOURCE_DIR=$CMAKE_SOURCE_DIR/Tests/RunCMake/$TEST_NAME" \ + "-DRunCMake_BINARY_DIR=$CMAKE_BUILD_DIR/Tests/RunCMake/$TEST_NAME" \ + "-P" "$CMAKE_SOURCE_DIR/Tests/RunCMake/RunCMakeTest.cmake" + +Once GDB loads, you may set breakpoints (e.g., ``b cmInstallCommand``) and +then start the test by typing ``run``. + +Filtering Tests +--------------- + +Some test suites contain multiple sub-tests. To run only a specific one, +you can use the ``RunCMake_TEST_FILTER`` environment variable. + +For example, to run only the "Metadata" test within the ``InstallPackageInfo`` +suite, you can set the variable before launching GDB: + +.. code-block:: bash + + RunCMake_TEST_FILTER="Metadata" gdb --args ... + +Alternatively, you can set the environment variable from within the +GDB session before running the test: + +.. code-block:: gdb-prompt + + (gdb) set environment RunCMake_TEST_FILTER Metadata + (gdb) run + + +IDE Integration +--------------- + +You can also debug CMake tests directly from your IDE. + +CLion +===== + +If you have configured GDB to auto-load local ``.gdbinit`` files as described +above, CLion will automatically pick up the necessary settings. + +A simple way to debug a test is to modify its ``CTest`` run configuration: + +#. **Select the Test**: In the "Run/Debug Configurations" dialog, find the + ``CTest`` entry for your test (e.g., ``RunCMake.InstallPackageInfo``). +#. **Add CTest Arguments**: In the "CTest arguments" field, add + ``--extra-verbose``. This is helpful for debugging because it prints the + exact command ``CTest`` uses to run the test. +#. **Set Working Directory**: Ensure the "Working Directory" field is set to + ``$CMakeCurrentLocalGenerationDir$``. + +You can now set breakpoints in your code and debug this configuration. + +Visual Studio Code +================== + +Create a ``launch.json`` file in the ``.vscode`` directory of your +CMake **source folder** with the following configuration. This configuration +hardcodes the necessary GDB settings, so it does not depend on an external +``.gdbinit`` file. + +.. code-block:: json + + { + "version": "0.2.0", + "configurations": [ + { + "name": "Debug CMake Test", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/build/bin/cmake", + "args": [ + "-DCMAKE_MODULE_PATH=${workspaceFolder}/Tests/RunCMake", + "-DRunCMake_GENERATOR=Ninja", + "-DRunCMake_SOURCE_DIR=${workspaceFolder}/Tests/RunCMake/InstallPackageInfo", + "-DRunCMake_BINARY_DIR=${workspaceFolder}/build/Tests/RunCMake/InstallPackageInfo", + "-P", + "${workspaceFolder}/Tests/RunCMake/RunCMakeTest.cmake" + ], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/build", + "environment": [], + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Follow child processes", + "text": "set follow-fork-mode child", + "ignoreFailures": true + }, + { + "description": "Don't stop the parent process", + "text": "set non-stop on", + "ignoreFailures": true + } + ] + } + ] + } + +.. note:: + + Remember to change the test name (``InstallPackageInfo``) in the ``"args"`` section to the specific test you want to debug.
diff --git a/Help/envvar/CTEST_USE_INSTRUMENTATION.rst b/Help/envvar/CTEST_USE_INSTRUMENTATION.rst index 6e33845..b00c92d 100644 --- a/Help/envvar/CTEST_USE_INSTRUMENTATION.rst +++ b/Help/envvar/CTEST_USE_INSTRUMENTATION.rst
@@ -10,6 +10,6 @@ This feature is only available when experimental support for instrumentation has been enabled by the ``CMAKE_EXPERIMENTAL_INSTRUMENTATION`` gate. -Setting this environment variable enables +Setting this environment variable to ``1``, ``True``, or ``ON`` enables :manual:`instrumentation <cmake-instrumentation(7)>` for CTest in :ref:`Dashboard Client` mode.
diff --git a/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst b/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst index 95053e4..4a119aa 100644 --- a/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst +++ b/Help/envvar/CTEST_USE_VERBOSE_INSTRUMENTATION.rst
@@ -10,8 +10,9 @@ This feature is only available when experimental support for instrumentation has been enabled by the ``CMAKE_EXPERIMENTAL_INSTRUMENTATION`` gate. -Setting this environment variable causes CTest to report the full -command line (including arguments) to CDash for each instrumented command. -By default, CTest truncates the command line at the first space. +Setting this environment variable to ``1``, ``True``, or ``ON`` causes CTest to +report the full command line (including arguments) to CDash for each +instrumented command. By default, CTest truncates the command line at the first +space. See also :envvar:`CTEST_USE_INSTRUMENTATION`
diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index f7896e5..7e1f61b 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst
@@ -154,7 +154,7 @@ ``Foo_FIND_COMPONENTS`` if it is set , and only set ``Foo_FOUND`` to true if for each searched-for component ``<c>`` that was not found, ``Foo_FIND_REQUIRED_<c>`` is not set to true. The ``HANDLE_COMPONENTS`` -argument of ``find_package_handle_standard_args()`` can be used to +argument of :command:`find_package_handle_standard_args` can be used to implement this. If ``Foo_FIND_COMPONENTS`` is not set, which modules are searched for
diff --git a/Help/manual/cmake-instrumentation.7.rst b/Help/manual/cmake-instrumentation.7.rst index d2106aa..06e71ed 100644 --- a/Help/manual/cmake-instrumentation.7.rst +++ b/Help/manual/cmake-instrumentation.7.rst
@@ -98,8 +98,7 @@ ---------------------------------------------- You can enable instrumentation when using CTest in :ref:`Dashboard Client` -mode by setting the :envvar:`CTEST_USE_INSTRUMENTATION` environment variable -to the current UUID for the ``CMAKE_EXPERIMENTAL_INSTRUMENTATION`` feature. +mode by setting the :envvar:`CTEST_USE_INSTRUMENTATION` environment variable. Doing so automatically enables the ``dynamicSystemInformation`` option. The following table shows how each type of instrumented command gets mapped
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 63622a8..58f5e3b 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst
@@ -282,6 +282,7 @@ /prop_tgt/IMPORT_SUFFIX /prop_tgt/INCLUDE_DIRECTORIES /prop_tgt/INSTALL_NAME_DIR + /prop_tgt/INSTALL_OBJECT_NAME_STRATEGY /prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH /prop_tgt/INSTALL_RPATH /prop_tgt/INSTALL_RPATH_USE_LINK_PATH
diff --git a/Help/manual/cmake-qt.7.rst b/Help/manual/cmake-qt.7.rst index f9729b3..fe269c2 100644 --- a/Help/manual/cmake-qt.7.rst +++ b/Help/manual/cmake-qt.7.rst
@@ -224,10 +224,10 @@ =============================== The ``moc`` and ``uic`` tools are executed as part of a synthesized -:ref:`<ORIGIN>_autogen` :command:`custom target <add_custom_target>` generated by -CMake. By default that :ref:`<ORIGIN>_autogen` target inherits the dependencies +``<ORIGIN>_autogen`` :command:`custom target <add_custom_target>` generated by +CMake. By default, that ``<ORIGIN>_autogen`` target inherits the dependencies of the ``<ORIGIN>`` target (see :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`). -Target dependencies may be added to the :ref:`<ORIGIN>_autogen` target by adding +Target dependencies may be added to the ``<ORIGIN>_autogen`` target by adding them to the :prop_tgt:`AUTOGEN_TARGET_DEPENDS` target property. .. note:: @@ -241,9 +241,10 @@ If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or :ref:`Makefile Generators`, the ``<ORIGIN>_autogen_timestamp_deps`` target is -also created in addition to the :ref:`<ORIGIN>_autogen` target. This target -does not have any sources or commands to execute, but it has dependencies that -were previously inherited by the pre-Qt 5.15 :ref:`<ORIGIN>_autogen` target. +also created in addition to the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` +target. This target does not have any sources or commands to execute, but it +has dependencies that were previously inherited by the pre-Qt 5.15 +:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. These dependencies will serve as a list of order-only dependencies for the custom command, without forcing the custom command to re-execute. @@ -252,11 +253,11 @@ When using the :ref:`Visual Studio Generators`, CMake generates a ``PRE_BUILD`` :command:`custom command <add_custom_command>` -instead of the :ref:`<ORIGIN>_autogen` +instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` :command:`custom target <add_custom_target>` (for :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`). This isn't always possible though and an -:ref:`<ORIGIN>_autogen` :command:`custom target <add_custom_target>` is used, -when either +:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` +:command:`custom target <add_custom_target>` is used, when either - the ``<ORIGIN>`` target depends on :prop_sf:`GENERATED` files which aren't excluded from :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` by
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index c936f50..28d7b38 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst
@@ -489,6 +489,7 @@ /variable/CMAKE_INCLUDE_CURRENT_DIR /variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE /variable/CMAKE_INSTALL_NAME_DIR + /variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY /variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH /variable/CMAKE_INSTALL_RPATH /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
diff --git a/Help/policy/CMP0183.rst b/Help/policy/CMP0183.rst index 6804c3b..f2d6601 100644 --- a/Help/policy/CMP0183.rst +++ b/Help/policy/CMP0183.rst
@@ -5,7 +5,7 @@ :command:`add_feature_info` supports full :ref:`Condition Syntax`. -The ``<enabled>`` parameter accepts a :ref:`semicolon-separated list <CMake +The ``<condition>`` parameter accepts a :ref:`semicolon-separated list <CMake Language Lists>` of conditions. CMake 3.31 and lower evaluate each ``condition`` as ``if(${condition})``, which does not properly handle conditions with nested paren groups. CMake 4.0 and above instead prefer
diff --git a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst index 33db8a7..4bf83eb 100644 --- a/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_ORIGIN_DEPENDS.rst
@@ -4,29 +4,29 @@ .. versionadded:: 3.14 Switch for forwarding origin target dependencies to the corresponding -:ref:`<ORIGIN>_autogen` target. +:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. .. note:: If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or :ref:`Makefile Generators`, origin target dependencies are forwarded to - the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of - :ref:`<ORIGIN>_autogen` - + the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>` + target instead of :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>`. Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property -``ON`` have a corresponding :ref:`<ORIGIN>_autogen` target which generates -``moc`` and ``uic`` files. As this :ref:`<ORIGIN>_autogen` target is created at +``ON`` have a corresponding :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target +which generates ``moc`` and ``uic`` files. +As this :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target is created at generate-time, it is not possible to define dependencies of it using e.g. :command:`add_dependencies`. Instead the ``AUTOGEN_ORIGIN_DEPENDS`` target property decides whether the origin target dependencies should be -forwarded to the :ref:`<ORIGIN>_autogen` target or not. +forwarded to the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target or not. By default ``AUTOGEN_ORIGIN_DEPENDS`` is initialized from :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` which is ``ON`` by default. -In total the dependencies of the :ref:`<ORIGIN>_autogen` target are composed -from +In total the dependencies of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` +target are composed from - forwarded origin target dependencies (enabled by default via ``AUTOGEN_ORIGIN_DEPENDS``) @@ -38,11 +38,12 @@ .. note:: Disabling ``AUTOGEN_ORIGIN_DEPENDS`` is useful to avoid building of - origin target dependencies when building the :ref:`<ORIGIN>_autogen` target - only. This is especially interesting when a + origin target dependencies when building the + :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target only. + This is especially interesting when a :variable:`global autogen target <CMAKE_GLOBAL_AUTOGEN_TARGET>` is enabled. - When the :ref:`<ORIGIN>_autogen` target doesn't require all the origin target's - dependencies, and ``AUTOGEN_ORIGIN_DEPENDS`` is disabled, it might be - necessary to extend :prop_tgt:`AUTOGEN_TARGET_DEPENDS` to add missing - dependencies. + When the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target doesn't require + all the origin target's dependencies, and ``AUTOGEN_ORIGIN_DEPENDS`` is + disabled, it might be necessary to extend :prop_tgt:`AUTOGEN_TARGET_DEPENDS` + to add missing dependencies.
diff --git a/Help/prop_tgt/AUTOGEN_PARALLEL.rst b/Help/prop_tgt/AUTOGEN_PARALLEL.rst index 9d34355..c1c86e8 100644 --- a/Help/prop_tgt/AUTOGEN_PARALLEL.rst +++ b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
@@ -6,9 +6,9 @@ Number of parallel ``moc`` or ``uic`` processes to start when using :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`. -The custom :ref:`<ORIGIN>_autogen` target starts a number of threads of which -each one parses a source file and on demand starts a ``moc`` or ``uic`` -process. ``AUTOGEN_PARALLEL`` controls how many parallel threads +The custom :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target starts a number +of threads. Each thread parses a source file and on demand starts a ``moc`` +or ``uic`` process. ``AUTOGEN_PARALLEL`` controls how many parallel threads (and therefore ``moc`` or ``uic`` processes) are started. - An empty (or unset) value or the string ``AUTO`` sets the number of
diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst index 13e2ef7..892dc5e 100644 --- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
@@ -1,28 +1,29 @@ AUTOGEN_TARGET_DEPENDS ---------------------- -Additional target dependencies of the corresponding :ref:`<ORIGIN>_autogen` -target. +Additional target dependencies of the corresponding +:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. .. note:: If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or :ref:`Makefile Generators`, additional target dependencies are added to - the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of the - :ref:`<ORIGIN>_autogen` target. + the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>` + target instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. Targets which have their :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` property -``ON`` have a corresponding :ref:`<ORIGIN>_autogen` target which generates -``moc`` and ``uic`` files. As this :ref:`<ORIGIN>_autogen` target is created +``ON`` have a corresponding :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target +which generates ``moc`` and ``uic`` files. +As this :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target is created at generate-time, it is not possible to define dependencies of it using e.g. :command:`add_dependencies`. Instead the ``AUTOGEN_TARGET_DEPENDS`` target property can be set to a :ref:`;-list <CMake Language Lists>` of additional -dependencies for the :ref:`<ORIGIN>_autogen` target. Dependencies can be target -names or file names. +dependencies for the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. +Dependencies can be target names or file names. -In total the dependencies of the :ref:`<ORIGIN>_autogen` target are composed -from +In total, the dependencies of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` +target are composed from - forwarded origin target dependencies (enabled by default via :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS`)
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 0bd4d13..25c5632 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst
@@ -251,8 +251,8 @@ :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`: A global ``autogen`` target, that depends on all ``AUTOMOC`` or -:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen` targets in the project, -will be generated when this variable is ``ON``. +:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` +targets in the project, will be generated when this variable is ``ON``. :prop_tgt:`AUTOGEN_PARALLEL`: This target property controls the number of ``moc`` or ``uic`` processes to
diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst index fec98f6..50da7c0 100644 --- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst +++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
@@ -22,7 +22,7 @@ If any of the extracted files is :prop_sf:`GENERATED` or if it is not in the target's sources, then it might be necessary to add it to the -:ref:`<ORIGIN>_autogen` target dependencies. +:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target dependencies. See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference. By default ``AUTOMOC_DEPEND_FILTERS`` is initialized from
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 6f1c85c..8901de3 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst
@@ -76,8 +76,8 @@ :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET`: A global ``autogen`` target, that depends on all :prop_tgt:`AUTOMOC` or -``AUTOUIC`` generated :ref:`<ORIGIN>_autogen` targets in the project, -will be generated when this variable is ``ON``. +``AUTOUIC`` generated :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` +targets in the project, will be generated when this variable is ``ON``. :prop_tgt:`AUTOGEN_PARALLEL`: This target property controls the number of ``moc`` or ``uic`` processes to
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst index 9b381e4..177f12e 100644 --- a/Help/prop_tgt/CXX_STANDARD.rst +++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -40,9 +40,6 @@ ``26`` .. versionadded:: 3.25 - C++26. CMake 3.25 and later *recognize* ``26`` as a valid value, - no version has support for any compiler. - If the value requested does not result in a compile flag being added for the compiler in use, a previous standard flag will be added instead. This means that using:
diff --git a/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst b/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst index b7405d6..f74f6d3 100644 --- a/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst +++ b/Help/prop_tgt/EXPORT_FIND_PACKAGE_NAME.rst
@@ -6,9 +6,10 @@ Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES``. Control the package name associated with a dependency target when exporting a -:command:`find_dependency` call in :command:`install(EXPORT)` or +:command:`find_dependency` call in :command:`install(PACKAGE_INFO)`, +:command:`export(PACKAGE_INFO)`, :command:`install(EXPORT)` or :command:`export(EXPORT)`. This can be used to assign a package name to a -package that is built by CMake and exported, or to override the package in the -:command:`find_package` call that created the target. +package that is built by CMake and exported, or a package that was provided by +:module:`FetchContent`. This property is initialized by :variable:`CMAKE_EXPORT_FIND_PACKAGE_NAME`.
diff --git a/Help/prop_tgt/INSTALL_OBJECT_NAME_STRATEGY.rst b/Help/prop_tgt/INSTALL_OBJECT_NAME_STRATEGY.rst new file mode 100644 index 0000000..99f5170 --- /dev/null +++ b/Help/prop_tgt/INSTALL_OBJECT_NAME_STRATEGY.rst
@@ -0,0 +1,23 @@ +INSTALL_OBJECT_NAME_STRATEGY +---------------------------- + +.. versionadded:: 4.2 + +``INSTALL_OBJECT_NAME_STRATEGY`` is a string target property variable +specifying the strategy to use when naming installed object files. The +supported values are: + +- ``FULL``: Object files are named after the associated source file. +- ``SHORT``: Object files are named based on the hash of the source file name + to reduce path lengths. + +When unset or the named strategy is not supported, the ``FULL`` strategy is +used. + +This property is initialized by the value of the variable +:variable:`CMAKE_INSTALL_OBJECT_NAME_STRATEGY` if it is set when a target is +created. + +.. note:: + Not all generators support all strategies and paths may differ between + generators.
diff --git a/Help/release/3.14.rst b/Help/release/3.14.rst index 6b3a187..e4a386a 100644 --- a/Help/release/3.14.rst +++ b/Help/release/3.14.rst
@@ -302,7 +302,7 @@ * A new :variable:`CMAKE_AUTOGEN_ORIGIN_DEPENDS` variable and :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` target property may be set to enable or disable forwarding of the origin target dependencies to the corresponding - :ref:`<ORIGIN>_autogen` target. + :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. CTest ----- @@ -346,6 +346,9 @@ ``xmlrpc``. CDash is the only maintained testing dashboard for CTest, and it only supports submissions over ``http`` and ``https``. +* The :module:`MacroAddFileDependencies` module is deprecated. + Port projects to use :command:`set_property` directly. + Other Changes =============
diff --git a/Help/release/3.16.rst b/Help/release/3.16.rst index 28273a7..f9f9b33 100644 --- a/Help/release/3.16.rst +++ b/Help/release/3.16.rst
@@ -165,7 +165,7 @@ a new ``REASON_FAILURE_MESSAGE`` option to specify a message giving the reason for the failure. -* The :module:`FindPkgConfig` module :command:`pkg_search_module` macro +* The :module:`FindPkgConfig` module :command:`pkg_search_module` command now defines a ``<prefix>_MODULE_NAME`` result variable containing the first matching module name.
diff --git a/Help/release/3.22.rst b/Help/release/3.22.rst index efc8115..fa57fc4 100644 --- a/Help/release/3.22.rst +++ b/Help/release/3.22.rst
@@ -75,7 +75,7 @@ * The :module:`FindMatlab` module now provides imported targets. -* The :module:`FindPkgConfig` module gained a :variable:`PKG_CONFIG_ARGN` +* The :module:`FindPkgConfig` module gained a ``PKG_CONFIG_ARGN`` variable to specify arguments to ``pkg-config`` calls. * The :module:`GoogleTest` module :command:`gtest_discover_tests`
diff --git a/Help/release/3.3.rst b/Help/release/3.3.rst index efb6a7c..3b1da25 100644 --- a/Help/release/3.3.rst +++ b/Help/release/3.3.rst
@@ -135,7 +135,7 @@ documentation, and unit tests. * The :module:`FindPackageHandleStandardArgs` module - ``find_package_handle_standard_args`` function now + :command:`find_package_handle_standard_args` command now always populates both the ``<PackageName>_FOUND`` and ``<UPPERCASE_NAME>_FOUND`` variables (the latter for backwards compatibility). The ``FOUND_VAR``
diff --git a/Help/release/dev/FindDevIL.rst b/Help/release/dev/FindDevIL.rst new file mode 100644 index 0000000..b94a933 --- /dev/null +++ b/Help/release/dev/FindDevIL.rst
@@ -0,0 +1,6 @@ +FindDevIL +--------- + +* The :module:`FindDevIL` module now provides a ``DevIL_VERSION`` result + variable and version argument and version range can be specified by + :command:`find_package`, when finding the DevIL package.
diff --git a/Help/release/dev/find-modules.rst b/Help/release/dev/find-modules.rst index 80f548a..6b92227 100644 --- a/Help/release/dev/find-modules.rst +++ b/Help/release/dev/find-modules.rst
@@ -31,6 +31,9 @@ * The :module:`FindGnuplot` module now provides a ``Gnuplot_VERSION`` result variable. The ``GNUPLOT_VERSION_STRING`` result variable is deprecated. +* The :module:`FindGnuTLS` module now provides a ``GnuTLS_VERSION`` result + variable. The ``GNUTLS_VERSION`` result variable is deprecated. + * The :module:`FindJasper` module now provides a ``Jasper_VERSION`` result variable. The ``JASPER_VERSION_STRING`` result variable is deprecated. @@ -46,6 +49,14 @@ * The :module:`FindLTTngUST` module now provides a ``LTTngUST_VERSION`` result variable. The ``LTTNGUST_VERSION_STRING`` result variable is deprecated. +* The :module:`FindLua` module now provides ``Lua_VERSION``, + ``Lua_VERSION_MAJOR``, ``Lua_VERSION_MINOR``, and ``Lua_VERSION_PATCH`` + result variables. The ``LUA_VERSION_STRING``, ``LUA_VERSION_MAJOR``, + ``LUA_VERSION_MINOR``, and ``LUA_VERSION_PATCH`` result variables are + deprecated. The :module:`FindLua51` module now similarly provides a + ``Lua_VERSION`` instead of the now deprecated ``LUA_VERSION_STRING`` result + variable. + * The :module:`FindOpenSceneGraph` module now provides an ``OpenSceneGraph_VERSION`` result variable. The ``OPENSCENEGRAPH_VERSION`` result variable is deprecated. @@ -53,6 +64,12 @@ * The :module:`FindOpenSSL` module now provides an ``OpenSSL_VERSION`` result variable. The ``OPENSSL_VERSION`` result variable is deprecated. +* The :module:`FindPerl` module now provides a ``Perl_VERSION`` result + variable. The ``PERL_VERSION_STRING`` result variable is deprecated. + +* The :module:`FindPerlLibs` module now provides a ``PerlLibs_VERSION`` + result variable. + * The :module:`FindPNG` module now provides a ``PNG_VERSION`` result variable. The ``PNG_VERSION_STRING`` result variable is deprecated. @@ -71,5 +88,9 @@ ``SQUISH_VERSION_MINOR``, and ``SQUISH_VERSION_PATCH`` result variables are deprecated. +* The :module:`FindSubversion` module now provides a ``Subversion_VERSION`` + result variable. The ``Subversion_VERSION_SVN`` result variable is + deprecated. + * The :module:`FindTIFF` module now provides a ``TIFF_VERSION`` result variable. The ``TIFF_VERSION_STRING`` result variable is deprecated.
diff --git a/Help/release/dev/install-object-name-strategy.rst b/Help/release/dev/install-object-name-strategy.rst new file mode 100644 index 0000000..bfc189a --- /dev/null +++ b/Help/release/dev/install-object-name-strategy.rst
@@ -0,0 +1,5 @@ +install-object-name-strategy +---------------------------- + +* The :prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` target property has been added + to control the naming strategy for installed object files.
diff --git a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst index 52aa891..139268b 100644 --- a/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst +++ b/Help/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS.rst
@@ -4,14 +4,14 @@ .. versionadded:: 3.14 Switch for forwarding origin target dependencies to the corresponding -:ref:`<ORIGIN>_autogen` targets. +:ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` targets. .. note:: If Qt 5.15 or later is used and the generator is either :generator:`Ninja` or :ref:`Makefile Generators`, additional target dependencies are added to - the :ref:`<ORIGIN>_autogen_timestamp_deps` target instead of the - :ref:`<ORIGIN>_autogen` target. + the :ref:`<ORIGIN>_autogen_timestamp_deps <<ORIGIN>_autogen_timestamp_deps>` + target instead of the :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` target. This variable is used to initialize the :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` property on all the targets. See that target property for additional
diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst index 2bf5f05..6e2ecc3 100644 --- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst +++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
@@ -7,9 +7,10 @@ When ``CMAKE_GLOBAL_AUTOGEN_TARGET`` is enabled, a custom target ``autogen`` is generated. This target depends on all :prop_tgt:`AUTOMOC` and -:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen` targets in the project. -By building the global ``autogen`` target, all :prop_tgt:`AUTOMOC` and -:prop_tgt:`AUTOUIC` files in the project will be generated. +:prop_tgt:`AUTOUIC` generated :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` +targets in the project. By building the global ``autogen`` target, all +:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` files in the project will be +generated. The name of the global ``autogen`` target can be changed by setting :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET_NAME`. @@ -21,7 +22,8 @@ .. note:: - :ref:`<ORIGIN>_autogen` targets by default inherit their origin target's - dependencies. This might result in unintended dependency target builds when - only :ref:`<ORIGIN>_autogen` targets are built. A solution is to disable - :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` on the respective origin targets. + :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` targets by default inherit their + origin target's dependencies. This might result in unintended dependency + target builds when only :ref:`<ORIGIN>_autogen <<ORIGIN>_autogen>` targets + are built. A solution is to disable :prop_tgt:`AUTOGEN_ORIGIN_DEPENDS` on + the respective origin targets.
diff --git a/Help/variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY.rst b/Help/variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY.rst new file mode 100644 index 0000000..14cba99 --- /dev/null +++ b/Help/variable/CMAKE_INSTALL_OBJECT_NAME_STRATEGY.rst
@@ -0,0 +1,8 @@ +CMAKE_INSTALL_OBJECT_NAME_STRATEGY +---------------------------------- + +Strategy to use for naming installed object files. + +``CMAKE_INSTALL_OBJECT_NAME_STRATEGY`` is used to initialize the +:prop_tgt:`INSTALL_OBJECT_NAME_STRATEGY` property on all targets. See that +target property for more information.
diff --git a/Help/variable/CMAKE_LANG_LINK_MODE.rst b/Help/variable/CMAKE_LANG_LINK_MODE.rst index 6025671..f8286e4 100644 --- a/Help/variable/CMAKE_LANG_LINK_MODE.rst +++ b/Help/variable/CMAKE_LANG_LINK_MODE.rst
@@ -12,3 +12,8 @@ The linker is used directly for the link step. This variable is read-only. Setting it is undefined behavior. + +See Also +^^^^^^^^ + +* The :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable.
diff --git a/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst b/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst index 7b252aa..a3d6c97 100644 --- a/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst +++ b/Help/variable/CMAKE_LANG_USING_LINKER_MODE.rst
@@ -1,10 +1,17 @@ CMAKE_<LANG>_USING_LINKER_MODE ------------------------------ +.. deprecated:: 4.0 + + This variable is no longer used. The type of information stored in the + :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable is determined by + the :variable:`CMAKE_<LANG>_LINK_MODE` variable. + .. versionadded:: 3.29 -This controls how the value of the :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` -variable should be interpreted. The supported linker mode values are: +This variable controls how the value of the +:variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable should be interpreted. +The supported linker mode values are: ``FLAG`` :variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` holds a @@ -22,11 +29,5 @@ * value ``TOOL`` is expected and required when the linker is used directly for the link step. - * value ``FLAGS`` is expected or the variable not set when the compiler is + * value ``FLAG`` is expected or the variable not set when the compiler is used as driver for the link step. - -.. deprecated:: 4.0 - -This variable is no longer used. The type of information stored in the -:variable:`CMAKE_<LANG>_USING_LINKER_<TYPE>` variable is determined by the -:variable:`CMAKE_<LANG>_LINK_MODE` variable.
diff --git a/Modules/AddFileDependencies.cmake b/Modules/AddFileDependencies.cmake index 13828f2..25a78a8 100644 --- a/Modules/AddFileDependencies.cmake +++ b/Modules/AddFileDependencies.cmake
@@ -6,28 +6,38 @@ ------------------- .. deprecated:: 3.20 + Do not use this module in new code. -Add dependencies to a source file. + Instead use the :command:`set_property` command to append to the + :prop_sf:`OBJECT_DEPENDS` source file property directly: + + .. code-block:: cmake + + set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...) + +Load this module in a CMake project with: .. code-block:: cmake - add_file_dependencies(<source> <files>...) + include(AddFileDependencies) -Adds the given ``<files>`` to the dependencies of file ``<source>``. +Commands +^^^^^^^^ -Do not use this command in new code. It is just a wrapper around: +This module provides the following command: -.. code-block:: cmake +.. command:: add_file_dependencies - set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...) + Adds dependencies to a source file: -Instead use the :command:`set_property` command to append to the -:prop_sf:`OBJECT_DEPENDS` source file property directly. + .. code-block:: cmake + add_file_dependencies(<source> <files>...) + + This command adds the given ``<files>`` to the dependencies of file + ``<source>``. #]=======================================================================] function(add_file_dependencies _file) - set_property(SOURCE "${_file}" APPEND PROPERTY OBJECT_DEPENDS "${ARGN}") - endfunction()
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake index 4df5bb9..0c7fede 100644 --- a/Modules/BundleUtilities.cmake +++ b/Modules/BundleUtilities.cmake
@@ -733,7 +733,9 @@ string(REGEX REPLACE "rpath " "" load_cmds_ov "${load_cmds_ov}") if(load_cmds_ov) foreach(rpath ${load_cmds_ov}) - gp_append_unique(${rpaths_var} "${rpath}") + if(NOT rpath IN_LIST ${rpaths_var}) + list(APPEND ${rpaths_var} "${rpath}") + endif() endforeach() endif() endif() @@ -744,7 +746,9 @@ foreach(rpath ${rpath_var} ${runpath_var}) # Substitute $ORIGIN with the exepath and add to the found rpaths string(REPLACE "$ORIGIN" "${item_dir}" rpath "${rpath}") - gp_append_unique(${rpaths_var} "${rpath}") + if(NOT rpath IN_LIST ${rpaths_var}) + list(APPEND ${rpaths_var} "${rpath}") + endif() endforeach() endif() @@ -787,7 +791,9 @@ get_item_key("${item}" key) list(LENGTH ${keys_var} length_before) - gp_append_unique(${keys_var} "${key}") + if(NOT key IN_LIST ${keys_var}) + list(APPEND ${keys_var} "${key}") + endif() list(LENGTH ${keys_var} length_after) if(NOT length_before EQUAL length_after)
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index ca69c38..edb3cc8 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -257,21 +257,27 @@ # _CUDA_TARGET_DIR always points to the directory containing the include directory. # On a scattered installation /usr, on a non-scattered something like /usr/local/cuda or /usr/local/cuda-10.2/targets/aarch64-linux. if(EXISTS "${_CUDA_TARGET_DIR}/include/cuda_runtime.h") - set(_CUDA_INCLUDE_DIR "${_CUDA_TARGET_DIR}/include") + set(_CUDA_INCLUDE_DIRS "${_CUDA_TARGET_DIR}/include") else() - message(FATAL_ERROR "Unable to find cuda_runtime.h in \"${_CUDA_TARGET_DIR}/include\" for _CUDA_INCLUDE_DIR.") + message(FATAL_ERROR "Unable to find cuda_runtime.h in \"${_CUDA_TARGET_DIR}/include\" for _CUDA_INCLUDE_DIRS.") + endif() + + # CUDA 13 has multiple includes that are implicitly added by nvcc that we need to replicate for + # clang-cuda + if(EXISTS "${_CUDA_TARGET_DIR}/include/cccl") + list(APPEND _CUDA_INCLUDE_DIRS "${_CUDA_TARGET_DIR}/include/cccl") endif() # Clang does not add any CUDA SDK libraries or directories when invoking the host linker. # Add the CUDA toolkit library directory ourselves so that linking works. # The CUDA runtime libraries are handled elsewhere by CMAKE_CUDA_RUNTIME_LIBRARY. - set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${_CUDA_INCLUDE_DIR}") + set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${_CUDA_INCLUDE_DIRS}") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "${_CUDA_LIBRARY_DIR}") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "") set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "") # Don't leak variables unnecessarily to user code. - unset(_CUDA_INCLUDE_DIR) + unset(_CUDA_INCLUDE_DIRS) unset(_CUDA_LIBRARY_DIR) unset(_CUDA_TARGET_DIR) elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
diff --git a/Modules/CMakeForceCompiler.cmake b/Modules/CMakeForceCompiler.cmake index e85c3f9..9b85c68 100644 --- a/Modules/CMakeForceCompiler.cmake +++ b/Modules/CMakeForceCompiler.cmake
@@ -9,66 +9,98 @@ Do not use. -The macros provided by this module were once intended for use by -cross-compiling toolchain files when CMake was not able to automatically -detect the compiler identification. Since the introduction of this module, -CMake's compiler identification capabilities have improved and can now be -taught to recognize any compiler. Furthermore, the suite of information -CMake detects from a compiler is now too extensive to be provided by -toolchain files using these macros. + The commands provided by this module were once intended for use by + cross-compiling toolchain files when CMake was not able to automatically + detect the compiler identification. Since the introduction of this module, + CMake's compiler identification capabilities have improved and can now be + taught to recognize any compiler. Furthermore, the suite of information + CMake detects from a compiler is now too extensive to be provided by + toolchain files using these macros. -One common use case for this module was to skip CMake's checks for a -working compiler when using a cross-compiler that cannot link binaries -without special flags or custom linker scripts. This case is now supported -by setting the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable in the -toolchain file instead. + One common use case for this module was to skip CMake's checks for a + working compiler when using a cross-compiler that cannot link binaries + without special flags or custom linker scripts. This case is now supported + by setting the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE` variable in the + toolchain file instead. -------------------------------------------------------------------------- - -Macro ``CMAKE_FORCE_C_COMPILER`` has the following signature: +Load this module in a CMake toolchain file: .. code-block:: cmake - CMAKE_FORCE_C_COMPILER(<compiler> <compiler-id>) + include(CMakeForceCompiler) -It sets :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>` to -the given compiler and the cmake internal variable -:variable:`CMAKE_C_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` to the given -compiler-id. It also bypasses the check for working compiler and basic -compiler information tests. +Commands +^^^^^^^^ -Macro ``CMAKE_FORCE_CXX_COMPILER`` has the following signature: +This module provides the following commands: + +.. command:: cmake_force_c_compiler + + Sets the :variable:`CMAKE_C_COMPILER <CMAKE_<LANG>_COMPILER>` variable to + the given compiler and the :variable:`CMAKE_C_COMPILER_ID + <CMAKE_<LANG>_COMPILER_ID>` variable to the given compiler-id: + + .. code-block:: cmake + + cmake_force_c_compiler(<compiler> <compiler-id>) + + This command also bypasses the check for working compiler and basic + compiler information tests. + +.. command:: cmake_force_cxx_compiler + + Sets the :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` variable + to the given compiler and the :variable:`CMAKE_CXX_COMPILER_ID + <CMAKE_<LANG>_COMPILER_ID>` variable to the given compiler-id: + + .. code-block:: cmake + + cmake_force_cxx_compiler(<compiler> <compiler-id>) + + This command also bypasses the check for working compiler and basic + compiler information tests. + +.. command:: cmake_force_fortran_compiler + + Sets the :variable:`CMAKE_Fortran_COMPILER <CMAKE_<LANG>_COMPILER>` + variable to the given compiler and the + :variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` variable + to the given compiler-id: + + .. code-block:: cmake + + cmake_force_fortran_compiler(<compiler> <compiler-id>) + + This command also bypasses the check for working compiler and basic + compiler information tests. + +Examples +^^^^^^^^ + +A simple toolchain file using this module could look like this: .. code-block:: cmake + :caption: ``cmake/toolchains/example-toolchain.cmake`` - CMAKE_FORCE_CXX_COMPILER(<compiler> <compiler-id>) + include(CMakeForceCompiler) + set(CMAKE_SYSTEM_NAME Generic) + cmake_force_c_compiler(chc12 MetrowerksHicross) + cmake_force_cxx_compiler(chc12 MetrowerksHicross) -It sets :variable:`CMAKE_CXX_COMPILER <CMAKE_<LANG>_COMPILER>` to -the given compiler and the cmake internal variable -:variable:`CMAKE_CXX_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` to the given -compiler-id. It also bypasses the check for working compiler and basic -compiler information tests. - -Macro ``CMAKE_FORCE_Fortran_COMPILER`` has the following signature: +In new CMake code, compiler is detected automatically when setting required +variables instead: .. code-block:: cmake + :caption: ``cmake/toolchains/example-toolchain.cmake`` - CMAKE_FORCE_Fortran_COMPILER(<compiler> <compiler-id>) + set(CMAKE_SYSTEM_NAME Generic) + set(CMAKE_C_COMPILER chc12) + set(CMAKE_CXX_COMPILER chc12) -It sets :variable:`CMAKE_Fortran_COMPILER <CMAKE_<LANG>_COMPILER>` to -the given compiler and the cmake internal variable -:variable:`CMAKE_Fortran_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` to the given -compiler-id. It also bypasses the check for working compiler and basic -compiler information tests. +See Also +^^^^^^^^ -So a simple toolchain file could look like this: - -.. code-block:: cmake - - include (CMakeForceCompiler) - set(CMAKE_SYSTEM_NAME Generic) - CMAKE_FORCE_C_COMPILER (chc12 MetrowerksHicross) - CMAKE_FORCE_CXX_COMPILER (chc12 MetrowerksHicross) +* :manual:`cmake-toolchains(7)` #]=======================================================================] macro(CMAKE_FORCE_C_COMPILER compiler id)
diff --git a/Modules/CMakeVerifyManifest.cmake b/Modules/CMakeVerifyManifest.cmake index d98a49e..5333869 100644 --- a/Modules/CMakeVerifyManifest.cmake +++ b/Modules/CMakeVerifyManifest.cmake
@@ -5,31 +5,53 @@ CMakeVerifyManifest ------------------- -Use this script to verify that embedded manifests and side-by-side -manifests for a project match. +This module is intended to be used in command-line mode using the +:ref:`cmake -P <Script Processing Mode>` to verify that embedded manifests +and side-by-side manifests for a project match. -This script first recursively globs ``*.manifest`` files from -the current directory and creates a list of allowed version. -Additional versions can be passed by setting ``allow_versions`` -from the invocation command. -Next, the script globs ``*.exe`` and ``*.dll`` files. Each +Load this module in a CMake script with: + +.. code-block:: cmake + + include(CMakeVerifyManifest) + +This module first recursively globs ``*.manifest`` files from +the current source directory and creates a list of allowed versions. + +Next, the script globs all ``*.exe`` and ``*.dll`` files. Each ``.exe`` and ``.dll`` file is scanned for embedded manifests and the versions of CRT are checked to be in the list of allowed -version. +versions. -Example -^^^^^^^ +Input Variables +^^^^^^^^^^^^^^^ -To run this script, navigate to a directory and run the script -with ``cmake -P``. +This module accepts the following variables: -:: +``allow_versions`` + Additional versions can be passed by setting the ``allow_versions`` + variable from the invocation command. This enables using additional + embedded manifest versions in a project, even if that version was not + found in a ``.manifest`` file. - cmake -Dallow_versions=8.0.50608.0 -PCMakeVerifyManifest.cmake +Examples +^^^^^^^^ -This call allows an embedded manifest of 8.0.50608.0 to be used -in a project, even if that version was not found in a -``.manifest`` file. +To use this module in the project, create a local command-line script (for +example, in the project's subdirectory ``cmake/scripts``) and include the +module: + +.. code-block:: cmake + :caption: ``cmake/scripts/verify-manifest.cmake`` + + include(CMakeVerifyManifest) + +Then run the local script in command-line and, for example, specify +additional embedded manifest of ``8.0.50608.0`` to be used in a project: + +.. code-block:: shell + + cmake -Dallow_versions=8.0.50608.0 -Pcmake/scripts/verify-manifest.cmake #]=======================================================================] # crt_version:
diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake index c4b27da..6b83903 100644 --- a/Modules/FeatureSummary.cmake +++ b/Modules/FeatureSummary.cmake
@@ -7,32 +7,45 @@ FeatureSummary -------------- -Functions for generating a summary of enabled/disabled features. +.. only:: html -These functions can be used to generate a summary of enabled and disabled -packages and/or features for a build tree such as:: + .. contents:: - -- The following features have been enabled: +This module provides commands for generating a summary of enabled/disabled +features. - * Example, usage example +Load this module in CMake with: - -- The following OPTIONAL packages have been found: +.. code-block:: cmake - * LibXml2 (required version >= 2.4), XML library, <http://xmlsoft.org> - Enables HTML-import in MyWordProcessor - Enables odt-export in MyWordProcessor - * PNG, image library, <http://www.libpng.org/pub/png/> - Enables saving screenshots + include(FeatureSummary) - -- The following OPTIONAL packages have not been found: +Commands provided by this module can be used to generate a summary of enabled +and disabled packages and/or features for a build tree such as:: - * Lua, the Lua scripting language, <https://www.lua.org> - Enables macros in MyWordProcessor - * OpenGL, Open Graphics Library + -- The following features have been enabled: + + * Example, usage example + + -- The following OPTIONAL packages have been found: + + * LibXml2 (required version >= 2.4), XML library, <http://xmlsoft.org> + Enables HTML-import in MyWordProcessor + Enables odt-export in MyWordProcessor + * PNG, image library, <http://www.libpng.org/pub/png/> + Enables saving screenshots + + -- The following OPTIONAL packages have not been found: + + * Lua, the Lua scripting language, <https://www.lua.org> + Enables macros in MyWordProcessor + * OpenGL, Open Graphics Library Global Properties ^^^^^^^^^^^^^^^^^ +The following global properties are used by this module: + .. variable:: FeatureSummary_PKG_TYPES .. versionadded:: 3.8 @@ -69,8 +82,9 @@ This global property defines the default package type. - When the :command:`feature_summary()` command is called, and the user has not - explicitly set a type of some package, its type will be set to this value. + When the :command:`feature_summary()` command is called, and the user has + not explicitly set a type of some package, its type will be set to the + value of this property. This value must be one of the types defined in the :variable:`FeatureSummary_PKG_TYPES` global property. @@ -88,6 +102,519 @@ The following <FeatureSummary_<TYPE>_DESCRIPTION> have been found: If not set, default string ``<TYPE> packages`` is used. + +Commands +^^^^^^^^ + +This module provides the following commands: + +* :command:`feature_summary` +* :command:`set_package_properties` +* :command:`add_feature_info` + +Printing Feature Summary +"""""""""""""""""""""""" + +.. command:: feature_summary + + Prints information about enabled or disabled packages and features of a + project: + + .. code-block:: cmake + + feature_summary( + WHAT (ALL + | PACKAGES_FOUND | PACKAGES_NOT_FOUND + | <TYPE>_PACKAGES_FOUND | <TYPE>_PACKAGES_NOT_FOUND + | ENABLED_FEATURES | DISABLED_FEATURES) + [FILENAME <file>] + [APPEND] + [VAR <variable-name>] + [INCLUDE_QUIET_PACKAGES] + [FATAL_ON_MISSING_REQUIRED_PACKAGES] + [DESCRIPTION <description> | DEFAULT_DESCRIPTION] + [QUIET_ON_EMPTY] + ) + + This command can be used to print information about enabled or disabled + packages and features of a project. By default, only the names of the + features/packages will be printed and their required version when one was + specified. Use :command:`set_package_properties()` to add more useful + information, e.g., a homepage URL for the respective package or their + purpose in the project. + + .. rubric:: The arguments are: + + ``WHAT`` + This is the only mandatory option. It specifies what information will be + printed: + + ``ALL`` + Print everything. + ``ENABLED_FEATURES`` + The list of all features which are enabled. + ``DISABLED_FEATURES`` + The list of all features which are disabled. + ``PACKAGES_FOUND`` + The list of all packages which have been found. + ``PACKAGES_NOT_FOUND`` + The list of all packages which have not been found. + + For each package type ``<TYPE>`` defined by the + :variable:`FeatureSummary_PKG_TYPES` global property, the following + information can also be used: + + ``<TYPE>_PACKAGES_FOUND`` + The list of only packages of type ``<TYPE>`` which have been found. + ``<TYPE>_PACKAGES_NOT_FOUND`` + The list of only packages of type ``<TYPE>`` which have not been found. + + .. versionchanged:: 3.1 + The ``WHAT`` option is now a multi-value keyword, so that these values can + be combined, with the exception of the ``ALL`` value, in order to + customize the output. For example: + + .. code-block:: cmake + + feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES) + + ``FILENAME <file>`` + If this option is given, the information is printed into this file instead + of the terminal. Relative ``<file>`` path is interpreted as being relative + to the current source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`). + + ``APPEND`` + If this option is given, the output is appended to the ``<file>`` provided + by the ``FILENAME`` option, otherwise the file is overwritten if it already + exists. + + ``VAR <variable-name>`` + If this option is given, the information is stored into the specified + variable ``<variable-name>`` instead of the terminal. + + ``INCLUDE_QUIET_PACKAGES`` + If this option is given, packages which have been searched with + :command:`find_package(... QUIET)` will also be listed. By default they are + skipped. + + ``FATAL_ON_MISSING_REQUIRED_PACKAGES`` + If this option is given, CMake will abort with fatal error if a package + which is marked as one of the package types listed in the + :variable:`FeatureSummary_REQUIRED_PKG_TYPES` global property has not been + found. + + ``DESCRIPTION <description>`` + A description or headline which will be printed above the actual content. + Without this option, if only one package type was requested, no title is + printed, unless a custom string is explicitly set using this option or + ``DEFAULT_DESCRIPTION`` option is used that outputs a default title for the + requested type. + + ``DEFAULT_DESCRIPTION`` + .. versionadded:: 3.9 + + The default description or headline to be printed above the content as + opposed to the customizable ``DESCRIPTION <description>``. + + ``QUIET_ON_EMPTY`` + .. versionadded:: 3.8 + + If this option is given, when only one package type was requested, and no + packages belonging to that category were found, then no output (including + the ``DESCRIPTION``) is printed nor added to the ``FILENAME``, or the + ``VAR`` variable. + +Package Properties +"""""""""""""""""" + +.. command:: set_package_properties + + Sets package properties: + + .. code-block:: cmake + + set_package_properties( + <PackageName> + PROPERTIES + [URL <url>] + [DESCRIPTION <description>] + [TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED)] + [PURPOSE <purpose>] + ) + + Use this command to configure and provide information about the package + named ``<PackageName>``, which can then be displayed using the + :command:`feature_summary()` command. This command can be called either + directly within the corresponding :ref:`Find module <Find Modules>` or in + the project that uses the module after invoking the :command:`find_package()` + call. The features for which information can be set are determined + automatically after the :command:`find_package()` command. + + .. rubric:: The arguments are: + + ``<PackageName>`` + The name of the package. For example, as specified in the + :command:`find_package(<PackageName>)` argument. + + ``PROPERTIES`` + Specifies the properties to set: + + ``URL <url>`` + This should be the homepage of the package, or something similar. + Ideally this is set already directly in the + :ref:`Find module <Find Modules>`. + + ``DESCRIPTION <description>`` + A short description what that package is, at most one sentence. + Ideally this is set already directly in the + :ref:`Find module <Find Modules>`. + + ``TYPE <type>`` + What type of dependency has the using project on that package. + + Default ``<type>`` is ``OPTIONAL``. In this case it is a package + which can be used by the project when available at buildtime, but the + project also works without it. + + ``RECOMMENDED`` package type is similar to ``OPTIONAL``, i.e. the + project will build if the package is not present, but the + functionality of the resulting binaries will be severely limited. If + a ``REQUIRED`` package is not available at buildtime, the project may + not even build. This can be combined with the + :command:`feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES)` command + option. + + Last, a ``RUNTIME`` package is a package which is actually not used + at all during the build, but which is required for actually running + the resulting binaries. So if such a package is missing, the project + can still be built, but it may not work later on. + + If ``set_package_properties()`` is called multiple times for the same + package with different TYPEs, the ``TYPE`` is only changed to higher + TYPEs (``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``), lower TYPEs + are ignored. The ``TYPE`` property is project-specific, so it cannot + be set by the :ref:`Find module <Find Modules>`, but must be set in + the project. + + The accepted types can be changed by setting the + :variable:`FeatureSummary_PKG_TYPES` global property. + + ``PURPOSE <purpose>`` + This describes which features this package enables in the project, + i.e. it tells the user what functionality they get in the resulting + binaries. If ``set_package_properties()`` is called multiple times + for a package, all ``PURPOSE`` properties are appended to a list of + purposes of the package in the project. As the ``TYPE`` property, + also the ``PURPOSE`` property is project-specific, so it cannot be + set by the :ref:`Find module <Find Modules>`, but must be set in the + project. + +Adding Feature Info +""""""""""""""""""" + +.. command:: add_feature_info + + Adds feature information: + + .. code-block:: cmake + + add_feature_info(<name> <condition> <description>) + + Use this command to add information about a feature identified with a given + ``<name>``. + + .. rubric:: The arguments are: + + ``<name>`` + Identification name for a feature being added. + + ``<condition>`` + Specifies the conditions that determine whether this feature is enabled + or disabled. + + The ``<condition>`` argument can be: + + * A single condition (such as a variable name). + + * .. versionadded:: 3.8 + A :ref:`semicolon-separated list <CMake Language Lists>` of multiple + conditions. + + * .. versionadded:: 4.0 + A full :ref:`Condition Syntax` as used in an ``if(<condition>)`` + clause. See policy :policy:`CMP0183`. This enables using entire + condition syntax (such as grouping conditions with parens and + similar). + + ``<description>`` + A text describing the feature. This information can be displayed using + :command:`feature_summary()` for ``ENABLED_FEATURES`` and + ``DISABLED_FEATURES`` respectively. + +Deprecated Commands +""""""""""""""""""" + +The following legacy and deprecated commands are provided for backward +compatibility with previous CMake versions: + +.. command:: set_package_info + + .. deprecated:: 3.8 + Use the :command:`set_package_properties`, and :command:`add_feature_info` + commands instead. + + Sets up information about the specified package, which can then be displayed + via :command:`feature_summary()`: + + .. code-block:: cmake + + set_package_info(<PackageName> <description> [<url> [<purpose>]]) + + ``<PackageName>`` + Name of the package. + + ``<description>`` + A short description of the package. + + ``<url>`` + Homepage of the package. + + ``<purpose>`` + The purpose of the package. + + This command can be used either directly in the + :ref:`Find module <Find Modules>` or in the project which uses the + ``FeatureSummary`` module after the :command:`find_package()` call. The + features for which information can be set are added automatically by the + ``find_package()`` command. + +.. command:: set_feature_info + + .. deprecated:: 3.8 + + Sets feature info for a package: + + .. code-block:: cmake + + set_feature_info(<name> <description> [<url>]) + + Does the same as: + + .. code-block:: cmake + + set_package_info(<name> <description> [<url>]) + +.. command:: print_enabled_features + + .. deprecated:: 3.8 + + Prints enabled features: + + .. code-block:: cmake + + print_enabled_features() + + Does the same as: + + .. code-block:: cmake + + feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") + +.. command:: print_disabled_features + + .. deprecated:: 3.8 + + Prints disabled features: + + .. code-block:: cmake + + print_disabled_features() + + Does the same as: + + .. code-block:: cmake + + feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:") + +Examples +^^^^^^^^ + +Example: Appending Feature Summary to a File +"""""""""""""""""""""""""""""""""""""""""""" + +In the following example, the feature summary output will be appended to +a specified file instead of printing: + +.. code-block:: cmake + + include(FeatureSummary) + feature_summary(WHAT ALL FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND) + +Example: Storing Feature Summary in a Variable +"""""""""""""""""""""""""""""""""""""""""""""" + +In the following example, the feature summary of enabled features is stored +in a specified variable ``enabledFeaturesText``, including the ``QUIET`` +packages: + +.. code-block:: cmake + + include(FeatureSummary) + + feature_summary( + WHAT ENABLED_FEATURES + INCLUDE_QUIET_PACKAGES + DESCRIPTION "Enabled Features:" + VAR enabledFeaturesText + ) + + message(STATUS "${enabledFeaturesText}") + +Example: Adding a Custom Package Type +""""""""""""""""""""""""""""""""""""" + +In the following example a custom package type is added and printed only +the categories that are not empty: + +.. code-block:: cmake + + include(FeatureSummary) + + set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD) + + find_package(FOO) + set_package_properties(FOO PROPERTIES TYPE BUILD) + + feature_summary( + WHAT BUILD_PACKAGES_FOUND + DESCRIPTION "Build tools found:" + QUIET_ON_EMPTY + ) + + feature_summary( + WHAT BUILD_PACKAGES_NOT_FOUND + DESCRIPTION "Build tools not found:" + QUIET_ON_EMPTY + ) + +Example: Setting Package Info +""""""""""""""""""""""""""""" + +Example for setting the info for a package: + +.. code-block:: cmake + + include(FeatureSummary) + + find_package(LibXml2) + set_package_properties( + LibXml2 + PROPERTIES + DESCRIPTION "XML library" + URL "http://xmlsoft.org" + ) + # or + set_package_properties( + LibXml2 + PROPERTIES + TYPE RECOMMENDED + PURPOSE "Enables HTML-import in MyWordProcessor" + ) + # or + set_package_properties( + LibXml2 + PROPERTIES + TYPE OPTIONAL + PURPOSE "Enables odt-export in MyWordProcessor" + ) + + find_package(DBUS) + set_package_properties( + DBUS + PROPERTIES + TYPE RUNTIME + PURPOSE "Necessary to disable the screensaver during a presentation" + ) + +Example: Printing Feature Summary +""""""""""""""""""""""""""""""""" + +In the following example, this module is used to output feature summary at +the end of the configuration. If any required package is not found, +processing stops with an error message at the end of the configuration +phase. + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.15) + project(Example) + + add_library(example example.c) + + include(FeatureSummary) + + find_package(CURL) + set_package_properties(CURL PROPERTIES TYPE REQUIRED) + target_link_libraries(example PRIVATE CURL::libcurl) + + find_package(LibXml2 QUIET) + set_package_properties(LibXml2 PROPERTIES TYPE RECOMMENDED) + if(LibXml2_FOUND) + target_link_libraries(example PRIVATE LibXml2::LibXml2) + endif() + + feature_summary( + WHAT ALL + INCLUDE_QUIET_PACKAGES + DESCRIPTION "Feature summary:" + FATAL_ON_MISSING_REQUIRED_PACKAGES + ) + +Examples: Setting Feature Info +"""""""""""""""""""""""""""""" + +Example for setting the info for a feature: + +.. code-block:: cmake + + include(FeatureSummary) + + option(WITH_FOO "Help for foo" ON) + + add_feature_info(Foo WITH_FOO "this feature provides very cool stuff") + +Example for setting feature info based on a list of conditions: + +.. code-block:: cmake + + include(FeatureSummary) + + option(WITH_FOO "Help for foo" ON) + option(WITH_BAR "Help for bar" OFF) + + add_feature_info( + FooBar + "WITH_FOO;NOT WITH_BAR" + "this feature is enabled when WITH_FOO is ON and WITH_BAR turned OFF" + ) + +In the next example feature info are set depending on a full condition +syntax. Unlike semicolon-separated list of conditions, this enables using +entire condition syntax as being the ``if`` clause argument: + +.. code-block:: cmake + + include(FeatureSummary) + + option(WITH_FOO "Help for foo" ON) + option(WITH_BAR "Help for bar" ON) + option(WITH_BAZ "Help for baz" OFF) + + add_feature_info( + FooBarBaz + "WITH_FOO AND (WITH_BAR OR WITH_BAZ)" + "this feature is enabled when the entire condition is true" + ) #]=======================================================================] get_property(_fsPkgTypeIsSet GLOBAL PROPERTY FeatureSummary_PKG_TYPES SET) @@ -105,15 +632,7 @@ set_property(GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE OPTIONAL) endif() -#[=======================================================================[.rst: - -Functions -^^^^^^^^^ - -#]=======================================================================] - function(_FS_GET_FEATURE_SUMMARY _property _var _includeQuiet) - get_property(_fsPkgTypes GLOBAL PROPERTY FeatureSummary_PKG_TYPES) get_property(_fsDefaultPkgType GLOBAL PROPERTY FeatureSummary_DEFAULT_PKG_TYPE) @@ -208,155 +727,6 @@ set(${_var} "${_currentFeatureText}" PARENT_SCOPE) endfunction() - -#[=======================================================================[.rst: -.. command:: feature_summary - - .. code-block:: cmake - - feature_summary([FILENAME <file>] - [APPEND] - [VAR <variable_name>] - [INCLUDE_QUIET_PACKAGES] - [FATAL_ON_MISSING_REQUIRED_PACKAGES] - [DESCRIPTION <description> | DEFAULT_DESCRIPTION] - [QUIET_ON_EMPTY] - WHAT (ALL - | PACKAGES_FOUND | PACKAGES_NOT_FOUND - | <TYPE>_PACKAGES_FOUND | <TYPE>_PACKAGES_NOT_FOUND - | ENABLED_FEATURES | DISABLED_FEATURES) - ) - - This function can be used to print information about - enabled or disabled packages and features of a project. By default, - only the names of the features/packages will be printed and their - required version when one was specified. Use - :command:`set_package_properties()` to add more useful information, like e.g. - a homepage URL for the respective package or their purpose in the project. - - The options are: - - ``WHAT`` - This is the only mandatory option. It specifies what information will be - printed: - - ``ALL`` - Print everything. - ``ENABLED_FEATURES`` - The list of all features which are enabled. - ``DISABLED_FEATURES`` - The list of all features which are disabled. - ``PACKAGES_FOUND`` - The list of all packages which have been found. - ``PACKAGES_NOT_FOUND`` - The list of all packages which have not been found. - - For each package type ``<TYPE>`` defined by the - :variable:`FeatureSummary_PKG_TYPES` global property, the following - information can also be used: - - ``<TYPE>_PACKAGES_FOUND`` - The list of only packages of type ``<TYPE>`` which have been found. - ``<TYPE>_PACKAGES_NOT_FOUND`` - The list of only packages of type ``<TYPE>`` which have not been found. - - .. versionchanged:: 3.1 - The ``WHAT`` option is now a multi-value keyword, so that these values can - be combined, with the exception of the ``ALL`` value, in order to - customize the output. For example: - - .. code-block:: cmake - - feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES) - - ``FILENAME <file>`` - If this option is given, the information is printed into this file instead - of the terminal. Relative ``<file>`` path is interpreted as being relative - to the current source directory (i.e. :variable:`CMAKE_CURRENT_SOURCE_DIR`). - - ``APPEND`` - If this option is given, the output is appended to the ``<file>`` provided - by the ``FILENAME`` option, otherwise the file is overwritten if it already - exists. - - ``VAR <variable_name>`` - If this option is given, the information is stored into the specified - variable ``<variable_name>`` instead of the terminal. - - ``DESCRIPTION <description>`` - A description or headline which will be printed above the actual content. - Without this option, if only one package type was requested, no title is - printed, unless a custom string is explicitly set using this option or - ``DEFAULT_DESCRIPTION`` option is used that outputs a default title for the - requested type. - - ``DEFAULT_DESCRIPTION`` - .. versionadded:: 3.9 - - The default description or headline to be printed above the content as - opposed to the customizable ``DESCRIPTION <description>``. - - ``INCLUDE_QUIET_PACKAGES`` - If this option is given, packages which have been searched with - :command:`find_package(... QUIET)` will also be listed. By default they are - skipped. - - ``FATAL_ON_MISSING_REQUIRED_PACKAGES`` - If this option is given, CMake will abort with fatal error if a package - which is marked as one of the package types listed in the - :variable:`FeatureSummary_REQUIRED_PKG_TYPES` global property has not been - found. - - The :variable:`FeatureSummary_DEFAULT_PKG_TYPE` global property can be - modified to change the default package type assigned when not explicitly - assigned by the user. - - ``QUIET_ON_EMPTY`` - .. versionadded:: 3.8 - - If this option is given, when only one package type was requested, and no - packages belonging to that category were found, then no output (including - the ``DESCRIPTION``) is printed nor added to the ``FILENAME``, or the - ``VAR`` variable. - - Example 1, append everything to a file: - - .. code-block:: cmake - - include(FeatureSummary) - feature_summary(WHAT ALL - FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND) - - Example 2, print the enabled features into the variable - ``enabledFeaturesText``, including the ``QUIET`` packages: - - .. code-block:: cmake - - include(FeatureSummary) - feature_summary(WHAT ENABLED_FEATURES - INCLUDE_QUIET_PACKAGES - DESCRIPTION "Enabled Features:" - VAR enabledFeaturesText) - message(STATUS "${enabledFeaturesText}") - - Example 3, add custom package type and print only the categories that are not - empty: - - .. code-block:: cmake - - include(FeatureSummary) - set_property(GLOBAL APPEND PROPERTY FeatureSummary_PKG_TYPES BUILD) - find_package(FOO) - set_package_properties(FOO PROPERTIES TYPE BUILD) - feature_summary(WHAT BUILD_PACKAGES_FOUND - DESCRIPTION "Build tools found:" - QUIET_ON_EMPTY) - feature_summary(WHAT BUILD_PACKAGES_NOT_FOUND - DESCRIPTION "Build tools not found:" - QUIET_ON_EMPTY) - -#]=======================================================================] - function(FEATURE_SUMMARY) # cmake_parse_arguments(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...) set(options APPEND @@ -498,93 +868,8 @@ if(requiredPackagesNotFound AND _FS_FATAL_ON_MISSING_REQUIRED_PACKAGES) message(FATAL_ERROR "feature_summary() Error: REQUIRED package(s) are missing, aborting CMake run.") endif() - endfunction() -#[=======================================================================[.rst: -.. command:: set_package_properties - - .. code-block:: cmake - - set_package_properties(<name> PROPERTIES - [URL <url>] - [DESCRIPTION <description>] - [TYPE (RUNTIME|OPTIONAL|RECOMMENDED|REQUIRED)] - [PURPOSE <purpose>] - ) - - Use this function to configure and provide information about the package named - ``<name>``, which can then be displayed using the - :command:`feature_summary()` command. This can be performed either directly - within the corresponding :ref:`Find module <Find Modules>` or in the project - that uses the module after invoking the :command:`find_package()` call. The - features for which information can be set are determined automatically after - the :command:`find_package()` command. - - ``URL <url>`` - This should be the homepage of the package, or something similar. - Ideally this is set already directly in the - :ref:`Find module <Find Modules>`. - - ``DESCRIPTION <description>`` - A short description what that package is, at most one sentence. - Ideally this is set already directly in the - :ref:`Find module <Find Modules>`. - - ``TYPE <type>`` - What type of dependency has the using project on that package. - Default is ``OPTIONAL``. In this case it is a package which can be used - by the project when available at buildtime, but it also work without. - ``RECOMMENDED`` is similar to ``OPTIONAL``, i.e. the project will build if - the package is not present, but the functionality of the resulting - binaries will be severely limited. If a ``REQUIRED`` package is not - available at buildtime, the project may not even build. This can be - combined with the - :command:`feature_summary(FATAL_ON_MISSING_REQUIRED_PACKAGES)` command - option. Last, a ``RUNTIME`` package is a package which is actually not used - at all during the build, but which is required for actually running the - resulting binaries. So if such a package is - missing, the project can still be built, but it may not work later on. - If ``set_package_properties()`` is called multiple times for the same - package with different TYPEs, the ``TYPE`` is only changed to higher - TYPEs (``RUNTIME < OPTIONAL < RECOMMENDED < REQUIRED``), lower TYPEs are - ignored. The ``TYPE`` property is project-specific, so it cannot be set - by the :ref:`Find module <Find Modules>`, but must be set in the project. - The accepted types can be changed by setting the - :variable:`FeatureSummary_PKG_TYPES` global property. - - ``PURPOSE <purpose>`` - This describes which features this package enables in the - project, i.e. it tells the user what functionality they get in the - resulting binaries. If ``set_package_properties()`` is called multiple - times for a package, all ``PURPOSE`` properties are appended to a list of - purposes of the package in the project. As the ``TYPE`` property, also - the ``PURPOSE`` property is project-specific, so it cannot be set by the - :ref:`Find module <Find Modules>`, but must be set in the project. - - Example for setting the info for a package: - - .. code-block:: cmake - - include(FeatureSummary) - find_package(LibXml2) - set_package_properties(LibXml2 PROPERTIES - DESCRIPTION "XML library" - URL "http://xmlsoft.org") - # or - set_package_properties(LibXml2 PROPERTIES - TYPE RECOMMENDED - PURPOSE "Enables HTML-import in MyWordProcessor") - # or - set_package_properties(LibXml2 PROPERTIES - TYPE OPTIONAL - PURPOSE "Enables odt-export in MyWordProcessor") - - find_package(DBUS) - set_package_properties(DBUS PROPERTIES - TYPE RUNTIME - PURPOSE "Necessary to disable the screensaver during a presentation") -#]=======================================================================] function(SET_PACKAGE_PROPERTIES _name _props) if(NOT "${_props}" STREQUAL "PROPERTIES") message(FATAL_ERROR "PROPERTIES keyword is missing in SET_PACKAGE_PROPERTIES() call.") @@ -609,7 +894,6 @@ set_property(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_SPP_DESCRIPTION}" ) endif() - if(_SPP_URL) get_property(_info GLOBAL PROPERTY _CMAKE_${_name}_URL) if(_info AND NOT "${_info}" STREQUAL "${_SPP_URL}") @@ -619,7 +903,6 @@ set_property(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_SPP_URL}" ) endif() - # handle the PURPOSE: use APPEND, since there can be multiple purposes for one package inside a project if(_SPP_PURPOSE) set_property(GLOBAL APPEND PROPERTY _CMAKE_${_name}_PURPOSE "${_SPP_PURPOSE}" ) @@ -648,68 +931,8 @@ set_property(GLOBAL PROPERTY _CMAKE_${_name}_TYPE "${_SPP_TYPE}" ) endif() endif() - endfunction() -#[=======================================================================[.rst: -.. command:: add_feature_info - - .. code-block:: cmake - - add_feature_info(<name> <enabled> <description>) - - Use this function to add information about a feature identified with a given - ``<name>``. The ``<enabled>`` contains whether this feature is enabled or - not. It can be a variable or a list of conditions. - ``<description>`` is a text describing the feature. The information can - be displayed using :command:`feature_summary()` for ``ENABLED_FEATURES`` and - ``DISABLED_FEATURES`` respectively. - - .. versionchanged:: 3.8 - ``<enabled>`` can be a list of conditions. - - .. versionchanged:: 4.0 - Full :ref:`Condition Syntax` is now supported for ``<enabled>``. - See policy :policy:`CMP0183`. - - Example for setting the info for a feature: - - .. code-block:: cmake - - include(FeatureSummary) - - option(WITH_FOO "Help for foo" ON) - add_feature_info(Foo WITH_FOO "this feature provides very cool stuff") - - Example for setting feature info based on a list of conditions: - - .. code-block:: cmake - - option(WITH_FOO "Help for foo" ON) - option(WITH_BAR "Help for bar" OFF) - add_feature_info( - FooBar - "WITH_FOO;NOT WITH_BAR" - "this feature is enabled when WITH_FOO is ON and WITH_BAR turned OFF" - ) - - Example for setting feature info depending on a full condition syntax: - - Unlike semicolon-separated list of conditions, this enables using entire - condition syntax as being the ``if`` clause argument, such as grouping - conditions with parens and similar. - - .. code-block:: cmake - - option(WITH_FOO "Help for foo" ON) - option(WITH_BAR "Help for bar" ON) - option(WITH_BAZ "Help for baz" OFF) - add_feature_info( - FooBarBaz - "WITH_FOO AND (WITH_BAR OR WITH_BAZ)" - "this feature is enabled when the entire condition is true" - ) -#]=======================================================================] function(ADD_FEATURE_INFO _name _depends _desc) cmake_policy(GET CMP0183 _CDO_CMP0183 PARENT_SCOPE # undocumented, do not use outside of CMake @@ -749,34 +972,8 @@ unset(_CDO_CMP0183) endfunction() - # The stuff below is only kept for compatibility -#[=======================================================================[.rst: -Deprecated Functions -^^^^^^^^^^^^^^^^^^^^ - -The following legacy and deprecated functions are provided for backward -compatibility with previous CMake versions: - -.. command:: set_package_info - - .. deprecated:: 3.8 - - .. code-block:: cmake - - set_package_info(<name> <description> [ <url> [<purpose>] ]) - - Set up information about the package ``<name>``, which can then be displayed - via :command:`feature_summary()`. This can be done either directly in the - :ref:`Find module <Find Modules>` or in the project which uses the - ``FeatureSummary`` module after the :command:`find_package()` call. The - features for which information can be set are added automatically by the - ``find_package()`` command. - - This function is deprecated. Use the :command:`set_package_properties()`, and - :command:`add_feature_info()` functions instead. -#]=======================================================================] function(SET_PACKAGE_INFO _name _desc) message(DEPRECATION "SET_PACKAGE_INFO is deprecated. Use SET_PACKAGE_PROPERTIES instead.") unset(_url) @@ -796,62 +993,17 @@ endif() endfunction() -#[=======================================================================[.rst: -.. command:: set_feature_info - - .. deprecated:: 3.8 - - .. code-block:: cmake - - set_feature_info(<name> <description> [<url>]) - - Does the same as: - - .. code-block:: cmake - - set_package_info(<name> <description> [<url>]) -#]=======================================================================] function(SET_FEATURE_INFO) message(DEPRECATION "SET_FEATURE_INFO is deprecated. Use ADD_FEATURE_INFO instead.") set_package_info(${ARGN}) endfunction() -#[=======================================================================[.rst: -.. command:: print_enabled_features - - .. deprecated:: 3.8 - - .. code-block:: cmake - - print_enabled_features() - - Does the same as: - - .. code-block:: cmake - - feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") -#]=======================================================================] function(PRINT_ENABLED_FEATURES) message(DEPRECATION "PRINT_ENABLED_FEATURES is deprecated. Use feature_summary(WHAT ENABLED_FEATURES DESCRIPTION \"Enabled features:\")") feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") endfunction() -#[=======================================================================[.rst: -.. command:: print_disabled_features - - .. deprecated:: 3.8 - - .. code-block:: cmake - - print_disabled_features() - - Does the same as: - - .. code-block:: cmake - - feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:") -#]=======================================================================] function(PRINT_DISABLED_FEATURES) message(DEPRECATION "PRINT_DISABLED_FEATURES is deprecated. Use feature_summary(WHAT DISABLED_FEATURES DESCRIPTION \"Disabled features:\")")
diff --git a/Modules/FindDevIL.cmake b/Modules/FindDevIL.cmake index f8e5575..019d45f 100644 --- a/Modules/FindDevIL.cmake +++ b/Modules/FindDevIL.cmake
@@ -9,7 +9,11 @@ .. code-block:: cmake - find_package(DevIL [...]) + find_package(DevIL [<version>] [...]) + +.. versionadded:: 4.2 + Support for the ``<version>`` argument in the :command:`find_package` + call. Version can be also specified as a range. The DevIL package internally consists of the following libraries, all distributed as part of the same release: @@ -62,8 +66,13 @@ This module defines the following variables: ``DevIL_FOUND`` - Boolean indicating whether the DevIL package is found, including the IL and - ILU libraries. + Boolean indicating whether the (requested version of) DevIL package is + found, including the IL and ILU libraries. + +``DevIL_VERSION`` + .. versionadded:: 4.2 + + The version of the DevIL found. ``DevIL_ILUT_FOUND`` .. versionadded:: 3.21 @@ -113,8 +122,8 @@ target_link_libraries(app PRIVATE DevIL::ILUT) #]=======================================================================] -# TODO: Add version support. -# Tested under Linux and Windows (MSVC) +cmake_policy(PUSH) +cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n> include(FindPackageHandleStandardArgs) @@ -123,35 +132,62 @@ DOC "The path to the directory that contains il.h" ) -#message("IL_INCLUDE_DIR is ${IL_INCLUDE_DIR}") - find_library(IL_LIBRARIES NAMES IL DEVIL PATH_SUFFIXES libx32 lib64 lib lib32 DOC "The file that corresponds to the base il library." ) -#message("IL_LIBRARIES is ${IL_LIBRARIES}") - find_library(ILUT_LIBRARIES NAMES ILUT PATH_SUFFIXES libx32 lib64 lib lib32 DOC "The file that corresponds to the il (system?) utility library." ) -#message("ILUT_LIBRARIES is ${ILUT_LIBRARIES}") - find_library(ILU_LIBRARIES NAMES ILU PATH_SUFFIXES libx32 lib64 lib lib32 DOC "The file that corresponds to the il utility library." ) -#message("ILU_LIBRARIES is ${ILU_LIBRARIES}") +# Get version. +block(PROPAGATE DevIL_VERSION) + if(IL_INCLUDE_DIR AND EXISTS "${IL_INCLUDE_DIR}/il.h") + set(regex "^[ \t]*#[ \t]*define[ \t]+IL_VERSION[ \t]+([0-9]+)[ \t]*$") -find_package_handle_standard_args(DevIL DEFAULT_MSG - IL_LIBRARIES ILU_LIBRARIES - IL_INCLUDE_DIR) + file(STRINGS ${IL_INCLUDE_DIR}/il.h result REGEX "${regex}") + + if(result MATCHES "${regex}") + set(DevIL_VERSION "${CMAKE_MATCH_1}") + + math(EXPR DevIL_VERSION_MAJOR "${DevIL_VERSION} / 100") + math(EXPR DevIL_VERSION_MINOR "${DevIL_VERSION} / 10 % 10") + math(EXPR DevIL_VERSION_PATCH "${DevIL_VERSION} % 10") + + set(DevIL_VERSION "") + foreach(part MAJOR MINOR PATCH) + if(DevIL_VERSION) + string(APPEND ".${DevIL_VERSION_${part}}") + else() + set(DevIL_VERSION "${DevIL_VERSION_${part}}") + endif() + + set( + DevIL_VERSION + "${DevIL_VERSION_MAJOR}.${DevIL_VERSION_MINOR}.${DevIL_VERSION_PATCH}" + ) + endforeach() + endif() + endif() +endblock() + +find_package_handle_standard_args( + DevIL + REQUIRED_VARS IL_LIBRARIES ILU_LIBRARIES IL_INCLUDE_DIR + VERSION_VAR DevIL_VERSION + HANDLE_VERSION_RANGE +) + # provide legacy variable for compatibility set(IL_FOUND ${DevIL_FOUND}) @@ -187,3 +223,5 @@ target_link_libraries(DevIL::ILUT INTERFACE DevIL::ILU) endif() endif() + +cmake_policy(POP)
diff --git a/Modules/FindGnuTLS.cmake b/Modules/FindGnuTLS.cmake index d9d8260..14c64d7 100644 --- a/Modules/FindGnuTLS.cmake +++ b/Modules/FindGnuTLS.cmake
@@ -5,12 +5,17 @@ FindGnuTLS ---------- -Finds the GNU Transport Layer Security library (GnuTLS). The GnuTLS -package includes the main libraries (libgnutls and libdane), as well as the -optional gnutls-openssl compatibility extra library. They are all distributed -as part of the same release. This module checks for the presence of the main -libgnutls library and provides usage requirements for integrating GnuTLS into -CMake projects. +Finds the GNU Transport Layer Security library (GnuTLS): + +.. code-block:: cmake + + find_package(GnuTLS [<version>] [...]) + +The GnuTLS package includes the main libraries (libgnutls and libdane), as +well as the optional gnutls-openssl compatibility extra library. They are +all distributed as part of the same release. This module checks for the +presence of the main libgnutls library and provides usage requirements for +integrating GnuTLS into CMake projects. Imported Targets ^^^^^^^^^^^^^^^^ @@ -29,12 +34,12 @@ This module defines the following variables: ``GnuTLS_FOUND`` - Boolean indicating whether the (requested version of) GnuTLS is found. For + Boolean indicating whether (the requested version of) GnuTLS is found. For backward compatibility, the ``GNUTLS_FOUND`` variable is also set to the same value. -``GNUTLS_VERSION`` - .. versionadded:: 3.16 +``GnuTLS_VERSION`` + .. versionadded:: 4.2 The version of GnuTLS found. @@ -61,13 +66,16 @@ Deprecated Variables ^^^^^^^^^^^^^^^^^^^^ -These variables are provided for backward compatibility: +The following variables are provided for backward compatibility: ``GNUTLS_VERSION_STRING`` .. deprecated:: 3.16 - Superseded by ``GNUTLS_VERSION``. + Use the ``GnuTLS_VERSION``, which has the same value. - The version of GnuTLS found. +``GNUTLS_VERSION`` + .. versionadded:: 3.16 + .. deprecated:: 4.2 + Use the ``GnuTLS_VERSION``, which has the same value. Examples ^^^^^^^^ @@ -80,6 +88,9 @@ target_link_libraries(project_target PRIVATE GnuTLS::GnuTLS) #]=======================================================================] +cmake_policy(PUSH) +cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n> + if (GNUTLS_INCLUDE_DIR AND GNUTLS_LIBRARY) # in cache already set(gnutls_FIND_QUIETLY TRUE) @@ -94,9 +105,6 @@ pkg_check_modules(PC_GNUTLS QUIET gnutls) endif() set(GNUTLS_DEFINITIONS ${PC_GNUTLS_CFLAGS_OTHER}) - set(GNUTLS_VERSION ${PC_GNUTLS_VERSION}) - # keep for backward compatibility - set(GNUTLS_VERSION_STRING ${PC_GNUTLS_VERSION}) endif () find_path(GNUTLS_INCLUDE_DIR gnutls/gnutls.h @@ -113,10 +121,43 @@ mark_as_advanced(GNUTLS_INCLUDE_DIR GNUTLS_LIBRARY) +if(GNUTLS_INCLUDE_DIR AND EXISTS "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h") + file( + STRINGS + "${GNUTLS_INCLUDE_DIR}/gnutls/gnutls.h" + gnutls_version + # GnuTLS versions prior to 2.7.2 defined LIBGNUTLS_VERSION instead of the + # current GNUTLS_VERSION. + REGEX "^#define[\t ]+(LIB)?GNUTLS_VERSION[\t ]+\".*\"" + ) + + string( + REGEX REPLACE + "^.*GNUTLS_VERSION[\t ]+\"([^\"]*)\".*$" + "\\1" + GnuTLS_VERSION + "${gnutls_version}" + ) + unset(gnutls_version) + + # Fallback to version defined by pkg-config if not successful. + if( + NOT GnuTLS_VERSION + AND PC_GNUTLS_VERSION + AND GNUTLS_INCLUDE_DIR IN_LIST PC_GNUTLS_INCLUDE_DIRS + ) + set(GnuTLS_VERSION "${PC_GNUTLS_VERSION}") + endif() + + # For backward compatibility. + set(GNUTLS_VERSION "${GnuTLS_VERSION}") + set(GNUTLS_VERSION_STRING "${GnuTLS_VERSION}") +endif() + include(FindPackageHandleStandardArgs) find_package_handle_standard_args(GnuTLS REQUIRED_VARS GNUTLS_LIBRARY GNUTLS_INCLUDE_DIR - VERSION_VAR GNUTLS_VERSION_STRING) + VERSION_VAR GnuTLS_VERSION) if(GnuTLS_FOUND) set(GNUTLS_LIBRARIES ${GNUTLS_LIBRARY}) @@ -131,3 +172,5 @@ IMPORTED_LOCATION "${GNUTLS_LIBRARIES}") endif() endif() + +cmake_policy(POP)
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 92e42ca..a203858 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake
@@ -71,8 +71,9 @@ ``HDF5::HDF5`` .. versionadded:: 3.19 - Target encapsulating the usage requirements for all found HDF5 libraries - (``HDF5_LIBRARIES``), available if HDF5 and all required components are found. + Target encapsulating the usage requirements for all found HDF5 binding + libraries (``HDF5_LIBRARIES``), available if HDF5 and all required components + are found. ``hdf5::hdf5`` .. versionadded:: 3.19
diff --git a/Modules/FindKDE3.cmake b/Modules/FindKDE3.cmake index f8a8615..438c0b0 100644 --- a/Modules/FindKDE3.cmake +++ b/Modules/FindKDE3.cmake
@@ -212,7 +212,7 @@ endif() # If Qt4 has already been found, fail. -if(QT4_FOUND) +if(Qt4_FOUND) if(KDE3_FIND_REQUIRED) message( FATAL_ERROR "KDE3/Qt3 and Qt4 cannot be used together in one project.") else()
diff --git a/Modules/FindKDE4.cmake b/Modules/FindKDE4.cmake index 220906b..4d289f6 100644 --- a/Modules/FindKDE4.cmake +++ b/Modules/FindKDE4.cmake
@@ -5,27 +5,214 @@ FindKDE4 -------- +.. note:: + + This module is specifically intended for KDE version 4, which is obsolete + and no longer maintained. For modern application development using KDE + technologies with CMake, use a newer version of KDE, and refer to the + `KDE documentation + <https://develop.kde.org/docs/getting-started/building/cmake-build/>`_. + +Finds the KDE 4 installation: + +.. code-block:: cmake + + find_package(KDE4 [...]) + +This module is a wrapper around the following upstream KDE 4 modules: + +``FindKDE4Internal.cmake`` + + Upstream internal module, which finds the KDE 4 include directories, + libraries, and KDE-specific preprocessor tools. It provides usage + requirements for building KDE 4 software and defines several helper + commands to simplify working with KDE 4 in CMake. + +``KDE4Macros.cmake`` + Upstream utility module that defines all additional KDE4-specific + commands to use KDE 4 in CMake. For example: + ``kde4_automoc()``, ``kde4_add_executable()``, ``kde4_add_library()``, + ``kde4_add_ui_files()``, ``kde4_add_ui3_files()``, + ``kde4_add_kcfg_files()``, ``kde4_add_kdeinit_executable()``, etc. + +Upstream KDE 4 modules are installed by the KDE 4 distribution package in +``$KDEDIRS/share/apps/cmake/modules/``. This path is automatically +appended to the :variable:`CMAKE_MODULE_PATH` variable when calling +``find_package(KDE4)``, so any additional KDE 4 modules can be included in +the project with :command:`include`. For example: + +``KDE4Defaults.cmake`` + Upstream internal module that sets some CMake options which are useful, + but not required for building KDE 4 software. If these settings should + be used, include this module after finding KDE 4: + + .. code-block:: cmake + + find_package(KDE4) + include(KDE4Defaults) + +For usage details, refer to the upstream KDE 4 documentation. For example, +at the top of the ``FindKDE4Internal`` module a complete documentation is +available for all variables and commands these modules provide. + +Hints +^^^^^ + +This module accepts the following variables before calling the +``find_package(KDE4)``: + +``ENV{KDEDIRS}`` + Environment variable containing the path to the KDE 4 installation. + +KDE 4 is searched in the following directories in the given order: + +* :variable:`CMAKE_INSTALL_PREFIX` variable +* ``KDEDIRS`` environment variable +* ``/opt/kde4`` path + +Examples +^^^^^^^^ + +Example: Basic Usage +"""""""""""""""""""" + +Finding KDE 4 as required and using it in CMake: + +.. code-block:: cmake + + find_package(KDE4 REQUIRED) + + set(sources main.cpp mywidget.cpp mypart.cpp) + + # The kde4_*() commands are provided by the KDE4Macros module, which is + # included automatically by FindKDE4, if KDE4 is found: + kde4_automoc(${sources}) + kde4_add_executable(example ${sources}) + + target_include_directories(example PRIVATE ${KDE4_INCLUDES}) + target_link_libraries(example PRIVATE ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS}) + + install(TARGETS example DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES kfoo.desktop DESTINATION ${XDG_APPS_DIR}) + +Example: Full Featured Example +"""""""""""""""""""""""""""""" + +In the following example this module is used to find KDE 4 installation. + +.. code-block:: cmake + + project(kfoo) + + find_package(KDE4 REQUIRED) + + # Append path from where to include local project modules if any: + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + + include_directories(${KDE4_INCLUDE_DIRS}) + add_definitions(${KDE4_DEFINITIONS}) + + set(sources main.cpp myappl.cpp view.cpp) + + # If Qt designer UI files version 3 or 4 are available add them to the + # sources variable: + kde4_add_ui_files(sources maindialog.ui logindialog.ui) + kde4_add_ui3_files(sources printerdlg.ui previewdlg.ui) + + # If there are files for the kconfig_compiler add them this way: + kde4_add_kcfg_files(sources settings.kcfg) + + # When everything is listed, probably automoc is wanted: + kde4_automoc(${sources}) + + # Finally, specify what to build: + kde4_add_executable(kfoo ${sources}) -Find KDE4 and provide all necessary variables and macros to compile -software for it. It looks for KDE 4 in the following directories in -the given order: +The ``kde4_add_executable()`` command is a slightly extended version of the +CMake command :command:`add_executable`. Additionally, it does some more +``RPATH`` handling and supports the ``KDE4_ENABLE_FINAL`` variable. The +first argument is the name of the executable followed by a list of source +files. If a library needs to be created instead of an executable, the +``kde4_add_library()`` can be used. It is an extended version of the +:command:`add_library` command. It adds support for the +``KDE4_ENABLE_FINAL`` variable and under Windows it adds the +``-DMAKE_KFOO_LIB`` to the compile flags. -:: +.. code-block:: cmake - CMAKE_INSTALL_PREFIX - KDEDIRS - /opt/kde4 + find_package(KDE4 REQUIRED) + # ... + kde4_add_library(kfoo ${sources}) -Please look in ``FindKDE4Internal.cmake`` and ``KDE4Macros.cmake`` for more -information. They are installed with the KDE 4 libraries in -$KDEDIRS/share/apps/cmake/modules/. + # Optionally, set the library version number if needed: + set_target_properties(kfoo PROPERTIES VERSION 5.0.0 SOVERSION 5) -Author: Alexander Neundorf <neundorf@kde.org> +KDE is very modular, so if a KPart, a control center module, or an ioslave +needs to be created, here's how to do it: + +.. code-block:: cmake + + find_package(KDE4 REQUIRED) + # ... + kde4_add_plugin(kfoo ${sources}) + +Now, the application/library/plugin probably needs to link to some +libraries. For this use the standard :command:`target_link_libraries` +command. For every KDE library there are variables available in the form +of ``KDE4_FOO_LIBS``. Use them to get also all depending libraries: + +.. code-block:: cmake + + target_link_libraries(kfoo ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS}) + +Example: The kdeinit Executable +""""""""""""""""""""""""""""""" + +In the following example, the so called kdeinit executable is created. +The ``kde4_add_kdeinit_executable()`` command creates both an executable +with the given name and a library with the given name prefixed with +``kdeinit_``. The :command:`target_link_libraries` command adds all +required libraries to the ``kdeinit_kbar`` library, and then links the +``kbar`` against the ``kdeinit_kbar``: + +.. code-block:: cmake + + find_package(KDE4 REQUIRED) + + # ... + + kde4_add_kdeinit_executable(kbar ${kbarSources}) + target_link_libraries(kdeinit_kbar ${KDE4_KIO_LIBS}) + target_link_libraries(kbar kdeinit_kbar) + + install(TARGETS kbar DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(TARGETS kdeinit_kbar DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +Example: Removing Compile Definitions +""""""""""""""""""""""""""""""""""""" + +Sometimes, a default compile definition passed to the compiler needs to be +removed. The :command:`remove_definitions` command can be used. For +example, by default, the KDE4 build system sets the ``-DQT_NO_STL`` flag. +If the project code uses some of the Qt STL compatibility layer, this flag +should be removed: + +.. code-block:: cmake + + find_package(KDE4 REQUIRED) + + add_definitions(${KDE4_DEFINITIONS}) + + # ... + + remove_definitions(-DQT_NO_STL) #]=======================================================================] +# Author: Alexander Neundorf <neundorf@kde.org> + # If Qt3 has already been found, fail. if(QT_QT_LIBRARY) if(KDE4_FIND_REQUIRED)
diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake index 50f37f6..720981d 100644 --- a/Modules/FindLua.cmake +++ b/Modules/FindLua.cmake
@@ -5,7 +5,13 @@ FindLua ------- -Finds the Lua library. Lua is a embeddable scripting language. +Finds the Lua library: + +.. code-block:: cmake + + find_package(Lua [<version>] [...]) + +Lua is a embeddable scripting language. .. versionadded:: 3.18 Support for Lua 5.4. @@ -35,14 +41,27 @@ Boolean indicating whether (the requested version of) Lua is found. For backward compatibility, the ``LUA_FOUND`` variable is also set to the same value. -``LUA_VERSION_STRING`` + +``Lua_VERSION`` + .. versionadded:: 4.2 + The version of Lua found. -``LUA_VERSION_MAJOR`` + +``Lua_VERSION_MAJOR`` + .. versionadded:: 4.2 + The major version of Lua found. -``LUA_VERSION_MINOR`` + +``Lua_VERSION_MINOR`` + .. versionadded:: 4.2 + The minor version of Lua found. -``LUA_VERSION_PATCH`` + +``Lua_VERSION_PATCH`` + .. versionadded:: 4.2 + The patch version of Lua found. + ``LUA_LIBRARIES`` Libraries needed to link against to use Lua. This list includes both ``lua`` and ``lualib`` libraries. @@ -56,6 +75,35 @@ The directory containing the Lua header files, such as ``lua.h``, ``lualib.h``, and ``lauxlib.h``, needed to use Lua. +Deprecated Variables +^^^^^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + +``LUA_VERSION_STRING`` + .. deprecated:: 4.2 + Superseded by the ``Lua_VERSION``. + + The version of Lua found. + +``LUA_VERSION_MAJOR`` + .. deprecated:: 4.2 + Superseded by the ``Lua_VERSION_MAJOR``. + + The major version of Lua found. + +``LUA_VERSION_MINOR`` + .. deprecated:: 4.2 + Superseded by the ``Lua_VERSION_MINOR``. + + The minor version of Lua found. + +``LUA_VERSION_PATCH`` + .. deprecated:: 4.2 + Superseded by the ``Lua_VERSION_PATCH``. + + The patch version of Lua found. + Examples ^^^^^^^^ @@ -81,6 +129,7 @@ #]=======================================================================] cmake_policy(PUSH) # Policies apply to functions at definition-time +cmake_policy(SET CMP0140 NEW) cmake_policy(SET CMP0159 NEW) # file(STRINGS) with REGEX updates CMAKE_MATCH_<n> unset(_lua_include_subdirs) @@ -146,7 +195,7 @@ endfunction() function(_lua_get_header_version) - unset(LUA_VERSION_STRING PARENT_SCOPE) + unset(Lua_VERSION PARENT_SCOPE) set(_hdr_file "${LUA_INCLUDE_DIR}/lua.h") if (NOT EXISTS "${_hdr_file}") @@ -159,27 +208,39 @@ file(STRINGS "${_hdr_file}" lua_version_strings REGEX "^#define[ \t]+LUA_(RELEASE[ \t]+\"Lua [0-9]|VERSION([ \t]+\"Lua [0-9]|_[MR])).*") - string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MAJOR ";${lua_version_strings};") - if (LUA_VERSION_MAJOR MATCHES "^[0-9]+$") - string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_MINOR ";${lua_version_strings};") - string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" LUA_VERSION_PATCH ";${lua_version_strings};") - set(LUA_VERSION_STRING "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}.${LUA_VERSION_PATCH}") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MAJOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" Lua_VERSION_MAJOR ";${lua_version_strings};") + + if (Lua_VERSION_MAJOR MATCHES "^[0-9]+$") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_MINOR[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" Lua_VERSION_MINOR ";${lua_version_strings};") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION_RELEASE[ \t]+\"([0-9])\"[ \t]*;.*" "\\1" Lua_VERSION_PATCH ";${lua_version_strings};") + set(Lua_VERSION "${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR}.${Lua_VERSION_PATCH}") else () - string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") - if (NOT LUA_VERSION_STRING MATCHES "^[0-9.]+$") - string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" LUA_VERSION_STRING ";${lua_version_strings};") + string(REGEX REPLACE ".*;#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" Lua_VERSION ";${lua_version_strings};") + if (NOT Lua_VERSION MATCHES "^[0-9.]+$") + string(REGEX REPLACE ".*;#define[ \t]+LUA_VERSION[ \t]+\"Lua ([0-9.]+)\"[ \t]*;.*" "\\1" Lua_VERSION ";${lua_version_strings};") endif () - string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" LUA_VERSION_MAJOR "${LUA_VERSION_STRING}") - string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" LUA_VERSION_MINOR "${LUA_VERSION_STRING}") - string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" LUA_VERSION_PATCH "${LUA_VERSION_STRING}") + string(REGEX REPLACE "^([0-9]+)\\.[0-9.]*$" "\\1" Lua_VERSION_MAJOR "${Lua_VERSION}") + string(REGEX REPLACE "^[0-9]+\\.([0-9]+)[0-9.]*$" "\\1" Lua_VERSION_MINOR "${Lua_VERSION}") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]).*" "\\1" Lua_VERSION_PATCH "${Lua_VERSION}") endif () foreach (ver IN LISTS _lua_append_versions) - if (ver STREQUAL "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}") - set(LUA_VERSION_MAJOR ${LUA_VERSION_MAJOR} PARENT_SCOPE) - set(LUA_VERSION_MINOR ${LUA_VERSION_MINOR} PARENT_SCOPE) - set(LUA_VERSION_PATCH ${LUA_VERSION_PATCH} PARENT_SCOPE) - set(LUA_VERSION_STRING ${LUA_VERSION_STRING} PARENT_SCOPE) - return() + if (ver STREQUAL "${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR}") + set(LUA_VERSION_STRING "${Lua_VERSION}") + set(LUA_VERSION_MAJOR "${Lua_VERSION_MAJOR}") + set(LUA_VERSION_MINOR "${Lua_VERSION_MINOR}") + set(LUA_VERSION_PATCH "${Lua_VERSION_PATCH}") + + return( + PROPAGATE + Lua_VERSION + Lua_VERSION_MAJOR + Lua_VERSION_MINOR + Lua_VERSION_PATCH + LUA_VERSION_STRING + LUA_VERSION_MAJOR + LUA_VERSION_MINOR + LUA_VERSION_PATCH + ) endif () endforeach () endfunction() @@ -208,9 +269,9 @@ endif() _lua_get_header_version() # Found accepted version -> Ok - if (LUA_VERSION_STRING) + if (Lua_VERSION) if (LUA_Debug) - message(STATUS "Found suitable version ${LUA_VERSION_STRING} in ${LUA_INCLUDE_DIR}/lua.h") + message(STATUS "Found suitable version ${Lua_VERSION} in ${LUA_INCLUDE_DIR}/lua.h") endif() return() endif() @@ -230,12 +291,12 @@ _lua_get_header_version() unset(_lua_append_versions) -if (LUA_VERSION_STRING) +if (Lua_VERSION) set(_lua_library_names - lua${LUA_VERSION_MAJOR}${LUA_VERSION_MINOR} - lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR} - lua-${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR} - lua.${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR} + lua${Lua_VERSION_MAJOR}${Lua_VERSION_MINOR} + lua${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR} + lua-${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR} + lua.${Lua_VERSION_MAJOR}.${Lua_VERSION_MINOR} ) endif () @@ -270,7 +331,7 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Lua REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR - VERSION_VAR LUA_VERSION_STRING) + VERSION_VAR Lua_VERSION) mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY)
diff --git a/Modules/FindLua50.cmake b/Modules/FindLua50.cmake index ac36c86..b512d37 100644 --- a/Modules/FindLua50.cmake +++ b/Modules/FindLua50.cmake
@@ -11,7 +11,13 @@ not maintained anymore. In new code use the latest supported Lua version and the version-agnostic module :module:`FindLua` instead. -Finds the Lua library. Lua is a embeddable scripting language. +Finds the Lua library: + +.. code-block:: cmake + + find_package(Lua50 [...]) + +Lua is a embeddable scripting language. When working with Lua, its library headers are intended to be included in project source code as:
diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake index cba30e4..8f105ed 100644 --- a/Modules/FindLua51.cmake +++ b/Modules/FindLua51.cmake
@@ -11,7 +11,13 @@ not maintained anymore. In new code use the latest supported Lua version and the version-agnostic module :module:`FindLua` instead. -Finds the Lua library. Lua is a embeddable scripting language. +Finds the Lua library: + +.. code-block:: cmake + + find_package(Lua51 [<version>] [...]) + +Lua is a embeddable scripting language. When working with Lua, its library headers are intended to be included in project source code as: @@ -35,9 +41,13 @@ This module defines the following variables: ``Lua51_FOUND`` - Boolean indicating whether Lua is found. For backward compatibility, the - ``LUA51_FOUND`` variable is also set to the same value. -``LUA_VERSION_STRING`` + Boolean indicating whether (the requested version of) Lua is found. For + backward compatibility, the ``LUA51_FOUND`` variable is also set to the + same value. + +``Lua_VERSION`` + .. versionadded:: 4.2 + The version of Lua found. Cache Variables @@ -48,9 +58,21 @@ ``LUA_INCLUDE_DIR`` The directory containing the Lua header files, such as ``lua.h``, ``lualib.h``, and ``lauxlib.h``, needed to use Lua. + ``LUA_LIBRARIES`` Libraries needed to link against to use Lua. +Deprecated Variables +^^^^^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + +``LUA_VERSION_STRING`` + .. deprecated:: 4.2 + Superseded by the ``Lua_VERSION``. + + The version of Lua found. + Examples ^^^^^^^^ @@ -118,14 +140,15 @@ if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/lua.h") file(STRINGS "${LUA_INCLUDE_DIR}/lua.h" lua_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"") - string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUA_VERSION_STRING "${lua_version_str}") + string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" Lua_VERSION "${lua_version_str}") + set(LUA_VERSION_STRING "${Lua_VERSION}") unset(lua_version_str) endif() include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Lua51 REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR - VERSION_VAR LUA_VERSION_STRING) + VERSION_VAR Lua_VERSION) mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY)
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index a842756..b32bbcc 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake
@@ -5,28 +5,56 @@ FindOpenGL ---------- -FindModule for OpenGL and OpenGL Utility Library (GLU). +Finds the OpenGL and OpenGL Utility Library (GLU), for using OpenGL in a +CMake project: + +.. code-block:: cmake + + find_package(OpenGL [COMPONENTS <components>...] [...]) + +OpenGL (Open Graphics Library) is a cross-platform API for rendering 2D and +3D graphics. It is widely used in CAD, games, and visualization software. + +* *GL* refers to the core OpenGL library, which provides the fundamental + graphics rendering API. + +* *GLU* (OpenGL Utility Library) is a companion library that offers utility + functions built on top of OpenGL, such as tessellation and more complex + shape drawing. .. versionchanged:: 3.2 X11 is no longer added as a dependency on Unix/Linux systems. .. versionadded:: 3.10 - GLVND support on Linux. See the :ref:`Linux Specific` section below. + GLVND (GL Vendor-Neutral Dispatch library) support on Linux. See the + :ref:`Linux Specific` section below. -Optional COMPONENTS -^^^^^^^^^^^^^^^^^^^ +Components +^^^^^^^^^^ -.. versionadded:: 3.10 +This module supports optional components which can be specified with the +:command:`find_package` command: -This module respects several optional COMPONENTS: +.. code-block:: cmake + + find_package(OpenGL [COMPONENTS <components>...]) + +Supported components are: ``EGL`` - The EGL interface between OpenGL, OpenGL ES and the underlying windowing system. + .. versionadded:: 3.10 + + The EGL interface between OpenGL, OpenGL ES and the underlying windowing + system. ``GLX`` + .. versionadded:: 3.10 + An extension to X that interfaces OpenGL, OpenGL ES with X window system. ``OpenGL`` + .. versionadded:: 3.10 + The cross platform API for 3D graphics. ``GLES2`` @@ -42,103 +70,177 @@ Imported Targets ^^^^^^^^^^^^^^^^ -.. versionadded:: 3.8 - -This module defines the :prop_tgt:`IMPORTED` targets: +This module provides the following :ref:`Imported Targets`: ``OpenGL::GL`` - Defined to the platform-specific OpenGL libraries if the system has OpenGL. -``OpenGL::GLU`` - Defined if the system has OpenGL Utility Library (GLU). + .. versionadded:: 3.8 -.. versionadded:: 3.10 - Additionally, the following GLVND-specific library targets are defined: + Target encapsulating the usage requirements of platform-specific OpenGL + libraries, available if OpenGL is found. + +``OpenGL::GLU`` + .. versionadded:: 3.8 + + Target encapsulating the OpenGL Utility Library (GLU) usage requirements, + available if GLU is found. + +Additionally, the following GLVND-specific library imported targets are +provided: ``OpenGL::OpenGL`` - Defined to libOpenGL if the system is GLVND-based. + .. versionadded:: 3.10 + + Target encapsulating the libOpenGL usage requirements, available if + system is GLVND-based and OpenGL is found. + ``OpenGL::GLX`` - Defined if the system has OpenGL Extension to the X Window System (GLX). + .. versionadded:: 3.10 + + Target encapsulating the usage requirements of the OpenGL Extension to the + the X Window System (GLX), available if OpenGL and GLX are found. + ``OpenGL::EGL`` - Defined if the system has EGL. + .. versionadded:: 3.10 + + Target encapsulating the EGL usage requirements, available if OpenGL and EGL + are found. + ``OpenGL::GLES2`` .. versionadded:: 3.27 - Defined if the system has GLES2. + Target encapsulating the GLES2 usage requirements, available if OpenGL and + GLES2 are found. + ``OpenGL::GLES3`` .. versionadded:: 3.27 - Defined if the system has GLES3. + Target encapsulating the GLES3 usage requirements, available if OpenGL and + GLES3 are found. Result Variables ^^^^^^^^^^^^^^^^ -This module sets the following variables: +This module defines the following variables: -``OPENGL_FOUND`` - True, if the system has OpenGL and all components are found. +``OpenGL_FOUND`` + .. versionadded:: 3.3 + + Boolean indicating whether the OpenGL and all requested components are found. + ``OPENGL_XMESA_FOUND`` - True, if the system has XMESA. + Boolean indicating whether OpenGL XMESA is found. + ``OPENGL_GLU_FOUND`` - True, if the system has GLU. + Boolean indicating whether GLU is found. + ``OpenGL_OpenGL_FOUND`` - True, if the system has an OpenGL library. + .. versionadded:: 3.10 + + Boolean indicating whether GLVND OpenGL library is found. + ``OpenGL_GLX_FOUND`` - True, if the system has GLX. + .. versionadded:: 3.10 + + Boolean indicating whether GLVND GLX is found. + ``OpenGL_EGL_FOUND`` - True, if the system has EGL. -``OpenGL::GLES2`` - Defined if the system has GLES2. -``OpenGL::GLES3`` - Defined if the system has GLES3. -``OPENGL_INCLUDE_DIR`` - Path to the OpenGL include directory. - The ``OPENGL_INCLUDE_DIRS`` variable is preferred. -``OPENGL_EGL_INCLUDE_DIRS`` - Path to the EGL include directory. -``OPENGL_LIBRARIES`` - Paths to the OpenGL library, windowing system libraries, and GLU libraries. - On Linux, this assumes GLX and is never correct for EGL-based targets. - Clients are encouraged to use the ``OpenGL::*`` import targets instead. + .. versionadded:: 3.10 + + Boolean indicating whether GLVND EGL is found. + +``OpenGL_GLES2_FOUND`` + .. versionadded:: 3.27 + + Boolean indicating whether GLES2 is found. + +``OpenGL_GLES3_FOUND`` + .. versionadded:: 3.27 + + Boolean indicating whether GLES3 is found. + ``OPENGL_INCLUDE_DIRS`` .. versionadded:: 3.29 Paths to the OpenGL include directories. -.. versionadded:: 3.10 - Variables for GLVND-specific libraries ``OpenGL``, ``EGL`` and ``GLX``. +``OPENGL_EGL_INCLUDE_DIRS`` + .. versionadded:: 3.10 -Cache variables + Path to the EGL include directory. + +``OPENGL_LIBRARIES`` + Paths to the OpenGL library, windowing system libraries, and GLU libraries. + On Linux, this assumes GLX and is never correct for EGL-based targets. + Clients are encouraged to use the ``OpenGL::*`` imported targets instead. + +Cache Variables ^^^^^^^^^^^^^^^ The following cache variables may also be set: -``OPENGL_egl_LIBRARY`` - Path to the EGL library. -``OPENGL_glu_LIBRARY`` - Path to the GLU library. -``OPENGL_glx_LIBRARY`` - Path to the GLVND 'GLX' library. -``OPENGL_opengl_LIBRARY`` - Path to the GLVND 'OpenGL' library -``OPENGL_gl_LIBRARY`` - Path to the OpenGL library. New code should prefer the ``OpenGL::*`` import - targets. -``OPENGL_gles2_LIBRARY`` - .. versionadded:: 3.27 - - Path to the OpenGL GLES2 library. -``OPENGL_gles3_LIBRARY`` - .. versionadded:: 3.27 - - Path to the OpenGL GLES3 library. +``OPENGL_INCLUDE_DIR`` + The path to the OpenGL include directory. + The ``OPENGL_INCLUDE_DIRS`` variable is preferred. ``OPENGL_GLU_INCLUDE_DIR`` .. versionadded:: 3.29 Path to the OpenGL GLU include directory. -.. versionadded:: 3.10 - Variables for GLVND-specific libraries ``OpenGL``, ``EGL`` and ``GLX``. +``OPENGL_egl_LIBRARY`` + .. versionadded:: 3.10 + + Path to the GLVND EGL library. + +``OPENGL_glu_LIBRARY`` + Path to the GLU library. + +``OPENGL_glx_LIBRARY`` + .. versionadded:: 3.10 + + Path to the GLVND GLX library. + +``OPENGL_opengl_LIBRARY`` + .. versionadded:: 3.10 + + Path to the GLVND OpenGL library + +``OPENGL_gl_LIBRARY`` + Path to the OpenGL library. + +``OPENGL_gles2_LIBRARY`` + .. versionadded:: 3.27 + + Path to the OpenGL GLES2 library. + +``OPENGL_gles3_LIBRARY`` + .. versionadded:: 3.27 + + Path to the OpenGL GLES3 library. + +Hints +^^^^^ + +This module accepts the following variables: + +``OpenGL_GL_PREFERENCE`` + .. versionadded:: 3.10 + + This variable is supported on Linux systems to specify the preferred way to + provide legacy GL interfaces in case multiple choices are available. The + value may be one of: + + ``GLVND`` + If the GLVND OpenGL and GLX libraries are available, prefer them. + This forces ``OPENGL_gl_LIBRARY`` to be empty. + + .. versionchanged:: 3.11 + This is the default, unless policy :policy:`CMP0072` is set to ``OLD`` + and no components are requested (since components + correspond to GLVND libraries). + + ``LEGACY`` + Prefer to use the legacy libGL library, if available. .. _`Linux Specific`: @@ -160,21 +262,8 @@ variable will use the corresponding libraries). Thus, for non-EGL-based Linux targets, the ``OpenGL::GL`` target is most portable. -A ``OpenGL_GL_PREFERENCE`` variable may be set to specify the preferred way +The ``OpenGL_GL_PREFERENCE`` variable may be set to specify the preferred way to provide legacy GL interfaces in case multiple choices are available. -The value may be one of: - -``GLVND`` - If the GLVND OpenGL and GLX libraries are available, prefer them. - This forces ``OPENGL_gl_LIBRARY`` to be empty. - - .. versionchanged:: 3.11 - This is the default, unless policy :policy:`CMP0072` is set to ``OLD`` - and no components are requested (since components - correspond to GLVND libraries). - -``LEGACY`` - Prefer to use the legacy libGL library, if available. For EGL targets the client must rely on GLVND support on the user's system. Linking should use the ``OpenGL::OpenGL OpenGL::EGL`` targets. Using GLES* @@ -189,7 +278,8 @@ On macOS this module defaults to using the macOS-native framework version of OpenGL. To use the X11 version of OpenGL on macOS, one -can disable searching of frameworks. For example: +can disable searching of frameworks using the :variable:`CMAKE_FIND_FRAMEWORK` +variable. For example: .. code-block:: cmake @@ -205,6 +295,33 @@ An end user building this project may need to point CMake at their X11 installation, e.g., with ``-DOpenGL_ROOT=/opt/X11``. +Deprecated Variables +^^^^^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + +``OPENGL_FOUND`` + .. deprecated:: 3.3 + Superseded by the ``OpenGL_FOUND``, which has the same value. + +Examples +^^^^^^^^ + +Finding the OpenGL library and linking it to a project target: + +.. code-block:: cmake + + find_package(OpenGL) + target_link_libraries(project_target PRIVATE OpenGL::OpenGL) + +See Also +^^^^^^^^ + +* The :module:`FindGLEW` module to find OpenGL Extension Wrangler Library + (GLEW). +* The :module:`FindGLUT` module to find OpenGL Utility Toolkit (GLUT) + library. +* The :module:`FindVulkan` module to find Vulkan graphics API. #]=======================================================================] set(_OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY) @@ -582,7 +699,7 @@ unset(_OpenGL_REQUIRED_VARS) # OpenGL:: targets -if(OPENGL_FOUND) +if(OpenGL_FOUND) set(OPENGL_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR}) # ::OpenGL is a GLVND library, and thus Linux-only: we don't bother checking
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index 5081936..b4c7291 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -5,28 +5,42 @@ FindPackageHandleStandardArgs ----------------------------- -This module provides functions intended to be used in :ref:`Find Modules` +This module provides commands intended to be used in :ref:`Find Modules` implementing :command:`find_package(<PackageName>)` calls. +Load this module in a CMake find module with: + +.. code-block:: cmake + :caption: ``FindFoo.cmake`` + + include(FindPackageHandleStandardArgs) + +Commands +^^^^^^^^ + +This module provides the following commands: + +* :command:`find_package_handle_standard_args` +* :command:`find_package_check_version` + .. command:: find_package_handle_standard_args - This command handles the ``REQUIRED``, ``QUIET`` and version-related - arguments of :command:`find_package`. It also sets the - ``<PackageName>_FOUND`` variable. The package is considered found if all - variables listed contain valid results, e.g. valid filepaths. + Handles the ``REQUIRED``, ``QUIET`` and version-related arguments of + :command:`find_package`. There are two signatures: .. code-block:: cmake - find_package_handle_standard_args(<PackageName> + find_package_handle_standard_args( + <PackageName> (DEFAULT_MSG|<custom-failure-message>) - <required-var>... - ) + <required-vars>... + ) - find_package_handle_standard_args(<PackageName> - [FOUND_VAR <result-var>] - [REQUIRED_VARS <required-var>...] + find_package_handle_standard_args( + <PackageName> + [REQUIRED_VARS <required-vars>...] [VERSION_VAR <version-var>] [HANDLE_VERSION_RANGE] [HANDLE_COMPONENTS] @@ -34,37 +48,33 @@ [NAME_MISMATCHED] [REASON_FAILURE_MESSAGE <reason-failure-message>] [FAIL_MESSAGE <custom-failure-message>] - ) + [FOUND_VAR <result-var>] # Deprecated + ) - The ``<PackageName>_FOUND`` variable will be set to ``TRUE`` if all - the variables ``<required-var>...`` are valid and any optional - constraints are satisfied, and ``FALSE`` otherwise. A success or - failure message may be displayed based on the results and on - whether the ``REQUIRED`` and/or ``QUIET`` option was given to - the :command:`find_package` call. + This command sets the ``<PackageName>_FOUND`` variable to ``TRUE`` if all + the variables listed in ``<required-vars>...`` contain valid results + (e.g., valid filepaths) and any optional constraints are satisfied, and + ``FALSE`` otherwise. A success or failure message may be displayed based + on the results and on whether the ``REQUIRED`` and/or ``QUIET`` option + was given to the :command:`find_package` call. - The options are: + The arguments are: + + ``<PackageName>`` + The name of the package. For example, as written in the + ``Find<PackageName>.cmake`` find module filename. ``(DEFAULT_MSG|<custom-failure-message>)`` In the simple signature this specifies the failure message. Use ``DEFAULT_MSG`` to ask for a default message to be computed (recommended). Not valid in the full signature. - ``FOUND_VAR <result-var>`` - .. deprecated:: 3.3 - - Specifies either ``<PackageName>_FOUND`` or - ``<PACKAGENAME>_FOUND`` as the result variable. This exists only - for compatibility with older versions of CMake and is now ignored. - Result variables of both names are now always set for compatibility - also with or without this option. - - ``REQUIRED_VARS <required-var>...`` + ``REQUIRED_VARS <required-vars>...`` Specify the variables which are required for this package. These may be named in the generated failure message asking the user to set the missing variable values. Therefore these should - typically be cache entries such as ``FOO_LIBRARY`` and not output - variables like ``FOO_LIBRARIES``. + typically be cache entries such as ``Foo_LIBRARY`` and not output + variables like ``Foo_LIBRARIES``. .. versionchanged:: 3.18 If ``HANDLE_COMPONENTS`` is specified, this option can be omitted. @@ -100,6 +110,14 @@ will automatically check whether the package configuration file was found. + ``NAME_MISMATCHED`` + .. versionadded:: 3.17 + + Indicate that the ``<PackageName>`` does not match the value of + :variable:`CMAKE_FIND_PACKAGE_NAME` variable. This is usually a mistake + and raises a warning, but it may be intentional for usage of the + command for components of a larger package. + ``REASON_FAILURE_MESSAGE <reason-failure-message>`` .. versionadded:: 3.16 @@ -110,48 +128,76 @@ Specify a custom failure message instead of using the default generated message. Not recommended. - ``NAME_MISMATCHED`` - .. versionadded:: 3.17 + ``FOUND_VAR <result-var>`` + .. deprecated:: 3.3 + This option should no longer be used. - Indicate that the ``<PackageName>`` does not match - ``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a - warning, but it may be intentional for usage of the command for components - of a larger package. + Specifies either ``<PackageName>_FOUND`` or ``<PACKAGENAME>_FOUND`` as the + result variable. This exists only for backward compatibility with older + versions of CMake and is now ignored. Result variables of both names are + now always set for compatibility also with or without this option. -Example for the simple signature: + .. note:: + + If ``<PackageName>`` does not match :variable:`CMAKE_FIND_PACKAGE_NAME` + for the calling module, a warning that there is a mismatch is given. The + ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using + the old signature and the ``NAME_MISMATCHED`` argument using the new + signature. To avoid forcing the caller to require newer versions of CMake + for usage, the variable's value will be used if defined when the + ``NAME_MISMATCHED`` argument is not passed for the new signature (but using + both is an error). + +.. command:: find_package_check_version + + .. versionadded:: 3.19 + + Checks if a given version is valid against the version-related arguments + of :command:`find_package`: + + .. code-block:: cmake + + find_package_check_version( + <version> + <result-var> + [HANDLE_VERSION_RANGE] + [RESULT_MESSAGE_VARIABLE <message-var>] + ) + + The arguments are: + + ``<version>`` + The version string to check. + + ``<result-var>`` + Name of the result variable that will hold a boolean value giving the + result of the check. + + ``HANDLE_VERSION_RANGE`` + Enable handling of a version range, if one is specified. Without this + option, a developer warning will be displayed if a version range is + specified. + + ``RESULT_MESSAGE_VARIABLE <message-var>`` + Specify a variable to get back a message describing the result of the check. + +Examples +^^^^^^^^ + +Examples: Full Signature +"""""""""""""""""""""""" + +Example for using a full signature of ``find_package_handle_standard_args()``: .. code-block:: cmake + :caption: ``FindLibArchive.cmake`` - find_package_handle_standard_args(LibXml2 DEFAULT_MSG - LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR) - -The ``LibXml2`` package is considered to be found if both -``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` are valid. -Then also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found -and ``REQUIRED`` was used, it fails with a -:command:`message(FATAL_ERROR)`, independent whether ``QUIET`` was -used or not. If it is found, success will be reported, including -the content of the first ``<required-var>``. On repeated CMake runs, -the same message will not be printed again. - -.. note:: - - If ``<PackageName>`` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the - calling module, a warning that there is a mismatch is given. The - ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using - the old signature and the ``NAME_MISMATCHED`` argument using the new - signature. To avoid forcing the caller to require newer versions of CMake for - usage, the variable's value will be used if defined when the - ``NAME_MISMATCHED`` argument is not passed for the new signature (but using - both is an error).. - -Example for the full signature: - -.. code-block:: cmake - - find_package_handle_standard_args(LibArchive + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args( + LibArchive REQUIRED_VARS LibArchive_LIBRARY LibArchive_INCLUDE_DIR - VERSION_VAR LibArchive_VERSION) + VERSION_VAR LibArchive_VERSION + ) In this case, the ``LibArchive`` package is considered to be found if both ``LibArchive_LIBRARY`` and ``LibArchive_INCLUDE_DIR`` are valid. @@ -159,56 +205,73 @@ contained in ``LibArchive_VERSION``. Since no ``FAIL_MESSAGE`` is given, the default messages will be printed. -Another example for the full signature: +Another example for the full signature of +``find_package_handle_standard_args()``: .. code-block:: cmake + :caption: ``FindAutomoc4.cmake`` find_package(Automoc4 QUIET NO_MODULE HINTS /opt/automoc4) - find_package_handle_standard_args(Automoc4 CONFIG_MODE) -In this case, a ``FindAutmoc4.cmake`` module wraps a call to + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(Automoc4 CONFIG_MODE) + +In this case, a ``FindAutomoc4.cmake`` module wraps a call to ``find_package(Automoc4 NO_MODULE)`` and adds an additional search directory for ``automoc4``. Then the call to -``find_package_handle_standard_args`` produces a proper success/failure +``find_package_handle_standard_args()`` produces a proper success/failure message. -.. command:: find_package_check_version +Example: Simple Signature +""""""""""""""""""""""""" - .. versionadded:: 3.19 - - Helper function which can be used to check if a ``<version>`` is valid - against version-related arguments of :command:`find_package`. - - .. code-block:: cmake - - find_package_check_version(<version> <result-var> - [HANDLE_VERSION_RANGE] - [RESULT_MESSAGE_VARIABLE <message-var>] - ) - - The ``<result-var>`` will hold a boolean value giving the result of the check. - - The options are: - - ``HANDLE_VERSION_RANGE`` - Enable handling of a version range, if one is specified. Without this - option, a developer warning will be displayed if a version range is - specified. - - ``RESULT_MESSAGE_VARIABLE <message-var>`` - Specify a variable to get back a message describing the result of the check. - -Example for the usage: +Example for using a simple signature of ``find_package_handle_standard_args()``: .. code-block:: cmake + :caption: ``FindLibXml2.cmake`` - find_package_check_version(1.2.3 result HANDLE_VERSION_RANGE - RESULT_MESSAGE_VARIABLE reason) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args( + LibXml2 + DEFAULT_MSG + LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR + ) + +In this example, the ``LibXml2`` package is considered to be found if both +``LIBXML2_LIBRARY`` and ``LIBXML2_INCLUDE_DIR`` variables are valid. Then +also ``LibXml2_FOUND`` is set to ``TRUE``. If it is not found and +``REQUIRED`` was used, it fails with a :command:`message(FATAL_ERROR)`, +independent whether ``QUIET`` was used or not. If it is found, success will +be reported, including the content of the first required variable specified +in ``<required-vars>...``. On repeated CMake runs, the same message will +not be printed again. + +Example: Checking Version +""""""""""""""""""""""""" + +Example for the ``find_package_check_version()`` usage: + +.. code-block:: cmake + :caption: ``FindFoo.cmake`` + + include(FindPackageHandleStandardArgs) + find_package_check_version( + 1.2.3 + result + HANDLE_VERSION_RANGE + RESULT_MESSAGE_VARIABLE reason + ) if(result) message(STATUS "${reason}") else() - message(FATAL_ERROR "${reason}") + # Logic when version check is not successful. + message(WARNING "${reason}") endif() + +See Also +^^^^^^^^ + +* :ref:`Find Modules` for details how to write a find module. #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindPackageMessage.cmake)
diff --git a/Modules/FindPerl.cmake b/Modules/FindPerl.cmake index 06a2e62..b1c4f51 100644 --- a/Modules/FindPerl.cmake +++ b/Modules/FindPerl.cmake
@@ -5,8 +5,13 @@ FindPerl -------- -Finds a Perl interpreter. Perl is a general-purpose, interpreted, dynamic -programming language. +Finds a Perl interpreter: + +.. code-block:: cmake + + find_package(Perl [<version>] [...]) + +Perl is a general-purpose, interpreted, dynamic programming language. Result Variables ^^^^^^^^^^^^^^^^ @@ -14,10 +19,13 @@ This module defines the following variables: ``Perl_FOUND`` - True if the Perl executable was found. For backward compatibility, the - ``PERL_FOUND`` variable is also set to the same value. + Boolean indicating whether the (requested version of) Perl executable is + found. For backward compatibility, the ``PERL_FOUND`` variable is also + set to the same value. -``PERL_VERSION_STRING`` +``Perl_VERSION`` + .. versionadded:: 4.2 + The version of Perl found. Cache Variables @@ -28,14 +36,34 @@ ``PERL_EXECUTABLE`` Full path to the ``perl`` executable. +Deprecated Variables +^^^^^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + +``PERL_VERSION_STRING`` + .. deprecated:: 4.2 + Superseded by the ``Perl_VERSION``. + + The version of Perl found. + Examples ^^^^^^^^ -Finding the Perl interpreter: +Finding the Perl interpreter and executing it in a process: .. code-block:: cmake find_package(Perl) + + if(Perl_FOUND) + execute_process(COMMAND ${PERL_EXECUTABLE} --help) + endif() + +See Also +^^^^^^^^ + +* The :module:`FindPerlLibs` to find Perl libraries. #]=======================================================================] include(${CMAKE_CURRENT_LIST_DIR}/FindCygwin.cmake) @@ -64,7 +92,6 @@ ) if(PERL_EXECUTABLE) - ### PERL_VERSION execute_process( COMMAND ${PERL_EXECUTABLE} -V:version @@ -76,7 +103,8 @@ OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT PERL_VERSION_RESULT_VARIABLE AND NOT PERL_VERSION_OUTPUT_VARIABLE MATCHES "^version='UNKNOWN'") - string(REGEX REPLACE "version='([^']+)'.*" "\\1" PERL_VERSION_STRING ${PERL_VERSION_OUTPUT_VARIABLE}) + string(REGEX REPLACE "version='([^']+)'.*" "\\1" Perl_VERSION ${PERL_VERSION_OUTPUT_VARIABLE}) + set(PERL_VERSION_STRING "${Perl_VERSION}") else() execute_process( COMMAND ${PERL_EXECUTABLE} -v @@ -86,9 +114,11 @@ OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl.*[ \\(]v([0-9\\._]+)[ \\)]") - set(PERL_VERSION_STRING "${CMAKE_MATCH_1}") + set(Perl_VERSION "${CMAKE_MATCH_1}") + set(PERL_VERSION_STRING "${Perl_VERSION}") elseif(NOT PERL_VERSION_RESULT_VARIABLE AND PERL_VERSION_OUTPUT_VARIABLE MATCHES "This is perl, version ([0-9\\._]+) +") - set(PERL_VERSION_STRING "${CMAKE_MATCH_1}") + set(Perl_VERSION "${CMAKE_MATCH_1}") + set(PERL_VERSION_STRING "${Perl_VERSION}") endif() endif() endif() @@ -105,7 +135,7 @@ endif () find_package_handle_standard_args(Perl REQUIRED_VARS PERL_EXECUTABLE - VERSION_VAR PERL_VERSION_STRING) + VERSION_VAR Perl_VERSION) unset(FPHSA_NAME_MISMATCHED) mark_as_advanced(PERL_EXECUTABLE)
diff --git a/Modules/FindPerlLibs.cmake b/Modules/FindPerlLibs.cmake index 330700e..ab6b333 100644 --- a/Modules/FindPerlLibs.cmake +++ b/Modules/FindPerlLibs.cmake
@@ -5,18 +5,33 @@ FindPerlLibs ------------ -Finds Perl libraries. Perl is a general-purpose, interpreted, dynamic -programming language. This module detects whether Perl is installed and -determines the locations of include paths, libraries, and the library name. +Finds Perl libraries: + +.. code-block:: cmake + + find_package(PerlLibs [<version>] [...]) + +Perl is a general-purpose, interpreted, dynamic programming language. + +This module detects whether Perl interpreter is installed via the +:module:`FindPerl` module and determines the locations of Perl include paths, +libraries, and the library name. Result Variables ^^^^^^^^^^^^^^^^ -This module sets the following variables: +This module defines the following variables: ``PerlLibs_FOUND`` - True if ``perl.h`` and ``libperl`` were found. For backward compatibility, - the ``PERLLIBS_FOUND`` variable is also set to the same value. + Boolean indicating whether the (requested version of) Perl library + (``perl.h`` and ``libperl``) is found. For backward compatibility, the + ``PERLLIBS_FOUND`` variable is also set to the same value. + +``PerlLibs_VERSION`` + .. versionadded:: 4.2 + + The version of Perl library found. + ``PERL_SITESEARCH`` Path to the sitesearch install directory (``-V:installsitesearch``). ``PERL_SITEARCH`` @@ -58,11 +73,18 @@ .. code-block:: cmake find_package(PerlLibs 6.0) + +See Also +^^^^^^^^ + +* The :module:`FindPerl` module to find the Perl interpreter. #]=======================================================================] # find the perl executable include(${CMAKE_CURRENT_LIST_DIR}/FindPerl.cmake) +set(PerlLibs_VERSION "${Perl_VERSION}") + if (PERL_EXECUTABLE) function (perl_get_info _pgi_info tag) @@ -122,10 +144,10 @@ ### PERL_POSSIBLE_LIBRARY_NAMES perl_get_info(PERL_POSSIBLE_LIBRARY_NAMES libperl) if (NOT PERL_POSSIBLE_LIBRARY_NAMES) - set(PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING} perl) + set(PERL_POSSIBLE_LIBRARY_NAMES perl${PerlLibs_VERSION} perl) endif() if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN") - list (APPEND PERL_POSSIBLE_LIBRARY_NAMES perl${PERL_VERSION_STRING}) + list (APPEND PERL_POSSIBLE_LIBRARY_NAMES perl${PerlLibs_VERSION}) endif() if (CMAKE_SYSTEM_NAME MATCHES "MSYS|CYGWIN") # On MSYS and CYGWIN environments, current perl -V:libperl gives shared @@ -141,10 +163,10 @@ PATHS "${PERL_UPDATE_ARCHLIB}/CORE" "${PERL_ARCHLIB}/CORE" - /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE - /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE - /usr/lib/perl5/${PERL_VERSION_STRING}/CORE - /usr/lib/perl/${PERL_VERSION_STRING}/CORE + /usr/lib/perl5/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE + /usr/lib/perl/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE + /usr/lib/perl5/${PerlLibs_VERSION}/CORE + /usr/lib/perl/${PerlLibs_VERSION}/CORE ) ### PERL_LIBRARY @@ -154,24 +176,24 @@ PATHS "${PERL_UPDATE_ARCHLIB}/CORE" "${PERL_ARCHLIB}/CORE" - /usr/lib/perl5/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE - /usr/lib/perl/${PERL_VERSION_STRING}/${PERL_ARCHNAME}/CORE - /usr/lib/perl5/${PERL_VERSION_STRING}/CORE - /usr/lib/perl/${PERL_VERSION_STRING}/CORE + /usr/lib/perl5/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE + /usr/lib/perl/${PerlLibs_VERSION}/${PERL_ARCHNAME}/CORE + /usr/lib/perl5/${PerlLibs_VERSION}/CORE + /usr/lib/perl/${PerlLibs_VERSION}/CORE ) endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PerlLibs REQUIRED_VARS PERL_LIBRARY PERL_INCLUDE_PATH - VERSION_VAR PERL_VERSION_STRING) + VERSION_VAR PerlLibs_VERSION) # Introduced after CMake 2.6.4 to bring module into compliance set(PERL_INCLUDE_DIR ${PERL_INCLUDE_PATH}) set(PERL_INCLUDE_DIRS ${PERL_INCLUDE_PATH}) set(PERL_LIBRARIES ${PERL_LIBRARY}) # For backward compatibility with CMake before 2.8.8 -set(PERL_VERSION ${PERL_VERSION_STRING}) +set(PERL_VERSION ${PerlLibs_VERSION}) mark_as_advanced( PERL_INCLUDE_PATH
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake index b230eb5..91c71ae 100644 --- a/Modules/FindPkgConfig.cmake +++ b/Modules/FindPkgConfig.cmake
@@ -7,28 +7,454 @@ A ``pkg-config`` module for CMake. -Finds the ``pkg-config`` executable and adds the :command:`pkg_get_variable`, -:command:`pkg_check_modules` and :command:`pkg_search_module` commands. The -following variables will also be set: +Finds the ``pkg-config`` executable and provides commands to use it in +CMake: + +.. code-block:: cmake + + find_package(PkgConfig [<version>] [QUIET] [REQUIRED] [...]) + +``pkg-config`` is a command-line program for configuring build dependency +information. Initially developed by FreeDesktop, it is also available in +several implementations, such as pkgconf, u-config, and similar. It reads +package data from the so-called PC metadata files (``<module-name>.pc``) +that may come installed with packages. This module is a wrapper around the +``pkg-config`` command-line executable. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: ``PKG_CONFIG_FOUND`` - True if a pkg-config executable was found. + Boolean indicating whether the (requested version of) ``pkg-config`` + executable is found. ``PKG_CONFIG_VERSION_STRING`` - The version of pkg-config that was found. + The version of ``pkg-config`` that was found. ``PKG_CONFIG_EXECUTABLE`` - The pathname of the pkg-config program. + The pathname of the ``pkg-config`` program. ``PKG_CONFIG_ARGN`` .. versionadded:: 3.22 - A list of arguments to pass to pkg-config. + A list of arguments to pass to ``pkg-config``. Both ``PKG_CONFIG_EXECUTABLE`` and ``PKG_CONFIG_ARGN`` are initialized by the -module, but may be overridden by the user. See `Variables Affecting Behavior`_ -for how these variables are initialized. +module, but may be overridden by the user. See `Hints`_ for how these +variables are initialized. +Commands +^^^^^^^^ + +This module provides the following commands, if ``pkg-config`` is found: + +* :command:`pkg_check_modules` +* :command:`pkg_search_module` +* :command:`pkg_get_variable` + +.. command:: pkg_check_modules + + Checks for all the given modules, setting a variety of result variables + in the calling scope: + + .. code-block:: cmake + + pkg_check_modules( + <prefix> + [QUIET] + [REQUIRED] + [NO_CMAKE_PATH] + [NO_CMAKE_ENVIRONMENT_PATH] + [IMPORTED_TARGET [GLOBAL]] + <module-spec> [<module-spec>...] + ) + + .. rubric:: The arguments are: + + ``<prefix>`` + Prefix string prepended to result variables for the specified modules. + + ``QUIET`` + When this argument is given, no status messages will be printed. + + ``REQUIRED`` + When this argument is given, the command will fail with an error if any + of the specified module(s) could not be found. + + ``NO_CMAKE_PATH``, ``NO_CMAKE_ENVIRONMENT_PATH`` + .. versionadded:: 3.3 + + The :variable:`CMAKE_PREFIX_PATH`, + :variable:`CMAKE_FRAMEWORK_PATH`, and :variable:`CMAKE_APPBUNDLE_PATH` cache + and environment variables will be added to the ``pkg-config`` search path. + The ``NO_CMAKE_PATH`` and ``NO_CMAKE_ENVIRONMENT_PATH`` arguments + disable this behavior for the cache variables and environment variables + respectively. + The ``PKG_CONFIG_USE_CMAKE_PREFIX_PATH`` variable set to ``FALSE`` + disables this behavior globally. + + .. This was actually added in 3.1, but didn't work until 3.3. + + ``IMPORTED_TARGET [GLOBAL]`` + .. versionadded:: 3.7 + + This argument will create an :ref:`imported target <Imported Targets>` + named ``PkgConfig::<prefix>`` that can be passed directly as an argument + to :command:`target_link_libraries`. It will encapsulate usage + requirements for all specified modules ``<module-spec>...`` at once. + + .. This was actually added in 3.6, but didn't work until 3.7. + + ``GLOBAL`` + .. versionadded:: 3.13 + + This argument is used together with ``IMPORTED_TARGET`` and will make + the imported target available in global scope. + + .. versionadded:: 3.15 + Non-library linker options reported by ``pkg-config`` are stored in the + :prop_tgt:`INTERFACE_LINK_OPTIONS` target property. + + .. versionchanged:: 3.18 + Include directories specified with ``-isystem`` are stored in the + :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property. Previous + versions of CMake left them in the :prop_tgt:`INTERFACE_COMPILE_OPTIONS` + property. + + ``<module-spec>`` + Each ``<module-spec>`` can be either a bare module name (as defined in + its PC metadata file name ``<module-name>.pc``) or it can be a module + name with a version constraint (operators ``=``, ``<``, ``>``, ``<=`` + and ``>=`` are supported). The following are examples for a module + named ``foo`` with various constraints: + + - ``foo`` matches any version. + - ``foo<2`` only matches versions before 2. + - ``foo>=3.1`` matches any version from 3.1 or later. + - ``foo=1.2.3`` requires that foo must be exactly version 1.2.3. + + .. rubric:: Result Variables + + The following variables may be set upon return. Two sets of values exist: + One for the common case (``<XXX> = <prefix>``) and another for the + information ``pkg-config`` provides when called with the ``--static`` + option (``<XXX> = <prefix>_STATIC``). + + ``<XXX>_FOUND`` + Boolean variable set to 1 if module(s) exist. + ``<XXX>_LIBRARIES`` + A list of only the libraries (without the ``-l``). + ``<XXX>_LINK_LIBRARIES`` + The libraries and their absolute paths. + ``<XXX>_LIBRARY_DIRS`` + The paths of the libraries (without the ``-L``). + ``<XXX>_LDFLAGS`` + All required linker flags. + ``<XXX>_LDFLAGS_OTHER`` + All other linker flags. + ``<XXX>_INCLUDE_DIRS`` + The ``-I`` preprocessor flags (without the ``-I``). + ``<XXX>_CFLAGS`` + All required cflags. + ``<XXX>_CFLAGS_OTHER`` + The other compiler flags. + + All but ``<XXX>_FOUND`` may be a :ref:`semicolon-separated list + <CMake Language Lists>` if the + associated variable returned from ``pkg-config`` has multiple values. + + .. versionchanged:: 3.18 + Include directories specified with ``-isystem`` are stored in the + ``<XXX>_INCLUDE_DIRS`` variable. Previous versions of CMake left them + in ``<XXX>_CFLAGS_OTHER``. + + There are some special variables whose prefix depends on the number of + ``<module-spec>`` given. When there is only one ``<module-spec>``, + ``<YYY>`` will simply be ``<prefix>``, but if two or more ``<module-spec>`` + items are given, ``<YYY>`` will be ``<prefix>_<module-name>``. + + ``<YYY>_VERSION`` + The version of the module. + ``<YYY>_PREFIX`` + The prefix directory of the module. + ``<YYY>_INCLUDEDIR`` + The include directory of the module. + ``<YYY>_LIBDIR`` + The lib directory of the module. + + .. versionchanged:: 3.8 + For any given ``<prefix>``, ``pkg_check_modules()`` can be called multiple + times with different parameters. Previous versions of CMake cached and + returned the first successful result. + + .. versionchanged:: 3.16 + If a full path to the found library can't be determined, but it's still + visible to the linker, pass it through as ``-l<name>``. Previous versions + of CMake failed in this case. + +.. command:: pkg_search_module + + Searches for the first successful match from one or more provided module + specifications: + + .. code-block:: cmake + + pkg_search_module( + <prefix> + [QUIET] + [REQUIRED] + [NO_CMAKE_PATH] + [NO_CMAKE_ENVIRONMENT_PATH] + [IMPORTED_TARGET [GLOBAL]] + <module-spec> [<module-spec>...] + ) + + The behavior and arguments of this command are the same as + :command:`pkg_check_modules`, except that rather than checking for all + the specified modules, it searches for just the first successful match. + + This command can be used, for example, when some package is known to have + possible multiple ``<module-spec>`` on different platforms or versions for + the same package. + + .. rubric:: Result Variables + + This command defines the same variables as described above with addition + to: + + ``<prefix>_MODULE_NAME`` + .. versionadded:: 3.16 + + If a module is found, the ``<prefix>_MODULE_NAME`` variable will contain + the name of the matching module. This variable can be used if the + :command:`pkg_get_variable` command needs to be called with the + ``<module-name>`` argument that was found by the + :command:`pkg_search_module`. + +.. command:: pkg_get_variable + + .. versionadded:: 3.4 + + Retrieves the value of a ``pkg-config`` variable and stores it in the + result variable in the calling scope: + + .. code-block:: cmake + + pkg_get_variable( + <result-var> + <module-name> + <var-name> + [DEFINE_VARIABLES <key>=<value>...] + ) + + .. rubric:: The arguments are: + + ``<result-var>`` + Name of the result variable that will contain the value of ``pkg-config`` + variable. If ``pkg-config`` returns multiple values for the specified + variable ``<var-name>``, ``<result-var>`` will contain a + :ref:`semicolon-separated list <CMake Language Lists>`. + + ``<module-name>`` + Name of the module as defined in its PC metadata file name + (``<module-name>.pc``). + + ``<var-name>`` + The ``pkg-config`` variable name from the PC metadata file + ``<module-name>.pc``. + + ``DEFINE_VARIABLES <key>=<value>...`` + .. versionadded:: 3.28 + + Specify key-value pairs to redefine variables affecting the variable + retrieved with ``pkg-config``. + +Hints +^^^^^ + +This module accepts the following variables before calling +``find_package(PkgConfig)`` to influence this module's behavior: + +``ENV{PKG_CONFIG_PATH}`` + Environment variable that specifies additional paths in which + ``pkg-config`` will search for its ``.pc`` files. The ``pkg-config`` + tool by default uses this variable, while CMake also provides more common + :variable:`CMAKE_PREFIX_PATH` variable to specify additional paths where + to look for packages and their ``.pc`` files. + +``ENV{PKG_CONFIG}`` + .. versionadded:: 3.1 + + Environment variable that can be set to the path of the ``pkg-config`` + executable and can be used to initialize the ``PKG_CONFIG_EXECUTABLE`` + variable, if it has not yet been set. + +``PKG_CONFIG_EXECUTABLE`` + + This cache variable can be set to the path of the ``pkg-config`` + executable. :command:`find_program` is called internally by the module + with this variable. + + .. versionchanged:: 3.22 + If the ``PKG_CONFIG`` environment variable is set, only the first + argument is taken from it when using it as a hint. + +``PKG_CONFIG_ARGN`` + + .. versionadded:: 3.22 + + This cache variable can be set to a list of arguments to additionally pass + to ``pkg-config`` if needed. If not provided, it will be initialized from + the ``PKG_CONFIG`` environment variable, if set. The first argument in that + environment variable is assumed to be the ``pkg-config`` program, while all + remaining arguments after that are used to initialize ``PKG_CONFIG_ARGN``. + If no such environment variable is defined, ``PKG_CONFIG_ARGN`` is + initialized to an empty string. The module does not update the variable once + it has been set in the cache. + +``PKG_CONFIG_USE_CMAKE_PREFIX_PATH`` + + .. versionadded:: 3.1 + + Specifies whether :command:`pkg_check_modules` and + :command:`pkg_search_module` should add the paths in the + :variable:`CMAKE_PREFIX_PATH`, :variable:`CMAKE_FRAMEWORK_PATH` and + :variable:`CMAKE_APPBUNDLE_PATH` cache and environment variables to the + ``pkg-config`` search path. + + If this variable is not set, this behavior is enabled by default if + :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` is 3.1 or later, disabled + otherwise. + +Examples +^^^^^^^^ + +Examples: Finding pkg-config +"""""""""""""""""""""""""""" + +Finding ``pkg-config``: + +.. code-block:: cmake + + find_package(PkgConfig) + +Finding ``pkg-config`` and making it required (if not found, processing stops +with an error message): + +.. code-block:: cmake + + find_package(PkgConfig REQUIRED) + +Finding ``pkg-config`` quietly without printing status message as commonly +used in find modules: + +.. code-block:: cmake + + find_package(PkgConfig QUIET) + +Examples: Using ``pkg_check_modules()`` +""""""""""""""""""""""""""""""""""""""" + +Checking for any version of glib2. If found, the output variable +``GLIB2_VERSION`` will hold the actual version found: + +.. code-block:: cmake + + find_package(PkgConfig QUIET) + + if(PKG_CONFIG_FOUND) + pkg_check_modules(GLIB2 glib-2.0) + endif() + +The following example looks for at least version 2.10 of glib2. If found, +the output variable ``GLIB2_VERSION`` will hold the actual version found: + +.. code-block:: cmake + + find_package(PkgConfig QUIET) + + if(PKG_CONFIG_FOUND) + pkg_check_modules(GLIB2 glib-2.0>=2.10) + endif() + +The following example looks for both glib2-2.0 (at least version 2.10) and +any version of gtk2+-2.0. Only if both are found will ``FOO`` be considered +found. The ``FOO_glib-2.0_VERSION`` and ``FOO_gtk+-2.0_VERSION`` variables +will be set to their respective found module versions. + +.. code-block:: cmake + + find_package(PkgConfig QUIET) + + if(PKG_CONFIG_FOUND) + pkg_check_modules(FOO glib-2.0>=2.10 gtk+-2.0) + endif() + +The following example requires any version of ``xrender``: + +.. code-block:: cmake + + find_package(PkgConfig QUIET REQUIRED) + pkg_check_modules(XRENDER REQUIRED xrender) + +Example output variables set by a successful call:: + + XRENDER_LIBRARIES=Xrender;X11 + XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp + +Example: Using ``pkg_search_module()`` +"""""""""""""""""""""""""""""""""""""" + +Searching for LibXml2 package, which might be provided with different +module specifications (``libxml-2.0`` or ``libxml2``): + +.. code-block:: cmake + + find_package(PkgConfig QUIET) + + if(PKG_CONFIG_FOUND) + pkg_search_module(BAR libxml-2.0 libxml2 libxml>=2) + endif() + +Example: Creating Imported Target +""""""""""""""""""""""""""""""""" + +In the following example an imported target is created from the module +specifications to use in the project directly without using a find module. +These imported targets can be used, for example, in cases, where package is +known to support ``pkg-config`` on all supported platforms: + +.. code-block:: cmake + + find_package(PkgConfig QUIET REQUIRED) + pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk4>=4.14) + target_link_libraries(example PRIVATE PkgConfig::GTK) + +Example: Using ``pkg_get_variable()`` +""""""""""""""""""""""""""""""""""""" + +Retrieving the value of ``pkg-config`` variable ``girdir`` from the package +Gobject: + +.. code-block:: cmake + + find_package(PkgConfig QUIET) + + if(PKG_CONFIG_FOUND) + pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir) + endif() + + message(STATUS "${GI_GIRDIR}") + +See Also +^^^^^^^^ + +* The :command:`cmake_pkg_config` command for a modern and more advanced + way to work with ``pkg-config`` in CMake without requiring ``pkg-config`` + executable to be installed. +* :ref:`Find Modules` for details how to write a find module. #]========================================] ### Common stuff #### @@ -703,161 +1129,6 @@ endif() endmacro() - -#[========================================[.rst: -.. command:: pkg_check_modules - - Checks for all the given modules, setting a variety of result variables in - the calling scope. - - .. code-block:: cmake - - pkg_check_modules(<prefix> - [REQUIRED] [QUIET] - [NO_CMAKE_PATH] - [NO_CMAKE_ENVIRONMENT_PATH] - [IMPORTED_TARGET [GLOBAL]] - <moduleSpec> [<moduleSpec>...]) - - When the ``REQUIRED`` argument is given, the command will fail with an error - if module(s) could not be found. - - When the ``QUIET`` argument is given, no status messages will be printed. - - .. versionadded:: 3.3 - The :variable:`CMAKE_PREFIX_PATH`, - :variable:`CMAKE_FRAMEWORK_PATH`, and :variable:`CMAKE_APPBUNDLE_PATH` cache - and environment variables will be added to the ``pkg-config`` search path. - The ``NO_CMAKE_PATH`` and ``NO_CMAKE_ENVIRONMENT_PATH`` arguments - disable this behavior for the cache variables and environment variables - respectively. - The :variable:`PKG_CONFIG_USE_CMAKE_PREFIX_PATH` variable set to ``FALSE`` - disables this behavior globally. - - .. This was actually added in 3.1, but didn't work until 3.3. - - .. versionadded:: 3.7 - The ``IMPORTED_TARGET`` argument will create an imported target named - ``PkgConfig::<prefix>`` that can be passed directly as an argument to - :command:`target_link_libraries`. - - .. This was actually added in 3.6, but didn't work until 3.7. - - .. versionadded:: 3.13 - The ``GLOBAL`` argument will make the - imported target available in global scope. - - .. versionadded:: 3.15 - Non-library linker options reported by ``pkg-config`` are stored in the - :prop_tgt:`INTERFACE_LINK_OPTIONS` target property. - - .. versionchanged:: 3.18 - Include directories specified with ``-isystem`` are stored in the - :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target property. Previous - versions of CMake left them in the :prop_tgt:`INTERFACE_COMPILE_OPTIONS` - property. - - Each ``<moduleSpec>`` can be either a bare module name or it can be a - module name with a version constraint (operators ``=``, ``<``, ``>``, - ``<=`` and ``>=`` are supported). The following are examples for a module - named ``foo`` with various constraints: - - - ``foo`` matches any version. - - ``foo<2`` only matches versions before 2. - - ``foo>=3.1`` matches any version from 3.1 or later. - - ``foo=1.2.3`` requires that foo must be exactly version 1.2.3. - - The following variables may be set upon return. Two sets of values exist: - One for the common case (``<XXX> = <prefix>``) and another for the - information ``pkg-config`` provides when called with the ``--static`` - option (``<XXX> = <prefix>_STATIC``). - - ``<XXX>_FOUND`` - set to 1 if module(s) exist - ``<XXX>_LIBRARIES`` - only the libraries (without the '-l') - ``<XXX>_LINK_LIBRARIES`` - the libraries and their absolute paths - ``<XXX>_LIBRARY_DIRS`` - the paths of the libraries (without the '-L') - ``<XXX>_LDFLAGS`` - all required linker flags - ``<XXX>_LDFLAGS_OTHER`` - all other linker flags - ``<XXX>_INCLUDE_DIRS`` - the '-I' preprocessor flags (without the '-I') - ``<XXX>_CFLAGS`` - all required cflags - ``<XXX>_CFLAGS_OTHER`` - the other compiler flags - - All but ``<XXX>_FOUND`` may be a :ref:`;-list <CMake Language Lists>` if the - associated variable returned from ``pkg-config`` has multiple values. - - .. versionchanged:: 3.18 - Include directories specified with ``-isystem`` are stored in the - ``<XXX>_INCLUDE_DIRS`` variable. Previous versions of CMake left them - in ``<XXX>_CFLAGS_OTHER``. - - There are some special variables whose prefix depends on the number of - ``<moduleSpec>`` given. When there is only one ``<moduleSpec>``, - ``<YYY>`` will simply be ``<prefix>``, but if two or more ``<moduleSpec>`` - items are given, ``<YYY>`` will be ``<prefix>_<moduleName>``. - - ``<YYY>_VERSION`` - version of the module - ``<YYY>_PREFIX`` - prefix directory of the module - ``<YYY>_INCLUDEDIR`` - include directory of the module - ``<YYY>_LIBDIR`` - lib directory of the module - - .. versionchanged:: 3.8 - For any given ``<prefix>``, ``pkg_check_modules()`` can be called multiple - times with different parameters. Previous versions of CMake cached and - returned the first successful result. - - .. versionchanged:: 3.16 - If a full path to the found library can't be determined, but it's still - visible to the linker, pass it through as ``-l<name>``. Previous versions - of CMake failed in this case. - - Examples: - - .. code-block:: cmake - - pkg_check_modules (GLIB2 glib-2.0) - - Looks for any version of glib2. If found, the output variable - ``GLIB2_VERSION`` will hold the actual version found. - - .. code-block:: cmake - - pkg_check_modules (GLIB2 glib-2.0>=2.10) - - Looks for at least version 2.10 of glib2. If found, the output variable - ``GLIB2_VERSION`` will hold the actual version found. - - .. code-block:: cmake - - pkg_check_modules (FOO glib-2.0>=2.10 gtk+-2.0) - - Looks for both glib2-2.0 (at least version 2.10) and any version of - gtk2+-2.0. Only if both are found will ``FOO`` be considered found. - The ``FOO_glib-2.0_VERSION`` and ``FOO_gtk+-2.0_VERSION`` variables will be - set to their respective found module versions. - - .. code-block:: cmake - - pkg_check_modules (XRENDER REQUIRED xrender) - - Requires any version of ``xrender``. Example output variables set by a - successful call:: - - XRENDER_LIBRARIES=Xrender;X11 - XRENDER_STATIC_LIBRARIES=Xrender;X11;pthread;Xau;Xdmcp -#]========================================] macro(pkg_check_modules _prefix _module0) _pkgconfig_parse_options(_pkg_modules _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global "${_module0}" ${ARGN}) # check cached value @@ -877,34 +1148,6 @@ endif() endmacro() - -#[========================================[.rst: -.. command:: pkg_search_module - - The behavior of this command is the same as :command:`pkg_check_modules`, - except that rather than checking for all the specified modules, it searches - for just the first successful match. - - .. code-block:: cmake - - pkg_search_module(<prefix> - [REQUIRED] [QUIET] - [NO_CMAKE_PATH] - [NO_CMAKE_ENVIRONMENT_PATH] - [IMPORTED_TARGET [GLOBAL]] - <moduleSpec> [<moduleSpec>...]) - - .. versionadded:: 3.16 - If a module is found, the ``<prefix>_MODULE_NAME`` variable will contain the - name of the matching module. This variable can be used if you need to run - :command:`pkg_get_variable`. - - Example: - - .. code-block:: cmake - - pkg_search_module (BAR libxml-2.0 libxml2 libxml>=2) -#]========================================] macro(pkg_search_module _prefix _module0) _pkgconfig_parse_options(_pkg_modules_alt _pkg_is_required _pkg_is_silent _no_cmake_path _no_cmake_environment_path _imp_target _imp_target_global "${_module0}" ${ARGN}) # check cached value @@ -939,36 +1182,6 @@ endif() endmacro() -#[========================================[.rst: -.. command:: pkg_get_variable - - .. versionadded:: 3.4 - - Retrieves the value of a pkg-config variable ``varName`` and stores it in the - result variable ``resultVar`` in the calling scope. - - .. code-block:: cmake - - pkg_get_variable(<resultVar> <moduleName> <varName> - [DEFINE_VARIABLES <key>=<value>...]) - - If ``pkg-config`` returns multiple values for the specified variable, - ``resultVar`` will contain a :ref:`;-list <CMake Language Lists>`. - - Options: - - ``DEFINE_VARIABLES <key>=<value>...`` - .. versionadded:: 3.28 - - Specify key-value pairs to redefine variables affecting the variable - retrieved with ``pkg-config``. - - For example: - - .. code-block:: cmake - - pkg_get_variable(GI_GIRDIR gobject-introspection-1.0 girdir) -#]========================================] function (pkg_get_variable result pkg variable) set(_multiValueArgs DEFINE_VARIABLES) @@ -989,55 +1202,3 @@ PARENT_SCOPE) _pkg_restore_path_internal() endfunction () - - -#[========================================[.rst: -Variables Affecting Behavior -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. variable:: PKG_CONFIG_EXECUTABLE - - This cache variable can be set to the path of the pkg-config executable. - :command:`find_program` is called internally by the module with this - variable. - - .. versionadded:: 3.1 - The ``PKG_CONFIG`` environment variable can be used as a hint if - ``PKG_CONFIG_EXECUTABLE`` has not yet been set. - - .. versionchanged:: 3.22 - If the ``PKG_CONFIG`` environment variable is set, only the first - argument is taken from it when using it as a hint. - -.. variable:: PKG_CONFIG_ARGN - - .. versionadded:: 3.22 - - This cache variable can be set to a list of arguments to additionally pass - to pkg-config if needed. If not provided, it will be initialized from the - ``PKG_CONFIG`` environment variable, if set. The first argument in that - environment variable is assumed to be the pkg-config program, while all - remaining arguments after that are used to initialize ``PKG_CONFIG_ARGN``. - If no such environment variable is defined, ``PKG_CONFIG_ARGN`` is - initialized to an empty string. The module does not update the variable once - it has been set in the cache. - -.. variable:: PKG_CONFIG_USE_CMAKE_PREFIX_PATH - - .. versionadded:: 3.1 - - Specifies whether :command:`pkg_check_modules` and - :command:`pkg_search_module` should add the paths in the - :variable:`CMAKE_PREFIX_PATH`, :variable:`CMAKE_FRAMEWORK_PATH` and - :variable:`CMAKE_APPBUNDLE_PATH` cache and environment variables to the - ``pkg-config`` search path. - - If this variable is not set, this behavior is enabled by default if - :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` is 3.1 or later, disabled - otherwise. -#]========================================] - - -### Local Variables: -### mode: cmake -### End:
diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake index 9ab193a..ae4bb93 100644 --- a/Modules/FindQt3.cmake +++ b/Modules/FindQt3.cmake
@@ -92,7 +92,7 @@ # QT_WRAP_UI set true if QT_UIC_EXECUTABLE is found # If Qt4 has already been found, fail. -if(QT4_FOUND) +if(Qt4_FOUND) if(Qt3_FIND_REQUIRED) message( FATAL_ERROR "Qt3 and Qt4 cannot be used together in one project.") else()
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 6ba7e1a..c084e81 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake
@@ -127,17 +127,18 @@ This module defines the following variables: ``Qt4_FOUND`` - Boolean whether Qt4 has been found. If false, don't try to use Qt4. + Boolean indicating whether (the requested version of) Qt4 is found. + ``QT_FOUND`` - Boolean whether Qt4 has been found. If false, don't try to use Qt4. This - variable is for compatibility with other Qt find modules. -``QT4_FOUND`` - Boolean whether Qt4 has been found. If false, don't try to use Qt4. This - variable is for backward compatibility only. + Boolean indicating whether (the requested version of) Qt4 has been found. + This variable is available for compatibility with other Qt find modules. + ``QT_VERSION_MAJOR`` The major version of Qt found. + ``QT_VERSION_MINOR`` The minor version of Qt found. + ``QT_VERSION_PATCH`` The patch version of Qt found. @@ -438,6 +439,15 @@ the ``QtCore``, ``QtGui`` and ``QtDeclarative`` components on the project target ``myexe``. +Deprecated Variables +^^^^^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + +``QT4_FOUND`` + .. deprecated:: 2.8.11 + Use ``Qt4_FOUND``, which has the same value. + Examples ^^^^^^^^
diff --git a/Modules/FindSubversion.cmake b/Modules/FindSubversion.cmake index ae17656..47e775f 100644 --- a/Modules/FindSubversion.cmake +++ b/Modules/FindSubversion.cmake
@@ -22,7 +22,9 @@ client is found. For backward compatibility, the ``SUBVERSION_FOUND`` variable is also set to the same value. -``Subversion_VERSION_SVN`` +``Subversion_VERSION`` + .. versionadded:: 4.2 + Version of the ``svn`` command-line client found. Cache Variables @@ -93,6 +95,17 @@ Last log of the base revision of a Subversion working copy located at ``<dir>``. +Deprecated Variables +^^^^^^^^^^^^^^^^^^^^ + +The following variables are provided for backward compatibility: + +``Subversion_VERSION_SVN`` + .. deprecated:: 4.2 + Use the ``Subversion_VERSION``. + + Version of the ``svn`` command-line client found. + Examples ^^^^^^^^ @@ -166,6 +179,12 @@ endif() endif() + if(DEFINED Subversion_VERSION_SVN) + set(Subversion_VERSION "${Subversion_VERSION_SVN}") + else() + unset(Subversion_VERSION) + endif() + macro(Subversion_WC_INFO dir prefix) cmake_parse_arguments( @@ -229,7 +248,7 @@ include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Subversion REQUIRED_VARS Subversion_SVN_EXECUTABLE - VERSION_VAR Subversion_VERSION_SVN ) + VERSION_VAR Subversion_VERSION) # for compatibility set(Subversion_SVN_FOUND ${Subversion_FOUND})
diff --git a/Modules/FindwxWidgets.cmake b/Modules/FindwxWidgets.cmake index fa2ad7b..ddcbdf6 100644 --- a/Modules/FindwxWidgets.cmake +++ b/Modules/FindwxWidgets.cmake
@@ -5,133 +5,251 @@ FindwxWidgets ------------- -Find a wxWidgets (a.k.a., wxWindows) installation. +Finds a wxWidgets installation and provides usage requirements for usage in +projects: -This module finds if wxWidgets is installed and selects a default -configuration to use. wxWidgets is a modular library. To specify the -modules that you will use, you need to name them as components to the -package: +.. code-block:: cmake -find_package(wxWidgets COMPONENTS core base ... OPTIONAL_COMPONENTS net ...) + find_package(wxWidgets [<version>] [COMPONENTS <components>...] [...]) + +wxWidgets (formerly known as wxWindows) is a widget toolkit and tools +library for creating graphical user interfaces (GUIs) for cross-platform +applications. .. versionadded:: 3.4 - Support for :command:`find_package` version argument; ``webview`` component. + Support for :command:`find_package` version argument. .. versionadded:: 3.14 ``OPTIONAL_COMPONENTS`` support. -There are two search branches: a windows style and a unix style. For -windows, the following variables are searched for and set to defaults -in case of multiple choices. Change them if the defaults are not -desired (i.e., these are the only variables you should change to -select a configuration): +Components +^^^^^^^^^^ -:: - - wxWidgets_ROOT_DIR - Base wxWidgets directory - (e.g., C:/wxWidgets-3.2.0). - wxWidgets_LIB_DIR - Path to wxWidgets libraries - (e.g., C:/wxWidgets-3.2.0/lib/vc_x64_lib). - wxWidgets_CONFIGURATION - Configuration to use - (e.g., msw, mswd, mswu, mswunivud, etc.) - wxWidgets_EXCLUDE_COMMON_LIBRARIES - - Set to TRUE to exclude linking of - commonly required libs (e.g., png tiff - jpeg zlib regex expat scintilla lexilla). - - - -For unix style it uses the wx-config utility. You can select between -debug/release, unicode/ansi, universal/non-universal, and -static/shared in the QtDialog or ccmake interfaces by turning ON/OFF -the following variables: - -:: - - wxWidgets_USE_DEBUG - wxWidgets_USE_UNICODE - wxWidgets_USE_UNIVERSAL - wxWidgets_USE_STATIC - -There is also a wxWidgets_CONFIG_OPTIONS variable for all other -options that need to be passed to the wx-config utility. For example, -to use the base toolkit found in the /usr/local path, set the variable -(before calling the FIND_PACKAGE command) as such: +wxWidgets is a modular library. This module supports components to specify +the modules to use. Components can be specified with the +:command:`find_package` command: .. code-block:: cmake - set(wxWidgets_CONFIG_OPTIONS --toolkit=base --prefix=/usr) + find_package( + wxWidgets + [COMPONENTS <components>...] + [OPTIONAL_COMPONENTS <components>...] + ) +Supported components include: +``base`` + Finds the library that provides mandatory classes that any wxWidgets code + depends on. This component is always required for applications + implementing wxWidgets. -The following are set after the configuration is done for both windows -and unix style: +``core`` + Finds the library that provides basic GUI classes such as GDI classes or + controls. -:: +``gl`` + Finds the OpenGL support. - wxWidgets_FOUND - Set to TRUE if wxWidgets was found. - wxWidgets_INCLUDE_DIRS - Include directories for WIN32 - i.e., where to find "wx/wx.h" and - "wx/setup.h"; possibly empty for unices. - wxWidgets_LIBRARIES - Path to the wxWidgets libraries. - wxWidgets_LIBRARY_DIRS - compile time link dirs, useful for - rpath on UNIX. Typically an empty string - in WIN32 environment. - wxWidgets_DEFINITIONS - Contains defines required to compile/link - against WX, e.g. WXUSINGDLL - wxWidgets_DEFINITIONS_DEBUG- Contains defines required to compile/link - against WX debug builds, e.g. __WXDEBUG__ - wxWidgets_CXX_FLAGS - Include dirs and compiler flags for - unices, empty on WIN32. Essentially - "`wx-config --cxxflags`". - wxWidgets_USE_FILE - Convenience include file. +``mono`` + Finds the wxWidgets monolithic library. -.. versionadded:: 3.11 - The following environment variables can be used as hints: ``WX_CONFIG``, - ``WXRC_CMD``. +``aui`` + Finds the Advanced User Interface docking library. +``net`` + Finds the library that provides network access. -Sample usage: +``webview`` + .. versionadded:: 3.4 -.. code-block:: cmake + Finds the library that provides rendering of web documents + (HTML/CSS/JavaScript). - # Note that for MinGW users the order of libs is important! - find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net) - if(wxWidgets_FOUND) - include(${wxWidgets_USE_FILE}) - # and for each of your dependent executable/library targets: - target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES}) - endif() +For a full list of supported wxWidgets components, refer to the upstream +documentation. - - -If wxWidgets is required (i.e., not an optional part): - -.. code-block:: cmake - - find_package(wxWidgets REQUIRED gl core base OPTIONAL_COMPONENTS net) - include(${wxWidgets_USE_FILE}) - # and for each of your dependent executable/library targets: - target_link_libraries(<YourTarget> ${wxWidgets_LIBRARIES}) +If no components are specified, this module by default searches for ``core`` +and ``base`` components. Imported Targets ^^^^^^^^^^^^^^^^ -.. versionadded:: 3.27 - -This module defines the following :prop_tgt:`IMPORTED` targets: +This module provides the following :ref:`Imported Targets`: ``wxWidgets::wxWidgets`` - An interface library providing usage requirements for the found components. -#]=======================================================================] + .. versionadded:: 3.27 -# -# FIXME: check this and provide a correct sample usage... -# Remember to connect back to the upper text. -# Sample usage with monolithic wx build: -# -# find_package(wxWidgets COMPONENTS mono) -# ... + An interface imported target encapsulating the wxWidgets usage requirements + for the found components, available if wxWidgets is found. + +Result Variables +^^^^^^^^^^^^^^^^ + +This module defines the following variables: + +``wxWidgets_FOUND`` + Boolean indicating whether (the requested version of) wxWidgets and all + its requested components are found. + +``wxWidgets_VERSION_STRING`` + .. versionadded:: 3.4 + + The version of the wxWidgets found. + +``wxWidgets_INCLUDE_DIRS`` + Include directories for WIN32, i.e., where to find ``<wx/wx.h>`` and + ``<wx/setup.h>``; possibly empty for Unix-like systems. + +``wxWidgets_LIBRARIES`` + Path to the wxWidgets libraries. + +``wxWidgets_LIBRARY_DIRS`` + Compile time link dirs, useful for setting ``rpath`` on Unix-like systems. + Typically an empty string in WIN32 environment. + +``wxWidgets_DEFINITIONS`` + Contains compile definitions required to compile/link against WX, e.g. + ``WXUSINGDLL``. + +``wxWidgets_DEFINITIONS_DEBUG`` + Contains compile definitions required to compile/link against WX debug builds, + e.g. ``__WXDEBUG__``. + +``wxWidgets_CXX_FLAGS`` + Include directories and compiler flags for Unix-like systems, empty on + Windows. Essentially the output of ``wx-config --cxxflags``. + +``wxWidgets_USE_FILE`` + Name of the CMake module for using wxWidgets in current directory. For + usage details refer to the :module:`UsewxWidgets` module. + +Hints +^^^^^ + +This module accepts the following variables before calling +``find_package(wxWidgets)``: + +``WX_CONFIG`` + .. versionadded:: 3.11 + + Environment variable to manually specify the name of the wxWidgets library + configuration provider executable that will be searched besides the default + name ``wx-config``. + +``WXRC_CMD`` + .. versionadded:: 3.11 + + Environment variable to manually specify the name of the wxWidgets resource + file compiler executable that will be searched besides the default name + ``wxrc``. + +There are two search branches: a Windows style and a Unix style. For +Windows, the following variables are searched for and set to defaults +in case of multiple choices. Change them if the defaults are not +desired (i.e., these are the only variables that should be changed to +select a configuration): + +``wxWidgets_ROOT_DIR`` + Base wxWidgets directory (e.g., ``C:/wxWidgets-3.2.0``). + +``wxWidgets_LIB_DIR`` + Path to wxWidgets libraries (e.g., ``C:/wxWidgets-3.2.0/lib/vc_x64_lib``). + +``wxWidgets_CONFIGURATION`` + Configuration to use (e.g., msw, mswd, mswu, mswunivud, etc.) + +``wxWidgets_EXCLUDE_COMMON_LIBRARIES`` + Set to TRUE to exclude linking of commonly required libs (e.g., png, tiff, + jpeg, zlib, regex, expat, scintilla, lexilla, etc.). + +For Unix style this module uses the ``wx-config`` utility. Selecting +between debug/release, unicode/ansi, universal/non-universal, and +static/shared is possible in the QtDialog or ccmake interfaces by turning +ON/OFF the following variables: + +``wxWidgets_USE_DEBUG`` + If enabled, the wxWidgets debug build will be searched. + +``wxWidgets_USE_UNICODE`` + If enabled, the wxWidgets unicode build will be searched. + +``wxWidgets_USE_UNIVERSAL`` + If enabled, the wxWidgets universal build will be searched. + +``wxWidgets_USE_STATIC`` + If enabled, static wxWidgets libraries will be linked. + +``wxWidgets_CONFIG_OPTIONS`` + This variable can be used for all other options that need to be passed to + the wx-config utility. For example, to use the base toolkit found on the + system at ``/usr`` install prefix, set the variable (before calling the + :command:`find_package` command) as such: + + .. code-block:: cmake + + set(wxWidgets_CONFIG_OPTIONS --toolkit=base --prefix=/usr) + +Examples +^^^^^^^^ + +Example: Finding wxWidgets +"""""""""""""""""""""""""" + +Finding wxWidgets and making it required (if wxWidgets is not found, +processing stops with an error message): + +.. code-block:: cmake + + find_package(wxWidgets REQUIRED) + +Example: Using Imported Target +"""""""""""""""""""""""""""""" + +Finding wxWidgets and using imported target in a project: + +.. code-block:: cmake + + find_package(wxWidgets) + target_link_libraries(example PRIVATE wxWidgets::wxWidgets) + +Example: Using Components +""""""""""""""""""""""""" + +Finding wxWidgets and specifying components: + +.. code-block:: cmake + + find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net) + target_link_libraries(example PRIVATE wxWidgets::wxWidgets) + +Example: Monolithic wxWidgets Build +""""""""""""""""""""""""""""""""""" + +Sample usage with monolithic wxWidgets build: + +.. code-block:: cmake + + find_package(wxWidgets COMPONENTS mono) + target_link_libraries(example PRIVATE wxWidgets::wxWidgets) + +Example: Using Variables +"""""""""""""""""""""""" + +Finding and using wxWidgets in CMake versions prior to 3.27, when the +imported target wasn't yet available: + +.. code-block:: cmake + + # Note that for MinGW users the order of libs is important. + find_package(wxWidgets COMPONENTS gl core base OPTIONAL_COMPONENTS net) + + if(wxWidgets_FOUND) + include(${wxWidgets_USE_FILE}) + # and for each of the project dependent executable/library targets: + target_link_libraries(example ${wxWidgets_LIBRARIES}) + endif() +#]=======================================================================] # NOTES #
diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index f1f5db7..952e66c 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake
@@ -9,12 +9,19 @@ Use :command:`file(GET_RUNTIME_DEPENDENCIES)` instead. -This module provides functions to analyze and list the dependencies -(prerequisites) of executable or shared library files. These functions list the -shared libraries (``.dll``, ``.dylib``, or ``.so`` files) required by an +This module provides commands to analyze and list the dependencies +(prerequisites) of executable or shared library files. These commands list +the shared libraries (``.dll``, ``.dylib``, or ``.so`` files) required by an executable or shared library. -It determines dependencies using the following platform-specific tools: +Load this module in CMake with: + +.. code-block:: cmake + + include(GetPrerequisites) + +This module determines dependencies using the following platform-specific +tools: * ``dumpbin`` (Windows) * ``objdump`` (MinGW on Windows) @@ -25,7 +32,10 @@ The tool specified by the :variable:`CMAKE_OBJDUMP` variable will be used, if set. -The following functions are provided by this module: +Commands +^^^^^^^^ + +This module provides the following commands: * :command:`get_prerequisites` * :command:`list_prerequisites` @@ -40,20 +50,18 @@ (projects can override it with ``gp_resolved_file_type_override()``) * :command:`gp_file_type` -Functions -^^^^^^^^^ - .. command:: get_prerequisites + Gets the list of shared library files required by specified target: + .. code-block:: cmake get_prerequisites(<target> <prerequisites-var> <exclude-system> <recurse> <exepath> <dirs> [<rpaths>]) - Gets the list of shared library files required by ``<target>``. The list - in the variable named ``<prerequisites-var>`` should be empty on first - entry to this function. On exit, ``<prerequisites-var>`` will contain the - list of required shared library files. + The list in the variable named ``<prerequisites-var>`` should be empty on + first entry to this command. On exit, ``<prerequisites-var>`` will contain + the list of required shared library files. The arguments are: @@ -80,16 +88,16 @@ .. versionadded:: 3.14 The variable ``GET_PREREQUISITES_VERBOSE`` can be set to true before calling - this function to enable verbose output. + this command to enable verbose output. .. command:: list_prerequisites + Prints a message listing the prerequisites of the specified target: + .. code-block:: cmake list_prerequisites(<target> [<recurse> [<exclude-system> [<verbose>]]]) - Prints a message listing the prerequisites of ``<target>``. - The arguments are: ``<target>`` @@ -107,15 +115,15 @@ .. command:: list_prerequisites_by_glob + Prints the prerequisites of shared library and executable files matching a + globbing pattern: + .. code-block:: cmake list_prerequisites_by_glob(<GLOB|GLOB_RECURSE> <glob-exp> [<optional-args>...]) - Prints the prerequisites of shared library and executable files matching a - globbing pattern. - The arguments are: ``GLOB`` or ``GLOB_RECURSE`` @@ -131,44 +139,56 @@ .. command:: gp_append_unique + Appends the value to the list only if it is not already in the list: + .. code-block:: cmake gp_append_unique(<list-var> <value>) - Appends ``<value>`` to the list variable ``<list-var>`` only if the value is - not already in the list. + The arguments are: + + ``<value>`` + The value to be appended to the list. + ``<list-var>`` + The list variable name that will have the value appended only if it is + not already in the list. .. command:: is_file_executable + Checks if given file is a binary executable: + .. code-block:: cmake is_file_executable(<file> <result-var>) - Sets ``<result-var>`` to 1 if ``<file>`` is a binary executable; otherwise - sets it to 0. + This command sets the ``<result-var>`` to 1 if ``<file>`` is a binary + executable; otherwise it sets it to 0. .. command:: gp_item_default_embedded_path + Determines the reference path for the specified item: + .. code-block:: cmake gp_item_default_embedded_path(<item> <default-embedded-path-var>) - Determines the reference path for ``<item>`` when it is embedded inside a - bundle and stores it to a variable ``<default-embedded-path-var>``. + This command determines the reference path for ``<item>`` when it is + embedded inside a bundle and stores it to a variable + ``<default-embedded-path-var>``. - Projects can override this function by defining a custom - ``gp_item_default_embedded_path_override()`` function. + Projects can override this command by defining a custom + ``gp_item_default_embedded_path_override()`` command. .. command:: gp_resolve_item + Resolves a given item into an existing full path file and stores it to a + variable: + .. code-block:: cmake gp_resolve_item(<context> <item> <exepath> <dirs> <resolved-item-var> [<rpaths>]) - Resolves a given ``<item>`` into an existing full path file and stores it to a - ``<resolved-item-var>`` variable. - The arguments are: ``<context>`` @@ -187,18 +207,21 @@ ``<rpaths>`` See the argument description in :command:`get_prerequisites`. - Projects can override this function by defining a custom - ``gp_resolve_item_override()`` function. + Projects can override this command by defining a custom + ``gp_resolve_item_override()`` command. .. command:: gp_resolved_file_type + Determines the type of a given file: + .. code-block:: cmake gp_resolved_file_type(<original-file> <file> <exepath> <dirs> <type-var> [<rpaths>]) - Determines the type of ``<file>`` with respect to ``<original-file>``. The - resulting type of prerequisite is stored in the ``<type-var>`` variable. + This command determines the type of ``<file>`` with respect to the + ``<original-file>``. The resulting type of prerequisite is stored in the + ``<type-var>`` variable. Use ``<exepath>`` and ``<dirs>`` if necessary to resolve non-absolute ``<file>`` values -- but only for non-embedded items. @@ -213,17 +236,20 @@ * ``embedded`` * ``other`` - Projects can override this function by defining a custom - ``gp_resolved_file_type_override()`` function. + Projects can override this command by defining a custom + ``gp_resolved_file_type_override()`` command. .. command:: gp_file_type + Determines the type of a given file: + .. code-block:: cmake gp_file_type(<original-file> <file> <type-var>) - Determines the type of ``<file>`` with respect to ``<original-file>``. The - resulting type of prerequisite is stored in the ``<type-var>`` variable. + This command determines the type of ``<file>`` with respect to the + ``<original-file>``. The resulting type of prerequisite is stored in the + ``<type-var>`` variable. The ``<type-var>`` variable will be set to one of the following values: @@ -235,6 +261,9 @@ Examples ^^^^^^^^ +Example: Basic Usage +"""""""""""""""""""" + Printing all dependencies of a shared library, including system libraries, with verbose output: @@ -242,6 +271,25 @@ include(GetPrerequisites) list_prerequisites("path/to/libfoo.dylib" 1 0 1) + +Example: Upgrading Code +""""""""""""""""""""""" + +For example: + +.. code-block:: cmake + + include(GetPrerequisites) + # ... + gp_append_unique(keys "${key}") + +the ``gp_append_unique()`` can be in new code replaced with: + +.. code-block:: cmake + + if(NOT key IN_LIST keys) + list(APPEND keys "${key}") + endif() #]=======================================================================] function(gp_append_unique list_var value)
diff --git a/Modules/MacroAddFileDependencies.cmake b/Modules/MacroAddFileDependencies.cmake index 9dee09d..0c65c46 100644 --- a/Modules/MacroAddFileDependencies.cmake +++ b/Modules/MacroAddFileDependencies.cmake
@@ -6,24 +6,38 @@ ------------------------ .. deprecated:: 3.14 + Do not use this module in new code. + + Instead use the :command:`set_property` command to append to the + :prop_sf:`OBJECT_DEPENDS` source file property directly: + + .. code-block:: cmake + + set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...) + +Load this module in a CMake project with: .. code-block:: cmake - macro_add_file_dependencies(<source> <files>...) + include(MacroAddFileDependencies) -Do not use this command in new code. It is just a wrapper around: +Commands +^^^^^^^^ -.. code-block:: cmake +This module provides the following command: - set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...) +.. command:: macro_add_file_dependencies -Instead use the :command:`set_property` command to append to the -:prop_sf:`OBJECT_DEPENDS` source file property directly. + Adds dependencies to a source file: + .. code-block:: cmake + + macro_add_file_dependencies(<source> <files>...) + + This command adds the given ``<files>`` to the dependencies of file + ``<source>``. #]=======================================================================] -macro (MACRO_ADD_FILE_DEPENDENCIES _file) - +macro(MACRO_ADD_FILE_DEPENDENCIES _file) set_property(SOURCE "${_file}" APPEND PROPERTY OBJECT_DEPENDS "${ARGN}") - -endmacro () +endmacro()
diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake index a39f8b3..69c7bc3 100644 --- a/Modules/TestCXXAcceptsFlag.cmake +++ b/Modules/TestCXXAcceptsFlag.cmake
@@ -12,11 +12,19 @@ :module:`CheckCompilerFlag` module is also available for checking flags across multiple languages. -This module provides a macro to test whether the C++ (CXX) compiler supports +This module provides a command to test whether the C++ (CXX) compiler supports specific flags. -Macros -^^^^^^ +Load this module in a CMake project with: + +.. code-block:: cmake + + include(TestCXXAcceptsFlag) + +Commands +^^^^^^^^ + +This module provides the following command: .. command:: check_cxx_accepts_flag
diff --git a/Modules/UsePkgConfig.cmake b/Modules/UsePkgConfig.cmake index 2c34c26..b047013 100644 --- a/Modules/UsePkgConfig.cmake +++ b/Modules/UsePkgConfig.cmake
@@ -10,7 +10,7 @@ This module should no longer be used. Instead, use the :module:`FindPkgConfig` module or the :command:`cmake_pkg_config` command. - This module provided a macro for finding external packages using + This module provided a command for finding external packages using ``pkg-config`` command-line utility. It has been replaced by the more convenient ``FindPkgConfig`` module, which is commonly used in :ref:`Find Modules`. @@ -18,10 +18,16 @@ As of CMake 3.31, the built-in :command:`cmake_pkg_config` command provides even more features to extract package information. -Macros -^^^^^^ +Load this module in a CMake project with: -This module defines the following macro: +.. code-block:: cmake + + include(UsePkgConfig) + +Commands +^^^^^^^^ + +This module provides the following command: .. command:: pkgconfig @@ -31,9 +37,10 @@ pkgconfig(<package> <includedir> <libdir> <linkflags> <cflags>) - This macro invokes ``pkg-config`` command-line utility to retrieve the package - information into specified variables. If ``pkg-config`` or the specified - package ``<package>`` is NOT found, the result variables remain empty. + This command invokes ``pkg-config`` command-line utility to retrieve the + package information into specified variables. If ``pkg-config`` or the + specified package ``<package>`` is NOT found, the result variables remain + empty. The arguments are:
diff --git a/Modules/UsewxWidgets.cmake b/Modules/UsewxWidgets.cmake index 3751025..4dc34e3 100644 --- a/Modules/UsewxWidgets.cmake +++ b/Modules/UsewxWidgets.cmake
@@ -5,42 +5,66 @@ UsewxWidgets ------------ +This module serves as a convenience wrapper for using the wxWidgets +library (formerly known as wxWindows) and propagates its usage requirements, +such as library directories, include directories, and compiler flags, into +the current directory scope for use by targets. + +Load this module in a CMake project with: + +.. code-block:: cmake + + include(UsewxWidgets) + This module calls :command:`include_directories` and -:command:`link_directories`, sets compile definitions for the current directory -and appends some compile flags to use wxWidgets library after calling the -:module:`find_package(wxWidgets) <FindwxWidgets>`. +:command:`link_directories`, sets compile definitions for the current +directory and appends some compile flags to use wxWidgets library after +calling the :module:`find_package(wxWidgets) <FindwxWidgets>`. Examples ^^^^^^^^ -Include ``UsewxWidgets`` module in project's ``CMakeLists.txt``: +Include this module in a project after finding wxWidgets to configure its +usage requirements: .. code-block:: cmake + :caption: ``CMakeLists.txt`` # Note that for MinGW users the order of libraries is important. find_package(wxWidgets REQUIRED net gl core base) - # Above also sets the wxWidgets_USE_FILE variable that points to this module. - include(${wxWidgets_USE_FILE}) + add_library(example example.cxx) - # Link wxWidgets libraries for each dependent executable/library target. - target_link_libraries(<ProjectTarget> ${wxWidgets_LIBRARIES}) + if(wxWidgets_FOUND) + # Above also sets the wxWidgets_USE_FILE variable that points to this module. + include(${wxWidgets_USE_FILE}) + + # Link wxWidgets libraries for each dependent executable/library target. + target_link_libraries(example PRIVATE ${wxWidgets_LIBRARIES}) + endif() As of CMake 3.27, a better approach is to link only the -:module:`wxWidgets::wxWidgets <FindwxWidgets>` ``IMPORTED`` target to specific -targets that require it, rather than including this module. Imported targets -provide better control of the package usage properties, such as include -directories and compile flags, by applying them only to the targets they are -linked to, avoiding unnecessary propagation to all targets in the current -directory. +:module:`wxWidgets::wxWidgets <FindwxWidgets>` imported target to specific +targets that require it, rather than including this module. Imported +targets provide better control of the package usage properties, such as +include directories and compile flags, by applying them only to the targets +they are linked to, avoiding unnecessary propagation to all targets in the +current directory. .. code-block:: cmake + :caption: ``CMakeLists.txt`` - # CMakeLists.txt find_package(wxWidgets) + add_library(example example.cxx) + # Link the imported target for each dependent executable/library target. - target_link_libraries(<ProjectTarget> wxWidgets::wxWidgets) + target_link_libraries(example PRIVATE wxWidgets::wxWidgets) + +See Also +^^^^^^^^ + +* The :module:`FindwxWidgets` module to find wxWidgets. #]=======================================================================] # Author: Jan Woetzel <jw -at- mip.informatik.uni-kiel.de>
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index a8f5fd1..600c95e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt
@@ -401,6 +401,8 @@ cmMSVC60LinkLineComputer.h cmOSXBundleGenerator.cxx cmOSXBundleGenerator.h + cmObjectLocation.cxx + cmObjectLocation.h cmOutputConverter.cxx cmOutputConverter.h cmNewLineStyle.h
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 51dfa3b..1013360 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 4) set(CMake_VERSION_MINOR 1) -set(CMake_VERSION_PATCH 20250813) +set(CMake_VERSION_PATCH 20250818) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx index 05489d0..f0c3439 100644 --- a/Source/CPack/cmCPackDragNDropGenerator.cxx +++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -76,6 +76,14 @@ paths.emplace_back("/Applications/Xcode.app/Contents/Developer/Tools"); paths.emplace_back("/Developer/Tools"); + std::string const sync_path = cmSystemTools::FindProgram("sync"); + if (sync_path.empty()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot locate sync command" << std::endl); + return 0; + } + this->SetOptionIfNotSet("CPACK_COMMAND_SYNC", sync_path); + std::string const hdiutil_path = cmSystemTools::FindProgram("hdiutil"); if (hdiutil_path.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, @@ -415,6 +423,16 @@ std::string temp_image = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/temp.dmg"); + // Finish filesystem operations before writing disk image. + std::string sync_command = this->GetOption("CPACK_COMMAND_SYNC"); + std::string sync_error; + if (!this->RunCommand(sync_command, &sync_error)) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error running sync command." << std::endl + << sync_error << std::endl); + return 0; + } + std::string create_error; auto temp_image_command = cmStrCat(this->GetOption("CPACK_COMMAND_HDIUTIL"),
diff --git a/Source/cmCMakePkgConfigCommand.cxx b/Source/cmCMakePkgConfigCommand.cxx index 181c7d8..0d753bb 100644 --- a/Source/cmCMakePkgConfigCommand.cxx +++ b/Source/cmCMakePkgConfigCommand.cxx
@@ -911,6 +911,9 @@ auto& pcEnv = maybeEnv->first; auto& imEnv = maybeEnv->second; + pcEnv.AllowSysCflags = true; + pcEnv.AllowSysLibs = true; + pkgProviders providers; if (args.Providers) { for (auto const& provider_str : *args.Providers) {
diff --git a/Source/cmExportPackageInfoGenerator.cxx b/Source/cmExportPackageInfoGenerator.cxx index d38c640..4b17ac2 100644 --- a/Source/cmExportPackageInfoGenerator.cxx +++ b/Source/cmExportPackageInfoGenerator.cxx
@@ -5,9 +5,11 @@ #include <cstddef> #include <memory> #include <set> +#include <type_traits> #include <utility> #include <vector> +#include <cm/optional> #include <cm/string_view> #include <cmext/algorithm> #include <cmext/string_view> @@ -27,7 +29,6 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" #include "cmTarget.h" -#include "cmValue.h" static std::string const kCPS_VERSION_STR = "0.13.0"; @@ -146,15 +147,25 @@ auto data = Json::Value{ Json::objectValue }; // Add required components. - if (!requirement.second.empty()) { + if (!requirement.second.Components.empty()) { auto components = Json::Value{ Json::arrayValue }; - for (std::string const& component : requirement.second) { + for (std::string const& component : requirement.second.Components) { components.append(component); } data["components"] = components; } - // TODO: version, hint + // Add additional dependency information. + if (requirement.second.Directory) { + auto hints = Json::Value{ Json::arrayValue }; + hints.append(*requirement.second.Directory); + data["hints"] = hints; + } + + if (requirement.second.Version) { + data["version"] = *requirement.second.Version; + } + requirements[requirement.first] = data; } } @@ -283,16 +294,24 @@ if (linkedTarget->IsImported()) { // Target is imported from a found package. - auto pkgName = [linkedTarget]() -> std::string { - auto const& pkgStack = linkedTarget->Target->GetFindPackageStack(); + using Package = cm::optional<std::pair<std::string, cmPackageInformation>>; + auto pkgInfo = [](cmTarget* t) -> Package { + cmFindPackageStack pkgStack = t->GetFindPackageStack(); if (!pkgStack.Empty()) { - return pkgStack.Top().Name; + return std::make_pair(pkgStack.Top().Name, pkgStack.Top().PackageInfo); } - return linkedTarget->Target->GetProperty("EXPORT_FIND_PACKAGE_NAME"); - }(); + cmPackageInformation package; + std::string const pkgName = + t->GetSafeProperty("EXPORT_FIND_PACKAGE_NAME"); + if (pkgName.empty()) { + return cm::nullopt; + } - if (pkgName.empty()) { + return std::make_pair(pkgName, package); + }(linkedTarget->Target); + + if (!pkgInfo) { target->Makefile->IssueMessage( MessageType::FATAL_ERROR, cmStrCat("Target \"", target->GetName(), @@ -301,6 +320,8 @@ return false; } + std::string const& pkgName = pkgInfo->first; + auto const& prefix = cmStrCat(pkgName, "::"); if (!cmHasPrefix(linkedName, prefix)) { target->Makefile->IssueMessage( @@ -314,8 +335,9 @@ std::string component = linkedName.substr(prefix.length()); this->LinkTargets.emplace(linkedName, cmStrCat(pkgName, ':', component)); - // TODO: Record package version, hint. - this->Requirements[pkgName].emplace(std::move(component)); + cmPackageInformation& req = + this->Requirements.insert(std::move(*pkgInfo)).first->second; + req.Components.emplace(std::move(component)); return true; } @@ -339,7 +361,7 @@ this->LinkTargets.emplace(linkedName, cmStrCat(':', component)); } else { this->LinkTargets.emplace(linkedName, cmStrCat(pkgName, ':', component)); - this->Requirements[pkgName].emplace(std::move(component)); + this->Requirements[pkgName].Components.emplace(std::move(component)); } return true; }
diff --git a/Source/cmExportPackageInfoGenerator.h b/Source/cmExportPackageInfoGenerator.h index 83cb6ad..0614e27 100644 --- a/Source/cmExportPackageInfoGenerator.h +++ b/Source/cmExportPackageInfoGenerator.h
@@ -6,13 +6,13 @@ #include <iosfwd> #include <map> -#include <set> #include <string> #include <vector> #include <cm/string_view> #include "cmExportFileGenerator.h" +#include "cmFindPackageStack.h" #include "cmStateTypes.h" namespace Json { @@ -112,9 +112,10 @@ std::string const PackageWebsite; std::string const PackageLicense; std::string const DefaultLicense; + std::vector<std::string> DefaultTargets; std::vector<std::string> DefaultConfigurations; std::map<std::string, std::string> LinkTargets; - std::map<std::string, std::set<std::string>> Requirements; + std::map<std::string, cmPackageInformation> Requirements; };
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 243061e..6c43c7a 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx
@@ -1224,6 +1224,8 @@ SetRestoreFindDefinitions setRestoreFindDefinitions(*this); cmFindPackageStackRAII findPackageStackRAII(this->Makefile, this->Name); + findPackageStackRAII.BindTop(this->CurrentPackageInfo); + // See if we have been told to delegate to FetchContent or some other // redirected config package first. We have to check all names that // find_package() may look for, but only need to invoke the override for the @@ -1270,6 +1272,8 @@ this->Names.clear(); this->Names.emplace_back(overrideName); // Force finding this one this->Variable = cmStrCat(this->Name, "_DIR"); + this->CurrentPackageInfo->Directory = redirectsDir; + this->CurrentPackageInfo->Version = this->VersionFound; this->SetConfigDirCacheVariable(redirectsDir); break; } @@ -1342,7 +1346,6 @@ } this->AppendSuccessInformation(); - return loadedPackage; } @@ -1971,6 +1974,8 @@ std::string init; if (found) { init = cmSystemTools::GetFilenamePath(this->FileFound); + this->CurrentPackageInfo->Directory = init; + this->CurrentPackageInfo->Version = this->VersionFound; } else { init = this->Variable + "-NOTFOUND"; }
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index d225fb9..ff8ff27 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h
@@ -37,6 +37,7 @@ class cmMakefile; class cmPackageState; class cmSearchPath; +class cmPackageInformation; /** \class cmFindPackageCommand * \brief Load settings from an external project. @@ -286,6 +287,8 @@ std::set<std::string> OptionalComponents; std::set<std::string> RequiredTargets; std::string DebugBuffer; + cmPackageInformation* CurrentPackageInfo; + enum class SearchResult { InsufficientVersion,
diff --git a/Source/cmFindPackageStack.h b/Source/cmFindPackageStack.h index f2bb6c6..e7fb9a6 100644 --- a/Source/cmFindPackageStack.h +++ b/Source/cmFindPackageStack.h
@@ -5,19 +5,41 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <memory> +#include <set> #include <string> +#include <cm/optional> + #include "cmStack.h" class cmMakefile; /** + * This data represents the actual contents of find_package + * <PACKAGE>-Config.cmake or <PACKAGE>.cps file, and not what is passed + * to the find_package command. They can be the same, but it is not guaranteed. + */ + +class cmPackageInformation +{ +public: + cm::optional<std::string> Directory; + cm::optional<std::string> Version; + cm::optional<std::string> Description; + cm::optional<std::string> License; + cm::optional<std::string> Website; + cm::optional<std::string> PackageUrl; + std::set<std::string> Components; +}; + +/** * Represents one call to find_package. */ class cmFindPackageCall { public: - std::string Name; + std::string const Name; + cmPackageInformation PackageInfo; unsigned int Index; }; @@ -28,7 +50,7 @@ class cmFindPackageStackRAII { cmMakefile* Makefile; - cmFindPackageCall** Value = nullptr; + cmPackageInformation** Value = nullptr; public: cmFindPackageStackRAII(cmMakefile* mf, std::string const& pkg); @@ -40,7 +62,7 @@ /** Get a mutable pointer to the top of the stack. The pointer is invalidated if BindTop is called again or when the cmFindPackageStackRAII goes out of scope. */ - void BindTop(cmFindPackageCall*& value); + void BindTop(cmPackageInformation*& value); }; /**
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index 96867e2..8b74118 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx
@@ -100,6 +100,9 @@ bool cmForEachFunctionBlocker::Replay( std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus) { + if (this->Args.size() == this->IterationVarsCount) { + return true; + } return this->ZipLists ? this->ReplayZipLists(functions, inStatus) : this->ReplayItems(functions, inStatus); }
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 24a66c4..006594a 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx
@@ -164,33 +164,36 @@ std::string result; std::string::size_type pos = 0; std::string::size_type lastPos = pos; - // stack of { Generator Expression Name, Start Position of Value } - std::stack<std::pair<std::string, std::string::size_type>> genexps; + std::stack<char const*> starts; // indices of "$<" + std::stack<char const*> colons; // indices of ":" while ((pos = input.find("$<", lastPos)) != std::string::npos) { result += input.substr(lastPos, pos - lastPos); + starts.push(input.c_str() + pos); pos += 2; char const* c = input.c_str() + pos; - char const* cName = c; char const* const cStart = c; for (; *c; ++c) { if (cmGeneratorExpression::StartsWithGeneratorExpression(c)) { + starts.push(c); ++c; - cName = c + 1; continue; } - if (c[0] == ':' && cName) { - genexps.push({ input.substr(pos + (cName - cStart), c - cName), - pos + (c + 1 - cStart) }); - cName = nullptr; - } else if (c[0] == '>') { - if (!cName && !genexps.empty()) { - if (collected) { - (*collected)[genexps.top().first].push_back(input.substr( - genexps.top().second, pos + c - cStart - genexps.top().second)); - } - genexps.pop(); + if (c[0] == ':') { + if (colons.size() < starts.size()) { + colons.push(c); } - if (genexps.empty()) { + } else if (c[0] == '>') { + if (collected && !starts.empty() && !colons.empty()) { + (*collected)[std::string(starts.top() + 2, colons.top())].push_back( + std::string(colons.top() + 1, c)); + } + if (!starts.empty()) { + starts.pop(); + } + if (!colons.empty()) { + colons.pop(); + } + if (starts.empty()) { break; } } @@ -202,7 +205,7 @@ pos += traversed; lastPos = pos; } - if (genexps.empty()) { + if (starts.empty()) { result += input.substr(lastPos); } return cmGeneratorExpression::StripEmptyListElements(result);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index dc29ca0..14cbee8 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx
@@ -856,7 +856,10 @@ std::string const& cmGeneratorTarget::GetObjectName(cmSourceFile const* file) { this->ComputeObjectMapping(); - return this->Objects[file]; + auto const useShortPaths = this->GetUseShortObjectNames() + ? cmObjectLocations::UseShortPath::Yes + : cmObjectLocations::UseShortPath::No; + return this->Objects[file].GetPath(useShortPaths); } char const* cmGeneratorTarget::GetCustomObjectExtension() const @@ -3995,9 +3998,21 @@ void cmGeneratorTarget::GetTargetObjectNames( std::string const& config, std::vector<std::string>& objects) const { + this->GetTargetObjectLocations( + config, + [&objects](cmObjectLocation const& buildLoc, cmObjectLocation const&) { + objects.push_back(buildLoc.GetPath()); + }); +} + +void cmGeneratorTarget::GetTargetObjectLocations( + std::string const& config, + std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb) + const +{ std::vector<cmSourceFile const*> objectSources; this->GetObjectSources(objectSources, config); - std::map<cmSourceFile const*, std::string> mapping; + std::map<cmSourceFile const*, cmObjectLocations> mapping; for (cmSourceFile const* sf : objectSources) { mapping[sf]; @@ -4005,12 +4020,20 @@ this->LocalGenerator->ComputeObjectFilenames(mapping, this); + auto const buildUseShortPaths = this->GetUseShortObjectNames() + ? cmObjectLocations::UseShortPath::Yes + : cmObjectLocations::UseShortPath::No; + auto const installUseShortPaths = this->GetUseShortObjectNamesForInstall(); + for (cmSourceFile const* src : objectSources) { // Find the object file name corresponding to this source file. auto map_it = mapping.find(src); + auto const& buildLoc = map_it->second.GetLocation(buildUseShortPaths); + auto const& installLoc = map_it->second.GetLocation(installUseShortPaths); // It must exist because we populated the mapping just above. - assert(!map_it->second.empty()); - objects.push_back(map_it->second); + assert(!buildLoc.GetPath().empty()); + assert(!installLoc.GetPath().empty()); + cb(buildLoc, installLoc); } // We need to compute the relative path from the root of @@ -4020,7 +4043,9 @@ auto ispcObjects = this->GetGeneratedISPCObjects(config); for (std::string const& output : ispcObjects) { auto relativePathFromObjectDir = output.substr(rootObjectDir.size()); - objects.push_back(relativePathFromObjectDir); + cmObjectLocation ispcLoc(relativePathFromObjectDir); + // FIXME: apply short path to this object if needed. + cb(ispcLoc, ispcLoc); } } @@ -5370,6 +5395,25 @@ return this->LocalGenerator->UseShortObjectNames(kind); } +cmObjectLocations::UseShortPath +cmGeneratorTarget::GetUseShortObjectNamesForInstall() const +{ + auto prop = this->Target->GetProperty("INSTALL_OBJECT_NAME_STRATEGY"); + if (prop == "SHORT"_s) { + return cmObjectLocations::UseShortPath::Yes; + } + if (prop == "FULL"_s) { + return cmObjectLocations::UseShortPath::No; + } + if (prop.IsSet()) { + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Property INSTALL_OBJECT_NAME_STRATEGY of target \"", + this->GetName(), "\" set to the unsupported strategy ", prop)); + } + return cmObjectLocations::UseShortPath::No; +} + std::string cmGeneratorTarget::GetSupportDirectory( cmStateEnums::IntermediateDirKind kind) const {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 9f2349e..517bfcc 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h
@@ -5,6 +5,7 @@ #include "cmConfigure.h" // IWYU pragma: keep #include <cstddef> +#include <functional> #include <map> #include <memory> #include <set> @@ -20,6 +21,7 @@ #include "cmAlgorithms.h" #include "cmLinkItem.h" #include "cmListFileCache.h" +#include "cmObjectLocation.h" #include "cmPolicies.h" #include "cmStandardLevel.h" #include "cmStateTypes.h" @@ -298,9 +300,14 @@ cmStateEnums::RuntimeBinaryArtifact) const; /** Get the names of an object library's object files underneath - its object file directory. */ + its object file directory for the build. */ void GetTargetObjectNames(std::string const& config, std::vector<std::string>& objects) const; + /** Get the build and install locations of objects for a given context. */ + void GetTargetObjectLocations( + std::string const& config, + std::function<void(cmObjectLocation const&, cmObjectLocation const&)> cb) + const; /** What hierarchy level should the reported directory contain */ enum BundleDirectoryLevel @@ -940,6 +947,7 @@ bool GetUseShortObjectNames( cmStateEnums::IntermediateDirKind kind = cmStateEnums::IntermediateDirKind::ObjectFiles) const; + cmObjectLocations::UseShortPath GetUseShortObjectNamesForInstall() const; /** Get a build-tree directory in which to place target support files. */ std::string GetSupportDirectory( @@ -1142,7 +1150,7 @@ using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>; SourceEntriesType SourceDepends; mutable std::set<std::string> VisitedConfigsForObjects; - mutable std::map<cmSourceFile const*, std::string> Objects; + mutable std::map<cmSourceFile const*, cmObjectLocations> Objects; std::set<cmSourceFile const*> ExplicitObjectName; using TargetPtrToBoolMap = std::unordered_map<cmTarget*, bool>;
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index c905a4e..4296c22 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -873,7 +873,7 @@ std::vector<std::string> empty; std::vector<cmSourceFile const*> objectSources; gt->GetObjectSources(objectSources, configName); - std::map<cmSourceFile const*, std::string> mapping; + std::map<cmSourceFile const*, cmObjectLocations> mapping; for (cmSourceFile const* it : objectSources) { mapping[it]; } @@ -891,12 +891,17 @@ return; } + auto const useShortPaths = this->UseShortObjectNames() + ? cmObjectLocations::UseShortPath::Yes + : cmObjectLocations::UseShortPath::No; + if (mdi->WindowsExportAllSymbols) { std::vector<std::string> objs; for (cmSourceFile const* it : objectSources) { // Find the object file name corresponding to this source file. // It must exist because we populated the mapping just above. - auto const& v = mapping[it]; + auto const& locs = mapping[it]; + std::string const& v = locs.GetPath(useShortPaths); assert(!v.empty()); std::string objFile = cmStrCat(obj_dir, v); objs.push_back(objFile);
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index b2a5f51..1bc347e 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx
@@ -4,6 +4,7 @@ #include <algorithm> #include <cassert> +#include <cstddef> #include <functional> #include <map> #include <set> @@ -21,6 +22,7 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmObjectLocation.h" #include "cmOutputConverter.h" #include "cmPolicies.h" #include "cmScriptGenerator.h" @@ -174,18 +176,40 @@ // Write code to install the target file. char const* no_dir_permissions = nullptr; - char const* no_rename = nullptr; bool optional = this->Optional || this->ImportLibrary; std::string literal_args; - if (!files.FromDir.empty()) { - literal_args += " FILES_FROM_DIR \"" + files.FromDir + "\""; - } if (files.UseSourcePermissions) { literal_args += " USE_SOURCE_PERMISSIONS"; } - this->AddInstallRule(os, dest, files.Type, files.From, optional, - this->FilePermissions.c_str(), no_dir_permissions, - no_rename, literal_args.c_str(), indent); + if (files.Rename) { + if (files.From.size() != files.To.size()) { + this->Target->GetLocalGenerator()->IssueMessage( + MessageType::INTERNAL_ERROR, + "cmInstallTargetGenerator generated a rename request with mismatched " + "names."); + return; + } + std::vector<std::string> FileNames; + FileNames.resize(1); + for (size_t i = 0; i < files.From.size(); ++i) { + if (files.FromDir.empty()) { + FileNames[0] = files.From[i]; + } else { + FileNames[0] = cmStrCat(files.FromDir, '/', files.From[i]); + } + this->AddInstallRule(os, dest, files.Type, FileNames, optional, + this->FilePermissions.c_str(), no_dir_permissions, + files.To[i].c_str(), literal_args.c_str(), indent); + } + } else { + char const* no_rename = nullptr; + if (!files.FromDir.empty()) { + literal_args += " FILES_FROM_DIR \"" + files.FromDir + "\""; + } + this->AddInstallRule(os, dest, files.Type, files.From, optional, + this->FilePermissions.c_str(), no_dir_permissions, + no_rename, literal_args.c_str(), indent); + } // Add post-installation tweaks. if (!files.NoTweak) { @@ -225,16 +249,21 @@ case cmStateEnums::OBJECT_LIBRARY: { // Compute all the object files inside this target - std::vector<std::string> objects; - this->Target->GetTargetObjectNames(config, objects); + std::vector<std::pair<cmObjectLocation, cmObjectLocation>> objects; + auto storeObjectLocations = [&objects](cmObjectLocation const& build, + cmObjectLocation const& install) { + objects.emplace_back(build, install); + }; + this->Target->GetTargetObjectLocations(config, storeObjectLocations); files.Type = cmInstallType_FILES; files.NoTweak = true; + files.Rename = true; files.FromDir = this->Target->GetObjectDirectory(config); files.ToDir = computeInstallObjectDir(this->Target, config); - for (std::string& obj : objects) { - files.From.emplace_back(obj); - files.To.emplace_back(std::move(obj)); + for (auto const& obj : objects) { + files.From.emplace_back(obj.first.GetPath()); + files.To.emplace_back(obj.second.GetPath()); } return files; } @@ -423,9 +452,17 @@ void cmInstallTargetGenerator::GetInstallObjectNames( std::string const& config, std::vector<std::string>& objects) const { - this->Target->GetTargetObjectNames(config, objects); - for (std::string& o : objects) { - o = cmStrCat(computeInstallObjectDir(this->Target, config), '/', o); + std::vector<cmObjectLocation> installedObjects; + auto storeObjectLocations = + [&installedObjects](cmObjectLocation const&, + cmObjectLocation const& install) { + installedObjects.emplace_back(install); + }; + this->Target->GetTargetObjectLocations(config, storeObjectLocations); + objects.reserve(installedObjects.size()); + auto const rootDir = computeInstallObjectDir(this->Target, config); + for (cmObjectLocation const& o : installedObjects) { + objects.emplace_back(cmStrCat(rootDir, '/', o.GetPath())); } }
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index da51a81..6ddfca6 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h
@@ -86,6 +86,7 @@ std::string ToDir; NamelinkModeType NamelinkMode = NamelinkModeNone; + bool Rename = false; bool NoTweak = false; bool UseSourcePermissions = false; cmInstallType Type = cmInstallType();
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx index 3a8453e..b79b24b 100644 --- a/Source/cmLocalCommonGenerator.cxx +++ b/Source/cmLocalCommonGenerator.cxx
@@ -6,9 +6,12 @@ #include <utility> #include <vector> +#include <cm/optional> + #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" +#include "cmObjectLocation.h" #include "cmOutputConverter.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" @@ -111,7 +114,7 @@ } void cmLocalCommonGenerator::ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* gt) { // Determine if these object files should use a custom extension @@ -119,7 +122,11 @@ for (auto& si : mapping) { cmSourceFile const* sf = si.first; bool keptSourceExtension; - si.second = this->GetObjectFileNameWithoutTarget( - *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext); + bool force = true; + si.second.ShortLoc.emplace(this->GetObjectFileNameWithoutTarget( + *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force)); + force = false; + si.second.LongLoc.Update(this->GetObjectFileNameWithoutTarget( + *sf, gt->ObjectDirectory, &keptSourceExtension, custom_ext, &force)); } }
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h index 7c63c19..1c104a7 100644 --- a/Source/cmLocalCommonGenerator.h +++ b/Source/cmLocalCommonGenerator.h
@@ -13,6 +13,7 @@ class cmGeneratorTarget; class cmGlobalGenerator; class cmMakefile; +struct cmObjectLocations; class cmSourceFile; /** \class cmLocalCommonGenerator @@ -39,7 +40,7 @@ cmGeneratorTarget const* target) const override; void ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* gt = nullptr) override; protected:
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index d1c03a2..f2e9412 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx
@@ -2837,18 +2837,7 @@ langFlags.find("-Zi") != std::string::npos; } - // MSVC 2008 is producing both .pdb and .idb files with /Zi. - bool msvc2008OrLess = - cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, - compilerVersion, "16.0") && - compilerId == "MSVC"; - // but not when used via toolset -Tv90 - if (this->Makefile->GetSafeDefinition( - "CMAKE_VS_PLATFORM_TOOLSET") == "v90") { - msvc2008OrLess = false; - } - - if (editAndContinueDebugInfo || msvc2008OrLess) { + if (editAndContinueDebugInfo) { this->CopyPchCompilePdb(config, lang, target, reuseTarget, { ".pdb", ".idb" }); } else if (programDatabaseDebugInfo) { @@ -2939,10 +2928,9 @@ std::string const from_file = replaceExtension(reuseTarget->GetCompilePDBPath(config), extension); std::string const to_dir = target->GetCompilePDBDirectory(config); - std::string const to_file = cmStrCat( - replaceExtension(reuseTarget->GetCompilePDBName(config), extension), - '/'); - std::string const dest_file = cmStrCat(to_dir, to_file); + std::string const to_file = + replaceExtension(reuseTarget->GetCompilePDBName(config), extension); + std::string const dest_file = cmStrCat(to_dir, '/', to_file); file << "foreach(retry RANGE 1 30)\n"; file << " if (EXISTS \"" << from_file << "\" AND (NOT EXISTS \"" @@ -4143,7 +4131,7 @@ } void cmLocalGenerator::ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& /*unused*/, + std::map<cmSourceFile const*, cmObjectLocations>& /*unused*/, cmGeneratorTarget const* /*unused*/) { } @@ -4227,8 +4215,13 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( cmSourceFile const& source, std::string const& dir_max, - bool* hasSourceExtension, char const* customOutputExtension) + bool* hasSourceExtension, char const* customOutputExtension, + bool const* forceShortObjectName) { + bool useShortObjectNames = this->UseShortObjectNames(); + if (forceShortObjectName) { + useShortObjectNames = *forceShortObjectName; + } // This can return an absolute path in the case where source is // not relative to the current source or binary directoreis @@ -4246,7 +4239,7 @@ // Short object path policy selected, use as little info as necessary to // select an object name bool keptSourceExtension = true; - if (this->UseShortObjectNames()) { + if (useShortObjectNames) { objectName = this->GetShortObjectFileName(source); keptSourceExtension = false; }
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 4fa48fb..81b516b 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h
@@ -37,6 +37,7 @@ class cmLinkLineComputer; class cmLinkLineDeviceComputer; class cmMakefile; +struct cmObjectLocations; class cmRulePlaceholderExpander; class cmSourceFile; class cmState; @@ -473,7 +474,8 @@ std::string GetObjectFileNameWithoutTarget( cmSourceFile const& source, std::string const& dir_max, bool* hasSourceExtension = nullptr, - char const* customOutputExtension = nullptr); + char const* customOutputExtension = nullptr, + bool const* forceShortObjectName = nullptr); /** Fill out the static linker flags for the given target. */ void GetStaticLibraryFlags(std::string& flags, std::string const& config, @@ -524,7 +526,7 @@ std::string const& config); virtual void ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* gt = nullptr); bool IsWindowsShell() const;
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx index 2e38dc7..812f025 100644 --- a/Source/cmLocalGhsMultiGenerator.cxx +++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -5,9 +5,12 @@ #include <utility> #include <vector> +#include <cm/optional> + #include "cmGeneratorTarget.h" #include "cmGhsMultiTargetGenerator.h" #include "cmGlobalGenerator.h" +#include "cmObjectLocation.h" #include "cmSourceFile.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -41,7 +44,7 @@ } void cmLocalGhsMultiGenerator::ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* gt) { std::string dir_max = cmStrCat(gt->GetSupportDirectory(), '/'); @@ -63,17 +66,21 @@ // object name computation. for (auto& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectName = cmStrCat( + bool forceShortObjectName = true; + std::string shortObjectName = this->GetObjectFileNameWithoutTarget( + *sf, dir_max, nullptr, nullptr, &forceShortObjectName); + std::string longObjectName = cmStrCat( cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()), this->GlobalGenerator->GetLanguageOutputExtension(*sf)); - if (counts[cmSystemTools::LowerCase(objectName)] > 1) { + if (counts[cmSystemTools::LowerCase(longObjectName)] > 1) { const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf); - bool keptSourceExtension; - objectName = this->GetObjectFileNameWithoutTarget(*sf, dir_max, - &keptSourceExtension); - cmsys::SystemTools::ReplaceString(objectName, "/", "_"); + forceShortObjectName = false; + longObjectName = this->GetObjectFileNameWithoutTarget( + *sf, dir_max, nullptr, nullptr, &forceShortObjectName); + cmsys::SystemTools::ReplaceString(longObjectName, "/", "_"); } - si.second = objectName; + si.second.ShortLoc.emplace(shortObjectName); + si.second.LongLoc.Update(longObjectName); } }
diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h index 698ef39..ae80b2b 100644 --- a/Source/cmLocalGhsMultiGenerator.h +++ b/Source/cmLocalGhsMultiGenerator.h
@@ -10,6 +10,7 @@ class cmGeneratorTarget; class cmGlobalGenerator; class cmMakefile; +struct cmObjectLocations; class cmSourceFile; /** \class cmLocalGhsMultiGenerator @@ -34,6 +35,6 @@ cmGeneratorTarget const* target) const override; void ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* gt = nullptr) override; };
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx index 4ea3f1b..9d7a507 100644 --- a/Source/cmLocalVisualStudioGenerator.cxx +++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -39,7 +39,7 @@ } void cmLocalVisualStudioGenerator::ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* gt) { char const* custom_ext = gt->GetCustomObjectExtension(); @@ -73,25 +73,25 @@ for (auto& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectName; - if (gt->GetUseShortObjectNames()) { - objectName = this->GetShortObjectFileName(*sf); - } else { - objectName = - cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); - } + std::string shortObjectName = this->GetShortObjectFileName(*sf); + std::string longObjectName = + cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()); if (custom_ext) { - objectName += custom_ext; + shortObjectName += custom_ext; + longObjectName += custom_ext; } else { - objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf); + shortObjectName += + this->GlobalGenerator->GetLanguageOutputExtension(*sf); + longObjectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf); } - if (counts[cmSystemTools::LowerCase(objectName)] > 1) { + if (counts[cmSystemTools::LowerCase(longObjectName)] > 1) { const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf); bool keptSourceExtension; - objectName = this->GetObjectFileNameWithoutTarget( + longObjectName = this->GetObjectFileNameWithoutTarget( *sf, dir_max, &keptSourceExtension, custom_ext); } - si.second = objectName; + si.second.ShortLoc.emplace(shortObjectName); + si.second.LongLoc.Update(longObjectName); } }
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h index fdc15be..8c472c5 100644 --- a/Source/cmLocalVisualStudioGenerator.h +++ b/Source/cmLocalVisualStudioGenerator.h
@@ -10,6 +10,7 @@ #include "cmGlobalVisualStudioGenerator.h" #include "cmLocalGenerator.h" +#include "cmObjectLocation.h" #include "cmStateTypes.h" #include "cmVsProjectType.h" @@ -49,7 +50,7 @@ cmGeneratorTarget const*) const = 0; void ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* = nullptr) override; std::string GetObjectOutputRoot(
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx index 5bf0966..5d6a32f 100644 --- a/Source/cmLocalXCodeGenerator.cxx +++ b/Source/cmLocalXCodeGenerator.cxx
@@ -119,7 +119,7 @@ } void cmLocalXCodeGenerator::ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const*) { // Count the number of object files with each name. Warn about duplicate @@ -129,15 +129,17 @@ std::map<std::string, int> counts; for (auto& si : mapping) { cmSourceFile const* sf = si.first; - std::string objectName = cmStrCat( + std::string shortObjectName = this->GetShortObjectFileName(*sf); + std::string longObjectName = cmStrCat( cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()), ".o"); - std::string objectNameLower = cmSystemTools::LowerCase(objectName); - counts[objectNameLower] += 1; - if (2 == counts[objectNameLower]) { + std::string longObjectNameLower = cmSystemTools::LowerCase(longObjectName); + counts[longObjectNameLower] += 1; + if (2 == counts[longObjectNameLower]) { // TODO: emit warning about duplicate name? } - si.second = objectName; + si.second.ShortLoc.emplace(shortObjectName); + si.second.LongLoc.Update(longObjectName); } }
diff --git a/Source/cmLocalXCodeGenerator.h b/Source/cmLocalXCodeGenerator.h index 49a5e93..7b501fb 100644 --- a/Source/cmLocalXCodeGenerator.h +++ b/Source/cmLocalXCodeGenerator.h
@@ -9,6 +9,7 @@ #include <string> #include "cmLocalGenerator.h" +#include "cmObjectLocation.h" class cmGeneratorTarget; class cmGlobalGenerator; @@ -35,7 +36,7 @@ void Generate() override; void AddGeneratorSpecificInstallSetup(std::ostream& os) override; void ComputeObjectFilenames( - std::map<cmSourceFile const*, std::string>& mapping, + std::map<cmSourceFile const*, cmObjectLocations>& mapping, cmGeneratorTarget const* gt = nullptr) override; void AddXCConfigSources(cmGeneratorTarget* target) override;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 5ceb35e..ec0fdb7 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx
@@ -4238,18 +4238,19 @@ this->Makefile->FindPackageStack = this->Makefile->FindPackageStack.Push(cmFindPackageCall{ name, + cmPackageInformation(), this->Makefile->FindPackageStackNextIndex, }); this->Makefile->FindPackageStackNextIndex++; } -void cmFindPackageStackRAII::BindTop(cmFindPackageCall*& value) +void cmFindPackageStackRAII::BindTop(cmPackageInformation*& value) { if (this->Value) { *this->Value = nullptr; } this->Value = &value; - value = &this->Makefile->FindPackageStack.cmStack::Top(); + value = &this->Makefile->FindPackageStack.cmStack::Top().PackageInfo; } cmFindPackageStackRAII::~cmFindPackageStackRAII()
diff --git a/Source/cmObjectLocation.cxx b/Source/cmObjectLocation.cxx new file mode 100644 index 0000000..bb0c2ee --- /dev/null +++ b/Source/cmObjectLocation.cxx
@@ -0,0 +1,47 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file LICENSE.rst or https://cmake.org/licensing for details. */ + +#include "cmObjectLocation.h" + +void cmObjectLocation::Update(std::string path) +{ + this->Path = std::move(path); +} + +std::string const& cmObjectLocation::GetPath() const +{ + return this->Path; +} + +cm::string_view cmObjectLocation::GetDirectory() const +{ + auto const pos = this->Path.rfind('/'); + if (pos == std::string::npos) { + return {}; + } + return cm::string_view(this->Path.c_str(), pos); +} + +cm::string_view cmObjectLocation::GetName() const +{ + auto const pos = this->Path.rfind('/'); + if (pos == std::string::npos) { + return this->Path; + } + auto const nameStart = pos + 1; + return cm::string_view(this->Path.c_str() + nameStart, + this->Path.size() - nameStart); +} + +cmObjectLocation const& cmObjectLocations::GetLocation(UseShortPath use) const +{ + if (use == UseShortPath::Yes && this->ShortLoc) { + return *this->ShortLoc; + } + return this->LongLoc; +} + +std::string const& cmObjectLocations::GetPath(UseShortPath use) const +{ + return this->GetLocation(use).GetPath(); +}
diff --git a/Source/cmObjectLocation.h b/Source/cmObjectLocation.h new file mode 100644 index 0000000..2cf2564 --- /dev/null +++ b/Source/cmObjectLocation.h
@@ -0,0 +1,50 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file LICENSE.rst or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <string> +#include <utility> + +#include <cm/optional> +#include <cm/string_view> + +struct cmObjectLocation +{ +public: + cmObjectLocation() = default; + cmObjectLocation(std::string path) + : Path(std::move(path)) + { + } + + void Update(std::string path); + + // Get the path to the object under the common directory for the target's + // objects. + std::string const& GetPath() const; + // Get the directory of the object file under the common directory. + cm::string_view GetDirectory() const; + // Get the name of the object file. + cm::string_view GetName() const; + +private: + std::string Path; +}; + +struct cmObjectLocations +{ + cmObjectLocations() = default; + + cm::optional<cmObjectLocation> ShortLoc; + cmObjectLocation LongLoc; + + enum class UseShortPath + { + Yes, + No, + }; + cmObjectLocation const& GetLocation(UseShortPath use) const; + std::string const& GetPath(UseShortPath use) const; +};
diff --git a/Source/cmPkgConfigResolver.cxx b/Source/cmPkgConfigResolver.cxx index bd8b9b7..8be5f34 100644 --- a/Source/cmPkgConfigResolver.cxx +++ b/Source/cmPkgConfigResolver.cxx
@@ -56,6 +56,15 @@ return { &*begin, static_cast<std::size_t>(cur - begin) + 1 }; } +cm::string_view TrimFlag(cm::string_view flag) +{ + std::size_t trim_size = 2; + for (auto c = flag.rbegin(); c != flag.rend() && std::isspace(*c); ++c) { + ++trim_size; + } + return { flag.data() + 2, flag.size() - trim_size }; +} + } // namespace std::string cmPkgConfigVersionReq::string() const @@ -460,12 +469,10 @@ for (auto flag : flags) { if (flag.rfind("-I", 0) == 0) { - cm::string_view noprefix{ flag.data() + 2, flag.size() - 2 }; - - if (std::all_of(syspaths.begin(), syspaths.end(), - [&](std::string const& path) { - return noprefix.rfind(path, 0) == noprefix.npos; - })) { + cm::string_view trimmed = TrimFlag(flag); + if (std::all_of( + syspaths.begin(), syspaths.end(), + [&](std::string const& path) { return path != trimmed; })) { result.Includes.emplace_back(AppendAndTrim(result.Flagline, flag)); } @@ -486,12 +493,10 @@ for (auto flag : flags) { if (flag.rfind("-I", 0) == 0) { std::string reroot = Reroot(flag, "-I", sysroot); - cm::string_view noprefix{ reroot.data() + 2, reroot.size() - 2 }; - - if (std::all_of(syspaths.begin(), syspaths.end(), - [&](std::string const& path) { - return noprefix.rfind(path, 0) == noprefix.npos; - })) { + cm::string_view trimmed = TrimFlag(reroot); + if (std::all_of( + syspaths.begin(), syspaths.end(), + [&](std::string const& path) { return path != trimmed; })) { result.Includes.emplace_back(AppendAndTrim(result.Flagline, reroot)); } @@ -548,12 +553,10 @@ for (auto flag : flags) { if (flag.rfind("-L", 0) == 0) { - cm::string_view noprefix{ flag.data() + 2, flag.size() - 2 }; - - if (std::all_of(syspaths.begin(), syspaths.end(), - [&](std::string const& path) { - return noprefix.rfind(path, 0) == noprefix.npos; - })) { + cm::string_view trimmed = TrimFlag(flag); + if (std::all_of( + syspaths.begin(), syspaths.end(), + [&](std::string const& path) { return path != trimmed; })) { result.LibDirs.emplace_back(AppendAndTrim(result.Flagline, flag)); } @@ -576,12 +579,10 @@ for (auto flag : flags) { if (flag.rfind("-L", 0) == 0) { std::string reroot = Reroot(flag, "-L", sysroot); - cm::string_view noprefix{ reroot.data() + 2, reroot.size() - 2 }; - - if (std::all_of(syspaths.begin(), syspaths.end(), - [&](std::string const& path) { - return noprefix.rfind(path, 0) == noprefix.npos; - })) { + cm::string_view trimmed = TrimFlag(reroot); + if (std::all_of( + syspaths.begin(), syspaths.end(), + [&](std::string const& path) { return path != trimmed; })) { result.LibDirs.emplace_back(AppendAndTrim(result.Flagline, reroot)); }
diff --git a/Source/cmStdIoTerminal.cxx b/Source/cmStdIoTerminal.cxx index 5baff5e..428f7c7 100644 --- a/Source/cmStdIoTerminal.cxx +++ b/Source/cmStdIoTerminal.cxx
@@ -141,9 +141,13 @@ f(os.IOS()); break; case TermKind::VT100: - SetVT100Attrs(os.IOS(), attrs); - f(os.IOS()); - SetVT100Attrs(os.IOS(), TermAttr::Normal); + if (!attrs.empty()) { + SetVT100Attrs(os.IOS(), attrs); + f(os.IOS()); + SetVT100Attrs(os.IOS(), TermAttr::Normal); + } else { + f(os.IOS()); + } break; #ifdef _WIN32 case TermKind::Console: {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index cbf8b90..4d35e5f 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx
@@ -419,6 +419,7 @@ { "BUILD_WITH_INSTALL_NAME_DIR"_s, IC::CanCompileSources }, // ---- Install { "INSTALL_NAME_DIR"_s, IC::CanCompileSources }, + { "INSTALL_OBJECT_NAME_STRATEGY"_s, IC::CanCompileSources }, { "INSTALL_REMOVE_ENVIRONMENT_RPATH"_s, IC::CanCompileSources }, { "INSTALL_RPATH"_s, ""_s, IC::CanCompileSources }, { "INSTALL_RPATH_USE_LINK_PATH"_s, "OFF"_s, IC::CanCompileSources },
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 9e38384..805bdab 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx
@@ -1923,7 +1923,7 @@ bool enabled = true; static cm::StdIo::TermAttrSet const noAttrs; - cm::StdIo::TermAttrSet attrs = cm::StdIo::TermAttr::Normal; + cm::StdIo::TermAttrSet attrs; bool newline = true; std::string progressDir; for (auto const& arg : cmMakeRange(args).advance(2)) { @@ -1959,6 +1959,9 @@ } else if (arg == "--white") { attrs = cm::StdIo::TermAttr::ForegroundWhite; } else if (arg == "--bold") { + if (attrs.empty()) { + attrs = cm::StdIo::TermAttr::Normal; + } attrs |= cm::StdIo::TermAttr::ForegroundBold; } else if (arg == "--no-newline") { newline = false;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2d40fd0..fed2c80 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt
@@ -36,6 +36,8 @@ set(TEST_HOME "${CMake_BINARY_DIR}/Tests/CMakeFiles/TestHome") set(TEST_CONFIG_ENV_CODE "# Isolate tests from user-wide configuration. set(ENV{CMAKE_CONFIG_DIR} \"${TEST_HOME}/.config/cmake\")\n") +set(TEST_INSTRUMENTATION_ENV_CODE "# Isolate tests from CTEST_USE_INSTRUMENTATION var +unset(ENV{CTEST_USE_INSTRUMENTATION})\n") file(MAKE_DIRECTORY "${TEST_HOME}/.config/cmake") # Fake a user home directory to avoid polluting the real one. @@ -593,11 +595,11 @@ if(NOT DEFINED CMake_TEST_Qt4) set(CMake_TEST_Qt4 1) endif() - if(CMake_TEST_Qt4 AND NOT QT4_FOUND) + if(CMake_TEST_Qt4 AND NOT Qt4_FOUND) find_package(Qt4 QUIET) endif() - if(CMake_TEST_Qt4 AND QT4_FOUND) + if(CMake_TEST_Qt4 AND Qt4_FOUND) # test whether the Qt4 which has been found works, on some machines # which run nightly builds there were errors like "wrong file format" # for libQtCore.so. So first check it works, and only if it does add
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt index 566282e..c2b510e 100644 --- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt +++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -44,7 +44,7 @@ endforeach() # Qt4 is not present, so we can check Qt3 -if (NOT QT4_FOUND) +if (NOT Qt4_FOUND) set(DESIRED_QT_VERSION 3) foreach(FIND_MODULE ${NO_QT4_MODULES} "Qt") do_find(${FIND_MODULE}) @@ -97,7 +97,7 @@ CUPS CURL EXPAT FREETYPE - GETTEXT GIT + GETTEXT GIT GNUTLS HG HSPELL ICOTOOL JASPER @@ -115,15 +115,15 @@ ALSA Armadillo BISON Boost BZip2 BZIP2 CUDA Cups - Doxygen DOXYGEN + DevIL Doxygen DOXYGEN EXPAT FLEX Freetype - Gettext GIF GTK2 + Gettext GIF GnuTLS GNUTLS GTK2 HDF5 Jasper JPEG LibArchive LibLZMA LIBLZMA LibXml2 LibXslt LTTngUST OpenSceneGraph OPENSCENEGRAPH OpenSSL OPENSSL - PNG PostgreSQL Protobuf + Perl PerlLibs PNG PostgreSQL Protobuf Ruby RUBY SDL SWIG TIFF @@ -133,4 +133,5 @@ endforeach() check_version_string(PYTHONINTERP PYTHON_VERSION_STRING) +check_version_string(SUBVERSION Subversion_VERSION) check_version_string(SUBVERSION Subversion_VERSION_SVN)
diff --git a/Tests/EnforceConfig.cmake.in b/Tests/EnforceConfig.cmake.in index 78dea00..6d634d6 100644 --- a/Tests/EnforceConfig.cmake.in +++ b/Tests/EnforceConfig.cmake.in
@@ -45,3 +45,4 @@ @TEST_CONFIG_ENV_CODE@ @TEST_HOME_ENV_CODE@ @TEST_WARN_VS_CODE@ +@TEST_INSTRUMENTATION_ENV_CODE@
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt index 1208152..c6f0fa3 100644 --- a/Tests/ExternalProject/CMakeLists.txt +++ b/Tests/ExternalProject/CMakeLists.txt
@@ -17,7 +17,7 @@ if(NOT DEFINED EP_TEST_SVN OR EP_TEST_SVN) find_package(Subversion) - if(Subversion_FOUND AND Subversion_VERSION_SVN VERSION_LESS 1.2) + if(Subversion_FOUND AND Subversion_VERSION VERSION_LESS 1.2) message(STATUS "No ExternalProject svn tests with svn client less than version 1.2") set(Subversion_FOUND 0) endif()
diff --git a/Tests/FindDevIL/Test/CMakeLists.txt b/Tests/FindDevIL/Test/CMakeLists.txt index 2b72cf8..f82b7fe 100644 --- a/Tests/FindDevIL/Test/CMakeLists.txt +++ b/Tests/FindDevIL/Test/CMakeLists.txt
@@ -4,19 +4,21 @@ find_package(DevIL) -#FIXME: check version too. -# add_definitions( -# -DCMAKE_EXPECTED_SDL_VERSION_MAJOR=${SDL_VERSION_MAJOR} -# -DCMAKE_EXPECTED_SDL_VERSION_MINOR=${SDL_VERSION_MINOR} -# -DCMAKE_EXPECTED_SDL_VERSION_PATCH=${SDL_VERSION_PATCH}) - add_executable(test_devil_var main.c) target_include_directories(test_devil_var PRIVATE ${IL_INCLUDE_DIRS}) target_link_libraries(test_devil_var PRIVATE ${IL_LIBRARIES}) +target_compile_definitions( + test_devil_var + PRIVATE CMAKE_EXPECTED_DEVIL_VERSION="${DevIL_VERSION}" +) add_test(NAME test_devil_var COMMAND test_devil_var) add_executable(test_devil_il_tgt main.c) target_link_libraries(test_devil_il_tgt DevIL::IL) +target_compile_definitions( + test_devil_il_tgt + PRIVATE CMAKE_EXPECTED_DEVIL_VERSION="${DevIL_VERSION}" +) add_test(NAME test_devil_il_tgt COMMAND test_devil_il_tgt) add_executable(test_devil_ilu_tgt main_ilu.c)
diff --git a/Tests/FindDevIL/Test/main.c b/Tests/FindDevIL/Test/main.c index dfb2f63..f7b2c8b 100644 --- a/Tests/FindDevIL/Test/main.c +++ b/Tests/FindDevIL/Test/main.c
@@ -1,4 +1,6 @@ #include <IL/il.h> +#include <stdio.h> +#include <string.h> int main(void) { @@ -6,5 +8,16 @@ ilInit(); ilShutDown(); - return 0; + + int version = IL_VERSION; + int major = version / 100; + int minor = version / 10 % 10; + int patch = version % 10; + char version_string[100]; + snprintf(version_string, sizeof(version_string), "%d.%d.%d", major, minor, + patch); + + printf("Found DevIL version %s, expected version %s\n", version_string, + CMAKE_EXPECTED_DEVIL_VERSION); + return strcmp(version_string, CMAKE_EXPECTED_DEVIL_VERSION); }
diff --git a/Tests/FindGnuTLS/Test/CMakeLists.txt b/Tests/FindGnuTLS/Test/CMakeLists.txt index 2a01298..b0e19e3 100644 --- a/Tests/FindGnuTLS/Test/CMakeLists.txt +++ b/Tests/FindGnuTLS/Test/CMakeLists.txt
@@ -4,7 +4,7 @@ find_package(GnuTLS REQUIRED) -add_definitions(-DCMAKE_EXPECTED_GNUTLS_VERSION="${GNUTLS_VERSION}") +add_definitions(-DCMAKE_EXPECTED_GNUTLS_VERSION="${GnuTLS_VERSION}") add_executable(test_tgt main.c) target_link_libraries(test_tgt GnuTLS::GnuTLS)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 7aeb192..4342434 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt
@@ -618,7 +618,7 @@ if(NOT CMAKE_GENERATOR MATCHES "Visual Studio") add_RunCMake_test(VisibilityPreset) endif() -if (QT4_FOUND) +if (Qt4_FOUND) set(CompatibleInterface_ARGS -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) endif() add_RunCMake_test(CompatibleInterface) @@ -728,6 +728,7 @@ if(DEFINED CMake_TEST_NO_WRITE_ONLY_DIR) list(APPEND if_ARGS -DCMake_TEST_NO_WRITE_ONLY_DIR=${CMake_TEST_NO_WRITE_ONLY_DIR}) endif() +add_RunCMake_test(INSTALL_OBJECT_NAME_STRATEGY) add_RunCMake_test(if -DMSYS=${MSYS}) add_RunCMake_test(include) add_RunCMake_test(include_directories) @@ -871,10 +872,10 @@ if(CMake_TEST_Qt5) find_package(Qt5Core QUIET) endif() -if (CMake_TEST_Qt4 AND CMake_TEST_Qt5 AND QT4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0) +if (CMake_TEST_Qt4 AND CMake_TEST_Qt5 AND Qt4_FOUND AND Qt5Core_FOUND AND NOT Qt5Core_VERSION VERSION_LESS 5.1.0) add_RunCMake_test(IncompatibleQt) endif() -if (CMake_TEST_Qt4 AND QT4_FOUND) +if (CMake_TEST_Qt4 AND Qt4_FOUND) add_RunCMake_test(ObsoleteQtMacros -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) endif()
diff --git a/Tests/RunCMake/ExportPackageInfo/DependencyVersionCMake-check.cmake b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCMake-check.cmake new file mode 100644 index 0000000..e4822b7 --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCMake-check.cmake
@@ -0,0 +1,15 @@ +include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake) + +set(out_dir "${RunCMake_BINARY_DIR}/DependencyVersionCMake-build") + +file(READ "${out_dir}/foo.cps" content) +expect_value("${content}" "foo" "name") +expect_array("${content}" 1 "requires" "bar" "components") +expect_value("${content}" "bar" "requires" "bar" "components" 0) +expect_value("${content}" "1.3.5" "requires" "bar" "version") +expect_array("${content}" 1 "requires" "bar" "hints") +expect_value("${content}" "${CMAKE_CURRENT_LIST_DIR}/config" "requires" "bar" "hints" 0) + +string(JSON component GET "${content}" "components" "foo") +expect_array("${component}" 1 "requires") +expect_value("${component}" "bar:bar" "requires" 0)
diff --git a/Tests/RunCMake/ExportPackageInfo/DependencyVersionCMake.cmake b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCMake.cmake new file mode 100644 index 0000000..e82a16e --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCMake.cmake
@@ -0,0 +1,11 @@ +find_package( + bar 1.3.4 REQUIRED CONFIG + NO_DEFAULT_PATH + PATHS ${CMAKE_CURRENT_LIST_DIR}/config +) + +add_library(foo INTERFACE) +target_link_libraries(foo INTERFACE bar::bar) + +install(TARGETS foo EXPORT foo DESTINATION .) +export(EXPORT foo PACKAGE_INFO foo)
diff --git a/Tests/RunCMake/ExportPackageInfo/DependencyVersionCps-check.cmake b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCps-check.cmake new file mode 100644 index 0000000..0b84ec1 --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCps-check.cmake
@@ -0,0 +1,15 @@ +include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake) + +set(out_dir "${RunCMake_BINARY_DIR}/DependencyVersionCps-build/") + +file(READ "${out_dir}/foo.cps" content) +expect_value("${content}" "foo" "name") +expect_array("${content}" 1 "requires" "baz" "components") +expect_value("${content}" "baz" "requires" "baz" "components" 0) +expect_value("${content}" "1.3.5" "requires" "baz" "version") +expect_array("${content}" 1 "requires" "baz" "hints") +expect_value("${content}" "${CMAKE_CURRENT_LIST_DIR}/cps" "requires" "baz" "hints" 0) + +string(JSON component GET "${content}" "components" "foo") +expect_array("${component}" 1 "requires") +expect_value("${component}" "baz:baz" "requires" 0)
diff --git a/Tests/RunCMake/ExportPackageInfo/DependencyVersionCps.cmake b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCps.cmake new file mode 100644 index 0000000..97cf54f --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/DependencyVersionCps.cmake
@@ -0,0 +1,11 @@ +find_package( + baz 1.3.4 REQUIRED + NO_DEFAULT_PATH + PATHS ${CMAKE_CURRENT_LIST_DIR} +) + +add_library(foo INTERFACE) +target_link_libraries(foo INTERFACE baz::baz) + +install(TARGETS foo EXPORT foo DESTINATION .) +export(EXPORT foo PACKAGE_INFO foo)
diff --git a/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake index c505f28..45c4397 100644 --- a/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake
@@ -8,6 +8,7 @@ set(RunCMake_TEST_OPTIONS -Wno-dev "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=b80be207-778e-46ba-8080-b23bba22639e" + "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" ) # Test incorrect usage @@ -43,3 +44,5 @@ run_cmake(Config) run_cmake(EmptyConfig) run_cmake(FileSetHeaders) +run_cmake(DependencyVersionCMake) +run_cmake(DependencyVersionCps)
diff --git a/Tests/RunCMake/ExportPackageInfo/config/bar-config-version.cmake b/Tests/RunCMake/ExportPackageInfo/config/bar-config-version.cmake new file mode 100644 index 0000000..ff683d6 --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/config/bar-config-version.cmake
@@ -0,0 +1,29 @@ +set(PACKAGE_VERSION "1.3.5") + +if (PACKAGE_FIND_VERSION_RANGE) + # Check for a version range + if (PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_RANGE_MIN) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + else () + if (PACKAGE_FIND_VERSION_RANGE_MAX) + if (PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_RANGE_MAX) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + else () + set(PACKAGE_VERSION_COMPATIBLE TRUE) + endif () + else () + set(PACKAGE_VERSION_COMPATIBLE TRUE) + endif () + endif () + +elseif (PACKAGE_FIND_VERSION) + # Check for a specific version or minimum version + if (PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + else () + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if (PACKAGE_VERSION VERSION_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif () + endif () +endif ()
diff --git a/Tests/RunCMake/ExportPackageInfo/config/bar-config.cmake b/Tests/RunCMake/ExportPackageInfo/config/bar-config.cmake new file mode 100644 index 0000000..d17ed84 --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/config/bar-config.cmake
@@ -0,0 +1 @@ +add_library(bar::bar INTERFACE IMPORTED)
diff --git a/Tests/RunCMake/ExportPackageInfo/cps/baz.cps b/Tests/RunCMake/ExportPackageInfo/cps/baz.cps new file mode 100644 index 0000000..6cf1042 --- /dev/null +++ b/Tests/RunCMake/ExportPackageInfo/cps/baz.cps
@@ -0,0 +1,14 @@ +{ + "components" : + { + "baz" : + { + "type" : "interface" + } + }, + "cps_path" : "@prefix@/cps", + "cps_version" : "0.13.0", + "compat_version": "1.0.0", + "name" : "baz", + "version": "1.3.5" +}
diff --git a/Tests/RunCMake/FindLua/FindLuaTest.cmake b/Tests/RunCMake/FindLua/FindLuaTest.cmake index 610d544..be5e3ab 100644 --- a/Tests/RunCMake/FindLua/FindLuaTest.cmake +++ b/Tests/RunCMake/FindLua/FindLuaTest.cmake
@@ -21,8 +21,11 @@ if(NOT "${LUA_INCLUDE_DIR}" STREQUAL "${path}") message(FATAL_ERROR "LUA_INCLUDE_PATH != path: '${LUA_INCLUDE_DIR}' != '${path}'") endif() - if(NOT LUA_VERSION_STRING MATCHES "^${version}\.[0-9]$") - message(FATAL_ERROR "Wrong versionfound in '${LUA_INCLUDE_DIR}': ${LUA_VERSION_STRING} != ${version}") + if(NOT Lua_VERSION MATCHES "^${version}\.[0-9]$") + message(FATAL_ERROR "Wrong version found in '${LUA_INCLUDE_DIR}': ${Lua_VERSION} != ${version}") + endif() + if(NOT LUA_VERSION_STRING STREQUAL Lua_VERSION) + message(FATAL_ERROR "LUA_VERSION_STRING != Lua_VERSION in '${LUA_INCLUDE_DIR}': ${LUA_VERSION_STRING} != ${Lua_VERSION}") endif() endfunction()
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/CMakeLists.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/CMakeLists.txt new file mode 100644 index 0000000..c89e908 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/CMakeLists.txt
@@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(${RunCMake_TEST} C) +include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Common.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Common.cmake new file mode 100644 index 0000000..0a538ba --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Common.cmake
@@ -0,0 +1,3 @@ +add_library(objlib OBJECT test.c subdir/inner_test.c) +install(TARGETS objlib EXPORT exp OBJECTS DESTINATION "lib/objlib") +install(EXPORT exp DESTINATION lib/cmake/IONS FILE ions-config.cmake NAMESPACE IONS::)
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-Default.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-Default.cmake new file mode 100644 index 0000000..57f13bb --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-Default.cmake
@@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-FULL.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-FULL.cmake new file mode 100644 index 0000000..57f13bb --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-FULL.cmake
@@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-SHORT.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-SHORT.cmake new file mode 100644 index 0000000..57f13bb --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume-SHORT.cmake
@@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/Consume.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume.cmake new file mode 100644 index 0000000..82192e0 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Consume.cmake
@@ -0,0 +1,7 @@ +find_package(IONS CONFIG REQUIRED) + +add_executable(main main.c) +target_link_libraries(main PRIVATE IONS::objlib) + +enable_testing() +add_test(NAME run COMMAND main)
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Default-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Default-install-check.cmake new file mode 100644 index 0000000..418557e --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Default-install-check.cmake
@@ -0,0 +1,2 @@ +# The default behavior is `FULL`. +include("${CMAKE_CURRENT_LIST_DIR}/FULL-install-check.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Default.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Default.cmake new file mode 100644 index 0000000..f635ae2 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Default.cmake
@@ -0,0 +1 @@ +include("${CMAKE_CURRENT_SOURCE_DIR}/Common.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/FULL-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/FULL-install-check.cmake new file mode 100644 index 0000000..4fcc007 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/FULL-install-check.cmake
@@ -0,0 +1,8 @@ +set(ext_suffix ".c") +set(subdir "subdir/") +if (RunCMake_GENERATOR MATCHES "(Visual Studio|Xcode)") + set(ext_suffix "") + set(subdir "") +endif () +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/test${ext_suffix}${CMAKE_C_OUTPUT_EXTENSION}") +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/${subdir}inner_test${ext_suffix}${CMAKE_C_OUTPUT_EXTENSION}")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/FULL.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/FULL.cmake new file mode 100644 index 0000000..d074526 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/FULL.cmake
@@ -0,0 +1,3 @@ +set(CMAKE_INSTALL_OBJECT_NAME_STRATEGY FULL) + +include("${CMAKE_CURRENT_SOURCE_DIR}/Common.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID-result.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID-result.txt
@@ -0,0 +1 @@ +1
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID-stderr.txt b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID-stderr.txt new file mode 100644 index 0000000..0ad494d --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID-stderr.txt
@@ -0,0 +1,6 @@ +CMake Error in CMakeLists.txt: + Property INSTALL_OBJECT_NAME_STRATEGY of target "objlib" set to the + unsupported strategy INVALID + + +CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID.cmake new file mode 100644 index 0000000..d7ae724 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/INVALID.cmake
@@ -0,0 +1,3 @@ +set(CMAKE_INSTALL_OBJECT_NAME_STRATEGY INVALID) + +include("${CMAKE_CURRENT_SOURCE_DIR}/Common.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Inspect.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Inspect.cmake new file mode 100644 index 0000000..ec74ed8 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/Inspect.cmake
@@ -0,0 +1,10 @@ +enable_language(C) + +set(info "") + +# Forward information about the C++ compile features. +string(APPEND info "\ +set(CMAKE_C_OUTPUT_EXTENSION \"${CMAKE_C_OUTPUT_EXTENSION}\") +") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/RunCMakeTest.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/RunCMakeTest.cmake new file mode 100644 index 0000000..67e030b --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/RunCMakeTest.cmake
@@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.16) + +include(RunCMake) + +# This test does installation of `OBJECT` libraries which does not work with +# multi-arch compilation under Xcode. +if (RunCMake_GENERATOR STREQUAL "Xcode" AND "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]") + return () +endif () + +function(run_install_test case) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build) + set(RunCMake_TEST_NO_CLEAN 1) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE:STRING=Debug "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/fake_install") + file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}") + run_cmake(${case}) + run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug) + set(prefix "${RunCMake_TEST_BINARY_DIR}/real_install") + run_cmake_command(${case}-install ${CMAKE_COMMAND} --install . --config Debug --prefix "${prefix}") + + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Consume-${case}-build) + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE:STRING=Debug "-DCMAKE_PREFIX_PATH:PATH=${prefix}") + run_cmake(Consume-${case} "-DCMAKE_PREFIX_PATH=${prefix}") + run_cmake_command(Consume-${case}-build ${CMAKE_COMMAND} --build . --config Debug) + run_cmake_command(Consume-${case}-test ${CMAKE_CTEST_COMMAND} -C Debug) +endfunction() + +function (check_installed_object path) + if (NOT EXISTS "${path}") + list(APPEND RunCMake_TEST_FAILED + "Could not find installed object at '${path}'") + endif () + set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE) +endfunction () + +run_cmake(Inspect) +include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake") + +run_install_test(Default) +run_install_test(FULL) +if (RunCMake_GENERATOR MATCHES "(Ninja|Makefiles|Visual Studio)") + run_install_test(SHORT) +endif () +run_cmake(INVALID)
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/SHORT-install-check.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/SHORT-install-check.cmake new file mode 100644 index 0000000..15b77d2 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/SHORT-install-check.cmake
@@ -0,0 +1,2 @@ +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/f3796fea${CMAKE_C_OUTPUT_EXTENSION}") +check_installed_object("${RunCMake_TEST_BINARY_DIR}/real_install/lib/objlib/objects-Debug/objlib/82237782${CMAKE_C_OUTPUT_EXTENSION}")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/SHORT.cmake b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/SHORT.cmake new file mode 100644 index 0000000..b21fb48 --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/SHORT.cmake
@@ -0,0 +1,3 @@ +set(CMAKE_INSTALL_OBJECT_NAME_STRATEGY SHORT) + +include("${CMAKE_CURRENT_SOURCE_DIR}/Common.cmake")
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/main.c b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/main.c new file mode 100644 index 0000000..7955cce --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/main.c
@@ -0,0 +1,7 @@ +int test(int a); +int inner(int a); + +int main(void) +{ + return test(0) + inner(0); +}
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/subdir/inner_test.c b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/subdir/inner_test.c new file mode 100644 index 0000000..32c726d --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/subdir/inner_test.c
@@ -0,0 +1,4 @@ +int inner(int a) +{ + return a; +}
diff --git a/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/test.c b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/test.c new file mode 100644 index 0000000..6fa39df --- /dev/null +++ b/Tests/RunCMake/INSTALL_OBJECT_NAME_STRATEGY/test.c
@@ -0,0 +1,4 @@ +int test(int a) +{ + return a; +}
diff --git a/Tests/RunCMake/InstallPackageInfo/DependencyVersionCMake-check.cmake b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCMake-check.cmake new file mode 100644 index 0000000..3bca2c9 --- /dev/null +++ b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCMake-check.cmake
@@ -0,0 +1,15 @@ +include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake) + +set(out_dir "${RunCMake_BINARY_DIR}/DependencyVersionCMake-build/CMakeFiles/Export/5058f1af8388633f609cadb75a75dc9d") + +file(READ "${out_dir}/foo.cps" content) +expect_value("${content}" "foo" "name") +expect_array("${content}" 1 "requires" "bar" "components") +expect_value("${content}" "bar" "requires" "bar" "components" 0) +expect_value("${content}" "1.3.5" "requires" "bar" "version") +expect_array("${content}" 1 "requires" "bar" "hints") +expect_value("${content}" "${CMAKE_CURRENT_LIST_DIR}/config" "requires" "bar" "hints" 0) + +string(JSON component GET "${content}" "components" "foo") +expect_array("${component}" 1 "requires") +expect_value("${component}" "bar:bar" "requires" 0)
diff --git a/Tests/RunCMake/InstallPackageInfo/DependencyVersionCMake.cmake b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCMake.cmake new file mode 100644 index 0000000..28f129f --- /dev/null +++ b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCMake.cmake
@@ -0,0 +1,11 @@ +find_package( + bar 1.3.4 REQUIRED CONFIG + NO_DEFAULT_PATH + PATHS ${CMAKE_CURRENT_LIST_DIR}/config +) + +add_library(foo INTERFACE) +target_link_libraries(foo INTERFACE bar::bar) + +install(TARGETS foo EXPORT foo) +install(PACKAGE_INFO foo EXPORT foo DESTINATION .)
diff --git a/Tests/RunCMake/InstallPackageInfo/DependencyVersionCps-check.cmake b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCps-check.cmake new file mode 100644 index 0000000..95c01cd --- /dev/null +++ b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCps-check.cmake
@@ -0,0 +1,15 @@ +include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake) + +set(out_dir "${RunCMake_BINARY_DIR}/DependencyVersionCps-build/CMakeFiles/Export/5058f1af8388633f609cadb75a75dc9d") + +file(READ "${out_dir}/foo.cps" content) +expect_value("${content}" "foo" "name") +expect_array("${content}" 1 "requires" "baz" "components") +expect_value("${content}" "baz" "requires" "baz" "components" 0) +expect_value("${content}" "1.3.5" "requires" "baz" "version") +expect_array("${content}" 1 "requires" "baz" "hints") +expect_value("${content}" "${CMAKE_CURRENT_LIST_DIR}/cps" "requires" "baz" "hints" 0) + +string(JSON component GET "${content}" "components" "foo") +expect_array("${component}" 1 "requires") +expect_value("${component}" "baz:baz" "requires" 0)
diff --git a/Tests/RunCMake/InstallPackageInfo/DependencyVersionCps.cmake b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCps.cmake new file mode 100644 index 0000000..1453d52 --- /dev/null +++ b/Tests/RunCMake/InstallPackageInfo/DependencyVersionCps.cmake
@@ -0,0 +1,11 @@ +find_package( + baz 1.3.4 REQUIRED + NO_DEFAULT_PATH + PATHS ${CMAKE_CURRENT_LIST_DIR} +) + +add_library(foo INTERFACE) +target_link_libraries(foo INTERFACE baz::baz) + +install(TARGETS foo EXPORT foo) +install(PACKAGE_INFO foo EXPORT foo DESTINATION .)
diff --git a/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake index 67e43ec..82c0d90 100644 --- a/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake +++ b/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake
@@ -8,6 +8,7 @@ set(RunCMake_TEST_OPTIONS -Wno-dev "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=b80be207-778e-46ba-8080-b23bba22639e" + "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261" ) function(run_cmake_install test) @@ -51,4 +52,6 @@ run_cmake(Config) run_cmake(EmptyConfig) run_cmake(FileSetHeaders) +run_cmake(DependencyVersionCMake) +run_cmake(DependencyVersionCps) run_cmake_install(Destination)
diff --git a/Tests/RunCMake/InstallPackageInfo/config/bar-config-version.cmake b/Tests/RunCMake/InstallPackageInfo/config/bar-config-version.cmake new file mode 100644 index 0000000..ff683d6 --- /dev/null +++ b/Tests/RunCMake/InstallPackageInfo/config/bar-config-version.cmake
@@ -0,0 +1,29 @@ +set(PACKAGE_VERSION "1.3.5") + +if (PACKAGE_FIND_VERSION_RANGE) + # Check for a version range + if (PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_RANGE_MIN) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + else () + if (PACKAGE_FIND_VERSION_RANGE_MAX) + if (PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_RANGE_MAX) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + else () + set(PACKAGE_VERSION_COMPATIBLE TRUE) + endif () + else () + set(PACKAGE_VERSION_COMPATIBLE TRUE) + endif () + endif () + +elseif (PACKAGE_FIND_VERSION) + # Check for a specific version or minimum version + if (PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_COMPATIBLE FALSE) + else () + set(PACKAGE_VERSION_COMPATIBLE TRUE) + if (PACKAGE_VERSION VERSION_EQUAL PACKAGE_FIND_VERSION) + set(PACKAGE_VERSION_EXACT TRUE) + endif () + endif () +endif ()
diff --git a/Tests/RunCMake/InstallPackageInfo/config/bar-config.cmake b/Tests/RunCMake/InstallPackageInfo/config/bar-config.cmake new file mode 100644 index 0000000..d17ed84 --- /dev/null +++ b/Tests/RunCMake/InstallPackageInfo/config/bar-config.cmake
@@ -0,0 +1 @@ +add_library(bar::bar INTERFACE IMPORTED)
diff --git a/Tests/RunCMake/InstallPackageInfo/cps/baz.cps b/Tests/RunCMake/InstallPackageInfo/cps/baz.cps new file mode 100644 index 0000000..6cf1042 --- /dev/null +++ b/Tests/RunCMake/InstallPackageInfo/cps/baz.cps
@@ -0,0 +1,14 @@ +{ + "components" : + { + "baz" : + { + "type" : "interface" + } + }, + "cps_path" : "@prefix@/cps", + "cps_version" : "0.13.0", + "compat_version": "1.0.0", + "name" : "baz", + "version": "1.3.5" +}
diff --git a/Tests/RunCMake/cmake_pkg_config/ExtractEnv-stderr.txt b/Tests/RunCMake/cmake_pkg_config/ExtractEnv-stderr.txt index 67713c9..e1c98f3 100644 --- a/Tests/RunCMake/cmake_pkg_config/ExtractEnv-stderr.txt +++ b/Tests/RunCMake/cmake_pkg_config/ExtractEnv-stderr.txt
@@ -1,5 +1,5 @@ -Includes: -I/Alpha;-I/Gamma -LibDirs: -L/Delta;-L/Zeta +Includes: -I/Alpha;-I/Alpha/sub;-I/Gamma +LibDirs: -L/Delta;-L/Delta/sub;-L/Zeta Cflags: QuxInstalled PC_LIB_DIRS: Alpha;Beta PC_PATH: [^
diff --git a/Tests/RunCMake/cmake_pkg_config/ExtractMangle-stderr.txt b/Tests/RunCMake/cmake_pkg_config/ExtractMangle-stderr.txt index 75557fc..04a1bc0 100644 --- a/Tests/RunCMake/cmake_pkg_config/ExtractMangle-stderr.txt +++ b/Tests/RunCMake/cmake_pkg_config/ExtractMangle-stderr.txt
@@ -1,8 +1,8 @@ -Cflags: Beta -I/Gamma -Includes: -I/Gamma -Libs: Epsilon -L/Zeta -LibDirs: -L/Zeta -Cflags: -I/Alpha Beta -I/Gamma -Includes: -I/Alpha;-I/Gamma -Libs: -L/Delta Epsilon -L/Zeta -LibDirs: -L/Delta;-L/Zeta +Cflags: -I/Alpha/sub Beta -I/Gamma +Includes: -I/Alpha/sub;-I/Gamma +Libs: -L/Delta/sub Epsilon -L/Zeta +LibDirs: -L/Delta/sub;-L/Zeta +Cflags: -I/Alpha -I/Alpha/sub Beta -I/Gamma +Includes: -I/Alpha;-I/Alpha/sub;-I/Gamma +Libs: -L/Delta -L/Delta/sub Epsilon -L/Zeta +LibDirs: -L/Delta;-L/Delta/sub;-L/Zeta
diff --git a/Tests/RunCMake/cmake_pkg_config/ExtractReroot-stderr.txt b/Tests/RunCMake/cmake_pkg_config/ExtractReroot-stderr.txt index ab524d4..d4bab07 100644 --- a/Tests/RunCMake/cmake_pkg_config/ExtractReroot-stderr.txt +++ b/Tests/RunCMake/cmake_pkg_config/ExtractReroot-stderr.txt
@@ -1,4 +1,4 @@ -Cflags: -I/NewRoot/Alpha Beta -I/NewRoot/Gamma -Includes: -I/NewRoot/Alpha;-I/NewRoot/Gamma -Libs: -L/NewRoot/Delta Epsilon -L/NewRoot/Zeta -LibDirs: -L/NewRoot/Delta;-L/NewRoot/Zeta +Cflags: -I/NewRoot/Alpha -I/NewRoot/Alpha/sub Beta -I/NewRoot/Gamma +Includes: -I/NewRoot/Alpha;-I/NewRoot/Alpha/sub;-I/NewRoot/Gamma +Libs: -L/NewRoot/Delta -L/NewRoot/Delta/sub Epsilon -L/NewRoot/Zeta +LibDirs: -L/NewRoot/Delta;-L/NewRoot/Delta/sub;-L/NewRoot/Zeta
diff --git a/Tests/RunCMake/cmake_pkg_config/ImportSystem-check.cmake b/Tests/RunCMake/cmake_pkg_config/ImportSystem-check.cmake new file mode 100644 index 0000000..a6f4eb3 --- /dev/null +++ b/Tests/RunCMake/cmake_pkg_config/ImportSystem-check.cmake
@@ -0,0 +1,11 @@ +set(expected +"Include Directories: /TestDirectories/Include +Link Directories: /TestDirectories/Library +" +) + +file(READ "${RunCMake_TEST_BINARY_DIR}/import-system.txt" actual) + +if(NOT(expected STREQUAL actual)) + set(RunCMake_TEST_FAILED "cmake_pkg_config import-system.txt does not match expected:\n${actual}") +endif()
diff --git a/Tests/RunCMake/cmake_pkg_config/ImportSystem.cmake b/Tests/RunCMake/cmake_pkg_config/ImportSystem.cmake new file mode 100644 index 0000000..bf0fb14 --- /dev/null +++ b/Tests/RunCMake/cmake_pkg_config/ImportSystem.cmake
@@ -0,0 +1,12 @@ +set(CMAKE_PKG_CONFIG_SYS_INCLUDE_DIRS /TestDirectories/Include) +set(CMAKE_PKG_CONFIG_SYS_LIB_DIRS /TestDirectories/Library) + +cmake_pkg_config(IMPORT import-simple REQUIRED) + +file(GENERATE + OUTPUT import-system.txt + CONTENT +"Include Directories: $<TARGET_PROPERTY:PkgConfig::import-simple,INTERFACE_INCLUDE_DIRECTORIES> +Link Directories: $<TARGET_PROPERTY:PkgConfig::import-simple,INTERFACE_LINK_DIRECTORIES> +" +)
diff --git a/Tests/RunCMake/cmake_pkg_config/PackageRoot/relocate.pc b/Tests/RunCMake/cmake_pkg_config/PackageRoot/relocate.pc index 5abce76..ac97d46 100644 --- a/Tests/RunCMake/cmake_pkg_config/PackageRoot/relocate.pc +++ b/Tests/RunCMake/cmake_pkg_config/PackageRoot/relocate.pc
@@ -2,5 +2,5 @@ Description: For testing relocation and flag mangling Version: 1.0.0 -Cflags: -I/Alpha Beta -I/Gamma -Libs: -L/Delta Epsilon -L/Zeta +Cflags: -I/Alpha -I/Alpha/sub Beta -I/Gamma +Libs: -L/Delta -L/Delta/sub Epsilon -L/Zeta
diff --git a/Tests/RunCMake/cmake_pkg_config/RunCMakeTest.cmake b/Tests/RunCMake/cmake_pkg_config/RunCMakeTest.cmake index 422a993..b2e38fc 100644 --- a/Tests/RunCMake/cmake_pkg_config/RunCMakeTest.cmake +++ b/Tests/RunCMake/cmake_pkg_config/RunCMakeTest.cmake
@@ -20,6 +20,7 @@ run_cmake(ImportPrefix) run_cmake(ImportRequires) run_cmake(ImportSimple) +run_cmake(ImportSystem) run_cmake(ImportTransitiveFail) run_cmake(ImportTransitiveVersion) run_cmake(ImportTransitiveVersionFail)
diff --git a/Tests/RunCMake/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake index 15ca477..acfc742 100644 --- a/Tests/RunCMake/foreach/RunCMakeTest.cmake +++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake
@@ -22,3 +22,4 @@ run_cmake(foreach-RANGE-out-of-range-test) run_cmake(foreach-var-scope-CMP0124-OLD) run_cmake(foreach-var-scope-CMP0124-NEW) +run_cmake(TrailingIn)
diff --git a/Tests/RunCMake/foreach/TrailingIn-result.txt b/Tests/RunCMake/foreach/TrailingIn-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/foreach/TrailingIn-result.txt
@@ -0,0 +1 @@ +0
diff --git a/Tests/RunCMake/foreach/TrailingIn.cmake b/Tests/RunCMake/foreach/TrailingIn.cmake new file mode 100644 index 0000000..e2b5b2f --- /dev/null +++ b/Tests/RunCMake/foreach/TrailingIn.cmake
@@ -0,0 +1,5 @@ +foreach(v IN) +endforeach() + +foreach(v1 v2 IN) +endforeach()
diff --git a/Tests/RunCMake/property_init/CompileSources.cmake b/Tests/RunCMake/property_init/CompileSources.cmake index 6909e07..d4f8b06 100644 --- a/Tests/RunCMake/property_init/CompileSources.cmake +++ b/Tests/RunCMake/property_init/CompileSources.cmake
@@ -78,6 +78,7 @@ "BUILD_WITH_INSTALL_NAME_DIR" "@rpath/" "<SAME>" ### Install "INSTALL_NAME_DIR" "@rpath/" "<SAME>" + "INSTALL_OBJECT_NAME_STRATEGY" "SHORT" "<SAME>" "INSTALL_REMOVE_ENVIRONMENT_RPATH" "ON" "<SAME>" "INSTALL_RPATH" "@rpath/" "<SAME>" "INSTALL_RPATH_USE_LINK_PATH" "ON" "<SAME>"
diff --git a/Tests/RunCMake/string/GenexpStrip.cmake b/Tests/RunCMake/string/GenexpStrip.cmake new file mode 100644 index 0000000..9de498c --- /dev/null +++ b/Tests/RunCMake/string/GenexpStrip.cmake
@@ -0,0 +1,37 @@ +function(test_strip input expected) + string(GENEX_STRIP "${input}" strip) + if (NOT strip STREQUAL expected) + message(FATAL_ERROR "message(GENEXP_STRIP \"${input}\") +evaluated to \"${strip}\" +expected \"${expected}\"") + endif() +endfunction() + +test_strip( # Simple case + "$<BOOL:1>" + "" +) +test_strip( # LHS contains generator expression + "$<$<CONFIG:Release>:NDEBUG>;DEBUG" + "DEBUG" +) +test_strip( # RHS contains generator expression + "$<AND:1,$<BOOL:TRUE>>" + "" +) +test_strip( # Empty and unfinished expressions + "$<>$<$<>" + "$<$<>" +) +test_strip( # Multiple independent expressions + "$<IF:TRUE,TRUE,FALSE> / $<IF:TRUE,TRUE,FALSE>" + " / " +) +test_strip( # Multiple : in one expression + "$<1:2:3>" + "" +) +test_strip( # Multiple case + "1$<AND:1,0>2$<IF:$<$<BOOL:1>:$<CONFIG:RELEASE>>,TRUE,FALSE>3" + "123" +)
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake index a495363..f4a6ff8 100644 --- a/Tests/RunCMake/string/RunCMakeTest.cmake +++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -57,3 +57,5 @@ run_cmake(Hex) run_cmake(HexTooManyArgs) run_cmake(HexNotEnoughArgs) + +run_cmake(GenexpStrip)
diff --git a/Utilities/gdb/gdbinit-template b/Utilities/gdb/gdbinit-template new file mode 100644 index 0000000..0e4a267 --- /dev/null +++ b/Utilities/gdb/gdbinit-template
@@ -0,0 +1,5 @@ +# Allows GDB to follow child processes +set follow-fork-mode child + +# Allows the parent process continue in parallel +set non-stop on
diff --git a/bootstrap b/bootstrap index d88a88d..e354aa9 100755 --- a/bootstrap +++ b/bootstrap
@@ -454,6 +454,7 @@ cmOSXBundleGenerator \ cmOptionCommand \ cmOrderDirectories \ + cmObjectLocation \ cmOutputConverter \ cmParseArgumentsCommand \ cmPathLabel \