diff options
160 files changed, 2174 insertions, 271 deletions
diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst index dc65249..a310e9f 100644 --- a/Help/cpack_gen/nsis.rst +++ b/Help/cpack_gen/nsis.rst @@ -149,3 +149,7 @@ on Windows Nullsoft Scriptable Install System. .. variable:: CPACK_NSIS_FINISH_TITLE_3LINES Display the title in the finish page on 3 lines instead of 2. + +.. variable:: CPACK_NSIS_MUI_HEADERIMAGE + + The image to display on the header of installers pages. diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst index 71cc392..92ca760 100644 --- a/Help/generator/Ninja Multi-Config.rst +++ b/Help/generator/Ninja Multi-Config.rst @@ -19,9 +19,10 @@ the desired ``build-<Config>.ninja`` file with ``ninja -f``. Running ``build-<Config>.ninja`` as the ``-f`` file and ``<target>`` as the build target. -Executables and libraries of any configuration can be built regardless of which +If :variable:`CMAKE_NINJA_CROSS_CONFIG_ENABLE` is turned on, executables and +libraries of any configuration can be built regardless of which ``build-<Config>.ninja`` file is used, simply by specifying -``<target>:<Config>`` as the Ninja target. You can also specify +``<target>:<OtherConfig>`` as the Ninja target. You can also specify ``<target>:all`` to build a target in all configurations. Each ``build-<Config>.ninja`` file will additionally have ``<target>`` targets which are aliases for ``<target>:<Config>``. However, custom commands and custom @@ -30,6 +31,11 @@ targets will always use the configuration specified in Ninja for the same file to be output with different commands in the same build graph. +If :variable:`CMAKE_NINJA_CROSS_CONFIG_ENABLE` is not enabled, you can still +build any target in ``build-<Config>.ninja`` by specifying +``<target>:<Config>`` or ``<target>``, but not ``<target>:<OtherConfig>`` or +``<target>:all``. + Consider the following example: .. code-block:: cmake @@ -54,7 +60,8 @@ This would build the ``Debug`` configuration of ``generator``, which would be used to generate ``generated.c``, which would be used to build the ``Debug`` configuration of ``generated``. -But if you run the following instead: +But if :variable:`CMAKE_NINJA_CROSS_CONFIG_ENABLE` is enabled, and you run the +following instead: .. code-block:: shell diff --git a/Help/guide/user-interaction/GUI-Add-Entry.png b/Help/guide/user-interaction/GUI-Add-Entry.png Binary files differnew file mode 100644 index 0000000..1e9be7e --- /dev/null +++ b/Help/guide/user-interaction/GUI-Add-Entry.png diff --git a/Help/guide/user-interaction/GUI-Choose-Generator.png b/Help/guide/user-interaction/GUI-Choose-Generator.png Binary files differnew file mode 100644 index 0000000..19ad2c0 --- /dev/null +++ b/Help/guide/user-interaction/GUI-Choose-Generator.png diff --git a/Help/guide/user-interaction/GUI-Configure-Dialog.png b/Help/guide/user-interaction/GUI-Configure-Dialog.png Binary files differnew file mode 100644 index 0000000..9839cac --- /dev/null +++ b/Help/guide/user-interaction/GUI-Configure-Dialog.png diff --git a/Help/guide/user-interaction/GUI-Source-Binary.png b/Help/guide/user-interaction/GUI-Source-Binary.png Binary files differnew file mode 100644 index 0000000..e338354 --- /dev/null +++ b/Help/guide/user-interaction/GUI-Source-Binary.png diff --git a/Help/guide/user-interaction/index.rst b/Help/guide/user-interaction/index.rst new file mode 100644 index 0000000..3a1038f --- /dev/null +++ b/Help/guide/user-interaction/index.rst @@ -0,0 +1,686 @@ +User Interaction Guide +********************** + +.. only:: html + + .. contents:: + +Introduction +============ + +Where a software package supplies a CMake-based buildsystem +with the source of their software, the consumer of the +software is required to run a CMake user interaction tool +in order to build it. + +Well-behaved CMake-based buildsystems do not create any +output in the source directory, so typically, the user +performs an out-of-source build and performs the build +there. First, CMake must be instructed to generate a +suitable buildsystem, then the user invokes a build tool +to process that generated buildsystem. The generated +buildsystem is specific to the machine used to generate +it and is not redistributable. Each consumer of a provided +source software package is required to use CMake to +generate a buildsystem specific to their system. + +Generated buildsystems should generally be treated as +read-only. The CMake files as a primary artifact should +completely specify the buildsystem and there should be no +reason to populate properties manually in an IDE for +example after generating the buildsystem. CMake will +periodically rewrite the generated buildsystem, so +modifications by users will be overwritten. + +The features and user interfaces described in this manual +are available for all CMake-based build systems by virtue +of providing CMake files. + +The CMake tooling may report errors to the user when +processing provided CMake files, such as reporting that +the compiler is not supported, or the compiler does not +support a required compile option, or a dependency can +not be found. These errors must be resolved by the user +by choosing a different compiler, +:guide:`installing dependencies <Using Dependencies Guide>`, +or instructing CMake where to find them, etc. + +Command Line cmake tool +----------------------- + +A simple but typical use of :manual:`cmake(1)` with a fresh +copy of software source code is to create a build directory +and invoke cmake there: + +.. code-block:: console + + $ cd some_software-1.4.2 + $ mkdir build + $ cd build + $ cmake .. -DCMAKE_INSTALL_PREFIX=/opt/the/prefix + $ cmake --build . + $ cmake --build . --target install + +It is recommended to build in a separate directory to the +source because that keeps the source directory pristine, +allows for building a single source with multiple +toolchains, and allows easy clearing of build artifacts by +simply deleting the build directory. + +The CMake tooling may report warnings which are intended +for the provider of the software, not intended for the +consumer of the software. Such warnings end with "This +warning is for project developers". Users may disable +such warnings by passing the ``-Wno-dev`` flag to +:manual:`cmake(1)`. + +cmake-gui tool +-------------- + +Users more accustomed to GUI interfaces may use the +:manual:`cmake-gui(1)` tool to invoke CMake and generate +a buildsystem. + +The source and binary directories must first be +populated. It is always advised to use different +directories for the source and the build. + +.. image:: /guide/user-interaction/GUI-Source-Binary.png + +Generating a Buildsystem +======================== + +There are several user interface tools which may be used +to generate a buildsystem from CMake files. The +:manual:`ccmake(1)` and :manual:`cmake-gui(1)` tools guide +the user through setting the various necessary options. +The :manual:`cmake(1)` tool can be invoked to specify +options on the command line. This manual describes options +which may be set using any of the user interface tools, +though the mode of setting an option is different for each +tool. + +Command line environment +------------------------ + +When invoking :manual:`cmake(1)` with a command line +buildsystem such as ``Makefiles`` or ``Ninja``, it is +necessary to use the correct build environment to +ensure that build tools are available. CMake must be +able to find the appropriate +:variable:`build tool <CMAKE_MAKE_PROGRAM>`, +compiler, linker and other tools as needed. + +On Linux systems, the appropriate tools are often +provided in system-wide locations and may be readily +installed through the system package manager. Other +toolchains provided by the user or installed in +non-default locations can also be used. + +When cross-compiling, some platforms may require +environment variables to be set or may provide +scripts to set the environment. + +Visual Studio ships multiple command prompts and +``vcvarsall.bat`` scripts for setting up the +correct environments for command line buildsystems. While +not strictly necessary to use a corresponding +command line environment when using a Visual Studio +generator, doing so has no disadvantages. + +When using Xcode, there can be more than one Xcode +version installed. Which one to use can be selected +in a number of different ways, but the most common +methods are: + +* Setting the default version in the preferences + of the Xcode IDE. +* Setting the default version via the ``xcode-select`` + command line tool. +* Overriding the default version by setting the + ``DEVELOPER_DIR`` environment variable when running + CMake and the build tool. + +Command line ``-G`` option +-------------------------- + +CMake chooses a generator by default based on the +platform. Usually, the default generator is sufficient +to allow the user to proceed to build the software. + +The user may override the default generator with +the ``-G`` option: + +.. code-block:: console + + $ cmake .. -G Ninja + +The output of ``cmake --help`` includes a list of +:manual:`generators <cmake-generators(7)>` available +for the user to choose from. Note that generator +names are case sensitive. + +On Unix-like systems (including Mac OS X), the +:generator:`Unix Makefiles` generator is used by +default. A variant of that generator can also be used +on Windows in various environments, such as the +:generator:`NMake Makefiles` and +:generator:`MinGW Makefiles` generator. These generators +generate a ``Makefile`` variant which can be executed +with ``make``, ``gmake``, ``nmake`` or similar tools. +See the individual generator documentation for more +information on targeted environments and tools. + +The :generator:`Ninja` generator is available on all +major platforms. ``ninja`` is a build tool similar +in use-cases to ``make``, but with a focus on +performance and efficiency. + +On Windows, :manual:`cmake(1)` can be used to generate +solutions for the Visual Studio IDE. Visual Studio +versions may be specified by the product name of the +IDE, which includes a four-digit year. Aliases are +provided for other means by which Visual Studio +versions are sometimes referred to, such as two +digits which correspond to the product version of the +VisualC++ compiler, or a combination of the two: + +.. code-block:: console + + $ cmake .. -G "Visual Studio 2019" + $ cmake .. -G "Visual Studio 16" + $ cmake .. -G "Visual Studio 16 2019" + +Visual Studio generators can target different architectures. +One can specify the target architecture using the `-A` option: + +.. code-block:: console + + cmake .. -G "Visual Studio 2019" -A x64 + cmake .. -G "Visual Studio 16" -A ARM + cmake .. -G "Visual Studio 16 2019" -A ARM64 + +On Apple, the :generator:`Xcode` generator may be used to +generate project files for the Xcode IDE. + +Some IDEs such as KDevelop4, QtCreator and CLion have +native support for CMake-based buildsystems. Those IDEs +provide user interface for selecting an underlying +generator to use, typically a choice between a ``Makefile`` +or a ``Ninja`` based generator. + +Note that it is not possible to change the generator +with ``-G`` after the first invocation of CMake. To +change the generator, the build directory must be +deleted and the build must be started from scratch. + +When generating Visual Studio project and solutions +files several other options are available to use when +initially running :manual:`cmake(1)`. + +The Visual Studio toolset can be specified with the +``-T`` option: + +.. code-block:: console + + $ # Build with the clang-cl toolset + $ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T LLVM + $ # Build targeting Windows XP + $ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T v120_xp + +Whereas the ``-A`` option specifies the _target_ +architecture, the ``-T`` option can be used to specify +details of the toolchain used. For example, `-Thost=x64` +can be given to select the 64-bit version of the host +tools. The following demonstrates how to use 64-bit +tools and also build for a 64-bit target architecture: + +.. code-block:: console + + $ cmake .. -G "Visual Studio 16 2019" -A x64 -Thost=x64 + +Choosing a generator in cmake-gui +--------------------------------- + +The "Configure" button triggers a new dialog to +select the CMake generator to use. + +.. image:: /guide/user-interaction/GUI-Configure-Dialog.png + +All generators available on the command line are also +available in :manual:`cmake-gui(1)`. + +.. image:: /guide/user-interaction/GUI-Choose-Generator.png + +When choosing a Visual Studio generator, further options +are available to set an architecture to generate for. + +.. image:: /manual/VS-Choose-Arch.png + +.. _`Setting Build Variables`: + +Setting Build Variables +======================= + +Software projects often require variables to be +set on the command line when invoking CMake. Some of +the most commonly used CMake variables are listed in +the table below: + +========================================== ============================================================ + Variable Meaning +========================================== ============================================================ + :variable:`CMAKE_PREFIX_PATH` Path to search for + :guide:`dependent packages <Using Dependencies Guide>` + :variable:`CMAKE_MODULE_PATH` Path to search for additional CMake modules + :variable:`CMAKE_BUILD_TYPE` Build configuration, such as + ``Debug`` or ``Release``, determining + debug/optimization flags. This is only + relevant for single-configuration buildsystems such + as ``Makefile`` and ``Ninja``. Multi-configuration + buildsystems such as those for Visual Studio and Xcode + ignore this setting. + :variable:`CMAKE_INSTALL_PREFIX` Location to install the + software to with the + ``install`` build target + :variable:`CMAKE_TOOLCHAIN_FILE` File containing cross-compiling + data such as + :manual:`toolchains and sysroots <cmake-toolchains(7)>`. + :variable:`BUILD_SHARED_LIBS` Whether to build shared + instead of static libraries + for :command:`add_library` + commands used without a type + :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` Generate a ``compile_commands.json`` + file for use with clang-based tools +========================================== ============================================================ + +Other project-specific variables may be available +to control builds, such as enabling or disabling +components of the project. + +There is no convention provided by CMake for how +such variables are named between different +provided buildsystems, except that variables with +the prefix ``CMAKE_`` usually refer to options +provided by CMake itself and should not be used +in third-party options, which should use +their own prefix instead. The +:manual:`cmake-gui(1)` tool can display options +in groups defined by their prefix, so it makes +sense for third parties to ensure that they use a +self-consistent prefix. + +Setting variables on the command line +------------------------------------- + +CMake variables can be set on the command line either +when creating the initial build: + +.. code-block:: console + + $ mkdir build + $ cd build + $ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug + +or later on a subsequent invocation of +:manual:`cmake(1)`: + +.. code-block:: console + + $ cd build + $ cmake . -DCMAKE_BUILD_TYPE=Debug + +The ``-U`` flag may be used to unset variables +on the :manual:`cmake(1)` command line: + +.. code-block:: console + + $ cd build + $ cmake . -UMyPackage_DIR + +A CMake buildsystem which was initially created +on the command line can be modified using the +:manual:`cmake-gui(1)` and vice-versa. + +The :manual:`cmake(1)` tool allows specifying a +file to use to populate the initial cache using +the ``-C`` option. This can be useful to simplify +commands and scripts which repeatedly require the +same cache entries. + +Setting variables with cmake-gui +-------------------------------- + +Variables may be set in the cmake-gui using the "Add Entry" +button. This triggers a new dialog to set the value of +the variable. + +.. image:: /guide/user-interaction/GUI-Add-Entry.png + +The main view of the :manual:`cmake-gui(1)` user interface +can be used to edit existing variables. + +The CMake Cache +--------------- + +When CMake is executed, it needs to find the locations of +compilers, tools and dependencies. It also needs to be +able to consistently re-generate a buildsystem to use the +same compile/link flags and paths to dependencies. Such +parameters are also required to be configurable by the +user because they are paths and options specific to the +users system. + +When it is first executed, CMake generates a +``CMakeCache.txt`` file in the build directory containing +key-value pairs for such artifacts. The cache file can be +viewed or edited by the user by running the +:manual:`cmake-gui(1)` or :manual:`ccmake(1)` tool. The +tools provide an interactive interface for re-configuring +the provided software and re-generating the buildsystem, +as is needed after editing cached values. Each cache +entry may have an associated short help text which is +displayed in the user interface tools. + +The cache entries may also have a type to signify how it +should be presented in the user interface. For example, +a cache entry of type ``BOOL`` can be edited by a +checkbox in a user interface, a ``STRING`` can be edited +in a text field, and a ``FILEPATH`` while similar to a +``STRING`` should also provide a way to locate filesystem +paths using a file dialog. An entry of type ``STRING`` +may provide a restricted list of allowed values which are +then provided in a drop-down menu in the +:manual:`cmake-gui(1)` user interface (see the +:prop_cache:`STRINGS` cache property). + +The CMake files shipped with a software package may also +define boolean toggle options using the :command:`option` +command. The command creates a cache entry which has a +help text and a default value. Such cache entries are +typically specific to the provided software and affect +the configuration of the build, such as whether tests +and examples are built, whether to build with exceptions +enabled etc. + +Invoking the Buildsystem +======================== + +After generating the buildsystem, the software can be +built by invoking the particular build tool. In the +case of the IDE generators, this can involve loading +the generated project file into the IDE to invoke the +build. + +CMake is aware of the specific build tool needed to invoke +a build so in general, to build a buildsystem or project +from the command line after generating, the following +command may be invoked in the build directory: + +.. code-block:: console + + $ cmake --build . + +The ``--build`` flag enables a particular mode of +operation for the :manual:`cmake(1)` tool. It invokes +the :variable:`CMAKE_MAKE_PROGRAM` command associated +with the :manual:`generator <cmake-generators(7)>`, or +the build tool configured by the user. + +The ``--build`` mode also accepts the parameter +``--target`` to specify a particular target to build, +for example a particular library, executable or +custom target, or a particular special target like +``install``: + +.. code-block:: console + + $ cmake --build . --target myexe + +The ``--build`` mode also accepts a ``--config`` parameter +in the case of multi-config generators to specify which +particular configuration to build: + +.. code-block:: console + + $ cmake --build . --target myexe --config Release + +The ``--config`` option has no effect if the generator +generates a buildsystem specific to a configuration which +is chosen when invoking cmake with the +:variable:`CMAKE_BUILD_TYPE` variable. + +Some buildsystems omit details of command lines invoked +during the build. The ``--verbose`` flag can be used to +cause those command lines to be shown: + +.. code-block:: console + + $ cmake --build . --target myexe --verbose + +The ``--build`` mode can also pass particular command +line options to the underlying build tool by listing +them after ``--``. This can be useful to specify +options to the build tool, such as to continue the +build after a failed job, where CMake does not +provide a high-level user interface. + +For all generators, it is possible to run the underlying +build tool after invoking CMake. For example, ``make`` +may be executed after generating with the +:generator:`Unix Makefiles` generator to invoke the build, +or ``ninja`` after generating with the :generator:`Ninja` +generator etc. The IDE buildsystems usually provide +command line tooling for building a project which can +also be invoked. + +Selecting a Target +------------------ + +Each executable and library described in the CMake files +is a build target, and the buildsystem may describe +custom targets, either for internal use, or for user +consumption, for example to create documentation. + +CMake provides some built-in targets for all buildsystems +providing CMake files. + +``all`` + The default target used by ``Makefile`` and ``Ninja`` + generators. Builds all targets in the buildsystem, + except those which are excluded by their + :prop_tgt:`EXCLUDE_FROM_ALL` target property or + :prop_dir:`EXCLUDE_FROM_ALL` directory property. The + name ``ALL_BUILD`` is used for this purpose for the + Xcode and Visual Studio generators. +``help`` + Lists the targets available for build. This target is + available when using the :generator:`Unix Makefiles` or + :generator:`Ninja` generator, and the exact output is + tool-specific. +``clean`` + Delete built object files and other output files. The + ``Makefile`` based generators create a ``clean`` target + per directory, so that an individual directory can be + cleaned. The ``Ninja`` tool provides its own granular + ``-t clean`` system. +``test`` + Runs tests. This target is only automatically available + if the CMake files provide CTest-based tests. See also + `Running Tests`_. +``install`` + Installs the software. This target is only automatically + available if the software defines install rules with the + :command:`install` command. See also + `Software Installation`_. +``package`` + Creates a binary package. This target is only + automatically available if the CMake files provide + CPack-based packages. +``package_source`` + Creates a source package. This target is only + automatically available if the CMake files provide + CPack-based packages. + +For ``Makefile`` based systems, ``/fast`` variants of binary +build targets are provided. The ``/fast`` variants are used +to build the specified target without regard for its +dependencies. The dependencies are not checked and +are not rebuilt if out of date. The :generator:`Ninja` +generator is sufficiently fast at dependency checking that +such targets are not provided for that generator. + +``Makefile`` based systems also provide build-targets to +preprocess, assemble and compile individual files in a +particular directory. + +.. code-block:: console + + $ make foo.cpp.i + $ make foo.cpp.s + $ make foo.cpp.o + +The file extension is built into the name of the target +because another file with the same name but a different +extension may exist. However, build-targets without the +file extension are also provided. + +.. code-block:: console + + $ make foo.i + $ make foo.s + $ make foo.o + +In buildsystems which contain ``foo.c`` and ``foo.cpp``, +building the ``foo.i`` target will preprocess both files. + +Specifying a Build Program +-------------------------- + +The program invoked by the ``--build`` mode is determined +by the :variable:`CMAKE_MAKE_PROGRAM` variable. For most +generators, the particular program does not need to be +configured. + +===================== =========================== =========================== + Generator Default make program Alternatives +===================== =========================== =========================== + XCode ``xcodebuild`` + Unix Makefiles ``make`` + NMake Makefiles ``nmake`` ``jom`` + NMake Makefiles JOM ``jom`` ``nmake`` + MinGW Makefiles ``mingw32-make`` + MSYS Makefiles ``make`` + Ninja ``ninja`` + Visual Studio ``msbuild`` + Watcom WMake ``wmake`` +===================== =========================== =========================== + +The ``jom`` tool is capable of reading makefiles of the +``NMake`` flavor and building in parallel, while the +``nmake`` tool always builds serially. After generating +with the :generator:`NMake Makefiles` generator a user +can run ``jom`` instead of ``nmake``. The ``--build`` +mode would also use ``jom`` if the +:variable:`CMAKE_MAKE_PROGRAM` was set to ``jom`` while +using the :generator:`NMake Makefiles` generator, and +as a convenience, the :generator:`NMake Makefiles JOM` +generator is provided to find ``jom`` in the normal way +and use it as the :variable:`CMAKE_MAKE_PROGRAM`. For +completeness, ``nmake`` is an alternative tool which +can process the output of the +:generator:`NMake Makefiles JOM` generator, but doing +so would be a pessimisation. + +Software Installation +===================== + +The :variable:`CMAKE_INSTALL_PREFIX` variable can be +set in the CMake cache to specify where to install the +provided software. If the provided software has install +rules, specified using the :command:`install` command, +they will install artifacts into that prefix. On Windows, +the default installation location corresponds to the +``ProgramFiles`` system directory which may be +architecture specific. On Unix hosts, ``/usr/local`` is +the default installation location. + +The :variable:`CMAKE_INSTALL_PREFIX` variable always +refers to the installation prefix on the target +filesystem. + +In cross-compiling or packaging scenarios where the +sysroot is read-only or where the sysroot should otherwise +remain pristine, the :variable:`CMAKE_STAGING_PREFIX` +variable can be set to a location to actually install +the files. + +The commands: + +.. code-block:: console + + $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \ + -DCMAKE_SYSROOT=$HOME/root \ + -DCMAKE_STAGING_PREFIX=/tmp/package + $ cmake --build . + $ cmake --build . --target install + +result in files being installed to paths such +as ``/tmp/package/lib/libfoo.so`` on the host machine. +The ``/usr/local`` location on the host machine is +not affected. + +Some provided software may specify ``uninstall`` rules, +but CMake does not generate such rules by default itself. + +Running Tests +============= + +The :manual:`ctest(1)` tool is shipped with the CMake +distribution to execute provided tests and report +results. The ``test`` build-target is provided to run +all available tests, but the :manual:`ctest(1)` tool +allows granular control over which tests to run, how to +run them, and how to report results. Executing +:manual:`ctest(1)` in the build directory is equivalent +to running the ``test`` target: + +.. code-block:: console + + $ ctest + +A regular expression can be passed to run only tests +which match the expression. To run only tests with +``Qt`` in their name: + +.. code-block:: console + + $ ctest -R Qt + +Tests can be excluded by regular expression too. To +run only tests without ``Qt`` in their name: + +.. code-block:: console + + $ ctest -E Qt + +Tests can be run in parallel by passing ``-j`` arguments +to :manual:`ctest(1)`: + +.. code-block:: console + + $ ctest -R Qt -j8 + +The environment variable :envvar:`CTEST_PARALLEL_LEVEL` +can alternatively be set to avoid the need to pass +``-j``. + +By default :manual:`ctest(1)` does not print the output +from the tests. The command line argument ``-V`` (or +``--verbose``) enables verbose mode to print the +output from all tests. +The ``--output-on-failure`` option prints the test +output for failing tests only. The environment variable +:envvar:`CTEST_OUTPUT_ON_FAILURE` +can be set to ``1`` as an alternative to passing the +``--output-on-failure`` option to :manual:`ctest(1)`. diff --git a/Help/guide/using-dependencies/index.rst b/Help/guide/using-dependencies/index.rst new file mode 100644 index 0000000..6fdcc55 --- /dev/null +++ b/Help/guide/using-dependencies/index.rst @@ -0,0 +1,200 @@ +Using Dependencies Guide +************************ + +.. only:: html + + .. contents:: + +Introduction +============ + +For developers wishing to use CMake to consume a third +party binary package, there are multiple possibilities +regarding how to optimally do so, depending on how +CMake-aware the third-party library is. + +CMake files provided with a software package contain +instructions for finding each build dependency. Some +build dependencies are optional in that the build may +succeed with a different feature set if the dependency +is missing, and some dependencies are required. CMake +searches well-known locations for each dependency, and +the provided software may supply additional hints or +locations to CMake to find each dependency. + +If a required dependency is not found by +:manual:`cmake(1)`, the cache is populated with an entry +which contains a ``NOTFOUND`` value. This value can be +replaced by specifying it on the command line, or in +the :manual:`ccmake(1)` or :manual:`cmake-gui(1)` tool. +See the :guide:`User Interaction Guide` for +more about setting cache entries. + +Libraries providing Config-file packages +---------------------------------------- + +The most convenient way for a third-party to provide library +binaries for use with CMake is to provide +:ref:`Config File Packages`. These packages are text files +shipped with the library which instruct CMake how to use the +library binaries and associated headers, helper tools and +CMake macros provided by the library. + +The config files can usually be found in a directory whose +name matches the pattern ``lib/cmake/<PackageName>``, though +they may be in other locations instead. The +``<PackageName>`` corresponds to use in CMake code with the +:command:`find_package` command such as +``find_package(PackageName REQUIRED)``. + +The ``lib/cmake/<PackageName>`` directory will contain a +file which is either named ``<PackageName>Config.cmake`` +or ``<PackageName>-config.cmake``. This is the entry point +to the package for CMake. A separate optional file named +``<PackageName>ConfigVersion.cmake`` may also exist in the +directory. This file is used by CMake to determine whether +the version of the third party package satisfies uses of the +:command:`find_package` command which specify version +constraints. It is optional to specify a version when using +:command:`find_package`, even if a ``ConfigVersion`` file is +present. + +If the ``Config.cmake`` file is found and the +optionally-specified version is satisfied, then the CMake +:command:`find_package` command considers the package to be +found and the entire library package is assumed to be +complete as designed. + +There may be additional files providing CMake macros or +:ref:`imported targets` for you to use. CMake does not +enforce any naming convention for these +files. They are related to the primary ``Config`` file by +use of the CMake :command:`include` command. + +:guide:`Invoking CMake <User Interaction Guide>` with the +intent of using a package of third party binaries requires +that cmake :command:`find_package` commands succeed in finding +the package. If the location of the package is in a directory +known to CMake, the :command:`find_package` call should +succeed. The directories known to cmake are platform-specific. +For example, packages installed on Linux with a standard +system package manager will be found in the ``/usr`` prefix +automatically. Packages installed in ``Program Files`` on +Windows will similarly be found automatically. + +Packages which are not found automatically are in locations +not predictable to CMake such as ``/opt/mylib`` or +``$HOME/dev/prefix``. This is a normal situation and CMake +provides several ways for users to specify where to find +such libraries. + +The :variable:`CMAKE_PREFIX_PATH` variable may be +:ref:`set when invoking CMake <Setting Build Variables>`. +It is treated as a list of paths to search for +:ref:`Config File Packages`. A package installed in +``/opt/somepackage`` will typically install config files +such as +``/opt/somepackage/lib/cmake/somePackage/SomePackageConfig.cmake``. +In that case, ``/opt/somepackage`` should be added to +:variable:`CMAKE_PREFIX_PATH`. + +The environment variable ``CMAKE_PREFIX_PATH`` may also be +populated with prefixes to search for packages. Like the +``PATH`` environment variable, this is a list and needs to use +the platform-specific environment variable list item separator +(``:`` on Unix and ``;`` on Windows). + +The :variable:`CMAKE_PREFIX_PATH` variable provides convenience +in cases where multiple prefixes need to be specified, or when +multiple different package binaries are available in the same +prefix. Paths to packages may also be specified by setting +variables matching ``<PackageName>_DIR``, such as +``SomePackage_DIR``. Note that this is not a prefix but should +be a full path to a directory containing a config-style package +file, such as ``/opt/somepackage/lib/cmake/SomePackage/`` in +the above example. + +Imported Targets from Packages +------------------------------ + +A third-party package which provides config-file packages may +also provide :ref:`Imported targets`. These will be +specified in files containing configuration-specific file +paths relevant to the package, such as debug and release +versions of libraries. + +Often the third-party package documentation will point out the +names of imported targets available after a successful +``find_package`` for a library. Those imported target names +can be used with the :command:`target_link_libraries` command. + +A complete example which makes a simple use of a third party +library might look like: + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.10) + project(MyExeProject VERSION 1.0.0) + + find_package(SomePackage REQUIRED) + add_executable(MyExe main.cpp) + target_link_libraries(MyExe PRIVATE SomePrefix::LibName) + +See :manual:`cmake-buildsystem(7)` for further information +about developing a CMake buildsystem. + +Libraries not Providing Config-file Packages +-------------------------------------------- + +Third-party libraries which do not provide config-file packages +can still be found with the :command:`find_package` command, if +a ``FindSomePackage.cmake`` file is available. + +These module-file packages are different to config-file packages +in that: + +#. They should not be provided by the third party, except + perhaps in the form of documentation +#. The availability of a ``Find<PackageName>.cmake`` file does + not indicate the availability of the binaries themselves. +#. CMake does not search the :variable:`CMAKE_PREFIX_PATH` for + ``Find<PackageName>.cmake`` files. Instead CMake searches + for such files in the :variable:`CMAKE_MODULE_PATH` + variable. It is common for users to set the + :variable:`CMAKE_MODULE_PATH` when running CMake, and it is + common for CMake projects to append to + :variable:`CMAKE_MODULE_PATH` to allow use of local + module-file packages. +#. CMake ships ``Find<PackageName>.cmake`` files for some + :manual:`third party packages <cmake-modules(7)>` + for convenience in cases where the third party does + not provide config-file packages directly. These files are + a maintenance burden for CMake, so new Find modules are + generally not added to CMake anymore. Third-parties should + provide config file packages instead of relying on a Find + module to be provided by CMake. + +Module-file packages may also provide :ref:`Imported targets`. +A complete example which finds such a package might look +like: + +.. code-block:: cmake + + cmake_minimum_required(VERSION 3.10) + project(MyExeProject VERSION 1.0.0) + + find_package(PNG REQUIRED) + + # Add path to a FindSomePackage.cmake file + list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") + find_package(SomePackage REQUIRED) + + add_executable(MyExe main.cpp) + target_link_libraries(MyExe PRIVATE + PNG::PNG + SomePrefix::LibName + ) + +The :variable:`<PackageName>_ROOT` variable is also +searched as a prefix for :command:`find_package` calls using +module-file packages such as ``FindSomePackage``. diff --git a/Help/index.rst b/Help/index.rst index cc6cee6..4d9a9c8 100644 --- a/Help/index.rst +++ b/Help/index.rst @@ -1,5 +1,34 @@ .. title:: CMake Reference Documentation +Introduction +############ + +CMake is a tool to manage building of source code. Originally, CMake was +designed as a generator for various dialects of ``Makefile``, today +CMake generates modern buildsystems such as ``Ninja`` as well as project +files for IDEs such as Visual Studio and Xcode. + +CMake is widely used for the C and C++ languages, but it may be used to +build source code of other languages too. + +People encountering CMake for the first time may have different initial +goals. To learn how to build a source code package downloaded from the +internet, start with the :guide:`User Interaction Guide`. +This will detail the steps needed to run the :manual:`cmake(1)` or +:manual:`cmake-gui(1)` executable and how to choose a generator, and +how to complete the build. + +The :guide:`Using Dependencies Guide` is aimed at developers +wishing to get started using a third-party library. + +For developers starting a project using CMake, the :guide:`CMake Tutorial` +is a suitable starting point. The :manual:`cmake-buildsystem(7)` +manual is aimed at developers expanding their knowledge of maintaining +a buildsystem and becoming familiar with the build targets that +can be represented in CMake. The :manual:`cmake-packages(7)` manual +explains how to create packages which can easily be consumed by +third-party CMake-based buildsystems. + Command-Line Tools ################## @@ -53,6 +82,8 @@ Reference Manuals :maxdepth: 1 /guide/tutorial/index + /guide/user-interaction/index + /guide/using-dependencies/index .. only:: html or text diff --git a/Help/manual/VS-Choose-Arch.png b/Help/manual/VS-Choose-Arch.png Binary files differnew file mode 100644 index 0000000..816b0f4 --- /dev/null +++ b/Help/manual/VS-Choose-Arch.png diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 1fd49ed..53cf264 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.17 .. toctree:: :maxdepth: 1 + CMP0101: target_compile_options honors BEFORE keyword in all scopes. </policy/CMP0101> CMP0100: Let AUTOMOC and AUTOUIC process .hh header files. </policy/CMP0100> CMP0099: Link properties are transitive over private dependency on static libraries. </policy/CMP0099> CMP0098: FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing. </policy/CMP0098> diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 10a0c7c..b3802d1 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -27,6 +27,8 @@ Properties of Global Scope /prop_gbl/CMAKE_ROLE /prop_gbl/DEBUG_CONFIGURATIONS /prop_gbl/DISABLED_FEATURES + /prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS + /prop_gbl/ECLIPSE_EXTRA_NATURES /prop_gbl/ENABLED_FEATURES /prop_gbl/ENABLED_LANGUAGES /prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS @@ -37,12 +39,10 @@ Properties of Global Scope /prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE /prop_gbl/GLOBAL_DEPENDS_NO_CYCLES /prop_gbl/IN_TRY_COMPILE + /prop_gbl/JOB_POOLS /prop_gbl/PACKAGES_FOUND /prop_gbl/PACKAGES_NOT_FOUND - /prop_gbl/JOB_POOLS /prop_gbl/PREDEFINED_TARGETS_FOLDER - /prop_gbl/ECLIPSE_EXTRA_NATURES - /prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS /prop_gbl/REPORT_UNDEFINED_PROPERTIES /prop_gbl/RULE_LAUNCH_COMPILE /prop_gbl/RULE_LAUNCH_CUSTOM @@ -130,20 +130,20 @@ Properties on Targets /prop_tgt/AUTOGEN_ORIGIN_DEPENDS /prop_tgt/AUTOGEN_PARALLEL /prop_tgt/AUTOGEN_TARGET_DEPENDS + /prop_tgt/AUTOMOC /prop_tgt/AUTOMOC_COMPILER_PREDEFINES /prop_tgt/AUTOMOC_DEPEND_FILTERS /prop_tgt/AUTOMOC_EXECUTABLE /prop_tgt/AUTOMOC_MACRO_NAMES /prop_tgt/AUTOMOC_MOC_OPTIONS /prop_tgt/AUTOMOC_PATH_PREFIX - /prop_tgt/AUTOMOC + /prop_tgt/AUTORCC + /prop_tgt/AUTORCC_EXECUTABLE + /prop_tgt/AUTORCC_OPTIONS /prop_tgt/AUTOUIC /prop_tgt/AUTOUIC_EXECUTABLE /prop_tgt/AUTOUIC_OPTIONS /prop_tgt/AUTOUIC_SEARCH_PATHS - /prop_tgt/AUTORCC - /prop_tgt/AUTORCC_EXECUTABLE - /prop_tgt/AUTORCC_OPTIONS /prop_tgt/BINARY_DIR /prop_tgt/BUILD_RPATH /prop_tgt/BUILD_RPATH_USE_ORIGIN @@ -446,8 +446,8 @@ Properties on Source Files :maxdepth: 1 /prop_sf/ABSTRACT - /prop_sf/AUTOUIC_OPTIONS /prop_sf/AUTORCC_OPTIONS + /prop_sf/AUTOUIC_OPTIONS /prop_sf/COMPILE_DEFINITIONS /prop_sf/COMPILE_FLAGS /prop_sf/COMPILE_OPTIONS diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 74dd1fb..26f1d80 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -423,6 +423,7 @@ Variables that Control the Build /variable/CMAKE_MODULE_LINKER_FLAGS_INIT /variable/CMAKE_MSVCIDE_RUN_PATH /variable/CMAKE_MSVC_RUNTIME_LIBRARY + /variable/CMAKE_NINJA_CROSS_CONFIG_ENABLE /variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX /variable/CMAKE_NO_BUILTIN_CHRPATH /variable/CMAKE_NO_SYSTEM_FROM_IMPORTED diff --git a/Help/policy/CMP0101.rst b/Help/policy/CMP0101.rst new file mode 100644 index 0000000..9941acf --- /dev/null +++ b/Help/policy/CMP0101.rst @@ -0,0 +1,20 @@ +CMP0101 +------- + +:command:`target_compile_options` now honors ``BEFORE`` keyword in all scopes. + +In CMake 3.16 and below the :command:`target_compile_options` ignores the +``BEFORE`` keyword in private scope. CMake 3.17 and later honors +``BEFORE`` keyword in all scopes. This policy provides compatibility for +projects that have not been updated to expect the new behavior. + +The ``OLD`` behavior for this policy is to not honor ``BEFORE`` keyword in +private scope. The ``NEW`` behavior of this policy is to honor +``BEFORE`` keyword in all scopes. + +This policy was introduced in CMake version 3.17. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. +Unlike many policies, CMake version |release| does *not* warn +when this policy is not set and simply uses ``OLD`` behavior. + +.. include:: DEPRECATED.txt diff --git a/Help/prop_tgt/AUTOGEN_PARALLEL.rst b/Help/prop_tgt/AUTOGEN_PARALLEL.rst index 07fbc5a..968b619 100644 --- a/Help/prop_tgt/AUTOGEN_PARALLEL.rst +++ b/Help/prop_tgt/AUTOGEN_PARALLEL.rst @@ -4,9 +4,9 @@ AUTOGEN_PARALLEL Number of parallel ``moc`` or ``uic`` processes to start when using :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`. -The custom `<origin>_autogen` target starts a number of threads of which +The custom ``<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. :prop_tgt:`AUTOGEN_PARALLEL` controls how many parallel threads +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 @@ -14,7 +14,7 @@ process. :prop_tgt:`AUTOGEN_PARALLEL` controls how many parallel threads - A positive non zero integer value sets the exact thread/process count. - Otherwise a single thread/process is started. -By default :prop_tgt:`AUTOGEN_PARALLEL` is initialized from +By default ``AUTOGEN_PARALLEL`` is initialized from :variable:`CMAKE_AUTOGEN_PARALLEL`. See the :manual:`cmake-qt(7)` manual for more information on using CMake diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index f6dfabd..c18859b 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -172,7 +172,7 @@ variables. If the call is in a different context than the then the version variables might not be available to the :prop_tgt:`AUTOMOC` enabled target. In that case the version variables can be forwarded from the -`find_package(Qt[45]...)` calling context to the :command:`add_executable` +``find_package(Qt[45]...)`` calling context to the :command:`add_executable` or :command:`add_library` calling context as directory properties. The following Qt5 example demonstrates the procedure. diff --git a/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst index ebd5c49..330849b 100644 --- a/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst +++ b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst @@ -1,7 +1,7 @@ AUTOMOC_MOC_OPTIONS ------------------- -Additional options for moc when using :prop_tgt:`AUTOMOC` +Additional options for ``moc`` when using :prop_tgt:`AUTOMOC` This property is only used if the :prop_tgt:`AUTOMOC` property is ``ON`` for this target. In this case, it holds additional command line @@ -9,7 +9,9 @@ options which will be used when ``moc`` is executed during the build, i.e. it is equivalent to the optional ``OPTIONS`` argument of the :module:`qt4_wrap_cpp() <FindQt4>` macro. -By default it is empty. +This property is initialized by the value of the +:variable:`CMAKE_AUTOMOC_MOC_OPTIONS` variable if it is set when a target +is created, or an empty string otherwise. See the :manual:`cmake-qt(7)` manual for more information on using CMake with Qt. diff --git a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst index e2ebb3f..3e3059d 100644 --- a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst +++ b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst @@ -21,11 +21,11 @@ with Qt. Reproducible builds ^^^^^^^^^^^^^^^^^^^ -For reproducible builds is is recommended to keep headers that are ``moc`` +For reproducible builds it is recommended to keep headers that are ``moc`` compiled in one of the target :command:`include directories <target_include_directories>` and set :prop_tgt:`AUTOMOC_PATH_PREFIX` to ``ON`` (which is the default). This ensures -that +that: - ``moc`` output files are identical on different build setups, - ``moc`` output files will compile correctly when the source and/or diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst index cca3e58..9a98f44 100644 --- a/Help/prop_tgt/AUTORCC.rst +++ b/Help/prop_tgt/AUTORCC.rst @@ -31,9 +31,10 @@ Modifiers The ``rcc`` executable will be detected automatically, but can be forced to a certain binary by setting this target property. -:prop_sf:`AUTORCC_OPTIONS`: -Additional command line options for ``rcc`` can be set via this ``.qrc`` -source file property. +:prop_tgt:`AUTORCC_OPTIONS`: +Additional command line options for ``rcc`` can be set via this target +property. The corresponding :prop_sf:`AUTORCC_OPTIONS` source file property +can be used to specify options to be applied only to a specific ``.qrc`` file. :prop_sf:`SKIP_AUTORCC`: ``.qrc`` files can be excluded from :prop_tgt:`AUTORCC` processing by diff --git a/Help/prop_tgt/AUTORCC_OPTIONS.rst b/Help/prop_tgt/AUTORCC_OPTIONS.rst index d6ade5a..5261aff 100644 --- a/Help/prop_tgt/AUTORCC_OPTIONS.rst +++ b/Help/prop_tgt/AUTORCC_OPTIONS.rst @@ -8,11 +8,9 @@ when ``rcc`` is executed during the build via :prop_tgt:`AUTORCC`, i.e. it is equivalent to the optional ``OPTIONS`` argument of the :module:`qt4_add_resources() <FindQt4>` macro. -By default it is empty. - This property is initialized by the value of the :variable:`CMAKE_AUTORCC_OPTIONS` variable if it is set when a target is -created. +created, or an empty string otherwise. The options set on the target may be overridden by :prop_sf:`AUTORCC_OPTIONS` set on the ``.qrc`` source file. diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 5cf8755..cd24f5e 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -52,8 +52,11 @@ Modifiers The ``uic`` executable will be detected automatically, but can be forced to a certain binary using this target property. -:prop_sf:`AUTOUIC_OPTIONS`: Additional command line options for ``uic`` can -be set via this source file property on a ``<base_name>.ui`` file. +:prop_tgt:`AUTOUIC_OPTIONS`: +Additional command line options for ``uic`` can be set via this target +property. The corresponding :prop_sf:`AUTOUIC_OPTIONS` source file property +can be used to specify options to be applied only to a specific +``<base_name>.ui`` file. :prop_sf:`SKIP_AUTOUIC`: Source files can be excluded from :prop_tgt:`AUTOUIC` processing by setting diff --git a/Help/prop_tgt/AUTOUIC_OPTIONS.rst b/Help/prop_tgt/AUTOUIC_OPTIONS.rst index 3f613b9..425ea1c 100644 --- a/Help/prop_tgt/AUTOUIC_OPTIONS.rst +++ b/Help/prop_tgt/AUTOUIC_OPTIONS.rst @@ -8,11 +8,9 @@ This property holds additional command line options which will be used when equivalent to the optional ``OPTIONS`` argument of the :module:`qt4_wrap_ui() <FindQt4>` macro. -By default it is empty. - This property is initialized by the value of the :variable:`CMAKE_AUTOUIC_OPTIONS` variable if it is set when a target is -created. +created, or an empty string otherwise. The options set on the target may be overridden by :prop_sf:`AUTOUIC_OPTIONS` set on the ``.ui`` source file. diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst index 23af503..a6f2b24 100644 --- a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst +++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst @@ -2,7 +2,7 @@ ------------------------ This property is implemented only when ``<LANG>`` is ``C``, ``CXX``, -``Fortran``, or ``CUDA``. +``Fortran``, ``OBJC``, ``OBJCXX``, or ``CUDA``. Specify a :ref:`semicolon-separated list <CMake Language Lists>` containing a command line for a compiler launching tool. The :ref:`Makefile Generators` and the diff --git a/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt index 1fdb6ad..fab4418 100644 --- a/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt +++ b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt @@ -2,8 +2,8 @@ A call to :command:`target_link_libraries(<target> ...)` may update this property on ``<target>``. If ``<target>`` was not created in the same directory as the call then :command:`target_link_libraries` will add a - suffix of the form ``::@<directory-id>`` to each entry, where the - ``::@`` is a separator and the ``<directory-id>`` is unspecified. + suffix of the form ``::@(directory-id)`` to each entry, where the + ``::@`` is a separator and the ``(directory-id)`` is unspecified. This tells the generators that the named libraries must be looked up in the scope of the caller rather than in the scope in which the ``<target>`` was created. Valid directory ids are stripped on export diff --git a/Help/release/dev/FindPython-SOABI.rst b/Help/release/dev/FindPython-SOABI.rst new file mode 100644 index 0000000..29f7292 --- /dev/null +++ b/Help/release/dev/FindPython-SOABI.rst @@ -0,0 +1,6 @@ +FindPython-SOABI +---------------- + +* The :module:`FindPython3` and :module:`FindPython` modules gained, + respectively, variable ``Python3_SOABI`` and ``Python_SOABI`` giving + the standard extension suffix for modules. diff --git a/Help/release/dev/cpack-nsis-headerimage_var.rst b/Help/release/dev/cpack-nsis-headerimage_var.rst new file mode 100644 index 0000000..d44686b --- /dev/null +++ b/Help/release/dev/cpack-nsis-headerimage_var.rst @@ -0,0 +1,7 @@ +cpack-nsis-headerimage_var +-------------------------- + +* The :cpack_gen:`CPack NSIS Generator` gained a new variable + :variable:`CPACK_NSIS_MUI_HEADERIMAGE` to set the header image. + To not break existing setups, it still defaults to + :variable:`CPACK_PACKAGE_ICON` if the new variable is not set. diff --git a/Help/release/dev/ninja-postgen-commands.rst b/Help/release/dev/ninja-postgen-commands.rst new file mode 100644 index 0000000..85b60dc --- /dev/null +++ b/Help/release/dev/ninja-postgen-commands.rst @@ -0,0 +1,5 @@ +ninja-postgen-commands +---------------------- + +* The :generator:`Ninja` generator learned to perform some post-processing on + the generated files for more consistent builds. diff --git a/Help/release/dev/target_compile_options-BEFORE-keyword.rst b/Help/release/dev/target_compile_options-BEFORE-keyword.rst new file mode 100644 index 0000000..8dafddd --- /dev/null +++ b/Help/release/dev/target_compile_options-BEFORE-keyword.rst @@ -0,0 +1,5 @@ +target_compile_options-BEFORE-keyword +------------------------------------- + +* :command:`target_compile_options` command learns to honor ``BEFORE`` keyword + in all scopes. See policy :policy:`CMP0101`. diff --git a/Help/release/dev/xcode-default-warnings.rst b/Help/release/dev/xcode-default-warnings.rst new file mode 100644 index 0000000..a9a2e49 --- /dev/null +++ b/Help/release/dev/xcode-default-warnings.rst @@ -0,0 +1,5 @@ +xcode-default-warnings +---------------------- + +* The :generator:`Xcode` generator no longer hard-codes ``-Wmost``, + ``-Wno-four-char-constants``, and ``-Wno-unknown-pragmas`` warning flags. diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst index e82867d..8587742 100644 --- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst +++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst @@ -3,7 +3,7 @@ CMAKE_GLOBAL_AUTOGEN_TARGET Switch to enable generation of a global ``autogen`` target. -When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a custom target +When :variable:`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 ``<ORIGIN>_autogen`` targets in the project. By building the global ``autogen`` target, all :prop_tgt:`AUTOMOC` and diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst index e5dda60..c76e2d0 100644 --- a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst +++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst @@ -4,7 +4,7 @@ CMAKE_<LANG>_COMPILER_LAUNCHER Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property. This variable is used to initialize the property on each target as it is created. This is done only when ``<LANG>`` is ``C``, ``CXX``, ``Fortran``, -or ``CUDA``. +``OBJC``, ``OBJCXX``, or ``CUDA``. This variable is initialized to the :envvar:`CMAKE_<LANG>_COMPILER_LAUNCHER` environment variable if it is set. diff --git a/Help/variable/CMAKE_NINJA_CROSS_CONFIG_ENABLE.rst b/Help/variable/CMAKE_NINJA_CROSS_CONFIG_ENABLE.rst new file mode 100644 index 0000000..5c9c1aa --- /dev/null +++ b/Help/variable/CMAKE_NINJA_CROSS_CONFIG_ENABLE.rst @@ -0,0 +1,6 @@ +CMAKE_NINJA_CROSS_CONFIG_ENABLE +------------------------------- + +If this variable is enabled, cross-configuration building is enabled in the +:generator:`Ninja Multi-Config` generator. See the generator's description for +more details. diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 490d659..7d7fb9a 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -186,33 +186,32 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA) "Failed to parsed CUDA nvcc implicit link information:\n${_nvcc_log}\n\n") message(FATAL_ERROR "Failed to extract nvcc implicit link line.") endif() +endif() - set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES ) - if(_nvcc_output_orig MATCHES "#\\\$ +INCLUDES= *([^\n]*)\n") - set(_nvcc_includes "${CMAKE_MATCH_1}") - string(APPEND _nvcc_log " found 'INCLUDES=' string: [${_nvcc_includes}]\n") - else() - set(_nvcc_includes "") - string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") - string(APPEND _nvcc_log " no 'INCLUDES=' string found in nvcc output:${_nvcc_output_log}\n") - endif() - if(_nvcc_includes) - # across all operating system each include directory is prefixed with -I - separate_arguments(_nvcc_output UNIX_COMMAND "${_nvcc_includes}") - foreach(line IN LISTS _nvcc_output) - string(REGEX REPLACE "^-I" "" line "${line}") - get_filename_component(line "${line}" ABSOLUTE) - list(APPEND CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${line}") - endforeach() - - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Parsed CUDA nvcc include information from above output:\n${_nvcc_log}\n${log}\n\n") - else() - file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log - "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n") - endif() - - +set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES ) +string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}") +if(_nvcc_output_orig MATCHES "#\\\$ +INCLUDES= *([^\n]*)\n") + set(_nvcc_includes "${CMAKE_MATCH_1}") + string(APPEND _nvcc_log " found 'INCLUDES=' string: [${_nvcc_includes}]\n") +else() + set(_nvcc_includes "") + string(REPLACE "\n" "\n " _nvcc_output_log "\n${_nvcc_output_orig}") + string(APPEND _nvcc_log " no 'INCLUDES=' string found in nvcc output:${_nvcc_output_log}\n") +endif() +if(_nvcc_includes) + # across all operating system each include directory is prefixed with -I + separate_arguments(_nvcc_output NATIVE_COMMAND "${_nvcc_includes}") + foreach(line IN LISTS _nvcc_output) + string(REGEX REPLACE "^-I" "" line "${line}") + get_filename_component(line "${line}" ABSOLUTE) + list(APPEND CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${line}") + endforeach() + + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Parsed CUDA nvcc include information from above output:\n${_nvcc_log}\n${log}\n\n") +else() + file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log + "Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n") endif() # configure all variables set in this file diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 52d8976..d125791 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -366,6 +366,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} endif() set(cuda_tools "CUDA ${CMAKE_VS_PLATFORM_TOOLSET_CUDA}") set(id_compile "CudaCompile") + set(id_ItemDefinitionGroup_entry "<CudaCompile><AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions></CudaCompile>") set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]]) if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR) set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc</CudaToolkitCustomDir>") @@ -376,7 +377,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS} string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]]) endif() if(CMAKE_VS_PLATFORM_NAME STREQUAL x64) - set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform></CudaCompile>") + set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform><AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions></CudaCompile>") endif() set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart.lib</AdditionalDependencies>") endif() diff --git a/Modules/CMakeOBJCInformation.cmake b/Modules/CMakeOBJCInformation.cmake index cb61cb8..15a3311 100644 --- a/Modules/CMakeOBJCInformation.cmake +++ b/Modules/CMakeOBJCInformation.cmake @@ -110,6 +110,11 @@ if(CMAKE_OBJC_STANDARD_LIBRARIES_INIT) mark_as_advanced(CMAKE_OBJC_STANDARD_LIBRARIES) endif() +if(NOT CMAKE_OBJC_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_OBJC_COMPILER_LAUNCHER}) + set(CMAKE_OBJC_COMPILER_LAUNCHER "$ENV{CMAKE_OBJC_COMPILER_LAUNCHER}" + CACHE STRING "Compiler launcher for OBJC.") +endif() + include(CMakeCommonLanguageInclude) # now define the following rule variables diff --git a/Modules/CMakeOBJCXXInformation.cmake b/Modules/CMakeOBJCXXInformation.cmake index 71ac26a..cb349d7 100644 --- a/Modules/CMakeOBJCXXInformation.cmake +++ b/Modules/CMakeOBJCXXInformation.cmake @@ -203,6 +203,11 @@ if(CMAKE_OBJCXX_STANDARD_LIBRARIES_INIT) mark_as_advanced(CMAKE_OBJCXX_STANDARD_LIBRARIES) endif() +if(NOT CMAKE_OBJCXX_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_OBJCXX_COMPILER_LAUNCHER}) + set(CMAKE_OBJCXX_COMPILER_LAUNCHER "$ENV{CMAKE_OBJCXX_COMPILER_LAUNCHER}" + CACHE STRING "Compiler launcher for OBJCXX.") +endif() + include(CMakeCommonLanguageInclude) # now define the following rules: diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index cbb5323..e4f75d5 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -470,8 +470,10 @@ if(CMAKE_PROJECT_HOMEPAGE_URL) "${CMAKE_PROJECT_HOMEPAGE_URL}") endif() -_cpack_set_default(CPACK_PACKAGE_DESCRIPTION_FILE +set(CPACK_DEFAULT_PACKAGE_DESCRIPTION_FILE "${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt") +_cpack_set_default(CPACK_PACKAGE_DESCRIPTION_FILE + "${CPACK_DEFAULT_PACKAGE_DESCRIPTION_FILE}") _cpack_set_default(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_ROOT}/Templates/CPack.GenericLicense.txt") _cpack_set_default(CPACK_RESOURCE_FILE_README diff --git a/Modules/Compiler/AppleClang-OBJCXX.cmake b/Modules/Compiler/AppleClang-OBJCXX.cmake index 7c6f763..2c084af 100644 --- a/Modules/Compiler/AppleClang-OBJCXX.cmake +++ b/Modules/Compiler/AppleClang-OBJCXX.cmake @@ -1,5 +1,7 @@ include(Compiler/Clang-OBJCXX) +set(CMAKE_OBJCXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") + if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.0) set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "-std=c++98") set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98") diff --git a/Modules/Compiler/GNU-OBJC.cmake b/Modules/Compiler/GNU-OBJC.cmake index 5fba801..fb9b0b2 100644 --- a/Modules/Compiler/GNU-OBJC.cmake +++ b/Modules/Compiler/GNU-OBJC.cmake @@ -1,6 +1,2 @@ include(Compiler/GNU) __compiler_gnu(OBJC) - -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2) - set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") -endif() diff --git a/Modules/Compiler/GNU-OBJCXX.cmake b/Modules/Compiler/GNU-OBJCXX.cmake index 66a547e..06f0244 100644 --- a/Modules/Compiler/GNU-OBJCXX.cmake +++ b/Modules/Compiler/GNU-OBJCXX.cmake @@ -1,8 +1,8 @@ include(Compiler/GNU) -__compiler_gnu(OBJC) +__compiler_gnu(OBJCXX) -if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2) - set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") +if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.2) + set(CMAKE_OBJCXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden") endif() if(NOT CMAKE_OBJCXX_LINK_FLAGS) diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index ad7f084..fb1fc20 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -4,7 +4,7 @@ set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True) set(CMAKE_CUDA_VERBOSE_FLAG "-v") set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v") -if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 10.2) +if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) # The -forward-unknown-to-host-compiler flag was only # added to nvcc in 10.2 so before that we had no good # way to invoke the CUDA compiler and propagate unknown @@ -20,7 +20,7 @@ else() set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "") endif() -if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 10.2) +if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89) # The -MD flag was only added to nvcc in 10.2 so # before that we had to invoke the compiler twice # to get header dependency information diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index 6b1da4b..d1257c9 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -1059,32 +1059,7 @@ macro(_MPI_assemble_libraries LANG) endif() endmacro() -macro(_MPI_assemble_include_dirs LANG) - if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}") - set(MPI_${LANG}_INCLUDE_DIRS "") - else() - set(MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}") - if("${LANG}" MATCHES "(C|CXX)") - if(MPI_${LANG}_HEADER_DIR) - list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}") - endif() - else() # Fortran - if(MPI_${LANG}_F77_HEADER_DIR) - list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_F77_HEADER_DIR}") - endif() - if(MPI_${LANG}_MODULE_DIR AND NOT "${MPI_${LANG}_MODULE_DIR}" IN_LIST MPI_${LANG}_INCLUDE_DIRS) - list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_MODULE_DIR}") - endif() - endif() - if(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS) - foreach(MPI_ADDITIONAL_INC_DIR IN LISTS MPI_${LANG}_ADDITIONAL_INCLUDE_VARS) - list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${MPI_ADDITIONAL_INC_DIR}_INCLUDE_DIR}") - endforeach() - endif() - endif() -endmacro() - -function(_MPI_split_include_dirs LANG) +macro(_MPI_split_include_dirs LANG) if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}") return() endif() @@ -1093,6 +1068,9 @@ function(_MPI_split_include_dirs LANG) list(APPEND MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_INCLUDE_PATH}") endif() + # Preserve the include dirs before stripping out the components + set(MPI_${LANG}_INCLUDE_DIRS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}) + # We try to find the headers/modules among those paths (and system paths) # For C/C++, we just need to have a look for mpi.h. if("${LANG}" MATCHES "(C|CXX)") @@ -1103,6 +1081,7 @@ function(_MPI_split_include_dirs LANG) if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS) list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}") endif() + # Fortran is more complicated here: An implementation could provide # any of the Fortran 77/90/2008 APIs for MPI. For example, MSMPI # only provides Fortran 77 and - if mpi.f90 is built - potentially @@ -1123,6 +1102,7 @@ function(_MPI_split_include_dirs LANG) endif() mark_as_advanced(MPI_${LANG}_F77_HEADER_DIR MPI_${LANG}_MODULE_DIR) endif() + # Remove duplicates and default system directories from the list. if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS) list(REMOVE_DUPLICATES MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS) @@ -1130,8 +1110,9 @@ function(_MPI_split_include_dirs LANG) list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_IMPLICIT_INC_DIR}) endforeach() endif() + set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories" FORCE) -endfunction() +endmacro() macro(_MPI_create_imported_target LANG) if(NOT TARGET MPI::MPI_${LANG}) @@ -1495,7 +1476,6 @@ foreach(LANG IN ITEMS C CXX Fortran) endif() _MPI_split_include_dirs(${LANG}) - _MPI_assemble_include_dirs(${LANG}) _MPI_assemble_libraries(${LANG}) _MPI_adjust_compile_definitions(${LANG}) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index c8cae2e..92ee729 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -241,6 +241,8 @@ if(NOT MATLAB_ADDITIONAL_VERSIONS) endif() set(MATLAB_VERSIONS_MAPPING + "R2019b=9.7" + "R2019a=9.6" "R2018b=9.5" "R2018a=9.4" "R2017b=9.3" @@ -974,10 +976,19 @@ function(matlab_add_mex) endif() if(NOT Matlab_VERSION_STRING VERSION_LESS "9.1") # For 9.1 (R2016b) and newer, add version source file - # TODO: check the file extensions in ${${prefix}_SRC} to see if they're C or C++ files - # Currently, the C and C++ versions of the version files are identical, so this doesn't matter. - set(MEX_VERSION_FILE "${Matlab_ROOT_DIR}/extern/version/c_mexapi_version.c") - #set(MEX_VERSION_FILE "${Matlab_ROOT_DIR}/extern/version/cpp_mexapi_version.cpp") + # Add the correct version file depending on which languages are enabled in the project + if(CMAKE_C_COMPILER_LOADED) + # If C is enabled, use the .c file as it will work fine also with C++ + set(MEX_VERSION_FILE "${Matlab_ROOT_DIR}/extern/version/c_mexapi_version.c") + elseif(CMAKE_CXX_COMPILER_LOADED) + # If C is not enabled, check if CXX is enabled and use the .cpp file + # to avoid that the .c file is silently ignored + set(MEX_VERSION_FILE "${Matlab_ROOT_DIR}/extern/version/cpp_mexapi_version.cpp") + else() + # If neither C or CXX is enabled, warn because we cannot add the source. + # TODO: add support for fortran mex files + message(WARNING "[MATLAB] matlab_add_mex requires that at least C or CXX are enabled languages") + endif() endif() if(NOT Matlab_VERSION_STRING VERSION_LESS "9.4") # For 9.4 (R2018a) and newer, add API macro diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake index 3688ae9..043fc6c 100644 --- a/Modules/FindOpenSSL.cmake +++ b/Modules/FindOpenSSL.cmake @@ -65,7 +65,7 @@ macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library) endif() endmacro() -function(_OpenSSL_add_dependencies libraries_var library) +function(_OpenSSL_add_dependencies libraries_var) if(CMAKE_THREAD_LIBS_INIT) list(APPEND ${libraries_var} ${CMAKE_THREAD_LIBS_INIT}) endif() @@ -341,13 +341,14 @@ else() endif() -# compat defines set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY}) set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) +set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES} ) _OpenSSL_test_and_find_dependencies("${OPENSSL_SSL_LIBRARY}" "${OPENSSL_CRYPTO_LIBRARY}") if(_OpenSSL_has_dependencies) - _OpenSSL_add_dependencies( OPENSSL_SSL_LIBRARIES "${OPENSSL_SSL_LIBRARY}" ) - _OpenSSL_add_dependencies( OPENSSL_CRYPTO_LIBRARIES "${OPENSSL_CRYPTO_LIBRARY}" ) + _OpenSSL_add_dependencies( OPENSSL_SSL_LIBRARIES ) + _OpenSSL_add_dependencies( OPENSSL_CRYPTO_LIBRARIES ) + _OpenSSL_add_dependencies( OPENSSL_LIBRARIES ) endif() function(from_hex HEX DEC) @@ -417,9 +418,6 @@ if(OPENSSL_INCLUDE_DIR AND EXISTS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h") endif () endif () -set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES} ) -list(REMOVE_DUPLICATES OPENSSL_LIBRARIES) - foreach(_comp IN LISTS OpenSSL_FIND_COMPONENTS) if(_comp STREQUAL "Crypto") if(EXISTS "${OPENSSL_INCLUDE_DIR}" AND diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake index 177ed58..be272e1 100644 --- a/Modules/FindPython.cmake +++ b/Modules/FindPython.cmake @@ -93,6 +93,13 @@ This module will set the following variables in your project Information returned by ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. +``Python_SOABI`` + Extension suffix for modules. + + Information returned by + ``distutils.sysconfig.get_config_flag('SOABI')`` or computed from + ``distutils.sysconfig.get_config_flag('EXT_SUFFIX')`` or + ``python-config --extension-suffix``. ``Python_Compiler_FOUND`` System has the Python compiler. ``Python_COMPILER`` diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 0163d56..7c20512 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -62,6 +62,9 @@ macro (_PYTHON_FIND_FRAMEWORKS) ${CMAKE_SYSTEM_FRAMEWORK_PATH}) list (REMOVE_DUPLICATES _pff_frameworks) foreach (_pff_framework IN LISTS _pff_frameworks) + if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework) + list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework) + endif() if (EXISTS ${_pff_framework}/Python.framework) list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework) endif() @@ -244,12 +247,16 @@ endfunction() function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) unset (${_PYTHON_PGCV_VALUE} PARENT_SCOPE) - if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS)$") + if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS|SOABI)$") return() endif() if (_${_PYTHON_PREFIX}_CONFIG) - set (config_flag "--${NAME}") + if (NAME STREQUAL "SOABI") + set (config_flag "--extension-suffix") + else() + set (config_flag "--${NAME}") + endif() string (TOLOWER "${config_flag}" config_flag) execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" ${config_flag} RESULT_VARIABLE _result @@ -264,6 +271,9 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) string (REGEX MATCHALL "(-I|-iwithsysroot)[ ]*[^ ]+" _values "${_values}") string (REGEX REPLACE "(-I|-iwithsysroot)[ ]*" "" _values "${_values}") list (REMOVE_DUPLICATES _values) + elseif (NAME STREQUAL "SOABI") + # clean-up: remove prefix character and suffix + string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\.(so|pyd))$" "\\1" _values "${_values}") endif() endif() endif() @@ -289,6 +299,25 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME) if (_result) unset (_values) endif() + elseif (NAME STREQUAL "SOABI") + execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _soabi + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (_result) + unset (_values) + else() + list (GET _soabi 0 _values) + if (NOT _values) + # try to compute SOABI from EXT_SUFFIX + list (GET _soabi 1 _values) + if (_values) + # clean-up: remove prefix character and suffix + string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\.(so|pyd))$" "\\1" _values "${_values}") + endif() + endif() + endif() else() set (config_flag "${NAME}") if (NAME STREQUAL "CONFIGDIR") @@ -745,6 +774,7 @@ else() _python_get_abiflags (_${_PYTHON_PREFIX}_ABIFLAGS) endif() endif() +unset (${_PYTHON_PREFIX}_SOABI) # Define lookup strategy if (_${_PYTHON_PREFIX}_LOOKUP_POLICY STREQUAL "NEW") @@ -1267,7 +1297,6 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) # retrieve various package installation directories execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))" - RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS ERROR_QUIET) @@ -1282,6 +1311,10 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) unset (${_PYTHON_PREFIX}_SITELIB) unset (${_PYTHON_PREFIX}_SITEARCH) endif() + + if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL 3) + _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) + endif() else() unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE) unset (${_PYTHON_PREFIX}_INTERPRETER_ID) @@ -1522,9 +1555,13 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE) unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE) unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE) - unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE) endif() endif() + if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT _${_PYTHON_PREFIX}_INCLUDE_DIR) + unset (_${_PYTHON_PREFIX}_CONFIG CACHE) + unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE) + endif() + if (DEFINED ${_PYTHON_PREFIX}_LIBRARY AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}") set (_${_PYTHON_PREFIX}_LIBRARY_RELEASE "${${_PYTHON_PREFIX}_LIBRARY}" CACHE INTERNAL "") @@ -2148,6 +2185,11 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS endif() endif() + if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL 3 + AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI) + _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI) + endif() + if (${_PYTHON_PREFIX}_Development_FOUND) # compute and save development signature string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}") @@ -2166,6 +2208,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE ${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG _${_PYTHON_PREFIX}_INCLUDE_DIR + _${_PYTHON_PREFIX}_CONFIG _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE) endif() @@ -2425,5 +2468,3 @@ if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK) else() unset (CMAKE_FIND_FRAMEWORK) endif() - -unset (_${_PYTHON_PREFIX}_CONFIG CACHE) diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake index 0a96fad..00c354e 100644 --- a/Modules/FindPython3.cmake +++ b/Modules/FindPython3.cmake @@ -94,6 +94,13 @@ This module will set the following variables in your project Information returned by ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``. +``Python3_SOABI`` + Extension suffix for modules. + + Information returned by + ``distutils.sysconfig.get_config_flag('SOABI')`` or computed from + ``distutils.sysconfig.get_config_flag('EXT_SUFFIX')`` or + ``python3-config --extension-suffix``. ``Python3_Compiler_FOUND`` System has the Python 3 compiler. ``Python3_COMPILER`` diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake index fe0fe09..c74c324 100644 --- a/Modules/Internal/CPack/CPackDeb.cmake +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -498,6 +498,11 @@ function(cpack_deb_prepare_package_vars) # Description: (mandatory) # Try package description first + if(CPACK_USED_DEFAULT_PACKAGE_DESCRIPTION_FILE) + set(_desc_fallback) + else() + set(_desc_fallback "CPACK_PACKAGE_DESCRIPTION") + endif() if(CPACK_DEB_PACKAGE_COMPONENT) cpack_deb_variable_fallback("CPACK_DEBIAN_PACKAGE_DESCRIPTION" "CPACK_DEBIAN_${_local_component_name}_DESCRIPTION" @@ -505,11 +510,13 @@ function(cpack_deb_prepare_package_vars) else() cpack_deb_variable_fallback("CPACK_DEBIAN_PACKAGE_DESCRIPTION" "CPACK_DEBIAN_PACKAGE_DESCRIPTION" - "CPACK_PACKAGE_DESCRIPTION") + ${_desc_fallback}) endif() # Still no description? ... and description file has set ... - if(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION AND CPACK_PACKAGE_DESCRIPTION_FILE) + if(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION + AND CPACK_PACKAGE_DESCRIPTION_FILE + AND NOT CPACK_PACKAGE_DESCRIPTION_FILE STREQUAL CPACK_DEFAULT_PACKAGE_DESCRIPTION_FILE) # Read `CPACK_PACKAGE_DESCRIPTION_FILE` then... file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_DEBIAN_PACKAGE_DESCRIPTION) endif() diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in index 23bb0018..660bfa3 100644 --- a/Modules/Internal/CPack/NSIS.template.in +++ b/Modules/Internal/CPack/NSIS.template.in @@ -524,14 +524,6 @@ FunctionEnd !endif ;-------------------------------- -; Installation types -@CPACK_NSIS_INSTALLATION_TYPES@ - -;-------------------------------- -; Component sections -@CPACK_NSIS_COMPONENT_SECTIONS@ - -;-------------------------------- ; Define some macro setting for the gui @CPACK_NSIS_INSTALLER_MUI_ICON_CODE@ @CPACK_NSIS_INSTALLER_ICON_CODE@ @@ -621,7 +613,6 @@ FunctionEnd !insertmacro MUI_LANGUAGE "Ukrainian" !insertmacro MUI_LANGUAGE "Welsh" - ;-------------------------------- ;Reserve Files @@ -632,6 +623,17 @@ FunctionEnd ReserveFile "NSIS.InstallOptions.ini" !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS + ; for UserInfo::GetName and UserInfo::GetAccountType + ReserveFile /plugin 'UserInfo.dll' + +;-------------------------------- +; Installation types +@CPACK_NSIS_INSTALLATION_TYPES@ + +;-------------------------------- +; Component sections +@CPACK_NSIS_COMPONENT_SECTIONS@ + ;-------------------------------- ;Installer Sections diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index 1482d76..e5a57b5 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -157,6 +157,10 @@ if(_CMAKE_OSX_SYSROOT_PATH) endif() endforeach() endif() +if (OSX_DEVELOPER_ROOT AND EXISTS "${OSX_DEVELOPER_ROOT}/Library/Frameworks") + list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH + ${OSX_DEVELOPER_ROOT}/Library/Frameworks) +endif() list(APPEND CMAKE_SYSTEM_FRAMEWORK_PATH /Library/Frameworks /Network/Library/Frameworks diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake index cf85367..235d9ce 100644 --- a/Modules/Platform/Windows-GNU.cmake +++ b/Modules/Platform/Windows-GNU.cmake @@ -152,7 +152,7 @@ macro(__windows_compiler_gnu_abi lang) # Query the VS Installer tool for locations of VS 2017 and above. set(_vs_installer_paths "") - foreach(vs RANGE 15 15 -1) # change the first number to the largest supported version + foreach(vs RANGE 16 15 -1) # change the first number to the largest supported version cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR) if(_vs_dir) list(APPEND _vs_installer_paths "${_vs_dir}/VC/Auxiliary/Build") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 8cc0ddc..985303c 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 16) -set(CMake_VERSION_PATCH 20200109) +set(CMake_VERSION_PATCH 20200114) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 6003493..712eb77 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -125,7 +125,7 @@ int cmCPackGenerator::PrepareNames() cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for: CPACK_PACKAGE_DESCRIPTION_FILE" << std::endl); const char* descFileName = this->GetOption("CPACK_PACKAGE_DESCRIPTION_FILE"); - if (descFileName) { + if (descFileName && !this->GetOption("CPACK_PACKAGE_DESCRIPTION")) { cmCPackLogger(cmCPackLog::LOG_DEBUG, "Look for: " << descFileName << std::endl); if (!cmSystemTools::FileExists(descFileName)) { @@ -149,7 +149,12 @@ int cmCPackGenerator::PrepareNames() while (ifs && cmSystemTools::GetLineFromStream(ifs, line)) { ostr << cmXMLSafe(line) << std::endl; } - this->SetOptionIfNotSet("CPACK_PACKAGE_DESCRIPTION", ostr.str().c_str()); + this->SetOption("CPACK_PACKAGE_DESCRIPTION", ostr.str().c_str()); + const char* defFileName = + this->GetOption("CPACK_DEFAULT_PACKAGE_DESCRIPTION_FILE"); + if (defFileName && !strcmp(defFileName, descFileName)) { + this->SetOption("CPACK_USED_DEFAULT_PACKAGE_DESCRIPTION_FILE", "ON"); + } } if (!this->GetOption("CPACK_PACKAGE_DESCRIPTION")) { cmCPackLogger( diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 4702639..363f536 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -139,10 +139,15 @@ int cmCPackNSISGenerator::PackageFiles() this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_ICON_CODE", installerIconCode.c_str()); } - if (this->IsSet("CPACK_PACKAGE_ICON")) { - std::string installerIconCode = - cmStrCat("!define MUI_HEADERIMAGE_BITMAP \"", - this->GetOption("CPACK_PACKAGE_ICON"), "\"\n"); + std::string installerHeaderImage; + if (this->IsSet("CPACK_NSIS_MUI_HEADERIMAGE")) { + installerHeaderImage = this->GetOption("CPACK_NSIS_MUI_HEADERIMAGE"); + } else if (this->IsSet("CPACK_PACKAGE_ICON")) { + installerHeaderImage = this->GetOption("CPACK_PACKAGE_ICON"); + } + if (!installerHeaderImage.empty()) { + std::string installerIconCode = cmStrCat( + "!define MUI_HEADERIMAGE_BITMAP \"", installerHeaderImage, "\"\n"); this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE", installerIconCode.c_str()); } diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 46b00b1..acb75b2 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -7,6 +7,7 @@ #include <utility> #include <cm/memory> +#include <cm/vector> #include "cm_static_string_view.hxx" @@ -174,7 +175,7 @@ void cmCTestSubmitCommand::CheckArguments( this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS"); this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES"); - cmEraseIf(this->Parts, [this](std::string const& arg) -> bool { + cm::erase_if(this->Parts, [this](std::string const& arg) -> bool { cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str()); if (p == cmCTest::PartCount) { std::ostringstream e; @@ -185,7 +186,7 @@ void cmCTestSubmitCommand::CheckArguments( return false; }); - cmEraseIf(this->Files, [this](std::string const& arg) -> bool { + cm::erase_if(this->Files, [this](std::string const& arg) -> bool { if (!cmSystemTools::FileExists(arg)) { std::ostringstream e; e << "File \"" << arg << "\" does not exist. Cannot submit " diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx index d0e3848..eaef1ca 100644 --- a/Source/CTest/cmCTestUploadCommand.cxx +++ b/Source/CTest/cmCTestUploadCommand.cxx @@ -4,11 +4,11 @@ #include <set> #include <sstream> -#include <vector> + +#include <cm/vector> #include "cm_static_string_view.hxx" -#include "cmAlgorithms.h" #include "cmCTest.h" #include "cmCTestUploadHandler.h" #include "cmMakefile.h" @@ -24,7 +24,7 @@ void cmCTestUploadCommand::BindArguments() void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&) { - cmEraseIf(this->Files, [this](std::string const& arg) -> bool { + cm::erase_if(this->Files, [this](std::string const& arg) -> bool { if (!cmSystemTools::FileExists(arg)) { std::ostringstream e; e << "File \"" << arg << "\" does not exist. Cannot submit " diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index a179acb..3b0a223 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -37,12 +37,6 @@ FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last) return first; } -template <typename Container, typename Predicate> -void cmEraseIf(Container& cont, Predicate pred) -{ - cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); -} - template <typename Range, typename Key> auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>) -> decltype(range.exists(key)) diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx index e3536d5..265941a 100644 --- a/Source/cmCacheManager.cxx +++ b/Source/cmCacheManager.cxx @@ -190,7 +190,7 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey, if (entryKey.size() > plen && *(end - plen) == '-' && strcmp(end - plen + 1, *p) == 0) { std::string key = entryKey.substr(0, entryKey.size() - plen); - cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str()); + cmCacheManager::CacheIterator it = this->GetCacheIterator(key); if (it.IsAtEnd()) { // Create an entry and store the property. CacheEntry& ne = this->Cache[key]; @@ -497,9 +497,15 @@ cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry( return nullptr; } -cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(const char* key) +cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator( + const std::string& key) { - return { *this, key }; + return { *this, key.c_str() }; +} + +cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator() +{ + return { *this, nullptr }; } const std::string* cmCacheManager::GetInitializedCacheValue( @@ -638,20 +644,21 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop, } void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop, - const char* value, + const std::string& value, bool asString) { if (prop == "TYPE") { - this->Type = cmState::StringToCacheEntryType(value ? value : "STRING"); + this->Type = cmState::StringToCacheEntryType(!value.empty() ? value.c_str() + : "STRING"); } else if (prop == "VALUE") { - if (value) { - if (!this->Value.empty() && *value && !asString) { + if (!value.empty()) { + if (!this->Value.empty() && !asString) { this->Value += ";"; } this->Value += value; } } else { - this->Properties.AppendProperty(prop, value, asString); + this->Properties.AppendProperty(prop, value.c_str(), asString); } } @@ -673,7 +680,7 @@ void cmCacheManager::CacheIterator::SetProperty(const std::string& p, } void cmCacheManager::CacheIterator::AppendProperty(const std::string& p, - const char* v, + const std::string& v, bool asString) { if (!this->IsAtEnd()) { diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h index faa60c5..d8be991 100644 --- a/Source/cmCacheManager.h +++ b/Source/cmCacheManager.h @@ -39,7 +39,7 @@ private: std::vector<std::string> GetPropertyList() const; const char* GetProperty(const std::string&) const; void SetProperty(const std::string& property, const char* value); - void AppendProperty(const std::string& property, const char* value, + void AppendProperty(const std::string& property, const std::string& value, bool asString = false); bool Initialized = false; }; @@ -58,10 +58,10 @@ public: bool GetPropertyAsBool(const std::string&) const; bool PropertyExists(const std::string&) const; void SetProperty(const std::string& property, const char* value); - void AppendProperty(const std::string& property, const char* value, + void AppendProperty(const std::string& property, const std::string& value, bool asString = false); void SetProperty(const std::string& property, bool value); - const char* GetValue() const { return this->GetEntry().Value.c_str(); } + const std::string& GetValue() const { return this->GetEntry().Value; } bool GetValueAsBool() const; void SetValue(const char*); cmStateEnums::CacheEntryType GetType() const @@ -111,7 +111,8 @@ public: void PrintCache(std::ostream&) const; //! Get the iterator for an entry with a given key. - cmCacheManager::CacheIterator GetCacheIterator(const char* key = nullptr); + cmCacheManager::CacheIterator GetCacheIterator(const std::string& key); + cmCacheManager::CacheIterator GetCacheIterator(); //! Remove an entry from the cache void RemoveCacheEntry(const std::string& key); @@ -124,52 +125,52 @@ public: const char* GetCacheEntryValue(const std::string& key) { - cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str()); + cmCacheManager::CacheIterator it = this->GetCacheIterator(key); if (it.IsAtEnd()) { return nullptr; } - return it.GetValue(); + return it.GetValue().c_str(); } const char* GetCacheEntryProperty(std::string const& key, std::string const& propName) { - return this->GetCacheIterator(key.c_str()).GetProperty(propName); + return this->GetCacheIterator(key).GetProperty(propName); } cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) { - return this->GetCacheIterator(key.c_str()).GetType(); + return this->GetCacheIterator(key).GetType(); } bool GetCacheEntryPropertyAsBool(std::string const& key, std::string const& propName) { - return this->GetCacheIterator(key.c_str()).GetPropertyAsBool(propName); + return this->GetCacheIterator(key).GetPropertyAsBool(propName); } void SetCacheEntryProperty(std::string const& key, std::string const& propName, std::string const& value) { - this->GetCacheIterator(key.c_str()).SetProperty(propName, value.c_str()); + this->GetCacheIterator(key).SetProperty(propName, value.c_str()); } void SetCacheEntryBoolProperty(std::string const& key, std::string const& propName, bool value) { - this->GetCacheIterator(key.c_str()).SetProperty(propName, value); + this->GetCacheIterator(key).SetProperty(propName, value); } void SetCacheEntryValue(std::string const& key, std::string const& value) { - this->GetCacheIterator(key.c_str()).SetValue(value.c_str()); + this->GetCacheIterator(key).SetValue(value.c_str()); } void RemoveCacheEntryProperty(std::string const& key, std::string const& propName) { - this->GetCacheIterator(key.c_str()).SetProperty(propName, nullptr); + this->GetCacheIterator(key).SetProperty(propName, nullptr); } void AppendCacheEntryProperty(std::string const& key, @@ -177,8 +178,7 @@ public: std::string const& value, bool asString = false) { - this->GetCacheIterator(key.c_str()) - .AppendProperty(propName, value.c_str(), asString); + this->GetCacheIterator(key).AppendProperty(propName, value, asString); } std::vector<std::string> GetCacheEntryKeys() diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 9eb256b..297c72b 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -161,6 +161,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) } this->DebugMode = ComputeIfDebugModeWanted(); + this->DebugBuffer.clear(); // Lookup target architecture, if any. if (const char* arch = @@ -575,6 +576,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) } this->AppendSuccessInformation(); + return loadedPackage; } @@ -708,7 +710,7 @@ bool cmFindPackageCommand::FindModule(bool& found) debugBuffer = cmStrCat(debugBuffer, "The file was found at\n ", mfile, "\n"); } - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } if (!mfile.empty()) { @@ -841,6 +843,11 @@ bool cmFindPackageCommand::HandlePackageMode( result = false; } + if (this->DebugMode) { + this->DebugMessage(this->DebugBuffer); + this->DebugBuffer.clear(); + } + // package not found if (result && !found) { // warn if package required or neither quiet nor in config mode @@ -1001,6 +1008,11 @@ bool cmFindPackageCommand::FindConfig() // Look for the project's configuration file. bool found = false; + if (this->DebugMode) { + this->DebugBuffer = cmStrCat(this->DebugBuffer, + "find_package considered the following " + "locations for the Config module:\n"); + } // Search for frameworks. if (!found && (this->SearchFrameworkFirst || this->SearchFrameworkOnly)) { @@ -1027,6 +1039,16 @@ bool cmFindPackageCommand::FindConfig() found = this->FindAppBundleConfig(); } + if (this->DebugMode) { + if (found) { + this->DebugBuffer = cmStrCat( + this->DebugBuffer, "The file was found at\n ", this->FileFound, "\n"); + } else { + this->DebugBuffer = + cmStrCat(this->DebugBuffer, "The file was not found.\n"); + } + } + // Store the entry in the cache so it can be set by the user. std::string init; if (found) { @@ -1040,6 +1062,7 @@ bool cmFindPackageCommand::FindConfig() // We force the value since we do not get here if it was already set. this->Makefile->AddCacheDefinition(this->Variable, init.c_str(), help.c_str(), cmStateEnums::PATH, true); + return found; } @@ -1244,7 +1267,7 @@ void cmFindPackageCommand::FillPrefixesPackageRoot() std::string debugBuffer = "<PackageName>_ROOT CMake variable " "[CMAKE_FIND_USE_PACKAGE_ROOT_PATH].\n"; collectPathsForDebug(debugBuffer, paths); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1280,7 +1303,7 @@ void cmFindPackageCommand::FillPrefixesCMakeEnvironment() "\nCMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH env " "variables [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].\n"); collectPathsForDebug(debugBuffer, paths, debugOffset); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1304,7 +1327,7 @@ void cmFindPackageCommand::FillPrefixesCMakeVariable() "\nCMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH variables " "[CMAKE_FIND_USE_CMAKE_PATH].\n"); collectPathsForDebug(debugBuffer, paths, debugOffset); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1329,7 +1352,7 @@ void cmFindPackageCommand::FillPrefixesSystemEnvironment() std::string debugBuffer = "Standard system environment variables " "[CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH].\n"; collectPathsForDebug(debugBuffer, paths); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1359,7 +1382,7 @@ void cmFindPackageCommand::FillPrefixesUserRegistry() "CMake User Package Registry [CMAKE_FIND_USE_PACKAGE_REGISTRY].\n"; collectPathsForDebug(debugBuffer, this->LabeledPaths[PathLabel::UserRegistry]); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1379,7 +1402,7 @@ void cmFindPackageCommand::FillPrefixesSystemRegistry() "[CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY].\n"; collectPathsForDebug(debugBuffer, this->LabeledPaths[PathLabel::SystemRegistry]); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1558,7 +1581,7 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable() std::string debugBuffer = "CMake variables defined in the Platform file " "[CMAKE_FIND_USE_CMAKE_SYSTEM_PATH].\n"; collectPathsForDebug(debugBuffer, paths); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1573,7 +1596,7 @@ void cmFindPackageCommand::FillPrefixesUserGuess() std::string debugBuffer = "Paths specified by the find_package PATHS option.\n"; collectPathsForDebug(debugBuffer, paths); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1588,7 +1611,7 @@ void cmFindPackageCommand::FillPrefixesUserHints() std::string debugBuffer = "Paths specified by the find_package HINTS option.\n"; collectPathsForDebug(debugBuffer, paths); - this->DebugMessage(debugBuffer); + this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n"); } } @@ -1634,8 +1657,7 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir, for (std::string const& c : this->Configs) { file = cmStrCat(dir, '/', c); if (this->DebugMode) { - std::string msg = "Checking file [" + file + "]\n"; - this->DebugMessage(msg); + this->DebugBuffer = cmStrCat(this->DebugBuffer, " ", file, "\n"); } if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) { // Allow resolving symlinks when the config file is found through a link diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index a65a292..ae9ade7 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -183,6 +183,7 @@ private: std::vector<std::string> Names; std::vector<std::string> Configs; std::set<std::string> IgnoredPaths; + std::string DebugBuffer; /*! the selected sortOrder (None by default)*/ SortOrderType SortOrder; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 4d43566..922beb7 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -530,6 +530,35 @@ void cmGlobalNinjaGenerator::Generate() if (!this->WriteDefaultBuildFile()) { return; } + + auto run_ninja_tool = [this](char const* tool) { + std::vector<std::string> command; + command.push_back(this->NinjaCommand); + command.emplace_back("-t"); + command.emplace_back(tool); + std::string error; + if (!cmSystemTools::RunSingleCommand(command, nullptr, &error, nullptr, + nullptr, + cmSystemTools::OUTPUT_NONE)) { + this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, + "Running\n '" + + cmJoin(command, "' '") + + "'\n" + "failed with:\n " + + error); + cmSystemTools::SetFatalErrorOccured(); + } + }; + + if (this->NinjaSupportsCleanDeadTool) { + run_ninja_tool("cleandead"); + } + if (this->NinjaSupportsUnconditionalRecompactTool) { + run_ninja_tool("recompact"); + } + if (this->NinjaSupportsRestatTool) { + run_ninja_tool("restat"); + } } bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf) @@ -593,6 +622,16 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures() } } } + this->NinjaSupportsCleanDeadTool = !cmSystemTools::VersionCompare( + cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), + RequiredNinjaVersionForCleanDeadTool().c_str()); + this->NinjaSupportsUnconditionalRecompactTool = + !cmSystemTools::VersionCompare( + cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), + RequiredNinjaVersionForUnconditionalRecompactTool().c_str()); + this->NinjaSupportsRestatTool = !cmSystemTools::VersionCompare( + cmSystemTools::OP_LESS, this->NinjaVersion.c_str(), + RequiredNinjaVersionForRestatTool().c_str()); } bool cmGlobalNinjaGenerator::CheckLanguages( @@ -1153,7 +1192,10 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) this->AppendTargetOutputs(ta.second.GeneratorTarget, build.ExplicitDeps, ta.second.Config); } - this->WriteBuild(os, build); + this->WriteBuild(this->EnableCrossConfigBuild() + ? os + : *this->GetConfigFileStream(ta.second.Config), + build); } if (this->IsMultiConfig()) { @@ -1220,7 +1262,10 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) } } // Write target - this->WriteBuild(os, build); + this->WriteBuild(this->EnableCrossConfigBuild() + ? os + : *this->GetConfigFileStream(config), + build); } // Add shortcut target @@ -1235,7 +1280,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) } // Add target for all configs - if (this->IsMultiConfig()) { + if (this->EnableCrossConfigBuild()) { build.ExplicitDeps.clear(); for (auto const& config : configs) { build.ExplicitDeps.push_back(this->BuildAlias( @@ -1243,7 +1288,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) } build.Outputs.front() = this->BuildAlias( this->ConvertToNinjaPath(currentBinaryDir + "/all"), "all"); - this->WriteBuild(*this->GetCommonFileStream(), build); + this->WriteBuild(os, build); } } } @@ -1671,6 +1716,9 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) config)); } for (auto const& fileConfig : configs) { + if (fileConfig != config && !this->EnableCrossConfigBuild()) { + continue; + } if (this->IsMultiConfig()) { build.Variables["FILE_ARG"] = cmStrCat( "-f ", cmGlobalNinjaMultiGenerator::GetNinjaFilename(fileConfig)); @@ -1679,7 +1727,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) } } - if (this->IsMultiConfig()) { + if (this->EnableCrossConfigBuild()) { build.Outputs.front() = this->BuildAlias( this->NinjaOutputPath(this->GetCleanTargetName()), "all"); build.ExplicitDeps.clear(); @@ -2153,6 +2201,12 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( return true; } +bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const +{ + return this->IsMultiConfig() && + this->Makefiles.front()->IsOn("CMAKE_NINJA_CROSS_CONFIG_ENABLE"); +} + int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg, std::vector<std::string>::const_iterator argEnd) { diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 2115042..3545f1e 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -349,6 +349,12 @@ public: return "1.9"; } static std::string RequiredNinjaVersionForDyndeps() { return "1.10"; } + static std::string RequiredNinjaVersionForRestatTool() { return "1.10"; } + static std::string RequiredNinjaVersionForUnconditionalRecompactTool() + { + return "1.10"; + } + static std::string RequiredNinjaVersionForCleanDeadTool() { return "1.10"; } bool SupportsConsolePool() const; bool SupportsImplicitOuts() const; bool SupportsManifestRestat() const; @@ -389,6 +395,8 @@ public: return this->Configs[config].ByproductsForCleanTarget; } + bool EnableCrossConfigBuild() const; + protected: void Generate() override; @@ -489,6 +497,9 @@ private: bool NinjaSupportsManifestRestat = false; bool NinjaSupportsMultilineDepfile = false; bool NinjaSupportsDyndeps = false; + bool NinjaSupportsRestatTool = false; + bool NinjaSupportsUnconditionalRecompactTool = false; + bool NinjaSupportsCleanDeadTool = false; private: void InitOutputPathPrefix(); diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index 779753e..f549b6a 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -2,7 +2,8 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmGlobalVisualStudio14Generator.h" -#include "cmAlgorithms.h" +#include <cm/vector> + #include "cmDocumentationEntry.h" #include "cmLocalVisualStudio10Generator.h" #include "cmMakefile.h" @@ -303,7 +304,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion() // Skip SDKs that do not contain <um/windows.h> because that indicates that // only the UCRT MSIs were installed for them. - cmEraseIf(sdks, NoWindowsH()); + cm::erase_if(sdks, NoWindowsH()); // Only use the filename, which will be the SDK version. for (std::string& i : sdks) { @@ -313,7 +314,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion() // Skip SDKs that cannot be used with our toolset. std::string maxVersion = this->GetWindows10SDKMaxVersion(); if (!maxVersion.empty()) { - cmEraseIf(sdks, WindowsSDKTooRecent(maxVersion)); + cm::erase_if(sdks, WindowsSDKTooRecent(maxVersion)); } // Sort the results to make sure we select the most recent one. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 607b2b3..f887284 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2357,9 +2357,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, buildSettings->AddAttribute("SECTORDER_FLAGS", this->CreateString("")); buildSettings->AddAttribute("USE_HEADERMAP", this->CreateString("NO")); cmXCodeObject* group = this->CreateObject(cmXCodeObject::OBJECT_LIST); - group->AddObject(this->CreateString("-Wmost")); - group->AddObject(this->CreateString("-Wno-four-char-constants")); - group->AddObject(this->CreateString("-Wno-unknown-pragmas")); group->AddObject(this->CreateString("$(inherited)")); buildSettings->AddAttribute("WARNING_CFLAGS", group); diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx index d845652..847334b 100644 --- a/Source/cmLinkLineDeviceComputer.cxx +++ b/Source/cmLinkLineDeviceComputer.cxx @@ -183,29 +183,29 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg, return cmIsOn(resolveDeviceSymbols); } - if (const char* separableCompilation = - target.GetProperty("CUDA_SEPARABLE_COMPILATION")) { - if (cmIsOn(separableCompilation)) { - bool doDeviceLinking = false; - switch (target.GetType()) { - case cmStateEnums::SHARED_LIBRARY: - case cmStateEnums::MODULE_LIBRARY: - case cmStateEnums::EXECUTABLE: - doDeviceLinking = true; - break; - default: - break; - } - return doDeviceLinking; - } - } - // Determine if we have any dependencies that require // us to do a device link step cmGeneratorTarget::LinkClosure const* closure = target.GetLinkClosure(config); if (cmContains(closure->Languages, "CUDA")) { + if (const char* separableCompilation = + target.GetProperty("CUDA_SEPARABLE_COMPILATION")) { + if (cmIsOn(separableCompilation)) { + bool doDeviceLinking = false; + switch (target.GetType()) { + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + case cmStateEnums::EXECUTABLE: + doDeviceLinking = true; + break; + default: + break; + } + return doDeviceLinking; + } + } + cmComputeLinkInformation* pcli = target.GetLinkInformation(config); if (pcli) { cmLinkLineDeviceComputer deviceLinkComputer( diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 1da6efe..4969d55 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2220,10 +2220,11 @@ static void AddVisibilityCompileOption(std::string& flags, static void AddInlineVisibilityCompileOption(std::string& flags, cmGeneratorTarget const* target, cmLocalGenerator* lg, - std::string* warnCMP0063) + std::string* warnCMP0063, + const std::string& lang) { std::string compileOption = - "CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN"; + cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN"); const char* opt = lg->GetMakefile()->GetDefinition(compileOption); if (!opt) { return; @@ -2265,8 +2266,8 @@ void cmLocalGenerator::AddVisibilityPresetFlags( AddVisibilityCompileOption(flags, target, this, lang, pWarnCMP0063); - if (lang == "CXX") { - AddInlineVisibilityCompileOption(flags, target, this, pWarnCMP0063); + if (lang == "CXX" || lang == "OBJCXX") { + AddInlineVisibilityCompileOption(flags, target, this, pWarnCMP0063, lang); } if (!warnCMP0063.empty() && this->WarnCMP0063.insert(target).second) { diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index f6a0e34..dbdde48 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -9,12 +9,12 @@ #include <utility> #include <cm/memory> +#include <cm/vector> #include <cmext/algorithm> #include "cmsys/FStream.hxx" #include "cmsys/Terminal.h" -#include "cmAlgorithms.h" #include "cmCustomCommand.h" // IWYU pragma: keep #include "cmCustomCommandGenerator.h" #include "cmFileTimeCache.h" @@ -1876,7 +1876,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo( std::string binaryDir = this->GetState()->GetBinaryDirectory(); if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) { std::string const& sourceDir = this->GetState()->GetSourceDirectory(); - cmEraseIf(includes, ::NotInProjectDir(sourceDir, binaryDir)); + cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir)); } for (std::string const& include : includes) { cmakefileStream << " \"" diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 7683855..55a9a72 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -530,6 +530,14 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorFortranLinkFlagTable[] = { "linkIncrementalNo", 0 }, { "LinkIncremental", "INCREMENTAL:YES", "link incremental", "linkIncrementalYes", 0 }, + { "EnableCOMDATFolding", "OPT:NOICF", "Do not remove redundant COMDATs", + "optNoFolding", 0 }, + { "EnableCOMDATFolding", "OPT:ICF", "Remove redundant COMDATs", "optFolding", + 0 }, + { "OptimizeReferences", "OPT:NOREF", "Keep unreferenced data", + "optNoReferences", 0 }, + { "OptimizeReferences", "OPT:REF", "Eliminate unreferenced data", + "optReferences", 0 }, { "", "", "", "", 0 } }; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index fa7bce1..7435e47 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -17,6 +17,7 @@ #include <cm/iterator> #include <cm/memory> #include <cm/optional> +#include <cm/vector> #include <cmext/algorithm> #include "cmsys/FStream.hxx" @@ -139,7 +140,7 @@ cmDirectoryId cmMakefile::GetDirectoryId() const // If we ever need to expose this to CMake language code we should // add a read-only property in cmMakefile::GetProperty. char buf[32]; - sprintf(buf, "<%p>", + sprintf(buf, "(%p)", static_cast<void const*>(this)); // cast avoids format warning return std::string(buf); } @@ -840,12 +841,12 @@ void cmMakefile::DoGenerate(cmLocalGenerator& lg) // we don't want cmake to re-run if a configured file is created and deleted // during processing as that would make it a transient file that can't // influence the build process - cmEraseIf(this->OutputFiles, file_not_persistent()); + cm::erase_if(this->OutputFiles, file_not_persistent()); // if a configured file is used as input for another configured file, // and then deleted it will show up in the input list files so we // need to scan those too - cmEraseIf(this->ListFiles, file_not_persistent()); + cm::erase_if(this->ListFiles, file_not_persistent()); } // Generate the output file diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index a9f68a6..77b6bc2 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -754,8 +754,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // See if we need to use a compiler launcher like ccache or distcc std::string compilerLauncher; if (!compileCommands.empty() && - (lang == "C" || lang == "CXX" || lang == "Fortran" || - lang == "CUDA")) { + (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" || + lang == "OBJC" || lang == "OBJCXX")) { std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER"; const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 987f241..517241e 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -11,8 +11,8 @@ #include <utility> #include <cm/memory> +#include <cm/vector> -#include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" #include "cmCustomCommand.h" // IWYU pragma: keep #include "cmCustomCommandGenerator.h" @@ -72,6 +72,10 @@ void cmNinjaNormalTargetGenerator::Generate(const std::string& config) // Write the build statements bool firstForConfig = true; for (auto const& fileConfig : this->GetConfigNames()) { + if (fileConfig != config && + !this->GetGlobalGenerator()->EnableCrossConfigBuild()) { + continue; + } this->WriteObjectBuildStatements(config, fileConfig, firstForConfig); firstForConfig = false; } @@ -84,12 +88,18 @@ void cmNinjaNormalTargetGenerator::Generate(const std::string& config) this->WriteDeviceLinkStatement(config); firstForConfig = true; for (auto const& fileConfig : this->GetConfigNames()) { + if (fileConfig != config && + !this->GetGlobalGenerator()->EnableCrossConfigBuild()) { + continue; + } this->WriteLinkStatement(config, fileConfig, firstForConfig); firstForConfig = false; } } - this->GetGlobalGenerator()->AddTargetAlias( - this->GetTargetName(), this->GetGeneratorTarget(), "all"); + if (this->GetGlobalGenerator()->EnableCrossConfigBuild()) { + this->GetGlobalGenerator()->AddTargetAlias( + this->GetTargetName(), this->GetGeneratorTarget(), "all"); + } // Find ADDITIONAL_CLEAN_FILES this->AdditionalCleanFiles(config); @@ -243,7 +253,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule( } // If there is no ranlib the command will be ":". Skip it. - cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands()); + cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands()); rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); @@ -379,7 +389,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, } // If there is no ranlib the command will be ":". Skip it. - cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands()); + cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands()); linkCmds.insert(linkCmds.begin(), "$PRE_LINK"); linkCmds.emplace_back("$POST_BUILD"); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 3f1dbe8..bd19b28 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -724,7 +724,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, // See if we need to use a compiler launcher like ccache or distcc std::string compilerLauncher; if (!compileCmds.empty() && - (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA")) { + (lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" || + lang == "OBJC" || lang == "OBJCXX")) { std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER"; const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop); if (clauncher && *clauncher) { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 8d292ac..eef41c0 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -299,6 +299,9 @@ class cmMakefile; "libraries.", \ 3, 17, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0100, "Let AUTOMOC and AUTOUIC process .hh files.", 3, \ + 17, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0101, \ + "target_compile_options honors BEFORE keyword in all scopes.", 3, \ 17, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 9d83a72..35f07a1 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -150,8 +150,7 @@ const std::string* cmState::GetInitializedCacheValue( cmStateEnums::CacheEntryType cmState::GetCacheEntryType( std::string const& key) const { - cmCacheManager::CacheIterator it = - this->CacheManager->GetCacheIterator(key.c_str()); + cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key); return it.GetType(); } @@ -165,8 +164,7 @@ void cmState::SetCacheEntryProperty(std::string const& key, std::string const& propertyName, std::string const& value) { - cmCacheManager::CacheIterator it = - this->CacheManager->GetCacheIterator(key.c_str()); + cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key); it.SetProperty(propertyName, value.c_str()); } @@ -174,24 +172,21 @@ void cmState::SetCacheEntryBoolProperty(std::string const& key, std::string const& propertyName, bool value) { - cmCacheManager::CacheIterator it = - this->CacheManager->GetCacheIterator(key.c_str()); + cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key); it.SetProperty(propertyName, value); } std::vector<std::string> cmState::GetCacheEntryPropertyList( const std::string& key) { - cmCacheManager::CacheIterator it = - this->CacheManager->GetCacheIterator(key.c_str()); + cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key); return it.GetPropertyList(); } const char* cmState::GetCacheEntryProperty(std::string const& key, std::string const& propertyName) { - cmCacheManager::CacheIterator it = - this->CacheManager->GetCacheIterator(key.c_str()); + cmCacheManager::CacheIterator it = this->CacheManager->GetCacheIterator(key); if (!it.PropertyExists(propertyName)) { return nullptr; } @@ -201,8 +196,8 @@ const char* cmState::GetCacheEntryProperty(std::string const& key, bool cmState::GetCacheEntryPropertyAsBool(std::string const& key, std::string const& propertyName) { - return this->CacheManager->GetCacheIterator(key.c_str()) - .GetPropertyAsBool(propertyName); + return this->CacheManager->GetCacheIterator(key).GetPropertyAsBool( + propertyName); } void cmState::AddCacheEntry(const std::string& key, const char* value, @@ -254,15 +249,14 @@ void cmState::AppendCacheEntryProperty(const std::string& key, const std::string& property, const std::string& value, bool asString) { - this->CacheManager->GetCacheIterator(key.c_str()) - .AppendProperty(property, value.c_str(), asString); + this->CacheManager->GetCacheIterator(key).AppendProperty(property, value, + asString); } void cmState::RemoveCacheEntryProperty(std::string const& key, std::string const& propertyName) { - this->CacheManager->GetCacheIterator(key.c_str()) - .SetProperty(propertyName, nullptr); + this->CacheManager->GetCacheIterator(key).SetProperty(propertyName, nullptr); } cmStateSnapshot cmState::Reset() diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d2693b8..9563321 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -336,6 +336,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("C_STANDARD"); initProp("C_STANDARD_REQUIRED"); initProp("C_EXTENSIONS"); + initProp("OBJC_COMPILER_LAUNCHER"); initProp("OBJC_STANDARD"); initProp("OBJC_STANDARD_REQUIRED"); initProp("OBJC_EXTENSIONS"); @@ -347,6 +348,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("CXX_STANDARD"); initProp("CXX_STANDARD_REQUIRED"); initProp("CXX_EXTENSIONS"); + initProp("OBJCXX_COMPILER_LAUNCHER"); initProp("OBJCXX_STANDARD"); initProp("OBJCXX_STANDARD_REQUIRED"); initProp("OBJCXX_EXTENSIONS"); @@ -358,7 +360,6 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("CUDA_RESOLVE_DEVICE_SYMBOLS"); initProp("LINK_SEARCH_START_STATIC"); initProp("LINK_SEARCH_END_STATIC"); - initProp("FOLDER"); initProp("Swift_LANGUAGE_VERSION"); initProp("Swift_MODULE_DIRECTORY"); initProp("VS_JUST_MY_CODE_DEBUGGING"); @@ -390,6 +391,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, } if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) { + initProp("FOLDER"); + if (this->GetGlobalGenerator()->IsXcode()) { initProp("XCODE_GENERATE_SCHEME"); } diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx index e39b726..dee2c10 100644 --- a/Source/cmTargetCompileOptionsCommand.cxx +++ b/Source/cmTargetCompileOptionsCommand.cxx @@ -5,6 +5,7 @@ #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmPolicies.h" #include "cmStringAlgorithms.h" #include "cmTarget.h" #include "cmTargetPropCommandBase.h" @@ -27,10 +28,16 @@ private: bool HandleDirectContent(cmTarget* tgt, const std::vector<std::string>& content, - bool /*prepend*/, bool /*system*/) override + bool prepend, bool /*system*/) override { + cmPolicies::PolicyStatus policyStatus = + this->Makefile->GetPolicyStatus(cmPolicies::CMP0101); + if (policyStatus == cmPolicies::OLD || policyStatus == cmPolicies::WARN) { + prepend = false; + } + cmListFileBacktrace lfbt = this->Makefile->GetBacktrace(); - tgt->InsertCompileOption(this->Join(content), lfbt); + tgt->InsertCompileOption(this->Join(content), lfbt, prepend); return true; // Successfully handled. } diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index e1ac6a8..ad59748 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -406,6 +406,10 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target, // the name to tell ResolveLinkItem to look up the name in the // caller's directory. cmDirectoryId const dirId = mf.GetDirectoryId(); + // FIXME: The "lib" may be a genex with a list inside it. + // After expansion this id will only attach to the last entry, + // or may attach to an empty string! We will need another way + // to encode this that can apply to a whole list. See issue #20204. libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String; } else { // This is an absolute path or a library name added by a caller diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt index 7c918e6..b430834 100644 --- a/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt @@ -2,7 +2,10 @@ add_executable(SubDirB SubDirB.c) # Link to a target imported in this directory that would not normally # be visible to the directory in which TopDir is defined. -target_link_libraries(TopDir PUBLIC SameNameImported) +target_link_libraries(TopDir PUBLIC debug SameNameImported optimized SameNameImported) + +#FIXME: Demonstrate known issue #20204. +#target_link_libraries(TopDir PUBLIC "$<1:SameNameImported;SameNameImported>") # Link SubDirA to a target imported in this directory that has the same # name as a target imported in SubDirA's directory. We verify when diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2456a26..6fad175 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -989,6 +989,27 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH endif() endif() + # On Windows run the CPackNSISGenerator test + # if the nsis is available + if(WIN32 AND NSIS_MAKENSIS_EXECUTABLE) + add_test(CPackNSISGenerator ${CMAKE_CTEST_COMMAND} + -C \${CTEST_CONFIGURATION_TYPE} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CPackNSISGenerator" + "${CMake_BINARY_DIR}/Tests/CPackNSISGenerator" + ${build_generator_args} + --build-project CPackNSISGenerator + --build-options + --test-command ${CMAKE_CMAKE_COMMAND} + "-DCPackNSISGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackNSISGenerator" + "-Dconfig=\${CTEST_CONFIGURATION_TYPE}" + -P "${CMake_SOURCE_DIR}/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake") + + set_property(TEST CPackNSISGenerator PROPERTY + ATTACHED_FILES_ON_FAIL + "${CMake_BINARY_DIR}/Tests/CPackNSISGenerator/_CPack_Packages/win32/NSIS/NSISOutput.log") + endif() + if(CTEST_TEST_CPACK) add_test(CPackUseDefaultVersion ${CMAKE_CTEST_COMMAND} --build-and-test diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake index 86a74b2..f46a575 100644 --- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake +++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description1.cmake @@ -65,9 +65,10 @@ if(DPKGDEB_EXECUTABLE) "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: `${dpkg_description}` != `${expected_description}`") endif() elseif(dpkg_package_name STREQUAL "mylib-libraries") - if(NOT dpkg_description MATCHES "main description\n.*") + set(expected_description "main description") + if(NOT dpkg_description STREQUAL expected_description) set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all} - "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: `${dpkg_description}` =~ `main description.*`") + "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: `${dpkg_description}` != `${expected_description}`") endif() else() set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all} diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake index d53c73d..c00921a 100644 --- a/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake +++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult-components-description2.cmake @@ -53,9 +53,10 @@ if(DPKGDEB_EXECUTABLE) message(STATUS "package='${dpkg_package_name}', description='${dpkg_description}'") if(dpkg_package_name STREQUAL "mylib-applications" OR dpkg_package_name STREQUAL "mylib-headers") - if(NOT dpkg_description MATCHES "main description 2\n.*") + set(expected_description "main description 2") + if(NOT dpkg_description STREQUAL expected_description) set(dpkgdeb_output_errors_all ${dpkgdeb_output_errors_all} - "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: `${dpkg_description}` =~ `main description 2`") + "dpkg-deb: ${_f}: Incorrect description for package ${dpkg_package_name}: `${dpkg_description}` != `${expected_description}`") endif() elseif(dpkg_package_name STREQUAL "mylib-libraries") set(expected_description "main description 2\n library description") diff --git a/Tests/CPackNSISGenerator/CMakeLists.txt b/Tests/CPackNSISGenerator/CMakeLists.txt new file mode 100644 index 0000000..b8b2ed6 --- /dev/null +++ b/Tests/CPackNSISGenerator/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.16) + +project(CPackNSISGenerator) + +add_executable(hello main.cpp) + +install(TARGETS hello + ARCHIVE DESTINATION . + RUNTIME DESTINATION . + LIBRARY DESTINATION . + BUNDLE DESTINATION .) + +set(CPACK_NSIS_MUI_HEADERIMAGE "${PROJECT_SOURCE_DIR}\\\\header-image.bmp") +set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}\\\\header-icon.bmp") +set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}\\\\install.ico") +set(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}\\\\uninstall.ico") +set(CPACK_GENERATOR "NSIS") +set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) + +include(CPack) diff --git a/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake new file mode 100644 index 0000000..f70cd24 --- /dev/null +++ b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake @@ -0,0 +1,46 @@ +message(STATUS "=============================================================") +message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") +message(STATUS "") + +if(NOT CPackNSISGenerator_BINARY_DIR) + message(FATAL_ERROR "CPackNSISGenerator_BINARY_DIR not set") +endif() + +message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}") +message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}") +message(STATUS "CPackNSISGenerator_BINARY_DIR: ${CPackNSISGenerator_BINARY_DIR}") + +if(config) + set(_C_config -C ${config}) +endif() + +execute_process(COMMAND "${CMAKE_CPACK_COMMAND}" + ${_C_config} + RESULT_VARIABLE CPack_result + OUTPUT_VARIABLE CPack_output + ERROR_VARIABLE CPack_error + WORKING_DIRECTORY "${CPackNSISGenerator_BINARY_DIR}") + +if(CPack_result) + message(FATAL_ERROR "CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}") +else () + message(STATUS "CPack_output=${CPack_output}") +endif() + +set(expected_file_mask "${CPackNSISGenerator_BINARY_DIR}/_CPack_Packages/win32/NSIS/*.nsi") +file(GLOB project_file "${expected_file_mask}") + +message(STATUS "project_file='${project_file}'") +message(STATUS "expected_file_mask='${expected_file_mask}'") + +if(NOT project_file) + message(FATAL_ERROR "project_file does not exist.") +endif() + +# should match !define MUI_HEADERIMAGE_BITMAP "${PROJECT_SOURCE_DIR}\header-image.bmp" +file(STRINGS "${project_file}" line REGEX "^!define MUI_HEADERIMAGE_BITMAP") +string(FIND "${line}" "header-image.bmp" output_index) +message(STATUS "Found the bitmap at index ${output_index}") +if("${output_index}" EQUAL "-1") + message(FATAL_ERROR "MUI_HEADERIMAGE_BITMAP not found in the project") +endif() diff --git a/Tests/CPackNSISGenerator/header-icon.bmp b/Tests/CPackNSISGenerator/header-icon.bmp Binary files differnew file mode 100644 index 0000000..ef6a656 --- /dev/null +++ b/Tests/CPackNSISGenerator/header-icon.bmp diff --git a/Tests/CPackNSISGenerator/header-image.bmp b/Tests/CPackNSISGenerator/header-image.bmp Binary files differnew file mode 100644 index 0000000..15b1730 --- /dev/null +++ b/Tests/CPackNSISGenerator/header-image.bmp diff --git a/Tests/CPackNSISGenerator/install.ico b/Tests/CPackNSISGenerator/install.ico Binary files differnew file mode 100644 index 0000000..3b1e480 --- /dev/null +++ b/Tests/CPackNSISGenerator/install.ico diff --git a/Tests/CPackNSISGenerator/main.cpp b/Tests/CPackNSISGenerator/main.cpp new file mode 100644 index 0000000..956f345 --- /dev/null +++ b/Tests/CPackNSISGenerator/main.cpp @@ -0,0 +1,4 @@ +int main() +{ + return 42; +} diff --git a/Tests/CPackNSISGenerator/uninstall.ico b/Tests/CPackNSISGenerator/uninstall.ico Binary files differnew file mode 100644 index 0000000..c4f6316 --- /dev/null +++ b/Tests/CPackNSISGenerator/uninstall.ico diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt index 35b9022..5ba82d8 100644 --- a/Tests/Cuda/CMakeLists.txt +++ b/Tests/Cuda/CMakeLists.txt @@ -9,6 +9,7 @@ ADD_TEST_MACRO(Cuda.MixedStandardLevels3 MixedStandardLevels3) ADD_TEST_MACRO(Cuda.MixedStandardLevels4 MixedStandardLevels4) ADD_TEST_MACRO(Cuda.MixedStandardLevels5 MixedStandardLevels5) ADD_TEST_MACRO(Cuda.NotEnabled CudaNotEnabled) +ADD_TEST_MACRO(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly) ADD_TEST_MACRO(Cuda.Toolkit Toolkit) ADD_TEST_MACRO(Cuda.IncludePathNoToolkit IncludePathNoToolkit) ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries) diff --git a/Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt b/Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt new file mode 100644 index 0000000..97670e3 --- /dev/null +++ b/Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt @@ -0,0 +1,3 @@ +project(SeparableCompCXXOnly LANGUAGES CXX CUDA) +set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) +add_executable(SeparableCompCXXOnly main.cpp) diff --git a/Tests/Cuda/SeparableCompCXXOnly/main.cpp b/Tests/Cuda/SeparableCompCXXOnly/main.cpp new file mode 100644 index 0000000..8135246 --- /dev/null +++ b/Tests/Cuda/SeparableCompCXXOnly/main.cpp @@ -0,0 +1,5 @@ + +int main(int, char const* []) +{ + return 0; +} diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt index 5e20dd3..bfec986 100644 --- a/Tests/FindPython/CMakeLists.txt +++ b/Tests/FindPython/CMakeLists.txt @@ -148,6 +148,34 @@ if(CMake_TEST_FindPython) --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> ) + if (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin") + add_test(NAME FindPython.Interpreter.SOABI COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/SOABI" + "${CMake_BINARY_DIR}/Tests/FindPython/SOABI.Interpreter" + ${build_generator_args} + --build-project TestSOABI + --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}" + "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}" + "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}" + "-DCMake_TEST_FindPython_COMPONENT=Interpreter" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + add_test(NAME FindPython.Development.SOABI COMMAND + ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION> + --build-and-test + "${CMake_SOURCE_DIR}/Tests/FindPython/SOABI" + "${CMake_BINARY_DIR}/Tests/FindPython/SOABI.Development" + ${build_generator_args} + --build-project TestSOABI + --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}" + "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}" + "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}" + "-DCMake_TEST_FindPython_COMPONENT=Development" + --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION> + ) + endif() endif() if(CMake_TEST_FindPython_NumPy) diff --git a/Tests/FindPython/SOABI/CMakeLists.txt b/Tests/FindPython/SOABI/CMakeLists.txt new file mode 100644 index 0000000..aea2baf --- /dev/null +++ b/Tests/FindPython/SOABI/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.1) + +project(TestSOABI C) + +find_package(Python3 COMPONENTS ${CMake_TEST_FindPython_COMPONENT}) +if (NOT Python3_FOUND) + message (FATAL_ERROR "Fail to found Python 3") +endif() + +if(NOT DEFINED Python3_SOABI) + message(FATAL_ERROR "Python3_SOABI for ${CMake_TEST_FindPython_COMPONENT} not found") +endif() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index cfb6ffe..b8ac45b 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -450,7 +450,7 @@ add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_I add_RunCMake_test(target_compile_definitions) add_RunCMake_test(target_compile_features) -add_RunCMake_test(target_compile_options) +add_RunCMake_test(target_compile_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) add_RunCMake_test(target_include_directories) add_RunCMake_test(target_sources) add_RunCMake_test(CheckModules) @@ -544,6 +544,9 @@ if("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") if(CMAKE_Fortran_COMPILER) list(APPEND CompilerLauncher_ARGS -DCMake_TEST_Fortran=1) endif() + if (APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU") + list(APPEND CompilerLauncher_ARGS -DCMake_TEST_OBJC=1) + endif() add_RunCMake_test(CompilerLauncher) add_RunCMake_test(ctest_labels_for_subprojects) endif() diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake index 76d16e1..6e413aa 100644 --- a/Tests/RunCMake/CPack/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake @@ -38,7 +38,7 @@ run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB.DEB_PACKAGE_VERSION_B run_cpack_test_subtests(EXTERNAL "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "External" false "MONOLITHIC;COMPONENT") run_cpack_test_subtests( DEB_DESCRIPTION - "CPACK_DEBIAN_PACKAGE_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION_FILE" + "CPACK_DEBIAN_PACKAGE_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION;CPACK_PACKAGE_DESCRIPTION_FILE;CPACK_NO_PACKAGE_DESCRIPTION" "DEB.DEB_DESCRIPTION" false "MONOLITHIC;COMPONENT" diff --git a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake index e9ac13a..a8e2e7a 100644 --- a/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake +++ b/Tests/RunCMake/CPack/tests/DEB_DESCRIPTION/VerifyResult.cmake @@ -56,6 +56,8 @@ set(_expected_description [[ Description: This is the summary line # workaround required! if(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_PACKAGE_DESCRIPTION_FILE" AND PACKAGING_TYPE STREQUAL "MONOLITHIC") string(APPEND _expected_description "\n ." ) +elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "CPACK_NO_PACKAGE_DESCRIPTION") + set(_expected_description [[ Description: This is the summary line]]) endif() foreach(_file_no RANGE 1 ${EXPECTED_FILES_COUNT}) diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJC-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-common.cmake b/Tests/RunCMake/CompilerLauncher/OBJC-common.cmake new file mode 100644 index 0000000..7b565f4 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-common.cmake @@ -0,0 +1,3 @@ +enable_language(OBJC) +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_executable(main main.m) diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJC-env-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-env-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJC-env-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-env-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJC-env.cmake new file mode 100644 index 0000000..949e88d --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-env.cmake @@ -0,0 +1 @@ +include(OBJC-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJC-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJC-launch-env.cmake new file mode 100644 index 0000000..1cf13d3 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-launch-env.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(OBJC-env.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-launch.cmake b/Tests/RunCMake/CompilerLauncher/OBJC-launch.cmake new file mode 100644 index 0000000..43e8521 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC-launch.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(OBJC.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/OBJC.cmake b/Tests/RunCMake/CompilerLauncher/OBJC.cmake new file mode 100644 index 0000000..3374e82 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJC.cmake @@ -0,0 +1,2 @@ +set(CMAKE_OBJC_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") +include(OBJC-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJCXX-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-common.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX-common.cmake new file mode 100644 index 0000000..e2ee4eb --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-common.cmake @@ -0,0 +1,3 @@ +enable_language(OBJCXX) +set(CMAKE_VERBOSE_MAKEFILE TRUE) +add_executable(main main.mm) diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX-env.cmake new file mode 100644 index 0000000..3ed966d --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-env.cmake @@ -0,0 +1 @@ +include(OBJCXX-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-Build-stdout.txt new file mode 100644 index 0000000..3313e31 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-Build-stdout.txt @@ -0,0 +1 @@ +.*-E env USED_LAUNCHER=1.* diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-env.cmake new file mode 100644 index 0000000..04c916a --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-env.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(OBJCXX-env.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-launch.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch.cmake new file mode 100644 index 0000000..5a54bff --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch.cmake @@ -0,0 +1,3 @@ +set(CTEST_USE_LAUNCHERS 1) +include(CTestUseLaunchers) +include(OBJCXX.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX.cmake new file mode 100644 index 0000000..993ec90 --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/OBJCXX.cmake @@ -0,0 +1,2 @@ +set(CMAKE_OBJCXX_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1") +include(OBJCXX-common.cmake) diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake index e9543f1..69fff20 100644 --- a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake @@ -29,6 +29,9 @@ endif() if(CMake_TEST_Fortran) list(APPEND langs Fortran) endif() +if(CMake_TEST_OBJC) + list(APPEND langs OBJC OBJCXX) +endif() foreach(lang ${langs}) run_compiler_launcher(${lang}) diff --git a/Tests/RunCMake/CompilerLauncher/main.m b/Tests/RunCMake/CompilerLauncher/main.m new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/main.m @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/Tests/RunCMake/CompilerLauncher/main.mm b/Tests/RunCMake/CompilerLauncher/main.mm new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/RunCMake/CompilerLauncher/main.mm @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index 4b51ddb..1271999 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -76,8 +76,9 @@ endfunction() set(RunCMake_TEST_NO_CLEAN 1) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Simple-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE=RelWithDebInfo") +set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE=RelWithDebInfo;-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON") run_cmake_configure(Simple) +unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(Simple debug-target Debug simpleexe) run_ninja(Simple debug-target build-Debug.ninja simplestatic) @@ -103,8 +104,22 @@ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1) file(TOUCH "${RunCMake_TEST_BINARY_DIR}/empty.cmake") run_ninja(Simple reconfigure-noconfig build.ninja simpleexe) +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleNoCross-build) +run_cmake_configure(SimpleNoCross) +include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) +run_cmake_build(SimpleNoCross debug-target Debug simpleexe) +run_ninja(SimpleNoCross debug-target build-Debug.ninja simplestatic:Debug) +run_ninja(SimpleNoCross relwithdebinfo-in-release-graph-target build-Release.ninja simplestatic:RelWithDebInfo) +run_cmake_build(SimpleNoCross relwithdebinfo-in-release-graph-all Release all:RelWithDebInfo) +run_cmake_build(SimpleNoCross relwithdebinfo-in-release-graph-clean Release clean:RelWithDebInfo) +run_ninja(SimpleNoCross all-target build-Debug.ninja simplestatic:all) +run_ninja(SimpleNoCross all-all build-Debug.ninja all:all) +run_cmake_build(SimpleNoCross all-clean Debug clean:all) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandGenerator-build) +set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON") run_cmake_configure(CustomCommandGenerator) +unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(CustomCommandGenerator debug Debug generated) run_cmake_command(CustomCommandGenerator-debug-generated "${TARGET_FILE_generated_Debug}") @@ -119,7 +134,9 @@ run_ninja(CustomCommandGenerator release-in-debug-graph build-Debug.ninja genera run_cmake_command(CustomCommandGenerator-release-in-debug-graph-generated "${TARGET_FILE_generated_Release}") set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandsAndTargets-build) +set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON") run_cmake_configure(CustomCommandsAndTargets) +unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(CustomCommandsAndTargets release-command Release SubdirCommand) #FIXME Get this working @@ -133,9 +150,9 @@ run_cmake_build(CustomCommandsAndTargets debug-targetpostbuild Debug TopTargetPo run_ninja(CustomCommandsAndTargets release-targetpostbuild build-Release.ninja SubdirTargetPostBuild) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostfixAndLocation-build) -set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release") +set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON") run_cmake_configure(PostfixAndLocation) -set(RunCMake_TEST_OPTIONS) +unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(PostfixAndLocation release-in-release-graph Release mylib:Release) run_cmake_build(PostfixAndLocation debug-in-release-graph Release mylib:Debug) @@ -148,14 +165,16 @@ run_ninja(Clean release-notall build-Release.ninja exenotall) run_cmake_build(Clean release-clean Release clean) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdditionalCleanFiles-build) +set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON") run_cmake_configure(AdditionalCleanFiles) +unset(RunCMake_TEST_OPTIONS) run_cmake_build(AdditionalCleanFiles release-clean Release clean) run_ninja(AdditionalCleanFiles all-clean build-Debug.ninja clean:all) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Install-build) -set(RunCMake_TEST_OPTIONS -DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install) +set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON") run_cmake_configure(Install) -set(RunCMake_TEST_OPTIONS) +unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(Install release-install Release install) run_ninja(Install debug-in-release-graph-install build-Release.ninja install:Debug) @@ -167,7 +186,9 @@ run_ninja(Install debug-in-release-graph-install build-Release.ninja install:Deb if(CMake_TEST_Qt5) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build) + set(RunCMake_TEST_OPTIONS "-DCMAKE_NINJA_CROSS_CONFIG_ENABLE=ON") run_cmake_configure(Qt5) + unset(RunCMake_TEST_OPTIONS) include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake) run_cmake_build(Qt5 debug-in-release-graph Release exe:Debug) endif() diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-stderr.txt new file mode 100644 index 0000000..905a355 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-stderr.txt @@ -0,0 +1 @@ +^ninja: error: unknown target 'all:all'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-stderr.txt new file mode 100644 index 0000000..43528de --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-stderr.txt @@ -0,0 +1 @@ +^ninja: error: unknown target 'clean:all'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-stderr.txt new file mode 100644 index 0000000..6db4bcc --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-stderr.txt @@ -0,0 +1 @@ +^ninja: error: unknown target 'simplestatic:all'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-build-check.cmake new file mode 100644 index 0000000..6bb7773 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-build-check.cmake @@ -0,0 +1,31 @@ +check_files("${RunCMake_TEST_BINARY_DIR}" + INCLUDE + ${GENERATED_FILES} + + ${TARGET_FILE_simpleexe_Debug} + ${TARGET_OBJECT_FILES_simpleexe_Debug} + + ${TARGET_FILE_simpleshared_Debug} + ${TARGET_LINKER_FILE_simpleshared_Debug} + ${TARGET_OBJECT_FILES_simpleshared_Debug} + + ${TARGET_OBJECT_FILES_simpleobj_Debug} + + EXCLUDE + ${TARGET_OBJECT_FILES_simplestatic_Debug} + + ${TARGET_OBJECT_FILES_simpleexe_Release} + ${TARGET_OBJECT_FILES_simpleshared_Release} + ${TARGET_OBJECT_FILES_simplestatic_Release} + ${TARGET_OBJECT_FILES_simpleobj_Release} + + ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel} + ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel} + ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel} + ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel} + + ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo} + ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo} + ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo} + ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo} + ) diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-ninja-check.cmake new file mode 100644 index 0000000..c8a735a --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-ninja-check.cmake @@ -0,0 +1,32 @@ +check_files("${RunCMake_TEST_BINARY_DIR}" + INCLUDE + ${GENERATED_FILES} + + ${TARGET_FILE_simpleexe_Debug} + ${TARGET_OBJECT_FILES_simpleexe_Debug} + + ${TARGET_FILE_simpleshared_Debug} + ${TARGET_LINKER_FILE_simpleshared_Debug} + ${TARGET_OBJECT_FILES_simpleshared_Debug} + + ${TARGET_FILE_simplestatic_Debug} + ${TARGET_OBJECT_FILES_simplestatic_Debug} + + ${TARGET_OBJECT_FILES_simpleobj_Debug} + + EXCLUDE + ${TARGET_OBJECT_FILES_simpleexe_Release} + ${TARGET_OBJECT_FILES_simpleshared_Release} + ${TARGET_OBJECT_FILES_simplestatic_Release} + ${TARGET_OBJECT_FILES_simpleobj_Release} + + ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel} + ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel} + ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel} + ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel} + + ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo} + ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo} + ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo} + ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo} + ) diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-stderr.txt new file mode 100644 index 0000000..fa8b462 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-stderr.txt @@ -0,0 +1 @@ +^ninja: error: unknown target 'all:RelWithDebInfo'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-stderr.txt new file mode 100644 index 0000000..70eef2f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-stderr.txt @@ -0,0 +1 @@ +^ninja: error: unknown target 'clean:RelWithDebInfo'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-stderr.txt new file mode 100644 index 0000000..1a1fe9e --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-stderr.txt @@ -0,0 +1 @@ +^ninja: error: unknown target 'simplestatic:RelWithDebInfo'$ diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross.cmake new file mode 100644 index 0000000..2a5b708 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake") diff --git a/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt b/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt index 5856d56..b35f05e 100644 --- a/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt +++ b/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt @@ -1,6 +1,7 @@ CMake Debug Log at FromPATHEnv.cmake:5 \(find_package\): - find_package considered the following paths for Resolved.cmake -.* + find_package considered the following paths for Resolved.cmake.* +.*/Modules/FindResolved.cmake.* + The file was not found.* <PackageName>_ROOT CMake variable.* CMAKE_PREFIX_PATH variable.* CMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH variables.* @@ -13,4 +14,7 @@ CMake Debug Log at FromPATHEnv.cmake:5 \(find_package\): CMake variables defined in the Platform file.* CMake System Package Registry.* Paths specified by the find_package PATHS option.* - Checking file.*\[.*Tests/RunCMake/find_package/PackageRoot/ResolvedConfig\.cmake\] + find_package considered the following locations for the Config module:.* +.*Tests/RunCMake/find_package/PackageRoot/ResolvedConfig\.cmake.* + The file was found at.* +.*Tests/RunCMake/find_package/PackageRoot/ResolvedConfig\.cmake diff --git a/Tests/RunCMake/find_package/MissingConfigDebug-stderr.txt b/Tests/RunCMake/find_package/MissingConfigDebug-stderr.txt index 8ff04a9..379bf7a 100644 --- a/Tests/RunCMake/find_package/MissingConfigDebug-stderr.txt +++ b/Tests/RunCMake/find_package/MissingConfigDebug-stderr.txt @@ -9,8 +9,9 @@ CMake System Package Registry.* Paths specified by the find_package PATHS option.* .* - Checking file \[.*NotHereConfig.cmake\].* - Checking file \[.*nothere-config.cmake\].* + .*NotHereConfig.cmake + .*nothere-config.cmake +.* CMake Warning at MissingConfigDebug.cmake:3 \(message\): This warning must be reachable. Call Stack \(most recent call first\): diff --git a/Tests/RunCMake/target_compile_options/BEFORE_keyword.cmake b/Tests/RunCMake/target_compile_options/BEFORE_keyword.cmake new file mode 100644 index 0000000..8016230 --- /dev/null +++ b/Tests/RunCMake/target_compile_options/BEFORE_keyword.cmake @@ -0,0 +1,8 @@ + +add_executable (CMP0101_OLD CMP0101.c) +target_compile_options (main PRIVATE -UBEFORE_KEYWORD) +target_compile_options (main BEFORE PRIVATE -DBEFORE_KEYWORD) + +add_executable (CMP0101_NEW CMP0101.c) +target_compile_options (main PRIVATE -UBEFORE_KEYWORD) +target_compile_options (main BEFORE PRIVATE -DBEFORE_KEYWORD) diff --git a/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-NEW-result.txt b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-NEW-result.txt new file mode 100644 index 0000000..573541a --- /dev/null +++ b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-NEW-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-result.txt b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-result.txt new file mode 100644 index 0000000..8d98f9d --- /dev/null +++ b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-result.txt @@ -0,0 +1 @@ +.* diff --git a/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-stdout.txt b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-stdout.txt new file mode 100644 index 0000000..850aa65 --- /dev/null +++ b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-stdout.txt @@ -0,0 +1 @@ +BEFORE not honored diff --git a/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword.cmake b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword.cmake new file mode 100644 index 0000000..577427f --- /dev/null +++ b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword.cmake @@ -0,0 +1,15 @@ + +enable_language(C) + +cmake_policy (SET CMP0101 OLD) + +add_executable (CMP0101_OLD CMP0101.c) +target_compile_options (CMP0101_OLD PRIVATE -UBEFORE_KEYWORD) +target_compile_options (CMP0101_OLD BEFORE PRIVATE -DBEFORE_KEYWORD) + + +cmake_policy (SET CMP0101 NEW) + +add_executable (CMP0101_NEW CMP0101.c) +target_compile_options (CMP0101_NEW PRIVATE -UBEFORE_KEYWORD) +target_compile_options (CMP0101_NEW BEFORE PRIVATE -DBEFORE_KEYWORD) diff --git a/Tests/RunCMake/target_compile_options/CMP0101.c b/Tests/RunCMake/target_compile_options/CMP0101.c new file mode 100644 index 0000000..250869a --- /dev/null +++ b/Tests/RunCMake/target_compile_options/CMP0101.c @@ -0,0 +1,9 @@ + +#if defined(BEFORE_KEYWORD) +# error "BEFORE not honored" +#endif + +int main() +{ + return 0; +} diff --git a/Tests/RunCMake/target_compile_options/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_options/RunCMakeTest.cmake index b67c598..9f51a9a 100644 --- a/Tests/RunCMake/target_compile_options/RunCMakeTest.cmake +++ b/Tests/RunCMake/target_compile_options/RunCMakeTest.cmake @@ -1,3 +1,21 @@ include(RunCMake) run_cmake(empty_keyword_args) + +if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") + macro(run_cmake_target test subtest target) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build) + set(RunCMake_TEST_OUTPUT_MERGE 1) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN}) + + unset(RunCMake_TEST_BINARY_DIR) + unset(RunCMake_TEST_OUTPUT_MERGE) + unset(RunCMake_TEST_NO_CLEAN) + endmacro() + + run_cmake(CMP0101-BEFORE_keyword) + + run_cmake_target(CMP0101-BEFORE_keyword OLD CMP0101_OLD) + run_cmake_target(CMP0101-BEFORE_keyword NEW CMP0101_NEW) +endif() diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt index 89cd806..90a5f37 100644 --- a/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt +++ b/Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt @@ -1 +1 @@ --- INTERFACE_LINK_LIBRARIES='foo::@<[Xx0-9A-Fa-f]+>' +-- INTERFACE_LINK_LIBRARIES='foo::@\([Xx0-9A-Fa-f]+\)' diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt index 8ef35c1..8670403 100644 --- a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt @@ -1,5 +1,5 @@ ^CMake Error at CMP0079-link-NEW-bogus.cmake:[0-9]+ \(add_executable\): - Target "top" links to target "foo::@<0xdeadbeef>" but the target was not + Target "top" links to target "foo::@\(0xdeadbeef\)" but the target was not found. Perhaps a find_package\(\) call is missing for an IMPORTED target, or an ALIAS target is missing\? Call Stack \(most recent call first\): diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake index 8622f14..ea9e071 100644 --- a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake @@ -3,4 +3,4 @@ cmake_policy(SET CMP0079 NEW) enable_language(C) add_executable(top empty.c) -set_property(TARGET top APPEND PROPERTY LINK_LIBRARIES "foo::@<0xdeadbeef>") +set_property(TARGET top APPEND PROPERTY LINK_LIBRARIES "foo::@(0xdeadbeef)") diff --git a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt index 84b30bd..3e8c7c6 100644 --- a/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt +++ b/Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt @@ -1 +1 @@ --- LINK_LIBRARIES='foo::@<[Xx0-9A-Fa-f]+>' +-- LINK_LIBRARIES='foo::@\([Xx0-9A-Fa-f]+\)' diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index d903dbe..f164fd0 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -191,6 +191,7 @@ _cmake_index_objs = { 'cpack_gen': _cmake_index_entry('cpack generator'), 'envvar': _cmake_index_entry('envvar'), 'generator': _cmake_index_entry('generator'), + 'guide': _cmake_index_entry('guide'), 'manual': _cmake_index_entry('manual'), 'module': _cmake_index_entry('module'), 'policy': _cmake_index_entry('policy'), @@ -251,7 +252,7 @@ class CMakeTransform(Transform): env = self.document.settings.env # Treat some documents as cmake domain objects. - objtype, sep, tail = env.docname.rpartition('/') + objtype, sep, tail = env.docname.partition('/') make_index_entry = _cmake_index_objs.get(objtype) if make_index_entry: title = self.parse_title(env.docname) @@ -373,6 +374,7 @@ class CMakeDomain(Domain): 'cpack_gen': ObjType('cpack_gen', 'cpack_gen'), 'envvar': ObjType('envvar', 'envvar'), 'generator': ObjType('generator', 'generator'), + 'guide': ObjType('guide', 'guide'), 'variable': ObjType('variable', 'variable'), 'module': ObjType('module', 'module'), 'policy': ObjType('policy', 'policy'), @@ -407,6 +409,7 @@ class CMakeDomain(Domain): 'cpack_gen': CMakeXRefRole(), 'envvar': CMakeXRefRole(), 'generator': CMakeXRefRole(), + 'guide': CMakeXRefRole(), 'variable': CMakeXRefRole(), 'module': CMakeXRefRole(), 'policy': CMakeXRefRole(), diff --git a/Utilities/Sphinx/create_identifiers.py b/Utilities/Sphinx/create_identifiers.py index 6716b48..b5cd914 100755 --- a/Utilities/Sphinx/create_identifiers.py +++ b/Utilities/Sphinx/create_identifiers.py @@ -25,6 +25,7 @@ for line in lines: ("envvar", "envvar"), ("variable", "variable"), ("generator", "generator"), + ("guide", "guide"), ("target property", "prop_tgt"), ("test property", "prop_test"), ("source file property", "prop_sf"), diff --git a/Utilities/std/.gitattributes b/Utilities/std/.gitattributes index 789a754..ad5459d 100644 --- a/Utilities/std/.gitattributes +++ b/Utilities/std/.gitattributes @@ -1,2 +1,2 @@ -cm/* our-c-style -cmext/* our-c-style +cm/** our-c-style +cmext/** our-c-style diff --git a/Utilities/std/cm/bits/erase_if.hxx b/Utilities/std/cm/bits/erase_if.hxx new file mode 100644 index 0000000..8952fb5 --- /dev/null +++ b/Utilities/std/cm/bits/erase_if.hxx @@ -0,0 +1,29 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#ifndef cm_bits_erase_if_hxx +#define cm_bits_erase_if_hxx + +namespace cm { +namespace internals { + +template <typename Container, typename Predicate> +void erase_if(Container& cont, Predicate pred) +{ + for (typename Container::iterator iter = cont.begin(), last = cont.end(); + iter != last;) { + if (pred(*iter)) { + iter = cont.erase(iter); + } else { + ++iter; + } + } +} + +} // namespace internals +} // namespace cm + +#endif diff --git a/Utilities/std/cm/deque b/Utilities/std/cm/deque new file mode 100644 index 0000000..4bb6725 --- /dev/null +++ b/Utilities/std/cm/deque @@ -0,0 +1,40 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_deque +#define cm_deque + +#include <algorithm> +#include <deque> // IWYU pragma: export + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase; +using std::erase_if; + +#else + +template <typename T, typename Allocator, typename V> +inline void erase(std::deque<T, Allocator>& cont, const V& value) +{ + cont.erase(std::remove(cont.begin(), cont.end(), value), cont.end()); +} + +template <typename T, typename Allocator, typename Predicate> +inline void erase_if(std::deque<T, Allocator>& cont, Predicate pred) +{ + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); +} + +#endif + +} // namespace cm + +#endif diff --git a/Utilities/std/cm/list b/Utilities/std/cm/list new file mode 100644 index 0000000..ba5d94a --- /dev/null +++ b/Utilities/std/cm/list @@ -0,0 +1,39 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_list +#define cm_list + +#include <list> // IWYU pragma: export + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase; +using std::erase_if; + +#else + +template <typename T, typename Allocator, typename V> +inline void erase(std::list<T, Allocator>& cont, const V& value) +{ + cont.remove_if([&](auto& elem) { return elem == value; }); +} + +template <typename T, typename Allocator, typename Predicate> +inline void erase_if(std::list<T, Allocator>& cont, Predicate pred) +{ + cont.remove_if(pred); +} + +#endif + +} // namespace cm + +#endif diff --git a/Utilities/std/cm/map b/Utilities/std/cm/map new file mode 100644 index 0000000..e348dec --- /dev/null +++ b/Utilities/std/cm/map @@ -0,0 +1,44 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_map +#define cm_map + +#include <map> // IWYU pragma: export + +#include <cm/bits/erase_if.hxx> + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase_if; + +#else + +template <typename Key, typename T, typename Compare, typename Allocator, + typename Predicate> +inline void erase_if(std::map<Key, T, Compare, Allocator>& cont, + Predicate pred) +{ + internals::erase_if(cont, pred); +} + +template <typename Key, typename T, typename Compare, typename Allocator, + typename Predicate> +inline void erase_if(std::multimap<Key, T, Compare, Allocator>& cont, + Predicate pred) +{ + internals::erase_if(cont, pred); +} + +#endif + +} // namespace cm + +#endif diff --git a/Utilities/std/cm/set b/Utilities/std/cm/set new file mode 100644 index 0000000..56dd474 --- /dev/null +++ b/Utilities/std/cm/set @@ -0,0 +1,43 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_set +#define cm_set + +#include <set> // IWYU pragma: export + +#include <cm/bits/erase_if.hxx> + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase_if; + +#else + +template <typename Key, typename Compare, typename Allocator, + typename Predicate> +inline void erase_if(std::set<Key, Compare, Allocator>& cont, Predicate pred) +{ + internals::erase_if(cont, pred); +} + +template <typename Key, typename Compare, typename Allocator, + typename Predicate> +inline void erase_if(std::multiset<Key, Compare, Allocator>& cont, + Predicate pred) +{ + internals::erase_if(cont, pred); +} + +#endif + +} // namespace cm + +#endif diff --git a/Utilities/std/cm/string b/Utilities/std/cm/string new file mode 100644 index 0000000..cc4c796 --- /dev/null +++ b/Utilities/std/cm/string @@ -0,0 +1,42 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_string +#define cm_string + +#include <algorithm> +#include <string> // IWYU pragma: export + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase; +using std::erase_if; + +#else + +template <typename T, typename Traits, typename Allocator, typename V> +inline void erase(std::basic_string<T, Traits, Allocator>& cont, + const V& value) +{ + cont.erase(std::remove(cont.begin(), cont.end(), value), cont.end()); +} + +template <typename T, typename Traits, typename Allocator, typename Predicate> +inline void erase_if(std::basic_string<T, Traits, Allocator>& cont, + Predicate pred) +{ + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); +} + +#endif + +} // namespace cm + +#endif diff --git a/Utilities/std/cm/unordered_map b/Utilities/std/cm/unordered_map new file mode 100644 index 0000000..5b8a456 --- /dev/null +++ b/Utilities/std/cm/unordered_map @@ -0,0 +1,45 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_unordered_map +#define cm_unordered_map + +#include <unordered_map> // IWYU pragma: export + +#include <cm/bits/erase_if.hxx> + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase_if; + +#else + +template <typename Key, typename T, typename Hash, typename KeyEqual, + typename Allocator, typename Predicate> +inline void erase_if( + std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& cont, Predicate pred) +{ + internals::erase_if(cont, pred); +} + +template <typename Key, typename T, typename Hash, typename KeyEqual, + typename Allocator, typename Predicate> +inline void erase_if( + std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>& cont, + Predicate pred) +{ + internals::erase_if(cont, pred); +} + +#endif + +} // namespace cm + +#endif diff --git a/Utilities/std/cm/unordered_set b/Utilities/std/cm/unordered_set new file mode 100644 index 0000000..9debac4 --- /dev/null +++ b/Utilities/std/cm/unordered_set @@ -0,0 +1,45 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_unordered_set +#define cm_unordered_set + +#include <unordered_set> // IWYU pragma: export + +#include <cm/bits/erase_if.hxx> + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase_if; + +#else + +template <typename Key, typename Hash, typename KeyEqual, typename Allocator, + typename Predicate> +inline void erase_if(std::unordered_set<Key, Hash, KeyEqual, Allocator>& cont, + Predicate pred) +{ + internals::erase_if(cont, pred); +} + +template <typename Key, typename Hash, typename KeyEqual, typename Allocator, + typename Predicate> +inline void erase_if( + std::unordered_multiset<Key, Hash, KeyEqual, Allocator>& cont, + Predicate pred) +{ + internals::erase_if(cont, pred); +} + +#endif + +} // namespace cm + +#endif diff --git a/Utilities/std/cm/vector b/Utilities/std/cm/vector new file mode 100644 index 0000000..2dbe704 --- /dev/null +++ b/Utilities/std/cm/vector @@ -0,0 +1,40 @@ +// -*-c++-*- +// vim: set ft=cpp: + +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cm_vector +#define cm_vector + +#include <algorithm> +#include <vector> // IWYU pragma: export + +namespace cm { + +// should be updated when C++20 is finalized +#if (__cplusplus > 201703L || \ + (defined(_MSVC_LANG) && _MSVC_LANG > 201703)) && \ + defined(__cpp_lib_erase_if) + +using std::erase; +using std::erase_if; + +#else + +template <typename T, typename Allocator, typename V> +inline void erase(std::vector<T, Allocator>& cont, const V& value) +{ + cont.erase(std::remove(cont.begin(), cont.end(), value), cont.end()); +} + +template <typename T, typename Allocator, typename Predicate> +inline void erase_if(std::vector<T, Allocator>& cont, Predicate pred) +{ + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); +} + +#endif + +} // namespace cm + +#endif @@ -1595,6 +1595,7 @@ rebuild_cache: echo ' # Generated by '"${cmake_source_dir}"'/bootstrap # Default cmake settings. These may be overridden any settings below. +set (CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build.") # not FORCE to preserve defaults specified elsewhere set (CMAKE_INSTALL_PREFIX "'"${cmake_prefix_dir}"'" CACHE PATH "Install path prefix, prepended onto install directories." FORCE) set (CMAKE_DOC_DIR "'"${cmake_doc_dir}"'" CACHE PATH "Install location for documentation (relative to prefix)." FORCE) set (CMAKE_MAN_DIR "'"${cmake_man_dir}"'" CACHE PATH "Install location for man pages (relative to prefix)." FORCE) |