diff options
407 files changed, 9860 insertions, 6803 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 073630e..680d77b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -284,6 +284,29 @@ upload:macos-package: variables: RSYNC_DESTINATION: dev +build:macos10.10-package: + extends: + - .macos10.10_package + - .cmake_build_macos_package + - .cmake_release_artifacts + - .macos_builder_tags_package + - .run_only_for_package + dependencies: + - prep:doc-package + needs: + - prep:doc-package + +upload:macos10.10-package: + extends: + - .rsync_upload + - .run_only_for_package + dependencies: + - build:macos10.10-package + needs: + - build:macos10.10-package + variables: + RSYNC_DESTINATION: dev + # Windows builds build:windows-vs2019-x64-ninja: diff --git a/.gitlab/artifacts.yml b/.gitlab/artifacts.yml index 76ffd27..87828e1 100644 --- a/.gitlab/artifacts.yml +++ b/.gitlab/artifacts.yml @@ -75,7 +75,7 @@ # Any packages made. - build/cmake-*-Linux-x86_64.* - build/cmake-*-Linux-aarch64.* - - build/cmake-*-macos-universal.* + - build/cmake-*-macos*-universal.* # Any source packages made. - build/cmake-*.tar.gz - build/cmake-*.zip diff --git a/.gitlab/ci/cmake.ps1 b/.gitlab/ci/cmake.ps1 index 9d7f317..e7b4de7 100755 --- a/.gitlab/ci/cmake.ps1 +++ b/.gitlab/ci/cmake.ps1 @@ -7,6 +7,7 @@ $tarball = "$filename.zip" $outdir = $pwd.Path $outdir = "$outdir\.gitlab" +$ProgressPreference = 'SilentlyContinue' Invoke-WebRequest -Uri "https://github.com/Kitware/CMake/releases/download/v$version/$tarball" -OutFile "$outdir\$tarball" $hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256 if ($hash.Hash -ne $sha256sum) { diff --git a/.gitlab/ci/configure_macos10.10_package.cmake b/.gitlab/ci/configure_macos10.10_package.cmake new file mode 100644 index 0000000..f01e6c8 --- /dev/null +++ b/.gitlab/ci/configure_macos10.10_package.cmake @@ -0,0 +1,4 @@ +set(CPACK_SYSTEM_NAME "macos10.10-universal" CACHE STRING "") +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.10" CACHE STRING "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_package_common.cmake") diff --git a/.gitlab/ci/configure_macos_package.cmake b/.gitlab/ci/configure_macos_package.cmake index a1dbdb9..380e44c 100644 --- a/.gitlab/ci/configure_macos_package.cmake +++ b/.gitlab/ci/configure_macos_package.cmake @@ -1,28 +1,4 @@ -set(CMake_DOC_ARTIFACT_PREFIX "$ENV{CI_PROJECT_DIR}/build/install-doc" CACHE PATH "") - -# Set up install destinations as expected by the packaging scripts. -set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "") -set(CMAKE_DOC_DIR "doc/cmake" CACHE STRING "") - -# Settings for CMake packages for macOS. -set(CPACK_DMG_FORMAT "UDBZ" CACHE STRING "") -set(CMAKE_CXX_FLAGS "-stdlib=libc++" CACHE STRING "") -set(CMAKE_C_STANDARD "11" CACHE STRING "") -set(CMAKE_CXX_STANDARD "14" CACHE STRING "") -set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "") -set(CMAKE_OSX_DEPLOYMENT_TARGET "10.10" CACHE STRING "") -set(CMAKE_SKIP_BOOTSTRAP_TEST "TRUE" CACHE STRING "") set(CPACK_SYSTEM_NAME "macos-universal" CACHE STRING "") -set(BUILD_CursesDialog "ON" CACHE BOOL "") -set(BUILD_QtDialog "TRUE" CACHE BOOL "") -set(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL "3" CACHE STRING "") -set(CMake_INSTALL_DEPENDENCIES "ON" CACHE BOOL "") -set(CMAKE_SKIP_RPATH "TRUE" CACHE BOOL "") -set(CMake_TEST_NO_FindPackageModeMakefileTest "TRUE" CACHE BOOL "") - -# XXX(sccache): restore sccache when it works for multiple architectures: -# https://github.com/mozilla/sccache/issues/847 -set(configure_no_sccache 1) +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "") -include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake") -include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_package_common.cmake") diff --git a/.gitlab/ci/configure_macos_package_common.cmake b/.gitlab/ci/configure_macos_package_common.cmake new file mode 100644 index 0000000..3aa8ae2 --- /dev/null +++ b/.gitlab/ci/configure_macos_package_common.cmake @@ -0,0 +1,26 @@ +set(CMake_DOC_ARTIFACT_PREFIX "$ENV{CI_PROJECT_DIR}/build/install-doc" CACHE PATH "") + +# Set up install destinations as expected by the packaging scripts. +set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "") +set(CMAKE_DOC_DIR "doc/cmake" CACHE STRING "") + +# Settings for CMake packages for macOS. +set(CPACK_DMG_FORMAT "UDBZ" CACHE STRING "") +set(CMAKE_CXX_FLAGS "-stdlib=libc++" CACHE STRING "") +set(CMAKE_C_STANDARD "11" CACHE STRING "") +set(CMAKE_CXX_STANDARD "14" CACHE STRING "") +set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "") +set(CMAKE_SKIP_BOOTSTRAP_TEST "TRUE" CACHE STRING "") +set(BUILD_CursesDialog "ON" CACHE BOOL "") +set(BUILD_QtDialog "TRUE" CACHE BOOL "") +set(CMake_GUI_DISTRIBUTE_WITH_Qt_LGPL "3" CACHE STRING "") +set(CMake_INSTALL_DEPENDENCIES "ON" CACHE BOOL "") +set(CMAKE_SKIP_RPATH "TRUE" CACHE BOOL "") +set(CMake_TEST_NO_FindPackageModeMakefileTest "TRUE" CACHE BOOL "") + +# XXX(sccache): restore sccache when it works for multiple architectures: +# https://github.com/mozilla/sccache/issues/847 +set(configure_no_sccache 1) + +include("${CMAKE_CURRENT_LIST_DIR}/configure_macos_common.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake") diff --git a/.gitlab/ci/download_qt.cmake b/.gitlab/ci/download_qt.cmake index 4a33f12..76c693d 100644 --- a/.gitlab/ci/download_qt.cmake +++ b/.gitlab/ci/download_qt.cmake @@ -48,7 +48,11 @@ if (qt_platform STREQUAL "windows_x86") set(qt_subdir "${qt_version}/msvc${msvc_year}_64") elseif (qt_platform STREQUAL "mac_x64") - if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "package") + if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "macos_package") + list(APPEND qt_files + "qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz") + set(qt_subdir "qt-5.15.2-macosx10.13-x86_64-arm64") + elseif ("$ENV{CMAKE_CONFIGURATION}" MATCHES "macos10.10_package") list(APPEND qt_files "qt-5.9.9-macosx10.10-x86_64-arm64.tar.xz") set(qt_subdir "qt-5.9.9-macosx10.10-x86_64-arm64") diff --git a/.gitlab/ci/download_qt_hashes.cmake b/.gitlab/ci/download_qt_hashes.cmake index 832fa98..afbc081 100644 --- a/.gitlab/ci/download_qt_hashes.cmake +++ b/.gitlab/ci/download_qt_hashes.cmake @@ -11,3 +11,4 @@ set("5.15.1-0-202009071110qtwinextras-Windows-Windows_10-MSVC2015-Windows-Window set("5.15.1-0-202009071110qtbase-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64.7z_hash" df2813ce7c6cb4287abd7956cd1cb9d08312e4ac1208b6cb57af4df11b8ebba1) set("qt-5.9.9-macosx10.10-x86_64-arm64.tar.xz_hash" d4449771afa0bc6a809c14f1e6d939e7732494cf059503ae451e2bfe8fc60cc1) +set("qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz_hash" 7b9463a01c8beeee5bf8d01c70deff2d08561cd20aaf6f7a2f41cf8b68ce8a6b) diff --git a/.gitlab/ci/ninja.ps1 b/.gitlab/ci/ninja.ps1 index 4cc6bcb..4c5333a 100755 --- a/.gitlab/ci/ninja.ps1 +++ b/.gitlab/ci/ninja.ps1 @@ -7,6 +7,7 @@ $tarball = "$filename.zip" $outdir = $pwd.Path $outdir = "$outdir\.gitlab" +$ProgressPreference = 'SilentlyContinue' Invoke-WebRequest -Uri "https://github.com/ninja-build/ninja/releases/download/v$version/$tarball" -OutFile "$outdir\$tarball" $hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256 if ($hash.Hash -ne $sha256sum) { diff --git a/.gitlab/ci/wix.ps1 b/.gitlab/ci/wix.ps1 new file mode 100755 index 0000000..a9322b6 --- /dev/null +++ b/.gitlab/ci/wix.ps1 @@ -0,0 +1,18 @@ +$erroractionpreference = "stop" + +$release = "wix3112rtm" +$sha256sum = "2C1888D5D1DBA377FC7FA14444CF556963747FF9A0A289A3599CF09DA03B9E2E" +$filename = "wix311-binaries" +$tarball = "$filename.zip" + +$outdir = $pwd.Path +$outdir = "$outdir\.gitlab" +$ProgressPreference = 'SilentlyContinue' +Invoke-WebRequest -Uri "https://github.com/wixtoolset/wix3/releases/download/$release/$tarball" -OutFile "$outdir\$tarball" +$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256 +if ($hash.Hash -ne $sha256sum) { + exit 1 +} + +Add-Type -AssemblyName System.IO.Compression.FileSystem +[System.IO.Compression.ZipFile]::ExtractToDirectory("$outdir\$tarball", "$outdir\wix\bin") diff --git a/.gitlab/os-macos.yml b/.gitlab/os-macos.yml index 8a006b1..450bae7 100644 --- a/.gitlab/os-macos.yml +++ b/.gitlab/os-macos.yml @@ -7,7 +7,7 @@ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci ext/$CI_CONCURRENT_ID" # TODO: Factor this out so that each job selects the Xcode version to # use so that different versions can be tested in a single pipeline. - DEVELOPER_DIR: "/Applications/Xcode-12.2.app/Contents/Developer" + DEVELOPER_DIR: "/Applications/Xcode-12.3.app/Contents/Developer" # Avoid conflicting with other projects running on the same machine. SCCACHE_SERVER_PORT: 4227 @@ -47,6 +47,14 @@ CTEST_NO_WARNINGS_ALLOWED: 1 CMake_SKIP_INSTALL: 1 +.macos10.10_package: + extends: .macos_build + + variables: + CMAKE_CONFIGURATION: macos10.10_package + CTEST_NO_WARNINGS_ALLOWED: 1 + CMake_SKIP_INSTALL: 1 + ### External testing .macos_xcode: @@ -63,7 +71,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos - shell - - xcode-12.2 + - xcode-12.3 - nonconcurrent .macos_builder_tags_package: @@ -71,7 +79,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos - shell - - xcode-12.2 + - xcode-12.3 - nonconcurrent - finder @@ -80,7 +88,7 @@ - cmake # Since this is a bare runner, pin to a project. - macos - shell - - xcode-12.2 + - xcode-12.3 - concurrent ## macOS-specific scripts diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml index 2e21fdf..1fff2bb 100644 --- a/.gitlab/os-windows.yml +++ b/.gitlab/os-windows.yml @@ -74,9 +74,12 @@ ## Windows-specific scripts .before_script_windows: &before_script_windows + - Invoke-Expression -Command .gitlab/ci/wix.ps1 - Invoke-Expression -Command .gitlab/ci/cmake.ps1 - Invoke-Expression -Command .gitlab/ci/ninja.ps1 - $pwdpath = $pwd.Path + - Set-Item -Force -Path "env:WIX" -Value "$pwdpath\.gitlab\wix" + - (& "$env:WIX\bin\light.exe" -help) | Select -First 1 - Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab;$pwdpath\.gitlab\cmake\bin;$env:PATH" - cmake --version - ninja --version diff --git a/.gitlab/upload.yml b/.gitlab/upload.yml index 6bfa763..8b8daa1 100644 --- a/.gitlab/upload.yml +++ b/.gitlab/upload.yml @@ -15,4 +15,4 @@ - dnf install -y --setopt=install_weak_deps=False rsync openssh-clients - chmod 400 $RSYNC_BINARY_KEY - ssh-keygen -y -f $RSYNC_BINARY_KEY > $RSYNC_BINARY_KEY.pub - - rsync -tv --recursive -e "ssh -i $RSYNC_BINARY_KEY -o StrictHostKeyChecking=no -o LogLevel=ERROR" build/ kitware@public.kitware.com:$RSYNC_DESTINATION/ + - rsync -tv --recursive -e "ssh -i $RSYNC_BINARY_KEY -o StrictHostKeyChecking=no -o LogLevel=ERROR" build/ kitware@cmake.org:$RSYNC_DESTINATION/ diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el index 52f2d41..ddc7b40 100644 --- a/Auxiliary/cmake-mode.el +++ b/Auxiliary/cmake-mode.el @@ -211,7 +211,7 @@ the indentation. Otherwise it retains the same position on the line" "end" (or "function" "macro") (zero-or-more space) - "(" (zero-or-more (not ")")) ")")) + "(" (zero-or-more (not-char ")")) ")")) (defun cmake-beginning-of-defun () "Move backward to the beginning of a CMake function or macro. diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim index a9bcf47..955beae 100644 --- a/Auxiliary/vim/syntax/cmake.vim +++ b/Auxiliary/vim/syntax/cmake.vim @@ -2040,6 +2040,7 @@ syn keyword cmakeKWExternalProject contained \ UPDATE_DISCONNECTED \ URL \ URL_HASH + \ URL_MD5 \ USES_TERMINAL_BUILD \ USES_TERMINAL_CONFIGURE \ USES_TERMINAL_DOWNLOAD diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst index 2d37ae0..5d2d7eb 100644 --- a/Help/command/cmake_path.rst +++ b/Help/command/cmake_path.rst @@ -3,109 +3,32 @@ cmake_path .. versionadded:: 3.20 -Filesystem path manipulation command. - -This command is dedicated to the manipulation of objects of type path which -represent paths on a filesystem. Only syntactic aspects of paths are handled: -the pathname may represent a non-existing path or even one that is not allowed -to exist on the current file system or OS. - -For operations involving the filesystem, have a look at the :command:`file` +This command is for the manipulation of paths. Only syntactic aspects of +paths are handled, there is no interaction of any kind with any underlying +file system. The path may represent a non-existing path or even one that +is not allowed to exist on the current file system or platform. +For operations that do interact with the filesystem, see the :command:`file` command. -The path name has the following syntax: - -1. ``root-name`` (optional): identifies the root on a filesystem with multiple - roots (such as ``"C:"`` or ``"//myserver"``). - -2. ``root-directory`` (optional): a directory separator that, if present, marks - this path as absolute. If it is missing (and the first element other than - the ``root-name`` is a ``item-name``), then the path is relative. - -Zero or more of the following: - -3. ``item-name``: sequence of characters that aren't directory separators. This - name may identify a file, a hard link, a symbolic link, or a directory. Two - special ``item-names`` are recognized: - - * ``dot``: the item name consisting of a single dot character ``.`` is a - directory name that refers to the current directory. - - * ``dot-dot``: the item name consisting of two dot characters ``..`` is a - directory name that refers to the parent directory. - -4. ``directory-separator``: the forward slash character ``/``. If this - character is repeated, it is treated as a single directory separator: - ``/usr///////lib`` is the same as ``/usr/lib``. - -.. _FILENAME_DEF: - -A path has a filename if it does not ends with a ``directory-separator``. The -filename is the last ``item-name`` of the path. - -.. _EXTENSION_DEF: - -A :ref:`filename <FILENAME_DEF>` can have an extension. By default, the -extension is defined as the sub-string beginning at the leftmost period -(including the period) and until the end of the pathname. When the option -``LAST_ONLY`` is specified, the extension is the sub-string beginning at the -rightmost period. - -The following exceptions apply: - - * If the first character in the :ref:`filename <FILENAME_DEF>` is a period, - that period is ignored (a filename like ``".profile"`` is not treated as an - extension). - - * If the pathname is either ``.`` or ``..``. - .. note:: - ``cmake_path`` command handles paths in the format of the build system, not - the target system. So this is not generally applicable to the target system - in cross-compiling environment. - -For all commands, ``<path-var>`` placeholder expect a variable name. An error -will be raised if the variable does not exist, except for `SET`_ and `APPEND`_ -sub-commands. ``<input>`` placeholder expect a string literal. -``[<input>...]`` placeholder expect zero or more arguments. ``<out-var>`` -placeholder expect a variable name. - -.. note:: - - ``cmake_path`` command does not support list of paths. The ``<path-var>`` - placeholder must store only one path name. - -To initialize a path variable, three possibilities can be used: - -1. :command:`set` command. -2. :ref:`cmake_path(SET) <SET>` command. Mainly used to build a - path variable from a native path. -3. :ref:`cmake_path(APPEND) <APPEND>` command. Can be used to build a path from - already available path fragments. - - .. code-block:: cmake - - # To build the path "${CMAKE_CURRENT_SOURCE_DIR}/data" - - set (path1 "${CMAKE_CURRENT_SOURCE_DIR}/data") - - cmake_path(SET path2 "${CMAKE_CURRENT_SOURCE_DIR}/data") - - cmake_path(APPEND path3 "${CMAKE_CURRENT_SOURCE_DIR}" "data") - -`Modification`_ and `Generation`_ sub-commands store the result in-place or in -the variable specified by ``OUTPUT_VARIABLE`` option. All other sub-commands -store the result in the required ``<out-var>`` variable. - -Sub-commands supporting ``NORMALIZE`` option will :ref:`normalize <NORMAL_PATH>` -the path. + The ``cmake_path`` command handles paths in the format of the build system + (i.e. the host platform), not the target system. When cross-compiling, + if the path contains elements that are not representable on the host + platform (e.g. a drive letter when the host is not Windows), the results + will be unpredictable. Synopsis ^^^^^^^^ .. parsed-literal:: + `Conventions`_ + + `Path Structure And Terminology`_ + + `Normalization`_ + `Decomposition`_ cmake_path(`GET`_ <path-var> :ref:`ROOT_NAME <GET_ROOT_NAME>` <out-var>) cmake_path(`GET`_ <path-var> :ref:`ROOT_DIRECTORY <GET_ROOT_DIRECTORY>` <out-var>) @@ -116,32 +39,6 @@ Synopsis cmake_path(`GET`_ <path-var> :ref:`RELATIVE_PATH <GET_RELATIVE_PATH>` <out-var>) cmake_path(`GET`_ <path-var> :ref:`PARENT_PATH <GET_PARENT_PATH>` <out-var>) - `Modification`_ - cmake_path(`SET`_ <path-var> [NORMALIZE] <input>) - cmake_path(`APPEND`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) - cmake_path(`APPEND_STRING`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) - cmake_path(`REMOVE_FILENAME`_ <path-var> [OUTPUT_VARIABLE <out-var>]) - cmake_path(`REPLACE_FILENAME`_ <path-var> <input> [OUTPUT_VARIABLE <out-var>]) - cmake_path(`REMOVE_EXTENSION`_ <path-var> [LAST_ONLY] - [OUTPUT_VARIABLE <out-var>]) - cmake_path(`REPLACE_EXTENSION`_ <path-var> [LAST_ONLY] <input> - [OUTPUT_VARIABLE <out-var>]) - - `Generation`_ - cmake_path(`NORMAL_PATH`_ <path-var> [OUTPUT_VARIABLE <out-var>]) - cmake_path(`RELATIVE_PATH`_ <path-var> [BASE_DIRECTORY <input>] - [OUTPUT_VARIABLE <out-var>]) - cmake_path(`ABSOLUTE_PATH`_ <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] - [OUTPUT_VARIABLE <out-var>]) - - `Conversion`_ - cmake_path(`NATIVE_PATH`_ <path-var> [NORMALIZE] <out-var>) - cmake_path(`CONVERT`_ <input> `TO_CMAKE_PATH_LIST`_ <out-var>) - cmake_path(`CONVERT`_ <input> `TO_NATIVE_PATH_LIST`_ <out-var>) - - `Comparison`_ - cmake_path(`COMPARE`_ <input1> <OP> <input2> <out-var>) - `Query`_ cmake_path(`HAS_ROOT_NAME`_ <path-var> <out-var>) cmake_path(`HAS_ROOT_DIRECTORY`_ <path-var> <out-var>) @@ -154,664 +51,755 @@ Synopsis cmake_path(`IS_ABSOLUTE`_ <path-var> <out-var>) cmake_path(`IS_RELATIVE`_ <path-var> <out-var>) cmake_path(`IS_PREFIX`_ <path-var> <input> [NORMALIZE] <out-var>) + cmake_path(`COMPARE`_ <input1> <OP> <input2> <out-var>) - `Hashing`_ - cmake_path(`HASH`_ <path-var> [NORMALIZE] <out-var>) - -Decomposition -^^^^^^^^^^^^^ - -.. _GET: -.. _GET_ROOT_NAME: - -.. code-block:: cmake - - cmake_path(GET <path-var> ROOT_NAME <out-var>) - -Returns the root name of the path. If the path does not include a root name, -returns an empty path. - -.. note:: - - Only ``Windows`` system has the concept of ``root-name``, so on all other - systems, it is always an empty path. - -For example: - - .. code-block:: cmake - - set (path "c:/a") - cmake_path (GET path ROOT_NAME output) - message ("Root name is \"${output}\"") + `Modification`_ + cmake_path(:ref:`SET <cmake_path-SET>` <path-var> [NORMALIZE] <input>) + cmake_path(`APPEND`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) + cmake_path(`APPEND_STRING`_ <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) + cmake_path(`REMOVE_FILENAME`_ <path-var> [OUTPUT_VARIABLE <out-var>]) + cmake_path(`REPLACE_FILENAME`_ <path-var> <input> [OUTPUT_VARIABLE <out-var>]) + cmake_path(`REMOVE_EXTENSION`_ <path-var> [LAST_ONLY] [OUTPUT_VARIABLE <out-var>]) + cmake_path(`REPLACE_EXTENSION`_ <path-var> [LAST_ONLY] <input> [OUTPUT_VARIABLE <out-var>]) - Will display:: + `Generation`_ + cmake_path(`NORMAL_PATH`_ <path-var> [OUTPUT_VARIABLE <out-var>]) + cmake_path(`RELATIVE_PATH`_ <path-var> [BASE_DIRECTORY <input>] [OUTPUT_VARIABLE <out-var>]) + cmake_path(`ABSOLUTE_PATH`_ <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] [OUTPUT_VARIABLE <out-var>]) - Root name is "c:" + `Native Conversion`_ + cmake_path(`NATIVE_PATH`_ <path-var> [NORMALIZE] <out-var>) + cmake_path(`CONVERT`_ <input> `TO_CMAKE_PATH_LIST`_ <out-var>) + cmake_path(`CONVERT`_ <input> `TO_NATIVE_PATH_LIST`_ <out-var>) -.. _GET_ROOT_DIRECTORY: + `Hashing`_ + cmake_path(`HASH`_ <path-var> <out-var>) -.. code-block:: cmake +Conventions +^^^^^^^^^^^ - cmake_path(GET <path-var> ROOT_DIRECTORY <out-var>) +The following conventions are used in this command's documentation: -Returns the root directory of the path. If the path does not include a root -directory, returns an empty path. +``<path-var>`` + Always the name of a variable. For commands that expect a ``<path-var>`` + as input, the variable must exist and it is expected to hold a single path. -For example: +``<input>`` + A string literal which may contain a path, path fragment, or multiple paths + with a special separator depending on the command. See the description of + each command to see how this is interpreted. - .. code-block:: cmake +``<input>...`` + Zero or more string literal arguments. - set (path "c:/a") - cmake_path (GET path ROOT_DIRECTORY output) - message ("Root directory is \"${output}\"") +``<out-var>`` + The name of a variable into which the result of a command will be written. - Will display:: - Root directory is "/" +Path Structure And Terminology +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. _GET_ROOT_PATH: +A path has the following structure (all components are optional, with some +constraints): -.. code-block:: cmake +:: - cmake_path(GET <path-var> ROOT_PATH <out-var>) + root-name root-directory-separator (item-name directory-separator)* filename -Returns the root path of the path. If the path does not include a root path, -returns an empty path. +``root-name`` + Identifies the root on a filesystem with multiple roots (such as ``"C:"`` + or ``"//myserver"``). It is optional. -Effectively, returns the following: ``root-name root-directory``. +``root-directory-separator`` + A directory separator that, if present, indicates that this path is + absolute. If it is missing and the first element other than the + ``root-name`` is an ``item-name``, then the path is relative. -For example: +``item-name`` + A sequence of characters that aren't directory separators. This name may + identify a file, a hard link, a symbolic link, or a directory. Two special + cases are recognized: - .. code-block:: cmake + * The item name consisting of a single dot character ``.`` is a + directory name that refers to the current directory. - set (path "c:/a") - cmake_path (GET path ROOT_PATH output) - message ("Root path is \"${output}\"") + * The item name consisting of two dot characters ``..`` is a + directory name that refers to the parent directory. - Will display:: + The ``(...)*`` pattern shown above is to indicate that there can be zero + or more item names, with multiple items separated by a + ``directory-separator``. The ``()*`` characters are not part of the path. - Root path is "c:/" +``directory-separator`` + The only recognized directory separator is a forward slash character ``/``. + If this character is repeated, it is treated as a single directory + separator. In other words, ``/usr///////lib`` is the same as ``/usr/lib``. -.. _GET_FILENAME: +.. _FILENAME_DEF: +.. _EXTENSION_DEF: +.. _STEM_DEF: -.. code-block:: cmake +``filename`` + A path has a ``filename`` if it does not end with a ``directory-separator``. + The ``filename`` is effectively the last ``item-name`` of the path, so it + can also be a hard link, symbolic link or a directory. - cmake_path(GET <path-var> FILENAME <out-var>) + A ``filename`` can have an *extension*. By default, the extension is + defined as the sub-string beginning at the left-most period (including + the period) and until the end of the ``filename``. In commands that + accept a ``LAST_ONLY`` keyword, ``LAST_ONLY`` changes the interpretation + to the sub-string beginning at the right-most period. -Returns the :ref:`filename <FILENAME_DEF>` component of the path. If the path -ends with a ``directory-separator``, there is no filename, so returns an empty -path. + The following exceptions apply to the above interpretation: -For example: + * If the first character in the ``filename`` is a period, that period is + ignored (i.e. a ``filename`` like ``".profile"`` is treated as having + no extension). - .. code-block:: cmake + * If the ``filename`` is either ``.`` or ``..``, it has no extension. - set (path "/a") - cmake_path (GET path FILENAME output) - message ("First filename is \"${output}\"") + The *stem* is the part of the ``filename`` before the extension. - set (path "/a/") - cmake_path (GET path FILENAME output) - message ("Second filename is \"${output}\"") +Some commands refer to a ``root-path``. This is the concatenation of +``root-name`` and ``root-directory``, either or both of which can be empty. - Will display:: - First filename is "a" - Second filename is "" +Creating A Path Variable +^^^^^^^^^^^^^^^^^^^^^^^^ -.. _GET_EXTENSION: +While a path can be created with care using an ordinary :command:`set` +command, it is recommended to use :ref:`cmake_path(SET) <cmake_path-SET>` +instead, as it automatically converts the path to the required form where +required. The :ref:`cmake_path(APPEND) <APPEND>` subcommand may +be another suitable alternative where a path needs to be constructed by +joining fragments. The following example compares the three methods for +constructing the same path: .. code-block:: cmake - cmake_path(GET <path-var> EXTENSION [LAST_ONLY] <out-var>) - -Returns the :ref:`extension <EXTENSION_DEF>` of the filename component. - -If the :ref:`filename <FILENAME_DEF>` component of the path contains a period -(``.``), and is not one of the special filesystem elements ``dot`` or -``dot-dot``, then the :ref:`extension <EXTENSION_DEF>` is returned. + set(path1 "${CMAKE_CURRENT_SOURCE_DIR}/data") -For example: + cmake_path(SET path2 "${CMAKE_CURRENT_SOURCE_DIR}/data") - .. code-block:: cmake + cmake_path(APPEND path3 "${CMAKE_CURRENT_SOURCE_DIR}" "data") - set (path "name.ext1.ext2") - cmake_path (GET path EXTENSION result) - message ("Full extension is \"${result}\"") - cmake_path (GET path EXTENSION LAST_ONLY result) - message ("Last extension is \"${result}\"") +`Modification`_ and `Generation`_ sub-commands can either store the result +in-place, or in a separate variable named after an ``OUTPUT_VARIABLE`` +keyword. All other sub-commands store the result in a mandatory ``<out-var>`` +variable. - Will display:: +.. _Normalization: - Full extension is ".ext1.ext2" - Last extension is ".ext2" +Normalization +^^^^^^^^^^^^^ -The following exceptions apply: +Some sub-commands support *normalizing* a path. The algorithm used to +normalize a path is as follows: + +1. If the path is empty, stop (the normalized form of an empty path is + also an empty path). +2. Replace each ``directory-separator``, which may consist of multiple + separators, with a single ``/`` (``/a///b --> /a/b``). +3. Remove each solitary period (``.``) and any immediately following + ``directory-separator`` (``/a/./b/. --> /a/b``). +4. Remove each ``item-name`` (other than ``..``) that is immediately + followed by a ``directory-separator`` and a ``..``, along with any + immediately following ``directory-separator`` (``/a/b/../c --> a/c``). +5. If there is a ``root-directory``, remove any ``..`` and any + ``directory-separators`` immediately following them. The parent of the + root directory is treated as still the root directory (``/../a --> /a``). +6. If the last ``item-name`` is ``..``, remove any trailing + ``directory-separator`` (``../ --> ..``). +7. If the path is empty by this stage, add a ``dot`` (normal form of ``./`` + is ``.``). - * If the first character in the filename is a period, that period is ignored - (a filename like ``".profile"`` is not treated as an extension). - * If the pathname is either ``.`` or ``..``, or if - :ref:`filename <FILENAME_DEF>` component does not contain the ``.`` - character, then an empty path is returned. +Decomposition +^^^^^^^^^^^^^ +.. _GET: +.. _GET_ROOT_NAME: +.. _GET_ROOT_DIRECTORY: +.. _GET_ROOT_PATH: +.. _GET_FILENAME: +.. _GET_EXTENSION: .. _GET_STEM: -.. code-block:: cmake +The following forms of the ``GET`` subcommand each retrieve a different +component or group of components from a path. +`Path Structure And Terminology`_ defines the meaning of each path component. + +:: + cmake_path(GET <path-var> ROOT_NAME <out-var>) + cmake_path(GET <path-var> ROOT_DIRECTORY <out-var>) + cmake_path(GET <path-var> ROOT_PATH <out-var>) + cmake_path(GET <path-var> FILENAME <out-var>) + cmake_path(GET <path-var> EXTENSION [LAST_ONLY] <out-var>) cmake_path(GET <path-var> STEM [LAST_ONLY] <out-var>) -Returns the :ref:`filename <FILENAME_DEF>` component of the path stripped of -its :ref:`extension <EXTENSION_DEF>`. +If a requested component is not present in the path, an empty string will be +stored in ``<out-var>``. For example, only Windows systems have the concept +of a ``root-name``, so when the host machine is non-Windows, the ``ROOT_NAME`` +subcommand will always return an empty string. -For Example: - .. code-block:: cmake +Root examples +""""""""""""" - set (path "name.ext1.ext2") - cmake_path (GET path STEM result) - message ("Filename without the extension is \"${result}\"") - cmake_path (GET path STEM LAST_ONLY result) - message ("Filename whiteout the last extension is \"${result}\"") +.. code-block:: cmake - Will display:: + set(path "c:/a") - Filename without the extension is "name" - Filename without the last extension is "name.ext1" + cmake_path(GET path ROOT_NAME rootName) + cmake_path(GET path ROOT_DIRECTORY rootDir) + cmake_path(GET path ROOT_PATH rootPath) -The following exceptions apply: + message("Root name is \"${rootName}\"") + message("Root directory is \"${rootDir}\"") + message("Root path is \"${rootPath}\"") - * If the first character in the filename is a period, that period is ignored - (a filename like ``".profile"`` is not treated as an extension). +:: - * If the filename is one of the special filesystem components ``dot`` or - ``dot-dot``, or if it has no periods, the function returns the entire - :ref:`filename <FILENAME_DEF>` component. + Root name is "c:" + Root directory is "/" + Root path is "c:/" -.. _GET_RELATIVE_PATH: +Filename examples +""""""""""""""""" .. code-block:: cmake - cmake_path(GET <path-var> RELATIVE_PATH <out-var>) - -Returns path relative to ``root-path``, that is, a pathname composed of -every component of ``<path-var>`` after ``root-path``. If ``<path-var>`` is -an empty path, returns an empty path. + set(path "/a/b") + cmake_path(GET path FILENAME filename) + message("First filename is \"${filename}\"") -For Example: + # Trailing slash means filename is empty + set(path "/a/b/") + cmake_path(GET path FILENAME filename) + message("Second filename is \"${filename}\"") - .. code-block:: cmake +:: - set (path "/a/b") - cmake_path (GET path RELATIVE_PATH result) - message ("Relative path is \"${result}\"") + First filename is "b" + Second filename is "" - set (path "/") - cmake_path (GET path RELATIVE_PATH result) - message ("Relative path is \"${result}\"") +Extension and stem examples +""""""""""""""""""""""""""" - Will display:: +.. code-block:: cmake - Relative path is "a/b" - Relative path is "" + set(path "name.ext1.ext2") -.. _GET_PARENT_PATH: + cmake_path(GET path EXTENSION fullExt) + cmake_path(GET path STEM fullStem) + message("Full extension is \"${fullExt}\"") + message("Full stem is \"${fullStem}\"") -.. code-block:: cmake + # Effect of LAST_ONLY + cmake_path(GET path EXTENSION LAST_ONLY lastExt) + cmake_path(GET path STEM LAST_ONLY lastStem) + message("Last extension is \"${lastExt}\"") + message("Last stem is \"${lastStem}\"") - cmake_path(GET <path-var> PARENT_PATH <out-var>) + # Special cases + set(dotPath "/a/.") + set(dotDotPath "/a/..") + set(someMorePath "/a/.some.more") + cmake_path(GET dotPath EXTENSION dotExt) + cmake_path(GET dotPath STEM dotStem) + cmake_path(GET dotDotPath EXTENSION dotDotExt) + cmake_path(GET dotDotPath STEM dotDotStem) + cmake_path(GET dotMorePath EXTENSION someMoreExt) + cmake_path(GET dotMorePath STEM someMoreStem) + message("Dot extension is \"${dotExt}\"") + message("Dot stem is \"${dotStem}\"") + message("Dot-dot extension is \"${dotDotExt}\"") + message("Dot-dot stem is \"${dotDotStem}\"") + message(".some.more extension is \"${someMoreExt}\"") + message(".some.more stem is \"${someMoreStem}\"") -Returns the path to the parent directory. +:: -If `HAS_RELATIVE_PATH`_ sub-command returns false, the result is a copy of -``<path-var>``. Otherwise, the result is ``<path-var>`` with one fewer element. + Full extension is ".ext1.ext2" + Full stem is "name" + Last extension is ".ext2" + Last stem is "name.ext1" + Dot extension is "" + Dot stem is "." + Dot-dot extension is "" + Dot-dot stem is ".." + .some.more extension is ".more" + .some.more stem is ".some" -For Example: - .. code-block:: cmake +Relative paths +"""""""""""""" - set (path "c:/a/b") - cmake_path (GET path PARENT_PATH result) - message ("Parent path is \"${result}\"") +Two other forms of the ``GET`` subcommand interpret a path and return +another path derived from it. - set (path "c:/") - cmake_path (GET path PARENT_PATH result) - message ("Parent path is \"${result}\"") +.. _GET_RELATIVE_PATH: - Will display:: +:: - Parent path is "c:/a" - Relative path is "c:/" + cmake_path(GET <path-var> RELATIVE_PATH <out-var>) -Modification -^^^^^^^^^^^^ +Returns the path with any ``root-name`` and ``root-directory-separator`` +removed. This leaves just the part of the path relative to the root +directory (or put another way, every component of ``<path-var>`` after +``root-path``). If ``<path-var>`` is an empty path, it returns an empty +path. -.. _cmake_path-SET: -.. _SET: +For example: .. code-block:: cmake - cmake_path(SET <path-var> [NORMALIZE] <input>) - -Assign the ``<input>`` path to ``<path-var>``. Moreover, if ``<input>`` is a -native path, it is converted into cmake-style path with forward-slashes -(``/``). On Windows, the long filename marker is taken into account. + set(path "/a/b") + cmake_path(GET path RELATIVE_PATH result) + message("Relative path is \"${result}\"") -When ``NORMALIZE`` option is specified, the path is :ref:`normalized -<NORMAL_PATH>` before the conversion. + set(path "/") + cmake_path(GET path RELATIVE_PATH result) + message("Relative path is \"${result}\"") -For Example: +Output:: - .. code-block:: cmake + Relative path is "a/b" + Relative path is "" - set (native_path "c:\\a\\b/..\\c") - cmake_path (SET path "${native_path}") - message ("CMake path is \"${path}\"") +.. _GET_PARENT_PATH: - cmake_path (SET path NORMALIZE "${native_path}") - message ("Normalized CMake path is \"${path}\"") +The other form returns the parent of the path:: - Will display:: + cmake_path(GET <path-var> PARENT_PATH <out-var>) - CMake path is "c:/a/b/../c" - Normalized CMake path is "c:/a/c" +If the `HAS_RELATIVE_PATH`_ sub-command returns false, the result is a +copy of ``<path-var>``. Otherwise, the result is ``<path-var>`` with +one fewer element. -.. _APPEND: +For example: .. code-block:: cmake - cmake_path(APPEND <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) + set(path "c:/a/b") + cmake_path(GET path PARENT_PATH result) + message("Parent path is \"${result}\"") -Append all the ``<input>`` arguments to the ``<path-var>`` using ``/`` as -``directory-separator``. - -For each ``<input>`` argument, the following algorithm (pseudo-code) applies: + set(path "c:/") + cmake_path(GET path PARENT_PATH result) + message("Parent path is \"${result}\"") - .. code-block:: cmake +Output:: - # <path> is the contents of <path-var> + Parent path is "c:/a" + Relative path is "c:/" - IF (<input>.is_absolute() OR - (<input>.has_root_name() AND - NOT <input>.root_name() STREQUAL <path>.root_name())) - replaces <path> with <input> - RETURN() - ENDIF() +Query +^^^^^ - IF (<input>.has_root_directory()) - remove any root-directory and the entire relative path from <path> - ELSEIF (<path>.has_filename() OR - (NOT <path-var>.has_root_directory() OR <path>.is_absolute())) - appends directory-separator to <path> - ENDIF() +Most of the ``GET`` subcommands also have corresponding ``HAS_...`` +subcommands which can be used to discover whether a particular path +component is present. `Path Structure And Terminology`_ defines the +meaning of each path component. - appends <input> omitting any root-name to <path> +.. _HAS_ROOT_NAME: +.. _HAS_ROOT_DIRECTORY: +.. _HAS_ROOT_PATH: +.. _HAS_FILENAME: +.. _HAS_EXTENSION: +.. _HAS_STEM: -.. _APPEND_STRING: +:: -.. code-block:: cmake + cmake_path(HAS_ROOT_NAME <path-var> <out-var>) + cmake_path(HAS_ROOT_DIRECTORY <path-var> <out-var>) + cmake_path(HAS_ROOT_PATH <path-var> <out-var>) + cmake_path(HAS_FILENAME <path-var> <out-var>) + cmake_path(HAS_EXTENSION <path-var> <out-var>) + cmake_path(HAS_STEM <path-var> <out-var>) - cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) +Each of the above follows the predictable pattern of setting ``<out-var>`` +to true if the path has the associated component, or false otherwise. +In the case of ``HAS_ROOT_PATH``, a true result will only be returned if +at least one of ``root-name`` or ``root-directory`` is non-empty. -Append all the ``<input>`` arguments to the ``<path-var>`` without -``directory-separator``. +.. _HAS_RELATIVE_PATH: -.. _REMOVE_FILENAME: +:: -.. code-block:: cmake + cmake_path(HAS_RELATIVE_PATH <path-var> <out-var>) - cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>]) +A relative path in this context means everything after the ``root-path``, +if present. This command sets ``<out-var>`` to true if there is at least +one ``item-name`` or ``filename`` in the path. -Removes the :ref:`filename <FILENAME_DEF>` component (as returned by -:ref:`GET ... FILENAME <GET_FILENAME>`) from ``<path-var>``. +.. _HAS_PARENT_PATH: -After this function returns, if change is done in-place, `HAS_FILENAME`_ -returns false for ``<path-var>``. +:: -For Example: + cmake_path(HAS_PARENT_PATH <path-var> <out-var>) - .. code-block:: cmake +This command sets ``<out-var>`` to true if ``<path-var>`` has parent path. +Note that the root directory is also considered to have a parent, which +will be itself. The result is true except if the path consists of just a +:ref:`filename <FILENAME_DEF>`. - set (path "/a/b") - cmake_path (REMOVE_FILENAME path) - message ("First path is \"${path}\"") +.. _IS_ABSOLUTE: - cmake_path (REMOVE_FILENAME path) - message ("Second path is \"${result}\"") +:: - Will display:: + cmake_path(IS_ABSOLUTE <path-var> <out-var>) - First path is "/a/" - Second path is "/a/" +Sets ``<out-var>`` to true if ``<path-var>`` is absolute. An absolute path +is a path that unambiguously identifies the location of a file without +reference to an additional starting location. On Windows, this means the +path must have both a ``root-name`` and a ``root-directory-separator`` to be +considered absolute. On other platforms, just a ``root-directory-separator`` +is sufficient. Note that this means on Windows, ``IS_ABSOLUTE`` can be +false while ``HAS_ROOT_DIRECTORY`` can be true. -.. _REPLACE_FILENAME: +.. _IS_RELATIVE: -.. code-block:: cmake +:: - cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>]) + cmake_path(IS_RELATIVE <path-var> <out-var>) -Replaces the :ref:`filename <FILENAME_DEF>` component from ``<path-var>`` with -``<input>``. +This will store the opposite of ``IS_ABSOLUTE`` in ``<out-var>``. -If ``<path-var>`` has no filename component (`HAS_FILENAME`_ returns false), -the path is unchanged. +.. _IS_PREFIX: -Equivalent to the following: +:: - .. code-block:: cmake + cmake_path(IS_PREFIX <path-var> <input> [NORMALIZE] <out-var>) - cmake_path(HAS_FILENAME path has_filename) - if (has_filename) - cmake_path(REMOVE_FILENAME path) - cmake_path(APPEND path "replacement"); - endif() +Checks if ``<path-var>`` is the prefix of ``<input>``. -.. _REMOVE_EXTENSION: +When the ``NORMALIZE`` option is specified, ``<path-var>`` and ``<input>`` +are :ref:`normalized <Normalization>` before the check. .. code-block:: cmake - cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY] - [OUTPUT_VARIABLE <out-var>]) + set(path "/a/b/c/d") + cmake_path(IS_PREFIX path "/a/b" result) # result = true + cmake_path(IS_PREFIX path "/x/y/z" result) # result = false -Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``. + set(path "/a/b") + cmake_path(IS_PREFIX path "/a/c/../b" NORMALIZE result) # result = true -.. _REPLACE_EXTENSION: +.. _COMPARE: -.. code-block:: cmake +:: - cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input> - [OUTPUT_VARIABLE <out-var>]) + cmake_path(COMPARE <input1> EQUAL <input2> <out-var>) + cmake_path(COMPARE <input1> NOT_EQUAL <input2> <out-var>) -Replaces the :ref:`extension <EXTENSION_DEF>` with ``<input>``. +Compares the lexical representations of two paths provided as string literals. +No normalization is performed on either path. Equality is determined +according to the following pseudo-code logic: - 1. If ``<path-var>`` has an :ref:`extension <EXTENSION_DEF>` - (`HAS_EXTENSION`_ is true), it is removed. - 2. A ``dot`` character is appended to ``<path-var>``, if ``<input>`` is not - empty or does not begin with a ``dot`` character. - 3. ``<input>`` is appended as if `APPEND_STRING`_ was used. +:: + if(NOT <input1>.root_name() STREQUAL <input2>.root_name()) + return FALSE -Equivalent to the following: + if(<input1>.has_root_directory() XOR <input2>.has_root_directory()) + return FALSE - .. code-block:: cmake + Return FALSE if a relative portion of <input1> is not lexicographically + equal to the relative portion of <input2>. This comparison is performed path + component-wise. If all of the components compare equal, then return TRUE. - cmake_path(REMOVE_EXTENSION path) - if (NOT "input" MATCHES "^\\.") - cmake_path(APPEND_STRING path ".") - endif() - cmake_path(APPEND_STRING path "input"); +.. note:: + Unlike most other ``cmake_path()`` subcommands, the ``COMPARE`` subcommand + takes literal strings as input, not the names of variables. -Generation -^^^^^^^^^^ -.. _NORMAL_PATH: +Modification +^^^^^^^^^^^^ -.. code-block:: cmake +.. _cmake_path-SET: - cmake_path(NORMAL_PATH <path-var> [OUTPUT_VARIABLE <out-var>]) +:: -Normalize ``<path-var>``. + cmake_path(SET <path-var> [NORMALIZE] <input>) -A path can be normalized by following this algorithm: +Assign the ``<input>`` path to ``<path-var>``. If ``<input>`` is a native +path, it is converted into a cmake-style path with forward-slashes +(``/``). On Windows, the long filename marker is taken into account. - 1. If the path is empty, stop (normal form of an empty path is an empty - path). - 2. Replace each ``directory-separator`` (which may consist of multiple - separators) with a single ``/``. - 3. Replace each ``directory-separator`` character in the ``root-name`` with - ``/``. - 4. Remove each ``dot`` and any immediately following ``directory-separator``. - 5. Remove each non-dot-dot filename immediately followed by a - ``directory-separator`` and a ``dot-dot``, along with any immediately - following ``directory-separator``. - 6. If there is ``root-directory``, remove all ``dot-dots`` and any - ``directory-separators`` immediately following them. - 7. If the last filename is ``dot-dot``, remove any trailing - ``directory-separator``. - 8. If the path is empty, add a ``dot`` (normal form of ``./`` is ``.``). +When the ``NORMALIZE`` option is specified, the path is :ref:`normalized +<Normalization>` before the conversion. -.. _cmake_path-RELATIVE_PATH: -.. _RELATIVE_PATH: +For example: .. code-block:: cmake - cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>] - [OUTPUT_VARIABLE <out-var>]) - -Returns ``<path-var>`` made relative to ``BASE_DIRECTORY`` argument. If -``BASE_DIRECTORY`` is not specified, the default base directory will be -:variable:`CMAKE_CURRENT_SOURCE_DIR`. - -For reference, the algorithm used to compute the relative path is described -`here <https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_. - -.. _ABSOLUTE_PATH: + set(native_path "c:\\a\\b/..\\c") + cmake_path(SET path "${native_path}") + message("CMake path is \"${path}\"") -.. code-block:: cmake + cmake_path(SET path NORMALIZE "${native_path}") + message("Normalized CMake path is \"${path}\"") - cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] - [OUTPUT_VARIABLE <out-var>]) +Output:: -If ``<path-var>`` is a relative path (`IS_RELATIVE`_ is true), it is evaluated -relative to the given base directory specified by ``BASE_DIRECTORY`` option. + CMake path is "c:/a/b/../c" + Normalized CMake path is "c:/a/c" -If ``BASE_DIRECTORY`` is not specifired, the default base directory will be -:variable:`CMAKE_CURRENT_SOURCE_DIR`. +.. _APPEND: -When ``NORMALIZE`` option is specified, the path is :ref:`normalized -<NORMAL_PATH>` after the path computation. +:: -Because ``cmake_path`` does not access to the filesystem, symbolic links are -not resolved. To compute a real path, use :command:`file(REAL_PATH)` -command. + cmake_path(APPEND <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) -Conversion -^^^^^^^^^^ +Append all the ``<input>`` arguments to the ``<path-var>`` using ``/`` as +the ``directory-separator``. Depending on the ``<input>``, the previous +contents of ``<path-var>`` may be discarded. For each ``<input>`` argument, +the following algorithm (pseudo-code) applies: -.. _cmake_path-NATIVE_PATH: -.. _NATIVE_PATH: +:: -.. code-block:: cmake + # <path> is the contents of <path-var> - cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>) + if(<input>.is_absolute() OR + (<input>.has_root_name() AND + NOT <input>.root_name() STREQUAL <path>.root_name())) + replace <path> with <input> + return() + endif() -Converts a cmake-style ``<path-var>`` into a native -path with platform-specific slashes (``\`` on Windows and ``/`` elsewhere). + if(<input>.has_root_directory()) + remove any root-directory and the entire relative path from <path> + elseif(<path>.has_filename() OR + (NOT <path-var>.has_root_directory() OR <path>.is_absolute())) + append directory-separator to <path> + endif() -When ``NORMALIZE`` option is specified, the path is :ref:`normalized -<NORMAL_PATH>` before the conversion. + append <input> omitting any root-name to <path> -.. _CONVERT: -.. _cmake_path-TO_CMAKE_PATH_LIST: -.. _TO_CMAKE_PATH_LIST: +.. _APPEND_STRING: -.. code-block:: cmake +:: - cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <out-var> [NORMALIZE]) + cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>]) -Converts a native ``<input>`` path into cmake-style path with forward-slashes -(``/``). On Windows, the long filename marker is taken into account. The input -can be a single path or a system search path like ``$ENV{PATH}``. A search -path will be converted to a cmake-style list separated by ``;`` characters. The -result of the conversion is stored in the ``<out-var>`` variable. +Append all the ``<input>`` arguments to the ``<path-var>`` without adding any +``directory-separator``. -When ``NORMALIZE`` option is specified, the path is :ref:`normalized -<NORMAL_PATH>` before the conversion. +.. _REMOVE_FILENAME: -.. _cmake_path-TO_NATIVE_PATH_LIST: -.. _TO_NATIVE_PATH_LIST: +:: -.. code-block:: cmake + cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>]) - cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <out-var> [NORMALIZE]) +Removes the :ref:`filename <FILENAME_DEF>` component (as returned by +:ref:`GET ... FILENAME <GET_FILENAME>`) from ``<path-var>``. After removal, +any trailing ``directory-separator`` is left alone, if present. -Converts a cmake-style ``<input>`` path into a native path with -platform-specific slashes (``\`` on Windows and ``/`` elsewhere). The input can -be a single path or a cmake-style list. A list will be converted into a native -search path. The result of the conversion is stored in the ``<out-var>`` -variable. +If ``OUTPUT_VARIABLE`` is not given, then after this function returns, +`HAS_FILENAME`_ returns false for ``<path-var>``. -When ``NORMALIZE`` option is specified, the path is :ref:`normalized -<NORMAL_PATH>` before the conversion. +For example: -For Example: +.. code-block:: cmake - .. code-block:: cmake + set(path "/a/b") + cmake_path(REMOVE_FILENAME path) + message("First path is \"${path}\"") - set (paths "/a/b/c" "/x/y/z") - cmake_path (CONVERT "${paths}" TO_NATIVE_PATH_LIST native_paths) - message ("Native path list is \"${native_paths}\"") + # filename is now already empty, the following removes nothing + cmake_path(REMOVE_FILENAME path) + message("Second path is \"${result}\"") - Will display, on Windows:: +Output:: - Native path list is "\a\b\c;\x\y\z" + First path is "/a/" + Second path is "/a/" - And on the all other systems:: +.. _REPLACE_FILENAME: - Native path list is "/a/b/c:/x/y/z" +:: -Comparison -^^^^^^^^^^ + cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>]) -.. _COMPARE: +Replaces the :ref:`filename <FILENAME_DEF>` component from ``<path-var>`` +with ``<input>``. If ``<path-var>`` has no filename component (i.e. +`HAS_FILENAME`_ returns false), the path is unchanged. The operation is +equivalent to the following: .. code-block:: cmake - cmake_path(COMPARE <input1> EQUAL <input2> <out-var>) - cmake_path(COMPARE <input1> NOT_EQUAL <input2> <out-var>) + cmake_path(HAS_FILENAME path has_filename) + if(has_filename) + cmake_path(REMOVE_FILENAME path) + cmake_path(APPEND path input); + endif() -Compares the lexical representations of the path and another path. +.. _REMOVE_EXTENSION: -For testing equality, the following algorithm (pseudo-code) apply: +:: - .. code-block:: cmake + cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY] + [OUTPUT_VARIABLE <out-var>]) - IF (NOT <input1>.root_name() STREQUAL <input2>.root_name()) - returns FALSE - ELSEIF (<input1>.has_root_directory() XOR <input2>.has_root_directory()) - returns FALSE - ENDIF() +Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``. - returns TRUE or FALSE if the relative portion of <input1> is - lexicographically equal or not to the relative portion of <input2>. - Comparison is performed path component-wise +.. _REPLACE_EXTENSION: -Query -^^^^^ +:: -.. _HAS_ROOT_NAME: + cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input> + [OUTPUT_VARIABLE <out-var>]) + +Replaces the :ref:`extension <EXTENSION_DEF>` with ``<input>``. Its effect +is equivalent to the following: .. code-block:: cmake - cmake_path(HAS_ROOT_NAME <path-var> <out-var>) + cmake_path(REMOVE_EXTENSION path) + if(NOT "input" MATCHES "^\\.") + cmake_path(APPEND_STRING path ".") + endif() + cmake_path(APPEND_STRING path "input") -Checks if ``<path-var>`` has ``root-name``. -.. _HAS_ROOT_DIRECTORY: +Generation +^^^^^^^^^^ -.. code-block:: cmake +.. _NORMAL_PATH: - cmake_path(HAS_ROOT_DIRECTORY <path-var> <out-var>) +:: -Checks if ``<path-var>`` has ``root-directory``. + cmake_path(NORMAL_PATH <path-var> [OUTPUT_VARIABLE <out-var>]) -.. _HAS_ROOT_PATH: +Normalize ``<path-var>`` according the steps described in :ref:`Normalization`. -.. code-block:: cmake +.. _cmake_path-RELATIVE_PATH: +.. _RELATIVE_PATH: - cmake_path(HAS_ROOT_PATH <path-var> <out-var>) +:: -Checks if ``<path-var>`` has root path. + cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>] + [OUTPUT_VARIABLE <out-var>]) -Effectively, checks if ``<path-var>`` has ``root-name`` and ``root-directory``. +Modifies ``<path-var>`` to make it relative to the ``BASE_DIRECTORY`` argument. +If ``BASE_DIRECTORY`` is not specified, the default base directory will be +:variable:`CMAKE_CURRENT_SOURCE_DIR`. -.. _HAS_FILENAME: +For reference, the algorithm used to compute the relative path is the same +as that used by C++ +`std::filesystem::path::lexically_relative +<https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_. -.. code-block:: cmake +.. _ABSOLUTE_PATH: - cmake_path(HAS_FILENAME <path-var> <out-var>) +:: -Checks if ``<path-var>`` has a :ref:`filename <FILENAME_DEF>`. + cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE] + [OUTPUT_VARIABLE <out-var>]) -.. _HAS_EXTENSION: +If ``<path-var>`` is a relative path (`IS_RELATIVE`_ is true), it is evaluated +relative to the given base directory specified by ``BASE_DIRECTORY`` option. +If ``BASE_DIRECTORY`` is not specified, the default base directory will be +:variable:`CMAKE_CURRENT_SOURCE_DIR`. -.. code-block:: cmake +When the ``NORMALIZE`` option is specified, the path is :ref:`normalized +<Normalization>` after the path computation. - cmake_path(HAS_EXTENSION <path-var> <out-var>) +Because ``cmake_path()`` does not access the filesystem, symbolic links are +not resolved. To compute a real path with symbolic links resolved, use the +:command:`file(REAL_PATH)` command instead. -Checks if ``<path-var>`` has an :ref:`extension <EXTENSION_DEF>`. If the first -character in the filename is a period, it is not treated as an extension (for -example ".profile"). +Native Conversion +^^^^^^^^^^^^^^^^^ -.. _HAS_STEM: +For commands in this section, *native* refers to the host platform, not the +target platform when cross-compiling. -.. code-block:: cmake +.. _cmake_path-NATIVE_PATH: +.. _NATIVE_PATH: - cmake_path(HAS_STEM <path-var> <out-var>) +:: -Checks if ``<path-var>`` has stem (:ref:`GET ... STEM <GET_STEM>` returns a non -empty path). + cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>) -.. _HAS_RELATIVE_PATH: +Converts a cmake-style ``<path-var>`` into a native path with +platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere). -.. code-block:: cmake - - cmake_path(HAS_RELATIVE_PATH <path-var> <out-var>) +When the ``NORMALIZE`` option is specified, the path is :ref:`normalized +<Normalization>` before the conversion. -Checks if ``<path-var>`` has relative path (`GET_RELATIVE_PATH`_ returns a -non-empty path). +.. _CONVERT: +.. _cmake_path-TO_CMAKE_PATH_LIST: +.. _TO_CMAKE_PATH_LIST: -.. _HAS_PARENT_PATH: +:: -.. code-block:: cmake + cmake_path(CONVERT <input> TO_CMAKE_PATH_LIST <out-var> [NORMALIZE]) - cmake_path(HAS_PARENT_PATH <path-var> <out-var>) +Converts a native ``<input>`` path into a cmake-style path with forward +slashes (``/``). On Windows hosts, the long filename marker is taken into +account. The input can be a single path or a system search path like +``$ENV{PATH}``. A search path will be converted to a cmake-style list +separated by ``;`` characters (on non-Windows platforms, this essentially +means ``:`` separators are replaced with ``;``). The result of the +conversion is stored in the ``<out-var>`` variable. -Checks if ``<path-var>`` has parent path. The result is true except if the path -is only composed of a :ref:`filename <FILENAME_DEF>`. +When the ``NORMALIZE`` option is specified, the path is :ref:`normalized +<Normalization>` before the conversion. -.. _IS_ABSOLUTE: +.. note:: + Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand + takes a literal string as input, not the name of a variable. -.. code-block:: cmake +.. _cmake_path-TO_NATIVE_PATH_LIST: +.. _TO_NATIVE_PATH_LIST: - cmake_path(IS_ABSOLUTE <path-var> <out-var>) +:: -Checks if ``<path-var>`` is absolute. + cmake_path(CONVERT <input> TO_NATIVE_PATH_LIST <out-var> [NORMALIZE]) -An absolute path is a path that unambiguously identifies the location of a file -without reference to an additional starting location. +Converts a cmake-style ``<input>`` path into a native path with +platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere). +The input can be a single path or a cmake-style list. A list will be +converted into a native search path (``;``-separated on Windows, +``:``-separated on other platforms). The result of the conversion is +stored in the ``<out-var>`` variable. -.. _IS_RELATIVE: +When the ``NORMALIZE`` option is specified, the path is :ref:`normalized +<Normalization>` before the conversion. -.. code-block:: cmake +.. note:: + Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand + takes a literal string as input, not the name of a variable. - cmake_path(IS_RELATIVE <path-var> <out-var>) +For example: -Checks if path is relative (i.e. not :ref:`absolute <IS_ABSOLUTE>`). +.. code-block:: cmake -.. _IS_PREFIX: + set(paths "/a/b/c" "/x/y/z") + cmake_path(CONVERT "${paths}" TO_NATIVE_PATH_LIST native_paths) + message("Native path list is \"${native_paths}\"") -.. code-block:: cmake +Output on Windows:: - cmake_path(IS_PREFIX <path-var> <input> [NORMALIZE] <out-var>) + Native path list is "\a\b\c;\x\y\z" -Checks if ``<path-var>`` is the prefix of ``<input>``. +Output on all other platforms:: -When ``NORMALIZE`` option is specified, the paths are :ref:`normalized -<NORMAL_PATH>` before the check. + Native path list is "/a/b/c:/x/y/z" Hashing ^^^^^^^ .. _HASH: -.. code-block:: cmake - - cmake_path(HASH <path-var> [NORMALIZE] <out-var>) +:: -Compute hash value of ``<path-var>`` such that if for two paths (``p1`` and -``p2``) are equal (:ref:`COMPARE ... EQUAL <COMPARE>`) then hash value of p1 is -equal to hash value of p2. + cmake_path(HASH <path-var> <out-var>) -When ``NORMALIZE`` option is specified, the paths are :ref:`normalized -<NORMAL_PATH>` before the check. +Compute a hash value of ``<path-var>`` such that for two paths ``p1`` and +``p2`` that compare equal (:ref:`COMPARE ... EQUAL <COMPARE>`), the hash +value of ``p1`` is equal to the hash value of ``p2``. The path is always +:ref:`normalized <Normalization>` before the hash is computed. diff --git a/Help/command/if.rst b/Help/command/if.rst index 72d328d..c51d2bc 100644 --- a/Help/command/if.rst +++ b/Help/command/if.rst @@ -47,7 +47,8 @@ as ``EXISTS``, ``COMMAND``, and ``DEFINED``. Then binary tests such as and ``MATCHES``. Then the boolean operators in the order ``NOT``, ``AND``, and finally ``OR``. -Possible conditions are: +Basic Expressions +""""""""""""""""" ``if(<constant>)`` True if the constant is ``1``, ``ON``, ``YES``, ``TRUE``, ``Y``, @@ -62,6 +63,9 @@ Possible conditions are: True if given a variable that is defined to a value that is not a false constant. False otherwise. (Note macro arguments are not variables.) +Logic Operators +""""""""""""""" + ``if(NOT <condition>)`` True if the condition is not true. @@ -71,6 +75,15 @@ Possible conditions are: ``if(<cond1> OR <cond2>)`` True if either condition would be considered true individually. +``if((condition) AND (condition OR (condition)))`` + The conditions inside the parenthesis are evaluated first and then + the remaining condition is evaluated as in the other examples. + Where there are nested parenthesis the innermost are evaluated as part + of evaluating the condition that contains them. + +Existence Checks +"""""""""""""""" + ``if(COMMAND command-name)`` True if the given name is a command, macro or function that can be invoked. @@ -89,6 +102,21 @@ Possible conditions are: True if the given name is an existing test name created by the :command:`add_test` command. +``if(DEFINED <name>|CACHE{<name>}|ENV{<name>})`` + True if a variable, cache variable or environment variable + with given ``<name>`` is defined. The value of the variable + does not matter. Note that macro arguments are not variables. + + .. versionadded:: 3.14 + Added support for ``CACHE{<name>}`` variables. + +``if(<variable|string> IN_LIST <variable>)`` + .. versionadded:: 3.3 + True if the given element is contained in the named list variable. + +File Operations +""""""""""""""" + ``if(EXISTS path-to-file-or-directory)`` True if the named file or directory exists. Behavior is well-defined only for full paths. Resolves symbolic links, i.e. if the named file or @@ -114,6 +142,9 @@ Possible conditions are: ``if(IS_ABSOLUTE path)`` True if the given path is an absolute path. +Comparisons +""""""""""" + ``if(<variable|string> MATCHES regex)`` True if the given string or variable's value matches the given regular condition. See :ref:`Regex Specification` for regex format. @@ -165,6 +196,9 @@ Possible conditions are: True if the given string or variable's value is lexicographically greater than or equal to the string or variable on the right. +Version Comparisons +""""""""""""""""""" + ``if(<variable|string> VERSION_LESS <variable|string>)`` Component-wise integer version number comparison (version format is ``major[.minor[.patch[.tweak]]]``, omitted components are treated as zero). @@ -197,24 +231,6 @@ Possible conditions are: Any non-integer version component or non-integer trailing part of a version component effectively truncates the string at that point. -``if(<variable|string> IN_LIST <variable>)`` - .. versionadded:: 3.3 - True if the given element is contained in the named list variable. - -``if(DEFINED <name>|CACHE{<name>}|ENV{<name>})`` - True if a variable, cache variable or environment variable - with given ``<name>`` is defined. The value of the variable - does not matter. Note that macro arguments are not variables. - - .. versionadded:: 3.14 - Added support for ``CACHE{<name>}`` variables. - -``if((condition) AND (condition OR (condition)))`` - The conditions inside the parenthesis are evaluated first and then - the remaining condition is evaluated as in the previous examples. - Where there are nested parenthesis the innermost are evaluated as part - of evaluating the condition that contains them. - Variable Expansion ^^^^^^^^^^^^^^^^^^ diff --git a/Help/command/install.rst b/Help/command/install.rst index bd8da39..35207f4 100644 --- a/Help/command/install.rst +++ b/Help/command/install.rst @@ -473,6 +473,11 @@ this advice while installing headers to a project-specific subdirectory: use "generator expressions" with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for available expressions. +.. versionadded:: 3.20 + An install rename given as a ``RENAME`` argument may + use "generator expressions" with the syntax ``$<...>``. See the + :manual:`cmake-generator-expressions(7)` manual for available expressions. + Installing Directories ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Help/dev/documentation.rst b/Help/dev/documentation.rst index c302790..29fc880 100644 --- a/Help/dev/documentation.rst +++ b/Help/dev/documentation.rst @@ -123,10 +123,23 @@ documentation: ``command`` A CMake language command. +``cpack_gen`` + A CPack package generator. + See the `cpack(1)`_ command-line tool's ``-G`` option. + +``envvar`` + An environment variable. + See the `cmake-env-variables(7)`_ manual + and the `set()`_ command. + ``generator`` A CMake native build system generator. See the `cmake(1)`_ command-line tool's ``-G`` option. +``genex`` + A CMake generator expression. + See the `cmake-generator-expressions(7)`_ manual. + ``manual`` A CMake manual page, like the `cmake(1)`_ manual. @@ -160,10 +173,12 @@ which is expected to be of the form:: ------------- and to appear at or near the top of the ``.rst`` file before any other -lines starting in a letter, digit, or ``<``. If no such title appears +lines starting in a letter, digit, ``<``, or ``$``. If no such title appears literally in the ``.rst`` file, the object name is the ``<file-name>``. If a title does appear, it is expected that ``<file-name>`` is equal -to ``<object-name>`` with any ``<`` and ``>`` characters removed. +to ``<object-name>`` with any ``<`` and ``>`` characters removed, +or in the case of a ``$<genex-name>`` or ``$<genex-name:...>``, the +``genex-name``. Second, the CMake Domain provides directives to define objects inside other documents: @@ -174,6 +189,14 @@ other documents: This indented block documents <command-name>. + .. envvar:: <envvar-name> + + This indented block documents <envvar-name>. + + .. genex:: <genex-name> + + This indented block documents <genex-name>. + .. variable:: <variable-name> This indented block documents <variable-name>. @@ -183,11 +206,14 @@ the first approach above. .. _`Sphinx Domain`: http://sphinx-doc.org/domains.html .. _`cmake(1)`: https://cmake.org/cmake/help/latest/manual/cmake.1.html +.. _`cmake-env-variables(7)`: https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html +.. _`cmake-generator-expressions(7)`: https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html .. _`cmake-modules(7)`: https://cmake.org/cmake/help/latest/manual/cmake-modules.7.html .. _`cmake-policies(7)`: https://cmake.org/cmake/help/latest/manual/cmake-policies.7.html .. _`cmake-properties(7)`: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html .. _`cmake-variables(7)`: https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html .. _`cmake_policy()`: https://cmake.org/cmake/help/latest/command/cmake_policy.html +.. _`cpack(1)`: https://cmake.org/cmake/help/latest/manual/cpack.1.html .. _`include()`: https://cmake.org/cmake/help/latest/command/include.html .. _`set()`: https://cmake.org/cmake/help/latest/command/set.html .. _`set_property()`: https://cmake.org/cmake/help/latest/command/set_property.html diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst index 4d2b076..d019161 100644 --- a/Help/dev/experimental.rst +++ b/Help/dev/experimental.rst @@ -7,4 +7,64 @@ See documentation on `CMake Development`_ for more information. .. _`CMake Development`: README.rst -No experimental features are under development in this version of CMake. +C++20 Module Dependencies +========================= + +The Ninja generator has experimental infrastructure supporting C++20 module +dependency scanning. This is similar to the Fortran modules support, but +relies on external tools to scan C++20 translation units for module +dependencies. The approach is described by Kitware's `D1483r1`_ paper. + +The ``CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP`` variable can be set to ``1`` +in order to activate this undocumented experimental infrastructure. This +is **intended to make the functionality available to compiler writers** so +they can use it to develop and test their dependency scanning tool. +The ``CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE`` variable must also be set +to tell CMake how to invoke the C++20 module dependency scanning tool. + +For example, add code like the following to a test project: + +.. code-block:: cmake + + set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) + string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE + "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> <SOURCE>" + " -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>" + " ${flags_to_scan_deps} -fdep-file=<DYNDEP_FILE> -fdep-output=<OBJECT>" + ) + +The tool specified by ``CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE`` is +expected to process the translation unit, write preprocessor dependencies +to the file specified by the ``<DEP_FILE>`` placeholder, and write module +dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder. + +The module dependencies should be written in the format described +by the `P1689r3`_ paper. + +Compiler writers may try out their scanning functionality using +the `cxx-modules-sandbox`_ test project, modified to set variables +as above for their compiler. + +For compilers that generate module maps, tell CMake as follows: + +.. code-block:: cmake + + set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc") + set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG + "${compiler_flags_for_module_map} -fmodule-mapper=<MODULE_MAP_FILE>") + +Currently, the only supported format is ``gcc``. The format is described in +the GCC documentation, but the relevant section for the purposes of CMake is: + + A mapping file consisting of space-separated module-name, filename + pairs, one per line. Only the mappings for the direct imports and any + module export name need be provided. If other mappings are provided, + they override those stored in any imported CMI files. A repository + root may be specified in the mapping file by using ``$root`` as the + module name in the first active line. + + -- GCC module mapper documentation + +.. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html +.. _`P1689r3`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1689r3.html +.. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst index d1df42b..8901192 100644 --- a/Help/generator/Ninja Multi-Config.rst +++ b/Help/generator/Ninja Multi-Config.rst @@ -130,3 +130,34 @@ output config using the ``Release`` command config. The ``Release`` build of the ``generator`` target is called with ``Debug.txt Debug Release`` as arguments. The command depends on the ``Release`` builds of ``tgt1`` and ``tgt4``, and the ``Debug`` builds of ``tgt2`` and ``tgt3``. + +``PRE_BUILD``, ``PRE_LINK``, and ``POST_BUILD`` custom commands for targets +only get run in their "native" configuration (the ``Release`` configuration in +the ``build-Release.ninja`` file) unless they have no ``BYPRODUCTS`` or their +``BYPRODUCTS`` are unique per config. Consider the following example: + +.. code-block:: cmake + + add_executable(exe main.c) + add_custom_command( + TARGET exe + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Running no-byproduct command" + ) + add_custom_command( + TARGET exe + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Running separate-byproduct command for $<CONFIG>" + BYPRODUCTS $<CONFIG>.txt + ) + add_custom_command( + TARGET exe + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Running common-byproduct command for $<CONFIG>" + BYPRODUCTS exe.txt + ) + +In this example, if you build ``exe:Debug`` in ``build-Release.ninja``, the +first and second custom commands get run, since their byproducts are unique +per-config, but the last custom command does not. However, if you build +``exe:Release`` in ``build-Release.ninja``, all three custom commands get run. diff --git a/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt b/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt index 13c82dd..9a9e40e 100644 --- a/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt +++ b/Help/guide/importing-exporting/MathFunctions/CMakeLists.txt @@ -31,7 +31,7 @@ install(FILES MathFunctions.h DESTINATION include) install(EXPORT MathFunctionsTargets FILE MathFunctionsTargets.cmake NAMESPACE MathFunctions:: - DESTINATION lib/cmake + DESTINATION lib/cmake/MathFunctions ) # include CMakePackageConfigHelpers macro @@ -58,14 +58,14 @@ write_basic_package_version_file( # create config file configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" - INSTALL_DESTINATION lib/cmake + INSTALL_DESTINATION lib/cmake/MathFunctions ) # install config files install(FILES "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/MathFunctionsConfigVersion.cmake" - DESTINATION lib/cmake + DESTINATION lib/cmake/MathFunctions ) # generate the export targets for the build tree diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst index 4b09e53..94753d5 100644 --- a/Help/guide/tutorial/index.rst +++ b/Help/guide/tutorial/index.rst @@ -176,7 +176,7 @@ directory: To make use of the new library we will add an :command:`add_subdirectory` call in the top-level ``CMakeLists.txt`` file so that the library will get built. We add the new library to the executable, and add ``MathFunctions`` as -an include directory so that the ``mqsqrt.h`` header file can be found. The +an include directory so that the ``mysqrt.h`` header file can be found. The last few lines of the top-level ``CMakeLists.txt`` file should now look like: .. code-block:: cmake @@ -414,27 +414,23 @@ tutorial assume that they are not common. If the platform has ``log`` and ``exp`` then we will use them to compute the square root in the ``mysqrt`` function. We first test for the availability of -these functions using the :module:`CheckSymbolExists` module in the top-level -``CMakeLists.txt``. On some platforms, we will need to link to the m library. -If ``log`` and ``exp`` are not initially found, require the m library and try -again. - -We're going to use the new defines in ``TutorialConfig.h.in``, so be sure to -set them before that file is configured. +these functions using the :module:`CheckSymbolExists` module in +``MathFunctions/CMakeLists.txt``. On some platforms, we will need to link to +the m library. If ``log`` and ``exp`` are not initially found, require the m +library and try again. .. literalinclude:: Step6/MathFunctions/CMakeLists.txt :language: cmake :start-after: # does this system provide the log and exp functions? :end-before: # add compile definitions -Now let's add these defines to ``TutorialConfig.h.in`` so that we can use them -from ``mysqrt.cxx``: - -.. code-block:: console +If available, use :command:`target_compile_definitions` to specify +``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions. - // does the platform provide exp and log functions? - #cmakedefine HAVE_LOG - #cmakedefine HAVE_EXP +.. literalinclude:: Step6/MathFunctions/CMakeLists.txt + :language: cmake + :start-after: # add compile definitions + :end-before: # install rules If ``log`` and ``exp`` are available on the system, then we will use them to compute the square root in the ``mysqrt`` function. Add the following code to @@ -456,51 +452,8 @@ Run the :manual:`cmake <cmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it with your chosen build tool and run the Tutorial executable. -You will notice that we're not using ``log`` and ``exp``, even if we think they -should be available. We should realize quickly that we have forgotten to -include ``TutorialConfig.h`` in ``mysqrt.cxx``. - -We will also need to update ``MathFunctions/CMakeLists.txt`` so ``mysqrt.cxx`` -knows where this file is located: - -.. code-block:: cmake - - target_include_directories(MathFunctions - INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_BINARY_DIR} - ) - -After making this update, go ahead and build the project again and run the -built Tutorial executable. If ``log`` and ``exp`` are still not being used, -open the generated ``TutorialConfig.h`` file from the build directory. Maybe -they aren't available on the current system? - Which function gives better results now, sqrt or mysqrt? -Specify Compile Definition --------------------------- - -Is there a better place for us to save the ``HAVE_LOG`` and ``HAVE_EXP`` values -other than in ``TutorialConfig.h``? Let's try to use -:command:`target_compile_definitions`. - -First, remove the defines from ``TutorialConfig.h.in``. We no longer need to -include ``TutorialConfig.h`` from ``mysqrt.cxx`` or the extra include in -``MathFunctions/CMakeLists.txt``. - -Next, we can move the check for ``HAVE_LOG`` and ``HAVE_EXP`` to -``MathFunctions/CMakeLists.txt`` and then specify those values as ``PRIVATE`` -compile definitions. - -.. literalinclude:: Step6/MathFunctions/CMakeLists.txt - :language: cmake - :start-after: # does this system provide the log and exp functions? - :end-before: # install rules - -After making these updates, go ahead and build the project again. Run the -built Tutorial executable and verify that the results are same as earlier in -this step. - Adding a Custom Command and Generated File (Step 6) =================================================== diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index 85ed935..af9a8ab 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -23,15 +23,14 @@ in turn link to developer guides for CMake itself. Find Modules ============ -A "find module" is a ``Find<PackageName>.cmake`` file to be loaded -by the :command:`find_package` command when invoked for ``<PackageName>``. +A "find module" is a ``Find<PackageName>.cmake`` file to be loaded by the +:command:`find_package` command when invoked for ``<PackageName>``. -The primary task of a find module is to determine whether a package -exists on the system, set the ``<PackageName>_FOUND`` variable to reflect -this and provide any variables, macros and imported targets required to -use the package. A find module is useful in cases where an upstream -library does not provide a -:ref:`config file package <Config File Packages>`. +The primary task of a find module is to determine whether a package is +available, set the ``<PackageName>_FOUND`` variable to reflect this and +provide any variables, macros and imported targets required to use the +package. A find module is useful in cases where an upstream library does +not provide a :ref:`config file package <Config File Packages>`. The traditional approach is to use variables for everything, including libraries and executables: see the `Standard Variable Names`_ section @@ -91,55 +90,92 @@ Standard Variable Names For a ``FindXxx.cmake`` module that takes the approach of setting variables (either instead of or in addition to creating imported targets), the following variable names should be used to keep things -consistent between find modules. Note that all variables start with -``Xxx_`` to make sure they do not interfere with other find modules; the -same consideration applies to macros, functions and imported targets. +consistent between Find modules. Note that all variables start with +``Xxx_``, which (unless otherwise noted) must match exactly the name +of the ``FindXxx.cmake`` file, including upper/lowercase. +This prefix on the variable names ensures that they do not conflict with +variables of other Find modules. The same pattern should also be followed +for any macros, functions and imported targets defined by the Find module. ``Xxx_INCLUDE_DIRS`` The final set of include directories listed in one variable for use by - client code. This should not be a cache entry. + client code. This should not be a cache entry (note that this also means + this variable should not be used as the result variable of a + :command:`find_path` command - see ``Xxx_INCLUDE_DIR`` below for that). ``Xxx_LIBRARIES`` - The libraries to link against to use Xxx. These should include full - paths. This should not be a cache entry. + The libraries to use with the module. These may be CMake targets, full + absolute paths to a library binary or the name of a library that the + linker must find in its search path. This should not be a cache entry + (note that this also means this variable should not be used as the + result variable of a :command:`find_library` command - see + ``Xxx_LIBRARY`` below for that). ``Xxx_DEFINITIONS`` - Definitions to use when compiling code that uses Xxx. This really - shouldn't include options such as ``-DHAS_JPEG`` that a client + The compile definitions to use when compiling code that uses the module. + This really shouldn't include options such as ``-DHAS_JPEG`` that a client source-code file uses to decide whether to ``#include <jpeg.h>`` ``Xxx_EXECUTABLE`` - Where to find the Xxx tool. - -``Xxx_Yyy_EXECUTABLE`` - Where to find the Yyy tool that comes with Xxx. + The full absolute path to an executable. In this case, ``Xxx`` might not + be the name of the module, it might be the name of the tool (usually + converted to all uppercase), assuming that tool has such a well-known name + that it is unlikely that another tool with the same name exists. It would + be appropriate to use this as the result variable of a + :command:`find_program` command. + +``Xxx_YYY_EXECUTABLE`` + Similar to ``Xxx_EXECUTABLE`` except here the ``Xxx`` is always the module + name and ``YYY`` is the tool name (again, usually fully uppercase). + Prefer this form if the tool name is not very widely known or has the + potential to clash with another tool. For greater consistency, also + prefer this form if the module provides more than one executable. ``Xxx_LIBRARY_DIRS`` Optionally, the final set of library directories listed in one - variable for use by client code. This should not be a cache entry. + variable for use by client code. This should not be a cache entry. ``Xxx_ROOT_DIR`` - Where to find the base directory of Xxx. - -``Xxx_VERSION_Yy`` - Expect Version Yy if true. Make sure at most one of these is ever true. - -``Xxx_WRAP_Yy`` - If False, do not try to use the relevant CMake wrapping command. + Where to find the base directory of the module. + +``Xxx_VERSION_VV`` + Variables of this form specify whether the ``Xxx`` module being provided + is version ``VV`` of the module. There should not be more than one + variable of this form set to true for a given module. For example, a + module ``Barry`` might have evolved over many years and gone through a + number of different major versions. Version 3 of the ``Barry`` module + might set the variable ``Barry_VERSION_3`` to true, whereas an older + version of the module might set ``Barry_VERSION_2`` to true instead. + It would be an error for both ``Barry_VERSION_3`` and ``Barry_VERSION_2`` + to both be set to true. + +``Xxx_WRAP_YY`` + When a variable of this form is set to false, it indicates that the + relevant wrapping command should not be used. The wrapping command + depends on the module, it may be implied by the module name or it might + be specified by the ``YY`` part of the variable. ``Xxx_Yy_FOUND`` - If False, optional Yy part of Xxx system is not available. + For variables of this form, ``Yy`` is the name of a component for the + module. It should match exactly one of the valid component names that + may be passed to the :command:`find_package` command for the module. + If a variable of this form is set to false, it means that the ``Yy`` + component of module ``Xxx`` was not found or is not available. + Variables of this form would typically be used for optional components + so that the caller can check whether an optional component is available. ``Xxx_FOUND`` - Set to false, or undefined, if we haven't found, or don't want to use - Xxx. + When the :command:`find_package` command returns to the caller, this + variable will be set to true if the module was deemed to have been found + successfully. ``Xxx_NOT_FOUND_MESSAGE`` Should be set by config-files in the case that it has set ``Xxx_FOUND`` to FALSE. The contained message will be printed by the :command:`find_package` command and by - ``find_package_handle_standard_args()`` to inform the user about the - problem. + :command:`find_package_handle_standard_args` to inform the user about the + problem. Use this instead of calling :command:`message` directly to + report a reason for failing to find the module or package. ``Xxx_RUNTIME_LIBRARY_DIRS`` Optionally, the runtime library search path for use when running an @@ -160,23 +196,36 @@ same consideration applies to macros, functions and imported targets. ``Xxx_VERSION_PATCH`` The patch version of the package found, if any. -The following names should not usually be used in CMakeLists.txt files, but -are typically cache variables for users to edit and control the -behaviour of find modules (like entering the path to a library manually) +The following names should not usually be used in ``CMakeLists.txt`` files. +They are intended for use by Find modules to specify and cache the locations +of specific files or directories. Users are typically able to set and edit +these variables to control the behavior of Find modules (like entering the +path to a library manually): ``Xxx_LIBRARY`` - The path of the Xxx library (as used with :command:`find_library`, for - example). + The path of the library. Use this form only when the module provides a + single library. It is appropriate to use this as the result variable + in a :command:`find_library` command. ``Xxx_Yy_LIBRARY`` - The path of the Yy library that is part of the Xxx system. It may or - may not be required to use Xxx. + The path of library ``Yy`` provided by the module ``Xxx``. Use this form + when the module provides more than one library or where other modules may + also provide a library of the same name. It is also appropriate to use + this form as the result variable in a :command:`find_library` command. ``Xxx_INCLUDE_DIR`` - Where to find headers for using the Xxx library. + When the module provides only a single library, this variable can be used + to specify where to find headers for using the library (or more accurately, + the path that consumers of the library should add to their header search + path). It would be appropriate to use this as the result variable in a + :command:`find_path` command. ``Xxx_Yy_INCLUDE_DIR`` - Where to find headers for using the Yy library of the Xxx system. + If the module provides more than one library or where other modules may + also provide a library of the same name, this form is recommended for + specifying where to find headers for using library ``Yy`` provided by + the module. Again, it would be appropriate to use this as the result + variable in a :command:`find_path` command. To prevent users being overwhelmed with settings to configure, try to keep as many options as possible out of the cache, leaving at least one @@ -185,7 +234,8 @@ not-found library (e.g. ``Xxx_ROOT_DIR``). For the same reason, mark most cache options as advanced. For packages which provide both debug and release binaries, it is common to create cache variables with a ``_LIBRARY_<CONFIG>`` suffix, such as ``Foo_LIBRARY_RELEASE`` and -``Foo_LIBRARY_DEBUG``. +``Foo_LIBRARY_DEBUG``. The :module:`SelectLibraryConfigurations` module +can be helpful for such cases. While these are the standard variable names, you should provide backwards compatibility for any old names that were actually in use. diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst index 6876e1c..89739b7 100644 --- a/Help/manual/cmake-file-api.7.rst +++ b/Help/manual/cmake-file-api.7.rst @@ -1154,3 +1154,160 @@ The members specific to ``cmakeFiles`` objects are: ``isCMake`` Optional member that is present with boolean value ``true`` if the path specifies a file in the CMake installation. + +Object Kind "toolchains" +------------------------ + +The ``toolchains`` object kind lists properties of the toolchains used during +the build. These include the language, compiler path, ID, and version. + +There is only one ``toolchains`` object major version, version 1. + +"toolchains" version 1 +^^^^^^^^^^^^^^^^^^^^^^ + +``toolchains`` object version 1 is a JSON object: + +.. code-block:: json + + { + "kind": "toolchains", + "version": { "major": 1, "minor": 0 }, + "toolchains": [ + { + "language": "C", + "compiler": { + "path": "/usr/bin/cc", + "id": "GNU", + "version": "9.3.0", + "implicit": { + "includeDirectories": [ + "/usr/lib/gcc/x86_64-linux-gnu/9/include", + "/usr/local/include", + "/usr/include/x86_64-linux-gnu", + "/usr/include" + ], + "linkDirectories": [ + "/usr/lib/gcc/x86_64-linux-gnu/9", + "/usr/lib/x86_64-linux-gnu", + "/usr/lib", + "/lib/x86_64-linux-gnu", + "/lib" + ], + "linkFrameworkDirectories": [], + "linkLibraries": [ "gcc", "gcc_s", "c", "gcc", "gcc_s" ] + } + }, + "sourceFileExtensions": [ "c", "m" ] + }, + { + "language": "CXX", + "compiler": { + "path": "/usr/bin/c++", + "id": "GNU", + "version": "9.3.0", + "implicit": { + "includeDirectories": [ + "/usr/include/c++/9", + "/usr/include/x86_64-linux-gnu/c++/9", + "/usr/include/c++/9/backward", + "/usr/lib/gcc/x86_64-linux-gnu/9/include", + "/usr/local/include", + "/usr/include/x86_64-linux-gnu", + "/usr/include" + ], + "linkDirectories": [ + "/usr/lib/gcc/x86_64-linux-gnu/9", + "/usr/lib/x86_64-linux-gnu", + "/usr/lib", + "/lib/x86_64-linux-gnu", + "/lib" + ], + "linkFrameworkDirectories": [], + "linkLibraries": [ + "stdc++", "m", "gcc_s", "gcc", "c", "gcc_s", "gcc" + ] + } + }, + "sourceFileExtensions": [ + "C", "M", "c++", "cc", "cpp", "cxx", "mm", "CPP" + ] + } + ] + } + +The members specific to ``toolchains`` objects are: + +``toolchains`` + A JSON array whose entries are each a JSON object specifying a toolchain + associated with a particular language. The members of each entry are: + + ``language`` + A JSON string specifying the toolchain language, like C or CXX. Language + names are the same as langauge names that can be passed to the + :command:`project` command. Because CMake only supports a single toolchain + per language, this field can be used as a key. + + ``compiler`` + A JSON object containing members: + + ``path`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_COMPILER` variable is defined for the current + language. Its value is a JSON string holding the path to the compiler. + + ``id`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_COMPILER_ID` variable is defined for the current + language. Its value is a JSON string holding the ID (GNU, MSVC, etc.) of + the compiler. + + ``version`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable is defined for the + current language. Its value is a JSON string holding the version of the + compiler. + + ``target`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_COMPILER_TARGET` variable is defined for the + current language. Its value is a JSON string holding the cross-compiling + target of the compiler. + + ``implicit`` + A JSON object containing members: + + ``includeDirectories`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_IMPLICIT_INCLUDE_DIRECTORIES` variable is + defined for the current language. Its value is a JSON array of JSON + strings where each string holds a path to an implicit include + directory for the compiler. + + ``linkDirectories`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES` variable is + defined for the current language. Its value is a JSON array of JSON + strings where each string holds a path to an implicit link directory + for the compiler. + + ``linkFrameworkDirectories`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES` variable + is defined for the current language. Its value is a JSON array of JSON + strings where each string holds a path to an implicit link framework + directory for the compiler. + + ``linkLibraries`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES` variable is defined + for the current language. Its value is a JSON array of JSON strings + where each string holds a path to an implicit link library for the + compiler. + + ``sourceFileExtensions`` + Optional member that is present when the + :variable:`CMAKE_<LANG>_SOURCE_FILE_EXTENSIONS` variable is defined for + the current language. Its value is a JSON array of JSON strings where each + each string holds a file extension (without the leading dot) for the + language. diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index c949ce1..ca4ea3e 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -46,7 +46,8 @@ Available boolean expressions are: Logical Operators ----------------- -``$<BOOL:string>`` +.. genex:: $<BOOL:string> + Converts ``string`` to ``0`` or ``1``. Evaluates to ``0`` if any of the following is true: @@ -57,23 +58,27 @@ Logical Operators Otherwise evaluates to ``1``. -``$<AND:conditions>`` +.. genex:: $<AND:conditions> + where ``conditions`` is a comma-separated list of boolean expressions. Evaluates to ``1`` if all conditions are ``1``. Otherwise evaluates to ``0``. -``$<OR:conditions>`` +.. genex:: $<OR:conditions> + where ``conditions`` is a comma-separated list of boolean expressions. Evaluates to ``1`` if at least one of the conditions is ``1``. Otherwise evaluates to ``0``. -``$<NOT:condition>`` +.. genex:: $<NOT:condition> + ``0`` if ``condition`` is ``1``, else ``1``. String Comparisons ------------------ -``$<STREQUAL:string1,string2>`` +.. genex:: $<STREQUAL:string1,string2> + ``1`` if ``string1`` and ``string2`` are equal, else ``0``. The comparison is case-sensitive. For a case-insensitive comparison, combine with a :ref:`string transforming generator expression @@ -83,101 +88,150 @@ String Comparisons $<STREQUAL:$<UPPER_CASE:${foo}>,"BAR"> # "1" if ${foo} is any of "BAR", "Bar", "bar", ... -``$<EQUAL:value1,value2>`` +.. genex:: $<EQUAL:value1,value2> + ``1`` if ``value1`` and ``value2`` are numerically equal, else ``0``. -``$<IN_LIST:string,list>`` + +.. genex:: $<IN_LIST:string,list> + ``1`` if ``string`` is member of the semicolon-separated ``list``, else ``0``. Uses case-sensitive comparisons. -``$<VERSION_LESS:v1,v2>`` + +.. genex:: $<VERSION_LESS:v1,v2> + ``1`` if ``v1`` is a version less than ``v2``, else ``0``. -``$<VERSION_GREATER:v1,v2>`` + +.. genex:: $<VERSION_GREATER:v1,v2> + ``1`` if ``v1`` is a version greater than ``v2``, else ``0``. -``$<VERSION_EQUAL:v1,v2>`` + +.. genex:: $<VERSION_EQUAL:v1,v2> + ``1`` if ``v1`` is the same version as ``v2``, else ``0``. -``$<VERSION_LESS_EQUAL:v1,v2>`` + +.. genex:: $<VERSION_LESS_EQUAL:v1,v2> + ``1`` if ``v1`` is a version less than or equal to ``v2``, else ``0``. -``$<VERSION_GREATER_EQUAL:v1,v2>`` - ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. +.. genex:: $<VERSION_GREATER_EQUAL:v1,v2> + + ``1`` if ``v1`` is a version greater than or equal to ``v2``, else ``0``. Variable Queries ---------------- -``$<TARGET_EXISTS:target>`` +.. genex:: $<TARGET_EXISTS:target> + ``1`` if ``target`` exists, else ``0``. -``$<CONFIG:cfgs>`` + +.. genex:: $<CONFIG:cfgs> + ``1`` if config is any one of the entries in ``cfgs``, else ``0``. This is a case-insensitive comparison. The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by this expression when it is evaluated on a property on an :prop_tgt:`IMPORTED` target. -``$<PLATFORM_ID:platform_ids>`` + +.. genex:: $<PLATFORM_ID:platform_ids> + where ``platform_ids`` is a comma-separated list. ``1`` if the CMake's platform id matches any one of the entries in ``platform_ids``, otherwise ``0``. See also the :variable:`CMAKE_SYSTEM_NAME` variable. -``$<C_COMPILER_ID:compiler_ids>`` + +.. genex:: $<C_COMPILER_ID:compiler_ids> + where ``compiler_ids`` is a comma-separated list. ``1`` if the CMake's compiler id of the C compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<CXX_COMPILER_ID:compiler_ids>`` + +.. genex:: $<CXX_COMPILER_ID:compiler_ids> + where ``compiler_ids`` is a comma-separated list. ``1`` if the CMake's compiler id of the CXX compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<CUDA_COMPILER_ID:compiler_ids>`` + +.. genex:: $<CUDA_COMPILER_ID:compiler_ids> + where ``compiler_ids`` is a comma-separated list. ``1`` if the CMake's compiler id of the CUDA compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<OBJC_COMPILER_ID:compiler_ids>`` + +.. genex:: $<OBJC_COMPILER_ID:compiler_ids> + where ``compiler_ids`` is a comma-separated list. ``1`` if the CMake's compiler id of the Objective-C compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<OBJCXX_COMPILER_ID:compiler_ids>`` + +.. genex:: $<OBJCXX_COMPILER_ID:compiler_ids> + where ``compiler_ids`` is a comma-separated list. ``1`` if the CMake's compiler id of the Objective-C++ compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<Fortran_COMPILER_ID:compiler_ids>`` + +.. genex:: $<Fortran_COMPILER_ID:compiler_ids> + where ``compiler_ids`` is a comma-separated list. ``1`` if the CMake's compiler id of the Fortran compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<ISPC_COMPILER_ID:compiler_ids>`` + +.. genex:: $<ISPC_COMPILER_ID:compiler_ids> + where ``compiler_ids`` is a comma-separated list. ``1`` if the CMake's compiler id of the ISPC compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<C_COMPILER_VERSION:version>`` + +.. genex:: $<C_COMPILER_VERSION:version> + ``1`` if the version of the C compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<CXX_COMPILER_VERSION:version>`` + +.. genex:: $<CXX_COMPILER_VERSION:version> + ``1`` if the version of the CXX compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<CUDA_COMPILER_VERSION:version>`` + +.. genex:: $<CUDA_COMPILER_VERSION:version> + ``1`` if the version of the CXX compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<OBJC_COMPILER_VERSION:version>`` + +.. genex:: $<OBJC_COMPILER_VERSION:version> + ``1`` if the version of the OBJC compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<OBJCXX_COMPILER_VERSION:version>`` + +.. genex:: $<OBJCXX_COMPILER_VERSION:version> + ``1`` if the version of the OBJCXX compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<Fortran_COMPILER_VERSION:version>`` + +.. genex:: $<Fortran_COMPILER_VERSION:version> + ``1`` if the version of the Fortran compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<ISPC_COMPILER_VERSION:version>`` + +.. genex:: $<ISPC_COMPILER_VERSION:version> + ``1`` if the version of the ISPC compiler matches ``version``, otherwise ``0``. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<TARGET_POLICY:policy>`` + +.. genex:: $<TARGET_POLICY:policy> + ``1`` if the ``policy`` was NEW when the 'head' target was created, else ``0``. If the ``policy`` was not set, the warning message for the policy will be emitted. This generator expression only works for a subset of policies. -``$<COMPILE_FEATURES:features>`` + +.. genex:: $<COMPILE_FEATURES:features> + where ``features`` is a comma-spearated list. Evaluates to ``1`` if all of the ``features`` are available for the 'head' target, and ``0`` otherwise. If this expression is used while evaluating @@ -189,7 +243,8 @@ Variable Queries .. _`Boolean COMPILE_LANGUAGE Generator Expression`: -``$<COMPILE_LANG_AND_ID:language,compiler_ids>`` +.. genex:: $<COMPILE_LANG_AND_ID:language,compiler_ids> + ``1`` when the language used for compilation unit matches ``language`` and the CMake's compiler id of the language compiler matches any one of the entries in ``compiler_ids``, otherwise ``0``. This expression is a short form @@ -225,7 +280,8 @@ Variable Queries $<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:Clang>>:COMPILING_C_WITH_CLANG> ) -``$<COMPILE_LANGUAGE:languages>`` +.. genex:: $<COMPILE_LANGUAGE:languages> + ``1`` when the language used for compilation unit matches any of the entries in ``languages``, otherwise ``0``. This expression may be used to specify compile options, compile definitions, and include directories for source files of a @@ -270,7 +326,8 @@ Variable Queries .. _`Boolean LINK_LANGUAGE Generator Expression`: -``$<LINK_LANG_AND_ID:language,compiler_ids>`` +.. genex:: $<LINK_LANG_AND_ID:language,compiler_ids> + ``1`` when the language used for link step matches ``language`` and the CMake's compiler id of the language linker matches any one of the entries in ``compiler_ids``, otherwise ``0``. This expression is a short form for the @@ -309,7 +366,8 @@ Variable Queries ``$<LINK_LANGUAGE:language>`` for constraints about the usage of this generator expression. -``$<LINK_LANGUAGE:languages>`` +.. genex:: $<LINK_LANGUAGE:languages> + ``1`` when the language used for link step matches any of the entries in ``languages``, otherwise ``0``. This expression may be used to specify link libraries, link options, link directories and link dependencies of a @@ -371,14 +429,16 @@ Variable Queries evaluation will give ``C`` as link language, so the second pass will correctly add target ``libother`` as link dependency. -``$<DEVICE_LINK:list>`` +.. genex:: $<DEVICE_LINK:list> + Returns the list if it is the device link step, an empty list otherwise. The device link step is controlled by :prop_tgt:`CUDA_SEPARABLE_COMPILATION` and :prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties and policy :policy:`CMP0105`. This expression can only be used to specify link options. -``$<HOST_LINK:list>`` +.. genex:: $<HOST_LINK:list> + Returns the list if it is the normal link step, an empty list otherwise. This expression is mainly useful when a device link step is also involved (see ``$<DEVICE_LINK:list>`` generator expression). This expression can only @@ -434,11 +494,16 @@ Escaped Characters String literals to escape the special meaning a character would otherwise have: -``$<ANGLE-R>`` +.. genex:: $<ANGLE-R> + A literal ``>``. Used for example to compare strings that contain a ``>``. -``$<COMMA>`` + +.. genex:: $<COMMA> + A literal ``,``. Used for example to compare strings which contain a ``,``. -``$<SEMICOLON>`` + +.. genex:: $<SEMICOLON> + A literal ``;``. Used to prevent list expansion on an argument with ``;``. .. _`Conditional Generator Expressions`: @@ -449,11 +514,13 @@ Conditional Expressions Conditional generator expressions depend on a boolean condition that must be ``0`` or ``1``. -``$<condition:true_string>`` +.. genex:: $<condition:true_string> + Evaluates to ``true_string`` if ``condition`` is ``1``. Otherwise evaluates to the empty string. -``$<IF:condition,true_string,false_string>`` +.. genex:: $<IF:condition,true_string,false_string> + Evaluates to ``true_string`` if ``condition`` is ``1``. Otherwise evaluates to ``false_string``. @@ -472,22 +539,34 @@ otherwise expands to the empty string. String Transformations ---------------------- -``$<JOIN:list,string>`` +.. genex:: $<JOIN:list,string> + Joins the list with the content of ``string``. -``$<REMOVE_DUPLICATES:list>`` + +.. genex:: $<REMOVE_DUPLICATES:list> + Removes duplicated items in the given ``list``. -``$<FILTER:list,INCLUDE|EXCLUDE,regex>`` + +.. genex:: $<FILTER:list,INCLUDE|EXCLUDE,regex> + Includes or removes items from ``list`` that match the regular expression ``regex``. -``$<LOWER_CASE:string>`` + +.. genex:: $<LOWER_CASE:string> + Content of ``string`` converted to lower case. -``$<UPPER_CASE:string>`` + +.. genex:: $<UPPER_CASE:string> + Content of ``string`` converted to upper case. -``$<GENEX_EVAL:expr>`` +.. genex:: $<GENEX_EVAL:expr> + Content of ``expr`` evaluated as a generator expression in the current context. This enables consumption of generator expressions whose evaluation results itself in generator expressions. -``$<TARGET_GENEX_EVAL:tgt,expr>`` + +.. genex:: $<TARGET_GENEX_EVAL:tgt,expr> + Content of ``expr`` evaluated as a generator expression in the context of ``tgt`` target. This enables consumption of custom target properties that themselves contain generator expressions. @@ -526,62 +605,99 @@ String Transformations Variable Queries ---------------- -``$<CONFIG>`` +.. genex:: $<CONFIG> + Configuration name. -``$<CONFIGURATION>`` + +.. genex:: $<CONFIGURATION> + Configuration name. Deprecated since CMake 3.0. Use ``CONFIG`` instead. -``$<PLATFORM_ID>`` + +.. genex:: $<PLATFORM_ID> + The current system's CMake platform id. See also the :variable:`CMAKE_SYSTEM_NAME` variable. -``$<C_COMPILER_ID>`` + +.. genex:: $<C_COMPILER_ID> + The CMake's compiler id of the C compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<CXX_COMPILER_ID>`` + +.. genex:: $<CXX_COMPILER_ID> + The CMake's compiler id of the CXX compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<CUDA_COMPILER_ID>`` + +.. genex:: $<CUDA_COMPILER_ID> + The CMake's compiler id of the CUDA compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<OBJC_COMPILER_ID>`` + +.. genex:: $<OBJC_COMPILER_ID> + The CMake's compiler id of the OBJC compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<OBJCXX_COMPILER_ID>`` + +.. genex:: $<OBJCXX_COMPILER_ID> + The CMake's compiler id of the OBJCXX compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<Fortran_COMPILER_ID>`` + +.. genex:: $<Fortran_COMPILER_ID> + The CMake's compiler id of the Fortran compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<ISPC_COMPILER_ID>`` + +.. genex:: $<ISPC_COMPILER_ID> + The CMake's compiler id of the ISPC compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable. -``$<C_COMPILER_VERSION>`` + +.. genex:: $<C_COMPILER_VERSION> + The version of the C compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<CXX_COMPILER_VERSION>`` + +.. genex:: $<CXX_COMPILER_VERSION> + The version of the CXX compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<CUDA_COMPILER_VERSION>`` + +.. genex:: $<CUDA_COMPILER_VERSION> + The version of the CUDA compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<OBJC_COMPILER_VERSION>`` + +.. genex:: $<OBJC_COMPILER_VERSION> + The version of the OBJC compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<OBJCXX_COMPILER_VERSION>`` + +.. genex:: $<OBJCXX_COMPILER_VERSION> + The version of the OBJCXX compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<Fortran_COMPILER_VERSION>`` + +.. genex:: $<Fortran_COMPILER_VERSION> + The version of the Fortran compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<ISPC_COMPILER_VERSION>`` + +.. genex:: $<ISPC_COMPILER_VERSION> + The version of the ISPC compiler used. See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable. -``$<COMPILE_LANGUAGE>`` + +.. genex:: $<COMPILE_LANGUAGE> + The compile language of source files when evaluating compile options. See :ref:`the related boolean expression <Boolean COMPILE_LANGUAGE Generator Expression>` ``$<COMPILE_LANGUAGE:language>`` for notes about the portability of this generator expression. -``$<LINK_LANGUAGE>`` + +.. genex:: $<LINK_LANGUAGE> + The link language of target when evaluating link options. See :ref:`the related boolean expression <Boolean LINK_LANGUAGE Generator Expression>` ``$<LINK_LANGUAGE:language>`` @@ -608,14 +724,19 @@ In the following, "the ``tgt`` filename" means the name of the ``tgt`` binary file. This has to be distinguished from "the target name", which is just the string ``tgt``. -``$<TARGET_NAME_IF_EXISTS:tgt>`` +.. genex:: $<TARGET_NAME_IF_EXISTS:tgt> + The target name ``tgt`` if the target exists, an empty string otherwise. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_FILE:tgt>`` + +.. genex:: $<TARGET_FILE:tgt> + Full path to the ``tgt`` binary file. -``$<TARGET_FILE_BASE_NAME:tgt>`` + +.. genex:: $<TARGET_FILE_BASE_NAME:tgt> + Base name of ``tgt``, i.e. ``$<TARGET_FILE_NAME:tgt>`` without prefix and suffix. For example, if the ``tgt`` filename is ``libbase.so``, the base name is ``base``. @@ -632,36 +753,48 @@ which is just the string ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_FILE_PREFIX:tgt>`` + +.. genex:: $<TARGET_FILE_PREFIX:tgt> + Prefix of the ``tgt`` filename (such as ``lib``). See also the :prop_tgt:`PREFIX` target property. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_FILE_SUFFIX:tgt>`` + +.. genex:: $<TARGET_FILE_SUFFIX:tgt> + Suffix of the ``tgt`` filename (extension such as ``.so`` or ``.exe``). See also the :prop_tgt:`SUFFIX` target property. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_FILE_NAME:tgt>`` + +.. genex:: $<TARGET_FILE_NAME:tgt> + The ``tgt`` filename. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_FILE_DIR:tgt>`` + +.. genex:: $<TARGET_FILE_DIR:tgt> + Directory of the ``tgt`` binary file. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_LINKER_FILE:tgt>`` + +.. genex:: $<TARGET_LINKER_FILE:tgt> + File used when linking to the ``tgt`` target. This will usually be the library that ``tgt`` represents (``.a``, ``.lib``, ``.so``), but for a shared library on DLL platforms, it would be the ``.lib`` import library associated with the DLL. -``$<TARGET_LINKER_FILE_BASE_NAME:tgt>`` + +.. genex:: $<TARGET_LINKER_FILE_BASE_NAME:tgt> + Base name of file used to link the target ``tgt``, i.e. ``$<TARGET_LINKER_FILE_NAME:tgt>`` without prefix and suffix. For example, if target file name is ``libbase.a``, the base name is ``base``. @@ -677,7 +810,9 @@ which is just the string ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_LINKER_FILE_PREFIX:tgt>`` + +.. genex:: $<TARGET_LINKER_FILE_PREFIX:tgt> + Prefix of file used to link target ``tgt``. See also the :prop_tgt:`PREFIX` and :prop_tgt:`IMPORT_PREFIX` target @@ -685,7 +820,9 @@ which is just the string ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_LINKER_FILE_SUFFIX:tgt>`` + +.. genex:: $<TARGET_LINKER_FILE_SUFFIX:tgt> + Suffix of file used to link where ``tgt`` is the name of a target. The suffix corresponds to the file extension (such as ".so" or ".lib"). @@ -695,36 +832,49 @@ which is just the string ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_LINKER_FILE_NAME:tgt>`` + +.. genex:: $<TARGET_LINKER_FILE_NAME:tgt> + Name of file used to link target ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_LINKER_FILE_DIR:tgt>`` + +.. genex:: $<TARGET_LINKER_FILE_DIR:tgt> + Directory of file used to link target ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_SONAME_FILE:tgt>`` + +.. genex:: $<TARGET_SONAME_FILE:tgt> + File with soname (``.so.3``) where ``tgt`` is the name of a target. -``$<TARGET_SONAME_FILE_NAME:tgt>`` +.. genex:: $<TARGET_SONAME_FILE_NAME:tgt> + Name of file with soname (``.so.3``). Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_SONAME_FILE_DIR:tgt>`` + +.. genex:: $<TARGET_SONAME_FILE_DIR:tgt> + Directory of with soname (``.so.3``). Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_PDB_FILE:tgt>`` + +.. genex:: $<TARGET_PDB_FILE:tgt> + Full path to the linker generated program database file (.pdb) where ``tgt`` is the name of a target. See also the :prop_tgt:`PDB_NAME` and :prop_tgt:`PDB_OUTPUT_DIRECTORY` target properties and their configuration specific variants :prop_tgt:`PDB_NAME_<CONFIG>` and :prop_tgt:`PDB_OUTPUT_DIRECTORY_<CONFIG>`. -``$<TARGET_PDB_FILE_BASE_NAME:tgt>`` + +.. genex:: $<TARGET_PDB_FILE_BASE_NAME:tgt> + Base name of the linker generated program database file (.pdb) where ``tgt`` is the name of a target. @@ -740,23 +890,31 @@ which is just the string ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_PDB_FILE_NAME:tgt>`` + +.. genex:: $<TARGET_PDB_FILE_NAME:tgt> + Name of the linker generated program database file (.pdb). Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_PDB_FILE_DIR:tgt>`` + +.. genex:: $<TARGET_PDB_FILE_DIR:tgt> + Directory of the linker generated program database file (.pdb). Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_BUNDLE_DIR:tgt>`` + +.. genex:: $<TARGET_BUNDLE_DIR:tgt> + Full path to the bundle directory (``my.app``, ``my.framework``, or ``my.bundle``) where ``tgt`` is the name of a target. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_BUNDLE_CONTENT_DIR:tgt>`` + +.. genex:: $<TARGET_BUNDLE_CONTENT_DIR:tgt> + Full path to the bundle content directory where ``tgt`` is the name of a target. For the macOS SDK it leads to ``my.app/Contents``, ``my.framework``, or ``my.bundle/Contents``. For all other SDKs (e.g. iOS) it leads to @@ -765,17 +923,23 @@ which is just the string ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on (see policy :policy:`CMP0112`). -``$<TARGET_PROPERTY:tgt,prop>`` + +.. genex:: $<TARGET_PROPERTY:tgt,prop> + Value of the property ``prop`` on the target ``tgt``. Note that ``tgt`` is not added as a dependency of the target this expression is evaluated on. -``$<TARGET_PROPERTY:prop>`` + +.. genex:: $<TARGET_PROPERTY:prop> + Value of the property ``prop`` on the target for which the expression is being evaluated. Note that for generator expressions in :ref:`Target Usage Requirements` this is the consuming target rather than the target specifying the requirement. -``$<INSTALL_PREFIX>`` + +.. genex:: $<INSTALL_PREFIX> + Content of the install prefix when the target is exported via :command:`install(EXPORT)`, or when evaluated in :prop_tgt:`INSTALL_NAME_DIR`, and empty otherwise. @@ -783,30 +947,43 @@ which is just the string ``tgt``. Output-Related Expressions -------------------------- -``$<TARGET_NAME:...>`` +.. genex:: $<TARGET_NAME:...> + Marks ``...`` as being the name of a target. This is required if exporting targets to multiple dependent export sets. The ``...`` must be a literal name of a target- it may not contain generator expressions. -``$<LINK_ONLY:...>`` + +.. genex:: $<LINK_ONLY:...> + Content of ``...`` except when evaluated in a link interface while propagating :ref:`Target Usage Requirements`, in which case it is the empty string. Intended for use only in an :prop_tgt:`INTERFACE_LINK_LIBRARIES` target property, perhaps via the :command:`target_link_libraries` command, to specify private link dependencies without other usage requirements. -``$<INSTALL_INTERFACE:...>`` + +.. genex:: $<INSTALL_INTERFACE:...> + Content of ``...`` when the property is exported using :command:`install(EXPORT)`, and empty otherwise. -``$<BUILD_INTERFACE:...>`` + +.. genex:: $<BUILD_INTERFACE:...> + Content of ``...`` when the property is exported using :command:`export`, or when the target is used by another target in the same buildsystem. Expands to the empty string otherwise. -``$<MAKE_C_IDENTIFIER:...>`` + +.. genex:: $<MAKE_C_IDENTIFIER:...> + Content of ``...`` converted to a C identifier. The conversion follows the same behavior as :command:`string(MAKE_C_IDENTIFIER)`. -``$<TARGET_OBJECTS:objLib>`` + +.. genex:: $<TARGET_OBJECTS:objLib> + List of objects resulting from build of ``objLib``. -``$<SHELL_PATH:...>`` + +.. genex:: $<SHELL_PATH:...> + Content of ``...`` converted to shell path style. For example, slashes are converted to backslashes in Windows shells and drive letters are converted to posix paths in MSYS shells. The ``...`` must be an absolute path. @@ -816,7 +993,8 @@ Output-Related Expressions ``;`` on Windows). Be sure to enclose the argument containing this genex in double quotes in CMake source code so that ``;`` does not split arguments. -``$<OUTPUT_CONFIG:...>`` +.. genex:: $<OUTPUT_CONFIG:...> + .. versionadded:: 3.20 Only valid in :command:`add_custom_command` and :command:`add_custom_target` @@ -825,7 +1003,8 @@ Output-Related Expressions in ``...`` are evaluated using the custom command's "output config". With other generators, the content of ``...`` is evaluated normally. -``$<COMMAND_CONFIG:...>`` +.. genex:: $<COMMAND_CONFIG:...> + .. versionadded:: 3.20 Only valid in :command:`add_custom_command` and :command:`add_custom_target` diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index 6f137c4..3ab0a62 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -29,337 +29,344 @@ is using Git, ``CMakePresets.json`` may be tracked, and Format ====== - The files are a JSON document with an object as the root: +The files are a JSON document with an object as the root: - .. literalinclude:: presets/example.json - :language: json +.. literalinclude:: presets/example.json + :language: json - The root object recognizes the following fields: +The root object recognizes the following fields: - ``version`` +``version`` - A required integer representing the version of the JSON schema. Currently, - the only supported version is 1. + A required integer representing the version of the JSON schema. Currently, + the only supported version is 1. - ``cmakeMinimumRequired`` +``cmakeMinimumRequired`` - An optional object representing the minimum version of CMake needed to - build this project. This object consists of the following fields: + An optional object representing the minimum version of CMake needed to + build this project. This object consists of the following fields: - ``major`` + ``major`` - An optional integer representing the major version. + An optional integer representing the major version. - ``minor`` + ``minor`` - An optional integer representing the minor version. + An optional integer representing the minor version. - ``patch`` + ``patch`` - An optional integer representing the patch version. + An optional integer representing the patch version. - ``vendor`` +``vendor`` - An optional map containing vendor-specific information. CMake does not - interpret the contents of this field except to verify that it is a map if - it does exist. However, the keys should be a vendor-specific domain name - followed by a ``/``-separated path. For example, the Example IDE 1.0 could - use ``example.com/ExampleIDE/1.0``. The value of each field can be anything - desired by the vendor, though will typically be a map. + An optional map containing vendor-specific information. CMake does not + interpret the contents of this field except to verify that it is a map if + it does exist. However, the keys should be a vendor-specific domain name + followed by a ``/``-separated path. For example, the Example IDE 1.0 could + use ``example.com/ExampleIDE/1.0``. The value of each field can be anything + desired by the vendor, though will typically be a map. - ``configurePresets`` +``configurePresets`` - An optional array of configure preset objects. Each preset may contain the - following fields: + An optional array of `Configure Preset`_ objects. - ``name`` +Configure Preset +^^^^^^^^^^^^^^^^ - A required string representing the machine-friendly name of the preset. - This identifier is used in the ``--preset`` argument. There must not be - two presets in the union of ``CMakePresets.json`` and - ``CMakeUserPresets.json`` in the same directory with the same name. +Each entry of the ``configurePresets`` array is a JSON object +that may contain the following fields: - ``hidden`` +``name`` - An optional boolean specifying whether or not a preset should be hidden. - If a preset is hidden, it cannot be used in the ``--preset=`` argument, - will not show up in the :manual:`CMake GUI <cmake-gui(1)>`, and does not - have to have a valid ``generator`` or ``binaryDir``, even from - inheritance. ``hidden`` presets are intended to be used as a base for - other presets to inherit via the ``inherits`` field. + A required string representing the machine-friendly name of the preset. + This identifier is used in the ``--preset`` argument. There must not be + two presets in the union of ``CMakePresets.json`` and + ``CMakeUserPresets.json`` in the same directory with the same name. - ``inherits`` +``hidden`` - An optional array of strings representing the names of presets to inherit - from. The preset will inherit all of the fields from the ``inherits`` - presets by default (except ``name``, ``hidden``, ``inherits``, - ``description``, and ``displayName``), but can override them as - desired. If multiple ``inherits`` presets provide conflicting values for - the same field, the earlier preset in the ``inherits`` list will be - preferred. Presets in ``CMakePresets.json`` may not inherit from presets - in ``CMakeUserPresets.json``. + An optional boolean specifying whether or not a preset should be hidden. + If a preset is hidden, it cannot be used in the ``--preset=`` argument, + will not show up in the :manual:`CMake GUI <cmake-gui(1)>`, and does not + have to have a valid ``generator`` or ``binaryDir``, even from + inheritance. ``hidden`` presets are intended to be used as a base for + other presets to inherit via the ``inherits`` field. - This field can also be a string, which is equivalent to an array - containing one string. +``inherits`` - ``vendor`` + An optional array of strings representing the names of presets to inherit + from. The preset will inherit all of the fields from the ``inherits`` + presets by default (except ``name``, ``hidden``, ``inherits``, + ``description``, and ``displayName``), but can override them as + desired. If multiple ``inherits`` presets provide conflicting values for + the same field, the earlier preset in the ``inherits`` list will be + preferred. Presets in ``CMakePresets.json`` may not inherit from presets + in ``CMakeUserPresets.json``. - An optional map containing vendor-specific information. CMake does not - interpret the contents of this field except to verify that it is a map - if it does exist. However, it should follow the same conventions as the - root-level ``vendor`` field. If vendors use their own per-preset - ``vendor`` field, they should implement inheritance in a sensible manner - when appropriate. + This field can also be a string, which is equivalent to an array + containing one string. - ``displayName`` +``vendor`` - An optional string with a human-friendly name of the preset. + An optional map containing vendor-specific information. CMake does not + interpret the contents of this field except to verify that it is a map + if it does exist. However, it should follow the same conventions as the + root-level ``vendor`` field. If vendors use their own per-preset + ``vendor`` field, they should implement inheritance in a sensible manner + when appropriate. - ``description`` +``displayName`` - An optional string with a human-friendly description of the preset. + An optional string with a human-friendly name of the preset. - ``generator`` +``description`` - An optional string representing the generator to use for the preset. If - ``generator`` is not specified, it must be inherited from the - ``inherits`` preset (unless this preset is ``hidden``). + An optional string with a human-friendly description of the preset. - Note that for Visual Studio generators, unlike in the command line ``-G`` - argument, you cannot include the platform name in the generator name. Use - the ``architecture`` field instead. +``generator`` - ``architecture`` - ``toolset`` + An optional string representing the generator to use for the preset. If + ``generator`` is not specified, it must be inherited from the + ``inherits`` preset (unless this preset is ``hidden``). - Optional fields representing the platform and toolset, respectively, for - generators that support them. Each may be either a string or an object - with the following fields: + Note that for Visual Studio generators, unlike in the command line ``-G`` + argument, you cannot include the platform name in the generator name. Use + the ``architecture`` field instead. - ``value`` +``architecture``, ``toolset`` - An optional string representing the value. + Optional fields representing the platform and toolset, respectively, for + generators that support them. Each may be either a string or an object + with the following fields: - ``strategy`` + ``value`` - An optional string telling CMake how to handle the ``architecture`` or - ``toolset`` field. Valid values are: + An optional string representing the value. - ``"set"`` + ``strategy`` - Set the respective value. This will result in an error for generators - that do not support the respective field. + An optional string telling CMake how to handle the ``architecture`` or + ``toolset`` field. Valid values are: - ``"external"`` + ``"set"`` - Do not set the value, even if the generator supports it. This is - useful if, for example, a preset uses the Ninja generator, and an IDE - knows how to set up the Visual C++ environment from the - ``architecture`` and ``toolset`` fields. In that case, CMake will - ignore the field, but the IDE can use them to set up the environment - before invoking CMake. + Set the respective value. This will result in an error for generators + that do not support the respective field. - ``binaryDir`` + ``"external"`` - An optional string representing the path to the output binary directory. - This field supports macro expansion. If a relative path is specified, it - is calculated relative to the source directory. If ``binaryDir`` is not - specified, it must be inherited from the ``inherits`` preset (unless this - preset is ``hidden``). + Do not set the value, even if the generator supports it. This is + useful if, for example, a preset uses the Ninja generator, and an IDE + knows how to set up the Visual C++ environment from the + ``architecture`` and ``toolset`` fields. In that case, CMake will + ignore the field, but the IDE can use them to set up the environment + before invoking CMake. - ``cmakeExecutable`` +``binaryDir`` - An optional string representing the path to the CMake executable to use - for this preset. This is reserved for use by IDEs, and is not used by - CMake itself. IDEs that use this field should expand any macros in it. + An optional string representing the path to the output binary directory. + This field supports `macro expansion`_. If a relative path is specified, + it is calculated relative to the source directory. If ``binaryDir`` is not + specified, it must be inherited from the ``inherits`` preset (unless this + preset is ``hidden``). - ``cacheVariables`` +``cmakeExecutable`` - An optional map of cache variables. The key is the variable name (which - may not be an empty string), and the value is either ``null``, a boolean - (which is equivalent to a value of ``"TRUE"`` or ``"FALSE"`` and a type - of ``BOOL``), a string representing the value of the variable (which - supports macro expansion), or an object with the following fields: + An optional string representing the path to the CMake executable to use + for this preset. This is reserved for use by IDEs, and is not used by + CMake itself. IDEs that use this field should expand any macros in it. - ``type`` +``cacheVariables`` - An optional string representing the type of the variable. + An optional map of cache variables. The key is the variable name (which + may not be an empty string), and the value is either ``null``, a boolean + (which is equivalent to a value of ``"TRUE"`` or ``"FALSE"`` and a type + of ``BOOL``), a string representing the value of the variable (which + supports `macro expansion`_), or an object with the following fields: - ``value`` + ``type`` - A required string or boolean representing the value of the variable. - A boolean is equivalent to ``"TRUE"`` or ``"FALSE"``. This field - supports macro expansion. + An optional string representing the type of the variable. - Cache variables are inherited through the ``inherits`` field, and the - preset's variables will be the union of its own ``cacheVariables`` and - the ``cacheVariables`` from all its parents. If multiple presets in this - union define the same variable, the standard rules of ``inherits`` are - applied. Setting a variable to ``null`` causes it to not be set, even if - a value was inherited from another preset. + ``value`` - ``environment`` + A required string or boolean representing the value of the variable. + A boolean is equivalent to ``"TRUE"`` or ``"FALSE"``. This field + supports `macro expansion`_. - An optional map of environment variables. The key is the variable name - (which may not be an empty string), and the value is either ``null`` or - a string representing the value of the variable. Each variable is set - regardless of whether or not a value was given to it by the process's - environment. This field supports macro expansion, and environment - variables in this map may reference each other, and may be listed in any - order, as long as such references do not cause a cycle (for example, - if ``ENV_1`` is ``$env{ENV_2}``, ``ENV_2`` may not be ``$env{ENV_1}``.) + Cache variables are inherited through the ``inherits`` field, and the + preset's variables will be the union of its own ``cacheVariables`` and + the ``cacheVariables`` from all its parents. If multiple presets in this + union define the same variable, the standard rules of ``inherits`` are + applied. Setting a variable to ``null`` causes it to not be set, even if + a value was inherited from another preset. - Environment variables are inherited through the ``inherits`` field, and - the preset's environment will be the union of its own ``environment`` and - the ``environment`` from all its parents. If multiple presets in this - union define the same variable, the standard rules of ``inherits`` are - applied. Setting a variable to ``null`` causes it to not be set, even if - a value was inherited from another preset. +``environment`` - ``warnings`` + An optional map of environment variables. The key is the variable name + (which may not be an empty string), and the value is either ``null`` or + a string representing the value of the variable. Each variable is set + regardless of whether or not a value was given to it by the process's + environment. This field supports `macro expansion`_, and environment + variables in this map may reference each other, and may be listed in any + order, as long as such references do not cause a cycle (for example, + if ``ENV_1`` is ``$env{ENV_2}``, ``ENV_2`` may not be ``$env{ENV_1}``.) - An optional object specifying the warnings to enable. The object may - contain the following fields: + Environment variables are inherited through the ``inherits`` field, and + the preset's environment will be the union of its own ``environment`` and + the ``environment`` from all its parents. If multiple presets in this + union define the same variable, the standard rules of ``inherits`` are + applied. Setting a variable to ``null`` causes it to not be set, even if + a value was inherited from another preset. - ``dev`` +``warnings`` - An optional boolean. Equivalent to passing ``-Wdev`` or ``-Wno-dev`` - on the command line. This may not be set to ``false`` if ``errors.dev`` - is set to ``true``. + An optional object specifying the warnings to enable. The object may + contain the following fields: - ``deprecated`` + ``dev`` - An optional boolean. Equivalent to passing ``-Wdeprecated`` or - ``-Wno-deprecated`` on the command line. This may not be set to - ``false`` if ``errors.deprecated`` is set to ``true``. + An optional boolean. Equivalent to passing ``-Wdev`` or ``-Wno-dev`` + on the command line. This may not be set to ``false`` if ``errors.dev`` + is set to ``true``. - ``uninitialized`` + ``deprecated`` - An optional boolean. Setting this to ``true`` is equivalent to passing - ``--warn-uninitialized`` on the command line. + An optional boolean. Equivalent to passing ``-Wdeprecated`` or + ``-Wno-deprecated`` on the command line. This may not be set to + ``false`` if ``errors.deprecated`` is set to ``true``. - ``unusedCli`` + ``uninitialized`` - An optional boolean. Setting this to ``false`` is equivalent to passing - ``--no-warn-unused-cli`` on the command line. + An optional boolean. Setting this to ``true`` is equivalent to passing + ``--warn-uninitialized`` on the command line. - ``systemVars`` + ``unusedCli`` - An optional boolean. Setting this to ``true`` is equivalent to passing - ``--check-system-vars`` on the command line. + An optional boolean. Setting this to ``false`` is equivalent to passing + ``--no-warn-unused-cli`` on the command line. - ``errors`` + ``systemVars`` - An optional object specifying the errors to enable. The object may - contain the following fields: + An optional boolean. Setting this to ``true`` is equivalent to passing + ``--check-system-vars`` on the command line. - ``dev`` +``errors`` - An optional boolean. Equivalent to passing ``-Werror=dev`` or - ``-Wno-error=dev`` on the command line. This may not be set to ``true`` - if ``warnings.dev`` is set to ``false``. + An optional object specifying the errors to enable. The object may + contain the following fields: - ``deprecated`` + ``dev`` - An optional boolean. Equivalent to passing ``-Werror=deprecated`` or - ``-Wno-error=deprecated`` on the command line. This may not be set to - ``true`` if ``warnings.deprecated`` is set to ``false``. + An optional boolean. Equivalent to passing ``-Werror=dev`` or + ``-Wno-error=dev`` on the command line. This may not be set to ``true`` + if ``warnings.dev`` is set to ``false``. - ``debug`` + ``deprecated`` - An optional object specifying debug options. The object may contain the - following fields: + An optional boolean. Equivalent to passing ``-Werror=deprecated`` or + ``-Wno-error=deprecated`` on the command line. This may not be set to + ``true`` if ``warnings.deprecated`` is set to ``false``. - ``output`` +``debug`` - An optional boolean. Setting this to ``true`` is equivalent to passing - ``--debug-output`` on the command line. + An optional object specifying debug options. The object may contain the + following fields: - ``tryCompile`` + ``output`` - An optional boolean. Setting this to ``true`` is equivalent to passing - ``--debug-trycompile`` on the command line. + An optional boolean. Setting this to ``true`` is equivalent to passing + ``--debug-output`` on the command line. - ``find`` + ``tryCompile`` - An optional boolean. Setting this to ``true`` is equivalent to passing - ``--debug-find`` on the command line. + An optional boolean. Setting this to ``true`` is equivalent to passing + ``--debug-trycompile`` on the command line. - As mentioned above, some fields support macro expansion. Macros are - recognized in the form ``$<macro-namespace>{<macro-name>}``. All macros are - evaluated in the context of the preset being used, even if the macro is in a - field that was inherited from another preset. For example, if the ``Base`` - preset sets variable ``PRESET_NAME`` to ``${presetName}``, and the - ``Derived`` preset inherits from ``Base``, ``PRESET_NAME`` will be set to - ``Derived``. + ``find`` - It is an error to not put a closing brace at the end of a macro name. For - example, ``${sourceDir`` is invalid. A dollar sign (``$``) followed by - anything other than a left curly brace (``{``) with a possible namespace is - interpreted as a literal dollar sign. + An optional boolean. Setting this to ``true`` is equivalent to passing + ``--debug-find`` on the command line. - Recognized macros include: +Macro Expansion +^^^^^^^^^^^^^^^ - ``${sourceDir}`` +As mentioned above, some fields support macro expansion. Macros are +recognized in the form ``$<macro-namespace>{<macro-name>}``. All macros are +evaluated in the context of the preset being used, even if the macro is in a +field that was inherited from another preset. For example, if the ``Base`` +preset sets variable ``PRESET_NAME`` to ``${presetName}``, and the +``Derived`` preset inherits from ``Base``, ``PRESET_NAME`` will be set to +``Derived``. - Path to the project source directory. +It is an error to not put a closing brace at the end of a macro name. For +example, ``${sourceDir`` is invalid. A dollar sign (``$``) followed by +anything other than a left curly brace (``{``) with a possible namespace is +interpreted as a literal dollar sign. - ``${sourceParentDir}`` +Recognized macros include: - Path to the project source directory's parent directory. +``${sourceDir}`` - ``${sourceDirName}`` + Path to the project source directory. - The last filename component of ``${sourceDir}``. For example, if - ``${sourceDir}`` is ``/path/to/source``, this would be ``source``. +``${sourceParentDir}`` - ``${presetName}`` + Path to the project source directory's parent directory. - Name specified in the preset's ``name`` field. +``${sourceDirName}`` - ``${generator}`` + The last filename component of ``${sourceDir}``. For example, if + ``${sourceDir}`` is ``/path/to/source``, this would be ``source``. - Generator specified in the preset's ``generator`` field. +``${presetName}`` - ``${dollar}`` + Name specified in the preset's ``name`` field. - A literal dollar sign (``$``). +``${generator}`` - ``$env{<variable-name>}`` + Generator specified in the preset's ``generator`` field. - Environment variable with name ``<variable-name>``. The variable name may - not be an empty string. If the variable is defined in the ``environment`` - field, that value is used instead of the value from the parent environment. - If the environment variable is not defined, this evaluates as an empty - string. +``${dollar}`` - Note that while Windows environment variable names are case-insensitive, - variable names within a preset are still case-sensitive. This may lead to - unexpected results when using inconsistent casing. For best results, keep - the casing of environment variable names consistent. + A literal dollar sign (``$``). - ``$penv{<variable-name>}`` +``$env{<variable-name>}`` - Similar to ``$env{<variable-name>}``, except that the value only comes from - the parent environment, and never from the ``environment`` field. This - allows you to prepend or append values to existing environment variables. - For example, setting ``PATH`` to ``/path/to/ninja/bin:$penv{PATH}`` will - prepend ``/path/to/ninja/bin`` to the ``PATH`` environment variable. This - is needed because ``$env{<variable-name>}`` does not allow circular - references. + Environment variable with name ``<variable-name>``. The variable name may + not be an empty string. If the variable is defined in the ``environment`` + field, that value is used instead of the value from the parent environment. + If the environment variable is not defined, this evaluates as an empty + string. - ``$vendor{<macro-name>}`` + Note that while Windows environment variable names are case-insensitive, + variable names within a preset are still case-sensitive. This may lead to + unexpected results when using inconsistent casing. For best results, keep + the casing of environment variable names consistent. - An extension point for vendors to insert their own macros. CMake will not - be able to use presets which have a ``$vendor{<macro-name>}`` macro, and - effectively ignores such presets. However, it will still be able to use - other presets from the same file. +``$penv{<variable-name>}`` - CMake does not make any attempt to interpret ``$vendor{<macro-name>}`` - macros. However, to avoid name collisions, IDE vendors should prefix - ``<macro-name>`` with a very short (preferably <= 4 characters) vendor - identifier prefix, followed by a ``.``, followed by the macro name. For - example, the Example IDE could have ``$vendor{xide.ideInstallDir}``. + Similar to ``$env{<variable-name>}``, except that the value only comes from + the parent environment, and never from the ``environment`` field. This + allows you to prepend or append values to existing environment variables. + For example, setting ``PATH`` to ``/path/to/ninja/bin:$penv{PATH}`` will + prepend ``/path/to/ninja/bin`` to the ``PATH`` environment variable. This + is needed because ``$env{<variable-name>}`` does not allow circular + references. + +``$vendor{<macro-name>}`` + + An extension point for vendors to insert their own macros. CMake will not + be able to use presets which have a ``$vendor{<macro-name>}`` macro, and + effectively ignores such presets. However, it will still be able to use + other presets from the same file. + + CMake does not make any attempt to interpret ``$vendor{<macro-name>}`` + macros. However, to avoid name collisions, IDE vendors should prefix + ``<macro-name>`` with a very short (preferably <= 4 characters) vendor + identifier prefix, followed by a ``.``, followed by the macro name. For + example, the Example IDE could have ``$vendor{xide.ideInstallDir}``. Schema ====== diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index 5dbc1a4..af170da 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -196,6 +196,7 @@ Properties on Targets /prop_tgt/EXCLUDE_FROM_ALL /prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD /prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG + /prop_tgt/EXPORT_COMPILE_COMMANDS /prop_tgt/EXPORT_NAME /prop_tgt/EXPORT_PROPERTIES /prop_tgt/FOLDER diff --git a/Help/prop_tgt/EXPORT_COMPILE_COMMANDS.rst b/Help/prop_tgt/EXPORT_COMPILE_COMMANDS.rst new file mode 100644 index 0000000..0b1145c --- /dev/null +++ b/Help/prop_tgt/EXPORT_COMPILE_COMMANDS.rst @@ -0,0 +1,9 @@ +EXPORT_COMPILE_COMMANDS +----------------------- + +.. versionadded:: 3.20 + +Enable/Disable output of compile commands during generation for a target. + +This property is initialized by the value of the variable +:variable:`CMAKE_EXPORT_COMPILE_COMMANDS` if it is set when a target is created. diff --git a/Help/release/3.19.rst b/Help/release/3.19.rst index eb49c6f..d819e8c 100644 --- a/Help/release/3.19.rst +++ b/Help/release/3.19.rst @@ -390,3 +390,21 @@ Changes made since CMake 3.19.0 include the following. ------ * A precompiled Linux ``aarch64`` binary is now provided on ``cmake.org``. + +* Two precompiled macOS binaries are now provided on ``cmake.org``: + + * The naming pattern ``cmake-$ver-macos-universal`` is a universal + binary with ``x86_64`` and ``arm64`` architectures. It requires + macOS 10.13 or newer. + + * The naming pattern ``cmake-$ver-macos10.10-universal`` is a universal + binary with ``x86_64`` and ``arm64`` architectures. It requires + macOS 10.10 or newer. + +3.19.4 +------ + +* The :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` + variable introduced in 3.19.0 previously worked only with the + :generator:`Visual Studio 14 2015` generator. It has now been fixed to + work with :ref:`Visual Studio Generators` for later VS versions too. diff --git a/Help/release/dev/Java-export-native_headers-target.rst b/Help/release/dev/Java-export-native_headers-target.rst new file mode 100644 index 0000000..13b6dfb --- /dev/null +++ b/Help/release/dev/Java-export-native_headers-target.rst @@ -0,0 +1,6 @@ +Java-export-native_headers-target +--------------------------------- + +* ``add_jar()`` command, from :module:`UseJava` module, gains new capabilities + for ``GENERATE_NATIVE_HEADERS`` option. These capabilities facilitate the + exportation of the generated target. diff --git a/Help/release/dev/clang-win32-subsystem.rst b/Help/release/dev/clang-win32-subsystem.rst new file mode 100644 index 0000000..c970f53 --- /dev/null +++ b/Help/release/dev/clang-win32-subsystem.rst @@ -0,0 +1,4 @@ +clang-win32-subsystem +--------------------- + +* :prop_tgt:`WIN32_EXECUTABLE` now works on Windows with Clang. diff --git a/Help/release/dev/cuda-nvcc-ccache-symlink.rst b/Help/release/dev/cuda-nvcc-ccache-symlink.rst new file mode 100644 index 0000000..4d38047 --- /dev/null +++ b/Help/release/dev/cuda-nvcc-ccache-symlink.rst @@ -0,0 +1,9 @@ +cuda-nvcc-ccache-symlink +------------------------ + +* ``CUDA`` language support now works when ``nvcc`` is a symbolic link, + for example due to a ``ccache`` or ``colornvcc`` wrapper script. + +* The :module:`FindCUDAToolkit` module gained support for finding CUDA + toolkits when ``nvcc`` is a symbolic link, + for example due to a ``ccache`` or ``colornvcc`` wrapper script. diff --git a/Help/release/dev/export-compile-commands-per-target.rst b/Help/release/dev/export-compile-commands-per-target.rst new file mode 100644 index 0000000..7063547 --- /dev/null +++ b/Help/release/dev/export-compile-commands-per-target.rst @@ -0,0 +1,6 @@ +export-compile-commands-per-target +---------------------------------- + +* The :prop_tgt:`EXPORT_COMPILE_COMMANDS` target property was added + for the associated :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` variable + to allow for configuration of exporting compile commands per target. diff --git a/Help/release/dev/external-project-configure-handled-by-build.rst b/Help/release/dev/external-project-configure-handled-by-build.rst new file mode 100644 index 0000000..4a1fac8 --- /dev/null +++ b/Help/release/dev/external-project-configure-handled-by-build.rst @@ -0,0 +1,8 @@ +external-project-configure-handled-by-build +------------------------------------------- + +* The :module:`ExternalProject` function ``ExternalProject_Add`` learned a new + ``CONFIGURE_HANDLED_BY_BUILD`` option to have subsequent runs of the configure + step be triggered by the build step when an external project dependency + rebuilds instead of always rerunning the configure step when an external + project dependency rebuilds. diff --git a/Help/release/dev/fileapi-toolchains.rst b/Help/release/dev/fileapi-toolchains.rst new file mode 100644 index 0000000..1a096bf --- /dev/null +++ b/Help/release/dev/fileapi-toolchains.rst @@ -0,0 +1,5 @@ +fileapi-toolchains +------------------ + +* The :manual:`cmake-file-api(7)` gained a new "toolchains" object + kind that describes the compiler used for each enabled language. diff --git a/Help/release/dev/install-files-rename-genex.rst b/Help/release/dev/install-files-rename-genex.rst new file mode 100644 index 0000000..f735e24 --- /dev/null +++ b/Help/release/dev/install-files-rename-genex.rst @@ -0,0 +1,5 @@ +install-files-rename-genex +-------------------------- + +* The :command:`install(FILES)` command ``RENAME`` option learned to + support :manual:`generator expressions <cmake-generator-expressions(7)>`. diff --git a/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst index 7f7e679..d885516 100644 --- a/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst +++ b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst @@ -18,3 +18,18 @@ and compiler versions. This variable is used to initialize the :prop_tgt:`CUDA_ARCHITECTURES` property on all targets. See the target property for additional information. + +Examples +^^^^^^^^ + +.. code-block:: cmake + + cmake_minimum_required(VERSION) + + if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES) + set(CMAKE_CUDA_ARCHITECTURES 75) + endif() + + project(example LANGUAGES CUDA) + +``CMAKE_CUDA_ARCHITECTURES`` will default to ``75`` unless overridden by the user. diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst index 724f309..53a19dc 100644 --- a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst +++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst @@ -28,7 +28,8 @@ form. The format of the JSON file looks like: ] This is initialized by the :envvar:`CMAKE_EXPORT_COMPILE_COMMANDS` environment -variable. +variable, and initializes the :prop_tgt:`EXPORT_COMPILE_COMMANDS` target +property for all targets. .. note:: This option is implemented only by :ref:`Makefile Generators` diff --git a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM.rst b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM.rst index 591ea91..d9f136c 100644 --- a/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM.rst +++ b/Help/variable/CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM.rst @@ -3,7 +3,7 @@ CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM .. versionadded:: 3.19 -Override the :ref:`Windows 10 SDK Maximum Version for VS 2015`. +Override the :ref:`Windows 10 SDK Maximum Version for VS 2015` and beyond. The :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM` variable may be set to a false value (e.g. ``OFF``, ``FALSE``, or ``0``) or the SDK version diff --git a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst index 6cd51fa..b6fee2e 100644 --- a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst +++ b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst @@ -5,3 +5,8 @@ CTEST_MEMORYCHECK_SANITIZER_OPTIONS Specify the CTest ``MemoryCheckSanitizerOptions`` setting in a :manual:`ctest(1)` dashboard client script. + +CTest prepends correct sanitizer options ``*_OPTIONS`` +environment variable to executed command. CTests adds +its own ``log_path`` to sanitizer options, don't provide your +own ``log_path``. diff --git a/Help/variable/MSVC.rst b/Help/variable/MSVC.rst index ca8775c..a2dbc2e 100644 --- a/Help/variable/MSVC.rst +++ b/Help/variable/MSVC.rst @@ -1,8 +1,7 @@ MSVC ---- -Set to ``true`` when the compiler is some version of Microsoft Visual -C++ or another compiler simulating Visual C++. Any compiler defining -``_MSC_VER`` is considered simulating Visual C++. +Set to ``true`` when the compiler is some version of Microsoft Visual C++ +or another compiler simulating the Visual C++ ``cl`` command-line syntax. See also the :variable:`MSVC_VERSION` variable. diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 92ae2ab..45acfe7 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -44,7 +44,7 @@ if(CMAKE_COMPILER_IS_MINGW) set(MINGW 1) endif() set(CMAKE_CXX_COMPILER_ID_RUN 1) -set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP) +set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;mpp;CPP) set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) foreach (lang C OBJC OBJCXX) diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake index ae3abe9..ab33b40 100644 --- a/Modules/CMakeDetermineCCompiler.cmake +++ b/Modules/CMakeDetermineCCompiler.cmake @@ -161,9 +161,10 @@ if (NOT _CMAKE_TOOLCHAIN_PREFIX) if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|QCC") get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME) - if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$") + if (COMPILER_BASENAME MATCHES "^(.+-)?(clang|g?cc)(-cl)?(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$") set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) - set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5}) + set(_CMAKE_TOOLCHAIN_SUFFIX ${CMAKE_MATCH_4}) + set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_6}) elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_C_COMPILER_TARGET) set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_C_COMPILER_TARGET}-) diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake index 578729c..c77fc3a 100644 --- a/Modules/CMakeDetermineCUDACompiler.cmake +++ b/Modules/CMakeDetermineCUDACompiler.cmake @@ -172,7 +172,20 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN) endif() endif() - get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY) + # If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the + # real non-scattered toolkit. + if(IS_SYMLINK ${_CUDA_NVCC_EXECUTABLE}) + execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR) + if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)") + set(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_MATCH_1}") + else() + message(FATAL_ERROR "Could not execute nvcc with -v.") + endif() + unset(NVCC_ERR) + else() + get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY) + endif() + set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/nvlink${CMAKE_EXECUTABLE_SUFFIX}") set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/fatbinary${CMAKE_EXECUTABLE_SUFFIX}") get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY) diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake index 905eb25..7283bc2 100644 --- a/Modules/CMakeDetermineCXXCompiler.cmake +++ b/Modules/CMakeDetermineCXXCompiler.cmake @@ -160,8 +160,9 @@ if (NOT _CMAKE_TOOLCHAIN_PREFIX) if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC") get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME) - if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$") + if (COMPILER_BASENAME MATCHES "^(.+-)?(clang\\+\\+|g\\+\\+|clang-cl)(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$") set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1}) + set(_CMAKE_TOOLCHAIN_SUFFIX ${CMAKE_MATCH_3}) set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5}) elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") if(CMAKE_CXX_COMPILER_TARGET) diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake index d81fd11..ff178f6 100644 --- a/Modules/CMakeFindBinUtils.cmake +++ b/Modules/CMakeFindBinUtils.cmake @@ -70,17 +70,18 @@ if(("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND OR (CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")) + set(_CMAKE_LINKER_NAMES "link") + set(_CMAKE_AR_NAMES "lib") + set(_CMAKE_MT_NAMES "mt") if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL "xClang") - find_program(CMAKE_NM NAMES ${_CMAKE_TOOLCHAIN_PREFIX}nm llvm-nm HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - set(_CMAKE_ADDITIONAL_LINKER_NAMES "lld-link") - set(_CMAKE_ADDITIONAL_AR_NAMES "llvm-lib") + set(_CMAKE_NM_NAMES "llvm-nm" "nm") + list(APPEND _CMAKE_AR_NAMES "lib" "llvm-lib") + list(APPEND _CMAKE_MT_NAMES "mt" "llvm-mt") + list(APPEND _CMAKE_LINKER_NAMES "lld-link") + list(APPEND _CMAKE_TOOL_VARS NM) endif() - find_program(CMAKE_LINKER NAMES ${_CMAKE_ADDITIONAL_LINKER_NAMES} link HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_AR NAMES ${_CMAKE_ADDITIONAL_AR_NAMES} lib HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_MT NAMES mt HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - - list(APPEND _CMAKE_TOOL_VARS LINKER MT) + list(APPEND _CMAKE_TOOL_VARS LINKER MT AR) # in all other cases search for ar, ranlib, etc. else() @@ -92,55 +93,54 @@ else() endif() if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL Clang) - set(_CMAKE_ADDITIONAL_AR_NAMES "llvm-ar") - set(_CMAKE_ADDITIONAL_RANLIB_NAMES "llvm-ranlib") - set(_CMAKE_ADDITIONAL_STRIP_NAMES "llvm-strip") if("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC") - set(_CMAKE_ADDITIONAL_LINKER_NAMES "lld-link") + set(_CMAKE_LINKER_NAMES "lld-link") else() - set(_CMAKE_ADDITIONAL_LINKER_NAMES "ld.lld") + set(_CMAKE_LINKER_NAMES "ld.lld") endif() - set(_CMAKE_ADDITIONAL_NM_NAMES "llvm-nm") - set(_CMAKE_ADDITIONAL_OBJDUMP_NAMES "llvm-objdump") - set(_CMAKE_ADDITIONAL_OBJCOPY_NAMES "llvm-objcopy") - set(_CMAKE_ADDITIONAL_READELF_NAMES "llvm-readelf") - set(_CMAKE_ADDITIONAL_DLLTOOL_NAMES "llvm-dlltool") - set(_CMAKE_ADDITIONAL_ADDR2LINE_NAMES "llvm-addr2line") + list(APPEND _CMAKE_AR_NAMES "llvm-ar") + list(APPEND _CMAKE_NM_NAMES "llvm-nm") + list(APPEND _CMAKE_OBJDUMP_NAMES "llvm-objdump") + list(APPEND _CMAKE_OBJCOPY_NAMES "llvm-objcopy") + list(APPEND _CMAKE_READELF_NAMES "llvm-readelf") + list(APPEND _CMAKE_DLLTOOL_NAMES "llvm-dlltool") + list(APPEND _CMAKE_ADDR2LINE_NAMES "llvm-addr2line") endif() - if(NOT CMAKE_CROSSCOMPILING AND NOT "${_CMAKE_TOOLCHAIN_PREFIX}" STREQUAL "") - list(APPEND _CMAKE_ADDITIONAL_AR_NAMES "ar") - list(APPEND _CMAKE_ADDITIONAL_RANLIB_NAMES "ranlib") - list(APPEND _CMAKE_ADDITIONAL_STRIP_NAMES "strip") - list(APPEND _CMAKE_ADDITIONAL_LINKER_NAMES "ld") - list(APPEND _CMAKE_ADDITIONAL_NM_NAMES "nm") - list(APPEND _CMAKE_ADDITIONAL_OBJDUMP_NAMES "objdump") - list(APPEND _CMAKE_ADDITIONAL_OBJCOPY_NAMES "objcopy") - list(APPEND _CMAKE_ADDITIONAL_READELF_NAMES "readelf") - list(APPEND _CMAKE_ADDITIONAL_DLLTOOL_NAMES "dlltool") - list(APPEND _CMAKE_ADDITIONAL_ADDR2LINE_NAMES "addr2line") - endif() + list(APPEND _CMAKE_AR_NAMES "ar") + list(APPEND _CMAKE_RANLIB_NAMES "ranlib") + list(APPEND _CMAKE_STRIP_NAMES "strip") + list(APPEND _CMAKE_LINKER_NAMES "ld") + list(APPEND _CMAKE_NM_NAMES "nm") + list(APPEND _CMAKE_OBJDUMP_NAMES "objdump") + list(APPEND _CMAKE_OBJCOPY_NAMES "objcopy") + list(APPEND _CMAKE_READELF_NAMES "readelf") + list(APPEND _CMAKE_DLLTOOL_NAMES "dlltool") + list(APPEND _CMAKE_ADDR2LINE_NAMES "addr2line") + + list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE) +endif() - find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar${_CMAKE_TOOLCHAIN_SUFFIX} ${_CMAKE_ADDITIONAL_AR_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +foreach(TOOL IN LISTS _CMAKE_TOOL_VARS) + foreach(NAME IN LISTS _CMAKE_${TOOL}_NAMES) + if(NOT _CMAKE_TOOLCHAIN_PREFIX STREQUAL "") + if(NOT _CMAKE_TOOLCHAIN_SUFFIX STREQUAL "") + list(PREPEND _CMAKE_${TOOL}_NAMES ${NAME}${_CMAKE_TOOLCHAIN_SUFFIX}) + endif() + list(PREPEND _CMAKE_${TOOL}_NAMES ${_CMAKE_TOOLCHAIN_PREFIX}${NAME}) + endif() + if(NOT _CMAKE_TOOLCHAIN_SUFFIX STREQUAL "") + list(PREPEND _CMAKE_${TOOL}_NAMES ${_CMAKE_TOOLCHAIN_PREFIX}${NAME}${_CMAKE_TOOLCHAIN_SUFFIX}) + endif() + endforeach() + find_program(CMAKE_${TOOL} NAMES ${_CMAKE_${TOOL}_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) +endforeach() - find_program(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib ${_CMAKE_ADDITIONAL_RANLIB_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - if(NOT CMAKE_RANLIB) +if(NOT CMAKE_RANLIB) set(CMAKE_RANLIB : CACHE INTERNAL "noop for ranlib") - endif() - - - find_program(CMAKE_STRIP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}strip${_CMAKE_TOOLCHAIN_SUFFIX} ${_CMAKE_ADDITIONAL_STRIP_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_LINKER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ld ${_CMAKE_ADDITIONAL_LINKER_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_NM NAMES ${_CMAKE_TOOLCHAIN_PREFIX}nm ${_CMAKE_ADDITIONAL_NM_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_OBJDUMP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objdump ${_CMAKE_ADDITIONAL_OBJDUMP_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_OBJCOPY NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objcopy ${_CMAKE_ADDITIONAL_OBJCOPY_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_READELF NAMES ${_CMAKE_TOOLCHAIN_PREFIX}readelf ${_CMAKE_ADDITIONAL_READELF_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_DLLTOOL NAMES ${_CMAKE_TOOLCHAIN_PREFIX}dlltool ${_CMAKE_ADDITIONAL_DLLTOOL_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - find_program(CMAKE_ADDR2LINE NAMES ${_CMAKE_TOOLCHAIN_PREFIX}addr2line ${_CMAKE_ADDITIONAL_ADDR2LINE_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) - - list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE) endif() + if(CMAKE_PLATFORM_HAS_INSTALLNAME) find_program(CMAKE_INSTALL_NAME_TOOL NAMES ${_CMAKE_TOOLCHAIN_PREFIX}install_name_tool HINTS ${_CMAKE_TOOLCHAIN_LOCATION}) @@ -157,7 +157,7 @@ foreach(var IN LISTS _CMAKE_TOOL_VARS) if(_CMAKE_TOOL_CACHED) mark_as_advanced(CMAKE_${var}) endif() - unset(_CMAKE_ADDITIONAL_${var}_NAMES) + unset(_CMAKE_${var}_NAMES) endforeach() unset(_CMAKE_TOOL_VARS) unset(_CMAKE_TOOL_CACHED) diff --git a/Modules/Compiler/Clang-FindBinUtils.cmake b/Modules/Compiler/Clang-FindBinUtils.cmake index b852660..e6c469a 100644 --- a/Modules/Compiler/Clang-FindBinUtils.cmake +++ b/Modules/Compiler/Clang-FindBinUtils.cmake @@ -2,6 +2,12 @@ if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set") endif() +# Ubuntu: +# * /usr/bin/llvm-ar-9 +# * /usr/bin/llvm-ranlib-9 +string(REGEX MATCH "^([0-9]+)" __version_x + "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}") + # Debian: # * /usr/bin/llvm-ar-4.0 # * /usr/bin/llvm-ranlib-4.0 @@ -19,6 +25,7 @@ set(__clang_hints ${__clang_hint_1} ${__clang_hint_2}) # http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ar.1.html find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x_y}" + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x}" "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar" HINTS ${__clang_hints} DOC "LLVM archiver" @@ -28,6 +35,7 @@ mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR) # http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ranlib.1.html find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x_y}" + "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x}" "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib" HINTS ${__clang_hints} DOC "Generate index for LLVM archive" diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 28d21c1..29cfba9 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -543,6 +543,18 @@ External Project Definition When ``BUILD_IN_SOURCE`` option is enabled, the ``BUILD_COMMAND`` is used to point to an alternative directory within the source tree. + ``CONFIGURE_HANDLED_BY_BUILD <bool>`` + .. versionadded:: 3.20 + + Enabling this option relaxes the dependencies of the configure step on + other external projects to order-only. This means the configure step will + be executed after its external project dependencies are built but it will + not be marked dirty when one of its external project dependencies is + rebuilt. This option can be enabled when the build step is smart enough + to figure out if the configure step needs to be rerun. CMake and Meson are + examples of build systems whose build step is smart enough to know if the + configure step needs to be rerun. + **Build Step Options:** If the configure step assumed the external project uses CMake as its build system, the build step will also. Otherwise, the build step will assume a @@ -1410,10 +1422,13 @@ function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_r if("${git_tag}" STREQUAL "") message(FATAL_ERROR "Tag for git checkout should not be empty.") endif() - if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.6) - set(git_stash_save_options --all --quiet) - else() - set(git_stash_save_options --quiet) + set(git_stash_save_options --quiet) + if(GIT_VERSION_STRING VERSION_GREATER_EQUAL 1.7.7) + # This avoids stashing files covered by .gitignore + list(APPEND git_stash_save_options --include-untracked) + elseif(GIT_VERSION_STRING VERSION_GREATER_EQUAL 1.7.6) + # Untracked files, but also ignored files, so potentially slower + list(APPEND git_stash_save_options --all) endif() configure_file( @@ -2618,10 +2633,13 @@ function(_ep_add_download_command name) --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args} ${src_name}) list(APPEND depends ${stamp_dir}/${name}-svninfo.txt) elseif(git_repository) - unset(CMAKE_MODULE_PATH) # Use CMake builtin find module - find_package(Git QUIET) - if(NOT GIT_EXECUTABLE) - message(FATAL_ERROR "error: could not find git for clone of ${name}") + # FetchContent gives us these directly, so don't try to recompute them + if(NOT GIT_EXECUTABLE OR NOT GIT_VERSION_STRING) + unset(CMAKE_MODULE_PATH) # Use CMake builtin find module + find_package(Git QUIET) + if(NOT GIT_EXECUTABLE) + message(FATAL_ERROR "error: could not find git for clone of ${name}") + endif() endif() _ep_get_git_submodules_recurse(git_submodules_recurse) @@ -2939,10 +2957,13 @@ function(_ep_add_update_command name) --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args}) set(always 1) elseif(git_repository) - unset(CMAKE_MODULE_PATH) # Use CMake builtin find module - find_package(Git QUIET) - if(NOT GIT_EXECUTABLE) - message(FATAL_ERROR "error: could not find git for fetch of ${name}") + # FetchContent gives us these directly, so don't try to recompute them + if(NOT GIT_EXECUTABLE OR NOT GIT_VERSION_STRING) + unset(CMAKE_MODULE_PATH) # Use CMake builtin find module + find_package(Git QUIET) + if(NOT GIT_EXECUTABLE) + message(FATAL_ERROR "error: could not find git for fetch of ${name}") + endif() endif() set(work_dir ${source_dir}) set(comment "Performing update step for '${name}'") @@ -3083,6 +3104,23 @@ function(_ep_add_patch_command name) ) endfunction() +function(_ep_get_file_deps var name) + set(file_deps) + + get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) + foreach(dep IN LISTS deps) + get_property(dep_type TARGET ${dep} PROPERTY TYPE) + if(dep_type STREQUAL "UTILITY") + get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT) + if(is_ep) + _ep_get_step_stampfile(${dep} "done" done_stamp_file) + list(APPEND file_deps ${done_stamp_file}) + endif() + endif() + endforeach() + + set("${var}" "${file_deps}" PARENT_SCOPE) +endfunction() function(_ep_extract_configure_command var name) get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET) @@ -3191,19 +3229,13 @@ endfunction() function(_ep_add_configure_command name) ExternalProject_Get_Property(${name} binary_dir tmp_dir) - # Depend on other external projects (file-level). set(file_deps) - get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS) - foreach(dep IN LISTS deps) - get_property(dep_type TARGET ${dep} PROPERTY TYPE) - if(dep_type STREQUAL "UTILITY") - get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT) - if(is_ep) - _ep_get_step_stampfile(${dep} "done" done_stamp_file) - list(APPEND file_deps ${done_stamp_file}) - endif() - endif() - endforeach() + get_property(configure_handled_by_build TARGET ${name} + PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD) + if(NOT configure_handled_by_build) + # Depend on other external projects (file-level) + _ep_get_file_deps(file_deps ${name}) + endif() _ep_extract_configure_command(cmd ${name}) @@ -3254,6 +3286,14 @@ endfunction() function(_ep_add_build_command name) ExternalProject_Get_Property(${name} binary_dir) + set(file_deps) + get_property(configure_handled_by_build TARGET ${name} + PROPERTY _EP_CONFIGURE_HANDLED_BY_BUILD) + if(configure_handled_by_build) + # Depend on other external projects (file-level) + _ep_get_file_deps(file_deps ${name}) + endif() + get_property(cmd_set TARGET ${name} PROPERTY _EP_BUILD_COMMAND SET) if(cmd_set) get_property(cmd TARGET ${name} PROPERTY _EP_BUILD_COMMAND) @@ -3296,6 +3336,7 @@ function(_ep_add_build_command name) BYPRODUCTS \${build_byproducts} WORKING_DIRECTORY \${binary_dir} DEPENDEES configure + DEPENDS \${file_deps} ALWAYS \${always} ${log} ${uses_terminal} diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index ba2acfc..8adef47 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -964,6 +964,22 @@ ExternalProject_Add_Step(${contentName}-populate copyfile "-DCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY=${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}") endif() + # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings + set(__FETCHCONTENT_CACHED_INFO "") + list(FIND ARG_UNPARSED_ARGUMENTS GIT_REPOSITORY indexResult) + if(indexResult GREATER_EQUAL 0) + find_package(Git QUIET) + set(__FETCHCONTENT_CACHED_INFO +"# Pass through things we've already detected in the main project to avoid +# paying the cost of redetecting them again in ExternalProject_Add() +set(GIT_EXECUTABLE [==[${GIT_EXECUTABLE}]==]) +set(GIT_VERSION_STRING [==[${GIT_VERSION_STRING}]==]) +set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION + [==[${GIT_EXECUTABLE};${GIT_VERSION_STRING}]==] +) +") + endif() + # Create and build a separate CMake project to carry out the population. # If we've already previously done these steps, they will not cause # anything to be updated, so extra rebuilds of the project won't occur. diff --git a/Modules/FetchContent/CMakeLists.cmake.in b/Modules/FetchContent/CMakeLists.cmake.in index 45e4df0..5ebb12f 100644 --- a/Modules/FetchContent/CMakeLists.cmake.in +++ b/Modules/FetchContent/CMakeLists.cmake.in @@ -9,6 +9,8 @@ cmake_minimum_required(VERSION ${CMAKE_VERSION}) project(${contentName}-populate NONE) +@__FETCHCONTENT_CACHED_INFO@ + include(ExternalProject) ExternalProject_Add(${contentName}-populate ${ARG_EXTRA} diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index 6daf81d..240f0a5 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -834,7 +834,20 @@ if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING) ) if (CUDA_TOOLKIT_ROOT_DIR_NVCC) - get_filename_component(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY) + # If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the + # real non-scattered toolkit. + if(IS_SYMLINK ${CUDA_TOOLKIT_ROOT_DIR_NVCC}) + execute_process(COMMAND ${CUDA_TOOLKIT_ROOT_DIR_NVCC} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR) + if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)") + set(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CMAKE_MATCH_1}") + else() + message(FATAL_ERROR "Could not execute nvcc with -v.") + endif() + unset(NVCC_ERR) + else() + get_filename_component(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY) + endif() + get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR}" DIRECTORY CACHE) string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR}) # We need to force this back into the cache. diff --git a/Modules/FindCUDA/select_compute_arch.cmake b/Modules/FindCUDA/select_compute_arch.cmake index 9351288..a35b3f8 100644 --- a/Modules/FindCUDA/select_compute_arch.cmake +++ b/Modules/FindCUDA/select_compute_arch.cmake @@ -25,44 +25,26 @@ if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language endif() # See: https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list +# Additions, deprecations, and removals can be found in the release notes: +# https://developer.nvidia.com/cuda-toolkit-archive -# This list will be used for CUDA_ARCH_NAME = All option -set(CUDA_KNOWN_GPU_ARCHITECTURES "Fermi" "Kepler" "Maxwell") +# The initial status here is for CUDA 7.0 +set(CUDA_KNOWN_GPU_ARCHITECTURES "Fermi" "Kepler" "Maxwell" "Kepler+Tegra" "Kepler+Tesla" "Maxwell+Tegra") +set(CUDA_COMMON_GPU_ARCHITECTURES "2.0" "2.1" "3.0" "3.5" "5.0" "5.3") +set(CUDA_LIMIT_GPU_ARCHITECTURE "6.0") +set(CUDA_ALL_GPU_ARCHITECTURES "2.0" "2.1" "3.0" "3.2" "3.5" "3.7" "5.0" "5.2" "5.3") +set(_CUDA_MAX_COMMON_ARCHITECTURE "5.2+PTX") -# This list will be used for CUDA_ARCH_NAME = Common option (enabled by default) -set(CUDA_COMMON_GPU_ARCHITECTURES "3.5" "5.0") -# 3.0 is removed in CUDA 11, see: -# https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#deprecated-features -if(CUDA_VERSION VERSION_LESS "11.0") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "3.0") -endif() - -if(CUDA_VERSION VERSION_LESS "7.0") - set(CUDA_LIMIT_GPU_ARCHITECTURE "5.2") -endif() - -# This list is used to filter CUDA archs when autodetecting -set(CUDA_ALL_GPU_ARCHITECTURES "3.0" "3.2" "3.5" "5.0") - -if(CUDA_VERSION VERSION_GREATER_EQUAL "7.0") - list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Kepler+Tegra" "Kepler+Tesla" "Maxwell+Tegra") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2") - - if(CUDA_VERSION VERSION_LESS "8.0") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "5.2+PTX") - set(CUDA_LIMIT_GPU_ARCHITECTURE "6.0") - endif() -endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "8.0") list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Pascal") list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.0" "6.1") list(APPEND CUDA_ALL_GPU_ARCHITECTURES "6.0" "6.1" "6.2") - if(CUDA_VERSION VERSION_LESS "9.0") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "6.2+PTX") - set(CUDA_LIMIT_GPU_ARCHITECTURE "7.0") - endif() + set(_CUDA_MAX_COMMON_ARCHITECTURE "6.2+PTX") + set(CUDA_LIMIT_GPU_ARCHITECTURE "7.0") + + list(REMOVE_ITEM CUDA_COMMON_GPU_ARCHITECTURES "2.0" "2.1") endif () if(CUDA_VERSION VERSION_GREATER_EQUAL "9.0") @@ -70,10 +52,11 @@ if(CUDA_VERSION VERSION_GREATER_EQUAL "9.0") list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.0") list(APPEND CUDA_ALL_GPU_ARCHITECTURES "7.0" "7.2") - if(CUDA_VERSION VERSION_LESS "10.0") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.2+PTX") - set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0") - endif() + set(_CUDA_MAX_COMMON_ARCHITECTURE "7.2+PTX") + set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0") + + list(REMOVE_ITEM CUDA_KNOWN_GPU_ARCHITECTURES "Fermi") + list(REMOVE_ITEM CUDA_ALL_GPU_ARCHITECTURES "2.0" "2.1") endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "10.0") @@ -81,32 +64,46 @@ if(CUDA_VERSION VERSION_GREATER_EQUAL "10.0") list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.5") list(APPEND CUDA_ALL_GPU_ARCHITECTURES "7.5") - if(CUDA_VERSION VERSION_LESS "11.0") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "7.5+PTX") - set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0") - endif() + set(_CUDA_MAX_COMMON_ARCHITECTURE "7.5+PTX") + set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0") + + list(REMOVE_ITEM CUDA_COMMON_GPU_ARCHITECTURES "3.0") endif() +# https://docs.nvidia.com/cuda/archive/11.0/cuda-toolkit-release-notes/index.html#cuda-general-new-features +# https://docs.nvidia.com/cuda/archive/11.0/cuda-toolkit-release-notes/index.html#deprecated-features if(CUDA_VERSION VERSION_GREATER_EQUAL "11.0") list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Ampere") list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.0") list(APPEND CUDA_ALL_GPU_ARCHITECTURES "8.0") - if(CUDA_VERSION VERSION_LESS "11.1") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.0+PTX") - set(CUDA_LIMIT_GPU_ARCHITECTURE "8.6") - endif() + set(_CUDA_MAX_COMMON_ARCHITECTURE "8.0+PTX") + set(CUDA_LIMIT_GPU_ARCHITECTURE "8.6") + + list(REMOVE_ITEM CUDA_COMMON_GPU_ARCHITECTURES "3.5" "5.0") + list(REMOVE_ITEM CUDA_ALL_GPU_ARCHITECTURES "3.0" "3.2") endif() if(CUDA_VERSION VERSION_GREATER_EQUAL "11.1") - list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.6" "8.6+PTX") + list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.6") list(APPEND CUDA_ALL_GPU_ARCHITECTURES "8.6") - if(CUDA_VERSION VERSION_LESS "12.0") - set(CUDA_LIMIT_GPU_ARCHITECTURE "9.0") - endif() + set(_CUDA_MAX_COMMON_ARCHITECTURE "8.6+PTX") + set(CUDA_LIMIT_GPU_ARCHITECTURE "9.0") endif() +list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "${_CUDA_MAX_COMMON_ARCHITECTURE}") + +# Check with: cmake -DCUDA_VERSION=7.0 -P select_compute_arch.cmake +if(DEFINED CMAKE_SCRIPT_MODE_FILE) + include(CMakePrintHelpers) + cmake_print_variables(CUDA_KNOWN_GPU_ARCHITECTURES) + cmake_print_variables(CUDA_COMMON_GPU_ARCHITECTURES) + cmake_print_variables(CUDA_LIMIT_GPU_ARCHITECTURE) + cmake_print_variables(CUDA_ALL_GPU_ARCHITECTURES) +endif() + + ################################################################################################ # A function for automatic detection of GPUs installed (if autodetection is enabled) # Usage: diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index 61e264b..0d80c80 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -519,7 +519,19 @@ else() endif() if(CUDAToolkit_NVCC_EXECUTABLE) - get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) + # If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the + # real non-scattered toolkit. + if(IS_SYMLINK ${CUDAToolkit_NVCC_EXECUTABLE}) + execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR) + if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)") + set(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}") + else() + message(FATAL_ERROR "Could not execute nvcc with -v.") + endif() + unset(NVCC_ERR) + else() + get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) + endif() set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE) mark_as_advanced(CUDAToolkit_BIN_DIR) diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake index f8346b6..83da707 100644 --- a/Modules/FindGit.cmake +++ b/Modules/FindGit.cmake @@ -77,14 +77,44 @@ unset(git_names) unset(_git_sourcetree_path) if(GIT_EXECUTABLE) - execute_process(COMMAND ${GIT_EXECUTABLE} --version - OUTPUT_VARIABLE git_version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (git_version MATCHES "^git version [0-9]") - string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}") + # Avoid querying the version if we've already done that this run. For + # projects that use things like ExternalProject or FetchContent heavily, + # this saving can be measurable on some platforms. + set(__doGitVersionCheck YES) + if(DEFINED GIT_VERSION_STRING) + # This is an internal property, projects must not try to use it. + # We don't want this stored in the cache because it might still change + # between CMake runs, but it shouldn't change during a run. + get_property(__gitVersionProp GLOBAL + PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION + ) + if(__gitVersionProp) + list(GET __gitVersionProp 0 __gitExe) + list(GET __gitVersionProp 1 __gitVersion) + if("${__gitExe}" STREQUAL "${GIT_EXECUTABLE}" AND + "${__gitVersion}" STREQUAL "${GIT_VERSION_STRING}") + set(__doGitVersionCheck NO) + endif() + endif() + unset(__gitVersionProp) + unset(__gitExe) + unset(__gitVersion) + endif() + + if(__doGitVersionCheck) + execute_process(COMMAND ${GIT_EXECUTABLE} --version + OUTPUT_VARIABLE git_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (git_version MATCHES "^git version [0-9]") + string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}") + set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION + "${GIT_EXECUTABLE};${GIT_VERSION_STRING}" + ) + endif() + unset(git_version) endif() - unset(git_version) + unset(__doGitVersionCheck) get_property(_findgit_role GLOBAL PROPERTY CMAKE_ROLE) if(_findgit_role STREQUAL "PROJECT" AND NOT TARGET Git::Git) diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake index 12f4c17..16bf279 100644 --- a/Modules/FindHDF5.cmake +++ b/Modules/FindHDF5.cmake @@ -116,15 +116,22 @@ also be defined. With all components enabled, the following variables will be d With all components enabled, the following targets will be defined: -:: - - ``hdf5::hdf5`` - ``hdf5::hdf5_hl_cpp`` - ``hdf5::hdf5_fortran`` - ``hdf5::hdf5_hl`` - ``hdf5::hdf5_hl_cpp`` - ``hdf5::hdf5_hl_fortran`` - ``hdf5::h5diff`` +``HDF5::HDF5`` + All detected ``HDF5_LIBRARIES``. +``hdf5::hdf5`` + C library. +``hdf5::hdf5_cpp`` + C++ library. +``hdf5::hdf5_fortran`` + Fortran library. +``hdf5::hdf5_hl`` + High-level C library. +``hdf5::hdf5_hl_cpp`` + High-level C++ library. +``hdf5::hdf5_hl_fortran`` + High-level Fortran library. +``hdf5::h5diff`` + ``h5diff`` executable. Hints ^^^^^ @@ -206,22 +213,6 @@ else() set(HDF5_Fortran_COMPILER_NAMES h5fc h5pfc) endif() -# We may have picked up some duplicates in various lists during the above -# process for the language bindings (both the C and C++ bindings depend on -# libz for example). Remove the duplicates. It appears that the default -# CMake behavior is to remove duplicates from the end of a list. However, -# for link lines, this is incorrect since unresolved symbols are searched -# for down the link line. Therefore, we reverse the list, remove the -# duplicates, and then reverse it again to get the duplicates removed from -# the beginning. -macro(_HDF5_remove_duplicates_from_beginning _list_name) - if(${_list_name}) - list(REVERSE ${_list_name}) - list(REMOVE_DUPLICATES ${_list_name}) - list(REVERSE ${_list_name}) - endif() -endmacro() - # Test first if the current compilers automatically wrap HDF5 function(_HDF5_test_regular_compiler_C success version is_parallel) set(scratch_directory @@ -370,9 +361,11 @@ function( _HDF5_invoke_compiler language output_var return_value_var version_var execute_process( COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file} WORKING_DIRECTORY ${scratch_dir} + OUTPUT_VARIABLE output + ERROR_VARIABLE output RESULT_VARIABLE return_value ) - if(return_value) + if(return_value AND NOT HDF5_FIND_QUIETLY) message(STATUS "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.") else() @@ -384,7 +377,7 @@ function( _HDF5_invoke_compiler language output_var return_value_var version_var RESULT_VARIABLE return_value OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(return_value) + if(return_value AND NOT HDF5_FIND_QUIETLY) message(STATUS "Unable to determine HDF5 ${language} flags from HDF5 wrapper.") endif() @@ -395,7 +388,7 @@ function( _HDF5_invoke_compiler language output_var return_value_var version_var RESULT_VARIABLE return_value OUTPUT_STRIP_TRAILING_WHITESPACE ) - if(return_value) + if(return_value AND NOT HDF5_FIND_QUIETLY) message(STATUS "Unable to determine HDF5 ${language} version_var from HDF5 wrapper.") endif() @@ -724,10 +717,8 @@ if(NOT HDF5_FOUND) endif() set(HDF5_${_lang}_FOUND TRUE) - _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_DEFINITIONS) - _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_INCLUDE_DIRS) - _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_LIBRARIES) - _HDF5_remove_duplicates_from_beginning(HDF5_${_lang}_HL_LIBRARIES) + list(REMOVE_DUPLICATES HDF5_${_lang}_DEFINITIONS) + list(REMOVE_DUPLICATES HDF5_${_lang}_INCLUDE_DIRS) else() set(_HDF5_NEED_TO_SEARCH TRUE) endif() @@ -780,10 +771,8 @@ elseif(NOT HDF5_FOUND AND NOT _HDF5_NEED_TO_SEARCH) endif() endif() endforeach() - _HDF5_remove_duplicates_from_beginning(HDF5_DEFINITIONS) - _HDF5_remove_duplicates_from_beginning(HDF5_INCLUDE_DIRS) - _HDF5_remove_duplicates_from_beginning(HDF5_LIBRARIES) - _HDF5_remove_duplicates_from_beginning(HDF5_HL_LIBRARIES) + list(REMOVE_DUPLICATES HDF5_DEFINITIONS) + list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) set(HDF5_FOUND TRUE) set(HDF5_REQUIRED_VARS HDF5_LIBRARIES) if(HDF5_FIND_HL) @@ -923,10 +912,8 @@ if( NOT HDF5_FOUND ) set(HDF5_HL_FOUND TRUE) endif() - _HDF5_remove_duplicates_from_beginning(HDF5_DEFINITIONS) - _HDF5_remove_duplicates_from_beginning(HDF5_INCLUDE_DIRS) - _HDF5_remove_duplicates_from_beginning(HDF5_LIBRARIES) - _HDF5_remove_duplicates_from_beginning(HDF5_HL_LIBRARIES) + list(REMOVE_DUPLICATES HDF5_DEFINITIONS) + list(REMOVE_DUPLICATES HDF5_INCLUDE_DIRS) # If the HDF5 include directory was found, open H5pubconf.h to determine if # HDF5 was compiled with parallel IO support @@ -1001,10 +988,10 @@ if (HDF5_FOUND) add_library(HDF5::HDF5 INTERFACE IMPORTED) string(REPLACE "-D" "" _hdf5_definitions "${HDF5_DEFINITIONS}") set_target_properties(HDF5::HDF5 PROPERTIES - INTERFACE_LINK_LIBRARIES "${HDF5_LIBRARIES}" INTERFACE_INCLUDE_DIRECTORIES "${HDF5_INCLUDE_DIRS}" INTERFACE_COMPILE_DEFINITIONS "${_hdf5_definitions}") unset(_hdf5_definitions) + target_link_libraries(HDF5::HDF5 INTERFACE ${HDF5_LIBRARIES}) endif () foreach (hdf5_lang IN LISTS HDF5_LANGUAGE_BINDINGS) @@ -1147,6 +1134,21 @@ if (HDF5_FIND_DEBUG) message(STATUS "HDF5_${_lang}_HL_LIBRARY: ${HDF5_${_lang}_HL_LIBRARY}") message(STATUS "HDF5_${_lang}_HL_LIBRARIES: ${HDF5_${_lang}_HL_LIBRARIES}") endforeach() + message(STATUS "Defined targets (if any):") + foreach(_lang IN ITEMS "" "_cpp" "_fortran") + foreach(_hl IN ITEMS "" "_hl") + foreach(_prefix IN ITEMS "hdf5::" "") + foreach(_suffix IN ITEMS "-static" "-shared" "") + set (_target ${_prefix}hdf5${_hl}${_lang}${_suffix}) + if (TARGET ${_target}) + message(STATUS "... ${_target}") + else() + #message(STATUS "... ${_target} does not exist") + endif() + endforeach() + endforeach() + endforeach() + endforeach() endif() unset(_lang) unset(_HDF5_NEED_TO_SEARCH) diff --git a/Modules/FindJPEG.cmake b/Modules/FindJPEG.cmake index 3f243de..add2486 100644 --- a/Modules/FindJPEG.cmake +++ b/Modules/FindJPEG.cmake @@ -58,7 +58,7 @@ Obsolete variables find_path(JPEG_INCLUDE_DIR jpeglib.h) -set(jpeg_names ${JPEG_NAMES} jpeg jpeg-static libjpeg libjpeg-static) +set(jpeg_names ${JPEG_NAMES} jpeg jpeg-static libjpeg libjpeg-static turbojpeg turbojpeg-static) foreach(name ${jpeg_names}) list(APPEND jpeg_names_debug "${name}d") endforeach() diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake index d5af5da..45e4be7 100644 --- a/Modules/FindLAPACK.cmake +++ b/Modules/FindLAPACK.cmake @@ -72,6 +72,12 @@ The following variables may be set to influence this module's behavior: ``BLA_F95`` if ``ON`` tries to find the BLAS95/LAPACK95 interfaces +``BLA_PREFER_PKGCONFIG`` + .. versionadded:: 3.20 + + if set ``pkg-config`` will be used to search for a LAPACK library first + and if one is found that is preferred + Imported targets ^^^^^^^^^^^^^^^^ @@ -121,6 +127,26 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake) include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +function(_add_lapack_target) + if(LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK) + add_library(LAPACK::LAPACK INTERFACE IMPORTED) + set(_lapack_libs "${LAPACK_LIBRARIES}") + if(_lapack_libs AND TARGET BLAS::BLAS) + # remove the ${BLAS_LIBRARIES} from the interface and replace it + # with the BLAS::BLAS target + list(REMOVE_ITEM _lapack_libs "${BLAS_LIBRARIES}") + list(APPEND _lapack_libs BLAS::BLAS) + endif() + + if(_lapack_libs) + set_target_properties(LAPACK::LAPACK PROPERTIES + INTERFACE_LINK_LIBRARIES "${_lapack_libs}" + ) + endif() + unset(_lapack_libs) + endif() +endfunction() + macro(_lapack_find_library_setup) cmake_push_check_state() set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY}) @@ -265,6 +291,21 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE) _lapack_find_dependency(BLAS) endif() +# Search with pkg-config if specified +if(BLA_PREFER_PKGCONFIG) + find_package(PkgConfig) + pkg_check_modules(PKGC_LAPACK lapack) + if(PKGC_LAPACK_FOUND) + set(LAPACK_FOUND TRUE) + set(LAPACK_LIBRARIES "${PKGC_LAPACK_LINK_LIBRARIES}") + if (BLAS_LIBRARIES) + list(APPEND LAPACK_LIBRARIES "${BLAS_LIBRARIES}") + endif() + _add_lapack_target() + return() + endif() +endif() + # Search for different LAPACK distributions if BLAS is found if(NOT LAPACK_NOT_FOUND_MESSAGE) set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS}) @@ -585,21 +626,6 @@ if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES") set(LAPACK_LIBRARIES "") endif() -if(LAPACK_FOUND AND NOT TARGET LAPACK::LAPACK) - add_library(LAPACK::LAPACK INTERFACE IMPORTED) - set(_lapack_libs "${LAPACK_LIBRARIES}") - if(_lapack_libs AND TARGET BLAS::BLAS) - # remove the ${BLAS_LIBRARIES} from the interface and replace it - # with the BLAS::BLAS target - list(REMOVE_ITEM _lapack_libs "${BLAS_LIBRARIES}") - endif() - - if(_lapack_libs) - set_target_properties(LAPACK::LAPACK PROPERTIES - INTERFACE_LINK_LIBRARIES "${_lapack_libs}" - ) - endif() - unset(_lapack_libs) -endif() +_add_lapack_target() _lapack_find_library_teardown() diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake index 19e6e57..8476823 100644 --- a/Modules/FindMPI.cmake +++ b/Modules/FindMPI.cmake @@ -653,6 +653,7 @@ function (_MPI_interrogate_compiler LANG) foreach(_MPI_INCLUDE_PATH IN LISTS MPI_ALL_INCLUDE_PATHS) string(REGEX REPLACE "^ ?${_MPI_PREPROCESSOR_FLAG_REGEX}${CMAKE_INCLUDE_FLAG_${LANG}} *" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}") string(REPLACE "\"" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}") + string(REPLACE "'" "" _MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}") get_filename_component(_MPI_INCLUDE_PATH "${_MPI_INCLUDE_PATH}" REALPATH) list(APPEND MPI_INCLUDE_DIRS_WORK "${_MPI_INCLUDE_PATH}") endforeach() diff --git a/Modules/FindPostgreSQL.cmake b/Modules/FindPostgreSQL.cmake index cd50d8c..147071a 100644 --- a/Modules/FindPostgreSQL.cmake +++ b/Modules/FindPostgreSQL.cmake @@ -30,6 +30,16 @@ This module will set the following variables in your project: the link directories for PostgreSQL libraries ``PostgreSQL_VERSION_STRING`` the version of PostgreSQL found +``PostgreSQL_TYPE_INCLUDE_DIR`` + the directories of the PostgreSQL server headers + +Components +^^^^^^^^^^ + +This module contains additional ``Server`` component, that forcibly checks +for the presence of server headers. Note that ``PostgreSQL_TYPE_INCLUDE_DIR`` +is set regardless of the presence of the ``Server`` component in find_package call. + #]=======================================================================] # ---------------------------------------------------------------------------- @@ -81,6 +91,9 @@ This module will set the following variables in your project: # # ---------------------------------------------------------------------------- +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST + set(PostgreSQL_INCLUDE_PATH_DESCRIPTION "top-level directory containing the PostgreSQL include directories. E.g /usr/local/include/PostgreSQL/8.4 or C:/Program Files/PostgreSQL/8.4/include") set(PostgreSQL_INCLUDE_DIR_MESSAGE "Set the PostgreSQL_INCLUDE_DIR cmake cache entry to the ${PostgreSQL_INCLUDE_PATH_DESCRIPTION}") set(PostgreSQL_LIBRARY_PATH_DESCRIPTION "top-level directory containing the PostgreSQL libraries.") @@ -244,10 +257,18 @@ if (PostgreSQL_INCLUDE_DIR) unset(pgsql_version_str) endif() +if("Server" IN_LIST PostgreSQL_FIND_COMPONENTS) + set(PostgreSQL_Server_FOUND TRUE) + if(NOT PostgreSQL_TYPE_INCLUDE_DIR) + set(PostgreSQL_Server_FOUND FALSE) + endif() +endif() + # Did we find anything? include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_package_handle_standard_args(PostgreSQL - REQUIRED_VARS PostgreSQL_LIBRARY PostgreSQL_INCLUDE_DIR PostgreSQL_TYPE_INCLUDE_DIR + REQUIRED_VARS PostgreSQL_LIBRARY PostgreSQL_INCLUDE_DIR + HANDLE_COMPONENTS VERSION_VAR PostgreSQL_VERSION_STRING) set(PostgreSQL_FOUND ${POSTGRESQL_FOUND}) @@ -271,16 +292,21 @@ endfunction() # Now try to get the include and library path. if(PostgreSQL_FOUND) + set(PostgreSQL_INCLUDE_DIRS ${PostgreSQL_INCLUDE_DIR}) + if(PostgreSQL_TYPE_INCLUDE_DIR) + list(APPEND PostgreSQL_INCLUDE_DIRS ${PostgreSQL_TYPE_INCLUDE_DIR}) + endif() + set(PostgreSQL_LIBRARY_DIRS ${PostgreSQL_LIBRARY_DIR}) if (NOT TARGET PostgreSQL::PostgreSQL) add_library(PostgreSQL::PostgreSQL UNKNOWN IMPORTED) set_target_properties(PostgreSQL::PostgreSQL PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${PostgreSQL_INCLUDE_DIR};${PostgreSQL_TYPE_INCLUDE_DIR}") + INTERFACE_INCLUDE_DIRECTORIES "${PostgreSQL_INCLUDE_DIRS}") __postgresql_import_library(PostgreSQL::PostgreSQL PostgreSQL_LIBRARY "") __postgresql_import_library(PostgreSQL::PostgreSQL PostgreSQL_LIBRARY "RELEASE") __postgresql_import_library(PostgreSQL::PostgreSQL PostgreSQL_LIBRARY "DEBUG") endif () - set(PostgreSQL_INCLUDE_DIRS ${PostgreSQL_INCLUDE_DIR} ${PostgreSQL_TYPE_INCLUDE_DIR} ) - set(PostgreSQL_LIBRARY_DIRS ${PostgreSQL_LIBRARY_DIR} ) endif() mark_as_advanced(PostgreSQL_INCLUDE_DIR PostgreSQL_TYPE_INCLUDE_DIR) + +cmake_policy(POP) diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index f325cfb..ed5c38b 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -736,7 +736,7 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa set(gp_regex_cmp_count 1) elseif(gp_tool MATCHES "otool$") set(gp_cmd_args "-L") - set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$") + set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)(, weak)?\\)${eol_char}$") set(gp_regex_error "") set(gp_regex_fallback "") set(gp_regex_cmp_count 3) diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake index c34b819..6ecdb9c 100644 --- a/Modules/InstallRequiredSystemLibraries.cmake +++ b/Modules/InstallRequiredSystemLibraries.cmake @@ -299,6 +299,7 @@ if(MSVC) foreach(crt "${MSVC_CRT_DIR}/msvcp${v}_1.dll" "${MSVC_CRT_DIR}/msvcp${v}_2.dll" + "${MSVC_CRT_DIR}/msvcp${v}_atomic_wait.dll" "${MSVC_CRT_DIR}/msvcp${v}_codecvt_ids.dll" "${MSVC_CRT_DIR}/vcruntime${v}_1.dll" ) @@ -327,6 +328,7 @@ if(MSVC) foreach(crt "${MSVC_CRT_DIR}/msvcp${v}_1d.dll" "${MSVC_CRT_DIR}/msvcp${v}_2d.dll" + "${MSVC_CRT_DIR}/msvcp${v}d_atomic_wait.dll" "${MSVC_CRT_DIR}/msvcp${v}d_codecvt_ids.dll" "${MSVC_CRT_DIR}/vcruntime${v}_1d.dll" ) diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake index 51e9e81..dc41572 100644 --- a/Modules/Platform/Windows-Clang.cmake +++ b/Modules/Platform/Windows-Clang.cmake @@ -71,6 +71,9 @@ macro(__windows_compiler_clang_gnu lang) set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>") + set(CMAKE_CREATE_WIN32_EXE "-Xlinker /subsystem:windows") + set(CMAKE_CREATE_CONSOLE_EXE "-Xlinker /subsystem:console") + if(NOT "${lang}" STREQUAL "ASM") set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmt) set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -D_DLL -D_MT -Xclang --dependent-lib=msvcrt) diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake index a5f8a08..120a54c 100644 --- a/Modules/UseJava.cmake +++ b/Modules/UseJava.cmake @@ -23,7 +23,8 @@ Creating And Installing JARs [VERSION <version>] [OUTPUT_NAME <name>] [OUTPUT_DIR <dir>] - [GENERATE_NATIVE_HEADERS <target> [DESTINATION <dir>]] + [GENERATE_NATIVE_HEADERS <target> + [DESTINATION (<dir>|INSTALL <dir> [BUILD <dir>])]] ) This command creates a ``<target_name>.jar``. It compiles the given @@ -37,7 +38,7 @@ For backwards compatibility, jar files listed as sources are ignored (as they have been since the first version of this module). .. versionadded:: 3.4 - Support fot response files (prefixed by ``@``) in the ``SOURCES`` list. + Support for response files (prefixed by ``@``) in the ``SOURCES`` list. The default ``OUTPUT_DIR`` can also be changed by setting the variable ``CMAKE_JAVA_TARGET_OUTPUT_DIR``. @@ -52,6 +53,12 @@ The default ``OUTPUT_DIR`` can also be changed by setting the variable ``GENERATE_NATIVE_HEADERS`` option requires, at least, version 1.8 of the JDK. +.. versionadded:: 3.20 + ``DESTINATION`` sub-option now supports the possibility to specify different + output directories for ``BUILD`` and ``INSTALL`` steps. This is required to + export the interface target generated by ``GENERATE_NATIVE_HEADERS`` option. + If ``BUILD`` directory is not specified, a default directory will be used. + The ``add_jar()`` function sets the following target properties on ``<target_name>``: @@ -66,6 +73,11 @@ The ``add_jar()`` function sets the following target properties on The directory where the class files can be found. For example to use them with ``javah``. +.. versionadded:: 3.20 + The target generated by option ``GENERATE_NATIVE_HEADERS`` has the property + ``NATIVE_HEADERS_DIRECTORY`` which specify the directory holding the native + headers. + .. code-block:: cmake install_jar(<target_name> <destination>) @@ -217,6 +229,18 @@ native headers can then be used to compile C/C++ sources with the add_library(bar bar.cpp) target_link_libraries(bar PRIVATE foo-native) +.. versionadded:: 3.20 + It is now possible to export the target generated by + ``GENERATE_NATIVE_HEADERS`` option. + + .. code-block:: cmake + + add_jar(foo foo.java GENERATE_NATIVE_HEADERS foo-native + DESTINATION INSTALL include) + install(TARGETS foo-native EXPORT native) + install(DIRECTORY "$<TARGET_PROPERTY:foo-native,NATIVE_HEADERS_DIRECTORY>/" + DESTINATION include) + install(EXPORT native DESTINATION /to/export NAMESPACE foo) Finding JARs ^^^^^^^^^^^^ @@ -493,7 +517,10 @@ function(add_jar _TARGET_NAME) if (Java_VERSION VERSION_LESS 1.8) message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS is not supported with this version of Java.") endif() - cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "DESTINATION" "" ${_add_jar_GENERATE_NATIVE_HEADERS}) + + unset (_GENERATE_NATIVE_HEADERS_OUTPUT_DESC) + + cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS "" "" "DESTINATION" ${_add_jar_GENERATE_NATIVE_HEADERS}) if (NOT _add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS) message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: missing required argument.") endif() @@ -504,11 +531,30 @@ function(add_jar _TARGET_NAME) endif() if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION) set (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers") + else() + list (LENGTH _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION length) + if (NOT length EQUAL 1) + cmake_parse_arguments (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "" "BUILD;INSTALL" "" "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}") + if (_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS) + message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: ${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_UNPARSED_ARGUMENTS}: unexpected argument(s).") + endif() + if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL) + message (FATAL_ERROR "ADD_JAR: GENERATE_NATIVE_HEADERS: DESTINATION: INSTALL sub-option is required.") + endif() + if (NOT _add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD) + set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir/native_headers") + endif() + set(_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}") + set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "$<BUILD_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_BUILD}>" "$<INSTALL_INTERFACE:${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION_INSTALL}>") + endif() endif() set (_GENERATE_NATIVE_HEADERS_TARGET ${_add_jar_GENERATE_NATIVE_HEADERS_UNPARSED_ARGUMENTS}) set (_GENERATE_NATIVE_HEADERS_OUTPUT_DIR "${_add_jar_GENERATE_NATIVE_HEADERS_DESTINATION}") set (_GENERATE_NATIVE_HEADERS -h "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") + if(NOT _GENERATE_NATIVE_HEADERS_OUTPUT_DESC) + set(_GENERATE_NATIVE_HEADERS_OUTPUT_DESC "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") + endif() endif() if (LIBRARY_OUTPUT_PATH) @@ -762,8 +808,9 @@ function(add_jar _TARGET_NAME) # create an INTERFACE library encapsulating include directory for generated headers add_library (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE) target_include_directories (${_GENERATE_NATIVE_HEADERS_TARGET} INTERFACE - "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}" + "${_GENERATE_NATIVE_HEADERS_OUTPUT_DESC}" ${JNI_INCLUDE_DIRS}) + set_property(TARGET ${_GENERATE_NATIVE_HEADERS_TARGET} PROPERTY NATIVE_HEADERS_DIRECTORY "${_GENERATE_NATIVE_HEADERS_OUTPUT_DIR}") # this INTERFACE library depends on jar generation add_dependencies (${_GENERATE_NATIVE_HEADERS_TARGET} ${_TARGET_NAME}) diff --git a/Modules/UseJava/javaTargets.cmake.in b/Modules/UseJava/javaTargets.cmake.in index c5f9c78..6e14256 100644 --- a/Modules/UseJava/javaTargets.cmake.in +++ b/Modules/UseJava/javaTargets.cmake.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) cmake_policy(PUSH) cmake_policy(VERSION 2.8) diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index c5b67c0..dca94ee 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -268,6 +268,8 @@ set(SRCS cmFileAPICodemodel.h cmFileAPICMakeFiles.cxx cmFileAPICMakeFiles.h + cmFileAPIToolchains.cxx + cmFileAPIToolchains.h cmFileCopier.cxx cmFileCopier.h cmFileInstaller.cxx diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 44fcb9b..d00e113 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 19) -set(CMake_VERSION_PATCH 20201230) +set(CMake_VERSION_PATCH 20210122) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 8e00ad6..359fc56 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -66,7 +66,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions() this->GetOption("CPACK_IFW_PACKAGE_PUBLISHER")) { this->Publisher = optIFW_PACKAGE_PUBLISHER; } else if (const char* optPACKAGE_VENDOR = - GetOption("CPACK_PACKAGE_VENDOR")) { + this->GetOption("CPACK_PACKAGE_VENDOR")) { this->Publisher = optPACKAGE_VENDOR; } @@ -204,7 +204,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions() this->GetOption("CPACK_IFW_PACKAGE_START_MENU_DIRECTORY")) { this->StartMenuDir = optIFW_START_MENU_DIR; } else { - this->StartMenuDir = Name; + this->StartMenuDir = this->Name; } // Default target directory for installation @@ -303,7 +303,7 @@ protected: void StartElement(const std::string& name, const char** /*atts*/) override { this->file = name == "file"; - if (file) { + if (this->file) { this->hasFiles = true; } } @@ -337,7 +337,7 @@ void cmCPackIFWInstaller::GenerateInstallerFile() xout.StartDocument(); - WriteGeneratedByToStrim(xout); + this->WriteGeneratedByToStrim(xout); xout.StartElement("Installer"); @@ -535,7 +535,7 @@ void cmCPackIFWInstaller::GeneratePackageFiles() package.ConfigureFromGroup(option); std::string forcedOption = "CPACK_IFW_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(option) + "_FORCED_INSTALLATION"; - if (!GetOption(forcedOption)) { + if (!this->GetOption(forcedOption)) { package.ForcedInstallation = "true"; } } else { diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index 56a74c5..c4bd7f1 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -337,7 +337,7 @@ int cmCPackIFWPackage::ConfigureFromGroup(const std::string& groupName) group.Name = groupName; - if (Generator) { + if (this->Generator) { this->Name = this->Generator->GetGroupPackageName(&group); } else { this->Name = group.Name; @@ -530,7 +530,7 @@ void cmCPackIFWPackage::GeneratePackageFile() xout.StartDocument(); - WriteGeneratedByToStrim(xout); + this->WriteGeneratedByToStrim(xout); xout.StartElement("Package"); @@ -577,7 +577,7 @@ void cmCPackIFWPackage::GeneratePackageFile() } // User Interfaces (copy to meta dir) - std::vector<std::string> userInterfaces = UserInterfaces; + std::vector<std::string> userInterfaces = this->UserInterfaces; for (std::string& userInterface : userInterfaces) { std::string name = cmSystemTools::GetFilenameName(userInterface); std::string path = this->Directory + "/meta/" + name; @@ -593,7 +593,7 @@ void cmCPackIFWPackage::GeneratePackageFile() } // Translations (copy to meta dir) - std::vector<std::string> translations = Translations; + std::vector<std::string> translations = this->Translations; for (std::string& translation : translations) { std::string name = cmSystemTools::GetFilenameName(translation); std::string path = this->Directory + "/meta/" + name; diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h index dbd5540..0cc6f2f 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.h +++ b/Source/CPack/IFW/cmCPackIFWPackage.h @@ -53,7 +53,7 @@ public: bool operator<(const DependenceStruct& other) const { - return Name < other.Name; + return this->Name < other.Name; } }; diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx index f5e8744..1287907 100644 --- a/Source/CPack/IFW/cmCPackIFWRepository.cxx +++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx @@ -46,9 +46,9 @@ bool cmCPackIFWRepository::ConfigureFromOptions() // Update if (this->IsOn(prefix + "ADD")) { this->Update = cmCPackIFWRepository::Add; - } else if (IsOn(prefix + "REMOVE")) { + } else if (this->IsOn(prefix + "REMOVE")) { this->Update = cmCPackIFWRepository::Remove; - } else if (IsOn(prefix + "REPLACE")) { + } else if (this->IsOn(prefix + "REPLACE")) { this->Update = cmCPackIFWRepository::Replace; } else { this->Update = cmCPackIFWRepository::None; @@ -247,7 +247,7 @@ void cmCPackIFWRepository::WriteRepositoryUpdate(cmXMLWriter& xout) if (this->Update == cmCPackIFWRepository::Add || this->Update == cmCPackIFWRepository::Remove) { xout.Attribute("url", this->Url); - } else if (Update == cmCPackIFWRepository::Replace) { + } else if (this->Update == cmCPackIFWRepository::Replace) { xout.Attribute("oldUrl", this->OldUrl); xout.Attribute("newUrl", this->NewUrl); } diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 967cc60..5348f86 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -80,10 +80,10 @@ std::string cmCPackArchiveGenerator::GetArchiveComponentFileName( packageFileName += this->GetOption("CPACK_ARCHIVE_" + componentUpper + "_FILE_NAME"); } else if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) { - packageFileName += GetComponentPackageFileName( + packageFileName += this->GetComponentPackageFileName( this->GetOption("CPACK_ARCHIVE_FILE_NAME"), component, isGroupName); } else { - packageFileName += GetComponentPackageFileName( + packageFileName += this->GetComponentPackageFileName( this->GetOption("CPACK_PACKAGE_FILE_NAME"), component, isGroupName); } @@ -181,7 +181,7 @@ int cmCPackArchiveGenerator::addOneComponentToArchive( int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) { - packageFileNames.clear(); + this->packageFileNames.clear(); // The default behavior is to have one package by component group // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. if (!ignoreGroup) { @@ -189,7 +189,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " << compG.first << std::endl); // Begin the archive for this group - std::string packageFileName = std::string(toplevel) + "/" + + std::string packageFileName = std::string(this->toplevel) + "/" + this->GetArchiveComponentFileName(compG.first, true); // open a block in order to automatically close archive @@ -199,11 +199,11 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) // now iterate over the component of this group for (cmCPackComponent* comp : (compG.second).Components) { // Add the files of this component to the archive - addOneComponentToArchive(archive, comp); + this->addOneComponentToArchive(archive, comp); } } // add the generated package to package file names list - packageFileNames.push_back(std::move(packageFileName)); + this->packageFileNames.push_back(std::move(packageFileName)); } // Handle Orphan components (components not belonging to any groups) for (auto& comp : this->Components) { @@ -217,7 +217,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) << std::endl); std::string localToplevel( this->GetOption("CPACK_TEMPORARY_DIRECTORY")); - std::string packageFileName = std::string(toplevel); + std::string packageFileName = std::string(this->toplevel); localToplevel += "/" + comp.first; packageFileName += @@ -226,10 +226,10 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) { DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive); // Add the files of this component to the archive - addOneComponentToArchive(archive, &(comp.second)); + this->addOneComponentToArchive(archive, &(comp.second)); } // add the generated package to package file names list - packageFileNames.push_back(std::move(packageFileName)); + this->packageFileNames.push_back(std::move(packageFileName)); } } } @@ -238,7 +238,7 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) else { for (auto& comp : this->Components) { std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); - std::string packageFileName = std::string(toplevel); + std::string packageFileName = std::string(this->toplevel); localToplevel += "/" + comp.first; packageFileName += @@ -247,10 +247,10 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) { DECLARE_AND_OPEN_ARCHIVE(packageFileName, archive); // Add the files of this component to the archive - addOneComponentToArchive(archive, &(comp.second)); + this->addOneComponentToArchive(archive, &(comp.second)); } // add the generated package to package file names list - packageFileNames.push_back(std::move(packageFileName)); + this->packageFileNames.push_back(std::move(packageFileName)); } } return 1; @@ -259,17 +259,17 @@ int cmCPackArchiveGenerator::PackageComponents(bool ignoreGroup) int cmCPackArchiveGenerator::PackageComponentsAllInOne() { // reset the package file names - packageFileNames.clear(); - packageFileNames.emplace_back(toplevel); - packageFileNames[0] += "/"; + this->packageFileNames.clear(); + this->packageFileNames.emplace_back(this->toplevel); + this->packageFileNames[0] += "/"; if (this->IsSet("CPACK_ARCHIVE_FILE_NAME")) { - packageFileNames[0] += this->GetOption("CPACK_ARCHIVE_FILE_NAME"); + this->packageFileNames[0] += this->GetOption("CPACK_ARCHIVE_FILE_NAME"); } else { - packageFileNames[0] += this->GetOption("CPACK_PACKAGE_FILE_NAME"); + this->packageFileNames[0] += this->GetOption("CPACK_PACKAGE_FILE_NAME"); } - packageFileNames[0] += this->GetOutputExtension(); + this->packageFileNames[0] += this->GetOutputExtension(); cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging all groups in one package..." @@ -280,7 +280,7 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne() // The ALL COMPONENTS in ONE package case for (auto& comp : this->Components) { // Add the files of this component to the archive - addOneComponentToArchive(archive, &(comp.second)); + this->addOneComponentToArchive(archive, &(comp.second)); } // archive goes out of scope so it will finalized and closed. @@ -289,41 +289,42 @@ int cmCPackArchiveGenerator::PackageComponentsAllInOne() int cmCPackArchiveGenerator::PackageFiles() { - cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Toplevel: " << this->toplevel << std::endl); - if (WantsComponentInstallation()) { + if (this->WantsComponentInstallation()) { // CASE 1 : COMPONENT ALL-IN-ONE package // If ALL COMPONENTS in ONE package has been requested // then the package file is unique and should be open here. - if (componentPackageMethod == ONE_PACKAGE) { - return PackageComponentsAllInOne(); + if (this->componentPackageMethod == ONE_PACKAGE) { + return this->PackageComponentsAllInOne(); } // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) // There will be 1 package for each component group // however one may require to ignore component group and // in this case you'll get 1 package for each component. - return PackageComponents(componentPackageMethod == - ONE_PACKAGE_PER_COMPONENT); + return this->PackageComponents(this->componentPackageMethod == + ONE_PACKAGE_PER_COMPONENT); } // CASE 3 : NON COMPONENT package. DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0], archive); - cmWorkingDirectory workdir(toplevel); + cmWorkingDirectory workdir(this->toplevel); if (workdir.Failed()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Failed to change working directory to " - << toplevel << " : " + << this->toplevel << " : " << std::strerror(workdir.GetLastResult()) << std::endl); return 0; } - for (std::string const& file : files) { + for (std::string const& file : this->files) { // Get the relative path to the file - std::string rp = cmSystemTools::RelativePath(toplevel, file); + std::string rp = cmSystemTools::RelativePath(this->toplevel, file); archive.Add(rp, 0, nullptr, false); if (!archive) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem while adding file <" - << file << "> to archive <" << packageFileNames[0] + << file << "> to archive <" << this->packageFileNames[0] << ">, ERROR = " << archive.GetError() << std::endl); return 0; } @@ -342,7 +343,7 @@ bool cmCPackArchiveGenerator::SupportsComponentInstallation() const // The Component installation support should only // be activated if explicitly requested by the user // (for backward compatibility reason) - return IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL"); + return this->IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL"); } bool cmCPackArchiveGenerator::SetArchiveOptions(cmArchiveWrite* archive) diff --git a/Source/CPack/cmCPackComponentGroup.cxx b/Source/CPack/cmCPackComponentGroup.cxx index d40e5fc..4305c7e 100644 --- a/Source/CPack/cmCPackComponentGroup.cxx +++ b/Source/CPack/cmCPackComponentGroup.cxx @@ -25,6 +25,6 @@ unsigned long cmCPackComponent::GetInstalledSize( unsigned long cmCPackComponent::GetInstalledSizeInKbytes( const std::string& installDir) const { - unsigned long result = (GetInstalledSize(installDir) + 512) / 1024; + unsigned long result = (this->GetInstalledSize(installDir) + 512) / 1024; return result ? result : 1; } diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 6f21d87..1220514 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -96,20 +96,20 @@ DebGenerator::DebGenerator( } if (!strcmp(debianCompressionType, "lzma")) { - CompressionSuffix = ".lzma"; - TarCompressionType = cmArchiveWrite::CompressLZMA; + this->CompressionSuffix = ".lzma"; + this->TarCompressionType = cmArchiveWrite::CompressLZMA; } else if (!strcmp(debianCompressionType, "xz")) { - CompressionSuffix = ".xz"; - TarCompressionType = cmArchiveWrite::CompressXZ; + this->CompressionSuffix = ".xz"; + this->TarCompressionType = cmArchiveWrite::CompressXZ; } else if (!strcmp(debianCompressionType, "bzip2")) { - CompressionSuffix = ".bz2"; - TarCompressionType = cmArchiveWrite::CompressBZip2; + this->CompressionSuffix = ".bz2"; + this->TarCompressionType = cmArchiveWrite::CompressBZip2; } else if (!strcmp(debianCompressionType, "gzip")) { - CompressionSuffix = ".gz"; - TarCompressionType = cmArchiveWrite::CompressGZip; + this->CompressionSuffix = ".gz"; + this->TarCompressionType = cmArchiveWrite::CompressGZip; } else if (!strcmp(debianCompressionType, "none")) { - CompressionSuffix.clear(); - TarCompressionType = cmArchiveWrite::CompressNone; + this->CompressionSuffix.clear(); + this->TarCompressionType = cmArchiveWrite::CompressNone; } else { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error unrecognized compression type: " @@ -119,22 +119,22 @@ DebGenerator::DebGenerator( bool DebGenerator::generate() const { - generateDebianBinaryFile(); - generateControlFile(); - if (!generateDataTar()) { + this->generateDebianBinaryFile(); + this->generateControlFile(); + if (!this->generateDataTar()) { return false; } - std::string md5Filename = generateMD5File(); - if (!generateControlTar(md5Filename)) { + std::string md5Filename = this->generateMD5File(); + if (!this->generateControlTar(md5Filename)) { return false; } - return generateDeb(); + return this->generateDeb(); } void DebGenerator::generateDebianBinaryFile() const { // debian-binary file - const std::string dbfilename = WorkDir + "/debian-binary"; + const std::string dbfilename = this->WorkDir + "/debian-binary"; cmGeneratedFileStream out; out.Open(dbfilename, false, true); out << "2.0\n"; // required for valid debian package @@ -142,18 +142,18 @@ void DebGenerator::generateDebianBinaryFile() const void DebGenerator::generateControlFile() const { - std::string ctlfilename = WorkDir + "/control"; + std::string ctlfilename = this->WorkDir + "/control"; cmGeneratedFileStream out; out.Open(ctlfilename, false, true); - for (auto const& kv : ControlValues) { + for (auto const& kv : this->ControlValues) { out << kv.first << ": " << kv.second << "\n"; } unsigned long totalSize = 0; { - std::string dirName = cmStrCat(TemporaryDir, '/'); - for (std::string const& file : PackageFiles) { + std::string dirName = cmStrCat(this->TemporaryDir, '/'); + for (std::string const& file : this->PackageFiles) { totalSize += cmSystemTools::FileLength(file); } } @@ -162,7 +162,8 @@ void DebGenerator::generateControlFile() const bool DebGenerator::generateDataTar() const { - std::string filename_data_tar = WorkDir + "/data.tar" + CompressionSuffix; + std::string filename_data_tar = + this->WorkDir + "/data.tar" + this->CompressionSuffix; cmGeneratedFileStream fileStream_data_tar; fileStream_data_tar.Open(filename_data_tar, false, true); if (!fileStream_data_tar) { @@ -171,8 +172,8 @@ bool DebGenerator::generateDataTar() const << filename_data_tar << "\" for writing" << std::endl); return false; } - cmArchiveWrite data_tar(fileStream_data_tar, TarCompressionType, - DebianArchiveType); + cmArchiveWrite data_tar(fileStream_data_tar, this->TarCompressionType, + this->DebianArchiveType); data_tar.Open(); // uid/gid should be the one of the root user, and this root user has @@ -184,16 +185,16 @@ bool DebGenerator::generateDataTar() const // collect all top level install dirs for that // e.g. /opt/bin/foo, /usr/bin/bar and /usr/bin/baz would // give /usr and /opt - size_t topLevelLength = WorkDir.length(); + size_t topLevelLength = this->WorkDir.length(); cmCPackLogger(cmCPackLog::LOG_DEBUG, - "WDIR: \"" << WorkDir << "\", length = " << topLevelLength - << std::endl); + "WDIR: \"" << this->WorkDir + << "\", length = " << topLevelLength << std::endl); std::set<std::string> orderedFiles; // we have to reconstruct the parent folders as well - for (std::string currentPath : PackageFiles) { - while (currentPath != WorkDir) { + for (std::string currentPath : this->PackageFiles) { + while (currentPath != this->WorkDir) { // the last one IS WorkDir, but we do not want this one: // XXX/application/usr/bin/myprogram with GEN_WDIR=XXX/application // should not add XXX/application @@ -235,7 +236,7 @@ bool DebGenerator::generateDataTar() const cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem adding file to tar:" << std::endl - << "#top level directory: " << WorkDir << std::endl + << "#top level directory: " << this->WorkDir << std::endl << "#file: " << file << std::endl << "#error:" << data_tar.GetError() << std::endl); return false; @@ -246,13 +247,13 @@ bool DebGenerator::generateDataTar() const std::string DebGenerator::generateMD5File() const { - std::string md5filename = WorkDir + "/md5sums"; + std::string md5filename = this->WorkDir + "/md5sums"; cmGeneratedFileStream out; out.Open(md5filename, false, true); - std::string topLevelWithTrailingSlash = cmStrCat(TemporaryDir, '/'); - for (std::string const& file : PackageFiles) { + std::string topLevelWithTrailingSlash = cmStrCat(this->TemporaryDir, '/'); + for (std::string const& file : this->PackageFiles) { // hash only regular files if (cmSystemTools::FileIsDirectory(file) || cmSystemTools::FileIsSymlink(file)) { @@ -281,7 +282,7 @@ std::string DebGenerator::generateMD5File() const bool DebGenerator::generateControlTar(std::string const& md5Filename) const { - std::string filename_control_tar = WorkDir + "/control.tar.gz"; + std::string filename_control_tar = this->WorkDir + "/control.tar.gz"; cmGeneratedFileStream fileStream_control_tar; fileStream_control_tar.Open(filename_control_tar, false, true); @@ -292,7 +293,8 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const return false; } cmArchiveWrite control_tar(fileStream_control_tar, - cmArchiveWrite::CompressGZip, DebianArchiveType); + cmArchiveWrite::CompressGZip, + this->DebianArchiveType); control_tar.Open(); // sets permissions and uid/gid for the files @@ -314,24 +316,25 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const control_tar.SetPermissions(permission644); // adds control and md5sums - if (!control_tar.Add(md5Filename, WorkDir.length(), ".") || - !control_tar.Add(WorkDir + "/control", WorkDir.length(), ".")) { + if (!control_tar.Add(md5Filename, this->WorkDir.length(), ".") || + !control_tar.Add(this->WorkDir + "/control", this->WorkDir.length(), + ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:" << std::endl - << "#top level directory: " << WorkDir << std::endl + << "#top level directory: " << this->WorkDir << std::endl << "#file: \"control\" or \"md5sums\"" << std::endl << "#error:" << control_tar.GetError() << std::endl); return false; } // adds generated shlibs file - if (GenShLibs) { - if (!control_tar.Add(ShLibsFilename, WorkDir.length(), ".")) { + if (this->GenShLibs) { + if (!control_tar.Add(this->ShLibsFilename, this->WorkDir.length(), ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:" << std::endl - << "#top level directory: " << WorkDir << std::endl + << "#top level directory: " << this->WorkDir << std::endl << "#file: \"shlibs\"" << std::endl << "#error:" << control_tar.GetError() << std::endl); return false; @@ -339,13 +342,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const } // adds LDCONFIG related files - if (GenPostInst) { + if (this->GenPostInst) { control_tar.SetPermissions(permission755); - if (!control_tar.Add(PostInst, WorkDir.length(), ".")) { + if (!control_tar.Add(this->PostInst, this->WorkDir.length(), ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:" << std::endl - << "#top level directory: " << WorkDir << std::endl + << "#top level directory: " << this->WorkDir << std::endl << "#file: \"postinst\"" << std::endl << "#error:" << control_tar.GetError() << std::endl); return false; @@ -353,13 +356,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const control_tar.SetPermissions(permission644); } - if (GenPostRm) { + if (this->GenPostRm) { control_tar.SetPermissions(permission755); - if (!control_tar.Add(PostRm, WorkDir.length(), ".")) { + if (!control_tar.Add(this->PostRm, this->WorkDir.length(), ".")) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error adding file to tar:" << std::endl - << "#top level directory: " << WorkDir << std::endl + << "#top level directory: " << this->WorkDir << std::endl << "#file: \"postinst\"" << std::endl << "#error:" << control_tar.GetError() << std::endl); return false; @@ -370,7 +373,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const // for the other files, we use // -either the original permission on the files // -either a permission strictly defined by the Debian policies - if (ControlExtra) { + if (this->ControlExtra) { // permissions are now controlled by the original file permissions static const char* strictFiles[] = { "config", "postinst", "postrm", @@ -381,19 +384,29 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const // default control_tar.ClearPermissions(); - std::vector<std::string> controlExtraList = cmExpandedList(ControlExtra); + std::vector<std::string> controlExtraList = + cmExpandedList(this->ControlExtra); for (std::string const& i : controlExtraList) { std::string filenamename = cmsys::SystemTools::GetFilenameName(i); - std::string localcopy = WorkDir + "/" + filenamename; + std::string localcopy = this->WorkDir + "/" + filenamename; - if (PermissionStrictPolicy) { + if (this->PermissionStrictPolicy) { control_tar.SetPermissions( setStrictFiles.count(filenamename) ? permission755 : permission644); } // if we can copy the file, it means it does exist, let's add it: + if (!cmsys::SystemTools::FileExists(i)) { + cmCPackLogger(cmCPackLog::LOG_WARNING, + "Adding file to tar:" << std::endl + << "#top level directory: " + << this->WorkDir << std::endl + << "#missing file: " << i + << std::endl); + } + if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) { - control_tar.Add(localcopy, WorkDir.length(), "."); + control_tar.Add(localcopy, this->WorkDir.length(), "."); } } } @@ -408,8 +421,8 @@ bool DebGenerator::generateDeb() const // difference is that debian uses the BSD ar style archive whereas most // Linux distro have a GNU ar. // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info - std::string const outputPath = TopLevelDir + "/" + OutputName; - std::string const tlDir = WorkDir + "/"; + std::string const outputPath = this->TopLevelDir + "/" + this->OutputName; + std::string const tlDir = this->WorkDir + "/"; cmGeneratedFileStream debStream; debStream.Open(outputPath, false, true); cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd"); @@ -422,12 +435,13 @@ bool DebGenerator::generateDeb() const if (!deb.Add(tlDir + "debian-binary", tlDir.length()) || !deb.Add(tlDir + "control.tar.gz", tlDir.length()) || - !deb.Add(tlDir + "data.tar" + CompressionSuffix, tlDir.length())) { + !deb.Add(tlDir + "data.tar" + this->CompressionSuffix, tlDir.length())) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error creating debian package:" << std::endl - << "#top level directory: " << TopLevelDir << std::endl - << "#file: " << OutputName << std::endl + << "#top level directory: " << this->TopLevelDir + << std::endl + << "#file: " << this->OutputName << std::endl << "#error:" << deb.GetError() << std::endl); return false; } @@ -455,7 +469,8 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, int retval = 1; // Begin the archive for this pack std::string localToplevel(initialTopLevel); - std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel)); + std::string packageFileName( + cmSystemTools::GetParentDirectory(this->toplevel)); std::string outputFileName( std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + "-" + packageName + this->GetOutputExtension()); @@ -495,17 +510,17 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, << std::endl); return 0; } - packageFiles = gl.GetFiles(); + this->packageFiles = gl.GetFiles(); } - int res = createDeb(); + int res = this->createDeb(); if (res != 1) { retval = 0; } // add the generated package to package file names list packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME")); - packageFileNames.push_back(std::move(packageFileName)); + this->packageFileNames.push_back(std::move(packageFileName)); if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") && this->GetOption("GEN_DBGSYMDIR")) { @@ -521,9 +536,9 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, << std::endl); return 0; } - packageFiles = gl.GetFiles(); + this->packageFiles = gl.GetFiles(); - res = createDbgsymDDeb(); + res = this->createDbgsymDDeb(); if (res != 1) { retval = 0; } @@ -531,7 +546,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel, packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME")); - packageFileNames.push_back(std::move(packageFileName)); + this->packageFileNames.push_back(std::move(packageFileName)); } return retval; @@ -542,7 +557,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup) int retval = 1; /* Reset package file name list it will be populated during the * component packaging run*/ - packageFileNames.clear(); + this->packageFileNames.clear(); std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); // The default behavior is to have one package by component group @@ -552,7 +567,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup) cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " << compG.first << std::endl); // Begin the archive for this group - retval &= PackageOnePack(initialTopLevel, compG.first); + retval &= this->PackageOnePack(initialTopLevel, compG.first); } // Handle Orphan components (components not belonging to any groups) for (auto const& comp : this->Components) { @@ -565,7 +580,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup) << "> does not belong to any group, package it separately." << std::endl); // Begin the archive for this orphan component - retval &= PackageOnePack(initialTopLevel, comp.first); + retval &= this->PackageOnePack(initialTopLevel, comp.first); } } } @@ -573,7 +588,7 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup) // We build 1 package per component else { for (auto const& comp : this->Components) { - retval &= PackageOnePack(initialTopLevel, comp.first); + retval &= this->PackageOnePack(initialTopLevel, comp.first); } } return retval; @@ -586,7 +601,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( int retval = 1; /* Reset package file name list it will be populated during the * component packaging run*/ - packageFileNames.clear(); + this->packageFileNames.clear(); std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); cmCPackLogger(cmCPackLog::LOG_VERBOSE, @@ -596,7 +611,8 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( // The ALL GROUPS in ONE package case std::string localToplevel(initialTopLevel); - std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel)); + std::string packageFileName( + cmSystemTools::GetParentDirectory(this->toplevel)); std::string outputFileName( std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + this->GetOutputExtension()); @@ -641,38 +657,38 @@ int cmCPackDebGenerator::PackageComponentsAllInOne( << std::endl); return 0; } - packageFiles = gl.GetFiles(); + this->packageFiles = gl.GetFiles(); - int res = createDeb(); + int res = this->createDeb(); if (res != 1) { retval = 0; } // add the generated package to package file names list packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/', this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME")); - packageFileNames.push_back(std::move(packageFileName)); + this->packageFileNames.push_back(std::move(packageFileName)); return retval; } int cmCPackDebGenerator::PackageFiles() { /* Are we in the component packaging case */ - if (WantsComponentInstallation()) { + if (this->WantsComponentInstallation()) { // CASE 1 : COMPONENT ALL-IN-ONE package // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested // then the package file is unique and should be open here. - if (componentPackageMethod == ONE_PACKAGE) { - return PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE"); + if (this->componentPackageMethod == ONE_PACKAGE) { + return this->PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE"); } // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) // There will be 1 package for each component group // however one may require to ignore component group and // in this case you'll get 1 package for each component. - return PackageComponents(componentPackageMethod == - ONE_PACKAGE_PER_COMPONENT); + return this->PackageComponents(this->componentPackageMethod == + ONE_PACKAGE_PER_COMPONENT); } // CASE 3 : NON COMPONENT package. - return PackageComponentsAllInOne(""); + return this->PackageComponentsAllInOne(""); } int cmCPackDebGenerator::createDeb() @@ -787,7 +803,7 @@ int cmCPackDebGenerator::createDeb() } DebGenerator gen( - Logger, this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"), strGenWDIR, + this->Logger, this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"), strGenWDIR, this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), this->GetOption("CPACK_TEMPORARY_DIRECTORY"), this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"), @@ -796,7 +812,7 @@ int cmCPackDebGenerator::createDeb() this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM"), postrm, this->GetOption("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA"), this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), - packageFiles); + this->packageFiles); if (!gen.generate()) { return 0; @@ -842,7 +858,7 @@ int cmCPackDebGenerator::createDbgsymDDeb() } DebGenerator gen( - Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"), + this->Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"), this->GetOption("GEN_DBGSYMDIR"), this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), @@ -851,7 +867,7 @@ int cmCPackDebGenerator::createDbgsymDDeb() this->GetOption("GEN_CPACK_DEBIAN_ARCHIVE_TYPE"), controlValues, false, "", false, "", false, "", nullptr, this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"), - packageFiles); + this->packageFiles); if (!gen.generate()) { return 0; @@ -861,25 +877,25 @@ int cmCPackDebGenerator::createDbgsymDDeb() bool cmCPackDebGenerator::SupportsComponentInstallation() const { - return IsOn("CPACK_DEB_COMPONENT_INSTALL"); + return this->IsOn("CPACK_DEB_COMPONENT_INSTALL"); } std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix( const std::string& componentName) { - if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) { + if (this->componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) { return componentName; } - if (componentPackageMethod == ONE_PACKAGE) { + if (this->componentPackageMethod == ONE_PACKAGE) { return std::string("ALL_COMPONENTS_IN_ONE"); } // We have to find the name of the COMPONENT GROUP // the current COMPONENT belongs to. std::string groupVar = "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP"; - if (nullptr != GetOption(groupVar)) { - return std::string(GetOption(groupVar)); + if (nullptr != this->GetOption(groupVar)) { + return std::string(this->GetOption(groupVar)); } return componentName; } diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx index 0bc8456..e3521a0 100644 --- a/Source/CPack/cmCPackExternalGenerator.cxx +++ b/Source/CPack/cmCPackExternalGenerator.cxx @@ -95,7 +95,7 @@ int cmCPackExternalGenerator::InstallProjectViaInstallCommands( bool setDestDir, const std::string& tempInstallDirectory) { if (this->StagingEnabled()) { - return cmCPackGenerator::InstallProjectViaInstallCommands( + return this->cmCPackGenerator::InstallProjectViaInstallCommands( setDestDir, tempInstallDirectory); } @@ -106,7 +106,7 @@ int cmCPackExternalGenerator::InstallProjectViaInstallScript( bool setDestDir, const std::string& tempInstallDirectory) { if (this->StagingEnabled()) { - return cmCPackGenerator::InstallProjectViaInstallScript( + return this->cmCPackGenerator::InstallProjectViaInstallScript( setDestDir, tempInstallDirectory); } @@ -118,7 +118,7 @@ int cmCPackExternalGenerator::InstallProjectViaInstalledDirectories( const mode_t* default_dir_mode) { if (this->StagingEnabled()) { - return cmCPackGenerator::InstallProjectViaInstalledDirectories( + return this->cmCPackGenerator::InstallProjectViaInstalledDirectories( setDestDir, tempInstallDirectory, default_dir_mode); } @@ -130,7 +130,7 @@ int cmCPackExternalGenerator::RunPreinstallTarget( cmGlobalGenerator* globalGenerator, const std::string& buildConfig) { if (this->StagingEnabled()) { - return cmCPackGenerator::RunPreinstallTarget( + return this->cmCPackGenerator::RunPreinstallTarget( installProjectName, installDirectory, globalGenerator, buildConfig); } @@ -145,7 +145,7 @@ int cmCPackExternalGenerator::InstallCMakeProject( std::string& absoluteDestFiles) { if (this->StagingEnabled()) { - return cmCPackGenerator::InstallCMakeProject( + return this->cmCPackGenerator::InstallCMakeProject( setDestDir, installDirectory, baseTempInstallDirectory, default_dir_mode, component, componentInstall, installSubDirectory, buildConfig, absoluteDestFiles); diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 8b544b4..3db4162 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -60,18 +60,18 @@ int cmCPackGenerator::PrepareNames() cmCPackLogger(cmCPackLog::LOG_DEBUG, "Create temp directory." << std::endl); // checks CPACK_SET_DESTDIR support - if (IsOn("CPACK_SET_DESTDIR")) { - if (SETDESTDIR_UNSUPPORTED == SupportsSetDestdir()) { + if (this->IsOn("CPACK_SET_DESTDIR")) { + if (SETDESTDIR_UNSUPPORTED == this->SupportsSetDestdir()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_SET_DESTDIR is set to ON but the '" - << Name << "' generator does NOT support it." + << this->Name << "' generator does NOT support it." << std::endl); return 0; } - if (SETDESTDIR_SHOULD_NOT_BE_USED == SupportsSetDestdir()) { + if (SETDESTDIR_SHOULD_NOT_BE_USED == this->SupportsSetDestdir()) { cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_SET_DESTDIR is set to ON but it is " - << "usually a bad idea to do that with '" << Name + << "usually a bad idea to do that with '" << this->Name << "' generator. Use at your own risk." << std::endl); } } @@ -380,8 +380,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories( << std::endl); return 0; } - files = gl.GetFiles(); - for (std::string const& gf : files) { + this->files = gl.GetFiles(); + for (std::string const& gf : this->files) { bool skip = false; std::string inFile = gf; if (cmSystemTools::FileIsDirectory(gf)) { @@ -763,7 +763,7 @@ int cmCPackGenerator::InstallCMakeProject( // one install directory for each component **GROUP** // instead of the default // one install directory for each component. - tempInstallDirectory += GetComponentInstallDirNameSuffix(component); + tempInstallDirectory += this->GetComponentInstallDirNameSuffix(component); if (this->IsOn("CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY")) { tempInstallDirectory += "/"; tempInstallDirectory += this->GetOption("CPACK_PACKAGE_FILE_NAME"); @@ -897,7 +897,7 @@ int cmCPackGenerator::InstallCMakeProject( // ABSOLUTE INSTALL DESTINATION or CPack has been asked for // then ask cmake_install.cmake script to error out // as soon as it occurs (before installing file) - if (!SupportsAbsoluteDestination() || + if (!this->SupportsAbsoluteDestination() || this->IsOn("CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION")) { mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1"); } @@ -933,7 +933,7 @@ int cmCPackGenerator::InstallCMakeProject( localFileName = cmSystemTools::RelativePath(InstallPrefix, *fit); localFileName = localFileName.substr(localFileName.find_first_not_of('/')); - Components[component].Files.push_back(localFileName); + this->Components[component].Files.push_back(localFileName); cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <" << localFileName << "> to component <" << component << ">" << std::endl); @@ -952,7 +952,7 @@ int cmCPackGenerator::InstallCMakeProject( if (componentInstall) { std::string absoluteDestFileComponent = std::string("CPACK_ABSOLUTE_DESTINATION_FILES") + "_" + - GetComponentInstallDirNameSuffix(component); + this->GetComponentInstallDirNameSuffix(component); if (nullptr != this->GetOption(absoluteDestFileComponent)) { std::string absoluteDestFilesListComponent = cmStrCat(this->GetOption(absoluteDestFileComponent), ';', *d); @@ -1073,17 +1073,17 @@ int cmCPackGenerator::DoPackage() } // The files to be installed - files = gl.GetFiles(); + this->files = gl.GetFiles(); - packageFileNames.clear(); + this->packageFileNames.clear(); /* Put at least one file name into the list of * wanted packageFileNames. The specific generator * may update this during PackageFiles. * (either putting several names or updating the provided one) */ - packageFileNames.emplace_back(tempPackageFileName ? tempPackageFileName - : ""); - toplevel = tempDirectory; + this->packageFileNames.emplace_back(tempPackageFileName ? tempPackageFileName + : ""); + this->toplevel = tempDirectory; { // scope that enables package generators to run internal scripts with // latest CMake policies enabled cmMakefile::ScopePushPop pp{ this->MakefileMap }; @@ -1127,10 +1127,10 @@ int cmCPackGenerator::DoPackage() * (because the specific generator did 'normalize' it) */ cmCPackLogger(cmCPackLog::LOG_VERBOSE, - "Copying final package(s) [" << packageFileNames.size() + "Copying final package(s) [" << this->packageFileNames.size() << "]:" << std::endl); /* now copy package one by one */ - for (std::string const& pkgFileName : packageFileNames) { + for (std::string const& pkgFileName : this->packageFileNames) { std::string tmpPF(this->GetOption("CPACK_OUTPUT_FILE_PREFIX")); std::string filename(cmSystemTools::GetFilenameName(pkgFileName)); tempPackageFileName = pkgFileName.c_str(); @@ -1211,7 +1211,7 @@ bool cmCPackGenerator::IsSet(const std::string& name) const bool cmCPackGenerator::IsOn(const std::string& name) const { - return cmIsOn(GetOption(name)); + return cmIsOn(this->GetOption(name)); } bool cmCPackGenerator::IsSetToOff(const std::string& op) const @@ -1405,7 +1405,7 @@ int cmCPackGenerator::PrepareGroupingKind() // fallback to default if not group based if (method == ONE_PACKAGE_PER_GROUP && this->ComponentGroups.empty() && !this->Components.empty()) { - if (componentPackageMethod == ONE_PACKAGE) { + if (this->componentPackageMethod == ONE_PACKAGE) { method = ONE_PACKAGE; } else { method = ONE_PACKAGE_PER_COMPONENT; @@ -1421,7 +1421,7 @@ int cmCPackGenerator::PrepareGroupingKind() // if user specified packaging method, override the default packaging // method if (method != UNKNOWN_COMPONENT_PACKAGE_METHOD) { - componentPackageMethod = method; + this->componentPackageMethod = method; } const char* method_names[] = { "ALL_COMPONENTS_IN_ONE", "IGNORE_GROUPS", @@ -1430,7 +1430,8 @@ int cmCPackGenerator::PrepareGroupingKind() cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" << this->Name << "]" << " requested component grouping = " - << method_names[componentPackageMethod] << std::endl); + << method_names[this->componentPackageMethod] + << std::endl); return 1; } @@ -1451,13 +1452,14 @@ std::string cmCPackGenerator::GetComponentPackageFileName( */ std::string suffix = "-" + groupOrComponentName; /* check if we should use DISPLAY name */ - std::string dispNameVar = "CPACK_" + Name + "_USE_DISPLAY_NAME_IN_FILENAME"; - if (IsOn(dispNameVar)) { + std::string dispNameVar = + "CPACK_" + this->Name + "_USE_DISPLAY_NAME_IN_FILENAME"; + if (this->IsOn(dispNameVar)) { /* the component Group case */ if (isGroupName) { std::string groupDispVar = "CPACK_COMPONENT_GROUP_" + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; - const char* groupDispName = GetOption(groupDispVar); + const char* groupDispName = this->GetOption(groupDispVar); if (groupDispName) { suffix = "-" + std::string(groupDispName); } @@ -1466,7 +1468,7 @@ std::string cmCPackGenerator::GetComponentPackageFileName( else { std::string dispVar = "CPACK_COMPONENT_" + cmSystemTools::UpperCase(groupOrComponentName) + "_DISPLAY_NAME"; - const char* dispName = GetOption(dispVar); + const char* dispName = this->GetOption(dispVar); if (dispName) { suffix = "-" + std::string(dispName); } @@ -1493,8 +1495,8 @@ bool cmCPackGenerator::SupportsComponentInstallation() const bool cmCPackGenerator::WantsComponentInstallation() const { - return (!IsOn("CPACK_MONOLITHIC_INSTALL") && - SupportsComponentInstallation() + return (!this->IsOn("CPACK_MONOLITHIC_INSTALL") && + this->SupportsComponentInstallation() // check that we have at least one group or component && (!this->ComponentGroups.empty() || !this->Components.empty())); } @@ -1557,7 +1559,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent( const char* groupName = this->GetOption(macroPrefix + "_GROUP"); if (cmNonempty(groupName)) { - component->Group = GetComponentGroup(projectName, groupName); + component->Group = this->GetComponentGroup(projectName, groupName); component->Group->Components.push_back(component); } else { component->Group = nullptr; @@ -1584,7 +1586,7 @@ cmCPackComponent* cmCPackGenerator::GetComponent( if (cmNonempty(depends)) { std::vector<std::string> dependsVector = cmExpandedList(depends); for (std::string const& depend : dependsVector) { - cmCPackComponent* child = GetComponent(projectName, depend); + cmCPackComponent* child = this->GetComponent(projectName, depend); component->Dependencies.push_back(child); child->ReverseDependencies.push_back(component); } @@ -1620,7 +1622,8 @@ cmCPackComponentGroup* cmCPackGenerator::GetComponentGroup( const char* parentGroupName = this->GetOption(macroPrefix + "_PARENT_GROUP"); if (cmNonempty(parentGroupName)) { - group->ParentGroup = GetComponentGroup(projectName, parentGroupName); + group->ParentGroup = + this->GetComponentGroup(projectName, parentGroupName); group->ParentGroup->Subgroups.push_back(group); } else { group->ParentGroup = nullptr; diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index 2109b4e..435f0ec 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -31,7 +31,7 @@ cmCPackNSISGenerator::cmCPackNSISGenerator(bool nsis64) { - Nsis64 = nsis64; + this->Nsis64 = nsis64; } cmCPackNSISGenerator::~cmCPackNSISGenerator() = default; @@ -61,18 +61,18 @@ int cmCPackNSISGenerator::PackageFiles() std::string nsisInstallOptions = nsisFileName + "/NSIS.InstallOptions.ini"; nsisFileName += "/project.nsi"; std::ostringstream str; - for (std::string const& file : files) { + for (std::string const& file : this->files) { std::string outputDir = "$INSTDIR"; - std::string fileN = cmSystemTools::RelativePath(toplevel, file); + std::string fileN = cmSystemTools::RelativePath(this->toplevel, file); if (!this->Components.empty()) { const std::string::size_type pos = fileN.find('/'); // Use the custom component install directory if we have one if (pos != std::string::npos) { auto componentName = cm::string_view(fileN).substr(0, pos); - outputDir = CustomComponentInstallDirectory(componentName); + outputDir = this->CustomComponentInstallDirectory(componentName); } else { - outputDir = CustomComponentInstallDirectory(fileN); + outputDir = this->CustomComponentInstallDirectory(fileN); } // Strip off the component part of the path. @@ -86,15 +86,15 @@ int cmCPackNSISGenerator::PackageFiles() "Uninstall Files: " << str.str() << std::endl); this->SetOptionIfNotSet("CPACK_NSIS_DELETE_FILES", str.str().c_str()); std::vector<std::string> dirs; - this->GetListOfSubdirectories(toplevel.c_str(), dirs); + this->GetListOfSubdirectories(this->toplevel.c_str(), dirs); std::ostringstream dstr; for (std::string const& dir : dirs) { std::string componentName; - std::string fileN = cmSystemTools::RelativePath(toplevel, dir); + std::string fileN = cmSystemTools::RelativePath(this->toplevel, dir); if (fileN.empty()) { continue; } - if (!Components.empty()) { + if (!this->Components.empty()) { // If this is a component installation, strip off the component // part of the path. std::string::size_type slash = fileN.find('/'); @@ -110,7 +110,7 @@ int cmCPackNSISGenerator::PackageFiles() std::replace(fileN.begin(), fileN.end(), '/', '\\'); const std::string componentOutputDir = - CustomComponentInstallDirectory(componentName); + this->CustomComponentInstallDirectory(componentName); dstr << " RMDir \"" << componentOutputDir << "\\" << fileN << "\"" << std::endl; @@ -677,7 +677,7 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( } const std::string componentOutputDir = - CustomComponentInstallDirectory(component->Name); + this->CustomComponentInstallDirectory(component->Name); componentCode += cmStrCat(" SetOutPath \"", componentOutputDir, "\"\n"); // Create the actual installation commands @@ -833,14 +833,16 @@ std::string cmCPackNSISGenerator::CreateComponentDescription( // depends on. std::set<cmCPackComponent*> visited; macrosOut << "!macro Select_" << component->Name << "_depends\n"; - macrosOut << CreateSelectionDependenciesDescription(component, visited); + macrosOut << this->CreateSelectionDependenciesDescription(component, + visited); macrosOut << "!macroend\n"; // Macro used to deselect each of the components that depend on this // component. visited.clear(); macrosOut << "!macro Deselect_required_by_" << component->Name << "\n"; - macrosOut << CreateDeselectionDependenciesDescription(component, visited); + macrosOut << this->CreateDeselectionDependenciesDescription(component, + visited); macrosOut << "!macroend\n"; return componentCode; } @@ -862,7 +864,8 @@ std::string cmCPackNSISGenerator::CreateSelectionDependenciesDescription( out << " SectionSetFlags ${" << depend->Name << "} $0\n"; out << " IntOp $" << depend->Name << "_selected 0 + ${SF_SELECTED}\n"; // Recurse - out << CreateSelectionDependenciesDescription(depend, visited).c_str(); + out + << this->CreateSelectionDependenciesDescription(depend, visited).c_str(); } return out.str(); @@ -887,7 +890,8 @@ std::string cmCPackNSISGenerator::CreateDeselectionDependenciesDescription( out << " IntOp $" << depend->Name << "_selected 0 + 0\n"; // Recurse - out << CreateDeselectionDependenciesDescription(depend, visited).c_str(); + out << this->CreateDeselectionDependenciesDescription(depend, visited) + .c_str(); } return out.str(); diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx index 60faecd..98dc890 100644 --- a/Source/CPack/cmCPackNuGetGenerator.cxx +++ b/Source/CPack/cmCPackNuGetGenerator.cxx @@ -17,32 +17,33 @@ bool cmCPackNuGetGenerator::SupportsComponentInstallation() const { - return IsOn("CPACK_NUGET_COMPONENT_INSTALL"); + return this->IsOn("CPACK_NUGET_COMPONENT_INSTALL"); } int cmCPackNuGetGenerator::PackageFiles() { - cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Toplevel: " << this->toplevel << std::endl); /* Reset package file name list it will be populated after the * `CPackNuGet.cmake` run */ - packageFileNames.clear(); + this->packageFileNames.clear(); /* Are we in the component packaging case */ - if (WantsComponentInstallation()) { - if (componentPackageMethod == ONE_PACKAGE) { + if (this->WantsComponentInstallation()) { + if (this->componentPackageMethod == ONE_PACKAGE) { // CASE 1 : COMPONENT ALL-IN-ONE package // Meaning that all per-component pre-installed files // goes into the single package. this->SetOption("CPACK_NUGET_ALL_IN_ONE", "TRUE"); - SetupGroupComponentVariables(true); + this->SetupGroupComponentVariables(true); } else { // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) // There will be 1 package for each component group // however one may require to ignore component group and // in this case you'll get 1 package for each component. - SetupGroupComponentVariables(componentPackageMethod == - ONE_PACKAGE_PER_COMPONENT); + this->SetupGroupComponentVariables(this->componentPackageMethod == + ONE_PACKAGE_PER_COMPONENT); } } else { // CASE 3 : NON COMPONENT package. @@ -51,7 +52,7 @@ int cmCPackNuGetGenerator::PackageFiles() auto retval = this->ReadListFile("Internal/CPack/CPackNuGet.cmake"); if (retval) { - AddGeneratedPackageNames(); + this->AddGeneratedPackageNames(); } else { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackNuGet.cmake" << std::endl); @@ -133,9 +134,9 @@ void cmCPackNuGetGenerator::AddGeneratedPackageNames() std::string::size_type pos1 = 0; std::string::size_type pos2 = fileNames.find(sep, pos1 + 1); while (pos2 != std::string::npos) { - packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); + this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); pos1 = pos2 + 1; pos2 = fileNames.find(sep, pos1 + 1); } - packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); + this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); } diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 0c1cecf..c3f6d59 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -51,11 +51,11 @@ void cmCPackRPMGenerator::AddGeneratedPackageNames() std::string::size_type pos1 = 0; std::string::size_type pos2 = fileNames.find(sep, pos1 + 1); while (pos2 != std::string::npos) { - packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); + this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); pos1 = pos2 + 1; pos2 = fileNames.find(sep, pos1 + 1); } - packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); + this->packageFileNames.push_back(fileNames.substr(pos1, pos2 - pos1)); } int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel, @@ -64,10 +64,11 @@ int cmCPackRPMGenerator::PackageOnePack(std::string const& initialToplevel, int retval = 1; // Begin the archive for this pack std::string localToplevel(initialToplevel); - std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel)); + std::string packageFileName( + cmSystemTools::GetParentDirectory(this->toplevel)); std::string outputFileName( - GetComponentPackageFileName(this->GetOption("CPACK_PACKAGE_FILE_NAME"), - packageName, true) + + this->GetComponentPackageFileName( + this->GetOption("CPACK_PACKAGE_FILE_NAME"), packageName, true) + this->GetOutputExtension()); localToplevel += "/" + packageName; @@ -99,7 +100,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) int retval = 1; /* Reset package file name list it will be populated during the * component packaging run*/ - packageFileNames.clear(); + this->packageFileNames.clear(); std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); const char* mainComponent = this->GetOption("CPACK_RPM_MAIN_COMPONENT"); @@ -202,7 +203,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " << compGIt->first << std::endl); - retval &= PackageOnePack(initialTopLevel, compGIt->first); + retval &= this->PackageOnePack(initialTopLevel, compGIt->first); } // Handle Orphan components (components not belonging to any groups) auto mainCompIt = this->Components.end(); @@ -227,7 +228,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) << compIt->second.Name << "> does not belong to any group, package it separately." << std::endl); - retval &= PackageOnePack(initialTopLevel, compIt->first); + retval &= this->PackageOnePack(initialTopLevel, compIt->first); } } @@ -235,9 +236,9 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) this->SetOption("GENERATE_SPEC_PARTS", "OFF"); if (mainCompGIt != this->ComponentGroups.end()) { - retval &= PackageOnePack(initialTopLevel, mainCompGIt->first); + retval &= this->PackageOnePack(initialTopLevel, mainCompGIt->first); } else if (mainCompIt != this->Components.end()) { - retval &= PackageOnePack(initialTopLevel, mainCompIt->first); + retval &= this->PackageOnePack(initialTopLevel, mainCompIt->first); } else { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT set" @@ -264,14 +265,14 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) continue; } - retval &= PackageOnePack(initialTopLevel, compIt->first); + retval &= this->PackageOnePack(initialTopLevel, compIt->first); } if (retval) { this->SetOption("GENERATE_SPEC_PARTS", "OFF"); if (mainCompIt != this->Components.end()) { - retval &= PackageOnePack(initialTopLevel, mainCompIt->first); + retval &= this->PackageOnePack(initialTopLevel, mainCompIt->first); } else { cmCPackLogger(cmCPackLog::LOG_ERROR, "CPACK_RPM_MAIN_COMPONENT set" @@ -291,7 +292,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " << compGIt->first << std::endl); - retval &= PackageOnePack(initialTopLevel, compGIt->first); + retval &= this->PackageOnePack(initialTopLevel, compGIt->first); } // Handle Orphan components (components not belonging to any groups) std::map<std::string, cmCPackComponent>::iterator compIt; @@ -305,7 +306,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) << compIt->second.Name << "> does not belong to any group, package it separately." << std::endl); - retval &= PackageOnePack(initialTopLevel, compIt->first); + retval &= this->PackageOnePack(initialTopLevel, compIt->first); } } } @@ -315,7 +316,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) std::map<std::string, cmCPackComponent>::iterator compIt; for (compIt = this->Components.begin(); compIt != this->Components.end(); ++compIt) { - retval &= PackageOnePack(initialTopLevel, compIt->first); + retval &= this->PackageOnePack(initialTopLevel, compIt->first); } } } else { @@ -328,7 +329,7 @@ int cmCPackRPMGenerator::PackageComponents(bool ignoreGroup) } if (retval) { - AddGeneratedPackageNames(); + this->AddGeneratedPackageNames(); } return retval; @@ -340,7 +341,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne( int retval = 1; /* Reset package file name list it will be populated during the * component packaging run*/ - packageFileNames.clear(); + this->packageFileNames.clear(); std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); if (this->IsOn("CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE")) { @@ -354,7 +355,8 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne( // The ALL GROUPS in ONE package case std::string localToplevel(initialTopLevel); - std::string packageFileName(cmSystemTools::GetParentDirectory(toplevel)); + std::string packageFileName( + cmSystemTools::GetParentDirectory(this->toplevel)); std::string outputFileName( std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME")) + this->GetOutputExtension()); @@ -378,7 +380,7 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne( } if (this->ReadListFile("Internal/CPack/CPackRPM.cmake")) { - AddGeneratedPackageNames(); + this->AddGeneratedPackageNames(); } else { cmCPackLogger(cmCPackLog::LOG_ERROR, "Error while execution CPackRPM.cmake" << std::endl); @@ -390,48 +392,49 @@ int cmCPackRPMGenerator::PackageComponentsAllInOne( int cmCPackRPMGenerator::PackageFiles() { - cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Toplevel: " << this->toplevel << std::endl); /* Are we in the component packaging case */ - if (WantsComponentInstallation()) { + if (this->WantsComponentInstallation()) { // CASE 1 : COMPONENT ALL-IN-ONE package // If ALL COMPONENTS in ONE package has been requested // then the package file is unique and should be open here. - if (componentPackageMethod == ONE_PACKAGE) { - return PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE"); + if (this->componentPackageMethod == ONE_PACKAGE) { + return this->PackageComponentsAllInOne("ALL_COMPONENTS_IN_ONE"); } // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) // There will be 1 package for each component group // however one may require to ignore component group and // in this case you'll get 1 package for each component. - return PackageComponents(componentPackageMethod == - ONE_PACKAGE_PER_COMPONENT); + return this->PackageComponents(this->componentPackageMethod == + ONE_PACKAGE_PER_COMPONENT); } // CASE 3 : NON COMPONENT package. - return PackageComponentsAllInOne(""); + return this->PackageComponentsAllInOne(""); } bool cmCPackRPMGenerator::SupportsComponentInstallation() const { - return IsOn("CPACK_RPM_COMPONENT_INSTALL"); + return this->IsOn("CPACK_RPM_COMPONENT_INSTALL"); } std::string cmCPackRPMGenerator::GetComponentInstallDirNameSuffix( const std::string& componentName) { - if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) { + if (this->componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) { return componentName; } - if (componentPackageMethod == ONE_PACKAGE) { + if (this->componentPackageMethod == ONE_PACKAGE) { return std::string("ALL_COMPONENTS_IN_ONE"); } // We have to find the name of the COMPONENT GROUP // the current COMPONENT belongs to. std::string groupVar = "CPACK_COMPONENT_" + cmSystemTools::UpperCase(componentName) + "_GROUP"; - if (nullptr != GetOption(groupVar)) { - return std::string(GetOption(groupVar)); + if (nullptr != this->GetOption(groupVar)) { + return std::string(this->GetOption(groupVar)); } return componentName; } diff --git a/Source/CPack/cmCPackSTGZGenerator.cxx b/Source/CPack/cmCPackSTGZGenerator.cxx index a4a5e6f..3e36e8c 100644 --- a/Source/CPack/cmCPackSTGZGenerator.cxx +++ b/Source/CPack/cmCPackSTGZGenerator.cxx @@ -50,7 +50,7 @@ int cmCPackSTGZGenerator::PackageFiles() * have generated several packages (component packaging) * so we must iterate over generated packages. */ - for (std::string const& pfn : packageFileNames) { + for (std::string const& pfn : this->packageFileNames) { retval &= cmSystemTools::SetPermissions(pfn.c_str(), #if defined(_MSC_VER) || defined(__MINGW32__) S_IREAD | S_IWRITE | S_IEXEC diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx index c533cd7..a353435 100644 --- a/Source/CTest/cmCTestBZR.cxx +++ b/Source/CTest/cmCTestBZR.cxx @@ -104,8 +104,8 @@ private: { if (this->RegexCheckOut.find(this->Line)) { this->BZR->URL = this->RegexCheckOut.match(1); - CheckOutFound = true; - } else if (!CheckOutFound && this->RegexParent.find(this->Line)) { + this->CheckOutFound = true; + } else if (!this->CheckOutFound && this->RegexParent.find(this->Line)) { this->BZR->URL = this->RegexParent.match(1); } return true; @@ -191,7 +191,7 @@ public: int InitializeParser() override { - int res = cmXMLParser::InitializeParser(); + int res = this->cmXMLParser::InitializeParser(); if (res) { XML_SetUnknownEncodingHandler(static_cast<XML_Parser>(this->Parser), cmBZRXMLParserUnknownEncodingHandler, diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 4151fde..88e2871 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -137,7 +137,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() bool cmCTestBuildCommand::InitialPass(std::vector<std::string> const& args, cmExecutionStatus& status) { - bool ret = cmCTestHandlerCommand::InitialPass(args, status); + bool ret = this->cmCTestHandlerCommand::InitialPass(args, status); if (!this->NumberErrors.empty()) { this->Makefile->AddDefinition( this->NumberErrors, std::to_string(this->Handler->GetTotalErrors())); diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 093b2d1..5fb52bf 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -778,16 +778,16 @@ struct cmCTestCoverageHandlerLocale { std::string l; if (cmSystemTools::GetEnv("LC_ALL", l)) { - lc_all = l; + this->lc_all = l; } - if (lc_all != "C") { + if (this->lc_all != "C") { cmSystemTools::PutEnv("LC_ALL=C"); } } ~cmCTestCoverageHandlerLocale() { - if (!lc_all.empty()) { - cmSystemTools::PutEnv("LC_ALL=" + lc_all); + if (!this->lc_all.empty()) { + cmSystemTools::PutEnv("LC_ALL=" + this->lc_all); } else { cmSystemTools::UnsetEnv("LC_ALL"); } diff --git a/Source/CTest/cmCTestLaunchReporter.cxx b/Source/CTest/cmCTestLaunchReporter.cxx index 6ec7d0e..f89fc9b 100644 --- a/Source/CTest/cmCTestLaunchReporter.cxx +++ b/Source/CTest/cmCTestLaunchReporter.cxx @@ -284,7 +284,7 @@ void cmCTestLaunchReporter::DumpFileToXML(cmXMLElement& e3, const char* tag, cmXMLElement e4(e3, tag); while (cmSystemTools::GetLineFromStream(fin, line)) { - if (MatchesFilterPrefix(line)) { + if (this->MatchesFilterPrefix(line)) { continue; } if (this->Match(line, this->RegexWarningSuppress)) { diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 8a30dc0..6e8091b 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -1364,9 +1364,15 @@ void cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res, } } if (this->LogWithPID) { - cmSystemTools::RemoveFile(ofile); - cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, - "Remove: " << ofile << "\n", this->Quiet); + auto pos = ofile.find_last_of('.'); + if (pos != std::string::npos) { + auto ofileWithoutPid = ofile.substr(0, pos); + cmSystemTools::RenameFile(ofile, ofileWithoutPid); + cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT, + "Renaming: " << ofile << " to: " << ofileWithoutPid + << "\n", + this->Quiet); + } } } diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index a08cb34..9793c5b 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -56,8 +56,8 @@ public: // Sorts tests in descending order of cost bool operator()(int index1, int index2) const { - return Handler->Properties[index1]->Cost > - Handler->Properties[index2]->Cost; + return this->Handler->Properties[index1]->Cost > + this->Handler->Properties[index2]->Cost; } private: @@ -169,7 +169,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test) this->TestRunningMap[test] = true; // mark the test as running // now remove the test itself this->EraseTest(test); - this->RunningCount += GetProcessorsUsed(test); + this->RunningCount += this->GetProcessorsUsed(test); auto testRun = cm::make_unique<cmCTestRunTest>(*this); @@ -552,12 +552,12 @@ void cmCTestMultiProcessHandler::StartNextTests() continue; } - size_t processors = GetProcessorsUsed(test); + size_t processors = this->GetProcessorsUsed(test); bool testLoadOk = true; if (this->TestLoad > 0) { if (processors <= spareLoad) { cmCTestLog(this->CTest, DEBUG, - "OK to run " << GetName(test) << ", it requires " + "OK to run " << this->GetName(test) << ", it requires " << processors << " procs & system load is: " << systemLoad << std::endl); allTestsFailedTestLoadCheck = false; @@ -568,7 +568,7 @@ void cmCTestMultiProcessHandler::StartNextTests() if (processors <= minProcessorsRequired) { minProcessorsRequired = processors; - testWithMinProcessors = GetName(test); + testWithMinProcessors = this->GetName(test); } if (testLoadOk && processors <= numToStart && this->StartTest(test)) { @@ -660,7 +660,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess( this->WriteCheckpoint(test); this->DeallocateResources(test); this->UnlockResources(test); - this->RunningCount -= GetProcessorsUsed(test); + this->RunningCount -= this->GetProcessorsUsed(test); for (auto p : properties->Affinity) { this->ProcessorsAvailable.insert(p); @@ -793,9 +793,9 @@ int cmCTestMultiProcessHandler::SearchByName(std::string const& name) void cmCTestMultiProcessHandler::CreateTestCostList() { if (this->ParallelLevel > 1) { - CreateParallelTestCostList(); + this->CreateParallelTestCostList(); } else { - CreateSerialTestCostList(); + this->CreateSerialTestCostList(); } } @@ -862,7 +862,7 @@ void cmCTestMultiProcessHandler::GetAllTestDependencies(int test, { TestSet const& dependencySet = this->Tests[test]; for (int i : dependencySet) { - GetAllTestDependencies(i, dependencies); + this->GetAllTestDependencies(i, dependencies); dependencies.push_back(i); } } @@ -886,7 +886,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList() } TestList dependencies; - GetAllTestDependencies(test, dependencies); + this->GetAllTestDependencies(test, dependencies); for (int testDependency : dependencies) { if (!cm::contains(alreadySortedTests, testDependency)) { @@ -1274,7 +1274,7 @@ void cmCTestMultiProcessHandler::PrintOutputAsJson() void cmCTestMultiProcessHandler::PrintTestList() { if (this->CTest->GetOutputAsJson()) { - PrintOutputAsJson(); + this->PrintOutputAsJson(); return; } diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx index 1375be4..50c9c16 100644 --- a/Source/CTest/cmCTestP4.cxx +++ b/Source/CTest/cmCTestP4.cxx @@ -56,7 +56,7 @@ public: ChangesParser(cmCTestP4* p4, const char* prefix) : P4(p4) { - this->SetLog(&P4->Log, prefix); + this->SetLog(&this->P4->Log, prefix); this->RegexIdentify.compile("^Change ([0-9]+) on"); } @@ -67,7 +67,7 @@ private: bool ProcessLine() override { if (this->RegexIdentify.find(this->Line)) { - P4->ChangeLists.push_back(this->RegexIdentify.match(1)); + this->P4->ChangeLists.push_back(this->RegexIdentify.match(1)); } return true; } @@ -79,7 +79,7 @@ public: UserParser(cmCTestP4* p4, const char* prefix) : P4(p4) { - this->SetLog(&P4->Log, prefix); + this->SetLog(&this->P4->Log, prefix); this->RegexUser.compile("^(.+) <(.*)> \\((.*)\\) accessed (.*)$"); } @@ -96,7 +96,7 @@ private: NewUser.EMail = this->RegexUser.match(2); NewUser.Name = this->RegexUser.match(3); NewUser.AccessTime = this->RegexUser.match(4); - P4->Users[this->RegexUser.match(1)] = NewUser; + this->P4->Users[this->RegexUser.match(1)] = NewUser; return false; } @@ -120,7 +120,7 @@ public: : P4(p4) , AlreadyNotified(false) { - this->SetLog(&P4->Log, prefix); + this->SetLog(&this->P4->Log, prefix); this->RegexDiff.compile("^==== (.*)#[0-9]+ - (.*)"); } @@ -134,12 +134,12 @@ private: { if (!this->Line.empty() && this->Line[0] == '=' && this->RegexDiff.find(this->Line)) { - CurrentPath = this->RegexDiff.match(1); - AlreadyNotified = false; + this->CurrentPath = this->RegexDiff.match(1); + this->AlreadyNotified = false; } else { - if (!AlreadyNotified) { - P4->DoModification(PathModified, CurrentPath); - AlreadyNotified = true; + if (!this->AlreadyNotified) { + this->P4->DoModification(PathModified, this->CurrentPath); + this->AlreadyNotified = true; } } return true; @@ -148,11 +148,11 @@ private: cmCTestP4::User cmCTestP4::GetUserData(const std::string& username) { - auto it = Users.find(username); + auto it = this->Users.find(username); - if (it == Users.end()) { + if (it == this->Users.end()) { std::vector<char const*> p4_users; - SetP4Options(p4_users); + this->SetP4Options(p4_users); p4_users.push_back("users"); p4_users.push_back("-m"); p4_users.push_back("1"); @@ -161,11 +161,11 @@ cmCTestP4::User cmCTestP4::GetUserData(const std::string& username) UserParser out(this, "users-out> "); OutputLogger err(this->Log, "users-err> "); - RunChild(&p4_users[0], &out, &err); + this->RunChild(&p4_users[0], &out, &err); // The user should now be added to the map. Search again. - it = Users.find(username); - if (it == Users.end()) { + it = this->Users.find(username); + if (it == this->Users.end()) { return cmCTestP4::User(); } } @@ -195,7 +195,7 @@ public: , P4(p4) , Section(SectionHeader) { - this->SetLog(&P4->Log, prefix); + this->SetLog(&this->P4->Log, prefix); this->RegexHeader.compile("^Change ([0-9]+) by (.+)@(.+) on (.*)$"); this->RegexDiff.compile(R"(^\.\.\. (.*)#[0-9]+ ([^ ]+)$)"); } @@ -259,7 +259,7 @@ private: this->Rev.Rev = this->RegexHeader.match(1); this->Rev.Date = this->RegexHeader.match(4); - cmCTestP4::User user = P4->GetUserData(this->RegexHeader.match(2)); + cmCTestP4::User user = this->P4->GetUserData(this->RegexHeader.match(2)); this->Rev.Author = user.Name; this->Rev.EMail = user.EMail; @@ -300,38 +300,38 @@ private: change.Action = 'M'; } - Changes.push_back(change); + this->Changes.push_back(change); } } }; void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions) { - if (P4Options.empty()) { + if (this->P4Options.empty()) { const char* p4 = this->CommandLineTool.c_str(); - P4Options.emplace_back(p4); + this->P4Options.emplace_back(p4); // The CTEST_P4_CLIENT variable sets the P4 client used when issuing // Perforce commands, if it's different from the default one. std::string client = this->CTest->GetCTestConfiguration("P4Client"); if (!client.empty()) { - P4Options.emplace_back("-c"); - P4Options.push_back(client); + this->P4Options.emplace_back("-c"); + this->P4Options.push_back(client); } // Set the message language to be English, in case the P4 admin // has localized them - P4Options.emplace_back("-L"); - P4Options.emplace_back("en"); + this->P4Options.emplace_back("-L"); + this->P4Options.emplace_back("en"); // The CTEST_P4_OPTIONS variable adds additional Perforce command line // options before the main command std::string opts = this->CTest->GetCTestConfiguration("P4Options"); - cm::append(P4Options, cmSystemTools::ParseArguments(opts)); + cm::append(this->P4Options, cmSystemTools::ParseArguments(opts)); } CommandOptions.clear(); - for (std::string const& o : P4Options) { + for (std::string const& o : this->P4Options) { CommandOptions.push_back(o.c_str()); } } @@ -339,7 +339,7 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions) std::string cmCTestP4::GetWorkingRevision() { std::vector<char const*> p4_identify; - SetP4Options(p4_identify); + this->SetP4Options(p4_identify); p4_identify.push_back("changes"); p4_identify.push_back("-m"); @@ -354,7 +354,7 @@ std::string cmCTestP4::GetWorkingRevision() IdentifyParser out(this, "p4_changes-out> ", rev); OutputLogger err(this->Log, "p4_changes-err> "); - bool result = RunChild(&p4_identify[0], &out, &err); + bool result = this->RunChild(&p4_identify[0], &out, &err); // If there was a problem contacting the server return "<unknown>" if (!result) { @@ -391,7 +391,7 @@ bool cmCTestP4::NoteNewRevision() bool cmCTestP4::LoadRevisions() { std::vector<char const*> p4_changes; - SetP4Options(p4_changes); + this->SetP4Options(p4_changes); // Use 'p4 changes ...@old,new' to get a list of changelists std::string range = this->SourceDirectory + "/..."; @@ -417,17 +417,17 @@ bool cmCTestP4::LoadRevisions() ChangesParser out(this, "p4_changes-out> "); OutputLogger err(this->Log, "p4_changes-err> "); - ChangeLists.clear(); + this->ChangeLists.clear(); this->RunChild(&p4_changes[0], &out, &err); - if (ChangeLists.empty()) { + if (this->ChangeLists.empty()) { return true; } // p4 describe -s ...@1111111,2222222 std::vector<char const*> p4_describe; - for (std::string const& i : cmReverseRange(ChangeLists)) { - SetP4Options(p4_describe); + for (std::string const& i : cmReverseRange(this->ChangeLists)) { + this->SetP4Options(p4_describe); p4_describe.push_back("describe"); p4_describe.push_back("-s"); p4_describe.push_back(i.c_str()); @@ -443,7 +443,7 @@ bool cmCTestP4::LoadRevisions() bool cmCTestP4::LoadModifications() { std::vector<char const*> p4_diff; - SetP4Options(p4_diff); + this->SetP4Options(p4_diff); p4_diff.push_back("diff"); @@ -491,7 +491,7 @@ bool cmCTestP4::UpdateImpl() } std::vector<char const*> p4_sync; - SetP4Options(p4_sync); + this->SetP4Options(p4_sync); p4_sync.push_back("sync"); diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 4d65c9b..5a6c775 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -139,7 +139,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode; } this->TestResult.CompletionStatus = s.str(); - cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped "); + outputStream << "***Skipped "; skipped = true; } else if (success != this->TestProperties->WillFail) { this->TestResult.Status = cmCTestTestHandler::COMPLETED; @@ -195,10 +195,11 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) sprintf(buf, "%6.2f sec", this->TestProcess->GetTotalTime().count()); outputStream << buf << "\n"; + bool passedOrSkipped = passed || skipped; if (this->CTest->GetTestProgressOutput()) { - if (!passed) { + if (!passedOrSkipped) { // If the test did not pass, reprint test name and error - std::string output = GetTestPrefix(completed, total); + std::string output = this->GetTestPrefix(completed, total); std::string testName = this->TestProperties->Name; const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth(); testName.resize(maxTestNameWidth + 4, '.'); @@ -211,12 +212,12 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, "\n"); // flush } if (completed == total) { - std::string testName = - GetTestPrefix(completed, total) + this->TestProperties->Name + "\n"; + std::string testName = this->GetTestPrefix(completed, total) + + this->TestProperties->Name + "\n"; cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName); } } - if (!this->CTest->GetTestProgressOutput() || !passed) { + if (!this->CTest->GetTestProgressOutput() || !passedOrSkipped) { cmCTestLog(this->CTest, HANDLER_OUTPUT, outputStream.str()); } @@ -485,8 +486,8 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total) << this->TestProperties->Index << ": " << this->TestProperties->Name << std::endl); } else { - std::string testName = - GetTestPrefix(completed, total) + this->TestProperties->Name + "\n"; + std::string testName = this->GetTestPrefix(completed, total) + + this->TestProperties->Name + "\n"; cmCTestLog(this->CTest, HANDLER_TEST_PROGRESS_OUTPUT, testName); } diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx index 44dfab2..4692dbd 100644 --- a/Source/CTest/cmCTestSVN.cxx +++ b/Source/CTest/cmCTestSVN.cxx @@ -286,9 +286,9 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters, args.push_back(nullptr); if (strcmp(parameters[0], "update") == 0) { - return RunUpdateCommand(&args[0], out, err); + return this->RunUpdateCommand(&args[0], out, err); } - return RunChild(&args[0], out, err); + return this->RunChild(&args[0], out, err); } class cmCTestSVN::LogParser @@ -328,7 +328,7 @@ private: this->CData.clear(); if (name == "logentry") { this->Rev = Revision(); - this->Rev.SVNInfo = &SVNRepo; + this->Rev.SVNInfo = &this->SVNRepo; if (const char* rev = cmCTestSVN::LogParser::FindAttribute(atts, "revision")) { this->Rev.Rev = rev; @@ -354,7 +354,7 @@ private: this->SVN->DoRevisionSVN(this->Rev, this->Changes); } else if (!this->CData.empty() && name == "path") { std::string orig_path(&this->CData[0], this->CData.size()); - std::string new_path = SVNRepo.BuildLocalPath(orig_path); + std::string new_path = this->SVNRepo.BuildLocalPath(orig_path); this->CurChange.Path.assign(new_path); this->Changes.push_back(this->CurChange); } else if (!this->CData.empty() && name == "author") { diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 84bb791..a8c9df6 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -340,7 +340,7 @@ void cmCTestTestHandler::Initialize() this->ExcludeFixtureSetupRegExp.clear(); this->ExcludeFixtureCleanupRegExp.clear(); - TestsToRunString.clear(); + this->TestsToRunString.clear(); this->UseUnion = false; this->TestList.clear(); } @@ -877,7 +877,7 @@ bool cmCTestTestHandler::ComputeTestList() finalList.push_back(tp); } - UpdateForFixtures(finalList); + this->UpdateForFixtures(finalList); // Save the total number of tests before exclusions this->TotalNumberOfTests = this->TestList.size(); @@ -906,7 +906,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed() finalList.push_back(tp); } - UpdateForFixtures(finalList); + this->UpdateForFixtures(finalList); // Save the total number of tests before exclusions this->TotalNumberOfTests = this->TestList.size(); diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx index 409025f..3a6651f 100644 --- a/Source/CTest/cmParseBlanketJSCoverage.cxx +++ b/Source/CTest/cmParseBlanketJSCoverage.cxx @@ -66,7 +66,7 @@ public: } foundFile = true; inSource = false; - filename = getValue(line, 0); + filename = this->getValue(line, 0); } else if ((line.find("coverage") != std::string::npos) && foundFile && inSource) { /* @@ -78,7 +78,7 @@ public: * FoundFile and foundSource ensure that * only the value of the line coverage is captured */ - std::string result = getValue(line, 1); + std::string result = this->getValue(line, 1); result = result.substr(2); if (result == "\"\"") { // Empty quotation marks indicate that the diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx index 711a856..9311769 100644 --- a/Source/CTest/cmParseCoberturaCoverage.cxx +++ b/Source/CTest/cmParseCoberturaCoverage.cxx @@ -66,7 +66,7 @@ protected: // Check if this is an absolute path that falls within our // source or binary directories. - for (std::string const& filePath : FilePaths) { + for (std::string const& filePath : this->FilePaths) { if (cmHasPrefix(filename, filePath)) { this->CurFileName = filename; break; @@ -76,7 +76,7 @@ protected: if (this->CurFileName.empty()) { // Check if this is a path that is relative to our source or // binary directories. - for (std::string const& filePath : FilePaths) { + for (std::string const& filePath : this->FilePaths) { finalpath = cmStrCat(filePath, "/", filename); if (cmSystemTools::FileExists(finalpath)) { this->CurFileName = finalpath; diff --git a/Source/CTest/cmParseDelphiCoverage.cxx b/Source/CTest/cmParseDelphiCoverage.cxx index 016e90c..640873e 100644 --- a/Source/CTest/cmParseDelphiCoverage.cxx +++ b/Source/CTest/cmParseDelphiCoverage.cxx @@ -133,7 +133,7 @@ public: cmsys::Glob gl; gl.RecurseOn(); gl.RecurseThroughSymlinksOff(); - std::string glob = Coverage.SourceDir + "*/" + filename; + std::string glob = this->Coverage.SourceDir + "*/" + filename; gl.FindFiles(glob); std::vector<std::string> const& files = gl.GetFiles(); if (files.empty()) { diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx index 9ee1c17..c7cbd34 100644 --- a/Source/CTest/cmProcess.cxx +++ b/Source/CTest/cmProcess.cxx @@ -177,7 +177,7 @@ bool cmProcess::Buffer::GetLine(std::string& line) // Start a new range for the next line. ++this->Last; - this->First = Last; + this->First = this->Last; // Return the line extracted. return true; diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake index 663d89a..7917d41 100644 --- a/Source/Checks/cm_cxx_features.cmake +++ b/Source/Checks/cm_cxx_features.cmake @@ -81,7 +81,13 @@ if(CMake_HAVE_CXX_MAKE_UNIQUE) endif() cm_check_cxx_feature(unique_ptr) if (NOT CMAKE_CXX_STANDARD LESS "17") - cm_check_cxx_feature(filesystem TRY_RUN) + if (NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR) + cm_check_cxx_feature(filesystem TRY_RUN) + else() + # In cross-compiling mode, it is not possible to check implementation bugs + # so rely only on conformance done by compilation + cm_check_cxx_feature(filesystem) + endif() else() set(CMake_HAVE_CXX_FILESYSTEM FALSE) endif() diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 452a303..0c263bb 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -3,20 +3,52 @@ project(QtDialog) CMake_OPTIONAL_COMPONENT(cmake-gui) -find_package(Qt5Widgets REQUIRED) +set (QT_COMPONENTS + Core + Widgets + Gui +) + +set(CMake_QT_MAJOR_VERSION "A" CACHE + STRING "Expected Qt major version. Valid values are A (auto-select), 5, 6.") +set(SUPPORTED_QT_VERSIONS "A" 5 6) +set_property(CACHE CMake_QT_MAJOR_VERSION PROPERTY STRINGS ${SUPPORTED_QT_VERSIONS}) +if(NOT CMake_QT_MAJOR_VERSION STREQUAL "A") + if(NOT CMake_QT_MAJOR_VERSION IN_LIST SUPPORTED_QT_VERSIONS) + message(FATAL_ERROR "Supported Qt versions are \"${SUPPORTED_QT_VERSIONS}\"." + " But CMake_QT_MAJOR_VERSION is set to ${CMake_QT_MAJOR_VERSION}.") + endif() + set(INSTALLED_QT_VERSION ${CMake_QT_MAJOR_VERSION}) +else() + find_package(Qt6Widgets QUIET) + set(INSTALLED_QT_VERSION 6) + if(NOT Qt6Widgets_FOUND) + find_package(Qt5Widgets QUIET) + if(NOT Qt5Widgets_FOUND) + message(FATAL_ERROR "Could not find a valid Qt installation.") + endif() + set(INSTALLED_QT_VERSION 5) + endif() +endif() + +find_package(Qt${INSTALLED_QT_VERSION} + COMPONENTS ${QT_COMPONENTS} + REQUIRED QUIET +) set(CMake_QT_EXTRA_LIBRARIES) # Try to find the package WinExtras for the task bar progress if(WIN32) - find_package(Qt5WinExtras QUIET) - if (Qt5WinExtras_FOUND) + find_package(Qt${INSTALLED_QT_VERSION}WinExtras QUIET) + if (Qt${INSTALLED_QT_VERSION}WinExtras_FOUND) add_definitions(-DQT_WINEXTRAS) - list(APPEND CMake_QT_EXTRA_LIBRARIES Qt5::WinExtras) + list(APPEND CMake_QT_EXTRA_LIBRARIES Qt${INSTALLED_QT_VERSION}::WinExtras) + list(APPEND QT_COMPONENTS WinExtras) endif() endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt${INSTALLED_QT_VERSION}Widgets_EXECUTABLE_COMPILE_FLAGS}") if(CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES) list(APPEND CMake_QT_EXTRA_LIBRARIES ${CMake_QT_STATIC_QXcbIntegrationPlugin_LIBRARIES}) @@ -31,11 +63,25 @@ if(CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES) endif() # We need to install platform plugin and add qt.conf for Qt5 on Mac and Windows. -# FIXME: This should be part of Qt5 CMake scripts, but unfortunately -# Qt5 support is missing there. if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32)) - macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var) - get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION) + function(_qt_get_plugin_name_with_version target out_var) + string(REGEX REPLACE "^Qt::(.+)" "Qt${INSTALLED_QT_VERSION}::\\1" + qt_plugin_with_version "${target}") + if(TARGET "${qt_plugin_with_version}") + set("${out_var}" "${qt_plugin_with_version}" PARENT_SCOPE) + else() + set("${out_var}" "" PARENT_SCOPE) + endif() + endfunction() + macro(install_qt_plugin _qt_plugin_name _qt_plugins_var) + if(TARGET "${_qt_plugin_name}") + get_target_property(_qt_plugin_path "${_qt_plugin_name}" LOCATION) + else() + _qt_get_plugin_name_with_version("Qt::${_qt_plugin_name}" _qt_plugin_with_version_name) + if(TARGET "${_qt_plugin_with_version_name}") + get_target_property(_qt_plugin_path "${_qt_plugin_with_version_name}" LOCATION) + endif() + endif() if(EXISTS "${_qt_plugin_path}") get_filename_component(_qt_plugin_file "${_qt_plugin_path}" NAME) get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH) @@ -51,19 +97,47 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32)) ${COMPONENT}) set(${_qt_plugins_var} "${${_qt_plugins_var}};\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${_qt_plugin_dest}/${_qt_plugin_file}") - else() - message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found") endif() endmacro() + macro(install_qt_plugins _comps _plugins_var) + foreach(_qt_comp ${${_comps}}) + if (INSTALLED_QT_VERSION VERSION_LESS 6) + set(_qt_module_plugins ${Qt${INSTALLED_QT_VERSION}${_qt_comp}_PLUGINS}) + else() + get_target_property(_qt_module_plugins Qt${INSTALLED_QT_VERSION}::${_qt_comp} QT_PLUGINS) + endif() + foreach(_qt_plugin ${_qt_module_plugins}) + if (INSTALLED_QT_VERSION VERSION_GREATER_EQUAL 6) + # Qt6 provides the plugins as individual packages that need to be found. + find_package(Qt${INSTALLED_QT_VERSION}${_qt_plugin} QUIET + PATHS ${Qt${INSTALLED_QT_VERSION}${_qt_comp}_DIR}) + endif() + install_qt_plugin("${_qt_plugin}" "${_plugins_var}") + endforeach() + endforeach() + endmacro() if(APPLE) - install_qt5_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS) + if (INSTALLED_QT_VERSION VERSION_EQUAL 5) + install_qt_plugin("Qt5::QCocoaIntegrationPlugin" QT_PLUGINS) + if(TARGET Qt5::QMacStylePlugin) + install_qt_plugin("Qt5::QMacStylePlugin" QT_PLUGINS) + endif() + else() + # FIXME: Minimize plugins for Qt6. + install_qt_plugins(QT_COMPONENTS QT_PLUGINS) + endif() file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" "[Paths]\nPlugins = ${_qt_plugin_dir}\n") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" DESTINATION "${CMAKE_INSTALL_PREFIX}/Resources" ${COMPONENT}) elseif(WIN32 AND NOT CMake_QT_STATIC_QWindowsIntegrationPlugin_LIBRARIES) - install_qt5_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS) + if (INSTALLED_QT_VERSION VERSION_EQUAL 5) + install_qt_plugin("Qt5::QWindowsIntegrationPlugin" QT_PLUGINS) + else() + # FIXME: Minimize plugins for Qt6. + install_qt_plugins(QT_COMPONENTS QT_PLUGINS) + endif() file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" "[Paths]\nPlugins = ../${_qt_plugin_dir}\n") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" @@ -72,8 +146,8 @@ if(CMake_INSTALL_DEPENDENCIES AND (APPLE OR WIN32)) endif() endif() -get_property(_Qt5_Core_LOCATION TARGET Qt5::Core PROPERTY LOCATION) -get_filename_component(Qt_BIN_DIR "${_Qt5_Core_LOCATION}" PATH) +get_property(_Qt_Core_LOCATION TARGET Qt${INSTALLED_QT_VERSION}::Core PROPERTY LOCATION) +get_filename_component(Qt_BIN_DIR "${_Qt_Core_LOCATION}" PATH) if(APPLE) get_filename_component(Qt_BIN_DIR "${Qt_BIN_DIR}" PATH) endif() @@ -105,7 +179,7 @@ set(SRCS WarningMessagesDialog.cxx WarningMessagesDialog.h ) -qt5_wrap_ui(UI_SRCS +set(UI_SRCS CMakeSetupDialog.ui Compilers.ui CrossCompiler.ui @@ -114,7 +188,7 @@ qt5_wrap_ui(UI_SRCS RegexExplorer.ui WarningMessagesDialog.ui ) -qt5_wrap_cpp(MOC_SRCS +set(MOC_SRCS AddCacheEntry.h Compilers.h CMakeSetupDialog.h @@ -128,7 +202,18 @@ qt5_wrap_cpp(MOC_SRCS RegexExplorer.h WarningMessagesDialog.h ) -qt5_add_resources(RC_SRCS CMakeSetup.qrc) +set(QRC_SRCS CMakeSetup.qrc) + +if (INSTALLED_QT_VERSION VERSION_LESS 6) + qt5_wrap_ui(UI_BUILT_SRCS ${UI_SRCS}) + qt5_wrap_cpp(MOC_BUILT_SRCS ${MOC_SRCS}) + qt5_add_resources(QRC_BUILT_SRCS ${QRC_SRCS}) +else() + qt_wrap_ui(UI_BUILT_SRCS ${UI_SRCS}) + qt_wrap_cpp(MOC_BUILT_SRCS ${MOC_SRCS}) + qt_add_resources(QRC_BUILT_SRCS ${QRC_SRCS}) +endif() +add_library(CMakeGUIQRCLib OBJECT ${QRC_BUILT_SRCS}) if (FALSE) # CMake's bootstrap binary does not support automoc set(CMAKE_AUTOMOC 1) @@ -136,9 +221,8 @@ if (FALSE) # CMake's bootstrap binary does not support automoc set(CMAKE_AUTOUIC 1) else () list(APPEND SRCS - ${UI_SRCS} - ${MOC_SRCS} - ${RC_SRCS}) + ${UI_BUILT_SRCS} + ${MOC_BUILT_SRCS}) endif () if(USE_LGPL) @@ -153,14 +237,16 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) add_library(CMakeGUILib STATIC ${SRCS}) # CMake_QT_EXTRA_LIBRARIES have to come before the main libraries on the link line -target_link_libraries(CMakeGUILib PUBLIC CMakeLib ${CMake_QT_EXTRA_LIBRARIES} Qt5::Core Qt5::Widgets) +target_link_libraries(CMakeGUILib PUBLIC CMakeLib ${CMake_QT_EXTRA_LIBRARIES} + Qt${INSTALLED_QT_VERSION}::Core Qt${INSTALLED_QT_VERSION}::Widgets) add_library(CMakeGUIMainLib STATIC CMakeSetup.cxx) target_link_libraries(CMakeGUIMainLib PUBLIC CMakeGUILib) add_executable(cmake-gui WIN32 MACOSX_BUNDLE CMakeGUIExec.cxx ${MANIFEST_FILE}) -target_link_libraries(cmake-gui CMakeGUIMainLib Qt5::Core) +target_link_libraries(cmake-gui CMakeGUIMainLib Qt${INSTALLED_QT_VERSION}::Core) +target_sources(CMakeGUIMainLib INTERFACE $<TARGET_OBJECTS:CMakeGUIQRCLib>) if(WIN32) target_sources(CMakeGUIMainLib INTERFACE $<TARGET_OBJECTS:CMakeVersion> CMakeSetup.rc) endif() diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 861c6e3..5debdb8 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -7,7 +7,6 @@ #include <QDir> #include <QLocale> #include <QString> -#include <QTextCodec> #include <QTranslator> #include <QtPlugin> @@ -122,9 +121,6 @@ int main(int argc, char** argv) setlocale(LC_NUMERIC, "C"); - QTextCodec* utf8_codec = QTextCodec::codecForName("UTF-8"); - QTextCodec::setCodecForLocale(utf8_codec); - // tell the cmake library where cmake is QDir cmExecDir(QApplication::applicationDirPath()); #if defined(Q_OS_MAC) diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 05518a9..0313088 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -22,7 +22,6 @@ #include <QShortcut> #include <QStatusBar> #include <QString> -#include <QToolButton> #include <QUrl> #include <QVector> @@ -253,7 +252,7 @@ void CMakeSetupDialog::initialize() &QCMake::propertiesChanged, this->CacheValues->cacheModel(), &QCMakeCacheModel::setProperties); - QObject::connect(this->ConfigureButton, &QPushButton::clicked, this, + QObject::connect(this->ConfigureButton, &QAbstractButton::clicked, this, &CMakeSetupDialog::doConfigure); QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::configureDone, @@ -261,15 +260,17 @@ void CMakeSetupDialog::initialize() QObject::connect(this->CMakeThread->cmakeInstance(), &QCMake::generateDone, this, &CMakeSetupDialog::exitLoop); - QObject::connect(this->GenerateButton, &QPushButton::clicked, this, + QObject::connect(this->GenerateButton, &QAbstractButton::clicked, this, &CMakeSetupDialog::doGenerate); - QObject::connect(this->OpenProjectButton, &QPushButton::clicked, this, + QObject::connect(this->OpenProjectButton, &QAbstractButton::clicked, this, &CMakeSetupDialog::doOpenProject); - QObject::connect(this->BrowseSourceDirectoryButton, &QPushButton::clicked, - this, &CMakeSetupDialog::doSourceBrowse); - QObject::connect(this->BrowseBinaryDirectoryButton, &QPushButton::clicked, - this, &CMakeSetupDialog::doBinaryBrowse); + QObject::connect(this->BrowseSourceDirectoryButton, + &QAbstractButton::clicked, this, + &CMakeSetupDialog::doSourceBrowse); + QObject::connect(this->BrowseBinaryDirectoryButton, + &QAbstractButton::clicked, this, + &CMakeSetupDialog::doBinaryBrowse); QObject::connect(this->BinaryDirectory, &QComboBox::editTextChanged, this, &CMakeSetupDialog::onBinaryDirectoryChanged); @@ -324,12 +325,12 @@ void CMakeSetupDialog::initialize() QObject::connect(this->CacheValues->selectionModel(), &QItemSelectionModel::selectionChanged, this, &CMakeSetupDialog::selectionChanged); - QObject::connect(this->RemoveEntry, &QToolButton::clicked, this, + QObject::connect(this->RemoveEntry, &QAbstractButton::clicked, this, &CMakeSetupDialog::removeSelectedCacheEntries); - QObject::connect(this->AddEntry, &QToolButton::clicked, this, + QObject::connect(this->AddEntry, &QAbstractButton::clicked, this, &CMakeSetupDialog::addCacheEntry); - QObject::connect(this->Environment, &QToolButton::clicked, this, + QObject::connect(this->Environment, &QAbstractButton::clicked, this, &CMakeSetupDialog::editEnvironment); QObject::connect(this->WarnUninitializedAction, &QAction::triggered, diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui index a5c35b1..c17c414 100644 --- a/Source/QtDialog/CMakeSetupDialog.ui +++ b/Source/QtDialog/CMakeSetupDialog.ui @@ -84,14 +84,11 @@ <item row="2" column="1"> <widget class="QComboBox" name="BinaryDirectory"> <property name="sizePolicy"> - <sizepolicy hsizetype="Ignored" vsizetype="Fixed"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="styleSheet"> - <string notr="true">padding-left: 0</string> - </property> <property name="editable"> <bool>true</bool> </property> @@ -208,7 +205,7 @@ </widget> </item> <item> - <widget class="QToolButton" name="AddEntry"> + <widget class="QPushButton" name="AddEntry"> <property name="toolTip"> <string>Add New Entry</string> </property> @@ -216,16 +213,13 @@ <string>&Add Entry</string> </property> <property name="icon"> - <iconset resource="CMakeSetup.qrc"> + <iconset theme="list-add" resource="CMakeSetup.qrc"> <normaloff>:/Icons/Plus16.png</normaloff>:/Icons/Plus16.png</iconset> </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> </widget> </item> <item> - <widget class="QToolButton" name="RemoveEntry"> + <widget class="QPushButton" name="RemoveEntry"> <property name="toolTip"> <string>Remove Selected Entries</string> </property> @@ -233,12 +227,9 @@ <string>&Remove Entry</string> </property> <property name="icon"> - <iconset resource="CMakeSetup.qrc"> + <iconset theme="list-remove" resource="CMakeSetup.qrc"> <normaloff>:/Icons/Delete16.png</normaloff>:/Icons/Delete16.png</iconset> </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> </widget> </item> <item> diff --git a/Source/QtDialog/EnvironmentDialog.cxx b/Source/QtDialog/EnvironmentDialog.cxx index 846456c..0339d1d 100644 --- a/Source/QtDialog/EnvironmentDialog.cxx +++ b/Source/QtDialog/EnvironmentDialog.cxx @@ -81,7 +81,11 @@ bool EnvironmentSearchFilter::filterAcceptsRow(int row, auto* model = this->sourceModel(); auto key = model->data(model->index(row, 0, parent), Qt::DisplayRole).toString(); +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + return key.contains(this->filterRegularExpression()); +#else return key.contains(this->filterRegExp()); +#endif } EnvironmentDialog::EnvironmentDialog(const QProcessEnvironment& environment, @@ -102,9 +106,9 @@ EnvironmentDialog::EnvironmentDialog(const QProcessEnvironment& environment, this->Environment->setSelectionMode(QAbstractItemView::ExtendedSelection); this->Environment->setSelectionBehavior(QAbstractItemView::SelectRows); - QObject::connect(this->AddEntry, &QToolButton::clicked, this, + QObject::connect(this->AddEntry, &QAbstractButton::clicked, this, &EnvironmentDialog::addEntry); - QObject::connect(this->RemoveEntry, &QToolButton::clicked, this, + QObject::connect(this->RemoveEntry, &QAbstractButton::clicked, this, &EnvironmentDialog::removeSelectedEntries); QObject::connect(this->Search, &QLineEdit::textChanged, this->m_filter, &EnvironmentSearchFilter::setFilterFixedString); diff --git a/Source/QtDialog/EnvironmentDialog.ui b/Source/QtDialog/EnvironmentDialog.ui index dea7624..ed23c2c 100644 --- a/Source/QtDialog/EnvironmentDialog.ui +++ b/Source/QtDialog/EnvironmentDialog.ui @@ -46,31 +46,25 @@ </spacer> </item> <item> - <widget class="QToolButton" name="AddEntry"> + <widget class="QPushButton" name="AddEntry"> <property name="text"> <string>&Add Entry</string> </property> <property name="icon"> - <iconset resource="CMakeSetup.qrc"> + <iconset theme="list-add" resource="CMakeSetup.qrc"> <normaloff>:/Icons/Plus16.png</normaloff>:/Icons/Plus16.png</iconset> </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> </widget> </item> <item> - <widget class="QToolButton" name="RemoveEntry"> + <widget class="QPushButton" name="RemoveEntry"> <property name="text"> <string>&Remove Entry</string> </property> <property name="icon"> - <iconset resource="CMakeSetup.qrc"> + <iconset theme="list-remove" resource="CMakeSetup.qrc"> <normaloff>:/Icons/Delete16.png</normaloff>:/Icons/Delete16.png</iconset> </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> </widget> </item> </layout> diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 22f5be1..7c9032e 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -47,7 +47,11 @@ protected: // check all strings for a match foreach (QString const& str, strs) { +#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)) + if (str.contains(this->filterRegularExpression())) { +#else if (str.contains(this->filterRegExp())) { +#endif return true; } } diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx index e68faba..03d6ed1 100644 --- a/Source/QtDialog/QCMakeWidgets.cxx +++ b/Source/QtDialog/QCMakeWidgets.cxx @@ -1,20 +1,23 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ -// FIXME: Port to QFileSystemModel from the deprecated QDirModel. -// Be sure completion works when incrementally editing existing paths. #define QT_DEPRECATED_WARNINGS_SINCE QT_VERSION_CHECK(5, 14, 0) #include "QCMakeWidgets.h" #include <utility> -#include <QDirModel> #include <QFileDialog> #include <QFileInfo> #include <QResizeEvent> #include <QToolButton> +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +# include <QFileSystemModel> +#else +# include <QDirModel> +#endif + QCMakeFileEditor::QCMakeFileEditor(QWidget* p, QString var) : QLineEdit(p) , Variable(std::move(var)) @@ -22,7 +25,7 @@ QCMakeFileEditor::QCMakeFileEditor(QWidget* p, QString var) this->ToolButton = new QToolButton(this); this->ToolButton->setText("..."); this->ToolButton->setCursor(QCursor(Qt::ArrowCursor)); - QObject::connect(this->ToolButton, &QToolButton::clicked, this, + QObject::connect(this->ToolButton, &QAbstractButton::clicked, this, &QCMakeFileEditor::chooseFile); } @@ -93,8 +96,30 @@ void QCMakePathEditor::chooseFile() } } +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +// use same QFileSystemModel for all completers +static QFileSystemModel* fileDirModel() + +{ + static QFileSystemModel* m = nullptr; + if (!m) { + m = new QFileSystemModel(); + } + return m; +} +static QFileSystemModel* pathDirModel() +{ + static QFileSystemModel* m = nullptr; + if (!m) { + m = new QFileSystemModel(); + m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot); + } + return m; +} +#else // use same QDirModel for all completers static QDirModel* fileDirModel() + { static QDirModel* m = nullptr; if (!m) { @@ -111,12 +136,19 @@ static QDirModel* pathDirModel() } return m; } +#endif QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs) : QCompleter(o) { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + QFileSystemModel* m = dirs ? pathDirModel() : fileDirModel(); + this->setModel(m); + m->setRootPath(QString()); +#else QDirModel* m = dirs ? pathDirModel() : fileDirModel(); this->setModel(m); +#endif } QString QCMakeFileCompleter::pathFromIndex(const QModelIndex& idx) const diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx index 8435740..0dc954a 100644 --- a/Source/bindexplib.cxx +++ b/Source/bindexplib.cxx @@ -467,7 +467,7 @@ bool DumpFile(std::string const& nmPath, const char* filename, bool bindexplib::AddObjectFile(const char* filename) { - return DumpFile(NmPath, filename, this->Symbols, this->DataSymbols); + return DumpFile(this->NmPath, filename, this->Symbols, this->DataSymbols); } bool bindexplib::AddDefinitionFile(const char* filename) @@ -511,5 +511,5 @@ void bindexplib::WriteFile(FILE* file) void bindexplib::SetNmPath(std::string const& nm) { - NmPath = nm; + this->NmPath = nm; } diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h index 87000da..c192e2a 100644 --- a/Source/cmAlgorithms.h +++ b/Source/cmAlgorithms.h @@ -47,7 +47,8 @@ struct BinarySearcher bool operator()(argument_type const& item) const { - return std::binary_search(m_range.begin(), m_range.end(), item); + return std::binary_search(this->m_range.begin(), this->m_range.end(), + item); } private: diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h index 0d33758..168d30e 100644 --- a/Source/cmArchiveWrite.h +++ b/Source/cmArchiveWrite.h @@ -26,7 +26,7 @@ public: } void Clear() { this->IsValueSet = false; } bool IsSet() const { return this->IsValueSet; } - T Get() const { return Value; } + T Get() const { return this->Value; } private: T Value; diff --git a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx index 351d92a..6d97720 100644 --- a/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx +++ b/Source/cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.cxx @@ -44,7 +44,7 @@ bool cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool::GetFileInfo( std::string line; static const cmsys::RegularExpression rpathRegex("^ *cmd LC_RPATH$"); static const cmsys::RegularExpression loadDylibRegex( - "^ *cmd LC_LOAD_DYLIB$"); + "^ *cmd LC_LOAD(_WEAK)?_DYLIB$"); static const cmsys::RegularExpression pathRegex( "^ *path (.*) \\(offset [0-9]+\\)$"); static const cmsys::RegularExpression nameRegex( diff --git a/Source/cmCMakePath.cxx b/Source/cmCMakePath.cxx index b8215df..73321c6 100644 --- a/Source/cmCMakePath.cxx +++ b/Source/cmCMakePath.cxx @@ -88,7 +88,8 @@ bool cmCMakePath::IsPrefix(const cmCMakePath& path) const ++prefix_it; ++path_it; } - return prefix_it == prefix_end; + return (prefix_it == prefix_end) || + (prefix_it->empty() && path_it != path_end); } std::string cmCMakePath::FormatPath(std::string path, format fmt) diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx index 85e7d9e..5662a2f 100644 --- a/Source/cmCMakePathCommand.cxx +++ b/Source/cmCMakePathCommand.cxx @@ -37,7 +37,7 @@ public: template <typename T> CMakePathArgumentParser& Bind(cm::static_string_view name, T Result::*member) { - cmArgumentParser<Result>::Bind(name, member); + this->cmArgumentParser<Result>::Bind(name, member); return *this; } @@ -48,12 +48,12 @@ public: { this->Inputs.clear(); - return cmArgumentParser<Result>::Parse(cmMakeRange(args).advance(Advance), - &this->Inputs, keywordsMissingValue, - parsedKeywords); + return this->cmArgumentParser<Result>::Parse( + cmMakeRange(args).advance(Advance), &this->Inputs, keywordsMissingValue, + parsedKeywords); } - const std::vector<std::string>& GetInputs() const { return Inputs; } + const std::vector<std::string>& GetInputs() const { return this->Inputs; } protected: mutable std::vector<std::string> Inputs; @@ -74,7 +74,7 @@ public: ArgumentParserWithOutputVariable& Bind(cm::static_string_view name, T Result::*member) { - cmArgumentParser<Result>::Bind(name, member); + this->cmArgumentParser<Result>::Bind(name, member); return *this; } @@ -84,7 +84,7 @@ public: this->KeywordsMissingValue.clear(); this->ParsedKeywords.clear(); - return CMakePathArgumentParser<Result>::template Parse<Advance>( + return this->CMakePathArgumentParser<Result>::template Parse<Advance>( args, &this->KeywordsMissingValue, &this->ParsedKeywords); } @@ -929,17 +929,8 @@ bool HandleIsPrefixCommand(std::vector<std::string> const& args, bool HandleHashCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { - if (args.size() < 3 || args.size() > 4) { - status.SetError("HASH must be called with two or three arguments."); - return false; - } - - static NormalizeParser const parser; - - const auto arguments = parser.Parse(args); - - if (parser.GetInputs().size() != 1) { - status.SetError("HASH called with unexpected arguments."); + if (args.size() != 3) { + status.SetError("HASH must be called with two arguments."); return false; } @@ -948,15 +939,14 @@ bool HandleHashCommand(std::vector<std::string> const& args, return false; } - const auto& output = parser.GetInputs().front(); + const auto& output = args[2]; if (output.empty()) { status.SetError("Invalid name for output variable."); return false; } - auto hash = hash_value(arguments.Normalize ? cmCMakePath(inputPath).Normal() - : cmCMakePath(inputPath)); + auto hash = hash_value(cmCMakePath(inputPath).Normal()); std::ostringstream out; out << std::setbase(16) << hash; diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 014ce4e..6c1071d 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -1326,11 +1326,11 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, if (result == cmsysProcess_State_Exited) { *retVal = cmsysProcess_GetExitValue(cp); if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) { - OutputTestErrors(tempOutput); + this->OutputTestErrors(tempOutput); } } else if (result == cmsysProcess_State_Exception) { if (this->Impl->OutputTestOutputOnTestFailure) { - OutputTestErrors(tempOutput); + this->OutputTestErrors(tempOutput); } *retVal = cmsysProcess_GetExitException(cp); std::string outerr = cmStrCat("\n*** Exception executing: ", @@ -2901,7 +2901,7 @@ bool cmCTest::GetFailover() const bool cmCTest::GetTestProgressOutput() const { - return this->Impl->TestProgressOutput; + return this->Impl->TestProgressOutput && !GetExtraVerbose(); } bool cmCTest::GetVerbose() const diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx index d4f5022..6d5e064 100644 --- a/Source/cmCommandArgumentParserHelper.cxx +++ b/Source/cmCommandArgumentParserHelper.cxx @@ -240,7 +240,7 @@ int cmCommandArgumentParserHelper::ParseString(std::string const& str, this->CleanupParser(); - if (Verbose) { + if (this->Verbose) { std::cerr << "Expanding [" << str << "] produced: [" << this->Result << "]" << std::endl; } diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h new file mode 100644 index 0000000..cbedf0a --- /dev/null +++ b/Source/cmCommandLineArgument.h @@ -0,0 +1,159 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmStringAlgorithms.h" +#include "cmSystemTools.h" + +template <typename FunctionSignature> +struct cmCommandLineArgument +{ + enum class Values + { + Zero, + One, + Two, + ZeroOrOne, + OneOrMore + }; + + std::string InvalidSyntaxMessage; + std::string InvalidValueMessage; + std::string Name; + Values Type; + std::function<FunctionSignature> StoreCall; + + template <typename FunctionType> + cmCommandLineArgument(std::string n, Values t, FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n)) + , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) + , Name(std::move(n)) + , Type(t) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + template <typename FunctionType> + cmCommandLineArgument(std::string n, std::string failedMsg, Values t, + FunctionType&& func) + : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n)) + , InvalidValueMessage(std::move(failedMsg)) + , Name(std::move(n)) + , Type(t) + , StoreCall(std::forward<FunctionType>(func)) + { + } + + bool matches(std::string const& input) const + { + return (this->Type == Values::Zero) ? (input == this->Name) + : cmHasPrefix(input, this->Name); + } + + template <typename T, typename... CallState> + bool parse(std::string const& input, T& index, + std::vector<std::string> const& allArgs, + CallState&&... state) const + { + enum class ParseMode + { + Valid, + Invalid, + SyntaxError, + ValueError + }; + ParseMode parseState = ParseMode::Valid; + + if (this->Type == Values::Zero) { + if (input.size() == this->Name.size()) { + parseState = + this->StoreCall(std::string{}, std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } else { + parseState = ParseMode::SyntaxError; + } + + } else if (this->Type == Values::One || this->Type == Values::ZeroOrOne) { + if (input.size() == this->Name.size()) { + ++index; + if (index >= allArgs.size() || allArgs[index][0] == '-') { + if (this->Type == Values::ZeroOrOne) { + parseState = + this->StoreCall(std::string{}, std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } else { + parseState = ParseMode::ValueError; + } + } else { + parseState = + this->StoreCall(allArgs[index], std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } + } else { + // parse the string to get the value + auto possible_value = cm::string_view(input).substr(this->Name.size()); + if (possible_value.empty()) { + parseState = ParseMode::SyntaxError; + parseState = ParseMode::ValueError; + } else if (possible_value[0] == '=') { + possible_value.remove_prefix(1); + if (possible_value.empty()) { + parseState = ParseMode::ValueError; + } else { + parseState = this->StoreCall(std::string(possible_value), + std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } + } + if (parseState == ParseMode::Valid) { + parseState = this->StoreCall(std::string(possible_value), + std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } + } + } else if (this->Type == Values::Two) { + if (input.size() == this->Name.size()) { + if (index + 2 >= allArgs.size() || allArgs[index + 1][0] == '-' || + allArgs[index + 2][0] == '-') { + parseState = ParseMode::ValueError; + } else { + index += 2; + parseState = + this->StoreCall(cmStrCat(allArgs[index - 1], ";", allArgs[index]), + std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } + } + } else if (this->Type == Values::OneOrMore) { + if (input.size() == this->Name.size()) { + auto nextValueIndex = index + 1; + if (nextValueIndex >= allArgs.size() || allArgs[index + 1][0] == '-') { + parseState = ParseMode::ValueError; + } else { + std::string buffer = allArgs[nextValueIndex++]; + while (nextValueIndex < allArgs.size() && + allArgs[nextValueIndex][0] != '-') { + buffer = cmStrCat(buffer, ";", allArgs[nextValueIndex++]); + } + parseState = + this->StoreCall(buffer, std::forward<CallState>(state)...) + ? ParseMode::Valid + : ParseMode::Invalid; + } + } + } + + if (parseState == ParseMode::SyntaxError) { + cmSystemTools::Error(this->InvalidSyntaxMessage); + } else if (parseState == ParseMode::ValueError) { + cmSystemTools::Error(this->InvalidValueMessage); + } + return (parseState == ParseMode::Valid); + } +}; diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx index 2b7c9f6..228cff7 100644 --- a/Source/cmCommonTargetGenerator.cxx +++ b/Source/cmCommonTargetGenerator.cxx @@ -27,7 +27,7 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt) static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator)) , GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>( gt->LocalGenerator->GetGlobalGenerator())) - , ConfigNames(LocalCommonGenerator->GetConfigNames()) + , ConfigNames(this->LocalCommonGenerator->GetConfigNames()) { } diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 1f22ce6..85a9d9c 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -525,7 +525,7 @@ void cmComputeTargetDepends::DisplayGraph(Graph const& graph, void cmComputeTargetDepends::DisplaySideEffects() { fprintf(stderr, "The side effects are:\n"); - int n = static_cast<int>(SideEffects.size()); + int n = static_cast<int>(this->SideEffects.size()); for (int depender_index = 0; depender_index < n; ++depender_index) { cmGeneratorTarget const* depender = this->Targets[depender_index]; fprintf(stderr, "target %d is [%s]\n", depender_index, diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx index 14f10bd74..62bc526 100644 --- a/Source/cmConditionEvaluator.cxx +++ b/Source/cmConditionEvaluator.cxx @@ -271,10 +271,10 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference( { // Use the policy if it is set. if (this->Policy12Status == cmPolicies::NEW) { - return GetBooleanValue(newArg); + return this->GetBooleanValue(newArg); } if (this->Policy12Status == cmPolicies::OLD) { - return GetBooleanValueOld(newArg, oneArg); + return this->GetBooleanValueOld(newArg, oneArg); } // Check policy only if old and new results differ. @@ -367,7 +367,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs, reducible = 0; auto arg = newArgs.begin(); while (arg != newArgs.end()) { - if (IsKeyword(keyParenL, *arg)) { + if (this->IsKeyword(keyParenL, *arg)) { // search for the closing paren for this opening one cmArgumentList::iterator argClose; argClose = arg; @@ -531,7 +531,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs, argP1 = arg; this->IncrementArguments(newArgs, argP1, argP2); if (argP1 != newArgs.end() && argP2 != newArgs.end() && - IsKeyword(keyMATCHES, *argP1)) { + this->IsKeyword(keyMATCHES, *argP1)) { def = this->GetDefinitionIfUnquoted(*arg); if (!def) { def = &arg->GetValue(); @@ -707,8 +707,8 @@ bool cmConditionEvaluator::HandleLevel3(cmArgumentList& newArgs, cmArgumentList::iterator argP2; while (arg != newArgs.end()) { argP1 = arg; - IncrementArguments(newArgs, argP1, argP2); - if (argP1 != newArgs.end() && IsKeyword(keyNOT, *arg)) { + this->IncrementArguments(newArgs, argP1, argP2); + if (argP1 != newArgs.end() && this->IsKeyword(keyNOT, *arg)) { bool rhs = this->GetBooleanValueWithAutoDereference( *argP1, errorString, status); this->HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2); @@ -735,8 +735,8 @@ bool cmConditionEvaluator::HandleLevel4(cmArgumentList& newArgs, cmArgumentList::iterator argP2; while (arg != newArgs.end()) { argP1 = arg; - IncrementArguments(newArgs, argP1, argP2); - if (argP1 != newArgs.end() && IsKeyword(keyAND, *argP1) && + this->IncrementArguments(newArgs, argP1, argP2); + if (argP1 != newArgs.end() && this->IsKeyword(keyAND, *argP1) && argP2 != newArgs.end()) { lhs = this->GetBooleanValueWithAutoDereference(*arg, errorString, status); diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx index b1e63ba..b331862 100644 --- a/Source/cmCryptoHash.cxx +++ b/Source/cmCryptoHash.cxx @@ -36,7 +36,7 @@ static rhash cmCryptoHash_rhash_init(unsigned int id) cmCryptoHash::cmCryptoHash(Algo algo) : Id(cmCryptoHashAlgoToId[algo]) - , CTX(cmCryptoHash_rhash_init(Id)) + , CTX(cmCryptoHash_rhash_init(this->Id)) { } diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index c67497a..4329caf 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -200,6 +200,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( argv.push_back(cmSystemTools::GetCMakeCommand()); argv.emplace_back("-E"); argv.emplace_back("cmake_transform_depfile"); + argv.push_back(this->LG->GetGlobalGenerator()->GetName()); switch (*this->LG->GetGlobalGenerator()->DepfileFormat()) { case cmDepfileFormat::GccDepfile: argv.emplace_back("gccdepfile"); @@ -208,15 +209,10 @@ cmCustomCommandGenerator::cmCustomCommandGenerator( argv.emplace_back("vstlog"); break; } - if (this->LG->GetCurrentBinaryDirectory() == - this->LG->GetBinaryDirectory()) { - argv.emplace_back("./"); - } else { - argv.push_back(cmStrCat(this->LG->MaybeConvertToRelativePath( - this->LG->GetBinaryDirectory(), - this->LG->GetCurrentBinaryDirectory()), - '/')); - } + argv.push_back(this->LG->GetSourceDirectory()); + argv.push_back(this->LG->GetCurrentSourceDirectory()); + argv.push_back(this->LG->GetBinaryDirectory()); + argv.push_back(this->LG->GetCurrentBinaryDirectory()); argv.push_back(this->GetFullDepfile()); argv.push_back(this->GetInternalDepfile()); diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index e6aef92..60e8cbf 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -7,6 +7,7 @@ #include "cmsys/FStream.hxx" #include "cmFileTime.h" +#include "cmGlobalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmProperty.h" @@ -215,16 +216,28 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, // directory. We must do the same here. std::string obj_m = this->LocalGenerator->ConvertToMakefilePath(obj_i); internalDepends << obj_i << '\n'; - - for (std::string const& dep : dependencies) { - makeDepends << obj_m << ": " - << this->LocalGenerator->ConvertToMakefilePath( - this->LocalGenerator->MaybeConvertToRelativePath(binDir, - dep)) - << '\n'; - internalDepends << ' ' << dep << '\n'; + if (!dependencies.empty()) { + const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->LineContinueDirective; + bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->SupportsLongLineDependencies(); + if (supportLongLineDepend) { + makeDepends << obj_m << ':'; + } + for (std::string const& dep : dependencies) { + std::string dependee = this->LocalGenerator->ConvertToMakefilePath( + this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep)); + if (supportLongLineDepend) { + makeDepends << ' ' << lineContinue << ' ' << dependee; + } else { + makeDepends << obj_m << ": " << dependee << '\n'; + } + internalDepends << ' ' << dep << '\n'; + } + makeDepends << '\n'; } - makeDepends << '\n'; return true; } diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx index beb080f..2b48df9 100644 --- a/Source/cmDependsCompiler.cxx +++ b/Source/cmDependsCompiler.cxx @@ -97,17 +97,8 @@ bool cmDependsCompiler::CheckDependencies( std::vector<std::string> depends; if (format == "custom"_s) { - std::string prefix; - if (this->LocalGenerator->GetCurrentBinaryDirectory() != - this->LocalGenerator->GetBinaryDirectory()) { - prefix = - cmStrCat(this->LocalGenerator->MaybeConvertToRelativePath( - this->LocalGenerator->GetBinaryDirectory(), - this->LocalGenerator->GetCurrentBinaryDirectory()), - '/'); - } - - auto deps = cmReadGccDepfile(depFile.c_str(), prefix); + auto deps = cmReadGccDepfile( + depFile.c_str(), this->LocalGenerator->GetCurrentBinaryDirectory()); if (!deps) { continue; } @@ -196,30 +187,39 @@ void cmDependsCompiler::WriteDependencies( const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>( this->LocalGenerator->GetGlobalGenerator()) ->LineContinueDirective; + bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->SupportsLongLineDependencies(); const auto& binDir = this->LocalGenerator->GetBinaryDirectory(); cmDepends::DependencyMap makeDependencies(dependencies); std::unordered_set<cm::string_view> phonyTargets; // external dependencies file for (auto& node : makeDependencies) { - auto target = LocalGenerator->ConvertToMakefilePath( + auto target = this->LocalGenerator->ConvertToMakefilePath( this->LocalGenerator->MaybeConvertToRelativePath(binDir, node.first)); auto& deps = node.second; std::transform( deps.cbegin(), deps.cend(), deps.begin(), [this, &binDir](const std::string& dep) { - return LocalGenerator->ConvertToMakefilePath( + return this->LocalGenerator->ConvertToMakefilePath( this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep)); }); bool first_dep = true; - makeDepends << target << ": "; + if (supportLongLineDepend) { + makeDepends << target << ": "; + } for (const auto& dep : deps) { - if (first_dep) { - first_dep = false; - makeDepends << dep; + if (supportLongLineDepend) { + if (first_dep) { + first_dep = false; + makeDepends << dep; + } else { + makeDepends << ' ' << lineContinue << " " << dep; + } } else { - makeDepends << ' ' << lineContinue << " " << dep; + makeDepends << target << ": " << dep << std::endl; } phonyTargets.emplace(dep.data(), dep.length()); diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index a239418..1a06f31 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -12,6 +12,7 @@ #include "cmFortranParser.h" /* Interface to parser object. */ #include "cmGeneratedFileStream.h" +#include "cmGlobalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmOutputConverter.h" @@ -320,14 +321,28 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj); std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i); internalDepends << obj_i << "\n " << src << '\n'; - for (std::string const& i : info.Includes) { - makeDepends << obj_m << ": " - << cmSystemTools::ConvertToOutputPath( - this->MaybeConvertToRelativePath(binDir, i)) - << '\n'; - internalDepends << ' ' << i << '\n'; + if (!info.Includes.empty()) { + const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->LineContinueDirective; + bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->SupportsLongLineDependencies(); + if (supportLongLineDepend) { + makeDepends << obj_m << ':'; + } + for (std::string const& i : info.Includes) { + std::string dependee = cmSystemTools::ConvertToOutputPath( + this->MaybeConvertToRelativePath(binDir, i)); + if (supportLongLineDepend) { + makeDepends << ' ' << lineContinue << ' ' << dependee; + } else { + makeDepends << obj_m << ": " << dependee << '\n'; + } + internalDepends << ' ' << i << '\n'; + } + makeDepends << '\n'; } - makeDepends << '\n'; // Write module requirements to the output stream. for (std::string const& i : info.Requires) { diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx index 1bc453d..3619ade 100644 --- a/Source/cmDocumentation.cxx +++ b/Source/cmDocumentation.cxx @@ -194,7 +194,7 @@ void cmDocumentation::addCTestStandardDocSections() { // This is currently done for backward compatibility reason // We may suppress some of these. - addCMakeStandardDocSections(); + this->addCMakeStandardDocSections(); } void cmDocumentation::addCPackStandardDocSections() diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx index a8d81f7..deffdb6 100644 --- a/Source/cmELF.cxx +++ b/Source/cmELF.cxx @@ -379,7 +379,7 @@ private: // Fix the byte order of the header. if (this->NeedSwap) { - ByteSwap(x); + this->ByteSwap(x); } return true; } @@ -387,7 +387,7 @@ private: { if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) && this->NeedSwap) { - ByteSwap(x); + this->ByteSwap(x); } return !this->Stream->fail(); } @@ -395,7 +395,7 @@ private: { if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) && this->NeedSwap) { - ByteSwap(x); + this->ByteSwap(x); } return !this->Stream->fail(); } @@ -573,7 +573,7 @@ std::vector<char> cmELFInternalImpl<Types>::EncodeDynamicEntries( dyn.d_un.d_val = static_cast<tagtype>(entry.second); if (this->NeedSwap) { - ByteSwap(dyn); + this->ByteSwap(dyn); } char* pdyn = reinterpret_cast<char*>(&dyn); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index a853bb1..113751a 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -707,7 +707,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpression( break; } input.replace(pos, endPos - pos + 1, targetName); - lastPos = endPos; + lastPos = pos + targetName.size(); } pos = 0; diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 0b9b183..3c69c50 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -290,6 +290,7 @@ bool cmExportInstallFileGenerator::GenerateImportFileConfig( cmSystemTools::Error(e.str()); return false; } + exportFileStream.SetCopyIfDifferent(true); std::ostream& os = exportFileStream; // Start with the import file header. diff --git a/Source/cmExprParserHelper.cxx b/Source/cmExprParserHelper.cxx index 56dfc6c..cc8b8b7 100644 --- a/Source/cmExprParserHelper.cxx +++ b/Source/cmExprParserHelper.cxx @@ -42,20 +42,22 @@ int cmExprParserHelper::ParseString(const char* str, int verb) try { int res = cmExpr_yyparse(yyscanner); if (res != 0) { - std::string e = cmStrCat("cannot parse the expression: \"", InputBuffer, - "\": ", ErrorString, '.'); + std::string e = + cmStrCat("cannot parse the expression: \"", this->InputBuffer, + "\": ", this->ErrorString, '.'); this->SetError(std::move(e)); } } catch (std::runtime_error const& fail) { - std::string e = cmStrCat("cannot evaluate the expression: \"", InputBuffer, - "\": ", fail.what(), '.'); + std::string e = cmStrCat("cannot evaluate the expression: \"", + this->InputBuffer, "\": ", fail.what(), '.'); this->SetError(std::move(e)); } catch (std::out_of_range const&) { - std::string e = "cannot evaluate the expression: \"" + InputBuffer + + std::string e = "cannot evaluate the expression: \"" + this->InputBuffer + "\": a numeric value is out of range."; this->SetError(std::move(e)); } catch (...) { - std::string e = "cannot parse the expression: \"" + InputBuffer + "\"."; + std::string e = + "cannot parse the expression: \"" + this->InputBuffer + "\"."; this->SetError(std::move(e)); } cmExpr_yylex_destroy(yyscanner); @@ -63,7 +65,7 @@ int cmExprParserHelper::ParseString(const char* str, int verb) return 0; } - if (Verbose) { + if (this->Verbose) { std::cerr << "Expanding [" << str << "] produced: [" << this->Result << "]" << std::endl; } diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h index 3ade67b..311a2ef 100644 --- a/Source/cmExternalMakefileProjectGenerator.h +++ b/Source/cmExternalMakefileProjectGenerator.h @@ -52,8 +52,8 @@ public: //! Generate the project files, the Makefiles have already been generated virtual void Generate() = 0; - void SetName(const std::string& n) { Name = n; } - std::string GetName() const { return Name; } + void SetName(const std::string& n) { this->Name = n; } + std::string GetName() const { return this->Name; } virtual bool Open(const std::string& bindir, const std::string& projectName, bool dryRun); @@ -104,7 +104,7 @@ public: CreateExternalMakefileProjectGenerator() const override { std::unique_ptr<cmExternalMakefileProjectGenerator> p(new T); - p->SetName(GetName()); + p->SetName(this->GetName()); return p; } }; diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 87b8f9b..800db8a 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -112,10 +112,10 @@ void Tree::InsertPath(const std::vector<std::string>& split, const std::string& fileName) { if (start == split.size()) { - files.insert(fileName); + this->files.insert(fileName); return; } - for (Tree& folder : folders) { + for (Tree& folder : this->folders) { if (folder.path == split[start]) { if (start + 1 < split.size()) { folder.InsertPath(split, start + 1, fileName); @@ -131,19 +131,19 @@ void Tree::InsertPath(const std::vector<std::string>& split, newFolder.path = split[start]; if (start + 1 < split.size()) { newFolder.InsertPath(split, start + 1, fileName); - folders.push_back(newFolder); + this->folders.push_back(newFolder); return; } // last part of split newFolder.files.insert(fileName); - folders.push_back(newFolder); + this->folders.push_back(newFolder); } void Tree::BuildVirtualFolder(cmXMLWriter& xml) const { xml.StartElement("Option"); std::string virtualFolders = "CMake Files\\;"; - for (Tree const& folder : folders) { + for (Tree const& folder : this->folders) { folder.BuildVirtualFolderImpl(virtualFolders, ""); } xml.Attribute("virtualFolders", virtualFolders); @@ -153,15 +153,15 @@ void Tree::BuildVirtualFolder(cmXMLWriter& xml) const void Tree::BuildVirtualFolderImpl(std::string& virtualFolders, const std::string& prefix) const { - virtualFolders += "CMake Files\\" + prefix + path + "\\;"; - for (Tree const& folder : folders) { - folder.BuildVirtualFolderImpl(virtualFolders, prefix + path + "\\"); + virtualFolders += "CMake Files\\" + prefix + this->path + "\\;"; + for (Tree const& folder : this->folders) { + folder.BuildVirtualFolderImpl(virtualFolders, prefix + this->path + "\\"); } } void Tree::BuildUnit(cmXMLWriter& xml, const std::string& fsPath) const { - for (std::string const& f : files) { + for (std::string const& f : this->files) { xml.StartElement("Unit"); xml.Attribute("filename", fsPath + f); @@ -171,7 +171,7 @@ void Tree::BuildUnit(cmXMLWriter& xml, const std::string& fsPath) const xml.EndElement(); } - for (Tree const& folder : folders) { + for (Tree const& folder : this->folders) { folder.BuildUnitImpl(xml, "", fsPath); } } @@ -180,20 +180,21 @@ void Tree::BuildUnitImpl(cmXMLWriter& xml, const std::string& virtualFolderPath, const std::string& fsPath) const { - for (std::string const& f : files) { + for (std::string const& f : this->files) { xml.StartElement("Unit"); - xml.Attribute("filename", cmStrCat(fsPath, path, "/", f)); + xml.Attribute("filename", cmStrCat(fsPath, this->path, "/", f)); xml.StartElement("Option"); - xml.Attribute("virtualFolder", - cmStrCat("CMake Files\\", virtualFolderPath, path, "\\")); + xml.Attribute( + "virtualFolder", + cmStrCat("CMake Files\\", virtualFolderPath, this->path, "\\")); xml.EndElement(); xml.EndElement(); } - for (Tree const& folder : folders) { - folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, path, "\\"), - cmStrCat(fsPath, path, "/")); + for (Tree const& folder : this->folders) { + folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, this->path, "\\"), + cmStrCat(fsPath, this->path, "/")); } } diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx index 95cfb0a..549b08b 100644 --- a/Source/cmExtraCodeLiteGenerator.cxx +++ b/Source/cmExtraCodeLiteGenerator.cxx @@ -64,7 +64,7 @@ void cmExtraCodeLiteGenerator::Generate() for (auto const& it : projectMap) { cmLocalGenerator* lg = it.second[0]; const cmMakefile* mf = lg->GetMakefile(); - this->ConfigName = GetConfigurationName(mf); + this->ConfigName = this->GetConfigurationName(mf); if (lg->GetCurrentBinaryDirectory() == lg->GetBinaryDirectory()) { workspaceOutputDir = lg->GetCurrentBinaryDirectory(); @@ -89,9 +89,9 @@ void cmExtraCodeLiteGenerator::Generate() std::vector<std::string> ProjectNames; if (targetsAreProjects) { - ProjectNames = CreateProjectsByTarget(&xml); + ProjectNames = this->CreateProjectsByTarget(&xml); } else { - ProjectNames = CreateProjectsByProjectMaps(&xml); + ProjectNames = this->CreateProjectsByProjectMaps(&xml); } xml.StartElement("BuildMatrix"); @@ -142,7 +142,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget( xml->Attribute("Active", "No"); xml->EndElement(); - CreateNewProjectFile(lt.get(), filename); + this->CreateNewProjectFile(lt.get(), filename); break; default: break; @@ -268,7 +268,7 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile( cmMakefile* makefile = lg->GetMakefile(); for (const auto& target : lg->GetGeneratorTargets()) { projectType = - CollectSourceFiles(makefile, target.get(), cFiles, otherFiles); + this->CollectSourceFiles(makefile, target.get(), cFiles, otherFiles); } } @@ -276,8 +276,8 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile( // their relative path) std::string projectPath = cmSystemTools::GetFilenamePath(filename); - CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf, - projectType, ""); + this->CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf, + projectType, ""); xml.EndElement(); // CodeLite_Project } @@ -402,7 +402,7 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries( const std::string& projectType, const std::string& targetName) { cmXMLWriter& xml(*_xml); - FindMatchingHeaderfiles(cFiles, otherFiles); + this->FindMatchingHeaderfiles(cFiles, otherFiles); // Create 2 virtual folders: src and include // and place all the implementation files into the src // folder, the rest goes to the include folder @@ -498,10 +498,10 @@ void cmExtraCodeLiteGenerator::CreateProjectSourceEntries( xml.StartElement("CustomBuild"); xml.Attribute("Enabled", "yes"); - xml.Element("RebuildCommand", GetRebuildCommand(mf, targetName)); - xml.Element("CleanCommand", GetCleanCommand(mf, targetName)); - xml.Element("BuildCommand", GetBuildCommand(mf, targetName)); - xml.Element("SingleFileCommand", GetSingleFileBuildCommand(mf)); + xml.Element("RebuildCommand", this->GetRebuildCommand(mf, targetName)); + xml.Element("CleanCommand", this->GetCleanCommand(mf, targetName)); + xml.Element("BuildCommand", this->GetBuildCommand(mf, targetName)); + xml.Element("SingleFileCommand", this->GetSingleFileBuildCommand(mf)); xml.Element("PreprocessFileCommand"); xml.Element("WorkingDirectory", "$(WorkspacePath)"); xml.EndElement(); // CustomBuild @@ -570,14 +570,14 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile( std::map<std::string, cmSourceFile*> cFiles; std::set<std::string> otherFiles; - projectType = CollectSourceFiles(mf, gt, cFiles, otherFiles); + projectType = this->CollectSourceFiles(mf, gt, cFiles, otherFiles); // Get the project path ( we need it later to convert files to // their relative path) std::string projectPath = cmSystemTools::GetFilenamePath(filename); - CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf, - projectType, targetName); + this->CreateProjectSourceEntries(cFiles, otherFiles, &xml, projectPath, mf, + projectType, targetName); xml.EndElement(); // CodeLite_Project } @@ -648,7 +648,7 @@ std::string cmExtraCodeLiteGenerator::GetCleanCommand( { std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR"); std::ostringstream ss; - std::string buildcommand = GetBuildCommand(mf, ""); + std::string buildcommand = this->GetBuildCommand(mf, ""); if (!targetName.empty() && generator == "Ninja") { ss << buildcommand << " -t clean " << targetName; } else { @@ -660,8 +660,8 @@ std::string cmExtraCodeLiteGenerator::GetCleanCommand( std::string cmExtraCodeLiteGenerator::GetRebuildCommand( const cmMakefile* mf, const std::string& targetName) const { - return GetCleanCommand(mf, targetName) + " && " + - GetBuildCommand(mf, targetName); + return this->GetCleanCommand(mf, targetName) + " && " + + this->GetBuildCommand(mf, targetName); } std::string cmExtraCodeLiteGenerator::GetSingleFileBuildCommand( diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx index 249dfaf..a92f6e3 100644 --- a/Source/cmExtraSublimeTextGenerator.cxx +++ b/Source/cmExtraSublimeTextGenerator.cxx @@ -132,7 +132,7 @@ void cmExtraSublimeTextGenerator::CreateNewProjectFile( // doesn't currently support these settings per build system, only project // wide MapSourceFileFlags sourceFileFlags; - AppendAllTargets(lgs, mf, fout, sourceFileFlags); + this->AppendAllTargets(lgs, mf, fout, sourceFileFlags); // End of build_systems fout << "\n\t]"; diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx index c2ab2f1..d2a9bec 100644 --- a/Source/cmFileAPI.cxx +++ b/Source/cmFileAPI.cxx @@ -18,6 +18,7 @@ #include "cmFileAPICMakeFiles.h" #include "cmFileAPICache.h" #include "cmFileAPICodemodel.h" +#include "cmFileAPIToolchains.h" #include "cmGlobalGenerator.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -262,6 +263,17 @@ bool cmFileAPI::ReadQuery(std::string const& query, objects.push_back(o); return true; } + if (kindName == ObjectKindName(ObjectKind::Toolchains)) { + Object o; + o.Kind = ObjectKind::Toolchains; + if (verStr == "v1") { + o.Version = 1; + } else { + return false; + } + objects.push_back(o); + return true; + } if (kindName == ObjectKindName(ObjectKind::InternalTest)) { Object o; o.Kind = ObjectKind::InternalTest; @@ -402,6 +414,7 @@ const char* cmFileAPI::ObjectKindName(ObjectKind kind) "codemodel", // "cache", // "cmakeFiles", // + "toolchains", // "__test" // }; return objectKindNames[size_t(kind)]; @@ -435,6 +448,9 @@ Json::Value cmFileAPI::BuildObject(Object const& object) case ObjectKind::CMakeFiles: value = this->BuildCMakeFiles(object); break; + case ObjectKind::Toolchains: + value = this->BuildToolchains(object); + break; case ObjectKind::InternalTest: value = this->BuildInternalTest(object); break; @@ -491,6 +507,8 @@ cmFileAPI::ClientRequest cmFileAPI::BuildClientRequest( r.Kind = ObjectKind::Cache; } else if (kindName == this->ObjectKindName(ObjectKind::CMakeFiles)) { r.Kind = ObjectKind::CMakeFiles; + } else if (kindName == this->ObjectKindName(ObjectKind::Toolchains)) { + r.Kind = ObjectKind::Toolchains; } else if (kindName == this->ObjectKindName(ObjectKind::InternalTest)) { r.Kind = ObjectKind::InternalTest; } else { @@ -518,6 +536,9 @@ cmFileAPI::ClientRequest cmFileAPI::BuildClientRequest( case ObjectKind::CMakeFiles: this->BuildClientRequestCMakeFiles(r, versions); break; + case ObjectKind::Toolchains: + this->BuildClientRequestToolchains(r, versions); + break; case ObjectKind::InternalTest: this->BuildClientRequestInternalTest(r, versions); break; @@ -765,6 +786,40 @@ Json::Value cmFileAPI::BuildCMakeFiles(Object const& object) return cmakeFiles; } +// The "toolchains" object kind. + +static unsigned int const ToolchainsV1Minor = 0; + +void cmFileAPI::BuildClientRequestToolchains( + ClientRequest& r, std::vector<RequestVersion> const& versions) +{ + // Select a known version from those requested. + for (RequestVersion const& v : versions) { + if ((v.Major == 1 && v.Minor <= ToolchainsV1Minor)) { + r.Version = v.Major; + break; + } + } + if (!r.Version) { + r.Error = NoSupportedVersion(versions); + } +} + +Json::Value cmFileAPI::BuildToolchains(Object const& object) +{ + Json::Value toolchains = cmFileAPIToolchainsDump(*this, object.Version); + toolchains["kind"] = this->ObjectKindName(object.Kind); + + Json::Value& version = toolchains["version"]; + if (object.Version == 1) { + version = BuildVersion(1, ToolchainsV1Minor); + } else { + return toolchains; // should be unreachable + } + + return toolchains; +} + // The "__test" object kind is for internal testing of CMake. static unsigned int const InternalTestV1Minor = 3; @@ -828,5 +883,13 @@ Json::Value cmFileAPI::ReportCapabilities() requests.append(std::move(request)); // NOLINT(*) } + { + Json::Value request = Json::objectValue; + request["kind"] = ObjectKindName(ObjectKind::Toolchains); + Json::Value& versions = request["version"] = Json::arrayValue; + versions.append(BuildVersion(1, ToolchainsV1Minor)); + requests.append(std::move(request)); // NOLINT(*) + } + return capabilities; } diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h index 086a92a..22302b4 100644 --- a/Source/cmFileAPI.h +++ b/Source/cmFileAPI.h @@ -56,6 +56,7 @@ private: CodeModel, Cache, CMakeFiles, + Toolchains, InternalTest }; @@ -200,6 +201,10 @@ private: ClientRequest& r, std::vector<RequestVersion> const& versions); Json::Value BuildCMakeFiles(Object const& object); + void BuildClientRequestToolchains( + ClientRequest& r, std::vector<RequestVersion> const& versions); + Json::Value BuildToolchains(Object const& object); + void BuildClientRequestInternalTest( ClientRequest& r, std::vector<RequestVersion> const& versions); Json::Value BuildInternalTest(Object const& object); diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx index 1e4f3b6..e208ca8 100644 --- a/Source/cmFileAPICMakeFiles.cxx +++ b/Source/cmFileAPICMakeFiles.cxx @@ -41,7 +41,7 @@ CMakeFiles::CMakeFiles(cmFileAPI& fileAPI, unsigned long version) , CMakeModules(cmSystemTools::GetCMakeRoot() + "/Modules") , TopSource(this->FileAPI.GetCMakeInstance()->GetHomeDirectory()) , TopBuild(this->FileAPI.GetCMakeInstance()->GetHomeOutputDirectory()) - , OutOfSource(TopBuild != TopSource) + , OutOfSource(this->TopBuild != this->TopSource) { static_cast<void>(this->Version); } @@ -50,7 +50,7 @@ Json::Value CMakeFiles::Dump() { Json::Value cmakeFiles = Json::objectValue; cmakeFiles["paths"] = this->DumpPaths(); - cmakeFiles["inputs"] = DumpInputs(); + cmakeFiles["inputs"] = this->DumpInputs(); return cmakeFiles; } diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx index 3ba943a..ddae527 100644 --- a/Source/cmFileAPICache.cxx +++ b/Source/cmFileAPICache.cxx @@ -44,7 +44,7 @@ Cache::Cache(cmFileAPI& fileAPI, unsigned long version) Json::Value Cache::Dump() { Json::Value cache = Json::objectValue; - cache["entries"] = DumpEntries(); + cache["entries"] = this->DumpEntries(); return cache; } diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx index 4a53c8a..7fcc3dc 100644 --- a/Source/cmFileAPICodemodel.cxx +++ b/Source/cmFileAPICodemodel.cxx @@ -145,7 +145,7 @@ class JBTIndex { public: JBTIndex() = default; - explicit operator bool() const { return Index != None; } + explicit operator bool() const { return this->Index != None; } Json::ArrayIndex Index = None; static Json::ArrayIndex const None = static_cast<Json::ArrayIndex>(-1); }; diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx new file mode 100644 index 0000000..722c114 --- /dev/null +++ b/Source/cmFileAPIToolchains.cxx @@ -0,0 +1,151 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmFileAPIToolchains.h" + +#include <memory> +#include <string> +#include <vector> + +#include <cm3p/json/value.h> + +#include "cmFileAPI.h" +#include "cmGlobalGenerator.h" +#include "cmMakefile.h" +#include "cmProperty.h" +#include "cmState.h" +#include "cmStringAlgorithms.h" +#include "cmake.h" + +namespace { + +struct ToolchainVariable +{ + std::string ObjectKey; + std::string VariableSuffix; + bool IsList; +}; + +class Toolchains +{ + cmFileAPI& FileAPI; + unsigned long Version; + + static const std::vector<ToolchainVariable> CompilerVariables; + static const std::vector<ToolchainVariable> CompilerImplicitVariables; + static const ToolchainVariable SourceFileExtensionsVariable; + + Json::Value DumpToolchains(); + Json::Value DumpToolchain(std::string const& lang); + Json::Value DumpToolchainVariables( + cmMakefile const* mf, std::string const& lang, + std::vector<ToolchainVariable> const& variables); + void DumpToolchainVariable(cmMakefile const* mf, Json::Value& object, + std::string const& lang, + ToolchainVariable const& variable); + +public: + Toolchains(cmFileAPI& fileAPI, unsigned long version); + Json::Value Dump(); +}; + +const std::vector<ToolchainVariable> Toolchains::CompilerVariables{ + { "path", "COMPILER", false }, + { "id", "COMPILER_ID", false }, + { "version", "COMPILER_VERSION", false }, + { "target", "COMPILER_TARGET", false }, +}; + +const std::vector<ToolchainVariable> Toolchains::CompilerImplicitVariables{ + { "includeDirectories", "IMPLICIT_INCLUDE_DIRECTORIES", true }, + { "linkDirectories", "IMPLICIT_LINK_DIRECTORIES", true }, + { "linkFrameworkDirectories", "IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", true }, + { "linkLibraries", "IMPLICIT_LINK_LIBRARIES", true }, +}; + +const ToolchainVariable Toolchains::SourceFileExtensionsVariable{ + "sourceFileExtensions", "SOURCE_FILE_EXTENSIONS", true +}; + +Toolchains::Toolchains(cmFileAPI& fileAPI, unsigned long version) + : FileAPI(fileAPI) + , Version(version) +{ + static_cast<void>(this->Version); +} + +Json::Value Toolchains::Dump() +{ + Json::Value toolchains = Json::objectValue; + toolchains["toolchains"] = this->DumpToolchains(); + return toolchains; +} + +Json::Value Toolchains::DumpToolchains() +{ + Json::Value toolchains = Json::arrayValue; + + for (std::string const& lang : + this->FileAPI.GetCMakeInstance()->GetState()->GetEnabledLanguages()) { + toolchains.append(this->DumpToolchain(lang)); + } + + return toolchains; +} + +Json::Value Toolchains::DumpToolchain(std::string const& lang) +{ + const auto& mf = + this->FileAPI.GetCMakeInstance()->GetGlobalGenerator()->GetMakefiles()[0]; + Json::Value toolchain = Json::objectValue; + toolchain["language"] = lang; + toolchain["compiler"] = + this->DumpToolchainVariables(mf.get(), lang, CompilerVariables); + toolchain["compiler"]["implicit"] = + this->DumpToolchainVariables(mf.get(), lang, CompilerImplicitVariables); + this->DumpToolchainVariable(mf.get(), toolchain, lang, + SourceFileExtensionsVariable); + return toolchain; +} + +Json::Value Toolchains::DumpToolchainVariables( + cmMakefile const* mf, std::string const& lang, + std::vector<ToolchainVariable> const& variables) +{ + Json::Value object = Json::objectValue; + for (const auto& variable : variables) { + this->DumpToolchainVariable(mf, object, lang, variable); + } + return object; +} + +void Toolchains::DumpToolchainVariable(cmMakefile const* mf, + Json::Value& object, + std::string const& lang, + ToolchainVariable const& variable) +{ + std::string const variableName = + cmStrCat("CMAKE_", lang, "_", variable.VariableSuffix); + + if (variable.IsList) { + std::vector<std::string> values; + if (mf->GetDefExpandList(variableName, values)) { + Json::Value jsonArray = Json::arrayValue; + for (std::string const& value : values) { + jsonArray.append(value); + } + object[variable.ObjectKey] = jsonArray; + } + } else { + cmProp def = mf->GetDefinition(variableName); + if (def) { + object[variable.ObjectKey] = *def; + } + } +} +} + +Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, unsigned long version) +{ + Toolchains toolchains(fileAPI, version); + return toolchains.Dump(); +} diff --git a/Source/cmFileAPIToolchains.h b/Source/cmFileAPIToolchains.h new file mode 100644 index 0000000..c188807 --- /dev/null +++ b/Source/cmFileAPIToolchains.h @@ -0,0 +1,12 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +#include <cm3p/json/value.h> + +class cmFileAPI; + +extern Json::Value cmFileAPIToolchainsDump(cmFileAPI& fileAPI, + unsigned long version); diff --git a/Source/cmFilePathChecksum.cxx b/Source/cmFilePathChecksum.cxx index bb3f610..6b52230 100644 --- a/Source/cmFilePathChecksum.cxx +++ b/Source/cmFilePathChecksum.cxx @@ -16,15 +16,16 @@ cmFilePathChecksum::cmFilePathChecksum(std::string const& currentSrcDir, std::string const& projectSrcDir, std::string const& projectBinDir) { - setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, projectBinDir); + this->setupParentDirs(currentSrcDir, currentBinDir, projectSrcDir, + projectBinDir); } cmFilePathChecksum::cmFilePathChecksum(cmMakefile* makefile) { - setupParentDirs(makefile->GetCurrentSourceDirectory(), - makefile->GetCurrentBinaryDirectory(), - makefile->GetHomeDirectory(), - makefile->GetHomeOutputDirectory()); + this->setupParentDirs(makefile->GetCurrentSourceDirectory(), + makefile->GetCurrentBinaryDirectory(), + makefile->GetHomeDirectory(), + makefile->GetHomeOutputDirectory()); } void cmFilePathChecksum::setupParentDirs(std::string const& currentSrcDir, @@ -81,5 +82,5 @@ std::string cmFilePathChecksum::get(std::string const& filePath) const std::string cmFilePathChecksum::getPart(std::string const& filePath, size_t length) const { - return get(filePath).substr(0, length); + return this->get(filePath).substr(0, length); } diff --git a/Source/cmFileTimes.cxx b/Source/cmFileTimes.cxx index d8fe24c..bd896f5 100644 --- a/Source/cmFileTimes.cxx +++ b/Source/cmFileTimes.cxx @@ -62,14 +62,14 @@ public: cmFileTimes::cmFileTimes() = default; cmFileTimes::cmFileTimes(std::string const& fileName) { - Load(fileName); + this->Load(fileName); } cmFileTimes::~cmFileTimes() = default; bool cmFileTimes::Load(std::string const& fileName) { std::unique_ptr<Times> ptr; - if (IsValid()) { + if (this->IsValid()) { // Invalidate this and re-use times ptr.swap(this->times); } else { @@ -103,7 +103,7 @@ bool cmFileTimes::Load(std::string const& fileName) bool cmFileTimes::Store(std::string const& fileName) const { - if (!IsValid()) { + if (!this->IsValid()) { return false; } diff --git a/Source/cmFileTimes.h b/Source/cmFileTimes.h index f1916f7..50d64fd 100644 --- a/Source/cmFileTimes.h +++ b/Source/cmFileTimes.h @@ -19,7 +19,7 @@ public: ~cmFileTimes(); //! @return true, if file times were loaded successfully - bool IsValid() const { return (times != nullptr); } + bool IsValid() const { return (this->times != nullptr); } //! Try to load the file times from @a fileName and @return IsValid() bool Load(std::string const& fileName); //! Stores the file times at @a fileName (if IsValid()) diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx index 7952336..d2f9619 100644 --- a/Source/cmFindCommon.cxx +++ b/Source/cmFindCommon.cxx @@ -289,7 +289,7 @@ void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore) void cmFindCommon::GetIgnoredPaths(std::set<std::string>& ignore) { std::vector<std::string> ignoreVec; - GetIgnoredPaths(ignoreVec); + this->GetIgnoredPaths(ignoreVec); ignore.insert(ignoreVec.begin(), ignoreVec.end()); } diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx index b87dfe3..49b1bd7 100644 --- a/Source/cmFindLibraryCommand.cxx +++ b/Source/cmFindLibraryCommand.cxx @@ -31,7 +31,7 @@ cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status) // cmFindLibraryCommand bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn) { - this->DebugMode = ComputeIfDebugModeWanted(); + this->DebugMode = this->ComputeIfDebugModeWanted(); this->VariableDocumentation = "Path to a library."; this->CMakePathName = "LIBRARY"; if (!this->ParseArguments(argsIn)) { diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index 92b1e80..3b7cf4c 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -144,7 +144,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0], v[1], v[2]); } - this->DebugMode = ComputeIfDebugModeWanted(); + this->DebugMode = this->ComputeIfDebugModeWanted(); this->DebugBuffer.clear(); // Lookup target architecture, if any. @@ -534,7 +534,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args) loadedPackage = true; } else { // The package was not loaded. Report errors. - if (HandlePackageMode(HandlePackageModeType::Module)) { + if (this->HandlePackageMode(HandlePackageModeType::Module)) { loadedPackage = true; } } @@ -2070,8 +2070,8 @@ public: void SetSort(cmFindPackageCommand::SortOrderType o, cmFindPackageCommand::SortDirectionType d) { - SortOrder = o; - SortDirection = d; + this->SortOrder = o; + this->SortDirection = d; } protected: @@ -2102,8 +2102,8 @@ private: // before testing the matches check if there is a specific sorting order to // perform if (this->SortOrder != cmFindPackageCommand::None) { - cmFindPackageCommand::Sort(matches.begin(), matches.end(), SortOrder, - SortDirection); + cmFindPackageCommand::Sort(matches.begin(), matches.end(), + this->SortOrder, this->SortDirection); } for (std::string const& i : matches) { diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 4bab469..bece33b 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -22,7 +22,7 @@ cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status) // cmFindPathCommand bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn) { - this->DebugMode = ComputeIfDebugModeWanted(); + this->DebugMode = this->ComputeIfDebugModeWanted(); this->VariableDocumentation = "Path to a file."; this->CMakePathName = "INCLUDE"; if (!this->ParseArguments(argsIn)) { diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx index 77728ec..5bb4234 100644 --- a/Source/cmFindProgramCommand.cxx +++ b/Source/cmFindProgramCommand.cxx @@ -152,7 +152,7 @@ cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status) // cmFindProgramCommand bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn) { - this->DebugMode = ComputeIfDebugModeWanted(); + this->DebugMode = this->ComputeIfDebugModeWanted(); this->VariableDocumentation = "Path to a program."; this->CMakePathName = "PROGRAM"; // call cmFindBase::ParseArguments @@ -171,7 +171,7 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn) return true; } - std::string const result = FindProgram(); + std::string const result = this->FindProgram(); if (!result.empty()) { // Save the value in the cache this->Makefile->AddCacheDefinition(this->VariableName, result, @@ -198,7 +198,7 @@ std::string cmFindProgramCommand::FindProgram() std::string program; if (this->SearchAppBundleFirst || this->SearchAppBundleOnly) { - program = FindAppBundle(); + program = this->FindAppBundle(); } if (program.empty() && !this->SearchAppBundleOnly) { program = this->FindNormalProgram(); @@ -274,7 +274,7 @@ std::string cmFindProgramCommand::FindAppBundle() cmSystemTools::FindDirectory(appName, this->SearchPaths, true); if (!appPath.empty()) { - std::string executable = GetBundleExecutable(appPath); + std::string executable = this->GetBundleExecutable(appPath); if (!executable.empty()) { return cmSystemTools::CollapseFullPath(executable); } diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx index 96a562e..6436baa 100644 --- a/Source/cmGccDepfileReader.cxx +++ b/Source/cmGccDepfileReader.cxx @@ -12,40 +12,33 @@ #include "cmStringAlgorithms.h" #include "cmSystemTools.h" -cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath) -{ - cmGccDepfileLexerHelper helper; - if (helper.readFile(filePath)) { - return cm::make_optional(std::move(helper).extractContent()); - } - return cm::nullopt; -} - cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath, const std::string& prefix) { - auto deps = cmReadGccDepfile(filePath); - - if (prefix.empty() || !deps) { - return deps; + cmGccDepfileLexerHelper helper; + if (!helper.readFile(filePath)) { + return cm::nullopt; } + auto deps = cm::make_optional(std::move(helper).extractContent()); for (auto& dep : *deps) { for (auto& rule : dep.rules) { - if (!cmSystemTools::FileIsFullPath(rule)) { - rule = cmStrCat(prefix, rule); + if (!prefix.empty() && !cmSystemTools::FileIsFullPath(rule)) { + rule = cmStrCat(prefix, '/', rule); } if (cmSystemTools::FileIsFullPath(rule)) { rule = cmSystemTools::CollapseFullPath(rule); } + cmSystemTools::ConvertToLongPath(rule); } for (auto& path : dep.paths) { - if (!cmSystemTools::FileIsFullPath(path)) { - path = cmStrCat(prefix, path); + if (!prefix.empty() && !cmSystemTools::FileIsFullPath(path)) { + path = cmStrCat(prefix, '/', path); } if (cmSystemTools::FileIsFullPath(path)) { path = cmSystemTools::CollapseFullPath(path); } + cmSystemTools::ConvertToLongPath(path); } } diff --git a/Source/cmGccDepfileReader.h b/Source/cmGccDepfileReader.h index 66ff75d..c8a3748 100644 --- a/Source/cmGccDepfileReader.h +++ b/Source/cmGccDepfileReader.h @@ -8,10 +8,8 @@ #include "cmGccDepfileReaderTypes.h" -cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath); - /* * Read dependencies file and append prefix to all relative paths */ -cm::optional<cmGccDepfileContent> cmReadGccDepfile(const char* filePath, - const std::string& prefix); +cm::optional<cmGccDepfileContent> cmReadGccDepfile( + const char* filePath, const std::string& prefix = {}); diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 2768547..43f384a 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -14,11 +14,11 @@ #endif cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding) - : OriginalLocale(getloc()) + : OriginalLocale(this->getloc()) { #ifndef CMAKE_BOOTSTRAP if (encoding != codecvt::None) { - imbue(std::locale(OriginalLocale, new codecvt(encoding))); + this->imbue(std::locale(this->OriginalLocale, new codecvt(encoding))); } #else static_cast<void>(encoding); @@ -28,7 +28,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding) cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name, bool quiet, Encoding encoding) : cmGeneratedFileStreamBase(name) - , Stream(TempName.c_str()) + , Stream(this->TempName.c_str()) { // Check if the file opened. if (!*this && !quiet) { @@ -37,7 +37,7 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name, } #ifndef CMAKE_BOOTSTRAP if (encoding != codecvt::None) { - imbue(std::locale(getloc(), new codecvt(encoding))); + this->imbue(std::locale(this->getloc(), new codecvt(encoding))); } #else static_cast<void>(encoding); diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index e223f15..a1fce55 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -28,7 +28,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( , Backtrace(std::move(backtrace)) , TransitivePropertiesOnly(false) { - Initialize(); + this->Initialize(); } cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( @@ -42,7 +42,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( , Backtrace() , TransitivePropertiesOnly(false) { - Initialize(); + this->Initialize(); } void cmGeneratorExpressionDAGChecker::Initialize() @@ -52,7 +52,7 @@ void cmGeneratorExpressionDAGChecker::Initialize() #define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) top->METHOD() || - if (CheckResult == DAG && + if (this->CheckResult == DAG && (CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD( TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(*) #undef TEST_TRANSITIVE_PROPERTY_METHOD diff --git a/Source/cmGeneratorExpressionEvaluationFile.cxx b/Source/cmGeneratorExpressionEvaluationFile.cxx index af129d3..ec44df3 100644 --- a/Source/cmGeneratorExpressionEvaluationFile.cxx +++ b/Source/cmGeneratorExpressionEvaluationFile.cxx @@ -39,7 +39,7 @@ void cmGeneratorExpressionEvaluationFile::Generate( std::map<std::string, std::string>& outputFiles, mode_t perm) { std::string rawCondition = this->Condition->GetInput(); - cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(Target); + cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target); if (!rawCondition.empty()) { std::string condResult = this->Condition->Evaluate(lg, config, target, nullptr, nullptr, lang); @@ -95,7 +95,7 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile( { std::vector<std::string> enabledLanguages; cmGlobalGenerator* gg = lg->GetGlobalGenerator(); - cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(Target); + cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target); gg->GetEnabledLanguages(enabledLanguages); for (std::string const& le : enabledLanguages) { diff --git a/Source/cmGeneratorExpressionLexer.cxx b/Source/cmGeneratorExpressionLexer.cxx index a7f090a..b8c38c0 100644 --- a/Source/cmGeneratorExpressionLexer.cxx +++ b/Source/cmGeneratorExpressionLexer.cxx @@ -35,14 +35,14 @@ std::vector<cmGeneratorExpressionToken> cmGeneratorExpressionLexer::Tokenize( 2); upto = c + 2; ++c; - SawBeginExpression = true; + this->SawBeginExpression = true; } break; case '>': InsertText(upto, c, result); result.emplace_back(cmGeneratorExpressionToken::EndExpression, c, 1); upto = c + 1; - SawGeneratorExpression = SawBeginExpression; + this->SawGeneratorExpression = this->SawBeginExpression; break; case ':': InsertText(upto, c, result); diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index c2c9ef7..794c1a1 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -22,7 +22,7 @@ cmGeneratorExpressionParser::cmGeneratorExpressionParser( void cmGeneratorExpressionParser::Parse( cmGeneratorExpressionEvaluatorVector& result) { - it = this->Tokens.begin(); + this->it = this->Tokens.begin(); while (this->it != this->Tokens.end()) { this->ParseContent(result); diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index e2943d6..17d211e 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -557,7 +557,7 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const // Frameworks created by multi config generators can have a special // framework postfix. - frameworkPostfix = GetFrameworkMultiConfigPostfix(config); + frameworkPostfix = this->GetFrameworkMultiConfigPostfix(config); if (!frameworkPostfix.empty()) { postfix = &frameworkPostfix; } @@ -576,7 +576,7 @@ std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix( if (!this->IsImported() && postfix && (this->IsFrameworkOnApple() && - !GetGlobalGenerator()->IsMultiConfig())) { + !this->GetGlobalGenerator()->IsMultiConfig())) { postfix = nullptr; } } @@ -2503,7 +2503,7 @@ public: bool GetHadLinkLanguageSensitiveCondition() const { - return HadLinkLanguageSensitiveCondition; + return this->HadLinkLanguageSensitiveCondition; } private: @@ -3278,7 +3278,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const flags += " --cuda-gpu-arch=sm_" + architecture.name; if (!architecture.real) { - Makefile->IssueMessage( + this->Makefile->IssueMessage( MessageType::WARNING, "Clang doesn't support disabling CUDA real code generation."); } @@ -4968,7 +4968,7 @@ void cmGeneratorTarget::GetFullNameInternal( // the base, because the suffix ends up being used in Xcode's // EXECUTABLE_SUFFIX attribute. if (this->IsFrameworkOnApple() && - GetGlobalGenerator()->GetName() == "Xcode") { + this->GetGlobalGenerator()->GetName() == "Xcode") { targetSuffix = &configPostfix; } else { outBase += configPostfix; diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 51369c2..8fe70ab 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -585,7 +585,8 @@ public: std::string PdbDir; bool empty() const { - return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); + return this->OutDir.empty() && this->ImpDir.empty() && + this->PdbDir.empty(); } }; diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index aabe43c..a7658f2 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -62,7 +62,7 @@ void cmGhsMultiTargetGenerator::Generate() // Get the name of the executable to generate. this->TargetNameReal = this->GeneratorTarget->GetExecutableNames(this->ConfigName).Real; - if (cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()) { + if (this->cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()) { this->TagType = GhsMultiGpj::INTERGRITY_APPLICATION; } else { this->TagType = GhsMultiGpj::PROGRAM; @@ -631,7 +631,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) } } else { std::vector<cmSourceFile const*> customCommands; - if (ComputeCustomCommandOrder(customCommands)) { + if (this->ComputeCustomCommandOrder(customCommands)) { std::string message = "The custom commands for target [" + this->GeneratorTarget->GetName() + "] had a cycle.\n"; cmSystemTools::Error(message); @@ -745,7 +745,7 @@ bool cmGhsMultiTargetGenerator::ComputeCustomCommandOrder( this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName); for (cmSourceFile const* si : customCommands) { - bool r = VisitCustomCommand(temp, perm, order, si); + bool r = this->VisitCustomCommand(temp, perm, order, si); if (r) { return r; } diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 06943e7..996fcff 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -26,6 +26,15 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm) this->DefineWindowsNULL = true; this->PassMakeflags = true; this->UnixCD = false; + + /* + * Borland Make does not support long line depend rule, as we have tested + * generate one source file includes 40000 header files, and generate + * depend.make in one line(use line continued tag), and error occured: + * ** Fatal CMakeFiles\main.dir\depend.make 1224: Rule line too long ** + * we disable long line dependencies rule generation for Borland make + */ + this->ToolSupportsLongLineDependencies = false; } void cmGlobalBorlandMakefileGenerator::EnableLanguage( diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 69373bd..86fb228 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -69,17 +69,17 @@ struct GeneratedMakeCommand void Add(T&&... args) { // iterate the args and append each one - AppendStrs(PrimaryCommand, std::forward<T>(args)...); + AppendStrs(this->PrimaryCommand, std::forward<T>(args)...); } // Add each value in the iterators as a separate element to the vector void Add(std::vector<std::string>::const_iterator start, std::vector<std::string>::const_iterator end) { - cm::append(PrimaryCommand, start, end); + cm::append(this->PrimaryCommand, start, end); } - std::string Printable() const { return cmJoin(PrimaryCommand, " "); } + std::string Printable() const { return cmJoin(this->PrimaryCommand, " "); } std::vector<std::string> PrimaryCommand; bool RequiresOutputForward = false; @@ -501,7 +501,7 @@ public: cmSourceFile* sf) const; #if !defined(CMAKE_BOOTSTRAP) - cmFileLockPool& GetFileLockPool() { return FileLockPool; } + cmFileLockPool& GetFileLockPool() { return this->FileLockPool; } #endif bool GetConfigureDoneCMP0026() const diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 33bf830..0ddfe77 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -366,7 +366,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout, target->GetType() == cmStateEnums::MODULE_LIBRARY || target->GetType() == cmStateEnums::SHARED_LIBRARY || (target->GetType() == cmStateEnums::GLOBAL_TARGET && - target->GetName() != GetInstallTargetName())) { + target->GetName() != this->GetInstallTargetName())) { continue; } fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION @@ -415,7 +415,7 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root) target->GetType() == cmStateEnums::MODULE_LIBRARY || target->GetType() == cmStateEnums::SHARED_LIBRARY || (target->GetType() == cmStateEnums::GLOBAL_TARGET && - target->GetName() != GetInstallTargetName())) { + target->GetName() != this->GetInstallTargetName())) { continue; } @@ -427,13 +427,13 @@ void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root) this->WriteFileHeader(fbld); GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld); std::vector<cmGeneratorTarget const*> build; - if (ComputeTargetBuildOrder(target, build)) { + if (this->ComputeTargetBuildOrder(target, build)) { cmSystemTools::Error( cmStrCat("The inter-target dependency graph for target [", target->GetName(), "] had a cycle.\n")); } else { for (auto& tgt : build) { - WriteProjectLine(fbld, tgt, root, rootBinaryDir); + this->WriteProjectLine(fbld, tgt, root, rootBinaryDir); } } fbld.Close(); @@ -471,12 +471,12 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget( if (!t->IsInBuildSystem()) { continue; } - if (!IsExcluded(t->GetLocalGenerator(), t)) { + if (!this->IsExcluded(t->GetLocalGenerator(), t)) { defaultTargets.push_back(t); } } std::vector<cmGeneratorTarget const*> build; - if (ComputeTargetBuildOrder(defaultTargets, build)) { + if (this->ComputeTargetBuildOrder(defaultTargets, build)) { std::string message = "The inter-target dependency graph for project [" + root->GetProjectName() + "] had a cycle.\n"; cmSystemTools::Error(message); @@ -694,7 +694,7 @@ bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder( cmGeneratorTarget const* tgt, std::vector<cmGeneratorTarget const*>& build) { std::vector<cmGeneratorTarget const*> t{ tgt }; - return ComputeTargetBuildOrder(t, build); + return this->ComputeTargetBuildOrder(t, build); } bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder( @@ -705,7 +705,7 @@ bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder( std::set<cmGeneratorTarget const*> perm; for (auto const ti : tgt) { - bool r = VisitTarget(temp, perm, build, ti); + bool r = this->VisitTarget(temp, perm, build, ti); if (r) { return r; } diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index c4bec23..36f583f 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -21,6 +21,8 @@ cmGlobalNMakeMakefileGenerator::cmGlobalNMakeMakefileGenerator(cmake* cm) this->PassMakeflags = true; this->UnixCD = false; this->MakeSilentFlag = "/nologo"; + // nmake breaks on '!' in long-line dependencies + this->ToolSupportsLongLineDependencies = false; } void cmGlobalNMakeMakefileGenerator::EnableLanguage( diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index a098f81..4f17408 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -182,7 +182,7 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path) else std::replace(result.begin(), result.end(), '/', '\\'); #endif - result = EncodeLiteral(result); + result = this->EncodeLiteral(result); cmSystemTools::ReplaceString(result, " ", "$ "); cmSystemTools::ReplaceString(result, ":", "$:"); return result; @@ -214,7 +214,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, { // Write explicit outputs for (std::string const& output : build.Outputs) { - buildStr += cmStrCat(' ', EncodePath(output)); + buildStr += cmStrCat(' ', this->EncodePath(output)); if (this->ComputingUnknownDependencies) { this->CombinedBuildOutputs.insert(output); } @@ -223,7 +223,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, if (!build.ImplicitOuts.empty()) { buildStr += " |"; for (std::string const& implicitOut : build.ImplicitOuts) { - buildStr += cmStrCat(' ', EncodePath(implicitOut)); + buildStr += cmStrCat(' ', this->EncodePath(implicitOut)); } } buildStr += ':'; @@ -238,14 +238,14 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, // Write explicit dependencies. for (std::string const& explicitDep : build.ExplicitDeps) { - arguments += cmStrCat(' ', EncodePath(explicitDep)); + arguments += cmStrCat(' ', this->EncodePath(explicitDep)); } // Write implicit dependencies. if (!build.ImplicitDeps.empty()) { arguments += " |"; for (std::string const& implicitDep : build.ImplicitDeps) { - arguments += cmStrCat(' ', EncodePath(implicitDep)); + arguments += cmStrCat(' ', this->EncodePath(implicitDep)); } } @@ -253,7 +253,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, if (!build.OrderOnlyDeps.empty()) { arguments += " ||"; for (std::string const& orderOnlyDep : build.OrderOnlyDeps) { - arguments += cmStrCat(' ', EncodePath(orderOnlyDep)); + arguments += cmStrCat(' ', this->EncodePath(orderOnlyDep)); } } @@ -331,11 +331,11 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( #endif vars["COMMAND"] = std::move(cmd); } - vars["DESC"] = EncodeLiteral(description); + vars["DESC"] = this->EncodeLiteral(description); if (restat) { vars["restat"] = "1"; } - if (uses_terminal && SupportsConsolePool()) { + if (uses_terminal && this->SupportsConsolePool()) { vars["pool"] = "console"; } else if (!job_pool.empty()) { vars["pool"] = job_pool; @@ -362,7 +362,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( void cmGlobalNinjaGenerator::AddMacOSXContentRule() { cmNinjaRule rule("COPY_OSX_CONTENT"); - rule.Command = cmStrCat(CMakeCmd(), " -E copy $in $out"); + rule.Command = cmStrCat(this->CMakeCmd(), " -E copy $in $out"); rule.Description = "Copying OS X Content $out"; rule.Comment = "Rule for copying OS X bundle content file."; this->AddRule(rule); @@ -555,6 +555,7 @@ void cmGlobalNinjaGenerator::Generate() this->TargetAll = this->NinjaOutputPath("all"); this->CMakeCacheFile = this->NinjaOutputPath("CMakeCache.txt"); this->DisableCleandead = false; + this->DiagnosedCxxModuleSupport = false; this->PolicyCMP0058 = this->LocalGenerators[0]->GetMakefile()->GetPolicyStatus( @@ -755,6 +756,37 @@ bool cmGlobalNinjaGenerator::CheckLanguages( return true; } +bool cmGlobalNinjaGenerator::CheckCxxModuleSupport() +{ + bool const diagnose = !this->DiagnosedCxxModuleSupport && + !this->CMakeInstance->GetIsInTryCompile(); + if (diagnose) { + this->DiagnosedCxxModuleSupport = true; + this->GetCMakeInstance()->IssueMessage( + MessageType::AUTHOR_WARNING, + "C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP " + "is experimental. It is meant only for compiler developers to try."); + } + if (this->NinjaSupportsDyndeps) { + return true; + } + if (diagnose) { + std::ostringstream e; + /* clang-format off */ + e << + "The Ninja generator does not support C++20 modules " + "using Ninja version \n" + " " << this->NinjaVersion << "\n" + "due to lack of required features. " + "Ninja " << RequiredNinjaVersionForDyndeps() << " or higher is required." + ; + /* clang-format on */ + this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str()); + cmSystemTools::SetFatalErrorOccured(); + } + return false; +} + bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const { if (this->NinjaSupportsDyndeps) { @@ -766,7 +798,8 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const e << "The Ninja generator does not support Fortran using Ninja version\n" " " << this->NinjaVersion << "\n" - "due to lack of required features. Ninja 1.10 or higher is required." + "due to lack of required features. " + "Ninja " << RequiredNinjaVersionForDyndeps() << " or higher is required." ; /* clang-format on */ mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); @@ -785,7 +818,9 @@ bool cmGlobalNinjaGenerator::CheckISPC(cmMakefile* mf) const e << "The Ninja generator does not support ISPC using Ninja version\n" " " << this->NinjaVersion << "\n" - "due to lack of required features. Ninja 1.10 or higher is required." + "due to lack of required features. " + "Ninja " << RequiredNinjaVersionForMultipleOutputs() << + " or higher is required." ; /* clang-format on */ mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); @@ -1032,8 +1067,8 @@ static void EnsureTrailingSlash(std::string& path) std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath( const std::string& path) const { - auto const f = ConvertToNinjaPathCache.find(path); - if (f != ConvertToNinjaPathCache.end()) { + auto const f = this->ConvertToNinjaPathCache.find(path); + if (f != this->ConvertToNinjaPathCache.end()) { return f->second; } @@ -1045,7 +1080,7 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath( #ifdef _WIN32 std::replace(convPath.begin(), convPath.end(), '/', '\\'); #endif - return ConvertToNinjaPathCache.emplace(path, std::move(convPath)) + return this->ConvertToNinjaPathCache.emplace(path, std::move(convPath)) .first->second; } @@ -1117,12 +1152,13 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() cmNinjaDeps orderOnlyDeps; std::copy(asd.second.begin(), asd.second.end(), std::back_inserter(orderOnlyDeps)); - WriteCustomCommandBuild(/*command=*/"", /*description=*/"", - "Assume dependencies for generated source file.", - /*depfile*/ "", /*job_pool*/ "", - /*uses_terminal*/ false, - /*restat*/ true, cmNinjaDeps(1, asd.first), "", - cmNinjaDeps(), orderOnlyDeps); + this->WriteCustomCommandBuild( + /*command=*/"", /*description=*/"", + "Assume dependencies for generated source file.", + /*depfile*/ "", /*job_pool*/ "", + /*uses_terminal*/ false, + /*restat*/ true, cmNinjaDeps(1, asd.first), "", cmNinjaDeps(), + orderOnlyDeps); } } @@ -1147,7 +1183,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs( case cmStateEnums::STATIC_LIBRARY: case cmStateEnums::MODULE_LIBRARY: { if (depends == DependOnTargetOrdering) { - outputs.push_back(OrderDependsTargetForTarget(target, config)); + outputs.push_back(this->OrderDependsTargetForTarget(target, config)); break; } } @@ -1159,7 +1195,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs( } case cmStateEnums::OBJECT_LIBRARY: { if (depends == DependOnTargetOrdering) { - outputs.push_back(OrderDependsTargetForTarget(target, config)); + outputs.push_back(this->OrderDependsTargetForTarget(target, config)); break; } } @@ -1476,7 +1512,7 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config); configDeps.emplace_back(build.Outputs.front()); for (DirectoryTarget::Target const& t : dt.Targets) { - if (!IsExcludedFromAllInConfig(t, config)) { + if (!this->IsExcludedFromAllInConfig(t, config)) { this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config, DependOnTargetArtifact); } @@ -1689,7 +1725,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) { cmNinjaRule rule("RERUN_CMAKE"); rule.Command = - cmStrCat(CMakeCmd(), " --regenerate-during-build -S", + cmStrCat(this->CMakeCmd(), " --regenerate-during-build -S", lg->ConvertToOutputFormat(lg->GetSourceDirectory(), cmOutputConverter::SHELL), " -B", @@ -1714,7 +1750,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) // Use 'console' pool to get non buffered output of the CMake re-run call // Available since Ninja 1.5 - if (SupportsConsolePool()) { + if (this->SupportsConsolePool()) { reBuild.Variables["pool"] = "console"; } @@ -1723,7 +1759,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) { cmNinjaRule rule("VERIFY_GLOBS"); rule.Command = - cmStrCat(CMakeCmd(), " -P ", + cmStrCat(this->CMakeCmd(), " -P ", lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(), cmOutputConverter::SHELL)); rule.Description = "Re-checking globbed directories..."; @@ -1784,8 +1820,8 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) build.Comment = "A missing CMake input file is not an error."; std::set_difference(std::make_move_iterator(reBuild.ImplicitDeps.begin()), std::make_move_iterator(reBuild.ImplicitDeps.end()), - CustomCommandOutputs.begin(), - CustomCommandOutputs.end(), + this->CustomCommandOutputs.begin(), + this->CustomCommandOutputs.end(), std::back_inserter(build.Outputs)); this->WriteBuild(os, build); } @@ -1869,7 +1905,8 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) fout << " file(REMOVE_RECURSE\n"; for (std::string const& acf : it->second.AdditionalCleanFiles) { fout << " " - << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf)) + << cmOutputConverter::EscapeForCMake( + this->ConvertToNinjaPath(acf)) << '\n'; } fout << " )\n"; @@ -1884,7 +1921,7 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) { cmNinjaRule rule("CLEAN_ADDITIONAL"); rule.Command = cmStrCat( - CMakeCmd(), " -DCONFIG=$CONFIG -P ", + this->CMakeCmd(), " -DCONFIG=$CONFIG -P ", lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel), cmOutputConverter::SHELL)); rule.Description = "Cleaning additional files..."; @@ -1901,13 +1938,13 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) build.Outputs.front() = this->BuildAlias( this->NinjaOutputPath(this->GetAdditionalCleanTargetName()), config); build.Variables["CONFIG"] = config; - WriteBuild(os, build); + this->WriteBuild(os, build); } if (this->IsMultiConfig()) { build.Outputs.front() = this->NinjaOutputPath(this->GetAdditionalCleanTargetName()); build.Variables["CONFIG"] = ""; - WriteBuild(os, build); + this->WriteBuild(os, build); } } // Return success @@ -1917,13 +1954,13 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) { // -- Additional clean target - bool additionalFiles = WriteTargetCleanAdditional(os); + bool additionalFiles = this->WriteTargetCleanAdditional(os); // -- Default clean target // Write rule { cmNinjaRule rule("CLEAN"); - rule.Command = cmStrCat(NinjaCmd(), " $FILE_ARG -t clean $TARGETS"); + rule.Command = cmStrCat(this->NinjaCmd(), " $FILE_ARG -t clean $TARGETS"); rule.Description = "Cleaning all built files..."; rule.Comment = "Rule for cleaning all built files."; WriteRule(*this->RulesFileStream, rule); @@ -2024,13 +2061,13 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) build.Outputs.emplace_back( this->ConvertToNinjaPath(GetByproductsForCleanTargetName())); build.ExplicitDeps = this->ByproductsForCleanTarget; - WriteBuild(os, build); + this->WriteBuild(os, build); for (auto const& config : configs) { build.Outputs.front() = this->BuildAlias( this->ConvertToNinjaPath(GetByproductsForCleanTargetName()), config); build.ExplicitDeps = this->Configs[config].ByproductsForCleanTarget; - WriteBuild(os, build); + this->WriteBuild(os, build); } } } @@ -2039,7 +2076,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) { { cmNinjaRule rule("HELP"); - rule.Command = cmStrCat(NinjaCmd(), " -t targets"); + rule.Command = cmStrCat(this->NinjaCmd(), " -t targets"); rule.Description = "All primary targets available:"; rule.Comment = "Rule for printing all primary targets available."; WriteRule(*this->RulesFileStream, rule); @@ -2048,7 +2085,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) cmNinjaBuild build("HELP"); build.Comment = "Print all primary targets available."; build.Outputs.push_back(this->NinjaOutputPath("help")); - WriteBuild(os, build); + this->WriteBuild(os, build); } } @@ -2334,7 +2371,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( std::string const& arg_dd, std::vector<std::string> const& arg_ddis, std::string const& module_dir, std::vector<std::string> const& linked_target_dirs, - std::string const& arg_lang) + std::string const& arg_lang, std::string const& arg_modmapfmt) { // Setup path conversions. { @@ -2421,6 +2458,48 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( build.Variables.emplace("restat", "1"); } + if (arg_modmapfmt.empty()) { + // nothing to do. + } else { + std::stringstream mm; + if (arg_modmapfmt == "gcc") { + // Documented in GCC's documentation. The format is a series of lines + // with a module name and the associated filename separated by + // spaces. The first line may use `$root` as the module name to + // specify a "repository root". That is used to anchor any relative + // paths present in the file (CMake should never generate any). + + // Write the root directory to use for module paths. + mm << "$root .\n"; + + for (auto const& l : object.Provides) { + auto m = mod_files.find(l.LogicalName); + if (m != mod_files.end()) { + mm << l.LogicalName << " " << this->ConvertToNinjaPath(m->second) + << "\n"; + } + } + for (auto const& r : object.Requires) { + auto m = mod_files.find(r.LogicalName); + if (m != mod_files.end()) { + mm << r.LogicalName << " " << this->ConvertToNinjaPath(m->second) + << "\n"; + } + } + } else { + cmSystemTools::Error( + cmStrCat("-E cmake_ninja_dyndep does not understand the ", + arg_modmapfmt, " module map format")); + return false; + } + + // XXX(modmap): If changing this path construction, change + // `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the + // corresponding file path. + cmGeneratedFileStream mmf(cmStrCat(object.PrimaryOutput, ".modmap")); + mmf << mm.str(); + } + this->WriteBuild(ddf, build); } } @@ -2444,6 +2523,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg, std::string arg_dd; std::string arg_lang; std::string arg_tdi; + std::string arg_modmapfmt; std::vector<std::string> arg_ddis; for (std::string const& arg : arg_full) { if (cmHasLiteralPrefix(arg, "--tdi=")) { @@ -2452,6 +2532,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg, arg_lang = arg.substr(7); } else if (cmHasLiteralPrefix(arg, "--dd=")) { arg_dd = arg.substr(5); + } else if (cmHasLiteralPrefix(arg, "--modmapfmt=")) { + arg_modmapfmt = arg.substr(12); } else if (!cmHasLiteralPrefix(arg, "--") && cmHasLiteralSuffix(arg, ".ddi")) { arg_ddis.push_back(arg); @@ -2510,7 +2592,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg, if (!ggd || !cm::static_reference_cast<cmGlobalNinjaGenerator>(ggd).WriteDyndepFile( dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis, - module_dir, linked_target_dirs, arg_lang)) { + module_dir, linked_target_dirs, arg_lang, arg_modmapfmt)) { return 1; } return 0; diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 5e9defe..fd8542f 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -150,7 +150,7 @@ public: static void WriteDefault(std::ostream& os, const cmNinjaDeps& targets, const std::string& comment = ""); - bool IsGCCOnWindows() const { return UsingGCCOnWindows; } + bool IsGCCOnWindows() const { return this->UsingGCCOnWindows; } public: cmGlobalNinjaGenerator(cmake* cm); @@ -354,7 +354,10 @@ public: outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE)); } - int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; } + int GetRuleCmdLength(const std::string& name) + { + return this->RuleCmdLength[name]; + } void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target, const std::string& config); @@ -393,15 +396,13 @@ public: bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); } void StripNinjaOutputPathPrefixAsSuffix(std::string& path); - bool WriteDyndepFile(std::string const& dir_top_src, - std::string const& dir_top_bld, - std::string const& dir_cur_src, - std::string const& dir_cur_bld, - std::string const& arg_dd, - std::vector<std::string> const& arg_ddis, - std::string const& module_dir, - std::vector<std::string> const& linked_target_dirs, - std::string const& arg_lang); + bool WriteDyndepFile( + std::string const& dir_top_src, std::string const& dir_top_bld, + std::string const& dir_cur_src, std::string const& dir_cur_bld, + std::string const& arg_dd, std::vector<std::string> const& arg_ddis, + std::string const& module_dir, + std::vector<std::string> const& linked_target_dirs, + std::string const& arg_lang, std::string const& arg_modmapfmt); virtual std::string BuildAlias(const std::string& alias, const std::string& /*config*/) const @@ -445,6 +446,8 @@ public: bool IsSingleConfigUtility(cmGeneratorTarget const* target) const; + bool CheckCxxModuleSupport(); + protected: void Generate() override; @@ -565,6 +568,8 @@ private: bool NinjaSupportsMultipleOutputs = false; bool NinjaSupportsMetadataOnRegeneration = false; + bool DiagnosedCxxModuleSupport = false; + private: void InitOutputPathPrefix(); diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 11e2cd6..97384cd 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -838,7 +838,7 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks() for (const auto& gt : lg->GetGeneratorTargets()) { cmLocalGenerator* tlg = gt->GetLocalGenerator(); - if (!gt->IsInBuildSystem() || IsExcluded(lg.get(), gt.get())) { + if (!gt->IsInBuildSystem() || this->IsExcluded(lg.get(), gt.get())) { continue; } diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 09679a7..c15f491 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -139,6 +139,12 @@ public: return this->ToolSupportsCompilerDependencies; } + // Make tool supports long line dependencies + bool SupportsLongLineDependencies() + { + return this->ToolSupportsLongLineDependencies; + } + /** Get the command to use for a target that has no rule. This is used for multiple output dependencies and for cmake_force. */ std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; } @@ -235,6 +241,10 @@ protected: // generated by the compiler bool ToolSupportsCompilerDependencies = true; + // some Make generator, such as Borland not support long line dependencies, + // we add SupportsLongLineDependencies to predicate. + bool ToolSupportsLongLineDependencies = true; + // Some make programs (Borland) do not keep a rule if there are no // dependencies or commands. This is a problem for creating rules // that might not do anything but might have other dependencies diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index e17c6d7..b46f1b9 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -253,6 +253,12 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion( // If value is an invalid pointer, leave result unchanged. } + return this->GetWindows10SDKMaxVersionDefault(mf); +} + +std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersionDefault( + cmMakefile*) const +{ // The last Windows 10 SDK version that VS 2015 can target is 10.0.14393.0. // // "VS 2015 Users: The Windows 10 SDK (15063, 16299, 17134, 17763) is diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h index 1ccd4c7..7804b83 100644 --- a/Source/cmGlobalVisualStudio14Generator.h +++ b/Source/cmGlobalVisualStudio14Generator.h @@ -40,9 +40,13 @@ protected: // of the toolset is installed bool IsWindowsStoreToolsetInstalled() const; + // Used to adjust the max-SDK-version calculation to accommodate user + // configuration. + std::string GetWindows10SDKMaxVersion(cmMakefile* mf) const; + // Used to make sure that the Windows 10 SDK selected can work with the // version of the toolset. - virtual std::string GetWindows10SDKMaxVersion(cmMakefile* mf) const; + virtual std::string GetWindows10SDKMaxVersionDefault(cmMakefile* mf) const; virtual bool SelectWindows10SDK(cmMakefile* mf, bool required); diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index a713dc4..e6c65bb 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -541,7 +541,8 @@ bool cmGlobalVisualStudioVersionedGenerator::IsWin81SDKInstalled() const return false; } -std::string cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersion( +std::string +cmGlobalVisualStudioVersionedGenerator::GetWindows10SDKMaxVersionDefault( cmMakefile*) const { return std::string(); diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h index af09cbd..46a5f40 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.h +++ b/Source/cmGlobalVisualStudioVersionedGenerator.h @@ -56,7 +56,7 @@ protected: // Check for a Win 8 SDK known to the registry or VS installer tool. bool IsWin81SDKInstalled() const; - std::string GetWindows10SDKMaxVersion(cmMakefile*) const override; + std::string GetWindows10SDKMaxVersionDefault(cmMakefile*) const override; std::string FindMSBuildCommand() override; std::string FindDevEnvCommand() override; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index d59d382..8a1ccd1 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -18,6 +18,7 @@ #include "cmsys/RegularExpression.hxx" #include "cmComputeLinkInformation.h" +#include "cmCryptoHash.h" #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" #include "cmCustomCommandLines.h" @@ -798,9 +799,10 @@ void cmGlobalXCodeGenerator::addObject(std::unique_ptr<cmXCodeObject> obj) } cmXCodeObject* cmGlobalXCodeGenerator::CreateObject( - cmXCodeObject::PBXType ptype) + cmXCodeObject::PBXType ptype, cm::string_view key) { - auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT); + auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT, + this->GetObjectId(ptype, key)); auto ptr = obj.get(); this->addObject(std::move(obj)); return ptr; @@ -808,7 +810,9 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateObject( cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type) { - auto obj = cm::make_unique<cmXCodeObject>(cmXCodeObject::None, type); + auto obj = cm::make_unique<cmXCodeObject>( + cmXCodeObject::None, type, + "Temporary cmake object, should not be referred to in Xcode file"); auto ptr = obj.get(); this->addObject(std::move(obj)); return ptr; @@ -1739,13 +1743,13 @@ void cmGlobalXCodeGenerator::CreateCustomCommands( if (this->XcodeBuildSystem >= BuildSystem::Twelve) { // create prebuild phase preBuildPhase = - this->CreateRunScriptBuildPhase("CMake PreBuild Rules", prebuild); + this->CreateRunScriptBuildPhase("CMake PreBuild Rules", gtgt, prebuild); // create prelink phase preLinkPhase = - this->CreateRunScriptBuildPhase("CMake PreLink Rules", prelink); + this->CreateRunScriptBuildPhase("CMake PreLink Rules", gtgt, prelink); // create postbuild phase - postBuildPhase = - this->CreateRunScriptBuildPhase("CMake PostBuild Rules", postbuild); + postBuildPhase = this->CreateRunScriptBuildPhase("CMake PostBuild Rules", + gtgt, postbuild); } else { std::vector<cmSourceFile*> classes; if (!gtgt->GetConfigCommonSourceFilesForXcode(classes)) { @@ -1877,7 +1881,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase( } cmXCodeObject* buildPhase = - this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase); + this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase, + cmStrCat(gt->GetName(), ':', sf->GetFullPath())); buildPhase->AddAttribute("buildActionMask", this->CreateString("2147483647")); cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); @@ -1936,7 +1941,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase( } cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase( - std::string const& name, std::vector<cmCustomCommand> const& commands) + std::string const& name, cmGeneratorTarget const* gt, + std::vector<cmCustomCommand> const& commands) { if (commands.empty()) { return nullptr; @@ -1959,7 +1965,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateRunScriptBuildPhase( } cmXCodeObject* buildPhase = - this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase); + this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase, + cmStrCat(gt->GetName(), ':', name)); buildPhase->AddAttribute("buildActionMask", this->CreateString("2147483647")); cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); @@ -2927,8 +2934,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt, cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget( cmGeneratorTarget* gtgt) { - cmXCodeObject* shellBuildPhase = - this->CreateObject(cmXCodeObject::PBXShellScriptBuildPhase); + cmXCodeObject* shellBuildPhase = this->CreateObject( + cmXCodeObject::PBXShellScriptBuildPhase, gtgt->GetName()); shellBuildPhase->AddAttribute("buildActionMask", this->CreateString("2147483647")); cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); @@ -3156,6 +3163,32 @@ cmXCodeObject* cmGlobalXCodeGenerator::FindXCodeTarget( return i->second; } +std::string cmGlobalXCodeGenerator::GetObjectId(cmXCodeObject::PBXType ptype, + cm::string_view key) +{ + std::string objectId; + if (!key.empty()) { + cmCryptoHash hash(cmCryptoHash::AlgoSHA256); + hash.Initialize(); + hash.Append(&ptype, sizeof(ptype)); + hash.Append(key); + objectId = cmSystemTools::UpperCase(hash.FinalizeHex().substr(0, 24)); + } else { + char cUuid[40] = { 0 }; + CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); + CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, uuid); + CFStringGetCString(s, cUuid, sizeof(cUuid), kCFStringEncodingUTF8); + objectId = cUuid; + CFRelease(s); + CFRelease(uuid); + cmSystemTools::ReplaceString(objectId, "-", ""); + if (objectId.size() > 24) { + objectId = objectId.substr(0, 24); + } + } + return objectId; +} + std::string cmGlobalXCodeGenerator::GetOrCreateId(const std::string& name, const std::string& id) { diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 14db1dc..1ab56e2 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -11,6 +11,8 @@ #include <string> #include <vector> +#include <cm/string_view> + #include "cmGlobalGenerator.h" #include "cmXCodeObject.h" @@ -162,11 +164,13 @@ private: const std::string& configName); cmXCodeObject* FindXCodeTarget(const cmGeneratorTarget*); + std::string GetObjectId(cmXCodeObject::PBXType ptype, cm::string_view key); std::string GetOrCreateId(const std::string& name, const std::string& id); // create cmXCodeObject from these functions so that memory can be managed // correctly. All objects created are stored in this->XCodeObjects. - cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype); + cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype, + cm::string_view key = {}); cmXCodeObject* CreateObject(cmXCodeObject::Type type); cmXCodeObject* CreateString(const std::string& s); cmXCodeObject* CreateObjectReference(cmXCodeObject*); @@ -256,7 +260,8 @@ private: cmGeneratorTarget const* gt, cmCustomCommand const& cc); cmXCodeObject* CreateRunScriptBuildPhase( - std::string const& name, std::vector<cmCustomCommand> const& commands); + std::string const& name, cmGeneratorTarget const* gt, + std::vector<cmCustomCommand> const& commands); std::string ConstructScript(cmCustomCommandGenerator const& ccg); void CreateReRunCMakeFile(cmLocalGenerator* root, std::vector<cmLocalGenerator*> const& gens); diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index cf4ba93..92ffe29 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -131,8 +131,8 @@ cmGraphVizWriter::~cmGraphVizWriter() void cmGraphVizWriter::VisitGraph(std::string const&) { - this->WriteHeader(GlobalFileStream, this->GraphName); - this->WriteLegend(GlobalFileStream); + this->WriteHeader(this->GlobalFileStream, this->GraphName); + this->WriteLegend(this->GlobalFileStream); } void cmGraphVizWriter::OnItem(cmLinkItem const& item) @@ -141,8 +141,9 @@ void cmGraphVizWriter::OnItem(cmLinkItem const& item) return; } - NodeNames[item.AsStr()] = cmStrCat(GraphNodePrefix, NextNodeId); - ++NextNodeId; + this->NodeNames[item.AsStr()] = + cmStrCat(this->GraphNodePrefix, this->NextNodeId); + ++this->NextNodeId; this->WriteNode(this->GlobalFileStream, item); } @@ -191,12 +192,13 @@ void cmGraphVizWriter::VisitLink(cmLinkItem const& depender, this->WriteConnection(this->GlobalFileStream, depender, dependee, scopeType); if (this->GeneratePerTarget) { - PerTargetConnections[depender].emplace_back(depender, dependee, scopeType); + this->PerTargetConnections[depender].emplace_back(depender, dependee, + scopeType); } if (this->GenerateDependers) { - TargetDependersConnections[dependee].emplace_back(dependee, depender, - scopeType); + this->TargetDependersConnections[dependee].emplace_back(dependee, depender, + scopeType); } } @@ -307,12 +309,12 @@ void cmGraphVizWriter::Write() } if (this->GeneratePerTarget) { - WritePerTargetConnections<DependeesDir>(PerTargetConnections); + this->WritePerTargetConnections<DependeesDir>(this->PerTargetConnections); } if (this->GenerateDependers) { - WritePerTargetConnections<DependersDir>(TargetDependersConnections, - ".dependers"); + this->WritePerTargetConnections<DependersDir>( + this->TargetDependersConnections, ".dependers"); } } @@ -336,7 +338,8 @@ void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap, bool const visited = visitedItems.find(dstItem) != visitedItems.cend(); if (!visited) { visitedItems.insert(dstItem); - FindAllConnections(connectionMap, dstItem, extendedCons, visitedItems); + this->FindAllConnections(connectionMap, dstItem, extendedCons, + visitedItems); } } } @@ -346,7 +349,8 @@ void cmGraphVizWriter::FindAllConnections(const ConnectionsMap& connectionMap, Connections& extendedCons) { std::set<cmLinkItem> visitedItems = { rootItem }; - FindAllConnections(connectionMap, rootItem, extendedCons, visitedItems); + this->FindAllConnections(connectionMap, rootItem, extendedCons, + visitedItems); } template <typename DirFunc> @@ -358,7 +362,7 @@ void cmGraphVizWriter::WritePerTargetConnections( for (auto const& conPerTarget : connections) { const cmLinkItem& rootItem = conPerTarget.first; Connections& extendedCons = extendedConnections[conPerTarget.first]; - FindAllConnections(connections, rootItem, extendedCons); + this->FindAllConnections(connections, rootItem, extendedCons); } for (auto const& conPerTarget : extendedConnections) { @@ -451,7 +455,7 @@ void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs, auto const& itemName = item.AsStr(); auto const& nodeName = this->NodeNames[itemName]; - auto const itemNameWithAliases = ItemNameWithAliases(itemName); + auto const itemNameWithAliases = this->ItemNameWithAliases(itemName); auto const escapedLabel = EscapeForDotFile(itemNameWithAliases); fs << " \"" << nodeName << "\" [ label = \"" << escapedLabel diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx index 175e7cf..0b45f28 100644 --- a/Source/cmInstallDirectoryGenerator.cxx +++ b/Source/cmInstallDirectoryGenerator.cxx @@ -27,7 +27,7 @@ cmInstallDirectoryGenerator::cmInstallDirectoryGenerator( , Optional(optional) { // We need per-config actions if destination have generator expressions. - if (cmGeneratorExpression::Find(Destination) != std::string::npos) { + if (cmGeneratorExpression::Find(this->Destination) != std::string::npos) { this->ActionsPerConfig = true; } diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 6e3508c..3683ada 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -122,10 +122,10 @@ size_t cmInstallExportGenerator::GetMaxConfigLength() const void cmInstallExportGenerator::GenerateScript(std::ostream& os) { // Skip empty sets. - if (ExportSet->GetTargetExports().empty()) { + if (this->ExportSet->GetTargetExports().empty()) { std::ostringstream e; - e << "INSTALL(EXPORT) given unknown export \"" << ExportSet->GetName() - << "\""; + e << "INSTALL(EXPORT) given unknown export \"" + << this->ExportSet->GetName() << "\""; cmSystemTools::Error(e.str()); return; } diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx index ad2f84e..0a353e4 100644 --- a/Source/cmInstallFilesGenerator.cxx +++ b/Source/cmInstallFilesGenerator.cxx @@ -25,8 +25,12 @@ cmInstallFilesGenerator::cmInstallFilesGenerator( , Programs(programs) , Optional(optional) { - // We need per-config actions if the destination has generator expressions. - if (cmGeneratorExpression::Find(Destination) != std::string::npos) { + // We need per-config actions if the destination and rename have generator + // expressions. + if (cmGeneratorExpression::Find(this->Destination) != std::string::npos) { + this->ActionsPerConfig = true; + } + if (cmGeneratorExpression::Find(this->Rename) != std::string::npos) { this->ActionsPerConfig = true; } @@ -56,6 +60,12 @@ std::string cmInstallFilesGenerator::GetDestination( this->LocalGenerator, config); } +std::string cmInstallFilesGenerator::GetRename(std::string const& config) const +{ + return cmGeneratorExpression::Evaluate(this->Rename, this->LocalGenerator, + config); +} + void cmInstallFilesGenerator::AddFilesInstallRule( std::ostream& os, std::string const& config, Indent indent, std::vector<std::string> const& files) @@ -66,7 +76,7 @@ void cmInstallFilesGenerator::AddFilesInstallRule( os, this->GetDestination(config), (this->Programs ? cmInstallType_PROGRAMS : cmInstallType_FILES), files, this->Optional, this->FilePermissions.c_str(), no_dir_permissions, - this->Rename.c_str(), nullptr, indent); + this->GetRename(config).c_str(), nullptr, indent); } void cmInstallFilesGenerator::GenerateScriptActions(std::ostream& os, diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h index b5a1ef4..66145f4 100644 --- a/Source/cmInstallFilesGenerator.h +++ b/Source/cmInstallFilesGenerator.h @@ -31,6 +31,7 @@ public: bool Compute(cmLocalGenerator* lg) override; std::string GetDestination(std::string const& config) const; + std::string GetRename(std::string const& config) const; protected: void GenerateScriptActions(std::ostream& os, Indent indent) override; diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx index 7cdf3b4..ce2472d 100644 --- a/Source/cmInstallScriptGenerator.cxx +++ b/Source/cmInstallScriptGenerator.cxx @@ -22,7 +22,7 @@ cmInstallScriptGenerator::cmInstallScriptGenerator( , AllowGenex(false) { // We need per-config actions if the script has generator expressions. - if (cmGeneratorExpression::Find(Script) != std::string::npos) { + if (cmGeneratorExpression::Find(this->Script) != std::string::npos) { this->ActionsPerConfig = true; } } diff --git a/Source/cmLinkedTree.h b/Source/cmLinkedTree.h index d70176d..616bf7e 100644 --- a/Source/cmLinkedTree.h +++ b/Source/cmLinkedTree.h @@ -133,9 +133,9 @@ public: return iterator(const_cast<cmLinkedTree*>(this), 0); } - iterator Push(iterator it) { return Push_impl(it, T()); } + iterator Push(iterator it) { return this->Push_impl(it, T()); } - iterator Push(iterator it, T t) { return Push_impl(it, std::move(t)); } + iterator Push(iterator it, T t) { return this->Push_impl(it, std::move(t)); } bool IsLast(iterator it) { return it.Position == this->Data.size(); } diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx index a2c14bd..fdddb45 100644 --- a/Source/cmListCommand.cxx +++ b/Source/cmListCommand.cxx @@ -422,9 +422,10 @@ bool HandleJoinCommand(std::vector<std::string> const& args, bool HandleRemoveItemCommand(std::vector<std::string> const& args, cmExecutionStatus& status) { - if (args.size() < 3) { - status.SetError("sub-command REMOVE_ITEM requires two or more arguments."); - return false; + assert(args.size() >= 2); + + if (args.size() == 2) { + return true; } const std::string& listName = args[1]; @@ -609,9 +610,9 @@ public: bool Validate(std::size_t count) override { - decltype(Indexes) indexes; + decltype(this->Indexes) indexes; - for (auto index : Indexes) { + for (auto index : this->Indexes) { indexes.push_back(this->NormalizeIndex(index, count)); } this->Indexes = std::move(indexes); @@ -750,7 +751,7 @@ bool HandleTransformCommand(std::vector<std::string> const& args, { } - operator const std::string&() const { return Name; } + operator const std::string&() const { return this->Name; } std::string Name; int Arity = 0; @@ -1093,8 +1094,9 @@ protected: public: cmStringSorter(Compare compare, CaseSensitivity caseSensitivity, Order desc = Order::ASCENDING) - : filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) } - , sortMethod(GetComparisonFunction(compare)) + : filters{ this->GetCompareFilter(compare), + this->GetCaseFilter(caseSensitivity) } + , sortMethod(this->GetComparisonFunction(compare)) , descending(desc == Order::DESCENDING) { } @@ -1102,7 +1104,7 @@ public: std::string ApplyFilter(const std::string& argument) { std::string result = argument; - for (auto filter : filters) { + for (auto filter : this->filters) { if (filter != nullptr) { result = filter(result); } @@ -1112,13 +1114,13 @@ public: bool operator()(const std::string& a, const std::string& b) { - std::string af = ApplyFilter(a); - std::string bf = ApplyFilter(b); + std::string af = this->ApplyFilter(a); + std::string bf = this->ApplyFilter(b); bool result; - if (descending) { - result = sortMethod(bf, af); + if (this->descending) { + result = this->sortMethod(bf, af); } else { - result = sortMethod(af, bf); + result = this->sortMethod(af, bf); } return result; } @@ -1424,7 +1426,7 @@ public: bool operator()(const std::string& target) { - return regex.find(target) ^ includeMatches; + return this->regex.find(target) ^ this->includeMatches; } private: diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx index 3658d11..36a1372 100644 --- a/Source/cmListFileCache.cxx +++ b/Source/cmListFileCache.cxx @@ -105,7 +105,7 @@ bool cmListFileParser::ParseFile(const char* filename) return false; } - return Parse(); + return this->Parse(); } bool cmListFileParser::ParseString(const char* str, @@ -118,7 +118,7 @@ bool cmListFileParser::ParseString(const char* str, return false; } - return Parse(); + return this->Parse(); } bool cmListFileParser::Parse() diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h index ed45c07..98cb4a7 100644 --- a/Source/cmListFileCache.h +++ b/Source/cmListFileCache.h @@ -249,7 +249,7 @@ public: BTs(T v = T(), cmListFileBacktrace bt = cmListFileBacktrace()) : Value(std::move(v)) { - Backtraces.emplace_back(std::move(bt)); + this->Backtraces.emplace_back(std::move(bt)); } T Value; std::vector<cmListFileBacktrace> Backtraces; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index b329e4b..86eddc2 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -2607,11 +2607,11 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target) } if (editAndContinueDebugInfo || msvc2008OrLess) { - CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget, - { ".pdb", ".idb" }); + this->CopyPchCompilePdb(config, target, *ReuseFrom, + reuseTarget, { ".pdb", ".idb" }); } else if (enableDebuggingInformation) { - CopyPchCompilePdb(config, target, *ReuseFrom, reuseTarget, - { ".pdb" }); + this->CopyPchCompilePdb(config, target, *ReuseFrom, + reuseTarget, { ".pdb" }); } } diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index b035f70..7229101 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -557,9 +557,13 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines( std::string launcher = this->MakeCustomLauncher(ccg); for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) { + std::string c = ccg.GetCommand(i); + if (c.empty()) { + continue; + } cmdLines.push_back(launcher + this->ConvertToOutputFormat( - ccg.GetCommand(i), + c, gg->IsMultiConfig() ? cmOutputConverter::NINJAMULTI : cmOutputConverter::SHELL)); @@ -689,13 +693,11 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } } -namespace { -bool HasUniqueByproducts(cmLocalGenerator& lg, - std::vector<std::string> const& byproducts, - cmListFileBacktrace const& bt) +bool cmLocalNinjaGenerator::HasUniqueByproducts( + std::vector<std::string> const& byproducts, cmListFileBacktrace const& bt) { std::vector<std::string> configs = - lg.GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); + this->GetMakefile()->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig); cmGeneratorExpression ge(bt); for (std::string const& p : byproducts) { if (cmGeneratorExpression::Find(p) == std::string::npos) { @@ -705,7 +707,7 @@ bool HasUniqueByproducts(cmLocalGenerator& lg, std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(p); for (std::string const& config : configs) { for (std::string const& b : - lg.ExpandCustomCommandOutputPaths(*cge, config)) { + this->ExpandCustomCommandOutputPaths(*cge, config)) { if (!seen.insert(b).second) { return false; } @@ -715,6 +717,7 @@ bool HasUniqueByproducts(cmLocalGenerator& lg, return true; } +namespace { bool HasUniqueOutputs(std::vector<cmCustomCommandGenerator> const& ccgs) { std::set<std::string> allOutputs; @@ -742,7 +745,7 @@ std::string cmLocalNinjaGenerator::CreateUtilityOutput( // In Ninja Multi-Config, we can only produce cross-config utility // commands if all byproducts are per-config. if (!this->GetGlobalGenerator()->IsMultiConfig() || - !HasUniqueByproducts(*this, byproducts, bt)) { + !this->HasUniqueByproducts(byproducts, bt)) { return this->cmLocalGenerator::CreateUtilityOutput(targetName, byproducts, bt); } diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 87d5e53..5b850f3 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -86,6 +86,9 @@ public: cmNinjaDeps& ninjaDeps, const std::string& config); + bool HasUniqueByproducts(std::vector<std::string> const& byproducts, + cmListFileBacktrace const& bt); + protected: std::string ConvertToIncludeReference( std::string const& path, diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 358df9d..df7952c 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -96,8 +96,8 @@ public: // If it's an absolute path, check if it starts with the source // directory: - return !(cmCMakePath(SourceDir).IsPrefix(path) || - cmCMakePath(BinaryDir).IsPrefix(path)); + return !(cmCMakePath(this->SourceDir).IsPrefix(path) || + cmCMakePath(this->BinaryDir).IsPrefix(path)); } private: diff --git a/Source/cmMSVC60LinkLineComputer.cxx b/Source/cmMSVC60LinkLineComputer.cxx index 74c9435..8cf3765 100644 --- a/Source/cmMSVC60LinkLineComputer.cxx +++ b/Source/cmMSVC60LinkLineComputer.cxx @@ -36,5 +36,5 @@ std::string cmMSVC60LinkLineComputer::ConvertToLinkReference( } #endif - return cmLinkLineComputer::ConvertToLinkReference(lib); + return this->cmLinkLineComputer::ConvertToLinkReference(lib); } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 9d37d61..cea20ad 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -303,7 +303,7 @@ void cmMakefile::PrintCommandTrace( args.reserve(lff.Arguments().size()); for (cmListFileArgument const& arg : lff.Arguments()) { - if (expand) { + if (expand && arg.Delim != cmListFileArgument::Bracket) { temp = arg.Value; this->ExpandVariablesInString(temp); args.push_back(temp); @@ -978,7 +978,7 @@ struct BacktraceGuard this->Backtrace = std::move(current); } - ~BacktraceGuard() { this->Backtrace = std::move(Previous); } + ~BacktraceGuard() { this->Backtrace = std::move(this->Previous); } private: cmListFileBacktrace& Backtrace; @@ -1216,9 +1216,10 @@ void cmMakefile::AddCustomCommandOldStyle( }; // Each output must get its own copy of this rule. - cmsys::RegularExpression sourceFiles("\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|m|mm|" - "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|" - "hm|hpp|hxx|in|txx|inl)$"); + cmsys::RegularExpression sourceFiles( + "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|mpp|cu|m|mm|" + "rc|def|r|odl|idl|hpj|bat|h|h\\+\\+|" + "hm|hpp|hxx|in|txx|inl)$"); // Choose whether to use a main dependency. if (sourceFiles.find(source)) { @@ -2438,7 +2439,7 @@ cmMakefile::AppleSDK cmMakefile::GetAppleSDKType() const bool cmMakefile::PlatformIsAppleEmbedded() const { - return GetAppleSDKType() != AppleSDK::MacOS; + return this->GetAppleSDKType() != AppleSDK::MacOS; } const char* cmMakefile::GetSONameFlag(const std::string& language) const @@ -2449,7 +2450,7 @@ const char* cmMakefile::GetSONameFlag(const std::string& language) const name += language; } name += "_FLAG"; - return cmToCStr(GetDefinition(name)); + return cmToCStr(this->GetDefinition(name)); } bool cmMakefile::CanIWriteThisFile(std::string const& fileName) const @@ -2472,7 +2473,7 @@ const std::string& cmMakefile::GetRequiredDefinition( const std::string& name) const { static std::string const empty; - const std::string* def = GetDefinition(name); + const std::string* def = this->GetDefinition(name); if (!def) { cmSystemTools::Error("Error required internal CMake variable not " "set, cmake may not be built correctly.\n" @@ -2532,7 +2533,7 @@ cmProp cmMakefile::GetDefinition(const std::string& name) const const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const { static std::string const empty; - const std::string* def = GetDefinition(name); + const std::string* def = this->GetDefinition(name); if (!def) { return empty; } @@ -2598,24 +2599,24 @@ const std::string& cmMakefile::ExpandVariablesInString( // Suppress variable watches to avoid calling hooks twice. Suppress new // dereferences since the OLD behavior is still what is actually used. this->SuppressSideEffects = true; - newError = ExpandVariablesInStringNew(newErrorstr, newResult, - escapeQuotes, noEscapes, atOnly, - filename, line, replaceAt); + newError = this->ExpandVariablesInStringNew( + newErrorstr, newResult, escapeQuotes, noEscapes, atOnly, filename, + line, replaceAt); this->SuppressSideEffects = false; CM_FALLTHROUGH; } case cmPolicies::OLD: - mtype = - ExpandVariablesInStringOld(errorstr, source, escapeQuotes, noEscapes, - atOnly, filename, line, removeEmpty, true); + mtype = this->ExpandVariablesInStringOld(errorstr, source, escapeQuotes, + noEscapes, atOnly, filename, + line, removeEmpty, true); break; case cmPolicies::REQUIRED_IF_USED: case cmPolicies::REQUIRED_ALWAYS: // Messaging here would be *very* verbose. case cmPolicies::NEW: - mtype = - ExpandVariablesInStringNew(errorstr, source, escapeQuotes, noEscapes, - atOnly, filename, line, replaceAt); + mtype = this->ExpandVariablesInStringNew(errorstr, source, escapeQuotes, + noEscapes, atOnly, filename, + line, replaceAt); break; } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 1617793..60b66a2 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -292,7 +292,7 @@ public: const char* doc, cmStateEnums::CacheEntryType type, bool force = false) { - AddCacheDefinition(name, value.c_str(), doc, type, force); + this->AddCacheDefinition(name, value.c_str(), doc, type, force); } /** diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 70a0393..adf40b0 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -71,7 +71,8 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target) this->CMP0113New = true; break; } - MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this); + this->MacOSXContentGenerator = + cm::make_unique<MacOSXContentGeneratorType>(this); } cmMakefileTargetGenerator::~cmMakefileTargetGenerator() = default; @@ -344,27 +345,51 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() this->LocalGenerator->GetBinaryDirectory(), compilerDependFile)) << "\n\n"; - if (!cmSystemTools::FileExists(compilerDependFile)) { - // Write an empty dependency file. - cmGeneratedFileStream depFileStream( - compilerDependFile, false, - this->GlobalGenerator->GetMakefileEncoding()); - depFileStream << "# Empty compiler generated dependencies file for " - << this->GeneratorTarget->GetName() << ".\n" - << "# This may be replaced when dependencies are built.\n"; - } + // Write an empty dependency file. + cmGeneratedFileStream depFileStream( + compilerDependFile, false, this->GlobalGenerator->GetMakefileEncoding()); + depFileStream << "# Empty compiler generated dependencies file for " + << this->GeneratorTarget->GetName() << ".\n" + << "# This may be replaced when dependencies are built.\n"; + // remove internal dependency file + cmSystemTools::RemoveFile( + cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.internal")); std::string compilerDependTimestamp = cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts"); if (!cmSystemTools::FileExists(compilerDependTimestamp)) { // Write a dependency timestamp file. - cmGeneratedFileStream depFileStream( + cmGeneratedFileStream timestampFileStream( compilerDependTimestamp, false, this->GlobalGenerator->GetMakefileEncoding()); - depFileStream << "# CMAKE generated file: DO NOT EDIT!\n" - << "# Timestamp file for compiler generated dependencies " - "management for " - << this->GeneratorTarget->GetName() << ".\n"; + timestampFileStream + << "# CMAKE generated file: DO NOT EDIT!\n" + << "# Timestamp file for compiler generated dependencies " + "management for " + << this->GeneratorTarget->GetName() << ".\n"; + } + + // deactivate no longer needed legacy dependency files + // Write an empty dependency file. + cmGeneratedFileStream legacyDepFileStream( + dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); + legacyDepFileStream + << "# Empty dependencies file for " << this->GeneratorTarget->GetName() + << ".\n" + << "# This may be replaced when dependencies are built.\n"; + // remove internal dependency file + cmSystemTools::RemoveFile( + cmStrCat(this->TargetBuildDirectoryFull, "/depend.internal")); + } else { + // make sure the depend file exists + if (!cmSystemTools::FileExists(dependFileNameFull)) { + // Write an empty dependency file. + cmGeneratedFileStream depFileStream( + dependFileNameFull, false, + this->GlobalGenerator->GetMakefileEncoding()); + depFileStream << "# Empty dependencies file for " + << this->GeneratorTarget->GetName() << ".\n" + << "# This may be replaced when dependencies are built.\n"; } } @@ -380,16 +405,6 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules() << "\n\n"; } - // make sure the depend file exists - if (!cmSystemTools::FileExists(dependFileNameFull)) { - // Write an empty dependency file. - cmGeneratedFileStream depFileStream( - dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding()); - depFileStream << "# Empty dependencies file for " - << this->GeneratorTarget->GetName() << ".\n" - << "# This may be replaced when dependencies are built.\n"; - } - // Open the flags file. This should be copy-if-different because the // rules may depend on this file itself. this->FlagFileNameFull = @@ -854,6 +869,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( shellDependencyFile = this->LocalGenerator->ConvertToOutputFormat( depFile, cmOutputConverter::SHELL); vars.DependencyFile = shellDependencyFile.c_str(); + this->CleanFiles.insert(depFile); dependencyTimestamp = this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetBinaryDirectory(), @@ -897,7 +913,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( cmExpandList(compileRule, compileCommands); } - if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") && + if (this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS") && lang_can_export_cmds && compileCommands.size() == 1) { std::string compileCommand = compileCommands[0]; diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx index a121332..28baeb6 100644 --- a/Source/cmNewLineStyle.cxx +++ b/Source/cmNewLineStyle.cxx @@ -8,13 +8,13 @@ cmNewLineStyle::cmNewLineStyle() = default; bool cmNewLineStyle::IsValid() const { - return NewLineStyle != Invalid; + return this->NewLineStyle != Invalid; } bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args, std::string& errorString) { - NewLineStyle = Invalid; + this->NewLineStyle = Invalid; for (size_t i = 0; i < args.size(); i++) { if (args[i] == "NEWLINE_STYLE") { @@ -22,11 +22,11 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args, if (args.size() > styleIndex) { std::string const& eol = args[styleIndex]; if (eol == "LF" || eol == "UNIX") { - NewLineStyle = LF; + this->NewLineStyle = LF; return true; } if (eol == "CRLF" || eol == "WIN32" || eol == "DOS") { - NewLineStyle = CRLF; + this->NewLineStyle = CRLF; return true; } errorString = "NEWLINE_STYLE sets an unknown style, only LF, " @@ -43,7 +43,7 @@ bool cmNewLineStyle::ReadFromArguments(const std::vector<std::string>& args, std::string cmNewLineStyle::GetCharacters() const { - switch (NewLineStyle) { + switch (this->NewLineStyle) { case Invalid: return ""; case LF: @@ -56,10 +56,10 @@ std::string cmNewLineStyle::GetCharacters() const void cmNewLineStyle::SetStyle(Style style) { - NewLineStyle = style; + this->NewLineStyle = style; } cmNewLineStyle::Style cmNewLineStyle::GetStyle() const { - return NewLineStyle; + return this->NewLineStyle; } diff --git a/Source/cmNinjaLinkLineComputer.cxx b/Source/cmNinjaLinkLineComputer.cxx index 7fbeeea..2304ad2 100644 --- a/Source/cmNinjaLinkLineComputer.cxx +++ b/Source/cmNinjaLinkLineComputer.cxx @@ -18,5 +18,5 @@ cmNinjaLinkLineComputer::cmNinjaLinkLineComputer( std::string cmNinjaLinkLineComputer::ConvertToLinkReference( std::string const& lib) const { - return GG->ConvertToNinjaPath(lib); + return this->GG->ConvertToNinjaPath(lib); } diff --git a/Source/cmNinjaLinkLineDeviceComputer.cxx b/Source/cmNinjaLinkLineDeviceComputer.cxx index 84c1b37..f66e2f5 100644 --- a/Source/cmNinjaLinkLineDeviceComputer.cxx +++ b/Source/cmNinjaLinkLineDeviceComputer.cxx @@ -16,5 +16,5 @@ cmNinjaLinkLineDeviceComputer::cmNinjaLinkLineDeviceComputer( std::string cmNinjaLinkLineDeviceComputer::ConvertToLinkReference( std::string const& lib) const { - return GG->ConvertToNinjaPath(lib); + return this->GG->ConvertToNinjaPath(lib); } diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index a5b9466..49e5e4c 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -12,6 +12,7 @@ #include <utility> #include <cm/memory> +#include <cm/optional> #include <cm/vector> #include "cmComputeLinkInformation.h" @@ -49,7 +50,7 @@ cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator( // on Windows the output dir is already needed at compile time // ensure the directory exists (OutDir test) for (auto const& config : this->GetConfigNames()) { - EnsureDirectoryExists(target->GetDirectory(config)); + this->EnsureDirectoryExists(target->GetDirectory(config)); } } @@ -306,7 +307,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( { const cmMakefile* mf = this->GetMakefile(); - cmNinjaRule rule(LanguageLinkerCudaDeviceRule(config)); + cmNinjaRule rule(this->LanguageLinkerCudaDeviceRule(config)); rule.Command = this->GetLocalGenerator()->BuildCommandLine( { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_DEVICE_LINKER"), " -arch=$ARCH $REGISTER -o=$out $in") }); @@ -334,13 +335,13 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), compileCmd, vars); - rule.Name = LanguageLinkerCudaDeviceCompileRule(config); + rule.Name = this->LanguageLinkerCudaDeviceCompileRule(config); rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd }); rule.Comment = "Rule for compiling CUDA device stubs."; rule.Description = "Compiling CUDA device stub $out"; this->GetGlobalGenerator()->AddRule(rule); - rule.Name = LanguageLinkerCudaFatbinaryRule(config); + rule.Name = this->LanguageLinkerCudaFatbinaryRule(config); rule.Command = this->GetLocalGenerator()->BuildCommandLine( { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_FATBINARY"), " -64 -cmdline=--compile-only -compress-all -link " @@ -385,7 +386,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, // build response file name std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; - cmProp flag = GetMakefile()->GetDefinition(cmakeLinkVar); + cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); if (flag) { responseFlag = *flag; @@ -673,7 +674,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement( targetOutputDir = globalGen->ExpandCFGIntDir(targetOutputDir, config); std::string targetOutputReal = - ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt); + this->ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt); if (firstForConfig) { globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal); @@ -730,7 +731,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements( this->GetGlobalGenerator()->ConfigDirectory(config)); const std::string ninjaOutputDir = this->ConvertToNinjaPath(objectDir); - cmNinjaBuild fatbinary(LanguageLinkerCudaFatbinaryRule(config)); + cmNinjaBuild fatbinary(this->LanguageLinkerCudaFatbinaryRule(config)); // Link device code for each architecture. for (const std::string& architectureKind : architectures) { @@ -744,7 +745,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements( cmStrCat(" -im=profile=sm_", architecture, ",file=", cubin); fatbinary.ExplicitDeps.emplace_back(cubin); - cmNinjaBuild dlink(LanguageLinkerCudaDeviceRule(config)); + cmNinjaBuild dlink(this->LanguageLinkerCudaDeviceRule(config)); dlink.ExplicitDeps = explicitDeps; dlink.Outputs = { cubin }; dlink.Variables["ARCH"] = cmStrCat("sm_", architecture); @@ -767,7 +768,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatements( fatbinary); // Compile the stub that registers the kernels and contains the fatbinaries. - cmNinjaBuild dcompile(LanguageLinkerCudaDeviceCompileRule(config)); + cmNinjaBuild dcompile(this->LanguageLinkerCudaDeviceCompileRule(config)); dcompile.Outputs = { output }; dcompile.ExplicitDeps = { cmStrCat(ninjaOutputDir, "/cmake_cuda_fatbin.h") }; dcompile.Variables["FATBIN"] = @@ -787,7 +788,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement( cmGeneratorTarget* genTarget = this->GetGeneratorTarget(); cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator(); - std::string targetOutputImplib = ConvertToNinjaPath( + std::string targetOutputImplib = this->ConvertToNinjaPath( genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact)); if (config != fileConfig) { @@ -806,7 +807,7 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement( ->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact) .empty() && targetOutputImplib == - ConvertToNinjaPath(genTarget->GetFullPath( + this->ConvertToNinjaPath(genTarget->GetFullPath( fileConfig, cmStateEnums::ImportLibraryArtifact))) { return; } @@ -882,16 +883,16 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkStatement( const std::string impLibPath = localGen.ConvertToOutputFormat( targetOutputImplib, cmOutputConverter::SHELL); vars["TARGET_IMPLIB"] = impLibPath; - EnsureParentDirectoryExists(impLibPath); + this->EnsureParentDirectoryExists(impLibPath); } const std::string objPath = - cmStrCat(GetGeneratorTarget()->GetSupportDirectory(), + cmStrCat(this->GetGeneratorTarget()->GetSupportDirectory(), globalGen->ConfigDirectory(config)); vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat( this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL); - EnsureDirectoryExists(objPath); + this->EnsureDirectoryExists(objPath); this->SetMsvcTargetPdbVariable(vars, config); @@ -933,21 +934,22 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator(); cmGeneratorTarget* gt = this->GetGeneratorTarget(); - std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(config)); - std::string targetOutputReal = ConvertToNinjaPath( + std::string targetOutput = this->ConvertToNinjaPath(gt->GetFullPath(config)); + std::string targetOutputReal = this->ConvertToNinjaPath( gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact, /*realname=*/true)); - std::string targetOutputImplib = ConvertToNinjaPath( + std::string targetOutputImplib = this->ConvertToNinjaPath( gt->GetFullPath(config, cmStateEnums::ImportLibraryArtifact)); if (config != fileConfig) { - if (targetOutput == ConvertToNinjaPath(gt->GetFullPath(fileConfig))) { + if (targetOutput == + this->ConvertToNinjaPath(gt->GetFullPath(fileConfig))) { return; } if (targetOutputReal == - ConvertToNinjaPath(gt->GetFullPath(fileConfig, - cmStateEnums::RuntimeBinaryArtifact, - /*realname=*/true))) { + this->ConvertToNinjaPath( + gt->GetFullPath(fileConfig, cmStateEnums::RuntimeBinaryArtifact, + /*realname=*/true))) { return; } if (!gt->GetFullName(config, cmStateEnums::ImportLibraryArtifact) @@ -955,7 +957,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( !gt->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact) .empty() && targetOutputImplib == - ConvertToNinjaPath(gt->GetFullPath( + this->ConvertToNinjaPath(gt->GetFullPath( fileConfig, cmStateEnums::ImportLibraryArtifact))) { return; } @@ -1095,7 +1097,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( std::vector<std::string> extraISPCObjects = this->GetGeneratorTarget()->GetGeneratedISPCObjects(config); std::transform(extraISPCObjects.begin(), extraISPCObjects.end(), - std::back_inserter(linkBuild.ExplicitDeps), MapToNinjaPath()); + std::back_inserter(linkBuild.ExplicitDeps), + this->MapToNinjaPath()); linkBuild.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage(config), config); @@ -1189,7 +1192,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( const std::string impLibPath = localGen.ConvertToOutputFormat( targetOutputImplib, cmOutputConverter::SHELL); vars["TARGET_IMPLIB"] = impLibPath; - EnsureParentDirectoryExists(impLibPath); + this->EnsureParentDirectoryExists(impLibPath); if (gt->HasImportLibrary(config)) { byproducts.push_back(targetOutputImplib); if (firstForConfig) { @@ -1218,7 +1221,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( cmStrCat(gt->GetSupportDirectory(), globalGen->ConfigDirectory(config)); vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat( this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL); - EnsureDirectoryExists(objPath); + this->EnsureDirectoryExists(objPath); std::string& linkLibraries = vars["LINK_LIBRARIES"]; std::string& link_path = vars["LINK_PATH"]; @@ -1236,22 +1239,25 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( std::vector<std::string> preLinkCmdLines; std::vector<std::string> postBuildCmdLines; - if (config == fileConfig) { - std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines, - &preLinkCmdLines, - &postBuildCmdLines }; - - for (unsigned i = 0; i != 3; ++i) { - for (cmCustomCommand const& cc : *cmdLists[i]) { - cmCustomCommandGenerator ccg(cc, config, this->GetLocalGenerator()); + std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines, + &preLinkCmdLines, + &postBuildCmdLines }; + + for (unsigned i = 0; i != 3; ++i) { + for (cmCustomCommand const& cc : *cmdLists[i]) { + if (config == fileConfig || + this->GetLocalGenerator()->HasUniqueByproducts(cc.GetByproducts(), + cc.GetBacktrace())) { + cmCustomCommandGenerator ccg(cc, fileConfig, this->GetLocalGenerator(), + true, config); localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]); std::vector<std::string> const& ccByproducts = ccg.GetByproducts(); std::transform(ccByproducts.begin(), ccByproducts.end(), - std::back_inserter(byproducts), MapToNinjaPath()); + std::back_inserter(byproducts), this->MapToNinjaPath()); std::transform( ccByproducts.begin(), ccByproducts.end(), std::back_inserter(globalGen->GetByproductsForCleanTarget()), - MapToNinjaPath()); + this->MapToNinjaPath()); } } } @@ -1272,7 +1278,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( cmd += this->GetLocalGenerator()->ConvertToOutputFormat( obj_list_file, cmOutputConverter::SHELL); - cmProp nm_executable = GetMakefile()->GetDefinition("CMAKE_NM"); + cmProp nm_executable = this->GetMakefile()->GetDefinition("CMAKE_NM"); if (cmNonempty(nm_executable)) { cmd += " --nm="; cmd += this->LocalCommonGenerator->ConvertToOutputFormat( @@ -1325,7 +1331,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( // build response file name std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG"; - cmProp flag = GetMakefile()->GetDefinition(cmakeLinkVar); + cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); bool const lang_supports_response = !(this->TargetLinkLanguage(config) == "RC" || diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 9075563..672b579 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -35,6 +35,7 @@ #include "cmRange.h" #include "cmRulePlaceholderExpander.h" #include "cmSourceFile.h" +#include "cmStandardLevelResolver.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmStringAlgorithms.h" @@ -146,9 +147,26 @@ std::string cmNinjaTargetGenerator::LanguageDyndepRule( '_', config); } -bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const +bool cmNinjaTargetGenerator::NeedCxxModuleSupport( + std::string const& lang, std::string const& config) const { - return lang == "Fortran"; + if (lang != "CXX") { + return false; + } + if (!this->Makefile->IsOn("CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP")) { + return false; + } + cmGeneratorTarget const* tgt = this->GetGeneratorTarget(); + cmStandardLevelResolver standardResolver(this->Makefile); + bool const uses_cxx20 = + standardResolver.HaveStandardAvailable(tgt, "CXX", config, "cxx_std_20"); + return uses_cxx20 && this->GetGlobalGenerator()->CheckCxxModuleSupport(); +} + +bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang, + std::string const& config) const +{ + return lang == "Fortran" || this->NeedCxxModuleSupport(lang, config); } std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget( @@ -332,7 +350,8 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps( const std::vector<std::string>& deps = cli->GetDepends(); cmNinjaDeps result(deps.size()); - std::transform(deps.begin(), deps.end(), result.begin(), MapToNinjaPath()); + std::transform(deps.begin(), deps.end(), result.begin(), + this->MapToNinjaPath()); // Add a dependency on the link definitions file, if any. if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi = @@ -353,7 +372,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps( std::vector<std::string> linkDeps; this->GeneratorTarget->GetLinkDepends(linkDeps, config, linkLanguage); std::transform(linkDeps.begin(), linkDeps.end(), std::back_inserter(result), - MapToNinjaPath()); + this->MapToNinjaPath()); return result; } @@ -361,7 +380,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps( std::string cmNinjaTargetGenerator::GetSourceFilePath( cmSourceFile const* source) const { - return ConvertToNinjaPath(source->GetFullPath()); + return this->ConvertToNinjaPath(source->GetFullPath()); } std::string cmNinjaTargetGenerator::GetObjectFilePath( @@ -442,7 +461,7 @@ std::string cmNinjaTargetGenerator::GetTargetOutputDir( const std::string& config) const { std::string dir = this->GeneratorTarget->GetDirectory(config); - return ConvertToNinjaPath(dir); + return this->ConvertToNinjaPath(dir); } std::string cmNinjaTargetGenerator::GetTargetFilePath( @@ -479,13 +498,13 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable( } vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( - ConvertToNinjaPath(pdbPath), cmOutputConverter::SHELL); + this->ConvertToNinjaPath(pdbPath), cmOutputConverter::SHELL); vars["TARGET_COMPILE_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat( - ConvertToNinjaPath(compilePdbPath), cmOutputConverter::SHELL); + this->ConvertToNinjaPath(compilePdbPath), cmOutputConverter::SHELL); - EnsureParentDirectoryExists(pdbPath); - EnsureParentDirectoryExists(compilePdbPath); + this->EnsureParentDirectoryExists(pdbPath); + this->EnsureParentDirectoryExists(compilePdbPath); return true; } return false; @@ -529,8 +548,9 @@ cmNinjaRule GetScanRule( scanVars.CMTargetName = vars.CMTargetName; scanVars.CMTargetType = vars.CMTargetType; scanVars.Language = vars.Language; - scanVars.Object = "$out"; // for RULE_LAUNCH_COMPILE + scanVars.Object = "$OBJ_FILE"; scanVars.PreprocessedSource = "$out"; + scanVars.DynDepFile = "$DYNDEP_INTERMEDIATE_FILE"; scanVars.DependencyFile = rule.DepFile.c_str(); scanVars.DependencyTarget = "$out"; @@ -585,7 +605,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, cmMakefile* mf = this->GetMakefile(); // For some cases we scan to dynamically discover dependencies. - bool const needDyndep = this->NeedDyndep(lang); + bool const needDyndep = this->NeedDyndep(lang, config); bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(lang); std::string flags = "$FLAGS"; @@ -600,12 +620,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, responseFlag = "@"; } } + std::string const modmapFormatVar = + cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FORMAT"); + std::string const modmapFormat = + this->Makefile->GetSafeDefinition(modmapFormatVar); std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander( this->GetLocalGenerator()->CreateRulePlaceholderExpander()); std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat( - ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)), + this->ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)), cmLocalGenerator::SHELL); std::string launcher; @@ -623,16 +647,26 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, // Rule to scan dependencies of sources that need preprocessing. { std::vector<std::string> scanCommands; - std::string const& scanRuleName = - this->LanguagePreprocessAndScanRule(lang, config); - std::string const& ppCommmand = mf->GetRequiredDefinition( - cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE")); - cmExpandList(ppCommmand, scanCommands); - for (std::string& i : scanCommands) { - i = cmStrCat(launcher, i); + std::string scanRuleName; + if (compilationPreprocesses) { + scanRuleName = this->LanguageScanRule(lang, config); + std::string const& scanCommand = mf->GetRequiredDefinition( + cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_SOURCE")); + cmExpandList(scanCommand, scanCommands); + for (std::string& i : scanCommands) { + i = cmStrCat(launcher, i); + } + } else { + scanRuleName = this->LanguagePreprocessAndScanRule(lang, config); + std::string const& ppCommmand = mf->GetRequiredDefinition( + cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE")); + cmExpandList(ppCommmand, scanCommands); + for (std::string& i : scanCommands) { + i = cmStrCat(launcher, i); + } + scanCommands.emplace_back(GetScanCommand(cmakeCmd, tdi, lang, "$out", + "$DYNDEP_INTERMEDIATE_FILE")); } - scanCommands.emplace_back(GetScanCommand(cmakeCmd, tdi, lang, "$out", - "$DYNDEP_INTERMEDIATE_FILE")); auto scanRule = GetScanRule( scanRuleName, vars, responseFlag, flags, rulePlaceholderExpander.get(), @@ -640,12 +674,18 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, scanRule.Comment = cmStrCat("Rule for generating ", lang, " dependencies."); - scanRule.Description = cmStrCat("Building ", lang, " preprocessed $out"); + if (compilationPreprocesses) { + scanRule.Description = + cmStrCat("Scanning $in for ", lang, " dependencies"); + } else { + scanRule.Description = + cmStrCat("Building ", lang, " preprocessed $out"); + } this->GetGlobalGenerator()->AddRule(scanRule); } - { + if (!compilationPreprocesses) { // Compilation will not preprocess, so it does not need the defines // unless the compiler wants them for some other purpose. if (!this->CompileWithDefines(lang)) { @@ -680,12 +720,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, // Run CMake dependency scanner on the source file (using the preprocessed // source if that was performed). + std::string ddModmapArg; + if (!modmapFormat.empty()) { + ddModmapArg += cmStrCat(" --modmapfmt=", modmapFormat); + } { std::vector<std::string> ddCmds; { - std::string ccmd = - cmStrCat(cmakeCmd, " -E cmake_ninja_dyndep --tdi=", tdi, - " --lang=", lang, " --dd=$out @", rule.RspFile); + std::string ccmd = cmStrCat( + cmakeCmd, " -E cmake_ninja_dyndep --tdi=", tdi, " --lang=", lang, + ddModmapArg, " --dd=$out @", rule.RspFile); ddCmds.emplace_back(std::move(ccmd)); } rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds); @@ -747,6 +791,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, } } + if (needDyndep && !modmapFormat.empty()) { + std::string modmapFlags = mf->GetRequiredDefinition( + cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_MODULE_MAP_FLAG")); + cmSystemTools::ReplaceString(modmapFlags, "<MODULE_MAP_FILE>", + "$DYNDEP_MODULE_MAP_FILE"); + flags += cmStrCat(' ', modmapFlags); + } + vars.Flags = flags.c_str(); vars.DependencyFile = rule.DepFile.c_str(); @@ -922,7 +974,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements( config); } if (firstForConfig) { - cmProp pchExtension = GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); + cmProp pchExtension = + this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION"); std::vector<cmSourceFile const*> externalObjects; this->GeneratorTarget->GetExternalObjects(externalObjects, config); @@ -956,9 +1009,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements( const std::vector<std::string>& ccoutputs = ccg.GetOutputs(); const std::vector<std::string>& ccbyproducts = ccg.GetByproducts(); std::transform(ccoutputs.begin(), ccoutputs.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::back_inserter(orderOnlyDeps), + this->MapToNinjaPath()); std::transform(ccbyproducts.begin(), ccbyproducts.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::back_inserter(orderOnlyDeps), + this->MapToNinjaPath()); } std::sort(orderOnlyDeps.begin(), orderOnlyDeps.end()); @@ -1049,6 +1104,7 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, const std::string& ppFileName, bool compilePP, bool compilePPWithDefines, cmNinjaBuild& objBuild, cmNinjaVars& vars, + std::string const& modmapFormat, const std::string& objectFileName, cmLocalGenerator* lg) { @@ -1119,6 +1175,15 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName, vars.erase("DEP_FILE"); } + if (!modmapFormat.empty()) { + // XXX(modmap): If changing this path construction, change + // `cmGlobalNinjaGenerator::WriteDyndep` to expect the corresponding + // file path. + std::string const ddModmapFile = cmStrCat(objectFileName, ".modmap"); + scanBuild.Variables["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile; + scanBuild.ImplicitOuts.push_back(ddModmapFile); + } + return scanBuild; } } @@ -1143,7 +1208,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( // build response file name std::string cmakeLinkVar = cmStrCat(cmakeVarLang, "_RESPONSE_FILE_FLAG"); - cmProp flag = GetMakefile()->GetDefinition(cmakeLinkVar); + cmProp flag = this->GetMakefile()->GetDefinition(cmakeLinkVar); bool const lang_supports_response = !(language == "RC" || (language == "CUDA" && !flag)); @@ -1240,7 +1305,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } std::transform(depList.begin(), depList.end(), std::back_inserter(objBuild.ImplicitDeps), - MapToNinjaPath()); + this->MapToNinjaPath()); } objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config)); @@ -1258,10 +1323,17 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } // For some cases we scan to dynamically discover dependencies. - bool const needDyndep = this->NeedDyndep(language); + bool const needDyndep = this->NeedDyndep(language, config); bool const compilationPreprocesses = !this->NeedExplicitPreprocessing(language); + std::string modmapFormat; + if (needDyndep) { + std::string const modmapFormatVar = + cmStrCat("CMAKE_EXPERIMENTAL_", language, "_MODULE_MAP_FORMAT"); + modmapFormat = this->Makefile->GetSafeDefinition(modmapFormatVar); + } + if (needDyndep) { // If source/target has preprocessing turned off, we still need to // generate an explicit dependency step @@ -1291,7 +1363,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( cmNinjaBuild ppBuild = GetScanBuildStatement( scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild, - vars, objectFileName, this->LocalGenerator); + vars, modmapFormat, objectFileName, this->LocalGenerator); if (compilePP) { // In case compilation requires flags that are incompatible with @@ -1327,9 +1399,15 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( std::string const dyndep = this->GetDyndepFilePath(language, config); objBuild.OrderOnlyDeps.push_back(dyndep); vars["dyndep"] = dyndep; + + if (!modmapFormat.empty()) { + std::string const ddModmapFile = cmStrCat(objectFileName, ".modmap"); + vars["DYNDEP_MODULE_MAP_FILE"] = ddModmapFile; + objBuild.OrderOnlyDeps.push_back(ddModmapFile); + } } - EnsureParentDirectoryExists(objectFileName); + this->EnsureParentDirectoryExists(objectFileName); vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat( objectDir, cmOutputConverter::SHELL); @@ -1402,7 +1480,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( auto headers = this->GeneratorTarget->GetGeneratedISPCHeaders(config); if (!headers.empty()) { std::transform(headers.begin(), headers.end(), headers.begin(), - MapToNinjaPath()); + this->MapToNinjaPath()); objBuild.OrderOnlyDeps.insert(objBuild.OrderOnlyDeps.end(), headers.begin(), headers.end()); } @@ -1424,7 +1502,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( build.Comment = "Additional output files."; build.Outputs = cmExpandedList(evaluatedObjectOutputs); std::transform(build.Outputs.begin(), build.Outputs.end(), - build.Outputs.begin(), MapToNinjaPath()); + build.Outputs.begin(), this->MapToNinjaPath()); build.ExplicitDeps = objBuild.Outputs; this->GetGlobalGenerator()->WriteBuild( this->GetImplFileStream(fileConfig), build); @@ -1440,17 +1518,26 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang, tdi["compiler-id"] = this->Makefile->GetSafeDefinition( cmStrCat("CMAKE_", lang, "_COMPILER_ID")); + std::string mod_dir; if (lang == "Fortran") { - std::string mod_dir = this->GeneratorTarget->GetFortranModuleDirectory( + mod_dir = this->GeneratorTarget->GetFortranModuleDirectory( this->Makefile->GetHomeOutputDirectory()); - if (mod_dir.empty()) { - mod_dir = this->Makefile->GetCurrentBinaryDirectory(); - } - tdi["module-dir"] = mod_dir; + } else if (lang == "CXX") { + mod_dir = + cmSystemTools::CollapseFullPath(this->GeneratorTarget->ObjectDirectory); + } + if (mod_dir.empty()) { + mod_dir = this->Makefile->GetCurrentBinaryDirectory(); + } + tdi["module-dir"] = mod_dir; + + if (lang == "Fortran") { tdi["submodule-sep"] = this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_SEP"); tdi["submodule-ext"] = this->Makefile->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT"); + } else if (lang == "CXX") { + // No extra information necessary. } tdi["dir-cur-bld"] = this->Makefile->GetCurrentBinaryDirectory(); @@ -1532,7 +1619,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( std::string const& objectFileDir, std::string const& flags, std::string const& defines, std::string const& includes) { - if (!this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS")) { + if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) { return; } @@ -1644,7 +1731,7 @@ void cmNinjaTargetGenerator::EnsureDirectoryExists( void cmNinjaTargetGenerator::EnsureParentDirectoryExists( const std::string& path) const { - EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path)); + this->EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path)); } void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()( diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 83a4342..79dc622 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -71,9 +71,11 @@ protected: const std::string& config) const; std::string LanguageDyndepRule(std::string const& lang, const std::string& config) const; - bool NeedDyndep(std::string const& lang) const; + bool NeedDyndep(std::string const& lang, std::string const& config) const; bool NeedExplicitPreprocessing(std::string const& lang) const; bool CompileWithDefines(std::string const& lang) const; + bool NeedCxxModuleSupport(std::string const& lang, + std::string const& config) const; std::string OrderDependsTargetForTarget(const std::string& config); diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 0b62e16..3995624 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -83,7 +83,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( lg->AppendCustomCommandLines(ccg, commands); std::vector<std::string> const& ccByproducts = ccg.GetByproducts(); std::transform(ccByproducts.begin(), ccByproducts.end(), - std::back_inserter(util_outputs), MapToNinjaPath()); + std::back_inserter(util_outputs), + this->MapToNinjaPath()); if (ci.GetUsesTerminal()) { uses_terminal = true; } @@ -103,9 +104,9 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( const std::vector<std::string>& ccOutputs = ccg.GetOutputs(); const std::vector<std::string>& ccByproducts = ccg.GetByproducts(); std::transform(ccOutputs.begin(), ccOutputs.end(), - std::back_inserter(deps), MapToNinjaPath()); + std::back_inserter(deps), this->MapToNinjaPath()); std::transform(ccByproducts.begin(), ccByproducts.end(), - std::back_inserter(deps), MapToNinjaPath()); + std::back_inserter(deps), this->MapToNinjaPath()); } } } diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx index 0fb4ff7..2d2676e 100644 --- a/Source/cmProcessOutput.cxx +++ b/Source/cmProcessOutput.cxx @@ -126,7 +126,7 @@ bool cmProcessOutput::DecodeText(std::string raw, std::string& decoded, bool cmProcessOutput::DecodeText(const char* data, size_t length, std::string& decoded, size_t id) { - return DecodeText(std::string(data, length), decoded, id); + return this->DecodeText(std::string(data, length), decoded, id); } bool cmProcessOutput::DecodeText(std::vector<char> raw, @@ -134,7 +134,7 @@ bool cmProcessOutput::DecodeText(std::vector<char> raw, { std::string str; const bool success = - DecodeText(std::string(raw.begin(), raw.end()), str, id); + this->DecodeText(std::string(raw.begin(), raw.end()), str, id); decoded.assign(str.begin(), str.end()); return success; } diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx index f22f36d..06e151a 100644 --- a/Source/cmPropertyMap.cxx +++ b/Source/cmPropertyMap.cxx @@ -7,17 +7,17 @@ void cmPropertyMap::Clear() { - Map_.clear(); + this->Map_.clear(); } void cmPropertyMap::SetProperty(const std::string& name, const char* value) { if (!value) { - Map_.erase(name); + this->Map_.erase(name); return; } - Map_[name] = value; + this->Map_[name] = value; } void cmPropertyMap::AppendProperty(const std::string& name, @@ -29,7 +29,7 @@ void cmPropertyMap::AppendProperty(const std::string& name, } { - std::string& pVal = Map_[name]; + std::string& pVal = this->Map_[name]; if (!pVal.empty() && !asString) { pVal += ';'; } @@ -39,13 +39,13 @@ void cmPropertyMap::AppendProperty(const std::string& name, void cmPropertyMap::RemoveProperty(const std::string& name) { - Map_.erase(name); + this->Map_.erase(name); } cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const { - auto it = Map_.find(name); - if (it != Map_.end()) { + auto it = this->Map_.find(name); + if (it != this->Map_.end()) { return &it->second; } return nullptr; @@ -54,8 +54,8 @@ cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const std::vector<std::string> cmPropertyMap::GetKeys() const { std::vector<std::string> keyList; - keyList.reserve(Map_.size()); - for (auto const& item : Map_) { + keyList.reserve(this->Map_.size()); + for (auto const& item : this->Map_) { keyList.push_back(item.first); } std::sort(keyList.begin(), keyList.end()); @@ -66,8 +66,8 @@ std::vector<std::pair<std::string, std::string>> cmPropertyMap::GetList() const { using StringPair = std::pair<std::string, std::string>; std::vector<StringPair> kvList; - kvList.reserve(Map_.size()); - for (auto const& item : Map_) { + kvList.reserve(this->Map_.size()); + for (auto const& item : this->Map_) { kvList.emplace_back(item.first, item.second); } std::sort(kvList.begin(), kvList.end(), diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index 2db1b84..e12a653 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -111,20 +111,20 @@ public: RccLister(std::string rccExecutable, std::vector<std::string> listOptions); //! The rcc executable - std::string const& RccExcutable() const { return RccExcutable_; } + std::string const& RccExcutable() const { return this->RccExcutable_; } void SetRccExecutable(std::string const& rccExecutable) { - RccExcutable_ = rccExecutable; + this->RccExcutable_ = rccExecutable; } //! The rcc executable list options std::vector<std::string> const& ListOptions() const { - return ListOptions_; + return this->ListOptions_; } void SetListOptions(std::vector<std::string> const& listOptions) { - ListOptions_ = listOptions; + this->ListOptions_ = listOptions; } /** diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index ff6fcd0..62b879f 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -57,7 +57,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( if (targetName.empty()) { targetName = "autogen"; } - GlobalAutoGenTargets_.emplace(localGen.get(), std::move(targetName)); + this->GlobalAutoGenTargets_.emplace(localGen.get(), + std::move(targetName)); globalAutoGenTarget = true; } @@ -68,7 +69,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( if (targetName.empty()) { targetName = "autorcc"; } - GlobalAutoRccTargets_.emplace(localGen.get(), std::move(targetName)); + this->GlobalAutoRccTargets_.emplace(localGen.get(), + std::move(targetName)); globalAutoRccTarget = true; } } @@ -99,16 +101,16 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( continue; } - bool const moc = target->GetPropertyAsBool(kw().AUTOMOC); - bool const uic = target->GetPropertyAsBool(kw().AUTOUIC); - bool const rcc = target->GetPropertyAsBool(kw().AUTORCC); + bool const moc = target->GetPropertyAsBool(this->kw().AUTOMOC); + bool const uic = target->GetPropertyAsBool(this->kw().AUTOUIC); + bool const rcc = target->GetPropertyAsBool(this->kw().AUTORCC); if (moc || uic || rcc) { std::string const& mocExec = - target->GetSafeProperty(kw().AUTOMOC_EXECUTABLE); + target->GetSafeProperty(this->kw().AUTOMOC_EXECUTABLE); std::string const& uicExec = - target->GetSafeProperty(kw().AUTOUIC_EXECUTABLE); + target->GetSafeProperty(this->kw().AUTOUIC_EXECUTABLE); std::string const& rccExec = - target->GetSafeProperty(kw().AUTORCC_EXECUTABLE); + target->GetSafeProperty(this->kw().AUTORCC_EXECUTABLE); // We support Qt4, Qt5 and Qt6 auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target.get()); @@ -141,9 +143,10 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer( } if (mocIsValid || uicIsValid || rccIsValid) { // Create autogen target initializer - Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>( - this, target.get(), qtVersion.first, mocIsValid, uicIsValid, - rccIsValid, globalAutoGenTarget, globalAutoRccTarget)); + this->Initializers_.emplace_back( + cm::make_unique<cmQtAutoGenInitializer>( + this, target.get(), qtVersion.first, mocIsValid, uicIsValid, + rccIsValid, globalAutoGenTarget, globalAutoRccTarget)); } } } @@ -184,8 +187,8 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget( void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen( cmLocalGenerator* localGen, std::string const& targetName) { - auto it = GlobalAutoGenTargets_.find(localGen); - if (it != GlobalAutoGenTargets_.end()) { + auto it = this->GlobalAutoGenTargets_.find(localGen); + if (it != this->GlobalAutoGenTargets_.end()) { cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second); if (target != nullptr) { target->Target->AddUtility(targetName, false, localGen->GetMakefile()); @@ -196,8 +199,8 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen( void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc( cmLocalGenerator* localGen, std::string const& targetName) { - auto it = GlobalAutoRccTargets_.find(localGen); - if (it != GlobalAutoRccTargets_.end()) { + auto it = this->GlobalAutoRccTargets_.find(localGen); + if (it != this->GlobalAutoRccTargets_.end()) { cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second); if (target != nullptr) { target->Target->AddUtility(targetName, false, localGen->GetMakefile()); @@ -258,7 +261,7 @@ cmQtAutoGenGlobalInitializer::GetCompilerFeatures( bool cmQtAutoGenGlobalInitializer::generate() { - return (InitializeCustomTargets() && SetupCustomTargets()); + return (this->InitializeCustomTargets() && this->SetupCustomTargets()); } bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() @@ -266,19 +269,19 @@ bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() // Initialize global autogen targets { std::string const comment = "Global AUTOGEN target"; - for (auto const& pair : GlobalAutoGenTargets_) { - GetOrCreateGlobalTarget(pair.first, pair.second, comment); + for (auto const& pair : this->GlobalAutoGenTargets_) { + this->GetOrCreateGlobalTarget(pair.first, pair.second, comment); } } // Initialize global autorcc targets { std::string const comment = "Global AUTORCC target"; - for (auto const& pair : GlobalAutoRccTargets_) { - GetOrCreateGlobalTarget(pair.first, pair.second, comment); + for (auto const& pair : this->GlobalAutoRccTargets_) { + this->GetOrCreateGlobalTarget(pair.first, pair.second, comment); } } // Initialize per target autogen targets - for (auto& initializer : Initializers_) { + for (auto& initializer : this->Initializers_) { if (!initializer->InitCustomTargets()) { return false; } @@ -288,7 +291,7 @@ bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets() bool cmQtAutoGenGlobalInitializer::SetupCustomTargets() { - for (auto& initializer : Initializers_) { + for (auto& initializer : this->Initializers_) { if (!initializer->SetupCustomTargets()) { return false; } diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h index cdae137..ea3821d 100644 --- a/Source/cmQtAutoGenGlobalInitializer.h +++ b/Source/cmQtAutoGenGlobalInitializer.h @@ -50,7 +50,7 @@ public: std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators); ~cmQtAutoGenGlobalInitializer(); - Keywords const& kw() const { return Keywords_; }; + Keywords const& kw() const { return this->Keywords_; }; bool generate(); diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index 1f74578..bfe174c 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -152,7 +152,8 @@ std::vector<std::string> SearchPathSanitizer::operator()( res.reserve(paths.size()); for (std::string const& srcPath : paths) { // Collapse relative paths - std::string path = cmSystemTools::CollapseFullPath(srcPath, SourcePath_); + std::string path = + cmSystemTools::CollapseFullPath(srcPath, this->SourcePath_); // Remove suffix slashes while (cmHasSuffix(path, '/')) { path.pop_back(); @@ -172,14 +173,17 @@ public: // -- Single value void Set(std::string const& key, std::string const& value) { - Value_[key] = value; + this->Value_[key] = value; } void SetConfig(std::string const& key, cmQtAutoGenInitializer::ConfigString const& cfgStr); - void SetBool(std::string const& key, bool value) { Value_[key] = value; } + void SetBool(std::string const& key, bool value) + { + this->Value_[key] = value; + } void SetUInt(std::string const& key, unsigned int value) { - Value_[key] = value; + this->Value_[key] = value; } // -- Array utility @@ -211,9 +215,9 @@ private: void InfoWriter::SetConfig(std::string const& key, cmQtAutoGenInitializer::ConfigString const& cfgStr) { - Set(key, cfgStr.Default); + this->Set(key, cfgStr.Default); for (auto const& item : cfgStr.Config) { - Set(cmStrCat(key, '_', item.first), item.second); + this->Set(cmStrCat(key, '_', item.first), item.second); } } @@ -243,14 +247,14 @@ void InfoWriter::MakeStringArray(Json::Value& jval, CONT const& container) template <typename CONT> void InfoWriter::SetArray(std::string const& key, CONT const& container) { - MakeStringArray(Value_[key], container); + MakeStringArray(this->Value_[key], container); } template <typename CONT, typename FUNC> void InfoWriter::SetArrayArray(std::string const& key, CONT const& container, FUNC func) { - Json::Value& jval = Value_[key]; + Json::Value& jval = this->Value_[key]; if (MakeArray(jval, container)) { Json::ArrayIndex ii = 0; for (auto const& citem : container) { @@ -266,9 +270,9 @@ void InfoWriter::SetConfigArray( std::string const& key, cmQtAutoGenInitializer::ConfigStrings<CONT> const& cfgStr) { - SetArray(key, cfgStr.Default); + this->SetArray(key, cfgStr.Default); for (auto const& item : cfgStr.Config) { - SetArray(cmStrCat(key, '_', item.first), item.second); + this->SetArray(cmStrCat(key, '_', item.first), item.second); } } @@ -283,7 +287,7 @@ bool InfoWriter::Save(std::string const& filename) Json::StyledStreamWriter jsonWriter; try { - jsonWriter.write(fileStream, Value_); + jsonWriter.write(fileStream, this->Value_); } catch (...) { return false; } @@ -306,11 +310,11 @@ cmQtAutoGenInitializer::cmQtAutoGenInitializer( , PathCheckSum(genTarget->Makefile) , QtVersion(qtVersion) { - AutogenTarget.GlobalTarget = globalAutogenTarget; - Moc.Enabled = mocEnabled; - Uic.Enabled = uicEnabled; - Rcc.Enabled = rccEnabled; - Rcc.GlobalTarget = globalAutoRccTarget; + this->AutogenTarget.GlobalTarget = globalAutogenTarget; + this->Moc.Enabled = mocEnabled; + this->Uic.Enabled = uicEnabled; + this->Rcc.Enabled = rccEnabled; + this->Rcc.GlobalTarget = globalAutoRccTarget; } bool cmQtAutoGenInitializer::InitCustomTargets() @@ -416,8 +420,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets() cmSystemTools::ConvertToUnixSlashes(this->Dir.Work); // Include directory - ConfigFileNames(this->Dir.Include, cmStrCat(this->Dir.Build, "/include"), - ""); + this->ConfigFileNames(this->Dir.Include, + cmStrCat(this->Dir.Build, "/include"), ""); this->Dir.IncludeGenExp = this->Dir.Include.Default; if (this->MultiConfig) { this->Dir.IncludeGenExp += "_$<CONFIG>"; @@ -427,12 +431,12 @@ bool cmQtAutoGenInitializer::InitCustomTargets() // Moc, Uic and _autogen target settings if (this->MocOrUicEnabled()) { // Init moc specific settings - if (this->Moc.Enabled && !InitMoc()) { + if (this->Moc.Enabled && !this->InitMoc()) { return false; } // Init uic specific settings - if (this->Uic.Enabled && !InitUic()) { + if (this->Uic.Enabled && !this->InitUic()) { return false; } @@ -459,14 +463,14 @@ bool cmQtAutoGenInitializer::InitCustomTargets() cmStrCat(this->Dir.Info, "/AutogenInfo.json"); // Used settings file - ConfigFileNames(this->AutogenTarget.SettingsFile, - cmStrCat(this->Dir.Info, "/AutogenUsed"), ".txt"); - ConfigFileClean(this->AutogenTarget.SettingsFile); + this->ConfigFileNames(this->AutogenTarget.SettingsFile, + cmStrCat(this->Dir.Info, "/AutogenUsed"), ".txt"); + this->ConfigFileClean(this->AutogenTarget.SettingsFile); // Parse cache file - ConfigFileNames(this->AutogenTarget.ParseCacheFile, - cmStrCat(this->Dir.Info, "/ParseCache"), ".txt"); - ConfigFileClean(this->AutogenTarget.ParseCacheFile); + this->ConfigFileNames(this->AutogenTarget.ParseCacheFile, + cmStrCat(this->Dir.Info, "/ParseCache"), ".txt"); + this->ConfigFileClean(this->AutogenTarget.ParseCacheFile); } // Autogen target: Compute user defined dependencies @@ -535,7 +539,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets() } // Init rcc specific settings - if (this->Rcc.Enabled && !InitRcc()) { + if (this->Rcc.Enabled && !this->InitRcc()) { return false; } @@ -572,8 +576,9 @@ bool cmQtAutoGenInitializer::InitMoc() cmStrCat(this->Dir.Build, "/mocs_compilation.cpp"); this->Moc.CompilationFileGenex = this->Moc.CompilationFile.Default; } else { - ConfigFileNames(this->Moc.CompilationFile, - cmStrCat(this->Dir.Build, "/mocs_compilation"), ".cpp"); + this->ConfigFileNames(this->Moc.CompilationFile, + cmStrCat(this->Dir.Build, "/mocs_compilation"), + ".cpp"); if (this->MultiConfig) { this->Moc.CompilationFileGenex = cmStrCat(this->Dir.Build, "/mocs_compilation_$<CONFIG>.cpp"_s); @@ -590,8 +595,8 @@ bool cmQtAutoGenInitializer::InitMoc() this->Moc.PredefsCmd); // Header if (!this->Moc.PredefsCmd.empty()) { - ConfigFileNames(this->Moc.PredefsFile, - cmStrCat(this->Dir.Build, "/moc_predefs"), ".h"); + this->ConfigFileNames(this->Moc.PredefsFile, + cmStrCat(this->Dir.Build, "/moc_predefs"), ".h"); } } @@ -1035,7 +1040,7 @@ bool cmQtAutoGenInitializer::InitScanFiles() qrc.QrcName, '_', qrc.QrcPathChecksum); qrc.LockFile = cmStrCat(base, "_Lock.lock"); qrc.InfoFile = cmStrCat(base, "_Info.json"); - ConfigFileNames(qrc.SettingsFile, cmStrCat(base, "_Used"), ".txt"); + this->ConfigFileNames(qrc.SettingsFile, cmStrCat(base, "_Used"), ".txt"); } // rcc options for (Qrc& qrc : this->Rcc.Qrcs) { @@ -1133,7 +1138,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget() usePRE_BUILD = false; } // Cannot use PRE_BUILD when a global autogen target is in place - if (AutogenTarget.GlobalTarget) { + if (this->AutogenTarget.GlobalTarget) { usePRE_BUILD = false; } } diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx index ee2bc09..ebb6bd7 100644 --- a/Source/cmQtAutoGenerator.cxx +++ b/Source/cmQtAutoGenerator.cxx @@ -18,10 +18,10 @@ cmQtAutoGenerator::Logger::Logger() if (cmSystemTools::GetEnv("VERBOSE", verbose) && !verbose.empty()) { unsigned long iVerbose = 0; if (cmStrToULong(verbose, &iVerbose)) { - SetVerbosity(static_cast<unsigned int>(iVerbose)); + this->SetVerbosity(static_cast<unsigned int>(iVerbose)); } else { // Non numeric verbosity - SetVerbose(cmIsOn(verbose)); + this->SetVerbose(cmIsOn(verbose)); } } } @@ -29,9 +29,9 @@ cmQtAutoGenerator::Logger::Logger() std::string colorEnv; cmSystemTools::GetEnv("COLOR", colorEnv); if (!colorEnv.empty()) { - SetColorOutput(cmIsOn(colorEnv)); + this->SetColorOutput(cmIsOn(colorEnv)); } else { - SetColorOutput(true); + this->SetColorOutput(true); } } } @@ -47,7 +47,7 @@ void cmQtAutoGenerator::Logger::RaiseVerbosity(unsigned int value) void cmQtAutoGenerator::Logger::SetColorOutput(bool value) { - ColorOutput_ = value; + this->ColorOutput_ = value; } std::string cmQtAutoGenerator::Logger::HeadLine(cm::string_view title) @@ -61,7 +61,7 @@ void cmQtAutoGenerator::Logger::Info(GenT genType, std::string msg = cmStrCat(GeneratorName(genType), ": ", message, cmHasSuffix(message, '\n') ? "" : "\n"); { - std::lock_guard<std::mutex> lock(Mutex_); + std::lock_guard<std::mutex> lock(this->Mutex_); cmSystemTools::Stdout(msg); } } @@ -80,7 +80,7 @@ void cmQtAutoGenerator::Logger::Warning(GenT genType, message, cmHasSuffix(message, '\n') ? "\n" : "\n\n"); } { - std::lock_guard<std::mutex> lock(Mutex_); + std::lock_guard<std::mutex> lock(this->Mutex_); cmSystemTools::Stdout(msg); } } @@ -92,7 +92,7 @@ void cmQtAutoGenerator::Logger::Error(GenT genType, cmStrCat('\n', HeadLine(cmStrCat(GeneratorName(genType), " error")), message, cmHasSuffix(message, '\n') ? "\n" : "\n\n"); { - std::lock_guard<std::mutex> lock(Mutex_); + std::lock_guard<std::mutex> lock(this->Mutex_); cmSystemTools::Stderr(msg); } } @@ -108,7 +108,7 @@ void cmQtAutoGenerator::Logger::ErrorCommand( msg += cmStrCat(HeadLine("Output"), output, cmHasSuffix(output, '\n') ? "\n" : "\n\n"); { - std::lock_guard<std::mutex> lock(Mutex_); + std::lock_guard<std::mutex> lock(this->Mutex_); cmSystemTools::Stderr(msg); } } @@ -215,7 +215,7 @@ cmQtAutoGenerator::~cmQtAutoGenerator() = default; bool cmQtAutoGenerator::InfoT::Read(std::istream& istr) { try { - istr >> Json_; + istr >> this->Json_; } catch (...) { return false; } @@ -264,22 +264,22 @@ bool cmQtAutoGenerator::InfoT::GetJsonArray( std::string cmQtAutoGenerator::InfoT::ConfigKey(cm::string_view key) const { - return cmStrCat(key, '_', Gen_.InfoConfig()); + return cmStrCat(key, '_', this->Gen_.InfoConfig()); } bool cmQtAutoGenerator::InfoT::GetString(std::string const& key, std::string& value, bool required) const { - Json::Value const& jval = Json_[key]; + Json::Value const& jval = this->Json_[key]; if (!jval.isString()) { if (!jval.isNull() || required) { - return LogError(cmStrCat(key, " is not a string.")); + return this->LogError(cmStrCat(key, " is not a string.")); } } else { value = jval.asString(); if (value.empty() && required) { - return LogError(cmStrCat(key, " is empty.")); + return this->LogError(cmStrCat(key, " is empty.")); } } return true; @@ -290,32 +290,32 @@ bool cmQtAutoGenerator::InfoT::GetStringConfig(std::string const& key, bool required) const { { // Try config - std::string const configKey = ConfigKey(key); - Json::Value const& jval = Json_[configKey]; + std::string const configKey = this->ConfigKey(key); + Json::Value const& jval = this->Json_[configKey]; if (!jval.isNull()) { if (!jval.isString()) { - return LogError(cmStrCat(configKey, " is not a string.")); + return this->LogError(cmStrCat(configKey, " is not a string.")); } value = jval.asString(); if (required && value.empty()) { - return LogError(cmStrCat(configKey, " is empty.")); + return this->LogError(cmStrCat(configKey, " is empty.")); } return true; } } // Try plain - return GetString(key, value, required); + return this->GetString(key, value, required); } bool cmQtAutoGenerator::InfoT::GetBool(std::string const& key, bool& value, bool required) const { - Json::Value const& jval = Json_[key]; + Json::Value const& jval = this->Json_[key]; if (jval.isBool()) { value = jval.asBool(); } else { if (!jval.isNull() || required) { - return LogError(cmStrCat(key, " is not a boolean.")); + return this->LogError(cmStrCat(key, " is not a boolean.")); } } return true; @@ -325,12 +325,12 @@ bool cmQtAutoGenerator::InfoT::GetUInt(std::string const& key, unsigned int& value, bool required) const { - Json::Value const& jval = Json_[key]; + Json::Value const& jval = this->Json_[key]; if (jval.isUInt()) { value = jval.asUInt(); } else { if (!jval.isNull() || required) { - return LogError(cmStrCat(key, " is not an unsigned integer.")); + return this->LogError(cmStrCat(key, " is not an unsigned integer.")); } } return true; @@ -340,10 +340,10 @@ bool cmQtAutoGenerator::InfoT::GetArray(std::string const& key, std::vector<std::string>& list, bool required) const { - Json::Value const& jval = Json_[key]; + Json::Value const& jval = this->Json_[key]; if (!jval.isArray()) { if (!jval.isNull() || required) { - return LogError(cmStrCat(key, " is not an array.")); + return this->LogError(cmStrCat(key, " is not an array.")); } } return GetJsonArray(list, jval) || !required; @@ -353,10 +353,10 @@ bool cmQtAutoGenerator::InfoT::GetArray(std::string const& key, std::unordered_set<std::string>& list, bool required) const { - Json::Value const& jval = Json_[key]; + Json::Value const& jval = this->Json_[key]; if (!jval.isArray()) { if (!jval.isNull() || required) { - return LogError(cmStrCat(key, " is not an array.")); + return this->LogError(cmStrCat(key, " is not an array.")); } } return GetJsonArray(list, jval) || !required; @@ -367,34 +367,35 @@ bool cmQtAutoGenerator::InfoT::GetArrayConfig(std::string const& key, bool required) const { { // Try config - std::string const configKey = ConfigKey(key); - Json::Value const& jval = Json_[configKey]; + std::string const configKey = this->ConfigKey(key); + Json::Value const& jval = this->Json_[configKey]; if (!jval.isNull()) { if (!jval.isArray()) { - return LogError(cmStrCat(configKey, " is not an array string.")); + return this->LogError(cmStrCat(configKey, " is not an array string.")); } if (!GetJsonArray(list, jval) && required) { - return LogError(cmStrCat(configKey, " is empty.")); + return this->LogError(cmStrCat(configKey, " is empty.")); } return true; } } // Try plain - return GetArray(key, list, required); + return this->GetArray(key, list, required); } bool cmQtAutoGenerator::InfoT::LogError(GenT genType, cm::string_view message) const { - Gen_.Log().Error(genType, - cmStrCat("Info error in info file\n", - Quoted(Gen_.InfoFile()), ":\n", message)); + this->Gen_.Log().Error(genType, + cmStrCat("Info error in info file\n", + Quoted(this->Gen_.InfoFile()), ":\n", + message)); return false; } bool cmQtAutoGenerator::InfoT::LogError(cm::string_view message) const { - return LogError(Gen_.GenType_, message); + return this->LogError(this->Gen_.GenType_, message); } std::string cmQtAutoGenerator::SettingsFind(cm::string_view content, @@ -418,10 +419,10 @@ std::string cmQtAutoGenerator::SettingsFind(cm::string_view content, std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const { std::string res; - if (cmHasPrefix(path, ProjectDirs().Source)) { - res = cmStrCat("SRC:", path.substr(ProjectDirs().Source.size())); - } else if (cmHasPrefix(path, ProjectDirs().Binary)) { - res = cmStrCat("BIN:", path.substr(ProjectDirs().Binary.size())); + if (cmHasPrefix(path, this->ProjectDirs().Source)) { + res = cmStrCat("SRC:", path.substr(this->ProjectDirs().Source.size())); + } else if (cmHasPrefix(path, this->ProjectDirs().Binary)) { + res = cmStrCat("BIN:", path.substr(this->ProjectDirs().Binary.size())); } else { res = std::string(path); } @@ -431,17 +432,18 @@ std::string cmQtAutoGenerator::MessagePath(cm::string_view path) const bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config) { // Info config - InfoConfig_ = std::string(config); + this->InfoConfig_ = std::string(config); // Info file - InfoFile_ = std::string(infoFile); - cmSystemTools::CollapseFullPath(InfoFile_); - InfoDir_ = cmSystemTools::GetFilenamePath(InfoFile_); + this->InfoFile_ = std::string(infoFile); + cmSystemTools::CollapseFullPath(this->InfoFile_); + this->InfoDir_ = cmSystemTools::GetFilenamePath(this->InfoFile_); // Load info file time - if (!InfoFileTime_.Load(InfoFile_)) { + if (!this->InfoFileTime_.Load(this->InfoFile_)) { cmSystemTools::Stderr(cmStrCat("AutoGen: The info file ", - Quoted(InfoFile_), " is not readable\n")); + Quoted(this->InfoFile_), + " is not readable\n")); return false; } @@ -450,17 +452,18 @@ bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config) // Read info file { - cmsys::ifstream ifs(InfoFile_.c_str(), + cmsys::ifstream ifs(this->InfoFile_.c_str(), (std::ios::in | std::ios::binary)); if (!ifs) { - Log().Error( - GenType_, - cmStrCat("Could not to open info file ", Quoted(InfoFile_))); + this->Log().Error( + this->GenType_, + cmStrCat("Could not to open info file ", Quoted(this->InfoFile_))); return false; } if (!info.Read(ifs)) { - Log().Error(GenType_, - cmStrCat("Could not read info file ", Quoted(InfoFile_))); + this->Log().Error( + this->GenType_, + cmStrCat("Could not read info file ", Quoted(this->InfoFile_))); return false; } } @@ -470,15 +473,17 @@ bool cmQtAutoGenerator::Run(cm::string_view infoFile, cm::string_view config) unsigned int verbosity = 0; // Info: setup project directories if (!info.GetUInt("VERBOSITY", verbosity, false) || - !info.GetString("CMAKE_SOURCE_DIR", ProjectDirs_.Source, true) || - !info.GetString("CMAKE_BINARY_DIR", ProjectDirs_.Binary, true) || + !info.GetString("CMAKE_SOURCE_DIR", this->ProjectDirs_.Source, + true) || + !info.GetString("CMAKE_BINARY_DIR", this->ProjectDirs_.Binary, + true) || !info.GetString("CMAKE_CURRENT_SOURCE_DIR", - ProjectDirs_.CurrentSource, true) || + this->ProjectDirs_.CurrentSource, true) || !info.GetString("CMAKE_CURRENT_BINARY_DIR", - ProjectDirs_.CurrentBinary, true)) { + this->ProjectDirs_.CurrentBinary, true)) { return false; } - Logger_.RaiseVerbosity(verbosity); + this->Logger_.RaiseVerbosity(verbosity); } // -- Call virtual init from info method. diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h index b4f057d..53fbd69 100644 --- a/Source/cmQtAutoGenerator.h +++ b/Source/cmQtAutoGenerator.h @@ -88,10 +88,10 @@ public: cmQtAutoGenerator& operator=(cmQtAutoGenerator const&) = delete; // -- Info options - std::string const& InfoFile() const { return InfoFile_; } - std::string const& InfoDir() const { return InfoDir_; } - cmFileTime const& InfoFileTime() const { return InfoFileTime_; } - std::string const& InfoConfig() const { return InfoConfig_; } + std::string const& InfoFile() const { return this->InfoFile_; } + std::string const& InfoDir() const { return this->InfoDir_; } + cmFileTime const& InfoFileTime() const { return this->InfoFileTime_; } + std::string const& InfoConfig() const { return this->InfoConfig_; } // -- Info file parsing /** Info file reader class. */ @@ -124,7 +124,7 @@ public: Json::Value const& GetValue(std::string const& key) const { - return Json_[key]; + return this->Json_[key]; } /** Returns true if strings were appended to the list. */ @@ -150,7 +150,7 @@ public: cm::string_view key); // -- Directories - ProjectDirsT const& ProjectDirs() const { return ProjectDirs_; } + ProjectDirsT const& ProjectDirs() const { return this->ProjectDirs_; } std::string MessagePath(cm::string_view path) const; // -- Run @@ -161,7 +161,7 @@ protected: virtual bool InitFromInfo(InfoT const& info) = 0; virtual bool Process() = 0; // - Utility classes - Logger const& Log() const { return Logger_; } + Logger const& Log() const { return this->Logger_; } private: // -- Generator type diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx index c9d4268..3556051 100644 --- a/Source/cmQtAutoMocUic.cxx +++ b/Source/cmQtAutoMocUic.cxx @@ -313,22 +313,22 @@ public: //! Get the generator. Only valid during Process() call! cmQtAutoMocUicT* Gen() const { - return static_cast<cmQtAutoMocUicT*>(UserData()); + return static_cast<cmQtAutoMocUicT*>(this->UserData()); }; // -- Accessors. Only valid during Process() call! - Logger const& Log() const { return Gen()->Log(); } - BaseSettingsT const& BaseConst() const { return Gen()->BaseConst(); } - BaseEvalT& BaseEval() const { return Gen()->BaseEval(); } - MocSettingsT const& MocConst() const { return Gen()->MocConst(); } - MocEvalT& MocEval() const { return Gen()->MocEval(); } - UicSettingsT const& UicConst() const { return Gen()->UicConst(); } - UicEvalT& UicEval() const { return Gen()->UicEval(); } + Logger const& Log() const { return this->Gen()->Log(); } + BaseSettingsT const& BaseConst() const { return this->Gen()->BaseConst(); } + BaseEvalT& BaseEval() const { return this->Gen()->BaseEval(); } + MocSettingsT const& MocConst() const { return this->Gen()->MocConst(); } + MocEvalT& MocEval() const { return this->Gen()->MocEval(); } + UicSettingsT const& UicConst() const { return this->Gen()->UicConst(); } + UicEvalT& UicEval() const { return this->Gen()->UicEval(); } // -- Logging std::string MessagePath(cm::string_view path) const { - return Gen()->MessagePath(path); + return this->Gen()->MessagePath(path); } // - Error logging with automatic abort void LogError(GenT genType, cm::string_view message) const; @@ -522,6 +522,7 @@ public: class JobDepFilesMergeT : public JobFenceT { private: + std::vector<std::string> initialDependencies() const; void Process() override; }; @@ -541,9 +542,9 @@ public: UicEvalT& UicEval() { return this->UicEval_; } // -- Parallel job processing interface - cmWorkerPool& WorkerPool() { return WorkerPool_; } - void AbortError() { Abort(true); } - void AbortSuccess() { Abort(false); } + cmWorkerPool& WorkerPool() { return this->WorkerPool_; } + void AbortError() { this->Abort(true); } + void AbortSuccess() { this->Abort(false); } // -- Utility std::string AbsoluteBuildPath(cm::string_view relativePath) const; @@ -597,19 +598,19 @@ cmQtAutoMocUicT::IncludeKeyT::IncludeKeyT(std::string const& key, , Base(cmSystemTools::GetFilenameWithoutLastExtension(key)) { if (basePrefixLength != 0) { - Base = Base.substr(basePrefixLength); + this->Base = this->Base.substr(basePrefixLength); } } void cmQtAutoMocUicT::ParseCacheT::FileT::Clear() { - Moc.Macro.clear(); - Moc.Include.Underscore.clear(); - Moc.Include.Dot.clear(); - Moc.Depends.clear(); + this->Moc.Macro.clear(); + this->Moc.Include.Underscore.clear(); + this->Moc.Include.Dot.clear(); + this->Moc.Depends.clear(); - Uic.Include.clear(); - Uic.Depends.clear(); + this->Uic.Include.clear(); + this->Uic.Depends.clear(); } cmQtAutoMocUicT::ParseCacheT::GetOrInsertT @@ -617,15 +618,15 @@ cmQtAutoMocUicT::ParseCacheT::GetOrInsert(std::string const& fileName) { // Find existing entry { - auto it = Map_.find(fileName); - if (it != Map_.end()) { + auto it = this->Map_.find(fileName); + if (it != this->Map_.end()) { return GetOrInsertT{ it->second, false }; } } // Insert new entry return GetOrInsertT{ - Map_.emplace(fileName, std::make_shared<FileT>()).first->second, true + this->Map_.emplace(fileName, std::make_shared<FileT>()).first->second, true }; } @@ -655,7 +656,7 @@ bool cmQtAutoMocUicT::ParseCacheT::ReadFromFile(std::string const& fileName) } // Check if this a file name line if (line.front() != ' ') { - fileHandle = GetOrInsert(line).first; + fileHandle = this->GetOrInsert(line).first; continue; } @@ -702,7 +703,7 @@ bool cmQtAutoMocUicT::ParseCacheT::WriteToFile(std::string const& fileName) return false; } ofs << "# Generated by CMake. Changes will be overwritten.\n"; - for (auto const& pair : Map_) { + for (auto const& pair : this->Map_) { ofs << pair.first << '\n'; FileT const& file = *pair.second; if (!file.Moc.Macro.empty()) { @@ -732,7 +733,7 @@ cmQtAutoMocUicT::BaseSettingsT::~BaseSettingsT() = default; cmQtAutoMocUicT::MocSettingsT::MocSettingsT() { - RegExpInclude.compile( + this->RegExpInclude.compile( "(^|\n)[ \t]*#[ \t]*include[ \t]+" "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); } @@ -741,14 +742,15 @@ cmQtAutoMocUicT::MocSettingsT::~MocSettingsT() = default; bool cmQtAutoMocUicT::MocSettingsT::skipped(std::string const& fileName) const { - return (!Enabled || (SkipList.find(fileName) != SkipList.end())); + return (!this->Enabled || + (this->SkipList.find(fileName) != this->SkipList.end())); } std::string cmQtAutoMocUicT::MocSettingsT::MacrosString() const { std::string res; - const auto itB = MacroFilters.cbegin(); - const auto itE = MacroFilters.cend(); + const auto itB = this->MacroFilters.cbegin(); + const auto itE = this->MacroFilters.cend(); const auto itL = itE - 1; auto itC = itB; for (; itC != itE; ++itC) { @@ -768,30 +770,31 @@ std::string cmQtAutoMocUicT::MocSettingsT::MacrosString() const cmQtAutoMocUicT::UicSettingsT::UicSettingsT() { - RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+" - "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]"); + this->RegExpInclude.compile("(^|\n)[ \t]*#[ \t]*include[ \t]+" + "[\"<](([^ \">]+/)?ui_[^ \">/]+\\.h)[\">]"); } cmQtAutoMocUicT::UicSettingsT::~UicSettingsT() = default; bool cmQtAutoMocUicT::UicSettingsT::skipped(std::string const& fileName) const { - return (!Enabled || (SkipList.find(fileName) != SkipList.end())); + return (!this->Enabled || + (this->SkipList.find(fileName) != this->SkipList.end())); } void cmQtAutoMocUicT::JobT::LogError(GenT genType, cm::string_view message) const { - Gen()->AbortError(); - Gen()->Log().Error(genType, message); + this->Gen()->AbortError(); + this->Gen()->Log().Error(genType, message); } void cmQtAutoMocUicT::JobT::LogCommandError( GenT genType, cm::string_view message, std::vector<std::string> const& command, std::string const& output) const { - Gen()->AbortError(); - Gen()->Log().ErrorCommand(genType, message, command, output); + this->Gen()->AbortError(); + this->Gen()->Log().ErrorCommand(genType, message, command, output); } bool cmQtAutoMocUicT::JobT::RunProcess(GenT genType, @@ -800,48 +803,48 @@ bool cmQtAutoMocUicT::JobT::RunProcess(GenT genType, std::string* infoMessage) { // Log command - if (Log().Verbose()) { + if (this->Log().Verbose()) { cm::string_view info; if (infoMessage != nullptr) { info = *infoMessage; } - Log().Info(genType, - cmStrCat(info, - info.empty() || cmHasSuffix(info, '\n') ? "" : "\n", - QuotedCommand(command), '\n')); + this->Log().Info( + genType, + cmStrCat(info, info.empty() || cmHasSuffix(info, '\n') ? "" : "\n", + QuotedCommand(command), '\n')); } // Run command - return cmWorkerPool::JobT::RunProcess(result, command, - BaseConst().AutogenBuildDir); + return this->cmWorkerPool::JobT::RunProcess( + result, command, this->BaseConst().AutogenBuildDir); } void cmQtAutoMocUicT::JobMocPredefsT::Process() { // (Re)generate moc_predefs.h on demand std::unique_ptr<std::string> reason; - if (Log().Verbose()) { + if (this->Log().Verbose()) { reason = cm::make_unique<std::string>(); } - if (!Update(reason.get())) { + if (!this->Update(reason.get())) { return; } - std::string const& predefsFileAbs = MocConst().PredefsFileAbs; + std::string const& predefsFileAbs = this->MocConst().PredefsFileAbs; { cmWorkerPool::ProcessResultT result; { // Compose command - std::vector<std::string> cmd = MocConst().PredefsCmd; + std::vector<std::string> cmd = this->MocConst().PredefsCmd; // Add definitions - cm::append(cmd, MocConst().OptionsDefinitions); + cm::append(cmd, this->MocConst().OptionsDefinitions); // Add includes - cm::append(cmd, MocConst().OptionsIncludes); + cm::append(cmd, this->MocConst().OptionsIncludes); // Execute command - if (!RunProcess(GenT::MOC, result, cmd, reason.get())) { - LogCommandError(GenT::MOC, - cmStrCat("The content generation command for ", - MessagePath(predefsFileAbs), " failed.\n", - result.ErrorMessage), - cmd, result.StdOut); + if (!this->RunProcess(GenT::MOC, result, cmd, reason.get())) { + this->LogCommandError(GenT::MOC, + cmStrCat("The content generation command for ", + this->MessagePath(predefsFileAbs), + " failed.\n", result.ErrorMessage), + cmd, result.StdOut); return; } } @@ -849,30 +852,31 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process() // (Re)write predefs file only on demand if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) { if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) { - LogError( + this->LogError( GenT::MOC, - cmStrCat("Writing ", MessagePath(predefsFileAbs), " failed.")); + cmStrCat("Writing ", this->MessagePath(predefsFileAbs), " failed.")); return; } } else { // Touch to update the time stamp - if (Log().Verbose()) { - Log().Info(GenT::MOC, "Touching " + MessagePath(predefsFileAbs)); + if (this->Log().Verbose()) { + this->Log().Info(GenT::MOC, + "Touching " + this->MessagePath(predefsFileAbs)); } if (!cmSystemTools::Touch(predefsFileAbs, false)) { - LogError( - GenT::MOC, - cmStrCat("Touching ", MessagePath(predefsFileAbs), " failed.")); + this->LogError(GenT::MOC, + cmStrCat("Touching ", this->MessagePath(predefsFileAbs), + " failed.")); return; } } } // Read file time afterwards - if (!MocEval().PredefsTime.Load(predefsFileAbs)) { - LogError(GenT::MOC, - cmStrCat("Reading the file time of ", MessagePath(predefsFileAbs), - " failed.")); + if (!this->MocEval().PredefsTime.Load(predefsFileAbs)) { + this->LogError(GenT::MOC, + cmStrCat("Reading the file time of ", + this->MessagePath(predefsFileAbs), " failed.")); return; } } @@ -880,18 +884,20 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process() bool cmQtAutoMocUicT::JobMocPredefsT::Update(std::string* reason) const { // Test if the file exists - if (!MocEval().PredefsTime.Load(MocConst().PredefsFileAbs)) { + if (!this->MocEval().PredefsTime.Load(this->MocConst().PredefsFileAbs)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs), + *reason = cmStrCat("Generating ", + this->MessagePath(this->MocConst().PredefsFileAbs), ", because it doesn't exist."); } return true; } // Test if the settings changed - if (MocConst().SettingsChanged) { + if (this->MocConst().SettingsChanged) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs), + *reason = cmStrCat("Generating ", + this->MessagePath(this->MocConst().PredefsFileAbs), ", because the moc settings changed."); } return true; @@ -899,14 +905,14 @@ bool cmQtAutoMocUicT::JobMocPredefsT::Update(std::string* reason) const // Test if the executable is newer { - std::string const& exec = MocConst().PredefsCmd.at(0); + std::string const& exec = this->MocConst().PredefsCmd.at(0); cmFileTime execTime; if (execTime.Load(exec)) { - if (MocEval().PredefsTime.Older(execTime)) { + if (this->MocEval().PredefsTime.Older(execTime)) { if (reason != nullptr) { - *reason = - cmStrCat("Generating ", MessagePath(MocConst().PredefsFileAbs), - " because it is older than ", MessagePath(exec), '.'); + *reason = cmStrCat( + "Generating ", this->MessagePath(this->MocConst().PredefsFileAbs), + " because it is older than ", this->MessagePath(exec), '.'); } return true; } @@ -919,25 +925,27 @@ bool cmQtAutoMocUicT::JobMocPredefsT::Update(std::string* reason) const bool cmQtAutoMocUicT::JobParseT::ReadFile() { // Clear old parse information - FileHandle->ParseData->Clear(); - std::string const& fileName = FileHandle->FileName; + this->FileHandle->ParseData->Clear(); + std::string const& fileName = this->FileHandle->FileName; // Write info - if (Log().Verbose()) { - Log().Info(GenT::GEN, cmStrCat("Parsing ", MessagePath(fileName))); + if (this->Log().Verbose()) { + this->Log().Info(GenT::GEN, + cmStrCat("Parsing ", this->MessagePath(fileName))); } // Read file content { std::string error; - if (!cmQtAutoGenerator::FileRead(Content, fileName, &error)) { - LogError( - GenT::GEN, - cmStrCat("Could not read ", MessagePath(fileName), ".\n", error)); + if (!cmQtAutoGenerator::FileRead(this->Content, fileName, &error)) { + this->LogError(GenT::GEN, + cmStrCat("Could not read ", this->MessagePath(fileName), + ".\n", error)); return false; } } // Warn if empty - if (Content.empty()) { - Log().Warning(GenT::GEN, cmStrCat(MessagePath(fileName), " is empty.")); + if (this->Content.empty()) { + this->Log().Warning(GenT::GEN, + cmStrCat(this->MessagePath(fileName), " is empty.")); return false; } return true; @@ -958,16 +966,16 @@ void cmQtAutoMocUicT::JobParseT::CreateKeys( void cmQtAutoMocUicT::JobParseT::MocMacro() { - for (KeyExpT const& filter : MocConst().MacroFilters) { + for (KeyExpT const& filter : this->MocConst().MacroFilters) { // Run a simple find string check - if (Content.find(filter.Key) == std::string::npos) { + if (this->Content.find(filter.Key) == std::string::npos) { continue; } // Run the expensive regular expression check loop cmsys::RegularExpressionMatch match; - if (filter.Exp.find(Content.c_str(), match)) { + if (filter.Exp.find(this->Content.c_str(), match)) { // Keep detected macro name - FileHandle->ParseData->Moc.Macro = filter.Key; + this->FileHandle->ParseData->Moc.Macro = filter.Key; return; } } @@ -975,19 +983,20 @@ void cmQtAutoMocUicT::JobParseT::MocMacro() void cmQtAutoMocUicT::JobParseT::MocDependecies() { - if (MocConst().DependFilters.empty() || MocConst().CanOutputDependencies) { + if (this->MocConst().DependFilters.empty() || + this->MocConst().CanOutputDependencies) { return; } // Find dependency strings std::set<std::string> parseDepends; - for (KeyExpT const& filter : MocConst().DependFilters) { + for (KeyExpT const& filter : this->MocConst().DependFilters) { // Run a simple find string check - if (Content.find(filter.Key) == std::string::npos) { + if (this->Content.find(filter.Key) == std::string::npos) { continue; } // Run the expensive regular expression check loop - const char* contentChars = Content.c_str(); + const char* contentChars = this->Content.c_str(); cmsys::RegularExpressionMatch match; while (filter.Exp.find(contentChars, match)) { { @@ -1002,7 +1011,7 @@ void cmQtAutoMocUicT::JobParseT::MocDependecies() // Store dependency strings { - auto& Depends = FileHandle->ParseData->Moc.Depends; + auto& Depends = this->FileHandle->ParseData->Moc.Depends; Depends.reserve(parseDepends.size()); for (std::string const& item : parseDepends) { Depends.emplace_back(item); @@ -1016,15 +1025,15 @@ void cmQtAutoMocUicT::JobParseT::MocDependecies() void cmQtAutoMocUicT::JobParseT::MocIncludes() { - if (Content.find("moc") == std::string::npos) { + if (this->Content.find("moc") == std::string::npos) { return; } std::set<std::string> underscore; std::set<std::string> dot; { - const char* contentChars = Content.c_str(); - cmsys::RegularExpression const& regExp = MocConst().RegExpInclude; + const char* contentChars = this->Content.c_str(); + cmsys::RegularExpression const& regExp = this->MocConst().RegExpInclude; cmsys::RegularExpressionMatch match; while (regExp.find(contentChars, match)) { std::string incString = match.match(2); @@ -1042,21 +1051,21 @@ void cmQtAutoMocUicT::JobParseT::MocIncludes() contentChars += match.end(); } } - auto& Include = FileHandle->ParseData->Moc.Include; - CreateKeys(Include.Underscore, underscore, MocUnderscoreLength); - CreateKeys(Include.Dot, dot, 0); + auto& Include = this->FileHandle->ParseData->Moc.Include; + this->CreateKeys(Include.Underscore, underscore, MocUnderscoreLength); + this->CreateKeys(Include.Dot, dot, 0); } void cmQtAutoMocUicT::JobParseT::UicIncludes() { - if (Content.find("ui_") == std::string::npos) { + if (this->Content.find("ui_") == std::string::npos) { return; } std::set<std::string> includes; { - const char* contentChars = Content.c_str(); - cmsys::RegularExpression const& regExp = UicConst().RegExpInclude; + const char* contentChars = this->Content.c_str(); + cmsys::RegularExpression const& regExp = this->UicConst().RegExpInclude; cmsys::RegularExpressionMatch match; while (regExp.find(contentChars, match)) { includes.emplace(match.match(2)); @@ -1064,39 +1073,40 @@ void cmQtAutoMocUicT::JobParseT::UicIncludes() contentChars += match.end(); } } - CreateKeys(FileHandle->ParseData->Uic.Include, includes, UiUnderscoreLength); + this->CreateKeys(this->FileHandle->ParseData->Uic.Include, includes, + UiUnderscoreLength); } void cmQtAutoMocUicT::JobParseHeaderT::Process() { - if (!ReadFile()) { + if (!this->ReadFile()) { return; } // Moc parsing - if (FileHandle->Moc) { - MocMacro(); - MocDependecies(); + if (this->FileHandle->Moc) { + this->MocMacro(); + this->MocDependecies(); } // Uic parsing - if (FileHandle->Uic) { - UicIncludes(); + if (this->FileHandle->Uic) { + this->UicIncludes(); } } void cmQtAutoMocUicT::JobParseSourceT::Process() { - if (!ReadFile()) { + if (!this->ReadFile()) { return; } // Moc parsing - if (FileHandle->Moc) { - MocMacro(); - MocDependecies(); - MocIncludes(); + if (this->FileHandle->Moc) { + this->MocMacro(); + this->MocDependecies(); + this->MocIncludes(); } // Uic parsing - if (FileHandle->Uic) { - UicIncludes(); + if (this->FileHandle->Uic) { + this->UicIncludes(); } } @@ -1104,9 +1114,9 @@ std::string cmQtAutoMocUicT::JobEvalCacheT::MessageSearchLocations() const { std::string res; res.reserve(512); - for (std::string const& path : SearchLocations) { + for (std::string const& path : this->SearchLocations) { res += " "; - res += MessagePath(path); + res += this->MessagePath(path); res += '\n'; } return res; @@ -1115,14 +1125,14 @@ std::string cmQtAutoMocUicT::JobEvalCacheT::MessageSearchLocations() const void cmQtAutoMocUicT::JobEvalCacheMocT::Process() { // Evaluate headers - for (auto const& pair : BaseEval().Headers) { - if (!EvalHeader(pair.second)) { + for (auto const& pair : this->BaseEval().Headers) { + if (!this->EvalHeader(pair.second)) { return; } } // Evaluate sources - for (auto const& pair : BaseEval().Sources) { - if (!EvalSource(pair.second)) { + for (auto const& pair : this->BaseEval().Sources) { + if (!this->EvalSource(pair.second)) { return; } } @@ -1142,14 +1152,16 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalHeader(SourceFileHandleT source) handle->SourceFile = std::move(source); // Absolute build path - if (BaseConst().MultiConfig) { - handle->OutputFile = Gen()->AbsoluteIncludePath(sourceFile.BuildPath); + if (this->BaseConst().MultiConfig) { + handle->OutputFile = + this->Gen()->AbsoluteIncludePath(sourceFile.BuildPath); } else { - handle->OutputFile = Gen()->AbsoluteBuildPath(sourceFile.BuildPath); + handle->OutputFile = + this->Gen()->AbsoluteBuildPath(sourceFile.BuildPath); } // Register mapping in headers map - RegisterMapping(handle); + this->RegisterMapping(handle); } return true; @@ -1171,7 +1183,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource( cmSystemTools::GetFilenameWithoutLastExtension(sourceFile.FileName); // For relaxed mode check if the own "moc_" or ".moc" file is included - bool const relaxedMode = MocConst().RelaxedMode; + bool const relaxedMode = this->MocConst().RelaxedMode; bool sourceIncludesMocUnderscore = false; bool sourceIncludesDotMoc = false; // Check if the sources own "moc_" or ".moc" file is included @@ -1193,12 +1205,13 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource( // Check if this source needs to be moc processed but doesn't. if (!sourceIncludesDotMoc && !parseData.Macro.empty() && !(relaxedMode && sourceIncludesMocUnderscore)) { - LogError(GenT::MOC, - cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ", - Quoted(parseData.Macro), " macro, but does not include ", - MessagePath(sourceBase + ".moc"), - "!\nConsider to\n - add #include \"", sourceBase, - ".moc\"\n - enable SKIP_AUTOMOC for this file")); + this->LogError(GenT::MOC, + cmStrCat(this->MessagePath(sourceFile.FileName), + "\ncontains a ", Quoted(parseData.Macro), + " macro, but does not include ", + this->MessagePath(sourceBase + ".moc"), + "!\nConsider to\n - add #include \"", sourceBase, + ".moc\"\n - enable SKIP_AUTOMOC for this file")); return false; } @@ -1207,14 +1220,16 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource( SourceFileHandleT headerHandle; { std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base); - if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) { - LogError(GenT::MOC, - cmStrCat(MessagePath(sourceFile.FileName), - "\nincludes the moc file ", MessagePath(incKey.Key), - ",\nbut a header ", MessageHeader(headerBase), - "\ncould not be found " - "in the following directories\n", - MessageSearchLocations())); + if (!this->FindIncludedHeader(headerHandle, sourceDirPrefix, + headerBase)) { + this->LogError( + GenT::MOC, + cmStrCat(this->MessagePath(sourceFile.FileName), + "\nincludes the moc file ", this->MessagePath(incKey.Key), + ",\nbut a header ", this->MessageHeader(headerBase), + "\ncould not be found " + "in the following directories\n", + this->MessageSearchLocations())); return false; } } @@ -1228,30 +1243,31 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource( // used. This is for KDE4 compatibility. // Issue a warning - Log().Warning( + this->Log().Warning( GenT::MOC, - cmStrCat(MessagePath(sourceFile.FileName), "\ncontains a ", + cmStrCat(this->MessagePath(sourceFile.FileName), "\ncontains a ", Quoted(parseData.Macro), " macro, but does not include ", - MessagePath(sourceBase + ".moc"), ".\nInstead it includes ", - MessagePath(incKey.Key), ".\nRunning moc on the source\n ", - MessagePath(sourceFile.FileName), "!\nBetter include ", - MessagePath(sourceBase + ".moc"), + this->MessagePath(sourceBase + ".moc"), + ".\nInstead it includes ", this->MessagePath(incKey.Key), + ".\nRunning moc on the source\n ", + this->MessagePath(sourceFile.FileName), "!\nBetter include ", + this->MessagePath(sourceBase + ".moc"), " for compatibility with regular mode.\n", "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); // Create mapping - if (!RegisterIncluded(incKey.Key, source, source)) { + if (!this->RegisterIncluded(incKey.Key, source, source)) { return false; } continue; } // Check if header is skipped - if (MocConst().skipped(headerHandle->FileName)) { + if (this->MocConst().skipped(headerHandle->FileName)) { continue; } // Create mapping - if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) { + if (!this->RegisterIncluded(incKey.Key, source, std::move(headerHandle))) { return false; } } @@ -1264,7 +1280,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource( bool const ownMoc = (incKey.Base == sourceBase); if (ownMoc && !parseData.Macro.empty()) { // Create mapping for the regular use case - if (!RegisterIncluded(incKey.Key, source, source)) { + if (!this->RegisterIncluded(incKey.Key, source, source)) { return false; } continue; @@ -1274,50 +1290,54 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource( SourceFileHandleT headerHandle; { std::string const headerBase = cmStrCat(incKey.Dir, incKey.Base); - if (!FindIncludedHeader(headerHandle, sourceDirPrefix, headerBase)) { - LogError( + if (!this->FindIncludedHeader(headerHandle, sourceDirPrefix, + headerBase)) { + this->LogError( GenT::MOC, cmStrCat( - MessagePath(sourceFile.FileName), "\nincludes the moc file ", - MessagePath(incKey.Key), + this->MessagePath(sourceFile.FileName), + "\nincludes the moc file ", this->MessagePath(incKey.Key), ",\nwhich seems to be the moc file from a different source " "file.\nCMAKE_AUTOMOC_RELAXED_MODE:\nAlso a matching header ", - MessageHeader(headerBase), + this->MessageHeader(headerBase), "\ncould not be found in the following directories\n", - MessageSearchLocations())); + this->MessageSearchLocations())); return false; } } // Check if header is skipped - if (MocConst().skipped(headerHandle->FileName)) { + if (this->MocConst().skipped(headerHandle->FileName)) { continue; } // Issue a warning if (ownMoc && parseData.Macro.empty()) { - Log().Warning( + this->Log().Warning( GenT::MOC, - cmStrCat(MessagePath(sourceFile.FileName), - "\nincludes the moc file ", MessagePath(incKey.Key), - ", but does not contain a\n", MocConst().MacrosString(), - " macro.\nRunning moc on the header\n ", - MessagePath(headerHandle->FileName), "!\nBetter include ", - MessagePath("moc_" + incKey.Base + ".cpp"), - " for a compatibility with regular mode.\n", - "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); + cmStrCat( + this->MessagePath(sourceFile.FileName), "\nincludes the moc file ", + this->MessagePath(incKey.Key), ", but does not contain a\n", + this->MocConst().MacrosString(), + " macro.\nRunning moc on the header\n ", + this->MessagePath(headerHandle->FileName), "!\nBetter include ", + this->MessagePath("moc_" + incKey.Base + ".cpp"), + " for a compatibility with regular mode.\n", + "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); } else { - Log().Warning( + this->Log().Warning( GenT::MOC, - cmStrCat(MessagePath(sourceFile.FileName), - "\nincludes the moc file ", MessagePath(incKey.Key), - " instead of ", MessagePath("moc_" + incKey.Base + ".cpp"), - ".\nRunning moc on the header\n ", - MessagePath(headerHandle->FileName), "!\nBetter include ", - MessagePath("moc_" + incKey.Base + ".cpp"), - " for compatibility with regular mode.\n", - "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); + cmStrCat( + this->MessagePath(sourceFile.FileName), "\nincludes the moc file ", + this->MessagePath(incKey.Key), " instead of ", + this->MessagePath("moc_" + incKey.Base + ".cpp"), + ".\nRunning moc on the header\n ", + this->MessagePath(headerHandle->FileName), "!\nBetter include ", + this->MessagePath("moc_" + incKey.Base + ".cpp"), + " for compatibility with regular mode.\n", + "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n")); } // Create mapping - if (!RegisterIncluded(incKey.Key, source, std::move(headerHandle))) { + if (!this->RegisterIncluded(incKey.Key, source, + std::move(headerHandle))) { return false; } } @@ -1328,26 +1348,27 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::EvalSource( bool const ownMoc = (incKey.Base == sourceBase); if (!ownMoc) { // Don't allow <BASE>.moc include other than own in regular mode - LogError(GenT::MOC, - cmStrCat(MessagePath(sourceFile.FileName), - "\nincludes the moc file ", MessagePath(incKey.Key), - ",\nwhich seems to be the moc file from a different " - "source file.\nThis is not supported. Include ", - MessagePath(sourceBase + ".moc"), - " to run moc on this source file.")); + this->LogError( + GenT::MOC, + cmStrCat(this->MessagePath(sourceFile.FileName), + "\nincludes the moc file ", this->MessagePath(incKey.Key), + ",\nwhich seems to be the moc file from a different " + "source file.\nThis is not supported. Include ", + this->MessagePath(sourceBase + ".moc"), + " to run moc on this source file.")); return false; } // Accept but issue a warning if moc isn't required if (parseData.Macro.empty()) { - Log().Warning(GenT::MOC, - cmStrCat(MessagePath(sourceFile.FileName), - "\nincludes the moc file ", - MessagePath(incKey.Key), - ", but does not contain a ", - MocConst().MacrosString(), " macro.")); + this->Log().Warning( + GenT::MOC, + cmStrCat(this->MessagePath(sourceFile.FileName), + "\nincludes the moc file ", this->MessagePath(incKey.Key), + ", but does not contain a ", + this->MocConst().MacrosString(), " macro.")); } // Create mapping - if (!RegisterIncluded(incKey.Key, source, source)) { + if (!this->RegisterIncluded(incKey.Key, source, source)) { return false; } } @@ -1361,7 +1382,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader( cm::string_view includeBase) { // Clear search locations - SearchLocations.clear(); + this->SearchLocations.clear(); auto findHeader = [this, &headerHandle](std::string const& basePath) -> bool { @@ -1377,8 +1398,8 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader( // Return a known file if it exists already { - auto it = BaseEval().Headers.find(testPath); - if (it != BaseEval().Headers.end()) { + auto it = this->BaseEval().Headers.find(testPath); + if (it != this->BaseEval().Headers.end()) { headerHandle = it->second; found = true; break; @@ -1387,7 +1408,8 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader( // Created and return discovered file entry { - SourceFileHandleT& handle = MocEval().HeadersDiscovered[testPath]; + SourceFileHandleT& handle = + this->MocEval().HeadersDiscovered[testPath]; if (!handle) { handle = std::make_shared<SourceFileT>(testPath); handle->FileTime = fileTime; @@ -1410,7 +1432,7 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::FindIncludedHeader( return true; } // Search in include directories - for (std::string const& path : MocConst().IncludePaths) { + for (std::string const& path : this->MocConst().IncludePaths) { if (findHeader(cmStrCat(path, '/', includeBase))) { return true; } @@ -1424,24 +1446,24 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::RegisterIncluded( SourceFileHandleT sourceFileHandle) const { // Check if this file is already included - MappingHandleT& handle = MocEval().Includes[includeString]; + MappingHandleT& handle = this->MocEval().Includes[includeString]; if (handle) { // Check if the output file would be generated from different source files if (handle->SourceFile != sourceFileHandle) { std::string files = - cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n'); + cmStrCat(" ", this->MessagePath(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { - files += cmStrCat(" ", MessagePath(item->FileName), '\n'); + files += cmStrCat(" ", this->MessagePath(item->FileName), '\n'); } - LogError( + this->LogError( GenT::MOC, cmStrCat("The source files\n", files, "contain the same include string ", - MessagePath(includeString), + this->MessagePath(includeString), ", but\nthe moc file would be generated from different " "source files\n ", - MessagePath(sourceFileHandle->FileName), " and\n ", - MessagePath(handle->SourceFile->FileName), + this->MessagePath(sourceFileHandle->FileName), " and\n ", + this->MessagePath(handle->SourceFile->FileName), ".\nConsider to\n" " - not include the \"moc_<NAME>.cpp\" file\n" " - add a directory prefix to a \"<NAME>.moc\" include " @@ -1460,10 +1482,10 @@ bool cmQtAutoMocUicT::JobEvalCacheMocT::RegisterIncluded( handle->IncludeString = includeString; handle->IncluderFiles.emplace_back(std::move(includerFileHandle)); handle->SourceFile = std::move(sourceFileHandle); - handle->OutputFile = Gen()->AbsoluteIncludePath(includeString); + handle->OutputFile = this->Gen()->AbsoluteIncludePath(includeString); // Register mapping in sources/headers map - RegisterMapping(handle); + this->RegisterMapping(handle); return true; } @@ -1471,8 +1493,8 @@ void cmQtAutoMocUicT::JobEvalCacheMocT::RegisterMapping( MappingHandleT mappingHandle) const { auto& regMap = mappingHandle->SourceFile->IsHeader - ? MocEval().HeaderMappings - : MocEval().SourceMappings; + ? this->MocEval().HeaderMappings + : this->MocEval().SourceMappings; // Check if source file already gets mapped auto& regHandle = regMap[mappingHandle->SourceFile->FileName]; if (!regHandle) { @@ -1489,24 +1511,24 @@ void cmQtAutoMocUicT::JobEvalCacheMocT::RegisterMapping( std::string cmQtAutoMocUicT::JobEvalCacheMocT::MessageHeader( cm::string_view headerBase) const { - return MessagePath(cmStrCat( + return this->MessagePath(cmStrCat( headerBase, ".{", cmJoin(this->BaseConst().HeaderExtensions, ","), '}')); } void cmQtAutoMocUicT::JobEvalCacheUicT::Process() { // Prepare buffers - SearchLocations.reserve((UicConst().SearchPaths.size() + 1) * 2); + this->SearchLocations.reserve((this->UicConst().SearchPaths.size() + 1) * 2); // Evaluate headers - for (auto const& pair : BaseEval().Headers) { - if (!EvalFile(pair.second)) { + for (auto const& pair : this->BaseEval().Headers) { + if (!this->EvalFile(pair.second)) { return; } } // Evaluate sources - for (auto const& pair : BaseEval().Sources) { - if (!EvalFile(pair.second)) { + for (auto const& pair : this->BaseEval().Sources) { + if (!this->EvalFile(pair.second)) { return; } } @@ -1524,22 +1546,24 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::EvalFile( std::string const sourceDirPrefix = SubDirPrefix(sourceFile.FileName); for (IncludeKeyT const& incKey : Include) { // Find .ui file - UiName = cmStrCat(incKey.Base, ".ui"); - if (!FindIncludedUi(sourceDirPrefix, incKey.Dir)) { - LogError(GenT::UIC, - cmStrCat(MessagePath(sourceFile.FileName), - "\nincludes the uic file ", MessagePath(incKey.Key), - ",\nbut the user interface file ", MessagePath(UiName), - "\ncould not be found in the following directories\n", - MessageSearchLocations())); + this->UiName = cmStrCat(incKey.Base, ".ui"); + if (!this->FindIncludedUi(sourceDirPrefix, incKey.Dir)) { + this->LogError( + GenT::UIC, + cmStrCat(this->MessagePath(sourceFile.FileName), + "\nincludes the uic file ", this->MessagePath(incKey.Key), + ",\nbut the user interface file ", + this->MessagePath(this->UiName), + "\ncould not be found in the following directories\n", + this->MessageSearchLocations())); return false; } // Check if the file is skipped - if (UicConst().skipped(UiFileHandle->FileName)) { + if (this->UicConst().skipped(this->UiFileHandle->FileName)) { continue; } // Register mapping - if (!RegisterMapping(incKey.Key, sourceFileHandle)) { + if (!this->RegisterMapping(incKey.Key, sourceFileHandle)) { return false; } } @@ -1551,7 +1575,7 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi( cm::string_view sourceDirPrefix, cm::string_view includePrefix) { // Clear locations buffer - SearchLocations.clear(); + this->SearchLocations.clear(); auto findUi = [this](std::string const& testPath) -> bool { std::string const fullPath = this->Gen()->CollapseFullPathTS(testPath); @@ -1573,25 +1597,25 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi( }; // Vicinity of the source - if (findUi(cmStrCat(sourceDirPrefix, UiName))) { + if (findUi(cmStrCat(sourceDirPrefix, this->UiName))) { return true; } if (!includePrefix.empty()) { - if (findUi(cmStrCat(sourceDirPrefix, includePrefix, UiName))) { + if (findUi(cmStrCat(sourceDirPrefix, includePrefix, this->UiName))) { return true; } } // Additional AUTOUIC search paths - auto const& searchPaths = UicConst().SearchPaths; + auto const& searchPaths = this->UicConst().SearchPaths; if (!searchPaths.empty()) { for (std::string const& sPath : searchPaths) { - if (findUi(cmStrCat(sPath, '/', UiName))) { + if (findUi(cmStrCat(sPath, '/', this->UiName))) { return true; } } if (!includePrefix.empty()) { for (std::string const& sPath : searchPaths) { - if (findUi(cmStrCat(sPath, '/', includePrefix, UiName))) { + if (findUi(cmStrCat(sPath, '/', includePrefix, this->UiName))) { return true; } } @@ -1604,26 +1628,26 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::FindIncludedUi( bool cmQtAutoMocUicT::JobEvalCacheUicT::RegisterMapping( std::string const& includeString, SourceFileHandleT includerFileHandle) { - auto& Includes = Gen()->UicEval().Includes; + auto& Includes = this->Gen()->UicEval().Includes; auto it = Includes.find(includeString); if (it != Includes.end()) { MappingHandleT const& handle = it->second; - if (handle->SourceFile != UiFileHandle) { + if (handle->SourceFile != this->UiFileHandle) { // The output file already gets generated - from a different .ui file! std::string files = - cmStrCat(" ", MessagePath(includerFileHandle->FileName), '\n'); + cmStrCat(" ", this->MessagePath(includerFileHandle->FileName), '\n'); for (auto const& item : handle->IncluderFiles) { - files += cmStrCat(" ", MessagePath(item->FileName), '\n'); + files += cmStrCat(" ", this->MessagePath(item->FileName), '\n'); } - LogError( + this->LogError( GenT::UIC, cmStrCat( "The source files\n", files, "contain the same include string ", Quoted(includeString), ", but\nthe uic file would be generated from different " "user interface files\n ", - MessagePath(UiFileHandle->FileName), " and\n ", - MessagePath(handle->SourceFile->FileName), + this->MessagePath(this->UiFileHandle->FileName), " and\n ", + this->MessagePath(handle->SourceFile->FileName), ".\nConsider to\n" " - add a directory prefix to a \"ui_<NAME>.h\" include " "(e.g \"sub/ui_<NAME>.h\")\n" @@ -1638,8 +1662,8 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::RegisterMapping( MappingHandleT handle = std::make_shared<MappingT>(); handle->IncludeString = includeString; handle->IncluderFiles.emplace_back(std::move(includerFileHandle)); - handle->SourceFile = UiFileHandle; - handle->OutputFile = Gen()->AbsoluteIncludePath(includeString); + handle->SourceFile = this->UiFileHandle; + handle->OutputFile = this->Gen()->AbsoluteIncludePath(includeString); // Register mapping Includes.emplace(includeString, std::move(handle)); } @@ -1649,40 +1673,42 @@ bool cmQtAutoMocUicT::JobEvalCacheUicT::RegisterMapping( void cmQtAutoMocUicT::JobEvalCacheFinishT::Process() { // Add discovered header parse jobs - Gen()->CreateParseJobs<JobParseHeaderT>(MocEval().HeadersDiscovered); + this->Gen()->CreateParseJobs<JobParseHeaderT>( + this->MocEval().HeadersDiscovered); // Add dependency probing jobs { // Add fence job to ensure all parsing has finished - Gen()->WorkerPool().EmplaceJob<JobFenceT>(); - if (MocConst().Enabled) { - Gen()->WorkerPool().EmplaceJob<JobProbeDepsMocT>(); + this->Gen()->WorkerPool().EmplaceJob<JobFenceT>(); + if (this->MocConst().Enabled) { + this->Gen()->WorkerPool().EmplaceJob<JobProbeDepsMocT>(); } - if (UicConst().Enabled) { - Gen()->WorkerPool().EmplaceJob<JobProbeDepsUicT>(); + if (this->UicConst().Enabled) { + this->Gen()->WorkerPool().EmplaceJob<JobProbeDepsUicT>(); } // Add probe finish job - Gen()->WorkerPool().EmplaceJob<JobProbeDepsFinishT>(); + this->Gen()->WorkerPool().EmplaceJob<JobProbeDepsFinishT>(); } } void cmQtAutoMocUicT::JobProbeDepsMocT::Process() { // Create moc header jobs - for (auto const& pair : MocEval().HeaderMappings) { + for (auto const& pair : this->MocEval().HeaderMappings) { // Register if this mapping is a candidate for mocs_compilation.cpp bool const compFile = pair.second->IncludeString.empty(); if (compFile) { - MocEval().CompFiles.emplace_back(pair.second->SourceFile->BuildPath); + this->MocEval().CompFiles.emplace_back( + pair.second->SourceFile->BuildPath); } - if (!Generate(pair.second, compFile)) { + if (!this->Generate(pair.second, compFile)) { return; } } // Create moc source jobs - for (auto const& pair : MocEval().SourceMappings) { - if (!Generate(pair.second, false)) { + for (auto const& pair : this->MocEval().SourceMappings) { + if (!this->Generate(pair.second, false)) { return; } } @@ -1692,22 +1718,23 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping, bool compFile) const { std::unique_ptr<std::string> reason; - if (Log().Verbose()) { + if (this->Log().Verbose()) { reason = cm::make_unique<std::string>(); } - if (Probe(*mapping, reason.get())) { + if (this->Probe(*mapping, reason.get())) { // Register the parent directory for creation - MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile)); + this->MocEval().OutputDirs.emplace( + cmQtAutoGen::ParentDir(mapping->OutputFile)); // Fetch the cache entry for the source file std::string const& sourceFile = mapping->SourceFile->FileName; ParseCacheT::GetOrInsertT cacheEntry = - BaseEval().ParseCache.GetOrInsert(sourceFile); + this->BaseEval().ParseCache.GetOrInsert(sourceFile); // Add moc job - Gen()->WorkerPool().EmplaceJob<JobCompileMocT>( + this->Gen()->WorkerPool().EmplaceJob<JobCompileMocT>( mapping, std::move(reason), std::move(cacheEntry.first)); // Check if a moc job for a mocs_compilation.cpp entry was generated if (compFile) { - MocEval().CompUpdated = true; + this->MocEval().CompUpdated = true; } } return true; @@ -1723,19 +1750,19 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping, cmFileTime outputFileTime; if (!outputFileTime.Load(outputFile)) { if (reason != nullptr) { - *reason = - cmStrCat("Generating ", MessagePath(outputFile), - ", because it doesn't exist, from ", MessagePath(sourceFile)); + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), + ", because it doesn't exist, from ", + this->MessagePath(sourceFile)); } return true; } // Test if any setting changed - if (MocConst().SettingsChanged) { + if (this->MocConst().SettingsChanged) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), ", because the uic settings changed, from ", - MessagePath(sourceFile)); + this->MessagePath(sourceFile)); } return true; } @@ -1743,32 +1770,32 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping, // Test if the source file is newer if (outputFileTime.Older(mapping.SourceFile->FileTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), ", because it's older than its source file, from ", - MessagePath(sourceFile)); + this->MessagePath(sourceFile)); } return true; } // Test if the moc_predefs file is newer - if (!MocConst().PredefsFileAbs.empty()) { - if (outputFileTime.Older(MocEval().PredefsTime)) { + if (!this->MocConst().PredefsFileAbs.empty()) { + if (outputFileTime.Older(this->MocEval().PredefsTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), ", because it's older than ", - MessagePath(MocConst().PredefsFileAbs), ", from ", - MessagePath(sourceFile)); + this->MessagePath(this->MocConst().PredefsFileAbs), + ", from ", this->MessagePath(sourceFile)); } return true; } } // Test if the moc executable is newer - if (outputFileTime.Older(MocConst().ExecutableTime)) { + if (outputFileTime.Older(this->MocConst().ExecutableTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), ", because it's older than the moc executable, from ", - MessagePath(sourceFile)); + this->MessagePath(sourceFile)); } return true; } @@ -1782,26 +1809,26 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Probe(MappingT const& mapping, auto& dep = *it; // Find dependency file - auto const depMatch = FindDependency(sourceDir, dep); + auto const depMatch = this->FindDependency(sourceDir, dep); if (depMatch.first.empty()) { if (reason != nullptr) { - *reason = - cmStrCat("Generating ", MessagePath(outputFile), " from ", - MessagePath(sourceFile), ", because its dependency ", - MessagePath(dep), " vanished."); + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), + " from ", this->MessagePath(sourceFile), + ", because its dependency ", + this->MessagePath(dep), " vanished."); } dependencies.erase(it); - BaseEval().ParseCacheChanged = true; + this->BaseEval().ParseCacheChanged = true; return true; } // Test if dependency file is older if (outputFileTime.Older(depMatch.second)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), ", because it's older than its dependency file ", - MessagePath(depMatch.first), ", from ", - MessagePath(sourceFile)); + this->MessagePath(depMatch.first), ", from ", + this->MessagePath(sourceFile)); } return true; } @@ -1817,7 +1844,7 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency( { using ResPair = std::pair<std::string, cmFileTime>; // moc's dependency file contains absolute paths - if (MocConst().CanOutputDependencies) { + if (this->MocConst().CanOutputDependencies) { ResPair res{ includeString, {} }; if (res.second.Load(res.first)) { return res; @@ -1832,7 +1859,7 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency( } } // Search in include directories - for (std::string const& includePath : MocConst().IncludePaths) { + for (std::string const& includePath : this->MocConst().IncludePaths) { ResPair res{ cmStrCat(includePath, '/', includeString), {} }; if (res.second.Load(res.first)) { return res; @@ -1844,20 +1871,22 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency( void cmQtAutoMocUicT::JobProbeDepsUicT::Process() { - for (auto const& pair : Gen()->UicEval().Includes) { + for (auto const& pair : this->Gen()->UicEval().Includes) { MappingHandleT const& mapping = pair.second; std::unique_ptr<std::string> reason; - if (Log().Verbose()) { + if (this->Log().Verbose()) { reason = cm::make_unique<std::string>(); } - if (!Probe(*mapping, reason.get())) { + if (!this->Probe(*mapping, reason.get())) { continue; } // Register the parent directory for creation - UicEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile)); + this->UicEval().OutputDirs.emplace( + cmQtAutoGen::ParentDir(mapping->OutputFile)); // Add uic job - Gen()->WorkerPool().EmplaceJob<JobCompileUicT>(mapping, std::move(reason)); + this->Gen()->WorkerPool().EmplaceJob<JobCompileUicT>(mapping, + std::move(reason)); } } @@ -1871,19 +1900,19 @@ bool cmQtAutoMocUicT::JobProbeDepsUicT::Probe(MappingT const& mapping, cmFileTime outputFileTime; if (!outputFileTime.Load(outputFile)) { if (reason != nullptr) { - *reason = - cmStrCat("Generating ", MessagePath(outputFile), - ", because it doesn't exist, from ", MessagePath(sourceFile)); + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), + ", because it doesn't exist, from ", + this->MessagePath(sourceFile)); } return true; } // Test if the uic settings changed - if (UicConst().SettingsChanged) { + if (this->UicConst().SettingsChanged) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), ", because the uic settings changed, from ", - MessagePath(sourceFile)); + this->MessagePath(sourceFile)); } return true; } @@ -1891,19 +1920,19 @@ bool cmQtAutoMocUicT::JobProbeDepsUicT::Probe(MappingT const& mapping, // Test if the source file is newer if (outputFileTime.Older(mapping.SourceFile->FileTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), " because it's older than the source file ", - MessagePath(sourceFile)); + this->MessagePath(sourceFile)); } return true; } // Test if the uic executable is newer - if (outputFileTime.Older(UicConst().ExecutableTime)) { + if (outputFileTime.Older(this->UicConst().ExecutableTime)) { if (reason != nullptr) { - *reason = cmStrCat("Generating ", MessagePath(outputFile), + *reason = cmStrCat("Generating ", this->MessagePath(outputFile), ", because it's older than the uic executable, from ", - MessagePath(sourceFile)); + this->MessagePath(sourceFile)); } return true; } @@ -1919,64 +1948,64 @@ void cmQtAutoMocUicT::JobProbeDepsFinishT::Process() auto createDirs = [this](GenT genType, StringSet const& dirSet) { for (std::string const& dirName : dirSet) { if (!cmSystemTools::MakeDirectory(dirName)) { - this->LogError( - genType, - cmStrCat("Creating directory ", MessagePath(dirName), " failed.")); + this->LogError(genType, + cmStrCat("Creating directory ", + this->MessagePath(dirName), " failed.")); return; } } }; - if (MocConst().Enabled && UicConst().Enabled) { - StringSet outputDirs = MocEval().OutputDirs; - outputDirs.insert(UicEval().OutputDirs.begin(), - UicEval().OutputDirs.end()); + if (this->MocConst().Enabled && this->UicConst().Enabled) { + StringSet outputDirs = this->MocEval().OutputDirs; + outputDirs.insert(this->UicEval().OutputDirs.begin(), + this->UicEval().OutputDirs.end()); createDirs(GenT::GEN, outputDirs); - } else if (MocConst().Enabled) { - createDirs(GenT::MOC, MocEval().OutputDirs); - } else if (UicConst().Enabled) { - createDirs(GenT::UIC, UicEval().OutputDirs); + } else if (this->MocConst().Enabled) { + createDirs(GenT::MOC, this->MocEval().OutputDirs); + } else if (this->UicConst().Enabled) { + createDirs(GenT::UIC, this->UicEval().OutputDirs); } } - if (MocConst().Enabled) { + if (this->MocConst().Enabled) { // Add mocs compilations job - Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>(); + this->Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>(); } - if (!BaseConst().DepFile.empty()) { + if (!this->BaseConst().DepFile.empty()) { // Add job to merge dep files - Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>(); + this->Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>(); } // Add finish job - Gen()->WorkerPool().EmplaceJob<JobFinishT>(); + this->Gen()->WorkerPool().EmplaceJob<JobFinishT>(); } void cmQtAutoMocUicT::JobCompileMocT::Process() { - std::string const& sourceFile = Mapping->SourceFile->FileName; - std::string const& outputFile = Mapping->OutputFile; + std::string const& sourceFile = this->Mapping->SourceFile->FileName; + std::string const& outputFile = this->Mapping->OutputFile; // Compose moc command std::vector<std::string> cmd; { // Reserve large enough - cmd.reserve(MocConst().OptionsDefinitions.size() + - MocConst().OptionsIncludes.size() + - MocConst().OptionsExtra.size() + 16); - cmd.push_back(MocConst().Executable); + cmd.reserve(this->MocConst().OptionsDefinitions.size() + + this->MocConst().OptionsIncludes.size() + + this->MocConst().OptionsExtra.size() + 16); + cmd.push_back(this->MocConst().Executable); // Add definitions - cm::append(cmd, MocConst().OptionsDefinitions); + cm::append(cmd, this->MocConst().OptionsDefinitions); // Add includes - cm::append(cmd, MocConst().OptionsIncludes); + cm::append(cmd, this->MocConst().OptionsIncludes); // Add predefs include - if (!MocConst().PredefsFileAbs.empty()) { + if (!this->MocConst().PredefsFileAbs.empty()) { cmd.emplace_back("--include"); - cmd.push_back(MocConst().PredefsFileAbs); + cmd.push_back(this->MocConst().PredefsFileAbs); } // Add path prefix on demand - if (MocConst().PathPrefix && Mapping->SourceFile->IsHeader) { - for (std::string const& dir : MocConst().IncludePaths) { + if (this->MocConst().PathPrefix && this->Mapping->SourceFile->IsHeader) { + for (std::string const& dir : this->MocConst().IncludePaths) { cm::string_view prefix = sourceFile; if (cmHasPrefix(prefix, dir)) { prefix.remove_prefix(dir.size()); @@ -1996,8 +2025,8 @@ void cmQtAutoMocUicT::JobCompileMocT::Process() } } // Add extra options - cm::append(cmd, MocConst().OptionsExtra); - if (MocConst().CanOutputDependencies) { + cm::append(cmd, this->MocConst().OptionsExtra); + if (this->MocConst().CanOutputDependencies) { cmd.emplace_back("--output-dep-file"); } // Add output file @@ -2009,60 +2038,60 @@ void cmQtAutoMocUicT::JobCompileMocT::Process() // Execute moc command cmWorkerPool::ProcessResultT result; - if (!RunProcess(GenT::MOC, result, cmd, Reason.get())) { + if (!this->RunProcess(GenT::MOC, result, cmd, this->Reason.get())) { // Moc command failed std::string includers; - if (!Mapping->IncluderFiles.empty()) { + if (!this->Mapping->IncluderFiles.empty()) { includers = "included by\n"; - for (auto const& item : Mapping->IncluderFiles) { - includers += cmStrCat(" ", MessagePath(item->FileName), '\n'); + for (auto const& item : this->Mapping->IncluderFiles) { + includers += cmStrCat(" ", this->MessagePath(item->FileName), '\n'); } } - LogCommandError(GenT::MOC, - cmStrCat("The moc process failed to compile\n ", - MessagePath(sourceFile), "\ninto\n ", - MessagePath(outputFile), '\n', includers, - result.ErrorMessage), - cmd, result.StdOut); + this->LogCommandError(GenT::MOC, + cmStrCat("The moc process failed to compile\n ", + this->MessagePath(sourceFile), "\ninto\n ", + this->MessagePath(outputFile), '\n', + includers, result.ErrorMessage), + cmd, result.StdOut); return; } // Moc command success. Print moc output. if (!result.StdOut.empty()) { - Log().Info(GenT::MOC, result.StdOut); + this->Log().Info(GenT::MOC, result.StdOut); } // Extract dependencies from the dep file moc generated for us - if (MocConst().CanOutputDependencies) { + if (this->MocConst().CanOutputDependencies) { const std::string depfile = outputFile + ".d"; - if (Log().Verbose()) { - Log().Info(GenT::MOC, - "Reading dependencies from " + MessagePath(depfile)); + if (this->Log().Verbose()) { + this->Log().Info( + GenT::MOC, "Reading dependencies from " + this->MessagePath(depfile)); } if (!cmSystemTools::FileExists(depfile)) { - Log().Warning(GenT::MOC, - "Dependency file " + MessagePath(depfile) + - " does not exist."); + this->Log().Warning(GenT::MOC, + "Dependency file " + this->MessagePath(depfile) + + " does not exist."); return; } - CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str()); + this->CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str()); } } void cmQtAutoMocUicT::JobCompileUicT::Process() { - std::string const& sourceFile = Mapping->SourceFile->FileName; - std::string const& outputFile = Mapping->OutputFile; + std::string const& sourceFile = this->Mapping->SourceFile->FileName; + std::string const& outputFile = this->Mapping->OutputFile; // Compose uic command std::vector<std::string> cmd; - cmd.push_back(UicConst().Executable); + cmd.push_back(this->UicConst().Executable); { - std::vector<std::string> allOpts = UicConst().Options; - auto optionIt = UicConst().UiFiles.find(sourceFile); - if (optionIt != UicConst().UiFiles.end()) { + std::vector<std::string> allOpts = this->UicConst().Options; + auto optionIt = this->UicConst().UiFiles.find(sourceFile); + if (optionIt != this->UicConst().UiFiles.end()) { UicMergeOptions(allOpts, optionIt->second.Options, - (BaseConst().QtVersion.Major == 5)); + (this->BaseConst().QtVersion.Major == 5)); } cm::append(cmd, allOpts); } @@ -2071,24 +2100,25 @@ void cmQtAutoMocUicT::JobCompileUicT::Process() cmd.emplace_back(sourceFile); cmWorkerPool::ProcessResultT result; - if (RunProcess(GenT::UIC, result, cmd, Reason.get())) { + if (this->RunProcess(GenT::UIC, result, cmd, this->Reason.get())) { // Uic command success // Print uic output if (!result.StdOut.empty()) { - Log().Info(GenT::UIC, result.StdOut); + this->Log().Info(GenT::UIC, result.StdOut); } } else { // Uic command failed std::string includers; - for (auto const& item : Mapping->IncluderFiles) { - includers += cmStrCat(" ", MessagePath(item->FileName), '\n'); + for (auto const& item : this->Mapping->IncluderFiles) { + includers += cmStrCat(" ", this->MessagePath(item->FileName), '\n'); } - LogCommandError(GenT::UIC, - cmStrCat("The uic process failed to compile\n ", - MessagePath(sourceFile), "\ninto\n ", - MessagePath(outputFile), "\nincluded by\n", - includers, result.ErrorMessage), - cmd, result.StdOut); + this->LogCommandError(GenT::UIC, + cmStrCat("The uic process failed to compile\n ", + this->MessagePath(sourceFile), "\ninto\n ", + this->MessagePath(outputFile), + "\nincluded by\n", includers, + result.ErrorMessage), + cmd, result.StdOut); } } @@ -2098,41 +2128,41 @@ void cmQtAutoMocUicT::JobMocsCompilationT::Process() std::string content = "// This file is autogenerated. Changes will be overwritten.\n"; - if (MocEval().CompFiles.empty()) { + if (this->MocEval().CompFiles.empty()) { // Placeholder content content += "// No files found that require moc or the moc files are " "included\n" "enum some_compilers { need_more_than_nothing };\n"; } else { // Valid content - const bool mc = BaseConst().MultiConfig; + const bool mc = this->BaseConst().MultiConfig; cm::string_view const wrapFront = mc ? "#include <" : "#include \""; cm::string_view const wrapBack = mc ? ">\n" : "\"\n"; - content += cmWrap(wrapFront, MocEval().CompFiles, wrapBack, ""); + content += cmWrap(wrapFront, this->MocEval().CompFiles, wrapBack, ""); } - std::string const& compAbs = MocConst().CompFileAbs; + std::string const& compAbs = this->MocConst().CompFileAbs; if (cmQtAutoGenerator::FileDiffers(compAbs, content)) { // Actually write mocs compilation file - if (Log().Verbose()) { - Log().Info(GenT::MOC, - "Generating MOC compilation " + MessagePath(compAbs)); + if (this->Log().Verbose()) { + this->Log().Info( + GenT::MOC, "Generating MOC compilation " + this->MessagePath(compAbs)); } if (!FileWrite(compAbs, content)) { - LogError(GenT::MOC, - cmStrCat("Writing MOC compilation ", MessagePath(compAbs), - " failed.")); + this->LogError(GenT::MOC, + cmStrCat("Writing MOC compilation ", + this->MessagePath(compAbs), " failed.")); } - } else if (MocEval().CompUpdated) { + } else if (this->MocEval().CompUpdated) { // Only touch mocs compilation file - if (Log().Verbose()) { - Log().Info(GenT::MOC, - "Touching MOC compilation " + MessagePath(compAbs)); + if (this->Log().Verbose()) { + this->Log().Info( + GenT::MOC, "Touching MOC compilation " + this->MessagePath(compAbs)); } if (!cmSystemTools::Touch(compAbs, false)) { - LogError(GenT::MOC, - cmStrCat("Touching MOC compilation ", MessagePath(compAbs), - " failed.")); + this->LogError(GenT::MOC, + cmStrCat("Touching MOC compilation ", + this->MessagePath(compAbs), " failed.")); } } } @@ -2169,12 +2199,36 @@ std::string escapeDependencyPath(cm::string_view path) return escapedPath; } +/* + * Return the initial dependencies of the merged depfile. + * Those are dependencies from the project files, not from moc runs. + */ +std::vector<std::string> +cmQtAutoMocUicT::JobDepFilesMergeT::initialDependencies() const +{ + std::vector<std::string> dependencies; + dependencies.reserve(this->BaseConst().ListFiles.size() + + this->BaseEval().Headers.size() + + this->BaseEval().Sources.size()); + cm::append(dependencies, this->BaseConst().ListFiles); + auto append_file_path = + [&dependencies](const SourceFileMapT::value_type& p) { + dependencies.push_back(p.first); + }; + std::for_each(this->BaseEval().Headers.begin(), + this->BaseEval().Headers.end(), append_file_path); + std::for_each(this->BaseEval().Sources.begin(), + this->BaseEval().Sources.end(), append_file_path); + return dependencies; +} + void cmQtAutoMocUicT::JobDepFilesMergeT::Process() { - if (Log().Verbose()) { - Log().Info(GenT::MOC, - cmStrCat("Merging MOC dependencies into ", - MessagePath(BaseConst().DepFile.c_str()))); + if (this->Log().Verbose()) { + this->Log().Info( + GenT::MOC, + cmStrCat("Merging MOC dependencies into ", + this->MessagePath(this->BaseConst().DepFile.c_str()))); } auto processDepFile = [](const std::string& mocOutputFile) -> std::vector<std::string> { @@ -2185,8 +2239,8 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process() return dependenciesFromDepFile(f.c_str()); }; - std::vector<std::string> dependencies = BaseConst().ListFiles; - ParseCacheT& parseCache = BaseEval().ParseCache; + std::vector<std::string> dependencies = this->initialDependencies(); + ParseCacheT& parseCache = this->BaseEval().ParseCache; auto processMappingEntry = [&](const MappingMapT::value_type& m) { auto cacheEntry = parseCache.GetOrInsert(m.first); if (cacheEntry.first->Moc.Depends.empty()) { @@ -2197,10 +2251,10 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process() cacheEntry.first->Moc.Depends.end()); }; - std::for_each(MocEval().HeaderMappings.begin(), - MocEval().HeaderMappings.end(), processMappingEntry); - std::for_each(MocEval().SourceMappings.begin(), - MocEval().SourceMappings.end(), processMappingEntry); + std::for_each(this->MocEval().HeaderMappings.begin(), + this->MocEval().HeaderMappings.end(), processMappingEntry); + std::for_each(this->MocEval().SourceMappings.begin(), + this->MocEval().SourceMappings.end(), processMappingEntry); // Remove duplicates to make the depfile smaller std::sort(dependencies.begin(), dependencies.end()); @@ -2208,39 +2262,42 @@ void cmQtAutoMocUicT::JobDepFilesMergeT::Process() dependencies.end()); // Add form files - for (const auto& uif : UicEval().UiFiles) { + for (const auto& uif : this->UicEval().UiFiles) { dependencies.push_back(uif.first); } // Write the file cmsys::ofstream ofs; - ofs.open(BaseConst().DepFile.c_str(), + ofs.open(this->BaseConst().DepFile.c_str(), (std::ios::out | std::ios::binary | std::ios::trunc)); if (!ofs) { - LogError(GenT::GEN, - cmStrCat("Cannot open ", MessagePath(BaseConst().DepFile), - " for writing.")); + this->LogError(GenT::GEN, + cmStrCat("Cannot open ", + this->MessagePath(this->BaseConst().DepFile), + " for writing.")); return; } - ofs << BaseConst().DepFileRuleName << ": \\\n"; + ofs << this->BaseConst().DepFileRuleName << ": \\\n"; for (const std::string& file : dependencies) { ofs << '\t' << escapeDependencyPath(file) << " \\\n"; if (!ofs.good()) { - LogError(GenT::GEN, - cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile), - " failed.")); + this->LogError(GenT::GEN, + cmStrCat("Writing depfile", + this->MessagePath(this->BaseConst().DepFile), + " failed.")); return; } } // Add the CMake executable to re-new cache data if necessary. // Also, this is the last entry, so don't add a backslash. - ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable) << '\n'; + ofs << '\t' << escapeDependencyPath(this->BaseConst().CMakeExecutable) + << '\n'; } void cmQtAutoMocUicT::JobFinishT::Process() { - Gen()->AbortSuccess(); + this->Gen()->AbortSuccess(); } cmQtAutoMocUicT::cmQtAutoMocUicT() @@ -2252,42 +2309,51 @@ cmQtAutoMocUicT::~cmQtAutoMocUicT() = default; bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) { // -- Required settings - if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) || - !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersion.Major, true) || - !info.GetUInt("QT_VERSION_MINOR", BaseConst_.QtVersion.Minor, true) || - !info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) || - !info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) || - !info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir, - true) || - !info.GetString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) || - !info.GetStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile, + if (!info.GetBool("MULTI_CONFIG", this->BaseConst_.MultiConfig, true) || + !info.GetUInt("QT_VERSION_MAJOR", this->BaseConst_.QtVersion.Major, + true) || + !info.GetUInt("QT_VERSION_MINOR", this->BaseConst_.QtVersion.Minor, + true) || + !info.GetUInt("PARALLEL", this->BaseConst_.ThreadCount, false) || + !info.GetString("BUILD_DIR", this->BaseConst_.AutogenBuildDir, true) || + !info.GetStringConfig("INCLUDE_DIR", this->BaseConst_.AutogenIncludeDir, true) || - !info.GetString("DEP_FILE", BaseConst_.DepFile, false) || - !info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName, + !info.GetString("CMAKE_EXECUTABLE", this->BaseConst_.CMakeExecutable, + true) || + !info.GetStringConfig("PARSE_CACHE_FILE", + this->BaseConst_.ParseCacheFile, true) || + !info.GetString("DEP_FILE", this->BaseConst_.DepFile, false) || + !info.GetString("DEP_FILE_RULE_NAME", this->BaseConst_.DepFileRuleName, false) || - !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) || - !info.GetArray("CMAKE_LIST_FILES", BaseConst_.ListFiles, true) || - !info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) || - !info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) || - !info.GetString("QT_UIC_EXECUTABLE", UicConst_.Executable, false)) { + !info.GetStringConfig("SETTINGS_FILE", this->SettingsFile_, true) || + !info.GetArray("CMAKE_LIST_FILES", this->BaseConst_.ListFiles, true) || + !info.GetArray("HEADER_EXTENSIONS", this->BaseConst_.HeaderExtensions, + true) || + !info.GetString("QT_MOC_EXECUTABLE", this->MocConst_.Executable, + false) || + !info.GetString("QT_UIC_EXECUTABLE", this->UicConst_.Executable, + false)) { return false; } // -- Checks - if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) { - return info.LogError(cmStrCat("The CMake executable ", - MessagePath(BaseConst_.CMakeExecutable), - " does not exist.")); + if (!this->BaseConst_.CMakeExecutableTime.Load( + this->BaseConst_.CMakeExecutable)) { + return info.LogError( + cmStrCat("The CMake executable ", + this->MessagePath(this->BaseConst_.CMakeExecutable), + " does not exist.")); } // -- Evaluate values - BaseConst_.ThreadCount = std::min(BaseConst_.ThreadCount, ParallelMax); - WorkerPool_.SetThreadCount(BaseConst_.ThreadCount); + this->BaseConst_.ThreadCount = + std::min(this->BaseConst_.ThreadCount, ParallelMax); + this->WorkerPool_.SetThreadCount(this->BaseConst_.ThreadCount); // -- Moc - if (!MocConst_.Executable.empty()) { + if (!this->MocConst_.Executable.empty()) { // -- Moc is enabled - MocConst_.Enabled = true; + this->MocConst_.Enabled = true; // -- Temporary buffers struct @@ -2297,18 +2363,21 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) } tmp; // -- Required settings - if (!info.GetBool("MOC_RELAXED_MODE", MocConst_.RelaxedMode, false) || - !info.GetBool("MOC_PATH_PREFIX", MocConst_.PathPrefix, true) || - !info.GetArray("MOC_SKIP", MocConst_.SkipList, false) || - !info.GetArrayConfig("MOC_DEFINITIONS", MocConst_.Definitions, + if (!info.GetBool("MOC_RELAXED_MODE", this->MocConst_.RelaxedMode, + false) || + !info.GetBool("MOC_PATH_PREFIX", this->MocConst_.PathPrefix, true) || + !info.GetArray("MOC_SKIP", this->MocConst_.SkipList, false) || + !info.GetArrayConfig("MOC_DEFINITIONS", this->MocConst_.Definitions, false) || - !info.GetArrayConfig("MOC_INCLUDES", MocConst_.IncludePaths, false) || - !info.GetArray("MOC_OPTIONS", MocConst_.OptionsExtra, false) || - !info.GetStringConfig("MOC_COMPILATION_FILE", MocConst_.CompFileAbs, - true) || - !info.GetArray("MOC_PREDEFS_CMD", MocConst_.PredefsCmd, false) || - !info.GetStringConfig("MOC_PREDEFS_FILE", MocConst_.PredefsFileAbs, - !MocConst_.PredefsCmd.empty()) || + !info.GetArrayConfig("MOC_INCLUDES", this->MocConst_.IncludePaths, + false) || + !info.GetArray("MOC_OPTIONS", this->MocConst_.OptionsExtra, false) || + !info.GetStringConfig("MOC_COMPILATION_FILE", + this->MocConst_.CompFileAbs, true) || + !info.GetArray("MOC_PREDEFS_CMD", this->MocConst_.PredefsCmd, false) || + !info.GetStringConfig("MOC_PREDEFS_FILE", + this->MocConst_.PredefsFileAbs, + !this->MocConst_.PredefsCmd.empty()) || !info.GetArray("MOC_MACRO_NAMES", tmp.MacroNames, true) || !info.GetArray("MOC_DEPEND_FILTERS", tmp.DependFilters, false)) { return false; @@ -2316,12 +2385,12 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) // -- Evaluate settings for (std::string const& item : tmp.MacroNames) { - MocConst_.MacroFilters.emplace_back( + this->MocConst_.MacroFilters.emplace_back( item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]")); } // Can moc output dependencies or do we need to setup dependency filters? - if (BaseConst_.QtVersion >= IntegerVersion(5, 15)) { - MocConst_.CanOutputDependencies = true; + if (this->BaseConst_.QtVersion >= IntegerVersion(5, 15)) { + this->MocConst_.CanOutputDependencies = true; } else { Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS"); if (!val.isArray()) { @@ -2371,22 +2440,23 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) } } // Check if moc executable exists (by reading the file time) - if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) { - return info.LogError(cmStrCat("The moc executable ", - MessagePath(MocConst_.Executable), - " does not exist.")); + if (!this->MocConst_.ExecutableTime.Load(this->MocConst_.Executable)) { + return info.LogError(cmStrCat( + "The moc executable ", this->MessagePath(this->MocConst_.Executable), + " does not exist.")); } } // -- Uic - if (!UicConst_.Executable.empty()) { + if (!this->UicConst_.Executable.empty()) { // Uic is enabled - UicConst_.Enabled = true; + this->UicConst_.Enabled = true; // -- Required settings - if (!info.GetArray("UIC_SKIP", UicConst_.SkipList, false) || - !info.GetArray("UIC_SEARCH_PATHS", UicConst_.SearchPaths, false) || - !info.GetArrayConfig("UIC_OPTIONS", UicConst_.Options, false)) { + if (!info.GetArray("UIC_SKIP", this->UicConst_.SkipList, false) || + !info.GetArray("UIC_SEARCH_PATHS", this->UicConst_.SearchPaths, + false) || + !info.GetArrayConfig("UIC_OPTIONS", this->UicConst_.Options, false)) { return false; } // .ui files @@ -2420,17 +2490,17 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) return false; } - auto& uiFile = UicConst_.UiFiles[entryName.asString()]; + auto& uiFile = this->UicConst_.UiFiles[entryName.asString()]; InfoT::GetJsonArray(uiFile.Options, entryOptions); } } // -- Evaluate settings // Check if uic executable exists (by reading the file time) - if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) { - return info.LogError(cmStrCat("The uic executable ", - MessagePath(UicConst_.Executable), - " does not exist.")); + if (!this->UicConst_.ExecutableTime.Load(this->UicConst_.Executable)) { + return info.LogError(cmStrCat( + "The uic executable ", this->MessagePath(this->UicConst_.Executable), + " does not exist.")); } } @@ -2505,14 +2575,15 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) sourceHandle->IsHeader = true; sourceHandle->Moc = (flags[0] == 'M'); sourceHandle->Uic = (flags[1] == 'U'); - if (sourceHandle->Moc && MocConst().Enabled) { + if (sourceHandle->Moc && this->MocConst().Enabled) { if (build.empty()) { return info.LogError( cmStrCat("Header file ", ii, " build path is empty")); } sourceHandle->BuildPath = std::move(build); } - BaseEval().Headers.emplace(std::move(name), std::move(sourceHandle)); + this->BaseEval().Headers.emplace(std::move(name), + std::move(sourceHandle)); } } @@ -2583,18 +2654,19 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) sourceHandle->IsHeader = false; sourceHandle->Moc = (flags[0] == 'M'); sourceHandle->Uic = (flags[1] == 'U'); - BaseEval().Sources.emplace(std::move(name), std::move(sourceHandle)); + this->BaseEval().Sources.emplace(std::move(name), + std::move(sourceHandle)); } } // -- Init derived information // Moc variables - if (MocConst().Enabled) { + if (this->MocConst().Enabled) { // Compose moc includes list { // Compute framework paths std::set<std::string> frameworkPaths; - for (std::string const& path : MocConst().IncludePaths) { + for (std::string const& path : this->MocConst().IncludePaths) { // Extract framework path if (cmHasLiteralSuffix(path, ".framework/Headers")) { // Go up twice to get to the framework root @@ -2605,24 +2677,25 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) } } // Reserve options - MocConst_.OptionsIncludes.reserve(MocConst().IncludePaths.size() + - frameworkPaths.size() * 2); + this->MocConst_.OptionsIncludes.reserve( + this->MocConst().IncludePaths.size() + frameworkPaths.size() * 2); // Append includes - for (std::string const& path : MocConst().IncludePaths) { - MocConst_.OptionsIncludes.emplace_back("-I" + path); + for (std::string const& path : this->MocConst().IncludePaths) { + this->MocConst_.OptionsIncludes.emplace_back("-I" + path); } // Append framework includes for (std::string const& path : frameworkPaths) { - MocConst_.OptionsIncludes.emplace_back("-F"); - MocConst_.OptionsIncludes.push_back(path); + this->MocConst_.OptionsIncludes.emplace_back("-F"); + this->MocConst_.OptionsIncludes.push_back(path); } } // Compose moc definitions list { - MocConst_.OptionsDefinitions.reserve(MocConst().Definitions.size()); - for (std::string const& def : MocConst().Definitions) { - MocConst_.OptionsDefinitions.emplace_back("-D" + def); + this->MocConst_.OptionsDefinitions.reserve( + this->MocConst().Definitions.size()); + for (std::string const& def : this->MocConst().Definitions) { + this->MocConst_.OptionsDefinitions.emplace_back("-D" + def); } } } @@ -2633,16 +2706,16 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info) template <class JOBTYPE> void cmQtAutoMocUicT::CreateParseJobs(SourceFileMapT const& sourceMap) { - cmFileTime const parseCacheTime = BaseEval().ParseCacheTime; - ParseCacheT& parseCache = BaseEval().ParseCache; + cmFileTime const parseCacheTime = this->BaseEval().ParseCacheTime; + ParseCacheT& parseCache = this->BaseEval().ParseCache; for (auto& src : sourceMap) { // Get or create the file parse data reference ParseCacheT::GetOrInsertT cacheEntry = parseCache.GetOrInsert(src.first); src.second->ParseData = std::move(cacheEntry.first); // Create a parse job if the cache file was missing or is older if (cacheEntry.second || src.second->FileTime.Newer(parseCacheTime)) { - BaseEval().ParseCacheChanged = true; - WorkerPool().EmplaceJob<JOBTYPE>(src.second); + this->BaseEval().ParseCacheChanged = true; + this->WorkerPool().EmplaceJob<JOBTYPE>(src.second); } } } @@ -2650,55 +2723,56 @@ void cmQtAutoMocUicT::CreateParseJobs(SourceFileMapT const& sourceMap) /** Concurrently callable implementation of cmSystemTools::CollapseFullPath */ std::string cmQtAutoMocUicT::CollapseFullPathTS(std::string const& path) const { - std::lock_guard<std::mutex> guard(CMakeLibMutex_); - return cmSystemTools::CollapseFullPath(path, ProjectDirs().CurrentSource); + std::lock_guard<std::mutex> guard(this->CMakeLibMutex_); + return cmSystemTools::CollapseFullPath(path, + this->ProjectDirs().CurrentSource); } void cmQtAutoMocUicT::InitJobs() { // Add moc_predefs.h job - if (MocConst().Enabled && !MocConst().PredefsCmd.empty()) { - WorkerPool().EmplaceJob<JobMocPredefsT>(); + if (this->MocConst().Enabled && !this->MocConst().PredefsCmd.empty()) { + this->WorkerPool().EmplaceJob<JobMocPredefsT>(); } // Add header parse jobs - CreateParseJobs<JobParseHeaderT>(BaseEval().Headers); + this->CreateParseJobs<JobParseHeaderT>(this->BaseEval().Headers); // Add source parse jobs - CreateParseJobs<JobParseSourceT>(BaseEval().Sources); + this->CreateParseJobs<JobParseSourceT>(this->BaseEval().Sources); // Add parse cache evaluations jobs { // Add a fence job to ensure all parsing has finished - WorkerPool().EmplaceJob<JobFenceT>(); - if (MocConst().Enabled) { - WorkerPool().EmplaceJob<JobEvalCacheMocT>(); + this->WorkerPool().EmplaceJob<JobFenceT>(); + if (this->MocConst().Enabled) { + this->WorkerPool().EmplaceJob<JobEvalCacheMocT>(); } - if (UicConst().Enabled) { - WorkerPool().EmplaceJob<JobEvalCacheUicT>(); + if (this->UicConst().Enabled) { + this->WorkerPool().EmplaceJob<JobEvalCacheUicT>(); } // Add evaluate job - WorkerPool().EmplaceJob<JobEvalCacheFinishT>(); + this->WorkerPool().EmplaceJob<JobEvalCacheFinishT>(); } } bool cmQtAutoMocUicT::Process() { - SettingsFileRead(); - ParseCacheRead(); - if (!CreateDirectories()) { + this->SettingsFileRead(); + this->ParseCacheRead(); + if (!this->CreateDirectories()) { return false; } - InitJobs(); - if (!WorkerPool_.Process(this)) { + this->InitJobs(); + if (!this->WorkerPool_.Process(this)) { return false; } - if (JobError_) { + if (this->JobError_) { return false; } - if (!ParseCacheWrite()) { + if (!this->ParseCacheWrite()) { return false; } - if (!SettingsFileWrite()) { + if (!this->SettingsFileWrite()) { return false; } return true; @@ -2714,70 +2788,72 @@ void cmQtAutoMocUicT::SettingsFileRead() cryptoHash.Append(";"); }; - if (MocConst_.Enabled) { + if (this->MocConst_.Enabled) { cryptoHash.Initialize(); - cha(MocConst().Executable); - for (auto const& item : MocConst().OptionsDefinitions) { + cha(this->MocConst().Executable); + for (auto const& item : this->MocConst().OptionsDefinitions) { cha(item); } - for (auto const& item : MocConst().OptionsIncludes) { + for (auto const& item : this->MocConst().OptionsIncludes) { cha(item); } - for (auto const& item : MocConst().OptionsExtra) { + for (auto const& item : this->MocConst().OptionsExtra) { cha(item); } - for (auto const& item : MocConst().PredefsCmd) { + for (auto const& item : this->MocConst().PredefsCmd) { cha(item); } - for (auto const& filter : MocConst().DependFilters) { + for (auto const& filter : this->MocConst().DependFilters) { cha(filter.Key); } - for (auto const& filter : MocConst().MacroFilters) { + for (auto const& filter : this->MocConst().MacroFilters) { cha(filter.Key); } - SettingsStringMoc_ = cryptoHash.FinalizeHex(); + this->SettingsStringMoc_ = cryptoHash.FinalizeHex(); } - if (UicConst().Enabled) { + if (this->UicConst().Enabled) { cryptoHash.Initialize(); - cha(UicConst().Executable); - std::for_each(UicConst().Options.begin(), UicConst().Options.end(), cha); - for (const auto& item : UicConst().UiFiles) { + cha(this->UicConst().Executable); + std::for_each(this->UicConst().Options.begin(), + this->UicConst().Options.end(), cha); + for (const auto& item : this->UicConst().UiFiles) { cha(item.first); auto const& opts = item.second.Options; std::for_each(opts.begin(), opts.end(), cha); } - SettingsStringUic_ = cryptoHash.FinalizeHex(); + this->SettingsStringUic_ = cryptoHash.FinalizeHex(); } } // Read old settings and compare { std::string content; - if (cmQtAutoGenerator::FileRead(content, SettingsFile_)) { - if (MocConst().Enabled) { - if (SettingsStringMoc_ != SettingsFind(content, "moc")) { - MocConst_.SettingsChanged = true; + if (cmQtAutoGenerator::FileRead(content, this->SettingsFile_)) { + if (this->MocConst().Enabled) { + if (this->SettingsStringMoc_ != SettingsFind(content, "moc")) { + this->MocConst_.SettingsChanged = true; } } - if (UicConst().Enabled) { - if (SettingsStringUic_ != SettingsFind(content, "uic")) { - UicConst_.SettingsChanged = true; + if (this->UicConst().Enabled) { + if (this->SettingsStringUic_ != SettingsFind(content, "uic")) { + this->UicConst_.SettingsChanged = true; } } // In case any setting changed remove the old settings file. // This triggers a full rebuild on the next run if the current // build is aborted before writing the current settings in the end. - if (MocConst().SettingsChanged || UicConst().SettingsChanged) { - cmSystemTools::RemoveFile(SettingsFile_); + if (this->MocConst().SettingsChanged || + this->UicConst().SettingsChanged) { + cmSystemTools::RemoveFile(this->SettingsFile_); } } else { // Settings file read failed - if (MocConst().Enabled) { - MocConst_.SettingsChanged = true; + if (this->MocConst().Enabled) { + this->MocConst_.SettingsChanged = true; } - if (UicConst().Enabled) { - UicConst_.SettingsChanged = true; + if (this->UicConst().Enabled) { + this->UicConst_.SettingsChanged = true; } } } @@ -2786,11 +2862,11 @@ void cmQtAutoMocUicT::SettingsFileRead() bool cmQtAutoMocUicT::SettingsFileWrite() { // Only write if any setting changed - if (MocConst().SettingsChanged || UicConst().SettingsChanged) { - if (Log().Verbose()) { - Log().Info( - GenT::GEN, - cmStrCat("Writing the settings file ", MessagePath(SettingsFile_))); + if (this->MocConst().SettingsChanged || this->UicConst().SettingsChanged) { + if (this->Log().Verbose()) { + this->Log().Info(GenT::GEN, + cmStrCat("Writing the settings file ", + this->MessagePath(this->SettingsFile_))); } // Compose settings file content std::string content; @@ -2801,17 +2877,18 @@ bool cmQtAutoMocUicT::SettingsFileWrite() content += cmStrCat(key, ':', value, '\n'); } }; - SettingAppend("moc", SettingsStringMoc_); - SettingAppend("uic", SettingsStringUic_); + SettingAppend("moc", this->SettingsStringMoc_); + SettingAppend("uic", this->SettingsStringUic_); } // Write settings file std::string error; - if (!cmQtAutoGenerator::FileWrite(SettingsFile_, content, &error)) { - Log().Error(GenT::GEN, - cmStrCat("Writing the settings file ", - MessagePath(SettingsFile_), " failed.\n", error)); + if (!cmQtAutoGenerator::FileWrite(this->SettingsFile_, content, &error)) { + this->Log().Error(GenT::GEN, + cmStrCat("Writing the settings file ", + this->MessagePath(this->SettingsFile_), + " failed.\n", error)); // Remove old settings file to trigger a full rebuild on the next run - cmSystemTools::RemoveFile(SettingsFile_); + cmSystemTools::RemoveFile(this->SettingsFile_); return false; } } @@ -2822,41 +2899,46 @@ void cmQtAutoMocUicT::ParseCacheRead() { cm::string_view reason; // Don't read the cache if it is invalid - if (!BaseEval().ParseCacheTime.Load(BaseConst().ParseCacheFile)) { + if (!this->BaseEval().ParseCacheTime.Load( + this->BaseConst().ParseCacheFile)) { reason = "Refreshing parse cache because it doesn't exist."; - } else if (MocConst().SettingsChanged || UicConst().SettingsChanged) { + } else if (this->MocConst().SettingsChanged || + this->UicConst().SettingsChanged) { reason = "Refreshing parse cache because the settings changed."; - } else if (BaseEval().ParseCacheTime.Older( - BaseConst().CMakeExecutableTime)) { + } else if (this->BaseEval().ParseCacheTime.Older( + this->BaseConst().CMakeExecutableTime)) { reason = "Refreshing parse cache because it is older than the CMake executable."; } if (!reason.empty()) { // Don't read but refresh the complete parse cache - if (Log().Verbose()) { - Log().Info(GenT::GEN, reason); + if (this->Log().Verbose()) { + this->Log().Info(GenT::GEN, reason); } - BaseEval().ParseCacheChanged = true; + this->BaseEval().ParseCacheChanged = true; } else { // Read parse cache - BaseEval().ParseCache.ReadFromFile(BaseConst().ParseCacheFile); + this->BaseEval().ParseCache.ReadFromFile(this->BaseConst().ParseCacheFile); } } bool cmQtAutoMocUicT::ParseCacheWrite() { - if (BaseEval().ParseCacheChanged) { - if (Log().Verbose()) { - Log().Info(GenT::GEN, - cmStrCat("Writing the parse cache file ", - MessagePath(BaseConst().ParseCacheFile))); - } - if (!BaseEval().ParseCache.WriteToFile(BaseConst().ParseCacheFile)) { - Log().Error(GenT::GEN, - cmStrCat("Writing the parse cache file ", - MessagePath(BaseConst().ParseCacheFile), - " failed.")); + if (this->BaseEval().ParseCacheChanged) { + if (this->Log().Verbose()) { + this->Log().Info( + GenT::GEN, + cmStrCat("Writing the parse cache file ", + this->MessagePath(this->BaseConst().ParseCacheFile))); + } + if (!this->BaseEval().ParseCache.WriteToFile( + this->BaseConst().ParseCacheFile)) { + this->Log().Error( + GenT::GEN, + cmStrCat("Writing the parse cache file ", + this->MessagePath(this->BaseConst().ParseCacheFile), + " failed.")); return false; } } @@ -2866,11 +2948,12 @@ bool cmQtAutoMocUicT::ParseCacheWrite() bool cmQtAutoMocUicT::CreateDirectories() { // Create AUTOGEN include directory - if (!cmSystemTools::MakeDirectory(BaseConst().AutogenIncludeDir)) { - Log().Error(GenT::GEN, - cmStrCat("Creating the AUTOGEN include directory ", - MessagePath(BaseConst().AutogenIncludeDir), - " failed.")); + if (!cmSystemTools::MakeDirectory(this->BaseConst().AutogenIncludeDir)) { + this->Log().Error( + GenT::GEN, + cmStrCat("Creating the AUTOGEN include directory ", + this->MessagePath(this->BaseConst().AutogenIncludeDir), + " failed.")); return false; } return true; @@ -2892,21 +2975,21 @@ std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile( void cmQtAutoMocUicT::Abort(bool error) { if (error) { - JobError_.store(true); + this->JobError_.store(true); } - WorkerPool_.Abort(); + this->WorkerPool_.Abort(); } std::string cmQtAutoMocUicT::AbsoluteBuildPath( cm::string_view relativePath) const { - return cmStrCat(BaseConst().AutogenBuildDir, '/', relativePath); + return cmStrCat(this->BaseConst().AutogenBuildDir, '/', relativePath); } std::string cmQtAutoMocUicT::AbsoluteIncludePath( cm::string_view relativePath) const { - return cmStrCat(BaseConst().AutogenIncludeDir, '/', relativePath); + return cmStrCat(this->BaseConst().AutogenIncludeDir, '/', relativePath); } } // End of unnamed namespace diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx index 08eb4b5..943cc93 100644 --- a/Source/cmQtAutoRcc.cxx +++ b/Source/cmQtAutoRcc.cxx @@ -35,7 +35,7 @@ public: private: // -- Utility - bool IsMultiConfig() const { return MultiConfig_; } + bool IsMultiConfig() const { return this->MultiConfig_; } std::string MultiConfigOutput() const; // -- Abstract processing interface @@ -93,38 +93,41 @@ cmQtAutoRccT::~cmQtAutoRccT() = default; bool cmQtAutoRccT::InitFromInfo(InfoT const& info) { // -- Required settings - if (!info.GetBool("MULTI_CONFIG", MultiConfig_, true) || - !info.GetString("BUILD_DIR", AutogenBuildDir_, true) || - !info.GetStringConfig("INCLUDE_DIR", IncludeDir_, true) || - !info.GetString("RCC_EXECUTABLE", RccExecutable_, true) || - !info.GetArray("RCC_LIST_OPTIONS", RccListOptions_, false) || - !info.GetString("LOCK_FILE", LockFile_, true) || - !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) || - !info.GetString("SOURCE", QrcFile_, true) || - !info.GetString("OUTPUT_CHECKSUM", RccPathChecksum_, true) || - !info.GetString("OUTPUT_NAME", RccFileName_, true) || - !info.GetArray("OPTIONS", Options_, false) || - !info.GetArray("INPUTS", Inputs_, false)) { + if (!info.GetBool("MULTI_CONFIG", this->MultiConfig_, true) || + !info.GetString("BUILD_DIR", this->AutogenBuildDir_, true) || + !info.GetStringConfig("INCLUDE_DIR", this->IncludeDir_, true) || + !info.GetString("RCC_EXECUTABLE", this->RccExecutable_, true) || + !info.GetArray("RCC_LIST_OPTIONS", this->RccListOptions_, false) || + !info.GetString("LOCK_FILE", this->LockFile_, true) || + !info.GetStringConfig("SETTINGS_FILE", this->SettingsFile_, true) || + !info.GetString("SOURCE", this->QrcFile_, true) || + !info.GetString("OUTPUT_CHECKSUM", this->RccPathChecksum_, true) || + !info.GetString("OUTPUT_NAME", this->RccFileName_, true) || + !info.GetArray("OPTIONS", this->Options_, false) || + !info.GetArray("INPUTS", this->Inputs_, false)) { return false; } // -- Derive information - QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_); - QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_); - RccFilePublic_ = - cmStrCat(AutogenBuildDir_, '/', RccPathChecksum_, '/', RccFileName_); + this->QrcFileName_ = cmSystemTools::GetFilenameName(this->QrcFile_); + this->QrcFileDir_ = cmSystemTools::GetFilenamePath(this->QrcFile_); + this->RccFilePublic_ = + cmStrCat(this->AutogenBuildDir_, '/', this->RccPathChecksum_, '/', + this->RccFileName_); // rcc output file name - if (IsMultiConfig()) { - RccFileOutput_ = cmStrCat(IncludeDir_, '/', MultiConfigOutput()); + if (this->IsMultiConfig()) { + this->RccFileOutput_ = + cmStrCat(this->IncludeDir_, '/', this->MultiConfigOutput()); } else { - RccFileOutput_ = RccFilePublic_; + this->RccFileOutput_ = this->RccFilePublic_; } // -- Checks - if (!RccExecutableTime_.Load(RccExecutable_)) { - return info.LogError(cmStrCat( - "The rcc executable ", MessagePath(RccExecutable_), " does not exist.")); + if (!this->RccExecutableTime_.Load(this->RccExecutable_)) { + return info.LogError(cmStrCat("The rcc executable ", + this->MessagePath(this->RccExecutable_), + " does not exist.")); } return true; @@ -132,41 +135,41 @@ bool cmQtAutoRccT::InitFromInfo(InfoT const& info) bool cmQtAutoRccT::Process() { - if (!SettingsFileRead()) { + if (!this->SettingsFileRead()) { return false; } // Test if the rcc output needs to be regenerated bool generate = false; - if (!TestQrcRccFiles(generate)) { + if (!this->TestQrcRccFiles(generate)) { return false; } - if (!generate && !TestResources(generate)) { + if (!generate && !this->TestResources(generate)) { return false; } // Generate on demand if (generate) { - if (!GenerateRcc()) { + if (!this->GenerateRcc()) { return false; } } else { // Test if the info file is newer than the output file - if (!TestInfoFile()) { + if (!this->TestInfoFile()) { return false; } } - if (!GenerateWrapper()) { + if (!this->GenerateWrapper()) { return false; } - return SettingsFileWrite(); + return this->SettingsFileWrite(); } std::string cmQtAutoRccT::MultiConfigOutput() const { - return cmStrCat(RccPathChecksum_, '/', - AppendFilenameSuffix(RccFileName_, "_CMAKE_")); + return cmStrCat(this->RccPathChecksum_, '/', + AppendFilenameSuffix(this->RccFileName_, "_CMAKE_")); } bool cmQtAutoRccT::SettingsFileRead() @@ -178,23 +181,25 @@ bool cmQtAutoRccT::SettingsFileRead() cryptoHash.Append(value); cryptoHash.Append(";"); }; - cha(RccExecutable_); - std::for_each(RccListOptions_.begin(), RccListOptions_.end(), cha); - cha(QrcFile_); - cha(RccPathChecksum_); - cha(RccFileName_); - std::for_each(Options_.begin(), Options_.end(), cha); - std::for_each(Inputs_.begin(), Inputs_.end(), cha); - SettingsString_ = cryptoHash.FinalizeHex(); + cha(this->RccExecutable_); + std::for_each(this->RccListOptions_.begin(), this->RccListOptions_.end(), + cha); + cha(this->QrcFile_); + cha(this->RccPathChecksum_); + cha(this->RccFileName_); + std::for_each(this->Options_.begin(), this->Options_.end(), cha); + std::for_each(this->Inputs_.begin(), this->Inputs_.end(), cha); + this->SettingsString_ = cryptoHash.FinalizeHex(); } // Make sure the settings file exists - if (!cmSystemTools::FileExists(SettingsFile_, true)) { + if (!cmSystemTools::FileExists(this->SettingsFile_, true)) { // Touch the settings file to make sure it exists - if (!cmSystemTools::Touch(SettingsFile_, true)) { - Log().Error(GenT::RCC, - cmStrCat("Touching the settings file ", - MessagePath(SettingsFile_), " failed.")); + if (!cmSystemTools::Touch(this->SettingsFile_, true)) { + this->Log().Error(GenT::RCC, + cmStrCat("Touching the settings file ", + this->MessagePath(this->SettingsFile_), + " failed.")); return false; } } @@ -202,21 +207,23 @@ bool cmQtAutoRccT::SettingsFileRead() // Lock the lock file { // Make sure the lock file exists - if (!cmSystemTools::FileExists(LockFile_, true)) { - if (!cmSystemTools::Touch(LockFile_, true)) { - Log().Error(GenT::RCC, - cmStrCat("Touching the lock file ", MessagePath(LockFile_), - " failed.")); + if (!cmSystemTools::FileExists(this->LockFile_, true)) { + if (!cmSystemTools::Touch(this->LockFile_, true)) { + this->Log().Error(GenT::RCC, + cmStrCat("Touching the lock file ", + this->MessagePath(this->LockFile_), + " failed.")); return false; } } // Lock the lock file - cmFileLockResult lockResult = - LockFileLock_.Lock(LockFile_, static_cast<unsigned long>(-1)); + cmFileLockResult lockResult = this->LockFileLock_.Lock( + this->LockFile_, static_cast<unsigned long>(-1)); if (!lockResult.IsOk()) { - Log().Error(GenT::RCC, - cmStrCat("Locking of the lock file ", MessagePath(LockFile_), - " failed.\n", lockResult.GetOutputMessage())); + this->Log().Error(GenT::RCC, + cmStrCat("Locking of the lock file ", + this->MessagePath(this->LockFile_), + " failed.\n", lockResult.GetOutputMessage())); return false; } } @@ -224,23 +231,24 @@ bool cmQtAutoRccT::SettingsFileRead() // Read old settings { std::string content; - if (FileRead(content, SettingsFile_)) { - SettingsChanged_ = (SettingsString_ != SettingsFind(content, "rcc")); + if (FileRead(content, this->SettingsFile_)) { + this->SettingsChanged_ = + (this->SettingsString_ != SettingsFind(content, "rcc")); // In case any setting changed clear the old settings file. // This triggers a full rebuild on the next run if the current // build is aborted before writing the current settings in the end. - if (SettingsChanged_) { + if (this->SettingsChanged_) { std::string error; - if (!FileWrite(SettingsFile_, "", &error)) { - Log().Error(GenT::RCC, - cmStrCat("Clearing of the settings file ", - MessagePath(SettingsFile_), " failed.\n", - error)); + if (!FileWrite(this->SettingsFile_, "", &error)) { + this->Log().Error(GenT::RCC, + cmStrCat("Clearing of the settings file ", + this->MessagePath(this->SettingsFile_), + " failed.\n", error)); return false; } } } else { - SettingsChanged_ = true; + this->SettingsChanged_ = true; } } @@ -250,26 +258,28 @@ bool cmQtAutoRccT::SettingsFileRead() bool cmQtAutoRccT::SettingsFileWrite() { // Only write if any setting changed - if (SettingsChanged_) { - if (Log().Verbose()) { - Log().Info(GenT::RCC, - "Writing settings file " + MessagePath(SettingsFile_)); + if (this->SettingsChanged_) { + if (this->Log().Verbose()) { + this->Log().Info(GenT::RCC, + "Writing settings file " + + this->MessagePath(this->SettingsFile_)); } // Write settings file - std::string content = cmStrCat("rcc:", SettingsString_, '\n'); + std::string content = cmStrCat("rcc:", this->SettingsString_, '\n'); std::string error; - if (!FileWrite(SettingsFile_, content, &error)) { - Log().Error(GenT::RCC, - cmStrCat("Writing of the settings file ", - MessagePath(SettingsFile_), " failed.\n", error)); + if (!FileWrite(this->SettingsFile_, content, &error)) { + this->Log().Error(GenT::RCC, + cmStrCat("Writing of the settings file ", + this->MessagePath(this->SettingsFile_), + " failed.\n", error)); // Remove old settings file to trigger a full rebuild on the next run - cmSystemTools::RemoveFile(SettingsFile_); + cmSystemTools::RemoveFile(this->SettingsFile_); return false; } } // Unlock the lock file - LockFileLock_.Release(); + this->LockFileLock_.Release(); return true; } @@ -277,52 +287,57 @@ bool cmQtAutoRccT::SettingsFileWrite() bool cmQtAutoRccT::TestQrcRccFiles(bool& generate) { // Test if the rcc input file exists - if (!QrcFileTime_.Load(QrcFile_)) { - Log().Error(GenT::RCC, - cmStrCat("The resources file ", MessagePath(QrcFile_), - " does not exist")); + if (!this->QrcFileTime_.Load(this->QrcFile_)) { + this->Log().Error(GenT::RCC, + cmStrCat("The resources file ", + this->MessagePath(this->QrcFile_), + " does not exist")); return false; } // Test if the rcc output file exists - if (!RccFileTime_.Load(RccFileOutput_)) { - if (Log().Verbose()) { - Reason = - cmStrCat("Generating ", MessagePath(RccFileOutput_), - ", because it doesn't exist, from ", MessagePath(QrcFile_)); + if (!this->RccFileTime_.Load(this->RccFileOutput_)) { + if (this->Log().Verbose()) { + this->Reason = + cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_), + ", because it doesn't exist, from ", + this->MessagePath(this->QrcFile_)); } generate = true; return true; } // Test if the settings changed - if (SettingsChanged_) { - if (Log().Verbose()) { - Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), - ", because the rcc settings changed, from ", - MessagePath(QrcFile_)); + if (this->SettingsChanged_) { + if (this->Log().Verbose()) { + this->Reason = + cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_), + ", because the rcc settings changed, from ", + this->MessagePath(this->QrcFile_)); } generate = true; return true; } // Test if the rcc output file is older than the .qrc file - if (RccFileTime_.Older(QrcFileTime_)) { - if (Log().Verbose()) { - Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), - ", because it is older than ", MessagePath(QrcFile_), - ", from ", MessagePath(QrcFile_)); + if (this->RccFileTime_.Older(this->QrcFileTime_)) { + if (this->Log().Verbose()) { + this->Reason = cmStrCat( + "Generating ", this->MessagePath(this->RccFileOutput_), + ", because it is older than ", this->MessagePath(this->QrcFile_), + ", from ", this->MessagePath(this->QrcFile_)); } generate = true; return true; } // Test if the rcc output file is older than the rcc executable - if (RccFileTime_.Older(RccExecutableTime_)) { - if (Log().Verbose()) { - Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), - ", because it is older than the rcc executable, from ", - MessagePath(QrcFile_)); + if (this->RccFileTime_.Older(this->RccExecutableTime_)) { + if (this->Log().Verbose()) { + this->Reason = + cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_), + ", because it is older than the rcc executable, from ", + this->MessagePath(this->QrcFile_)); } generate = true; return true; @@ -334,34 +349,38 @@ bool cmQtAutoRccT::TestQrcRccFiles(bool& generate) bool cmQtAutoRccT::TestResources(bool& generate) { // Read resource files list - if (Inputs_.empty()) { + if (this->Inputs_.empty()) { std::string error; - RccLister const lister(RccExecutable_, RccListOptions_); - if (!lister.list(QrcFile_, Inputs_, error, Log().Verbose())) { - Log().Error( - GenT::RCC, - cmStrCat("Listing of ", MessagePath(QrcFile_), " failed.\n", error)); + RccLister const lister(this->RccExecutable_, this->RccListOptions_); + if (!lister.list(this->QrcFile_, this->Inputs_, error, + this->Log().Verbose())) { + this->Log().Error(GenT::RCC, + cmStrCat("Listing of ", + this->MessagePath(this->QrcFile_), + " failed.\n", error)); return false; } } // Check if any resource file is newer than the rcc output file - for (std::string const& resFile : Inputs_) { + for (std::string const& resFile : this->Inputs_) { // Check if the resource file exists cmFileTime fileTime; if (!fileTime.Load(resFile)) { - Log().Error(GenT::RCC, - cmStrCat("The resource file ", MessagePath(resFile), - " listed in ", MessagePath(QrcFile_), - " does not exist.")); + this->Log().Error(GenT::RCC, + cmStrCat("The resource file ", + this->MessagePath(resFile), " listed in ", + this->MessagePath(this->QrcFile_), + " does not exist.")); return false; } // Check if the resource file is newer than the rcc output file - if (RccFileTime_.Older(fileTime)) { - if (Log().Verbose()) { - Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), - ", because it is older than ", MessagePath(resFile), - ", from ", MessagePath(QrcFile_)); + if (this->RccFileTime_.Older(fileTime)) { + if (this->Log().Verbose()) { + this->Reason = + cmStrCat("Generating ", this->MessagePath(this->RccFileOutput_), + ", because it is older than ", this->MessagePath(resFile), + ", from ", this->MessagePath(this->QrcFile_)); } generate = true; break; @@ -373,21 +392,23 @@ bool cmQtAutoRccT::TestResources(bool& generate) bool cmQtAutoRccT::TestInfoFile() { // Test if the rcc output file is older than the info file - if (RccFileTime_.Older(InfoFileTime())) { - if (Log().Verbose()) { - Log().Info(GenT::RCC, - cmStrCat("Touching ", MessagePath(RccFileOutput_), - " because it is older than ", - MessagePath(InfoFile()))); + if (this->RccFileTime_.Older(this->InfoFileTime())) { + if (this->Log().Verbose()) { + this->Log().Info(GenT::RCC, + cmStrCat("Touching ", + this->MessagePath(this->RccFileOutput_), + " because it is older than ", + this->MessagePath(this->InfoFile()))); } // Touch build file - if (!cmSystemTools::Touch(RccFileOutput_, false)) { - Log().Error( - GenT::RCC, - cmStrCat("Touching ", MessagePath(RccFileOutput_), " failed.")); + if (!cmSystemTools::Touch(this->RccFileOutput_, false)) { + this->Log().Error(GenT::RCC, + cmStrCat("Touching ", + this->MessagePath(this->RccFileOutput_), + " failed.")); return false; } - BuildFileChanged_ = true; + this->BuildFileChanged_ = true; } return true; @@ -396,51 +417,53 @@ bool cmQtAutoRccT::TestInfoFile() bool cmQtAutoRccT::GenerateRcc() { // Make parent directory - if (!MakeParentDirectory(RccFileOutput_)) { - Log().Error(GenT::RCC, - cmStrCat("Could not create parent directory of ", - MessagePath(RccFileOutput_))); + if (!MakeParentDirectory(this->RccFileOutput_)) { + this->Log().Error(GenT::RCC, + cmStrCat("Could not create parent directory of ", + this->MessagePath(this->RccFileOutput_))); return false; } // Compose rcc command std::vector<std::string> cmd; - cmd.push_back(RccExecutable_); - cm::append(cmd, Options_); + cmd.push_back(this->RccExecutable_); + cm::append(cmd, this->Options_); cmd.emplace_back("-o"); - cmd.push_back(RccFileOutput_); - cmd.push_back(QrcFile_); + cmd.push_back(this->RccFileOutput_); + cmd.push_back(this->QrcFile_); // Log reason and command - if (Log().Verbose()) { - Log().Info(GenT::RCC, - cmStrCat(Reason, cmHasSuffix(Reason, '\n') ? "" : "\n", - QuotedCommand(cmd), '\n')); + if (this->Log().Verbose()) { + this->Log().Info(GenT::RCC, + cmStrCat(this->Reason, + cmHasSuffix(this->Reason, '\n') ? "" : "\n", + QuotedCommand(cmd), '\n')); } std::string rccStdOut; std::string rccStdErr; int retVal = 0; bool result = cmSystemTools::RunSingleCommand( - cmd, &rccStdOut, &rccStdErr, &retVal, AutogenBuildDir_.c_str(), + cmd, &rccStdOut, &rccStdErr, &retVal, this->AutogenBuildDir_.c_str(), cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto); if (!result || (retVal != 0)) { // rcc process failed - Log().ErrorCommand(GenT::RCC, - cmStrCat("The rcc process failed to compile\n ", - MessagePath(QrcFile_), "\ninto\n ", - MessagePath(RccFileOutput_)), - cmd, rccStdOut + rccStdErr); - cmSystemTools::RemoveFile(RccFileOutput_); + this->Log().ErrorCommand(GenT::RCC, + cmStrCat("The rcc process failed to compile\n ", + this->MessagePath(this->QrcFile_), + "\ninto\n ", + this->MessagePath(this->RccFileOutput_)), + cmd, rccStdOut + rccStdErr); + cmSystemTools::RemoveFile(this->RccFileOutput_); return false; } // rcc process success // Print rcc output if (!rccStdOut.empty()) { - Log().Info(GenT::RCC, rccStdOut); + this->Log().Info(GenT::RCC, rccStdOut); } - BuildFileChanged_ = true; + this->BuildFileChanged_ = true; return true; } @@ -448,47 +471,48 @@ bool cmQtAutoRccT::GenerateRcc() bool cmQtAutoRccT::GenerateWrapper() { // Generate a wrapper source file on demand - if (IsMultiConfig()) { + if (this->IsMultiConfig()) { // Wrapper file content std::string content = cmStrCat("// This is an autogenerated configuration wrapper file.\n", "// Changes will be overwritten.\n", "#include <", - MultiConfigOutput(), ">\n"); + this->MultiConfigOutput(), ">\n"); // Compare with existing file content bool fileDiffers = true; { std::string oldContents; - if (FileRead(oldContents, RccFilePublic_)) { + if (FileRead(oldContents, this->RccFilePublic_)) { fileDiffers = (oldContents != content); } } if (fileDiffers) { // Write new wrapper file - if (Log().Verbose()) { - Log().Info(GenT::RCC, - cmStrCat("Generating RCC wrapper file ", - MessagePath(RccFilePublic_))); + if (this->Log().Verbose()) { + this->Log().Info(GenT::RCC, + cmStrCat("Generating RCC wrapper file ", + this->MessagePath(this->RccFilePublic_))); } std::string error; - if (!FileWrite(RccFilePublic_, content, &error)) { - Log().Error(GenT::RCC, - cmStrCat("Generating RCC wrapper file ", - MessagePath(RccFilePublic_), " failed.\n", - error)); + if (!FileWrite(this->RccFilePublic_, content, &error)) { + this->Log().Error(GenT::RCC, + cmStrCat("Generating RCC wrapper file ", + this->MessagePath(this->RccFilePublic_), + " failed.\n", error)); return false; } - } else if (BuildFileChanged_) { + } else if (this->BuildFileChanged_) { // Just touch the wrapper file - if (Log().Verbose()) { - Log().Info( - GenT::RCC, - cmStrCat("Touching RCC wrapper file ", MessagePath(RccFilePublic_))); + if (this->Log().Verbose()) { + this->Log().Info(GenT::RCC, + cmStrCat("Touching RCC wrapper file ", + this->MessagePath(this->RccFilePublic_))); } - if (!cmSystemTools::Touch(RccFilePublic_, false)) { - Log().Error(GenT::RCC, - cmStrCat("Touching RCC wrapper file ", - MessagePath(RccFilePublic_), " failed.")); + if (!cmSystemTools::Touch(this->RccFilePublic_, false)) { + this->Log().Error(GenT::RCC, + cmStrCat("Touching RCC wrapper file ", + this->MessagePath(this->RccFilePublic_), + " failed.")); return false; } } diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index 26e93bb..fce6e80 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -25,7 +25,7 @@ cmRST::cmRST(std::ostream& os, std::string docroot) , Markup(MarkupNone) , Directive(DirectiveNone) , CMakeDirective("^.. (cmake:)?(" - "command|variable" + "command|envvar|genex|variable" ")::[ \t]+([^ \t\n]+)$") , CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$") , ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$") @@ -37,7 +37,8 @@ cmRST::cmRST(std::ostream& os, std::string docroot) , NoteDirective("^.. note::[ \t]*(.*)$") , ModuleRST(R"(^#\[(=*)\[\.rst:$)") , CMakeRole("(:cmake)?:(" - "command|cpack_gen|generator|variable|envvar|module|policy|" + "command|cpack_gen|generator|genex|" + "variable|envvar|module|policy|" "prop_cache|prop_dir|prop_gbl|prop_inst|prop_sf|" "prop_test|prop_tgt|" "manual" diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx index 5363fef..d00bbdf 100644 --- a/Source/cmRulePlaceholderExpander.cxx +++ b/Source/cmRulePlaceholderExpander.cxx @@ -44,6 +44,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable( return replaceValues.Source; } } + if (replaceValues.DynDepFile) { + if (variable == "DYNDEP_FILE") { + return replaceValues.DynDepFile; + } + } if (replaceValues.PreprocessedSource) { if (variable == "PREPROCESSED_SOURCE") { return replaceValues.PreprocessedSource; diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h index 710f8a6..f8dc368 100644 --- a/Source/cmRulePlaceholderExpander.h +++ b/Source/cmRulePlaceholderExpander.h @@ -41,6 +41,7 @@ public: const char* Source = nullptr; const char* AssemblySource = nullptr; const char* PreprocessedSource = nullptr; + const char* DynDepFile = nullptr; const char* Output = nullptr; const char* Object = nullptr; const char* ObjectDir = nullptr; diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx index 40bf4c9..e046069 100644 --- a/Source/cmScanDepFormat.cxx +++ b/Source/cmScanDepFormat.cxx @@ -55,9 +55,8 @@ static Json::Value EncodeFilename(std::string const& path) #define PARSE_BLOB(val, res) \ do { \ if (!ParseFilename(val, res)) { \ - cmSystemTools::Error( \ - cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp, \ - ": invalid blob")); \ + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", \ + arg_pp, ": invalid blob")); \ return false; \ } \ } while (0) @@ -65,9 +64,8 @@ static Json::Value EncodeFilename(std::string const& path) #define PARSE_FILENAME(val, res) \ do { \ if (!ParseFilename(val, res)) { \ - cmSystemTools::Error( \ - cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp, \ - ": invalid filename")); \ + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", \ + arg_pp, ": invalid filename")); \ return false; \ } \ \ @@ -84,7 +82,7 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) { Json::Reader reader; if (!reader.parse(ppf, ppio, false)) { - cmSystemTools::Error(cmStrCat("-E cmake_ninja_depends failed to parse ", + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp, reader.getFormattedErrorMessages())); return false; @@ -93,7 +91,7 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) Json::Value const& version = ppi["version"]; if (version.asUInt() != 0) { - cmSystemTools::Error(cmStrCat("-E cmake_ninja_depends failed to parse ", + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp, ": version ", version.asString())); return false; } @@ -101,7 +99,7 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) Json::Value const& rules = ppi["rules"]; if (rules.isArray()) { if (rules.size() != 1) { - cmSystemTools::Error(cmStrCat("-E cmake_ninja_depends failed to parse ", + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp, ": expected 1 source entry")); return false; } @@ -109,9 +107,9 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) for (auto const& rule : rules) { Json::Value const& workdir = rule["work-directory"]; if (!workdir.isString()) { - cmSystemTools::Error( - cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp, - ": work-directory is not a string")); + cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ", + arg_pp, + ": work-directory is not a string")); return false; } std::string work_directory; @@ -134,7 +132,7 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp, cmSourceInfo* info) if (outputs.isArray()) { if (outputs.empty()) { cmSystemTools::Error( - cmStrCat("-E cmake_ninja_depends failed to parse ", arg_pp, + cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp, ": expected at least one 1 output")); return false; } diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h index 94b5cc8..76a5ded 100644 --- a/Source/cmSourceFile.h +++ b/Source/cmSourceFile.h @@ -175,7 +175,7 @@ private: #define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$" #define CM_SOURCE_REGEX \ - "\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \ + "\\.(C|F|M|c|c\\+\\+|cc|cpp|mpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \ "rc|def|r|odl|idl|hpj|bat)$" #define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$" diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx index 5d8ccf1..bf6925e 100644 --- a/Source/cmStandardLevelResolver.cxx +++ b/Source/cmStandardLevelResolver.cxx @@ -44,6 +44,16 @@ struct StandardNeeded int value; }; +int ParseStd(std::string const& level) +{ + try { + return std::stoi(level); + } catch (std::invalid_argument&) { + // Fall through to use an invalid value. + } + return -1; +} + struct StanardLevelComputer { explicit StanardLevelComputer(std::string lang, std::vector<int> levels, @@ -113,17 +123,8 @@ struct StanardLevelComputer standardStr = "03"; } - int standardValue = -1; - int defaultValue = -1; - try { - standardValue = std::stoi(standardStr); - defaultValue = std::stoi(*defaultStd); - } catch (std::invalid_argument&) { - // fall through as we want an error - // when we can't find the bad value in the `stds` vector - } - - auto stdIt = std::find(cm::cbegin(stds), cm::cend(stds), standardValue); + auto stdIt = + std::find(cm::cbegin(stds), cm::cend(stds), ParseStd(standardStr)); if (stdIt == cm::cend(stds)) { std::string e = cmStrCat(this->Language, "_STANDARD is set to invalid value '", @@ -134,7 +135,7 @@ struct StanardLevelComputer } auto defaultStdIt = - std::find(cm::cbegin(stds), cm::cend(stds), defaultValue); + std::find(cm::cbegin(stds), cm::cend(stds), ParseStd(*defaultStd)); if (defaultStdIt == cm::cend(stds)) { std::string e = cmStrCat("CMAKE_", this->Language, "_STANDARD_DEFAULT is set to invalid value '", @@ -195,7 +196,7 @@ struct StanardLevelComputer if (existingStandard) { existingLevelIter = std::find(cm::cbegin(this->Levels), cm::cend(this->Levels), - std::stoi(*existingStandard)); + ParseStd(*existingStandard)); if (existingLevelIter == cm::cend(this->Levels)) { const std::string e = cmStrCat("The ", this->Language, "_STANDARD property on target \"", @@ -240,7 +241,7 @@ struct StanardLevelComputer } // convert defaultStandard to an integer if (std::find(cm::cbegin(this->Levels), cm::cend(this->Levels), - std::stoi(*defaultStandard)) == cm::cend(this->Levels)) { + ParseStd(*defaultStandard)) == cm::cend(this->Levels)) { const std::string e = cmStrCat("The CMAKE_", this->Language, "_STANDARD_DEFAULT variable contains an " "invalid value: \"", @@ -257,7 +258,7 @@ struct StanardLevelComputer auto existingLevelIter = std::find(cm::cbegin(this->Levels), cm::cend(this->Levels), - std::stoi(*existingStandard)); + ParseStd(*existingStandard)); if (existingLevelIter == cm::cend(this->Levels)) { const std::string e = cmStrCat("The ", this->Language, "_STANDARD property on target \"", diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 3692a01..0fd7901 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -524,7 +524,7 @@ bool cmState::AddScriptedCommand(std::string const& name, BT<Command> command, cmState::Command cmState::GetCommand(std::string const& name) const { - return GetCommandByExactName(cmSystemTools::LowerCase(name)); + return this->GetCommandByExactName(cmSystemTools::LowerCase(name)); } cmState::Command cmState::GetCommandByExactName(std::string const& name) const diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx index 796bb1f..7ce362a 100644 --- a/Source/cmStateDirectory.cxx +++ b/Source/cmStateDirectory.cxx @@ -148,11 +148,13 @@ bool cmStateDirectory::ContainsBoth(std::string const& local_path, cmSystemTools::IsSubDirectory(a, b)); }; - bool bothInBinary = PathEqOrSubDir(local_path, GetRelativePathTopBinary()) && - PathEqOrSubDir(remote_path, GetRelativePathTopBinary()); + bool bothInBinary = + PathEqOrSubDir(local_path, this->GetRelativePathTopBinary()) && + PathEqOrSubDir(remote_path, this->GetRelativePathTopBinary()); - bool bothInSource = PathEqOrSubDir(local_path, GetRelativePathTopSource()) && - PathEqOrSubDir(remote_path, GetRelativePathTopSource()); + bool bothInSource = + PathEqOrSubDir(local_path, this->GetRelativePathTopSource()) && + PathEqOrSubDir(remote_path, this->GetRelativePathTopSource()); return bothInBinary || bothInSource; } diff --git a/Source/cmString.cxx b/Source/cmString.cxx index 898b828..8721242 100644 --- a/Source/cmString.cxx +++ b/Source/cmString.cxx @@ -19,17 +19,17 @@ void String::internally_mutate_to_stable_string() // We assume that only one thread mutates this instance at // a time even if we point to a shared string buffer referenced // by other threads. - *this = String(data(), size()); + *this = String(this->data(), this->size()); } bool String::is_stable() const { - return str_if_stable() != nullptr; + return this->str_if_stable() != nullptr; } void String::stabilize() { - if (is_stable()) { + if (this->is_stable()) { return; } this->internally_mutate_to_stable_string(); @@ -37,16 +37,17 @@ void String::stabilize() std::string const* String::str_if_stable() const { - if (!data()) { + if (!this->data()) { // We view no string. // This is stable for the lifetime of our current value. return &empty_string_; } - if (string_ && data() == string_->data() && size() == string_->size()) { + if (this->string_ && this->data() == this->string_->data() && + this->size() == this->string_->size()) { // We view an entire string. // This is stable for the lifetime of our current value. - return string_.get(); + return this->string_.get(); } return nullptr; @@ -54,18 +55,18 @@ std::string const* String::str_if_stable() const std::string const& String::str() { - if (std::string const* s = str_if_stable()) { + if (std::string const* s = this->str_if_stable()) { return *s; } // Mutate to hold a std::string that is stable for the lifetime // of our current value. this->internally_mutate_to_stable_string(); - return *string_; + return *this->string_; } const char* String::c_str() { - const char* c = data(); + const char* c = this->data(); if (c == nullptr) { return c; } @@ -73,42 +74,42 @@ const char* String::c_str() // We always point into a null-terminated string so it is safe to // access one past the end. If it is a null byte then we can use // the pointer directly. - if (c[size()] == '\0') { + if (c[this->size()] == '\0') { return c; } // Mutate to hold a std::string so we can get a null terminator. this->internally_mutate_to_stable_string(); - c = string_->c_str(); + c = this->string_->c_str(); return c; } String& String::insert(size_type index, size_type count, char ch) { std::string s; - s.reserve(size() + count); - s.assign(data(), size()); + s.reserve(this->size() + count); + s.assign(this->data(), this->size()); s.insert(index, count, ch); return *this = std::move(s); } String& String::erase(size_type index, size_type count) { - if (index > size()) { + if (index > this->size()) { throw std::out_of_range("Index out of range in String::erase"); } - size_type const rcount = std::min(count, size() - index); + size_type const rcount = std::min(count, this->size() - index); size_type const rindex = index + rcount; std::string s; - s.reserve(size() - rcount); - s.assign(data(), index); - s.append(data() + rindex, size() - rindex); + s.reserve(this->size() - rcount); + s.assign(this->data(), index); + s.append(this->data() + rindex, this->size() - rindex); return *this = std::move(s); } String String::substr(size_type pos, size_type count) const { - if (pos > size()) { + if (pos > this->size()) { throw std::out_of_range("Index out of range in String::substr"); } return String(*this, pos, count); @@ -116,14 +117,14 @@ String String::substr(size_type pos, size_type count) const String::String(std::string&& s, Private) : string_(std::make_shared<std::string>(std::move(s))) - , view_(string_->data(), string_->size()) + , view_(this->string_->data(), this->string_->size()) { } String::size_type String::copy(char* dest, size_type count, size_type pos) const { - return view_.copy(dest, count, pos); + return this->view_.copy(dest, count, pos); } std::ostream& operator<<(std::ostream& os, String const& s) diff --git a/Source/cmString.hxx b/Source/cmString.hxx index b41b960..f1e462b 100644 --- a/Source/cmString.hxx +++ b/Source/cmString.hxx @@ -301,8 +301,8 @@ public: The other instance is left as a null string. */ String& operator=(String&& s) noexcept { - string_ = std::move(s.string_); - view_ = s.view_; + this->string_ = std::move(s.string_); + this->view_ = s.view_; s.view_ = string_view(); return *this; } @@ -340,33 +340,33 @@ public: } /** Return true if the instance is not a null string. */ - explicit operator bool() const noexcept { return data() != nullptr; } + explicit operator bool() const noexcept { return this->data() != nullptr; } /** Return a view of the string. */ - string_view view() const noexcept { return view_; } + string_view view() const noexcept { return this->view_; } operator string_view() const noexcept { return this->view(); } /** Return true if the instance is an empty stringn or null string. */ - bool empty() const noexcept { return view_.empty(); } + bool empty() const noexcept { return this->view_.empty(); } /** Return a pointer to the start of the string. */ - const char* data() const noexcept { return view_.data(); } + const char* data() const noexcept { return this->view_.data(); } /** Return the length of the string in bytes. */ - size_type size() const noexcept { return view_.size(); } - size_type length() const noexcept { return view_.length(); } + size_type size() const noexcept { return this->view_.size(); } + size_type length() const noexcept { return this->view_.length(); } /** Return the character at the given position. No bounds checking is performed. */ - char operator[](size_type pos) const noexcept { return view_[pos]; } + char operator[](size_type pos) const noexcept { return this->view_[pos]; } /** Return the character at the given position. If the position is out of bounds, throws std::out_of_range. */ - char at(size_type pos) const { return view_.at(pos); } + char at(size_type pos) const { return this->view_.at(pos); } - char front() const noexcept { return view_.front(); } + char front() const noexcept { return this->view_.front(); } - char back() const noexcept { return view_.back(); } + char back() const noexcept { return this->view_.back(); } /** Return true if this instance is stable and otherwise false. An instance is stable if it is in the 'null' state or if it is @@ -392,15 +392,18 @@ public: or str() is called. */ const char* c_str(); - const_iterator begin() const noexcept { return view_.begin(); } - const_iterator end() const noexcept { return view_.end(); } - const_iterator cbegin() const noexcept { return begin(); } - const_iterator cend() const noexcept { return end(); } + const_iterator begin() const noexcept { return this->view_.begin(); } + const_iterator end() const noexcept { return this->view_.end(); } + const_iterator cbegin() const noexcept { return this->begin(); } + const_iterator cend() const noexcept { return this->end(); } - const_reverse_iterator rbegin() const noexcept { return view_.rbegin(); } - const_reverse_iterator rend() const noexcept { return view_.rend(); } - const_reverse_iterator crbegin() const noexcept { return rbegin(); } - const_reverse_iterator crend() const noexcept { return rend(); } + const_reverse_iterator rbegin() const noexcept + { + return this->view_.rbegin(); + } + const_reverse_iterator rend() const noexcept { return this->view_.rend(); } + const_reverse_iterator crbegin() const noexcept { return this->rbegin(); } + const_reverse_iterator crend() const noexcept { return this->rend(); } /** Append to the string using any type that implements the AsStringView trait. */ @@ -410,8 +413,8 @@ public: { string_view v = AsStringView<T>::view(std::forward<T>(s)); std::string r; - r.reserve(size() + v.size()); - r.assign(data(), size()); + r.reserve(this->size() + v.size()); + r.assign(this->data(), this->size()); r.append(v.data(), v.size()); return *this = std::move(r); } @@ -428,21 +431,21 @@ public: void push_back(char ch) { std::string s; - s.reserve(size() + 1); - s.assign(data(), size()); + s.reserve(this->size() + 1); + s.assign(this->data(), this->size()); s.push_back(ch); *this = std::move(s); } - void pop_back() { *this = String(*this, 0, size() - 1); } + void pop_back() { *this = String(*this, 0, this->size() - 1); } template <typename T> typename std::enable_if<AsStringView<T>::value, String&>::type replace( size_type pos, size_type count, T&& s) { - const_iterator first = begin() + pos; + const_iterator first = this->begin() + pos; const_iterator last = first + count; - return replace(first, last, std::forward<T>(s)); + return this->replace(first, last, std::forward<T>(s)); } template <typename InputIterator> @@ -450,9 +453,9 @@ public: InputIterator first2, InputIterator last2) { std::string out; - out.append(view_.begin(), first); + out.append(this->view_.begin(), first); out.append(first2, last2); - out.append(last, view_.end()); + out.append(last, this->view_.end()); return *this = std::move(out); } @@ -462,10 +465,11 @@ public: { string_view v = AsStringView<T>::view(std::forward<T>(s)); std::string out; - out.reserve((first - view_.begin()) + v.size() + (view_.end() - last)); - out.append(view_.begin(), first); + out.reserve((first - this->view_.begin()) + v.size() + + (this->view_.end() - last)); + out.append(this->view_.begin(), first); out.append(v.data(), v.size()); - out.append(last, view_.end()); + out.append(last, this->view_.end()); return *this = std::move(out); } @@ -476,39 +480,40 @@ public: { string_view v = AsStringView<T>::view(std::forward<T>(s)); v = v.substr(pos2, count2); - return replace(pos, count, v); + return this->replace(pos, count, v); } String& replace(size_type pos, size_type count, size_type count2, char ch) { - const_iterator first = begin() + pos; + const_iterator first = this->begin() + pos; const_iterator last = first + count; - return replace(first, last, count2, ch); + return this->replace(first, last, count2, ch); } String& replace(const_iterator first, const_iterator last, size_type count2, char ch) { std::string out; - out.reserve((first - view_.begin()) + count2 + (view_.end() - last)); - out.append(view_.begin(), first); + out.reserve((first - this->view_.begin()) + count2 + + (this->view_.end() - last)); + out.append(this->view_.begin(), first); out.append(count2, ch); - out.append(last, view_.end()); + out.append(last, this->view_.end()); return *this = std::move(out); } size_type copy(char* dest, size_type count, size_type pos = 0) const; - void resize(size_type count) { resize(count, char()); } + void resize(size_type count) { this->resize(count, char()); } void resize(size_type count, char ch) { std::string s; s.reserve(count); - if (count <= size()) { - s.assign(data(), count); + if (count <= this->size()) { + s.assign(this->data(), count); } else { - s.assign(data(), size()); + s.assign(this->data(), this->size()); s.resize(count, ch); } *this = std::move(s); @@ -516,8 +521,8 @@ public: void swap(String& other) { - std::swap(string_, other.string_); - std::swap(view_, other.view_); + std::swap(this->string_, other.string_); + std::swap(this->view_, other.view_); } /** Return a substring starting at position 'pos' and @@ -528,29 +533,29 @@ public: typename std::enable_if<AsStringView<T>::value, int>::type compare( T&& s) const { - return view_.compare(AsStringView<T>::view(std::forward<T>(s))); + return this->view_.compare(AsStringView<T>::view(std::forward<T>(s))); } int compare(size_type pos1, size_type count1, string_view v) const { - return view_.compare(pos1, count1, v); + return this->view_.compare(pos1, count1, v); } int compare(size_type pos1, size_type count1, string_view v, size_type pos2, size_type count2) const { - return view_.compare(pos1, count1, v, pos2, count2); + return this->view_.compare(pos1, count1, v, pos2, count2); } int compare(size_type pos1, size_type count1, const char* s) const { - return view_.compare(pos1, count1, s); + return this->view_.compare(pos1, count1, s); } int compare(size_type pos1, size_type count1, const char* s, size_type count2) const { - return view_.compare(pos1, count1, s, count2); + return this->view_.compare(pos1, count1, s, count2); } template <typename T> @@ -558,12 +563,12 @@ public: T&& s, size_type pos = 0) const { string_view v = AsStringView<T>::view(std::forward<T>(s)); - return view_.find(v, pos); + return this->view_.find(v, pos); } size_type find(const char* s, size_type pos, size_type count) const { - return view_.find(s, pos, count); + return this->view_.find(s, pos, count); } template <typename T> @@ -571,12 +576,12 @@ public: T&& s, size_type pos = npos) const { string_view v = AsStringView<T>::view(std::forward<T>(s)); - return view_.rfind(v, pos); + return this->view_.rfind(v, pos); } size_type rfind(const char* s, size_type pos, size_type count) const { - return view_.rfind(s, pos, count); + return this->view_.rfind(s, pos, count); } template <typename T> @@ -584,12 +589,12 @@ public: find_first_of(T&& s, size_type pos = 0) const { string_view v = AsStringView<T>::view(std::forward<T>(s)); - return view_.find_first_of(v, pos); + return this->view_.find_first_of(v, pos); } size_type find_first_of(const char* s, size_type pos, size_type count) const { - return view_.find_first_of(s, pos, count); + return this->view_.find_first_of(s, pos, count); } template <typename T> @@ -597,13 +602,13 @@ public: find_first_not_of(T&& s, size_type pos = 0) const { string_view v = AsStringView<T>::view(std::forward<T>(s)); - return view_.find_first_not_of(v, pos); + return this->view_.find_first_not_of(v, pos); } size_type find_first_not_of(const char* s, size_type pos, size_type count) const { - return view_.find_first_not_of(s, pos, count); + return this->view_.find_first_not_of(s, pos, count); } template <typename T> @@ -611,12 +616,12 @@ public: find_last_of(T&& s, size_type pos = npos) const { string_view v = AsStringView<T>::view(std::forward<T>(s)); - return view_.find_last_of(v, pos); + return this->view_.find_last_of(v, pos); } size_type find_last_of(const char* s, size_type pos, size_type count) const { - return view_.find_last_of(s, pos, count); + return this->view_.find_last_of(s, pos, count); } template <typename T> @@ -624,13 +629,13 @@ public: find_last_not_of(T&& s, size_type pos = npos) const { string_view v = AsStringView<T>::view(std::forward<T>(s)); - return view_.find_last_not_of(v, pos); + return this->view_.find_last_not_of(v, pos); } size_type find_last_not_of(const char* s, size_type pos, size_type count) const { - return view_.find_last_not_of(s, pos, count); + return this->view_.find_last_not_of(s, pos, count); } private: @@ -822,7 +827,10 @@ struct StringOpPlus } #endif operator std::string() const; - std::string::size_type size() const { return l.size() + r.size(); } + std::string::size_type size() const + { + return this->l.size() + this->r.size(); + } }; template <typename T> @@ -848,7 +856,7 @@ template <typename L, typename R> StringOpPlus<L, R>::operator std::string() const { std::string s; - s.reserve(size()); + s.reserve(this->size()); s += *this; return s; } diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx index e0af281..fb0b705 100644 --- a/Source/cmStringAlgorithms.cxx +++ b/Source/cmStringAlgorithms.cxx @@ -161,42 +161,42 @@ inline void MakeDigits(cm::string_view& view, char (&digits)[N], cmAlphaNum::cmAlphaNum(int val) { - MakeDigits(View_, Digits_, "%i", val); + MakeDigits(this->View_, this->Digits_, "%i", val); } cmAlphaNum::cmAlphaNum(unsigned int val) { - MakeDigits(View_, Digits_, "%u", val); + MakeDigits(this->View_, this->Digits_, "%u", val); } cmAlphaNum::cmAlphaNum(long int val) { - MakeDigits(View_, Digits_, "%li", val); + MakeDigits(this->View_, this->Digits_, "%li", val); } cmAlphaNum::cmAlphaNum(unsigned long int val) { - MakeDigits(View_, Digits_, "%lu", val); + MakeDigits(this->View_, this->Digits_, "%lu", val); } cmAlphaNum::cmAlphaNum(long long int val) { - MakeDigits(View_, Digits_, "%lli", val); + MakeDigits(this->View_, this->Digits_, "%lli", val); } cmAlphaNum::cmAlphaNum(unsigned long long int val) { - MakeDigits(View_, Digits_, "%llu", val); + MakeDigits(this->View_, this->Digits_, "%llu", val); } cmAlphaNum::cmAlphaNum(float val) { - MakeDigits(View_, Digits_, "%g", static_cast<double>(val)); + MakeDigits(this->View_, this->Digits_, "%g", static_cast<double>(val)); } cmAlphaNum::cmAlphaNum(double val) { - MakeDigits(View_, Digits_, "%g", val); + MakeDigits(this->View_, this->Digits_, "%g", val); } std::string cmCatViews(std::initializer_list<cm::string_view> views) diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h index 01e3d94..6b458ec 100644 --- a/Source/cmStringAlgorithms.h +++ b/Source/cmStringAlgorithms.h @@ -48,7 +48,7 @@ struct cmStrCmp { } - bool operator()(cm::string_view sv) const { return Test_ == sv; } + bool operator()(cm::string_view sv) const { return this->Test_ == sv; } private: std::string const Test_; @@ -163,9 +163,9 @@ public: { } cmAlphaNum(char ch) - : View_(Digits_, 1) + : View_(this->Digits_, 1) { - Digits_[0] = ch; + this->Digits_[0] = ch; } cmAlphaNum(int val); cmAlphaNum(unsigned int val); @@ -176,7 +176,7 @@ public: cmAlphaNum(float val); cmAlphaNum(double val); - cm::string_view View() const { return View_; } + cm::string_view View() const { return this->View_; } private: cm::string_view View_; diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index b28fca9..0c8adc7 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -966,21 +966,21 @@ public: const std::string& Args::PopFront(cm::string_view error) { - if (empty()) { + if (this->empty()) { throw json_error({ error }); } - const std::string& res = *begin(); - advance(1); + const std::string& res = *this->begin(); + this->advance(1); return res; } const std::string& Args::PopBack(cm::string_view error) { - if (empty()) { + if (this->empty()) { throw json_error({ error }); } - const std::string& res = *(end() - 1); - retreat(1); + const std::string& res = *(this->end() - 1); + this->retreat(1); return res; } diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 6a705f4..024356f 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1255,6 +1255,30 @@ void cmSystemTools::ConvertToOutputSlashes(std::string& path) #endif } +void cmSystemTools::ConvertToLongPath(std::string& path) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + // Try to convert path to a long path only if the path contains character '~' + if (path.find('~') == std::string::npos) { + return; + } + + std::wstring wPath = cmsys::Encoding::ToWide(path); + DWORD ret = GetLongPathNameW(wPath.c_str(), nullptr, 0); + std::vector<wchar_t> buffer(ret); + if (ret != 0) { + ret = GetLongPathNameW(wPath.c_str(), buffer.data(), + static_cast<DWORD>(buffer.size())); + } + + if (ret != 0) { + path = cmsys::Encoding::ToNarrow(buffer.data()); + } +#else + static_cast<void>(path); +#endif +} + std::string cmSystemTools::ConvertToRunCommandPath(const std::string& path) { #if defined(_WIN32) && !defined(__CYGWIN__) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 1100f05..5bbbb0c 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -287,6 +287,12 @@ public: // running cmake needs paths to be in its format static std::string ConvertToRunCommandPath(const std::string& path); + /** + * For windows computes the long path for the given path, + * For Unix, it is a noop + */ + static void ConvertToLongPath(std::string& path); + /** compute the relative path from local to remote. local must be a directory. remote can be a file or a directory. Both remote and local must be full paths. Basically, if diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 017ab10..1fd2355 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -230,34 +230,35 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, : impl(cm::make_unique<cmTargetInternals>()) { assert(mf); - impl->TargetType = type; - impl->Makefile = mf; - impl->Name = name; - impl->IsGeneratorProvided = false; - impl->HaveInstallRule = false; - impl->IsDLLPlatform = false; - impl->IsAIX = false; - impl->IsAndroid = false; - impl->IsImportedTarget = + this->impl->TargetType = type; + this->impl->Makefile = mf; + this->impl->Name = name; + this->impl->IsGeneratorProvided = false; + this->impl->HaveInstallRule = false; + this->impl->IsDLLPlatform = false; + this->impl->IsAIX = false; + this->impl->IsAndroid = false; + this->impl->IsImportedTarget = (vis == VisibilityImported || vis == VisibilityImportedGlobally); - impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally; - impl->BuildInterfaceIncludesAppended = false; - impl->PerConfig = (perConfig == PerConfig::Yes); + this->impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally; + this->impl->BuildInterfaceIncludesAppended = false; + this->impl->PerConfig = (perConfig == PerConfig::Yes); // Check whether this is a DLL platform. - impl->IsDLLPlatform = - !impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty(); + this->impl->IsDLLPlatform = + !this->impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX") + .empty(); // Check whether we are targeting AIX. { std::string const& systemName = - impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"); - impl->IsAIX = (systemName == "AIX" || systemName == "OS400"); + this->impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME"); + this->impl->IsAIX = (systemName == "AIX" || systemName == "OS400"); } // Check whether we are targeting an Android platform. - impl->IsAndroid = - (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android"); + this->impl->IsAndroid = (this->impl->Makefile->GetSafeDefinition( + "CMAKE_SYSTEM_NAME") == "Android"); std::string defKey; defKey.reserve(128); @@ -382,6 +383,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initProp("UNITY_BUILD"); initProp("UNITY_BUILD_UNIQUE_ID"); initProp("OPTIMIZE_DEPENDENCIES"); + initProp("EXPORT_COMPILE_COMMANDS"); initPropValue("UNITY_BUILD_BATCH_SIZE", "8"); initPropValue("UNITY_BUILD_MODE", "BATCH"); initPropValue("PCH_WARN_INVALID", "ON"); @@ -436,7 +438,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, for (auto const& prop : configProps) { // Interface libraries have no output locations, so honor only // the configuration map. - if (impl->TargetType == cmStateEnums::INTERFACE_LIBRARY && + if (this->impl->TargetType == cmStateEnums::INTERFACE_LIBRARY && strcmp(prop, "MAP_IMPORTED_CONFIG_") != 0) { continue; } @@ -449,15 +451,15 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, // compatibility with previous CMake versions in which executables // did not support this variable. Projects may still specify the // property directly. - if (impl->TargetType != cmStateEnums::EXECUTABLE && - impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) { + if (this->impl->TargetType != cmStateEnums::EXECUTABLE && + this->impl->TargetType != cmStateEnums::INTERFACE_LIBRARY) { std::string property = cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX"); initProp(property); } - if (impl->TargetType == cmStateEnums::SHARED_LIBRARY || - impl->TargetType == cmStateEnums::STATIC_LIBRARY) { + if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY || + this->impl->TargetType == cmStateEnums::STATIC_LIBRARY) { std::string property = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_", cmSystemTools::UpperCase(configName)); initProp(property); @@ -466,66 +468,67 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, } // Save the backtrace of target construction. - impl->Backtrace = impl->Makefile->GetBacktrace(); + this->impl->Backtrace = this->impl->Makefile->GetBacktrace(); if (!this->IsImported()) { // Initialize the INCLUDE_DIRECTORIES property based on the current value // of the same directory property: - cm::append(impl->IncludeDirectoriesEntries, - impl->Makefile->GetIncludeDirectoriesEntries()); - cm::append(impl->IncludeDirectoriesBacktraces, - impl->Makefile->GetIncludeDirectoriesBacktraces()); + cm::append(this->impl->IncludeDirectoriesEntries, + this->impl->Makefile->GetIncludeDirectoriesEntries()); + cm::append(this->impl->IncludeDirectoriesBacktraces, + this->impl->Makefile->GetIncludeDirectoriesBacktraces()); { - auto const& sysInc = impl->Makefile->GetSystemIncludeDirectories(); - impl->SystemIncludeDirectories.insert(sysInc.begin(), sysInc.end()); + auto const& sysInc = this->impl->Makefile->GetSystemIncludeDirectories(); + this->impl->SystemIncludeDirectories.insert(sysInc.begin(), + sysInc.end()); } - cm::append(impl->CompileOptionsEntries, - impl->Makefile->GetCompileOptionsEntries()); - cm::append(impl->CompileOptionsBacktraces, - impl->Makefile->GetCompileOptionsBacktraces()); + cm::append(this->impl->CompileOptionsEntries, + this->impl->Makefile->GetCompileOptionsEntries()); + cm::append(this->impl->CompileOptionsBacktraces, + this->impl->Makefile->GetCompileOptionsBacktraces()); - cm::append(impl->LinkOptionsEntries, - impl->Makefile->GetLinkOptionsEntries()); - cm::append(impl->LinkOptionsBacktraces, - impl->Makefile->GetLinkOptionsBacktraces()); + cm::append(this->impl->LinkOptionsEntries, + this->impl->Makefile->GetLinkOptionsEntries()); + cm::append(this->impl->LinkOptionsBacktraces, + this->impl->Makefile->GetLinkOptionsBacktraces()); - cm::append(impl->LinkDirectoriesEntries, - impl->Makefile->GetLinkDirectoriesEntries()); - cm::append(impl->LinkDirectoriesBacktraces, - impl->Makefile->GetLinkDirectoriesBacktraces()); + cm::append(this->impl->LinkDirectoriesEntries, + this->impl->Makefile->GetLinkDirectoriesEntries()); + cm::append(this->impl->LinkDirectoriesBacktraces, + this->impl->Makefile->GetLinkDirectoriesBacktraces()); } - if (impl->TargetType == cmStateEnums::EXECUTABLE) { + if (this->impl->TargetType == cmStateEnums::EXECUTABLE) { initProp("ANDROID_GUI"); initProp("CROSSCOMPILING_EMULATOR"); initProp("ENABLE_EXPORTS"); } - if (impl->TargetType == cmStateEnums::SHARED_LIBRARY || - impl->TargetType == cmStateEnums::MODULE_LIBRARY) { + if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY || + this->impl->TargetType == cmStateEnums::MODULE_LIBRARY) { this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); } else if (this->CanCompileSources()) { initProp("POSITION_INDEPENDENT_CODE"); } - if (impl->TargetType == cmStateEnums::SHARED_LIBRARY || - impl->TargetType == cmStateEnums::EXECUTABLE) { + if (this->impl->TargetType == cmStateEnums::SHARED_LIBRARY || + this->impl->TargetType == cmStateEnums::EXECUTABLE) { initProp("AIX_EXPORT_ALL_SYMBOLS"); initProp("WINDOWS_EXPORT_ALL_SYMBOLS"); } // Record current policies for later use. - impl->Makefile->RecordPolicies(impl->PolicyMap); + this->impl->Makefile->RecordPolicies(this->impl->PolicyMap); - if (impl->TargetType == cmStateEnums::INTERFACE_LIBRARY) { + if (this->impl->TargetType == cmStateEnums::INTERFACE_LIBRARY) { // This policy is checked in a few conditions. The properties relevant // to the policy are always ignored for cmStateEnums::INTERFACE_LIBRARY // targets, // so ensure that the conditions don't lead to nonsense. - impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW); + this->impl->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW); } - if (impl->TargetType <= cmStateEnums::GLOBAL_TARGET) { + if (this->impl->TargetType <= cmStateEnums::GLOBAL_TARGET) { initProp("DOTNET_TARGET_FRAMEWORK"); initProp("DOTNET_TARGET_FRAMEWORK_VERSION"); } @@ -558,40 +561,40 @@ cmTarget& cmTarget::operator=(cmTarget&&) noexcept = default; cmStateEnums::TargetType cmTarget::GetType() const { - return impl->TargetType; + return this->impl->TargetType; } cmMakefile* cmTarget::GetMakefile() const { - return impl->Makefile; + return this->impl->Makefile; } cmPolicies::PolicyMap const& cmTarget::GetPolicyMap() const { - return impl->PolicyMap; + return this->impl->PolicyMap; } const std::string& cmTarget::GetName() const { - return impl->Name; + return this->impl->Name; } cmPolicies::PolicyStatus cmTarget::GetPolicyStatus( cmPolicies::PolicyID policy) const { - return impl->PolicyMap.Get(policy); + return this->impl->PolicyMap.Get(policy); } cmGlobalGenerator* cmTarget::GetGlobalGenerator() const { - return impl->Makefile->GetGlobalGenerator(); + return this->impl->Makefile->GetGlobalGenerator(); } BTs<std::string> const* cmTarget::GetLanguageStandardProperty( const std::string& propertyName) const { - auto entry = impl->LanguageStandardProperties.find(propertyName); - if (entry != impl->LanguageStandardProperties.end()) { + auto entry = this->impl->LanguageStandardProperties.find(propertyName); + if (entry != this->impl->LanguageStandardProperties.end()) { return &entry->second; } @@ -603,17 +606,17 @@ void cmTarget::SetLanguageStandardProperty(std::string const& lang, const std::string& feature) { cmListFileBacktrace featureBacktrace; - for (size_t i = 0; i < impl->CompileFeaturesEntries.size(); i++) { - if (impl->CompileFeaturesEntries[i] == feature) { - if (i < impl->CompileFeaturesBacktraces.size()) { - featureBacktrace = impl->CompileFeaturesBacktraces[i]; + for (size_t i = 0; i < this->impl->CompileFeaturesEntries.size(); i++) { + if (this->impl->CompileFeaturesEntries[i] == feature) { + if (i < this->impl->CompileFeaturesBacktraces.size()) { + featureBacktrace = this->impl->CompileFeaturesBacktraces[i]; } break; } } BTs<std::string>& languageStandardProperty = - impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")]; + this->impl->LanguageStandardProperties[cmStrCat(lang, "_STANDARD")]; if (languageStandardProperty.Value != value) { languageStandardProperty.Value = value; languageStandardProperty.Backtraces.clear(); @@ -623,24 +626,24 @@ void cmTarget::SetLanguageStandardProperty(std::string const& lang, void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf) { - impl->Utilities.insert(BT<std::pair<std::string, bool>>( + this->impl->Utilities.insert(BT<std::pair<std::string, bool>>( { name, cross }, mf ? mf->GetBacktrace() : cmListFileBacktrace())); } void cmTarget::AddUtility(BT<std::pair<std::string, bool>> util) { - impl->Utilities.emplace(std::move(util)); + this->impl->Utilities.emplace(std::move(util)); } std::set<BT<std::pair<std::string, bool>>> const& cmTarget::GetUtilities() const { - return impl->Utilities; + return this->impl->Utilities; } cmListFileBacktrace const& cmTarget::GetBacktrace() const { - return impl->Backtrace; + return this->impl->Backtrace; } bool cmTarget::IsExecutableWithExports() const @@ -653,74 +656,74 @@ bool cmTarget::IsFrameworkOnApple() const { return ((this->GetType() == cmStateEnums::SHARED_LIBRARY || this->GetType() == cmStateEnums::STATIC_LIBRARY) && - impl->Makefile->IsOn("APPLE") && + this->impl->Makefile->IsOn("APPLE") && this->GetPropertyAsBool("FRAMEWORK")); } bool cmTarget::IsAppBundleOnApple() const { return (this->GetType() == cmStateEnums::EXECUTABLE && - impl->Makefile->IsOn("APPLE") && + this->impl->Makefile->IsOn("APPLE") && this->GetPropertyAsBool("MACOSX_BUNDLE")); } bool cmTarget::IsAndroidGuiExecutable() const { - return (this->GetType() == cmStateEnums::EXECUTABLE && impl->IsAndroid && - this->GetPropertyAsBool("ANDROID_GUI")); + return (this->GetType() == cmStateEnums::EXECUTABLE && + this->impl->IsAndroid && this->GetPropertyAsBool("ANDROID_GUI")); } std::vector<cmCustomCommand> const& cmTarget::GetPreBuildCommands() const { - return impl->PreBuildCommands; + return this->impl->PreBuildCommands; } void cmTarget::AddPreBuildCommand(cmCustomCommand const& cmd) { - impl->PreBuildCommands.push_back(cmd); + this->impl->PreBuildCommands.push_back(cmd); } void cmTarget::AddPreBuildCommand(cmCustomCommand&& cmd) { - impl->PreBuildCommands.push_back(std::move(cmd)); + this->impl->PreBuildCommands.push_back(std::move(cmd)); } std::vector<cmCustomCommand> const& cmTarget::GetPreLinkCommands() const { - return impl->PreLinkCommands; + return this->impl->PreLinkCommands; } void cmTarget::AddPreLinkCommand(cmCustomCommand const& cmd) { - impl->PreLinkCommands.push_back(cmd); + this->impl->PreLinkCommands.push_back(cmd); } void cmTarget::AddPreLinkCommand(cmCustomCommand&& cmd) { - impl->PreLinkCommands.push_back(std::move(cmd)); + this->impl->PreLinkCommands.push_back(std::move(cmd)); } std::vector<cmCustomCommand> const& cmTarget::GetPostBuildCommands() const { - return impl->PostBuildCommands; + return this->impl->PostBuildCommands; } void cmTarget::AddPostBuildCommand(cmCustomCommand const& cmd) { - impl->PostBuildCommands.push_back(cmd); + this->impl->PostBuildCommands.push_back(cmd); } void cmTarget::AddPostBuildCommand(cmCustomCommand&& cmd) { - impl->PostBuildCommands.push_back(std::move(cmd)); + this->impl->PostBuildCommands.push_back(std::move(cmd)); } void cmTarget::AddTracedSources(std::vector<std::string> const& srcs) { if (!srcs.empty()) { - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->SourceEntries.push_back(cmJoin(srcs, ";")); - impl->SourceBacktraces.push_back(lfbt); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->SourceEntries.push_back(cmJoin(srcs, ";")); + this->impl->SourceBacktraces.push_back(lfbt); } } @@ -731,21 +734,21 @@ void cmTarget::AddSources(std::vector<std::string> const& srcs) for (auto filename : srcs) { if (!cmGeneratorExpression::StartsWithGeneratorExpression(filename)) { if (!filename.empty()) { - filename = impl->ProcessSourceItemCMP0049(filename); + filename = this->impl->ProcessSourceItemCMP0049(filename); if (filename.empty()) { return; } } - impl->Makefile->GetOrCreateSource(filename); + this->impl->Makefile->GetOrCreateSource(filename); } srcFiles += sep; srcFiles += filename; sep = ";"; } if (!srcFiles.empty()) { - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->SourceEntries.push_back(std::move(srcFiles)); - impl->SourceBacktraces.push_back(lfbt); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->SourceEntries.push_back(std::move(srcFiles)); + this->impl->SourceBacktraces.push_back(lfbt); } } @@ -789,7 +792,7 @@ std::string cmTargetInternals::ProcessSourceItemCMP0049( std::string cmTarget::GetSourceCMP0049(const std::string& s) { - return impl->ProcessSourceItemCMP0049(s); + return this->impl->ProcessSourceItemCMP0049(s); } struct CreateLocation @@ -848,23 +851,25 @@ public: cmSourceFile* cmTarget::AddSource(const std::string& src, bool before) { - cmSourceFileLocation sfl(impl->Makefile, src, + cmSourceFileLocation sfl(this->impl->Makefile, src, cmSourceFileLocationKind::Known); - if (std::find_if(impl->SourceEntries.begin(), impl->SourceEntries.end(), - TargetPropertyEntryFinder(sfl)) == - impl->SourceEntries.end()) { - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->SourceEntries.insert( - before ? impl->SourceEntries.begin() : impl->SourceEntries.end(), src); - impl->SourceBacktraces.insert(before ? impl->SourceBacktraces.begin() - : impl->SourceBacktraces.end(), - lfbt); + if (std::find_if( + this->impl->SourceEntries.begin(), this->impl->SourceEntries.end(), + TargetPropertyEntryFinder(sfl)) == this->impl->SourceEntries.end()) { + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->SourceEntries.insert(before ? this->impl->SourceEntries.begin() + : this->impl->SourceEntries.end(), + src); + this->impl->SourceBacktraces.insert( + before ? this->impl->SourceBacktraces.begin() + : this->impl->SourceBacktraces.end(), + lfbt); } if (cmGeneratorExpression::Find(src) != std::string::npos) { return nullptr; } - return impl->Makefile->GetOrCreateSource(src, false, - cmSourceFileLocationKind::Known); + return this->impl->Makefile->GetOrCreateSource( + src, false, cmSourceFileLocationKind::Known); } void cmTarget::ClearDependencyInformation(cmMakefile& mf) const @@ -882,7 +887,7 @@ std::string cmTarget::GetDebugGeneratorExpressions( // Get the list of configurations considered to be DEBUG. std::vector<std::string> debugConfigs = - impl->Makefile->GetCMakeInstance()->GetDebugConfigs(); + this->impl->Makefile->GetCMakeInstance()->GetDebugConfigs(); std::string configString = "$<CONFIG:" + debugConfigs[0] + ">"; @@ -908,13 +913,14 @@ bool cmTarget::PushTLLCommandTrace(TLLSignature signature, cmListFileContext const& lfc) { bool ret = true; - if (!impl->TLLCommands.empty()) { - if (impl->TLLCommands.back().first != signature) { + if (!this->impl->TLLCommands.empty()) { + if (this->impl->TLLCommands.back().first != signature) { ret = false; } } - if (impl->TLLCommands.empty() || impl->TLLCommands.back().second != lfc) { - impl->TLLCommands.emplace_back(signature, lfc); + if (this->impl->TLLCommands.empty() || + this->impl->TLLCommands.back().second != lfc) { + this->impl->TLLCommands.emplace_back(signature, lfc); } return ret; } @@ -924,12 +930,13 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const const char* sigString = (sig == cmTarget::KeywordTLLSignature ? "keyword" : "plain"); s << "The uses of the " << sigString << " signature are here:\n"; - cmStateDirectory cmDir = impl->Makefile->GetStateSnapshot().GetDirectory(); - for (auto const& cmd : impl->TLLCommands) { + cmStateDirectory cmDir = + this->impl->Makefile->GetStateSnapshot().GetDirectory(); + for (auto const& cmd : this->impl->TLLCommands) { if (cmd.first == sig) { cmListFileContext lfc = cmd.second; lfc.FilePath = cmDir.ConvertToRelPathIfNotContained( - impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath); + this->impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath); s << " * " << lfc << '\n'; } } @@ -937,59 +944,59 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const std::string const& cmTarget::GetInstallPath() const { - return impl->InstallPath; + return this->impl->InstallPath; } void cmTarget::SetInstallPath(std::string const& name) { - impl->InstallPath = name; + this->impl->InstallPath = name; } std::string const& cmTarget::GetRuntimeInstallPath() const { - return impl->RuntimeInstallPath; + return this->impl->RuntimeInstallPath; } void cmTarget::SetRuntimeInstallPath(std::string const& name) { - impl->RuntimeInstallPath = name; + this->impl->RuntimeInstallPath = name; } bool cmTarget::GetHaveInstallRule() const { - return impl->HaveInstallRule; + return this->impl->HaveInstallRule; } void cmTarget::SetHaveInstallRule(bool hir) { - impl->HaveInstallRule = hir; + this->impl->HaveInstallRule = hir; } void cmTarget::AddInstallGenerator(cmInstallTargetGenerator* g) { - impl->InstallGenerators.emplace_back(g); + this->impl->InstallGenerators.emplace_back(g); } std::vector<cmInstallTargetGenerator*> const& cmTarget::GetInstallGenerators() const { - return impl->InstallGenerators; + return this->impl->InstallGenerators; } bool cmTarget::GetIsGeneratorProvided() const { - return impl->IsGeneratorProvided; + return this->impl->IsGeneratorProvided; } void cmTarget::SetIsGeneratorProvided(bool igp) { - impl->IsGeneratorProvided = igp; + this->impl->IsGeneratorProvided = igp; } cmTarget::LinkLibraryVectorType const& cmTarget::GetOriginalLinkLibraries() const { - return impl->OriginalLinkLibraries; + return this->impl->OriginalLinkLibraries; } void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, @@ -1011,11 +1018,11 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, (tgt && (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY || tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) || - (impl->Name == lib)) { + (this->impl->Name == lib)) { return; } - impl->OriginalLinkLibraries.emplace_back(lib, llt); + this->impl->OriginalLinkLibraries.emplace_back(lib, llt); // Add the explicit dependency information for libraries. This is // simply a set of libraries separated by ";". There should always @@ -1025,11 +1032,11 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, // may be purposefully duplicated to handle recursive dependencies, // and we removing one instance will break the link line. Duplicates // will be appropriately eliminated at emit time. - if (impl->TargetType >= cmStateEnums::STATIC_LIBRARY && - impl->TargetType <= cmStateEnums::MODULE_LIBRARY && + if (this->impl->TargetType >= cmStateEnums::STATIC_LIBRARY && + this->impl->TargetType <= cmStateEnums::MODULE_LIBRARY && (this->GetPolicyStatusCMP0073() == cmPolicies::OLD || this->GetPolicyStatusCMP0073() == cmPolicies::WARN)) { - std::string targetEntry = cmStrCat(impl->Name, "_LIB_DEPENDS"); + std::string targetEntry = cmStrCat(this->impl->Name, "_LIB_DEPENDS"); std::string dependencies; cmProp old_val = mf.GetDefinition(targetEntry); if (old_val) { @@ -1056,102 +1063,102 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib, void cmTarget::AddSystemIncludeDirectories(const std::set<std::string>& incs) { - impl->SystemIncludeDirectories.insert(incs.begin(), incs.end()); + this->impl->SystemIncludeDirectories.insert(incs.begin(), incs.end()); } std::set<std::string> const& cmTarget::GetSystemIncludeDirectories() const { - return impl->SystemIncludeDirectories; + return this->impl->SystemIncludeDirectories; } cmStringRange cmTarget::GetIncludeDirectoriesEntries() const { - return cmMakeRange(impl->IncludeDirectoriesEntries); + return cmMakeRange(this->impl->IncludeDirectoriesEntries); } cmBacktraceRange cmTarget::GetIncludeDirectoriesBacktraces() const { - return cmMakeRange(impl->IncludeDirectoriesBacktraces); + return cmMakeRange(this->impl->IncludeDirectoriesBacktraces); } cmStringRange cmTarget::GetCompileOptionsEntries() const { - return cmMakeRange(impl->CompileOptionsEntries); + return cmMakeRange(this->impl->CompileOptionsEntries); } cmBacktraceRange cmTarget::GetCompileOptionsBacktraces() const { - return cmMakeRange(impl->CompileOptionsBacktraces); + return cmMakeRange(this->impl->CompileOptionsBacktraces); } cmStringRange cmTarget::GetCompileFeaturesEntries() const { - return cmMakeRange(impl->CompileFeaturesEntries); + return cmMakeRange(this->impl->CompileFeaturesEntries); } cmBacktraceRange cmTarget::GetCompileFeaturesBacktraces() const { - return cmMakeRange(impl->CompileFeaturesBacktraces); + return cmMakeRange(this->impl->CompileFeaturesBacktraces); } cmStringRange cmTarget::GetCompileDefinitionsEntries() const { - return cmMakeRange(impl->CompileDefinitionsEntries); + return cmMakeRange(this->impl->CompileDefinitionsEntries); } cmBacktraceRange cmTarget::GetCompileDefinitionsBacktraces() const { - return cmMakeRange(impl->CompileDefinitionsBacktraces); + return cmMakeRange(this->impl->CompileDefinitionsBacktraces); } cmStringRange cmTarget::GetPrecompileHeadersEntries() const { - return cmMakeRange(impl->PrecompileHeadersEntries); + return cmMakeRange(this->impl->PrecompileHeadersEntries); } cmBacktraceRange cmTarget::GetPrecompileHeadersBacktraces() const { - return cmMakeRange(impl->PrecompileHeadersBacktraces); + return cmMakeRange(this->impl->PrecompileHeadersBacktraces); } cmStringRange cmTarget::GetSourceEntries() const { - return cmMakeRange(impl->SourceEntries); + return cmMakeRange(this->impl->SourceEntries); } cmBacktraceRange cmTarget::GetSourceBacktraces() const { - return cmMakeRange(impl->SourceBacktraces); + return cmMakeRange(this->impl->SourceBacktraces); } cmStringRange cmTarget::GetLinkOptionsEntries() const { - return cmMakeRange(impl->LinkOptionsEntries); + return cmMakeRange(this->impl->LinkOptionsEntries); } cmBacktraceRange cmTarget::GetLinkOptionsBacktraces() const { - return cmMakeRange(impl->LinkOptionsBacktraces); + return cmMakeRange(this->impl->LinkOptionsBacktraces); } cmStringRange cmTarget::GetLinkDirectoriesEntries() const { - return cmMakeRange(impl->LinkDirectoriesEntries); + return cmMakeRange(this->impl->LinkDirectoriesEntries); } cmBacktraceRange cmTarget::GetLinkDirectoriesBacktraces() const { - return cmMakeRange(impl->LinkDirectoriesBacktraces); + return cmMakeRange(this->impl->LinkDirectoriesBacktraces); } cmStringRange cmTarget::GetLinkImplementationEntries() const { - return cmMakeRange(impl->LinkImplementationPropertyEntries); + return cmMakeRange(this->impl->LinkImplementationPropertyEntries); } cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const { - return cmMakeRange(impl->LinkImplementationPropertyBacktraces); + return cmMakeRange(this->impl->LinkImplementationPropertyBacktraces); } void cmTarget::SetProperty(const std::string& prop, const char* value) @@ -1180,154 +1187,154 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) MAKE_STATIC_PROP(TYPE); #undef MAKE_STATIC_PROP if (prop == propMANUALLY_ADDED_DEPENDENCIES) { - impl->Makefile->IssueMessage( + this->impl->Makefile->IssueMessage( MessageType::FATAL_ERROR, "MANUALLY_ADDED_DEPENDENCIES property is read-only\n"); return; } if (prop == propNAME) { - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "NAME property is read-only\n"); + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "NAME property is read-only\n"); return; } if (prop == propTYPE) { - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "TYPE property is read-only\n"); + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "TYPE property is read-only\n"); return; } if (prop == propEXPORT_NAME && this->IsImported()) { std::ostringstream e; e << "EXPORT_NAME property can't be set on imported targets (\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } if (prop == propSOURCES && this->IsImported()) { std::ostringstream e; - e << "SOURCES property can't be set on imported targets (\"" << impl->Name - << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + e << "SOURCES property can't be set on imported targets (\"" + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } if (prop == propIMPORTED_GLOBAL && !this->IsImported()) { std::ostringstream e; e << "IMPORTED_GLOBAL property can't be set on non-imported targets (\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } if (prop == propINCLUDE_DIRECTORIES) { - impl->IncludeDirectoriesEntries.clear(); - impl->IncludeDirectoriesBacktraces.clear(); + this->impl->IncludeDirectoriesEntries.clear(); + this->impl->IncludeDirectoriesBacktraces.clear(); if (value) { - impl->IncludeDirectoriesEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->IncludeDirectoriesBacktraces.push_back(lfbt); + this->impl->IncludeDirectoriesEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->IncludeDirectoriesBacktraces.push_back(lfbt); } } else if (prop == propCOMPILE_OPTIONS) { - impl->CompileOptionsEntries.clear(); - impl->CompileOptionsBacktraces.clear(); + this->impl->CompileOptionsEntries.clear(); + this->impl->CompileOptionsBacktraces.clear(); if (value) { - impl->CompileOptionsEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->CompileOptionsBacktraces.push_back(lfbt); + this->impl->CompileOptionsEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->CompileOptionsBacktraces.push_back(lfbt); } } else if (prop == propCOMPILE_FEATURES) { - impl->CompileFeaturesEntries.clear(); - impl->CompileFeaturesBacktraces.clear(); + this->impl->CompileFeaturesEntries.clear(); + this->impl->CompileFeaturesBacktraces.clear(); if (value) { - impl->CompileFeaturesEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->CompileFeaturesBacktraces.push_back(lfbt); + this->impl->CompileFeaturesEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->CompileFeaturesBacktraces.push_back(lfbt); } } else if (prop == propCOMPILE_DEFINITIONS) { - impl->CompileDefinitionsEntries.clear(); - impl->CompileDefinitionsBacktraces.clear(); + this->impl->CompileDefinitionsEntries.clear(); + this->impl->CompileDefinitionsBacktraces.clear(); if (value) { - impl->CompileDefinitionsEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->CompileDefinitionsBacktraces.push_back(lfbt); + this->impl->CompileDefinitionsEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->CompileDefinitionsBacktraces.push_back(lfbt); } } else if (prop == propLINK_OPTIONS) { - impl->LinkOptionsEntries.clear(); - impl->LinkOptionsBacktraces.clear(); + this->impl->LinkOptionsEntries.clear(); + this->impl->LinkOptionsBacktraces.clear(); if (value) { - impl->LinkOptionsEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->LinkOptionsBacktraces.push_back(lfbt); + this->impl->LinkOptionsEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkOptionsBacktraces.push_back(lfbt); } } else if (prop == propLINK_DIRECTORIES) { - impl->LinkDirectoriesEntries.clear(); - impl->LinkDirectoriesBacktraces.clear(); + this->impl->LinkDirectoriesEntries.clear(); + this->impl->LinkDirectoriesBacktraces.clear(); if (value) { - impl->LinkDirectoriesEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->LinkDirectoriesBacktraces.push_back(lfbt); + this->impl->LinkDirectoriesEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkDirectoriesBacktraces.push_back(lfbt); } } else if (prop == propPRECOMPILE_HEADERS) { - impl->PrecompileHeadersEntries.clear(); - impl->PrecompileHeadersBacktraces.clear(); + this->impl->PrecompileHeadersEntries.clear(); + this->impl->PrecompileHeadersBacktraces.clear(); if (value) { - impl->PrecompileHeadersEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->PrecompileHeadersBacktraces.push_back(lfbt); + this->impl->PrecompileHeadersEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->PrecompileHeadersBacktraces.push_back(lfbt); } } else if (prop == propLINK_LIBRARIES) { - impl->LinkImplementationPropertyEntries.clear(); - impl->LinkImplementationPropertyBacktraces.clear(); + this->impl->LinkImplementationPropertyEntries.clear(); + this->impl->LinkImplementationPropertyBacktraces.clear(); if (value) { - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->LinkImplementationPropertyEntries.emplace_back(value); - impl->LinkImplementationPropertyBacktraces.push_back(lfbt); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkImplementationPropertyEntries.emplace_back(value); + this->impl->LinkImplementationPropertyBacktraces.push_back(lfbt); } } else if (prop == propSOURCES) { - impl->SourceEntries.clear(); - impl->SourceBacktraces.clear(); + this->impl->SourceEntries.clear(); + this->impl->SourceBacktraces.clear(); if (value) { - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->SourceEntries.emplace_back(value); - impl->SourceBacktraces.push_back(lfbt); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->SourceEntries.emplace_back(value); + this->impl->SourceBacktraces.push_back(lfbt); } } else if (prop == propIMPORTED_GLOBAL) { if (!cmIsOn(value)) { std::ostringstream e; e << "IMPORTED_GLOBAL property can't be set to FALSE on targets (\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } /* no need to change anything if value does not change */ - if (!impl->ImportedGloballyVisible) { - impl->ImportedGloballyVisible = true; + if (!this->impl->ImportedGloballyVisible) { + this->impl->ImportedGloballyVisible = true; this->GetGlobalGenerator()->IndexTarget(this); } } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") && - !impl->CheckImportedLibName(prop, value ? value : "")) { + !this->impl->CheckImportedLibName(prop, value ? value : "")) { /* error was reported by check method */ } else if (prop == propCUDA_PTX_COMPILATION && this->GetType() != cmStateEnums::OBJECT_LIBRARY) { std::ostringstream e; e << "CUDA_PTX_COMPILATION property can only be applied to OBJECT " "targets (\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } else if (prop == propPRECOMPILE_HEADERS_REUSE_FROM) { if (this->GetProperty("PRECOMPILE_HEADERS")) { std::ostringstream e; e << "PRECOMPILE_HEADERS property is already set on target (\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } - auto reusedTarget = - impl->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( - value); + auto reusedTarget = this->impl->Makefile->GetCMakeInstance() + ->GetGlobalGenerator() + ->FindTarget(value); if (!reusedTarget) { const std::string e( "PRECOMPILE_HEADERS_REUSE_FROM set with non existing target"); - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e); return; } @@ -1336,7 +1343,7 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) reusedFrom = value; } - impl->Properties.SetProperty(prop, reusedFrom.c_str()); + this->impl->Properties.SetProperty(prop, reusedFrom.c_str()); reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom); reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY", @@ -1344,18 +1351,18 @@ void cmTarget::SetProperty(const std::string& prop, const char* value) cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME"); this->SetProperty("COMPILE_PDB_NAME", cmToCStr(tmp)); - this->AddUtility(reusedFrom, false, impl->Makefile); + this->AddUtility(reusedFrom, false, this->impl->Makefile); } else if (prop == propC_STANDARD || prop == propCXX_STANDARD || prop == propCUDA_STANDARD || prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD) { if (value) { - impl->LanguageStandardProperties[prop] = - BTs<std::string>(value, impl->Makefile->GetBacktrace()); + this->impl->LanguageStandardProperties[prop] = + BTs<std::string>(value, this->impl->Makefile->GetBacktrace()); } else { - impl->LanguageStandardProperties.erase(prop); + this->impl->LanguageStandardProperties.erase(prop); } } else { - impl->Properties.SetProperty(prop, value); + this->impl->Properties.SetProperty(prop, value); } } @@ -1363,102 +1370,102 @@ void cmTarget::AppendProperty(const std::string& prop, const std::string& value, bool asString) { if (prop == "NAME") { - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, - "NAME property is read-only\n"); + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + "NAME property is read-only\n"); return; } if (prop == "EXPORT_NAME" && this->IsImported()) { std::ostringstream e; e << "EXPORT_NAME property can't be set on imported targets (\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } if (prop == "SOURCES" && this->IsImported()) { std::ostringstream e; - e << "SOURCES property can't be set on imported targets (\"" << impl->Name - << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + e << "SOURCES property can't be set on imported targets (\"" + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } if (prop == "IMPORTED_GLOBAL") { std::ostringstream e; e << "IMPORTED_GLOBAL property can't be appended, only set on imported " "targets (\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } if (prop == "INCLUDE_DIRECTORIES") { if (!value.empty()) { - impl->IncludeDirectoriesEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->IncludeDirectoriesBacktraces.push_back(lfbt); + this->impl->IncludeDirectoriesEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->IncludeDirectoriesBacktraces.push_back(lfbt); } } else if (prop == "COMPILE_OPTIONS") { if (!value.empty()) { - impl->CompileOptionsEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->CompileOptionsBacktraces.push_back(lfbt); + this->impl->CompileOptionsEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->CompileOptionsBacktraces.push_back(lfbt); } } else if (prop == "COMPILE_FEATURES") { if (!value.empty()) { - impl->CompileFeaturesEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->CompileFeaturesBacktraces.push_back(lfbt); + this->impl->CompileFeaturesEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->CompileFeaturesBacktraces.push_back(lfbt); } } else if (prop == "COMPILE_DEFINITIONS") { if (!value.empty()) { - impl->CompileDefinitionsEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->CompileDefinitionsBacktraces.push_back(lfbt); + this->impl->CompileDefinitionsEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->CompileDefinitionsBacktraces.push_back(lfbt); } } else if (prop == "LINK_OPTIONS") { if (!value.empty()) { - impl->LinkOptionsEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->LinkOptionsBacktraces.push_back(lfbt); + this->impl->LinkOptionsEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkOptionsBacktraces.push_back(lfbt); } } else if (prop == "LINK_DIRECTORIES") { if (!value.empty()) { - impl->LinkDirectoriesEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->LinkDirectoriesBacktraces.push_back(lfbt); + this->impl->LinkDirectoriesEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkDirectoriesBacktraces.push_back(lfbt); } } else if (prop == "PRECOMPILE_HEADERS") { if (this->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM")) { std::ostringstream e; e << "PRECOMPILE_HEADERS_REUSE_FROM property is already set on target " "(\"" - << impl->Name << "\")\n"; - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); + << this->impl->Name << "\")\n"; + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); return; } if (!value.empty()) { - impl->PrecompileHeadersEntries.emplace_back(value); - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->PrecompileHeadersBacktraces.push_back(lfbt); + this->impl->PrecompileHeadersEntries.emplace_back(value); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->PrecompileHeadersBacktraces.push_back(lfbt); } } else if (prop == "LINK_LIBRARIES") { if (!value.empty()) { - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->LinkImplementationPropertyEntries.emplace_back(value); - impl->LinkImplementationPropertyBacktraces.push_back(lfbt); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->LinkImplementationPropertyEntries.emplace_back(value); + this->impl->LinkImplementationPropertyBacktraces.push_back(lfbt); } } else if (prop == "SOURCES") { - cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace(); - impl->SourceEntries.emplace_back(value); - impl->SourceBacktraces.push_back(lfbt); + cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace(); + this->impl->SourceEntries.emplace_back(value); + this->impl->SourceBacktraces.push_back(lfbt); } else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) { - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, - prop + " property may not be APPENDed."); + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, prop + " property may not be APPENDed."); } else if (prop == "C_STANDARD" || prop == "CXX_STANDARD" || prop == "CUDA_STANDARD" || prop == "OBJC_STANDARD" || prop == "OBJCXX_STANDARD") { - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, - prop + " property may not be appended."); + this->impl->Makefile->IssueMessage( + MessageType::FATAL_ERROR, prop + " property may not be appended."); } else { - impl->Properties.AppendProperty(prop, value, asString); + this->impl->Properties.AppendProperty(prop, value, asString); } } @@ -1471,17 +1478,17 @@ void cmTarget::AppendBuildInterfaceIncludes() !this->IsExecutableWithExports()) { return; } - if (impl->BuildInterfaceIncludesAppended) { + if (this->impl->BuildInterfaceIncludesAppended) { return; } - impl->BuildInterfaceIncludesAppended = true; + this->impl->BuildInterfaceIncludesAppended = true; - if (impl->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE")) { - std::string dirs = impl->Makefile->GetCurrentBinaryDirectory(); + if (this->impl->Makefile->IsOn("CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE")) { + std::string dirs = this->impl->Makefile->GetCurrentBinaryDirectory(); if (!dirs.empty()) { dirs += ';'; } - dirs += impl->Makefile->GetCurrentSourceDirectory(); + dirs += this->impl->Makefile->GetCurrentSourceDirectory(); if (!dirs.empty()) { this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES", ("$<BUILD_INTERFACE:" + dirs + ">")); @@ -1492,67 +1499,67 @@ void cmTarget::AppendBuildInterfaceIncludes() void cmTarget::InsertInclude(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - auto position = before ? impl->IncludeDirectoriesEntries.begin() - : impl->IncludeDirectoriesEntries.end(); + auto position = before ? this->impl->IncludeDirectoriesEntries.begin() + : this->impl->IncludeDirectoriesEntries.end(); - auto btPosition = before ? impl->IncludeDirectoriesBacktraces.begin() - : impl->IncludeDirectoriesBacktraces.end(); + auto btPosition = before ? this->impl->IncludeDirectoriesBacktraces.begin() + : this->impl->IncludeDirectoriesBacktraces.end(); - impl->IncludeDirectoriesEntries.insert(position, entry); - impl->IncludeDirectoriesBacktraces.insert(btPosition, bt); + this->impl->IncludeDirectoriesEntries.insert(position, entry); + this->impl->IncludeDirectoriesBacktraces.insert(btPosition, bt); } void cmTarget::InsertCompileOption(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - auto position = before ? impl->CompileOptionsEntries.begin() - : impl->CompileOptionsEntries.end(); + auto position = before ? this->impl->CompileOptionsEntries.begin() + : this->impl->CompileOptionsEntries.end(); - auto btPosition = before ? impl->CompileOptionsBacktraces.begin() - : impl->CompileOptionsBacktraces.end(); + auto btPosition = before ? this->impl->CompileOptionsBacktraces.begin() + : this->impl->CompileOptionsBacktraces.end(); - impl->CompileOptionsEntries.insert(position, entry); - impl->CompileOptionsBacktraces.insert(btPosition, bt); + this->impl->CompileOptionsEntries.insert(position, entry); + this->impl->CompileOptionsBacktraces.insert(btPosition, bt); } void cmTarget::InsertCompileDefinition(std::string const& entry, cmListFileBacktrace const& bt) { - impl->CompileDefinitionsEntries.push_back(entry); - impl->CompileDefinitionsBacktraces.push_back(bt); + this->impl->CompileDefinitionsEntries.push_back(entry); + this->impl->CompileDefinitionsBacktraces.push_back(bt); } void cmTarget::InsertLinkOption(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - auto position = - before ? impl->LinkOptionsEntries.begin() : impl->LinkOptionsEntries.end(); + auto position = before ? this->impl->LinkOptionsEntries.begin() + : this->impl->LinkOptionsEntries.end(); - auto btPosition = before ? impl->LinkOptionsBacktraces.begin() - : impl->LinkOptionsBacktraces.end(); + auto btPosition = before ? this->impl->LinkOptionsBacktraces.begin() + : this->impl->LinkOptionsBacktraces.end(); - impl->LinkOptionsEntries.insert(position, entry); - impl->LinkOptionsBacktraces.insert(btPosition, bt); + this->impl->LinkOptionsEntries.insert(position, entry); + this->impl->LinkOptionsBacktraces.insert(btPosition, bt); } void cmTarget::InsertLinkDirectory(std::string const& entry, cmListFileBacktrace const& bt, bool before) { - auto position = before ? impl->LinkDirectoriesEntries.begin() - : impl->LinkDirectoriesEntries.end(); + auto position = before ? this->impl->LinkDirectoriesEntries.begin() + : this->impl->LinkDirectoriesEntries.end(); - auto btPosition = before ? impl->LinkDirectoriesBacktraces.begin() - : impl->LinkDirectoriesBacktraces.end(); + auto btPosition = before ? this->impl->LinkDirectoriesBacktraces.begin() + : this->impl->LinkDirectoriesBacktraces.end(); - impl->LinkDirectoriesEntries.insert(position, entry); - impl->LinkDirectoriesBacktraces.insert(btPosition, bt); + this->impl->LinkDirectoriesEntries.insert(position, entry); + this->impl->LinkDirectoriesBacktraces.insert(btPosition, bt); } void cmTarget::InsertPrecompileHeader(std::string const& entry, cmListFileBacktrace const& bt) { - impl->PrecompileHeadersEntries.push_back(entry); - impl->PrecompileHeadersBacktraces.push_back(bt); + this->impl->PrecompileHeadersEntries.push_back(entry); + this->impl->PrecompileHeadersBacktraces.push_back(bt); } static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop, @@ -1721,19 +1728,19 @@ cmProp cmTarget::GetProperty(const std::string& prop) const if (prop == propC_STANDARD || prop == propCXX_STANDARD || prop == propCUDA_STANDARD || prop == propOBJC_STANDARD || prop == propOBJCXX_STANDARD) { - auto propertyIter = impl->LanguageStandardProperties.find(prop); - if (propertyIter == impl->LanguageStandardProperties.end()) { + auto propertyIter = this->impl->LanguageStandardProperties.find(prop); + if (propertyIter == this->impl->LanguageStandardProperties.end()) { return nullptr; } return &(propertyIter->second.Value); } if (prop == propLINK_LIBRARIES) { - if (impl->LinkImplementationPropertyEntries.empty()) { + if (this->impl->LinkImplementationPropertyEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->LinkImplementationPropertyEntries, ";"); + output = cmJoin(this->impl->LinkImplementationPropertyEntries, ";"); return &output; } // the type property returns what type the target is @@ -1741,70 +1748,71 @@ cmProp cmTarget::GetProperty(const std::string& prop) const return &cmState::GetTargetTypeName(this->GetType()); } if (prop == propINCLUDE_DIRECTORIES) { - if (impl->IncludeDirectoriesEntries.empty()) { + if (this->impl->IncludeDirectoriesEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->IncludeDirectoriesEntries, ";"); + output = cmJoin(this->impl->IncludeDirectoriesEntries, ";"); return &output; } if (prop == propCOMPILE_FEATURES) { - if (impl->CompileFeaturesEntries.empty()) { + if (this->impl->CompileFeaturesEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->CompileFeaturesEntries, ";"); + output = cmJoin(this->impl->CompileFeaturesEntries, ";"); return &output; } if (prop == propCOMPILE_OPTIONS) { - if (impl->CompileOptionsEntries.empty()) { + if (this->impl->CompileOptionsEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->CompileOptionsEntries, ";"); + output = cmJoin(this->impl->CompileOptionsEntries, ";"); return &output; } if (prop == propCOMPILE_DEFINITIONS) { - if (impl->CompileDefinitionsEntries.empty()) { + if (this->impl->CompileDefinitionsEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->CompileDefinitionsEntries, ";"); + output = cmJoin(this->impl->CompileDefinitionsEntries, ";"); return &output; } if (prop == propLINK_OPTIONS) { - if (impl->LinkOptionsEntries.empty()) { + if (this->impl->LinkOptionsEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->LinkOptionsEntries, ";"); + output = cmJoin(this->impl->LinkOptionsEntries, ";"); return &output; } if (prop == propLINK_DIRECTORIES) { - if (impl->LinkDirectoriesEntries.empty()) { + if (this->impl->LinkDirectoriesEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->LinkDirectoriesEntries, ";"); + output = cmJoin(this->impl->LinkDirectoriesEntries, ";"); return &output; } if (prop == propMANUALLY_ADDED_DEPENDENCIES) { - if (impl->Utilities.empty()) { + if (this->impl->Utilities.empty()) { return nullptr; } static std::string output; static std::vector<std::string> utilities; - utilities.resize(impl->Utilities.size()); + utilities.resize(this->impl->Utilities.size()); std::transform( - impl->Utilities.cbegin(), impl->Utilities.cend(), utilities.begin(), + this->impl->Utilities.cbegin(), this->impl->Utilities.cend(), + utilities.begin(), [](const BT<std::pair<std::string, bool>>& item) -> std::string { return item.Value.first; }); @@ -1812,12 +1820,12 @@ cmProp cmTarget::GetProperty(const std::string& prop) const return &output; } if (prop == propPRECOMPILE_HEADERS) { - if (impl->PrecompileHeadersEntries.empty()) { + if (this->impl->PrecompileHeadersEntries.empty()) { return nullptr; } static std::string output; - output = cmJoin(impl->PrecompileHeadersEntries, ";"); + output = cmJoin(this->impl->PrecompileHeadersEntries, ";"); return &output; } if (prop == propIMPORTED) { @@ -1830,24 +1838,25 @@ cmProp cmTarget::GetProperty(const std::string& prop) const return &this->GetName(); } if (prop == propBINARY_DIR) { - return &impl->Makefile->GetStateSnapshot() + return &this->impl->Makefile->GetStateSnapshot() .GetDirectory() .GetCurrentBinary(); } if (prop == propSOURCE_DIR) { - return &impl->Makefile->GetStateSnapshot() + return &this->impl->Makefile->GetStateSnapshot() .GetDirectory() .GetCurrentSource(); } } - cmProp retVal = impl->Properties.GetPropertyValue(prop); + cmProp retVal = this->impl->Properties.GetPropertyValue(prop); if (!retVal) { - const bool chain = - impl->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TARGET); + const bool chain = this->impl->Makefile->GetState()->IsPropertyChained( + prop, cmProperty::TARGET); if (chain) { - return impl->Makefile->GetStateSnapshot().GetDirectory().GetProperty( - prop, chain); + return this->impl->Makefile->GetStateSnapshot() + .GetDirectory() + .GetProperty(prop, chain); } return nullptr; } @@ -1872,32 +1881,32 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const cmPropertyMap const& cmTarget::GetProperties() const { - return impl->Properties; + return this->impl->Properties; } bool cmTarget::IsDLLPlatform() const { - return impl->IsDLLPlatform; + return this->impl->IsDLLPlatform; } bool cmTarget::IsAIX() const { - return impl->IsAIX; + return this->impl->IsAIX; } bool cmTarget::IsImported() const { - return impl->IsImportedTarget; + return this->impl->IsImportedTarget; } bool cmTarget::IsImportedGloballyVisible() const { - return impl->ImportedGloballyVisible; + return this->impl->ImportedGloballyVisible; } bool cmTarget::IsPerConfig() const { - return impl->PerConfig; + return this->impl->PerConfig; } bool cmTarget::CanCompileSources() const @@ -1952,8 +1961,8 @@ const char* cmTarget::GetSuffixVariableInternal( ? "CMAKE_SHARED_LIBRARY_SUFFIX" : "CMAKE_EXECUTABLE_SUFFIX"); case cmStateEnums::ImportLibraryArtifact: - return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX" - : "CMAKE_IMPORT_LIBRARY_SUFFIX"); + return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX" + : "CMAKE_IMPORT_LIBRARY_SUFFIX"); } break; default: @@ -1993,8 +2002,8 @@ const char* cmTarget::GetPrefixVariableInternal( ? "CMAKE_SHARED_LIBRARY_PREFIX" : ""); case cmStateEnums::ImportLibraryArtifact: - return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX" - : "CMAKE_IMPORT_LIBRARY_PREFIX"); + return (this->impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX" + : "CMAKE_IMPORT_LIBRARY_PREFIX"); } break; default: @@ -2076,7 +2085,7 @@ std::string cmTarget::ImportedGetFullPath( switch (this->GetPolicyStatus(cmPolicies::CMP0111)) { case cmPolicies::WARN: - impl->Makefile->IssueMessage( + this->impl->Makefile->IssueMessage( MessageType::AUTHOR_WARNING, cmPolicies::GetPolicyWarning(cmPolicies::CMP0111) + "\n" + message()); @@ -2084,7 +2093,8 @@ std::string cmTarget::ImportedGetFullPath( case cmPolicies::OLD: break; default: - impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, message()); + this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, + message()); } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 27f0c59..3066eb2 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -172,7 +172,7 @@ public: void SetProperty(const std::string& prop, const char* value); void SetProperty(const std::string& prop, const std::string& value) { - SetProperty(prop, value.c_str()); + this->SetProperty(prop, value.c_str()); } void AppendProperty(const std::string& prop, const std::string& value, bool asString = false); diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx index bf4cc09..3897499 100644 --- a/Source/cmTargetIncludeDirectoriesCommand.cxx +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -84,8 +84,8 @@ void TargetIncludeDirectoriesImpl::HandleInterfaceContent( cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool system) { - cmTargetPropCommandBase::HandleInterfaceContent(tgt, content, prepend, - system); + this->cmTargetPropCommandBase::HandleInterfaceContent(tgt, content, prepend, + system); if (system) { std::string joined = this->Join(content); tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined); diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx index 0670bd9..a5066cc 100644 --- a/Source/cmTargetPrecompileHeadersCommand.cxx +++ b/Source/cmTargetPrecompileHeadersCommand.cxx @@ -57,7 +57,7 @@ private: bool prepend, bool system) override { std::string const& base = this->Makefile->GetCurrentSourceDirectory(); - cmTargetPropCommandBase::HandleInterfaceContent( + this->cmTargetPropCommandBase::HandleInterfaceContent( tgt, ConvertToAbsoluteContent(content, base), prepend, system); } diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx index a1fbc9b..26282ef 100644 --- a/Source/cmTargetSourcesCommand.cxx +++ b/Source/cmTargetSourcesCommand.cxx @@ -25,8 +25,9 @@ protected: const std::vector<std::string>& content, bool prepend, bool system) override { - cmTargetPropCommandBase::HandleInterfaceContent( - tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system); + this->cmTargetPropCommandBase::HandleInterfaceContent( + tgt, this->ConvertToAbsoluteContent(tgt, content, true), prepend, + system); } private: @@ -43,7 +44,8 @@ private: bool /*prepend*/, bool /*system*/) override { tgt->AppendProperty( - "SOURCES", this->Join(ConvertToAbsoluteContent(tgt, content, false))); + "SOURCES", + this->Join(this->ConvertToAbsoluteContent(tgt, content, false))); return true; // Successfully handled. } diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index da4593f..7022c4e 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -147,7 +147,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, // Evaluate command line arguments std::vector<std::string> argv = - EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config); + this->EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config); // Expand arguments if COMMAND_EXPAND_LISTS is set if (this->Test->GetCommandExpandLists()) { diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 67f7e11..7fb69bf 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -38,7 +38,7 @@ std::string cmTimestamp::CurrentTime(const std::string& formatString, return std::string(); } - return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag); + return this->CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag); } std::string cmTimestamp::FileModificationTime(const char* path, @@ -53,7 +53,7 @@ std::string cmTimestamp::FileModificationTime(const char* path, } time_t mtime = cmsys::SystemTools::ModifiedTime(real_path); - return CreateTimestampFromTimeT(mtime, formatString, utcFlag); + return this->CreateTimestampFromTimeT(mtime, formatString, utcFlag); } std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, @@ -90,7 +90,7 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, : static_cast<char>(0); if (c1 == '%' && c2 != 0) { - result += AddTimestampComponent(c2, timeStruct, timeT); + result += this->AddTimestampComponent(c2, timeStruct, timeT); ++i; } else { result += c1; diff --git a/Source/cmTransformDepfile.cxx b/Source/cmTransformDepfile.cxx index b91e1ce..78aa4b2 100644 --- a/Source/cmTransformDepfile.cxx +++ b/Source/cmTransformDepfile.cxx @@ -13,6 +13,7 @@ #include "cmGccDepfileReader.h" #include "cmGccDepfileReaderTypes.h" +#include "cmLocalGenerator.h" #include "cmSystemTools.h" namespace { @@ -33,8 +34,11 @@ void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename) } } -void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content) +void WriteGccDepfile(cmsys::ofstream& fout, const cmLocalGenerator& lg, + const cmGccDepfileContent& content) { + const auto& binDir = lg.GetBinaryDirectory(); + for (auto const& dep : content) { bool first = true; for (auto const& rule : dep.rules) { @@ -42,19 +46,32 @@ void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content) fout << " \\\n "; } first = false; - WriteFilenameGcc(fout, rule); + WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, rule)); } fout << ':'; for (auto const& path : dep.paths) { fout << " \\\n "; - WriteFilenameGcc(fout, path); + WriteFilenameGcc(fout, lg.MaybeConvertToRelativePath(binDir, path)); } fout << '\n'; } } -void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content) +// tlog format : always windows paths on Windows regardless the generator +std::string ConvertToTLogOutputPath(const std::string& path) { +#if defined(_WIN32) && !defined(__CYGWIN__) + return cmSystemTools::ConvertToWindowsOutputPath(path); +#else + return cmSystemTools::ConvertToOutputPath(path); +#endif +} + +void WriteVsTlog(cmsys::ofstream& fout, const cmLocalGenerator& lg, + const cmGccDepfileContent& content) +{ + const auto& binDir = lg.GetBinaryDirectory(); + for (auto const& dep : content) { fout << '^'; bool first = true; @@ -63,22 +80,26 @@ void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content) fout << '|'; } first = false; - fout << cmSystemTools::ConvertToOutputPath(rule); + fout << ConvertToTLogOutputPath( + lg.MaybeConvertToRelativePath(binDir, rule)); } fout << "\r\n"; for (auto const& path : dep.paths) { - fout << cmSystemTools::ConvertToOutputPath(path) << "\r\n"; + fout << ConvertToTLogOutputPath( + lg.MaybeConvertToRelativePath(binDir, path)) + << "\r\n"; } } } } -bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix, +bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, const std::string& infile, const std::string& outfile) { cmGccDepfileContent content; if (cmSystemTools::FileExists(infile)) { - auto result = cmReadGccDepfile(infile.c_str(), prefix); + auto result = + cmReadGccDepfile(infile.c_str(), lg.GetCurrentBinaryDirectory()); if (!result) { return false; } @@ -91,10 +112,10 @@ bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix, } switch (format) { case cmDepfileFormat::GccDepfile: - WriteGccDepfile(fout, content); + WriteGccDepfile(fout, lg, content); break; case cmDepfileFormat::VsTlog: - WriteVsTlog(fout, content); + WriteVsTlog(fout, lg, content); break; } return true; diff --git a/Source/cmTransformDepfile.h b/Source/cmTransformDepfile.h index 792c1aa..c43a45f 100644 --- a/Source/cmTransformDepfile.h +++ b/Source/cmTransformDepfile.h @@ -10,5 +10,7 @@ enum class cmDepfileFormat VsTlog, }; -bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix, +class cmLocalGenerator; + +bool cmTransformDepfile(cmDepfileFormat format, const cmLocalGenerator& lg, const std::string& infile, const std::string& outfile); diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx index df2f64e..e556a11 100644 --- a/Source/cmUVHandlePtr.cxx +++ b/Source/cmUVHandlePtr.cxx @@ -80,7 +80,7 @@ struct uv_handle_deleter template <typename T> void uv_handle_ptr_base_<T>::allocate(void* data) { - reset(); + this->reset(); /* We use calloc since we know all these types are c structs @@ -88,32 +88,33 @@ void uv_handle_ptr_base_<T>::allocate(void* data) but casting from uv_handle_t to certain other types -- namely uv_timer_t -- triggers a cast_align warning on certain systems. */ - handle.reset(static_cast<T*>(calloc(1, sizeof(T))), uv_handle_deleter<T>()); - handle->data = data; + this->handle.reset(static_cast<T*>(calloc(1, sizeof(T))), + uv_handle_deleter<T>()); + this->handle->data = data; } template <typename T> void uv_handle_ptr_base_<T>::reset() { - handle.reset(); + this->handle.reset(); } template <typename T> uv_handle_ptr_base_<T>::operator uv_handle_t*() { - return reinterpret_cast<uv_handle_t*>(handle.get()); + return reinterpret_cast<uv_handle_t*>(this->handle.get()); } template <typename T> T* uv_handle_ptr_base_<T>::operator->() const noexcept { - return handle.get(); + return this->handle.get(); } template <typename T> T* uv_handle_ptr_base_<T>::get() const { - return handle.get(); + return this->handle.get(); } template <typename T> @@ -146,7 +147,7 @@ struct uv_handle_deleter<uv_async_t> void operator()(uv_async_t* handle) { - std::lock_guard<std::mutex> lock(*handleMutex); + std::lock_guard<std::mutex> lock(*this->handleMutex); handle_default_delete(handle); } }; @@ -164,8 +165,8 @@ void uv_async_ptr::send() int uv_async_ptr::init(uv_loop_t& loop, uv_async_cb async_cb, void* data) { - allocate(data); - return uv_async_init(&loop, handle.get(), async_cb); + this->allocate(data); + return uv_async_init(&loop, this->handle.get(), async_cb); } #endif @@ -183,62 +184,62 @@ struct uv_handle_deleter<uv_signal_t> int uv_signal_ptr::init(uv_loop_t& loop, void* data) { - allocate(data); - return uv_signal_init(&loop, handle.get()); + this->allocate(data); + return uv_signal_init(&loop, this->handle.get()); } int uv_signal_ptr::start(uv_signal_cb cb, int signum) { - assert(handle); + assert(this->handle); return uv_signal_start(*this, cb, signum); } void uv_signal_ptr::stop() { - if (handle) { + if (this->handle) { uv_signal_stop(*this); } } int uv_pipe_ptr::init(uv_loop_t& loop, int ipc, void* data) { - allocate(data); + this->allocate(data); return uv_pipe_init(&loop, *this, ipc); } uv_pipe_ptr::operator uv_stream_t*() const { - return reinterpret_cast<uv_stream_t*>(handle.get()); + return reinterpret_cast<uv_stream_t*>(this->handle.get()); } int uv_process_ptr::spawn(uv_loop_t& loop, uv_process_options_t const& options, void* data) { - allocate(data); + this->allocate(data); return uv_spawn(&loop, *this, &options); } int uv_timer_ptr::init(uv_loop_t& loop, void* data) { - allocate(data); + this->allocate(data); return uv_timer_init(&loop, *this); } int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat) { - assert(handle); + assert(this->handle); return uv_timer_start(*this, cb, timeout, repeat); } #ifndef CMAKE_BOOTSTRAP uv_tty_ptr::operator uv_stream_t*() const { - return reinterpret_cast<uv_stream_t*>(handle.get()); + return reinterpret_cast<uv_stream_t*>(this->handle.get()); } int uv_tty_ptr::init(uv_loop_t& loop, int fd, int readable, void* data) { - allocate(data); + this->allocate(data); return uv_tty_init(&loop, *this, fd, readable); } #endif diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h index d9de7f3..356e227 100644 --- a/Source/cmUVHandlePtr.h +++ b/Source/cmUVHandlePtr.h @@ -128,7 +128,7 @@ public: // dtors to work. Some compilers do not like '= default' here. uv_handle_ptr_base_() {} // NOLINT(modernize-use-equals-default) uv_handle_ptr_base_(std::nullptr_t) {} - ~uv_handle_ptr_base_() { reset(); } + ~uv_handle_ptr_base_() { this->reset(); } /** * Properly close the handle if needed and sets the inner handle to nullptr diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx index cd52b3f..2513303 100644 --- a/Source/cmUuid.cxx +++ b/Source/cmUuid.cxx @@ -82,7 +82,7 @@ bool cmUuid::StringToBinary(std::string const& input, return false; } size_t digits = kUuidGroups[i] * 2; - if (!StringToBinaryImpl(input.substr(index, digits), output)) { + if (!this->StringToBinaryImpl(input.substr(index, digits), output)) { return false; } @@ -134,12 +134,12 @@ bool cmUuid::StringToBinaryImpl(std::string const& input, for (size_t i = 0; i < input.size(); i += 2) { char c1 = 0; - if (!IntFromHexDigit(input[i], c1)) { + if (!this->IntFromHexDigit(input[i], c1)) { return false; } char c2 = 0; - if (!IntFromHexDigit(input[i + 1], c2)) { + if (!this->IntFromHexDigit(input[i + 1], c2)) { return false; } diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9c41504..a93a78a 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1897,8 +1897,15 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1, } // Figure out if there's any additional flags to use if (cmProp saf = sf->GetProperty("VS_SHADER_FLAGS")) { + cmGeneratorExpression ge; + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*saf); + for (const std::string& config : this->Configurations) { - toolSettings[config]["AdditionalOptions"] = *saf; + std::string evaluated = cge->Evaluate(this->LocalGenerator, config); + + if (!evaluated.empty()) { + toolSettings[config]["AdditionalOptions"] = evaluated; + } } } // Figure out if debug information should be generated diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx index 12aba4f..f2c091f 100644 --- a/Source/cmWorkerPool.cxx +++ b/Source/cmWorkerPool.cxx @@ -50,11 +50,14 @@ public: bool startRead(DataFunction dataFunction, EndFunction endFunction); //! libuv pipe - uv_pipe_t* uv_pipe() const { return UVPipe_.get(); } + uv_pipe_t* uv_pipe() const { return this->UVPipe_.get(); } //! uv_pipe() casted to libuv stream - uv_stream_t* uv_stream() const { return static_cast<uv_stream_t*>(UVPipe_); } + uv_stream_t* uv_stream() const + { + return static_cast<uv_stream_t*>(this->UVPipe_); + } //! uv_pipe() casted to libuv handle - uv_handle_t* uv_handle() { return static_cast<uv_handle_t*>(UVPipe_); } + uv_handle_t* uv_handle() { return static_cast<uv_handle_t*>(this->UVPipe_); } private: // -- Libuv callbacks @@ -71,37 +74,37 @@ private: void cmUVPipeBuffer::reset() { - if (UVPipe_.get() != nullptr) { - EndFunction_ = nullptr; - DataFunction_ = nullptr; - Buffer_.clear(); - Buffer_.shrink_to_fit(); - UVPipe_.reset(); + if (this->UVPipe_.get() != nullptr) { + this->EndFunction_ = nullptr; + this->DataFunction_ = nullptr; + this->Buffer_.clear(); + this->Buffer_.shrink_to_fit(); + this->UVPipe_.reset(); } } bool cmUVPipeBuffer::init(uv_loop_t* uv_loop) { - reset(); + this->reset(); if (uv_loop == nullptr) { return false; } - int ret = UVPipe_.init(*uv_loop, 0, this); + int ret = this->UVPipe_.init(*uv_loop, 0, this); return (ret == 0); } bool cmUVPipeBuffer::startRead(DataFunction dataFunction, EndFunction endFunction) { - if (UVPipe_.get() == nullptr) { + if (this->UVPipe_.get() == nullptr) { return false; } if (!dataFunction || !endFunction) { return false; } - DataFunction_ = std::move(dataFunction); - EndFunction_ = std::move(endFunction); - int ret = uv_read_start(uv_stream(), &cmUVPipeBuffer::UVAlloc, + this->DataFunction_ = std::move(dataFunction); + this->EndFunction_ = std::move(endFunction); + int ret = uv_read_start(this->uv_stream(), &cmUVPipeBuffer::UVAlloc, &cmUVPipeBuffer::UVData); return (ret == 0); } @@ -153,10 +156,10 @@ public: public: // -- Const accessors - SetupT const& Setup() const { return Setup_; } - cmWorkerPool::ProcessResultT* Result() const { return Setup_.Result; } - bool IsStarted() const { return IsStarted_; } - bool IsFinished() const { return IsFinished_; } + SetupT const& Setup() const { return this->Setup_; } + cmWorkerPool::ProcessResultT* Result() const { return this->Setup_.Result; } + bool IsStarted() const { return this->IsStarted_; } + bool IsFinished() const { return this->IsFinished_; } // -- Runtime void setup(cmWorkerPool::ProcessResultT* result, bool mergedOutput, @@ -193,109 +196,113 @@ void cmUVReadOnlyProcess::setup(cmWorkerPool::ProcessResultT* result, std::vector<std::string> const& command, std::string const& workingDirectory) { - Setup_.WorkingDirectory = workingDirectory; - Setup_.Command = command; - Setup_.Result = result; - Setup_.MergedOutput = mergedOutput; + this->Setup_.WorkingDirectory = workingDirectory; + this->Setup_.Command = command; + this->Setup_.Result = result; + this->Setup_.MergedOutput = mergedOutput; } bool cmUVReadOnlyProcess::start(uv_loop_t* uv_loop, std::function<void()> finishedCallback) { - if (IsStarted() || (Result() == nullptr)) { + if (this->IsStarted() || (this->Result() == nullptr)) { return false; } // Reset result before the start - Result()->reset(); + this->Result()->reset(); // Fill command string pointers - if (!Setup().Command.empty()) { - CommandPtr_.reserve(Setup().Command.size() + 1); - for (std::string const& arg : Setup().Command) { - CommandPtr_.push_back(arg.c_str()); + if (!this->Setup().Command.empty()) { + this->CommandPtr_.reserve(this->Setup().Command.size() + 1); + for (std::string const& arg : this->Setup().Command) { + this->CommandPtr_.push_back(arg.c_str()); } - CommandPtr_.push_back(nullptr); + this->CommandPtr_.push_back(nullptr); } else { - Result()->ErrorMessage = "Empty command"; + this->Result()->ErrorMessage = "Empty command"; } - if (!Result()->error()) { - if (!UVPipeOut_.init(uv_loop)) { - Result()->ErrorMessage = "libuv stdout pipe initialization failed"; + if (!this->Result()->error()) { + if (!this->UVPipeOut_.init(uv_loop)) { + this->Result()->ErrorMessage = "libuv stdout pipe initialization failed"; } } - if (!Result()->error()) { - if (!UVPipeErr_.init(uv_loop)) { - Result()->ErrorMessage = "libuv stderr pipe initialization failed"; + if (!this->Result()->error()) { + if (!this->UVPipeErr_.init(uv_loop)) { + this->Result()->ErrorMessage = "libuv stderr pipe initialization failed"; } } - if (!Result()->error()) { + if (!this->Result()->error()) { // -- Setup process stdio options // stdin - UVOptionsStdIO_[0].flags = UV_IGNORE; - UVOptionsStdIO_[0].data.stream = nullptr; + this->UVOptionsStdIO_[0].flags = UV_IGNORE; + this->UVOptionsStdIO_[0].data.stream = nullptr; // stdout - UVOptionsStdIO_[1].flags = + this->UVOptionsStdIO_[1].flags = static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE); - UVOptionsStdIO_[1].data.stream = UVPipeOut_.uv_stream(); + this->UVOptionsStdIO_[1].data.stream = this->UVPipeOut_.uv_stream(); // stderr - UVOptionsStdIO_[2].flags = + this->UVOptionsStdIO_[2].flags = static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE); - UVOptionsStdIO_[2].data.stream = UVPipeErr_.uv_stream(); + this->UVOptionsStdIO_[2].data.stream = this->UVPipeErr_.uv_stream(); // -- Setup process options - std::fill_n(reinterpret_cast<char*>(&UVOptions_), sizeof(UVOptions_), 0); - UVOptions_.exit_cb = &cmUVReadOnlyProcess::UVExit; - UVOptions_.file = CommandPtr_[0]; - UVOptions_.args = const_cast<char**>(CommandPtr_.data()); - UVOptions_.cwd = Setup_.WorkingDirectory.c_str(); - UVOptions_.flags = UV_PROCESS_WINDOWS_HIDE; - UVOptions_.stdio_count = static_cast<int>(UVOptionsStdIO_.size()); - UVOptions_.stdio = UVOptionsStdIO_.data(); + std::fill_n(reinterpret_cast<char*>(&this->UVOptions_), + sizeof(this->UVOptions_), 0); + this->UVOptions_.exit_cb = &cmUVReadOnlyProcess::UVExit; + this->UVOptions_.file = this->CommandPtr_[0]; + this->UVOptions_.args = const_cast<char**>(this->CommandPtr_.data()); + this->UVOptions_.cwd = this->Setup_.WorkingDirectory.c_str(); + this->UVOptions_.flags = UV_PROCESS_WINDOWS_HIDE; + this->UVOptions_.stdio_count = + static_cast<int>(this->UVOptionsStdIO_.size()); + this->UVOptions_.stdio = this->UVOptionsStdIO_.data(); // -- Spawn process - int uvErrorCode = UVProcess_.spawn(*uv_loop, UVOptions_, this); + int uvErrorCode = this->UVProcess_.spawn(*uv_loop, this->UVOptions_, this); if (uvErrorCode != 0) { - Result()->ErrorMessage = "libuv process spawn failed"; + this->Result()->ErrorMessage = "libuv process spawn failed"; if (const char* uvErr = uv_strerror(uvErrorCode)) { - Result()->ErrorMessage += ": "; - Result()->ErrorMessage += uvErr; + this->Result()->ErrorMessage += ": "; + this->Result()->ErrorMessage += uvErr; } } } // -- Start reading from stdio streams - if (!Result()->error()) { - if (!UVPipeOut_.startRead( + if (!this->Result()->error()) { + if (!this->UVPipeOut_.startRead( [this](cmUVPipeBuffer::DataRange range) { this->UVPipeOutData(range); }, [this](ssize_t error) { this->UVPipeOutEnd(error); })) { - Result()->ErrorMessage = "libuv start reading from stdout pipe failed"; + this->Result()->ErrorMessage = + "libuv start reading from stdout pipe failed"; } } - if (!Result()->error()) { - if (!UVPipeErr_.startRead( + if (!this->Result()->error()) { + if (!this->UVPipeErr_.startRead( [this](cmUVPipeBuffer::DataRange range) { this->UVPipeErrData(range); }, [this](ssize_t error) { this->UVPipeErrEnd(error); })) { - Result()->ErrorMessage = "libuv start reading from stderr pipe failed"; + this->Result()->ErrorMessage = + "libuv start reading from stderr pipe failed"; } } - if (!Result()->error()) { - IsStarted_ = true; - FinishedCallback_ = std::move(finishedCallback); + if (!this->Result()->error()) { + this->IsStarted_ = true; + this->FinishedCallback_ = std::move(finishedCallback); } else { // Clear libuv handles and finish - UVProcess_.reset(); - UVPipeOut_.reset(); - UVPipeErr_.reset(); - CommandPtr_.clear(); + this->UVProcess_.reset(); + this->UVPipeOut_.reset(); + this->UVPipeErr_.reset(); + this->CommandPtr_.clear(); } - return IsStarted(); + return this->IsStarted(); } void cmUVReadOnlyProcess::UVExit(uv_process_t* handle, int64_t exitStatus, @@ -325,36 +332,36 @@ void cmUVReadOnlyProcess::UVExit(uv_process_t* handle, int64_t exitStatus, void cmUVReadOnlyProcess::UVPipeOutData(cmUVPipeBuffer::DataRange data) { - Result()->StdOut.append(data.begin(), data.end()); + this->Result()->StdOut.append(data.begin(), data.end()); } void cmUVReadOnlyProcess::UVPipeOutEnd(ssize_t error) { // Process pipe error - if ((error != 0) && !Result()->error()) { - Result()->ErrorMessage = cmStrCat( + if ((error != 0) && !this->Result()->error()) { + this->Result()->ErrorMessage = cmStrCat( "Reading from stdout pipe failed with libuv error code ", error); } // Try finish - UVTryFinish(); + this->UVTryFinish(); } void cmUVReadOnlyProcess::UVPipeErrData(cmUVPipeBuffer::DataRange data) { - std::string* str = - Setup_.MergedOutput ? &Result()->StdOut : &Result()->StdErr; + std::string* str = this->Setup_.MergedOutput ? &this->Result()->StdOut + : &this->Result()->StdErr; str->append(data.begin(), data.end()); } void cmUVReadOnlyProcess::UVPipeErrEnd(ssize_t error) { // Process pipe error - if ((error != 0) && !Result()->error()) { - Result()->ErrorMessage = cmStrCat( + if ((error != 0) && !this->Result()->error()) { + this->Result()->ErrorMessage = cmStrCat( "Reading from stderr pipe failed with libuv error code ", error); } // Try finish - UVTryFinish(); + this->UVTryFinish(); } void cmUVReadOnlyProcess::UVTryFinish() @@ -362,12 +369,13 @@ void cmUVReadOnlyProcess::UVTryFinish() // There still might be data in the pipes after the process has finished. // Therefore check if the process is finished AND all pipes are closed // before signaling the worker thread to continue. - if ((UVProcess_.get() != nullptr) || (UVPipeOut_.uv_pipe() != nullptr) || - (UVPipeErr_.uv_pipe() != nullptr)) { + if ((this->UVProcess_.get() != nullptr) || + (this->UVPipeOut_.uv_pipe() != nullptr) || + (this->UVPipeErr_.uv_pipe() != nullptr)) { return; } - IsFinished_ = true; - FinishedCallback_(); + this->IsFinished_ = true; + this->FinishedCallback_(); } /** @@ -385,7 +393,7 @@ public: /** * Set the internal thread */ - void SetThread(std::thread&& aThread) { Thread_ = std::move(aThread); } + void SetThread(std::thread&& aThread) { this->Thread_ = std::move(aThread); } /** * Run an external process @@ -414,13 +422,13 @@ private: cmWorkerPoolWorker::cmWorkerPoolWorker(uv_loop_t& uvLoop) { - Proc_.Request.init(uvLoop, &cmWorkerPoolWorker::UVProcessStart, this); + this->Proc_.Request.init(uvLoop, &cmWorkerPoolWorker::UVProcessStart, this); } cmWorkerPoolWorker::~cmWorkerPoolWorker() { - if (Thread_.joinable()) { - Thread_.join(); + if (this->Thread_.joinable()) { + this->Thread_.join(); } } @@ -433,17 +441,17 @@ bool cmWorkerPoolWorker::RunProcess(cmWorkerPool::ProcessResultT& result, } // Create process instance { - std::lock_guard<std::mutex> lock(Proc_.Mutex); - Proc_.ROP = cm::make_unique<cmUVReadOnlyProcess>(); - Proc_.ROP->setup(&result, true, command, workingDirectory); + std::lock_guard<std::mutex> lock(this->Proc_.Mutex); + this->Proc_.ROP = cm::make_unique<cmUVReadOnlyProcess>(); + this->Proc_.ROP->setup(&result, true, command, workingDirectory); } // Send asynchronous process start request to libuv loop - Proc_.Request.send(); + this->Proc_.Request.send(); // Wait until the process has been finished and destroyed { - std::unique_lock<std::mutex> ulock(Proc_.Mutex); - while (Proc_.ROP) { - Proc_.Condition.wait(ulock); + std::unique_lock<std::mutex> ulock(this->Proc_.Mutex); + while (this->Proc_.ROP) { + this->Proc_.Condition.wait(ulock); } } return !result.error(); @@ -469,12 +477,13 @@ void cmWorkerPoolWorker::UVProcessStart(uv_async_t* handle) void cmWorkerPoolWorker::UVProcessFinished() { - std::lock_guard<std::mutex> lock(Proc_.Mutex); - if (Proc_.ROP && (Proc_.ROP->IsFinished() || !Proc_.ROP->IsStarted())) { - Proc_.ROP.reset(); + std::lock_guard<std::mutex> lock(this->Proc_.Mutex); + if (this->Proc_.ROP && + (this->Proc_.ROP->IsFinished() || !this->Proc_.ROP->IsStarted())) { + this->Proc_.ROP.reset(); } // Notify idling thread - Proc_.Condition.notify_one(); + this->Proc_.Condition.notify_one(); } /** @@ -539,19 +548,19 @@ public: void cmWorkerPool::ProcessResultT::reset() { - ExitStatus = 0; - TermSignal = 0; - if (!StdOut.empty()) { - StdOut.clear(); - StdOut.shrink_to_fit(); + this->ExitStatus = 0; + this->TermSignal = 0; + if (!this->StdOut.empty()) { + this->StdOut.clear(); + this->StdOut.shrink_to_fit(); } - if (!StdErr.empty()) { - StdErr.clear(); - StdErr.shrink_to_fit(); + if (!this->StdErr.empty()) { + this->StdErr.clear(); + this->StdErr.shrink_to_fit(); } - if (!ErrorMessage.empty()) { - ErrorMessage.clear(); - ErrorMessage.shrink_to_fit(); + if (!this->ErrorMessage.empty()) { + this->ErrorMessage.clear(); + this->ErrorMessage.shrink_to_fit(); } } @@ -563,56 +572,58 @@ cmWorkerPoolInternal::cmWorkerPoolInternal(cmWorkerPool* pool) #ifdef CMAKE_UV_SIGNAL_HACK UVHackRAII = cm::make_unique<cmUVSignalHackRAII>(); #endif - UVLoop = cm::make_unique<uv_loop_t>(); - uv_loop_init(UVLoop.get()); + this->UVLoop = cm::make_unique<uv_loop_t>(); + uv_loop_init(this->UVLoop.get()); } cmWorkerPoolInternal::~cmWorkerPoolInternal() { - uv_loop_close(UVLoop.get()); + uv_loop_close(this->UVLoop.get()); } bool cmWorkerPoolInternal::Process() { // Reset state flags - Processing = true; - Aborting = false; + this->Processing = true; + this->Aborting = false; // Initialize libuv asynchronous request - UVRequestBegin.init(*UVLoop, &cmWorkerPoolInternal::UVSlotBegin, this); - UVRequestEnd.init(*UVLoop, &cmWorkerPoolInternal::UVSlotEnd, this); + this->UVRequestBegin.init(*this->UVLoop, &cmWorkerPoolInternal::UVSlotBegin, + this); + this->UVRequestEnd.init(*this->UVLoop, &cmWorkerPoolInternal::UVSlotEnd, + this); // Send begin request - UVRequestBegin.send(); + this->UVRequestBegin.send(); // Run libuv loop - bool success = (uv_run(UVLoop.get(), UV_RUN_DEFAULT) == 0); + bool success = (uv_run(this->UVLoop.get(), UV_RUN_DEFAULT) == 0); // Update state flags - Processing = false; - Aborting = false; + this->Processing = false; + this->Aborting = false; return success; } void cmWorkerPoolInternal::Abort() { // Clear all jobs and set abort flag - std::lock_guard<std::mutex> guard(Mutex); - if (!Aborting) { + std::lock_guard<std::mutex> guard(this->Mutex); + if (!this->Aborting) { // Register abort and clear queue - Aborting = true; - Queue.clear(); - Condition.notify_all(); + this->Aborting = true; + this->Queue.clear(); + this->Condition.notify_all(); } } inline bool cmWorkerPoolInternal::PushJob(cmWorkerPool::JobHandleT&& jobHandle) { - std::lock_guard<std::mutex> guard(Mutex); - if (Aborting) { + std::lock_guard<std::mutex> guard(this->Mutex); + if (this->Aborting) { return false; } // Append the job to the queue - Queue.emplace_back(std::move(jobHandle)); + this->Queue.emplace_back(std::move(jobHandle)); // Notify an idle worker if there's one - if (WorkersIdle != 0) { - Condition.notify_one(); + if (this->WorkersIdle != 0) { + this->Condition.notify_one(); } // Return success return true; @@ -652,79 +663,79 @@ void cmWorkerPoolInternal::UVSlotEnd(uv_async_t* handle) void cmWorkerPoolInternal::Work(unsigned int workerIndex) { cmWorkerPool::JobHandleT jobHandle; - std::unique_lock<std::mutex> uLock(Mutex); + std::unique_lock<std::mutex> uLock(this->Mutex); // Increment running workers count - ++WorkersRunning; + ++this->WorkersRunning; // Enter worker main loop while (true) { // Abort on request - if (Aborting) { + if (this->Aborting) { break; } // Wait for new jobs on the main CV - if (Queue.empty()) { - ++WorkersIdle; - Condition.wait(uLock); - --WorkersIdle; + if (this->Queue.empty()) { + ++this->WorkersIdle; + this->Condition.wait(uLock); + --this->WorkersIdle; continue; } // If there is a fence currently active or waiting, // sleep on the main CV and try again. - if (FenceProcessing) { - Condition.wait(uLock); + if (this->FenceProcessing) { + this->Condition.wait(uLock); continue; } // Pop next job from queue - jobHandle = std::move(Queue.front()); - Queue.pop_front(); + jobHandle = std::move(this->Queue.front()); + this->Queue.pop_front(); // Check for fence jobs bool raisedFence = false; if (jobHandle->IsFence()) { - FenceProcessing = true; + this->FenceProcessing = true; raisedFence = true; // Wait on the Fence CV until all pending jobs are done. - while (JobsProcessing != 0 && !Aborting) { - ConditionFence.wait(uLock); + while (this->JobsProcessing != 0 && !this->Aborting) { + this->ConditionFence.wait(uLock); } // When aborting, explicitly kick all threads alive once more. - if (Aborting) { - FenceProcessing = false; - Condition.notify_all(); + if (this->Aborting) { + this->FenceProcessing = false; + this->Condition.notify_all(); break; } } // Unlocked scope for job processing - ++JobsProcessing; + ++this->JobsProcessing; { uLock.unlock(); - jobHandle->Work(Pool, workerIndex); // Process job - jobHandle.reset(); // Destroy job + jobHandle->Work(this->Pool, workerIndex); // Process job + jobHandle.reset(); // Destroy job uLock.lock(); } - --JobsProcessing; + --this->JobsProcessing; // If this was the thread that entered fence processing // originally, notify all idling workers that the fence // is done. if (raisedFence) { - FenceProcessing = false; - Condition.notify_all(); + this->FenceProcessing = false; + this->Condition.notify_all(); } // If fence processing is still not done, notify the // the fencing worker when all active jobs are done. - if (FenceProcessing && JobsProcessing == 0) { - ConditionFence.notify_all(); + if (this->FenceProcessing && this->JobsProcessing == 0) { + this->ConditionFence.notify_all(); } } // Decrement running workers count - if (--WorkersRunning == 0) { + if (--this->WorkersRunning == 0) { // Last worker thread about to finish. Send libuv event. - UVRequestEnd.send(); + this->UVRequestEnd.send(); } } @@ -735,7 +746,7 @@ bool cmWorkerPool::JobT::RunProcess(ProcessResultT& result, std::string const& workingDirectory) { // Get worker by index - auto* wrk = Pool_->Int_->Workers.at(WorkerIndex_).get(); + auto* wrk = this->Pool_->Int_->Workers.at(this->WorkerIndex_).get(); return wrk->RunProcess(result, command, workingDirectory); } @@ -748,29 +759,29 @@ cmWorkerPool::~cmWorkerPool() = default; void cmWorkerPool::SetThreadCount(unsigned int threadCount) { - if (!Int_->Processing) { - ThreadCount_ = (threadCount > 0) ? threadCount : 1u; + if (!this->Int_->Processing) { + this->ThreadCount_ = (threadCount > 0) ? threadCount : 1u; } } bool cmWorkerPool::Process(void* userData) { // Setup user data - UserData_ = userData; + this->UserData_ = userData; // Run libuv loop - bool success = Int_->Process(); + bool success = this->Int_->Process(); // Clear user data - UserData_ = nullptr; + this->UserData_ = nullptr; // Return return success; } bool cmWorkerPool::PushJob(JobHandleT&& jobHandle) { - return Int_->PushJob(std::move(jobHandle)); + return this->Int_->PushJob(std::move(jobHandle)); } void cmWorkerPool::Abort() { - Int_->Abort(); + this->Int_->Abort(); } diff --git a/Source/cmWorkerPool.h b/Source/cmWorkerPool.h index 0fb6707..9082d7f 100644 --- a/Source/cmWorkerPool.h +++ b/Source/cmWorkerPool.h @@ -28,7 +28,8 @@ public: void reset(); bool error() const { - return (ExitStatus != 0) || (TermSignal != 0) || !ErrorMessage.empty(); + return (this->ExitStatus != 0) || (this->TermSignal != 0) || + !this->ErrorMessage.empty(); } std::int64_t ExitStatus = 0; @@ -60,7 +61,7 @@ public: * - no jobs later in the queue will be processed before this job was * processed */ - bool IsFence() const { return Fence_; } + bool IsFence() const { return this->Fence_; } protected: /** @@ -80,13 +81,13 @@ public: * Get the worker pool. * Only valid during the JobT::Process() call! */ - cmWorkerPool* Pool() const { return Pool_; } + cmWorkerPool* Pool() const { return this->Pool_; } /** * Get the user data. * Only valid during the JobT::Process() call! */ - void* UserData() const { return Pool_->UserData(); }; + void* UserData() const { return this->Pool_->UserData(); }; /** * Get the worker index. @@ -95,7 +96,7 @@ public: * Concurrently processing jobs will never have the same WorkerIndex(). * Only valid during the JobT::Process() call! */ - unsigned int WorkerIndex() const { return WorkerIndex_; } + unsigned int WorkerIndex() const { return this->WorkerIndex_; } /** * Run an external read only process. @@ -111,8 +112,8 @@ public: //! Worker thread entry method. void Work(cmWorkerPool* pool, unsigned int workerIndex) { - Pool_ = pool; - WorkerIndex_ = workerIndex; + this->Pool_ = pool; + this->WorkerIndex_ = workerIndex; this->Process(); } @@ -150,7 +151,7 @@ public: { public: //! Does nothing - void Process() override { Pool()->Abort(); } + void Process() override { this->Pool()->Abort(); } }; public: @@ -161,7 +162,7 @@ public: /** * Number of worker threads. */ - unsigned int ThreadCount() const { return ThreadCount_; } + unsigned int ThreadCount() const { return this->ThreadCount_; } /** * Set the number of worker threads. @@ -184,7 +185,7 @@ public: * * Only valid during Process(). */ - void* UserData() const { return UserData_; } + void* UserData() const { return this->UserData_; } // -- Job processing interface @@ -212,7 +213,7 @@ public: template <class T, typename... Args> bool EmplaceJob(Args&&... args) { - return PushJob(cm::make_unique<T>(std::forward<Args>(args)...)); + return this->PushJob(cm::make_unique<T>(std::forward<Args>(args)...)); } private: diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h index c8adea9..e593621 100644 --- a/Source/cmWorkingDirectory.h +++ b/Source/cmWorkingDirectory.h @@ -26,7 +26,7 @@ public: bool SetDirectory(std::string const& newdir); void Pop(); - bool Failed() const { return ResultCode != 0; } + bool Failed() const { return this->ResultCode != 0; } /** \return 0 if the last attempt to set the working directory was * successful. If it failed, the value returned will be the @@ -34,7 +34,7 @@ public: * of the error code can be obtained by passing the result * to \c std::strerror(). */ - int GetLastResult() const { return ResultCode; } + int GetLastResult() const { return this->ResultCode; } std::string const& GetOldDirectory() const { return this->OldDir; } diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx index 1cf9a95..9b0dc58 100644 --- a/Source/cmXCode21Object.cxx +++ b/Source/cmXCode21Object.cxx @@ -4,11 +4,12 @@ #include <ostream> #include <string> +#include <utility> #include "cmSystemTools.h" -cmXCode21Object::cmXCode21Object(PBXType ptype, Type type) - : cmXCodeObject(ptype, type) +cmXCode21Object::cmXCode21Object(PBXType ptype, Type type, std::string id) + : cmXCodeObject(ptype, type, std::move(id)) { this->Version = 21; } diff --git a/Source/cmXCode21Object.h b/Source/cmXCode21Object.h index eb017447..f3fc438 100644 --- a/Source/cmXCode21Object.h +++ b/Source/cmXCode21Object.h @@ -13,7 +13,7 @@ class cmXCode21Object : public cmXCodeObject { public: - cmXCode21Object(PBXType ptype, Type type); + cmXCode21Object(PBXType ptype, Type type, std::string id); void PrintComment(std::ostream&) override; static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&, std::ostream& out, PBXType t); diff --git a/Source/cmXCodeObject.cxx b/Source/cmXCodeObject.cxx index b301ab1..d5c5275 100644 --- a/Source/cmXCodeObject.cxx +++ b/Source/cmXCodeObject.cxx @@ -40,7 +40,7 @@ cmXCodeObject::~cmXCodeObject() this->Version = 15; } -cmXCodeObject::cmXCodeObject(PBXType ptype, Type type) +cmXCodeObject::cmXCodeObject(PBXType ptype, Type type, std::string id) { this->Version = 15; this->Target = nullptr; @@ -48,27 +48,7 @@ cmXCodeObject::cmXCodeObject(PBXType ptype, Type type) this->IsA = ptype; - if (type == OBJECT) { - // Set the Id of an Xcode object to a unique string for each instance. - // However the Xcode user file references certain Ids: for those cases, - // override the generated Id using SetId(). - // - char cUuid[40] = { 0 }; - CFUUIDRef uuid = CFUUIDCreate(kCFAllocatorDefault); - CFStringRef s = CFUUIDCreateString(kCFAllocatorDefault, uuid); - CFStringGetCString(s, cUuid, sizeof(cUuid), kCFStringEncodingUTF8); - this->Id = cUuid; - CFRelease(s); - CFRelease(uuid); - } else { - this->Id = - "Temporary cmake object, should not be referred to in Xcode file"; - } - - cmSystemTools::ReplaceString(this->Id, "-", ""); - if (this->Id.size() > 24) { - this->Id = this->Id.substr(0, 24); - } + this->Id = std::move(id); this->TypeValue = type; if (this->TypeValue == OBJECT) { diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h index ab7f99e..dd5e86e 100644 --- a/Source/cmXCodeObject.h +++ b/Source/cmXCodeObject.h @@ -57,7 +57,7 @@ public: }; static const char* PBXTypeNames[]; virtual ~cmXCodeObject(); - cmXCodeObject(PBXType ptype, Type type); + cmXCodeObject(PBXType ptype, Type type, std::string id); Type GetType() const { return this->TypeValue; } PBXType GetIsA() const { return this->IsA; } diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h index a16c4c8..8a32377 100644 --- a/Source/cmXMLWriter.h +++ b/Source/cmXMLWriter.h @@ -140,9 +140,9 @@ public: cmXMLDocument(cmXMLWriter& xml) : xmlwr(xml) { - xmlwr.StartDocument(); + this->xmlwr.StartDocument(); } - ~cmXMLDocument() { xmlwr.EndDocument(); } + ~cmXMLDocument() { this->xmlwr.EndDocument(); } cmXMLDocument(const cmXMLDocument&) = delete; cmXMLDocument& operator=(const cmXMLDocument&) = delete; @@ -157,19 +157,19 @@ public: cmXMLElement(cmXMLWriter& xml, const char* tag) : xmlwr(xml) { - xmlwr.StartElement(tag); + this->xmlwr.StartElement(tag); } cmXMLElement(cmXMLElement& par, const char* tag) : xmlwr(par.xmlwr) { - xmlwr.StartElement(tag); + this->xmlwr.StartElement(tag); } cmXMLElement(cmXMLDocument& doc, const char* tag) : xmlwr(doc.xmlwr) { - xmlwr.StartElement(tag); + this->xmlwr.StartElement(tag); } - ~cmXMLElement() { xmlwr.EndElement(); } + ~cmXMLElement() { this->xmlwr.EndElement(); } cmXMLElement(const cmXMLElement&) = delete; cmXMLElement& operator=(const cmXMLElement&) = delete; @@ -177,20 +177,20 @@ public: template <typename T> cmXMLElement& Attribute(const char* name, T const& value) { - xmlwr.Attribute(name, value); + this->xmlwr.Attribute(name, value); return *this; } template <typename T> void Content(T const& content) { - xmlwr.Content(content); + this->xmlwr.Content(content); } template <typename T> void Element(std::string const& name, T const& value) { - xmlwr.Element(name, value); + this->xmlwr.Element(name, value); } - void Comment(const char* comment) { xmlwr.Comment(comment); } + void Comment(const char* comment) { this->xmlwr.Comment(comment); } private: cmXMLWriter& xmlwr; diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx index 122e022..15f83e0 100644 --- a/Source/cm_codecvt.cxx +++ b/Source/cm_codecvt.cxx @@ -35,7 +35,7 @@ codecvt::codecvt(Encoding e) case codecvt::None: // No encoding default: - m_noconv = true; + this->m_noconv = true; } } @@ -43,7 +43,7 @@ codecvt::~codecvt() = default; bool codecvt::do_always_noconv() const throw() { - return m_noconv; + return this->m_noconv; } std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from, @@ -53,7 +53,7 @@ std::codecvt_base::result codecvt::do_out(mbstate_t& state, const char* from, { from_next = from; to_next = to; - if (m_noconv) { + if (this->m_noconv) { return std::codecvt_base::noconv; } #if defined(_WIN32) @@ -130,7 +130,7 @@ std::codecvt_base::result codecvt::do_unshift(mbstate_t& state, char* to, char*& to_next) const { to_next = to; - if (m_noconv) { + if (this->m_noconv) { return std::codecvt_base::noconv; } #if defined(_WIN32) diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 1691037..48848a7 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -29,6 +29,7 @@ #include "cm_sys_stat.h" #include "cmCMakePresetsFile.h" +#include "cmCommandLineArgument.h" #include "cmCommands.h" #include "cmDocumentation.h" #include "cmDocumentationEntry.h" @@ -132,131 +133,13 @@ namespace { using JsonValueMapType = std::unordered_map<std::string, Json::Value>; #endif -struct CommandArgument -{ - enum struct Values - { - Zero, - One, - Two, - }; - - std::string InvalidSyntaxMessage; - std::string InvalidValueMessage; - std::string Name; - CommandArgument::Values Type; - std::function<bool(std::string const& value, cmake* state)> StoreCall; - - template <typename FunctionType> - CommandArgument(std::string n, CommandArgument::Values t, - FunctionType&& func) - : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n)) - , InvalidValueMessage(cmStrCat("Invalid value used with ", n)) - , Name(std::move(n)) - , Type(t) - , StoreCall(std::forward<FunctionType>(func)) - { - } - - template <typename FunctionType> - CommandArgument(std::string n, std::string failedMsg, - CommandArgument::Values t, FunctionType&& func) - : InvalidSyntaxMessage(cmStrCat("Invalid syntax used with ", n)) - , InvalidValueMessage(std::move(failedMsg)) - , Name(std::move(n)) - , Type(t) - , StoreCall(std::forward<FunctionType>(func)) - { - } - - bool matches(std::string const& input) const - { - return cmHasPrefix(input, this->Name); - } - - template <typename T> - bool parse(std::string const& input, T& index, - std::vector<std::string> const& allArgs, cmake* state) const - { - enum struct ParseMode - { - Valid, - Invalid, - SyntaxError, - ValueError - }; - ParseMode parseState = ParseMode::Valid; - - // argument is the next parameter - if (this->Type == CommandArgument::Values::Zero) { - if (input.size() == this->Name.size()) { - parseState = this->StoreCall(input, state) ? ParseMode::Valid - : ParseMode::Invalid; - } else { - parseState = ParseMode::SyntaxError; - } - - } else if (this->Type == CommandArgument::Values::One) { - if (input.size() == this->Name.size()) { - ++index; - if (index >= allArgs.size() || allArgs[index][0] == '-') { - parseState = ParseMode::ValueError; - } else { - parseState = this->StoreCall(allArgs[index], state) - ? ParseMode::Valid - : ParseMode::Invalid; - } - } else { - // parse the string to get the value - auto possible_value = cm::string_view(input).substr(this->Name.size()); - if (possible_value.empty()) { - parseState = ParseMode::SyntaxError; - parseState = ParseMode::ValueError; - } else if (possible_value[0] == '=') { - possible_value.remove_prefix(1); - if (possible_value.empty()) { - parseState = ParseMode::ValueError; - } else { - parseState = this->StoreCall(std::string(possible_value), state) - ? ParseMode::Valid - : ParseMode::Invalid; - } - } - if (parseState == ParseMode::Valid) { - parseState = this->StoreCall(std::string(possible_value), state) - ? ParseMode::Valid - : ParseMode::Invalid; - } - } - } else if (this->Type == CommandArgument::Values::Two) { - if (input.size() == this->Name.size()) { - if (index + 2 >= allArgs.size() || allArgs[index + 1][0] == '-' || - allArgs[index + 2][0] == '-') { - parseState = ParseMode::ValueError; - } else { - index += 2; - parseState = - this->StoreCall(cmStrCat(allArgs[index - 1], ";", allArgs[index]), - state) - ? ParseMode::Valid - : ParseMode::Invalid; - } - } - } - - if (parseState == ParseMode::SyntaxError) { - cmSystemTools::Error(this->InvalidSyntaxMessage); - } else if (parseState == ParseMode::ValueError) { - cmSystemTools::Error(this->InvalidValueMessage); - } - return (parseState == ParseMode::Valid); - } -}; - auto IgnoreAndTrueLambda = [](std::string const&, cmake*) -> bool { return true; }; +using CommandArgument = + cmCommandLineArgument<bool(std::string const& value, cmake* state)>; + } // namespace static bool cmakeCheckStampFile(const std::string& stampName); @@ -325,8 +208,9 @@ cmake::cmake(Role role, cmState::Mode mode) }; // The "c" extension MUST precede the "C" extension. - setupExts(this->CLikeSourceFileExtensions, - { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" }); + setupExts( + this->CLikeSourceFileExtensions, + { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "mpp", "m", "M", "mm" }); setupExts(this->HeaderFileExtensions, { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" }); setupExts(this->CudaFileExtensions, { "cu" }); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index f7734a6..ba471b7 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -5,7 +5,6 @@ #include <algorithm> #include <cassert> -#include <cctype> #include <climits> #include <cstring> #include <iostream> @@ -19,6 +18,7 @@ #include <cm3p/uv.h> +#include "cmCommandLineArgument.h" #include "cmConsoleBuf.h" #include "cmDocumentationEntry.h" // IWYU pragma: keep #include "cmGlobalGenerator.h" @@ -213,61 +213,114 @@ int do_cmake(int ac, char const* const* av) } #endif + bool wizard_mode = false; bool sysinfo = false; bool list_cached = false; bool list_all_cached = false; bool list_help = false; bool view_only = false; cmake::WorkingMode workingMode = cmake::NORMAL_MODE; - std::vector<std::string> args; - for (int i = 0; i < ac; ++i) { - if (strcmp(av[i], "-i") == 0) { - /* clang-format off */ - std::cerr << - "The \"cmake -i\" wizard mode is no longer supported.\n" - "Use the -D option to set cache values on the command line.\n" - "Use cmake-gui or ccmake for an interactive dialog.\n"; - /* clang-format on */ - return 1; - } - if (strcmp(av[i], "--system-information") == 0) { - sysinfo = true; - } else if (strcmp(av[i], "-N") == 0) { - view_only = true; - } else if (strcmp(av[i], "-L") == 0) { - list_cached = true; - } else if (strcmp(av[i], "-LA") == 0) { - list_all_cached = true; - } else if (strcmp(av[i], "-LH") == 0) { - list_cached = true; - list_help = true; - } else if (strcmp(av[i], "-LAH") == 0) { - list_all_cached = true; - list_help = true; - } else if (cmHasLiteralPrefix(av[i], "-P")) { - if (i == ac - 1) { - cmSystemTools::Error("No script specified for argument -P"); - return 1; + std::vector<std::string> parsedArgs; + + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; + std::vector<CommandArgument> arguments = { + CommandArgument{ + "-i", CommandArgument::Values::Zero, + [&wizard_mode](std::string const&) -> bool { + /* clang-format off */ + std::cerr << + "The \"cmake -i\" wizard mode is no longer supported.\n" + "Use the -D option to set cache values on the command line.\n" + "Use cmake-gui or ccmake for an interactive dialog.\n"; + /* clang-format on */ + wizard_mode = true; + return true; + } }, + CommandArgument{ "--system-information", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + sysinfo = true; + return true; + } }, + CommandArgument{ "-N", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + view_only = true; + return true; + } }, + CommandArgument{ "-LAH", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + list_all_cached = true; + list_help = true; + return true; + } }, + CommandArgument{ "-LA", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + list_all_cached = true; + return true; + } }, + CommandArgument{ "-LH", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + list_cached = true; + list_help = true; + return true; + } }, + CommandArgument{ "-L", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + list_cached = true; + return true; + } }, + CommandArgument{ "-P", "No script specified for argument -P", + CommandArgument::Values::One, + [&](std::string const& value) -> bool { + workingMode = cmake::SCRIPT_MODE; + parsedArgs.emplace_back("-P"); + parsedArgs.push_back(value); + return true; + } }, + CommandArgument{ "--find-package", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + workingMode = cmake::FIND_PACKAGE_MODE; + parsedArgs.emplace_back("--find-package"); + return true; + } }, + CommandArgument{ "--list-presets", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + workingMode = cmake::HELP_MODE; + parsedArgs.emplace_back("--list-presets"); + return true; + } }, + }; + + std::vector<std::string> inputArgs; + inputArgs.reserve(ac); + cm::append(inputArgs, av, av + ac); + + for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) { + std::string const& arg = inputArgs[i]; + bool matched = false; + for (auto const& m : arguments) { + if (m.matches(arg)) { + matched = true; + if (m.parse(arg, i, inputArgs)) { + break; + } + return 1; // failed to parse } - workingMode = cmake::SCRIPT_MODE; - args.emplace_back(av[i]); - i++; - args.emplace_back(av[i]); - } else if (cmHasLiteralPrefix(av[i], "--find-package")) { - workingMode = cmake::FIND_PACKAGE_MODE; - args.emplace_back(av[i]); - } else if (strcmp(av[i], "--list-presets") == 0) { - workingMode = cmake::HELP_MODE; - args.emplace_back(av[i]); - } else { - args.emplace_back(av[i]); } + if (!matched) { + parsedArgs.emplace_back(av[i]); + } + } + + if (wizard_mode) { + return 1; } + if (sysinfo) { cmake cm(cmake::RoleProject, cmState::Project); cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); - int ret = cm.GetSystemInformation(args); + int ret = cm.GetSystemInformation(parsedArgs); return ret; } cmake::Role const role = @@ -297,7 +350,7 @@ int do_cmake(int ac, char const* const* av) }); cm.SetWorkingMode(workingMode); - int res = cm.Run(args, view_only); + int res = cm.Run(parsedArgs, view_only); if (list_cached || list_all_cached) { std::cout << "-- Cache values" << std::endl; std::vector<std::string> keys = cm.GetState()->GetCacheEntryKeys(); @@ -332,16 +385,9 @@ int do_cmake(int ac, char const* const* av) } #ifndef CMAKE_BOOTSTRAP -int extract_job_number(int& index, char const* current, char const* next, - int len_of_flag) +int extract_job_number(std::string const& command, + std::string const& jobString) { - std::string command(current); - std::string jobString = command.substr(len_of_flag); - if (jobString.empty() && next && isdigit(next[0])) { - ++index; // skip parsing the job number - jobString = std::string(next); - } - int jobs = -1; unsigned long numJobs = 0; if (jobString.empty()) { @@ -356,8 +402,8 @@ int extract_job_number(int& index, char const* current, char const* next, jobs = int(numJobs); } } else { - std::cerr << "'" << command.substr(0, len_of_flag) << "' invalid number '" - << jobString << "' given.\n\n"; + std::cerr << "'" << command << "' invalid number '" << jobString + << "' given.\n\n"; } return jobs; } @@ -374,88 +420,107 @@ int do_build(int ac, char const* const* av) std::string config; std::string dir; std::vector<std::string> nativeOptions; + bool nativeOptionsPassed = false; bool cleanFirst = false; bool foundClean = false; bool foundNonClean = false; bool verbose = cmSystemTools::HasEnv("VERBOSE"); - enum Doing - { - DoingNone, - DoingDir, - DoingTarget, - DoingConfig, - DoingNative + auto jLambda = [&](std::string const& value) -> bool { + jobs = extract_job_number("-j", value); + if (jobs < 0) { + dir.clear(); + } + return true; }; - Doing doing = DoingDir; - for (int i = 2; i < ac; ++i) { - if (doing == DoingNative) { - nativeOptions.emplace_back(av[i]); - } else if (cmHasLiteralPrefix(av[i], "-j")) { - const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr); - jobs = extract_job_number(i, av[i], nextArg, sizeof("-j") - 1); - if (jobs < 0) { - dir.clear(); - } - doing = DoingNone; - } else if (cmHasLiteralPrefix(av[i], "--parallel")) { - const char* nextArg = ((i + 1 < ac) ? av[i + 1] : nullptr); - jobs = extract_job_number(i, av[i], nextArg, sizeof("--parallel") - 1); - if (jobs < 0) { - dir.clear(); + auto parallelLambda = [&](std::string const& value) -> bool { + jobs = extract_job_number("--parallel", value); + if (jobs < 0) { + dir.clear(); + } + return true; + }; + auto targetLambda = [&](std::string const& value) -> bool { + if (!value.empty()) { + std::vector<std::string> values = cmExpandedList(value); + for (auto const& v : values) { + targets.emplace_back(v); + if (v == "clean") { + foundClean = true; + } else { + foundNonClean = true; + } } - doing = DoingNone; - } else if ((strcmp(av[i], "--target") == 0) || - (strcmp(av[i], "-t") == 0)) { - doing = DoingTarget; - } else if (strcmp(av[i], "--config") == 0) { - doing = DoingConfig; - } else if (strcmp(av[i], "--clean-first") == 0) { - cleanFirst = true; - doing = DoingNone; - } else if ((strcmp(av[i], "--verbose") == 0) || - (strcmp(av[i], "-v") == 0)) { - verbose = true; - doing = DoingNone; - } else if (strcmp(av[i], "--use-stderr") == 0) { - /* tolerate legacy option */ - } else if (strcmp(av[i], "--") == 0) { - doing = DoingNative; - } else { - switch (doing) { - case DoingDir: - dir = cmSystemTools::CollapseFullPath(av[i]); - doing = DoingNone; - break; - case DoingTarget: - if (strlen(av[i]) == 0) { - std::cerr << "Warning: Argument number " << i - << " after --target option is empty." << std::endl; - } else { - targets.emplace_back(av[i]); - if (strcmp(av[i], "clean") == 0) { - foundClean = true; - } else { - foundNonClean = true; - } - } - if (foundClean && foundNonClean) { - std::cerr << "Error: Building 'clean' and other targets together " - "is not supported." - << std::endl; - dir.clear(); - } - break; - case DoingConfig: - config = av[i]; - doing = DoingNone; - break; - default: - std::cerr << "Unknown argument " << av[i] << std::endl; - dir.clear(); + return true; + } + return false; + }; + auto verboseLambda = [&](std::string const&) -> bool { + verbose = true; + return true; + }; + + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; + + std::vector<CommandArgument> arguments = { + CommandArgument{ "-j", CommandArgument::Values::ZeroOrOne, jLambda }, + CommandArgument{ "--parallel", CommandArgument::Values::ZeroOrOne, + parallelLambda }, + CommandArgument{ "-t", CommandArgument::Values::OneOrMore, targetLambda }, + CommandArgument{ "--target", CommandArgument::Values::OneOrMore, + targetLambda }, + CommandArgument{ "--config", CommandArgument::Values::One, + [&](std::string const& value) -> bool { + config = value; + return true; + } }, + CommandArgument{ "--clean-first", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + cleanFirst = true; + return true; + } }, + CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda }, + CommandArgument{ "--verbose", CommandArgument::Values::Zero, + verboseLambda }, + /* legacy option no-op*/ + CommandArgument{ "--use-stderr", CommandArgument::Values::Zero, + [](std::string const&) -> bool { return true; } }, + CommandArgument{ "--", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + nativeOptionsPassed = true; + return true; + } }, + }; + + if (ac >= 3) { + dir = cmSystemTools::CollapseFullPath(av[2]); + + std::vector<std::string> inputArgs; + inputArgs.reserve(ac - 3); + cm::append(inputArgs, av + 3, av + ac); + + decltype(inputArgs.size()) i = 0; + for (; i < inputArgs.size() && !nativeOptionsPassed; ++i) { + + std::string const& arg = inputArgs[i]; + for (auto const& m : arguments) { + if (m.matches(arg) && m.parse(arg, i, inputArgs)) { break; + } } } + + if (nativeOptionsPassed) { + cm::append(nativeOptions, inputArgs.begin() + i, inputArgs.end()); + } + } + + if (foundClean && foundNonClean) { + std::cerr << "Error: Building 'clean' and other targets together " + "is not supported." + << std::endl; + dir.clear(); } if (jobs == cmake::NO_BUILD_PARALLEL_LEVEL) { @@ -658,60 +723,59 @@ int do_install(int ac, char const* const* av) bool strip = false; bool verbose = cmSystemTools::HasEnv("VERBOSE"); - enum Doing - { - DoingNone, - DoingDir, - DoingConfig, - DoingComponent, - DoingPrefix, - DoingDefaultDirectoryPermissions, + auto verboseLambda = [&](std::string const&) -> bool { + verbose = true; + return true; }; - Doing doing = DoingDir; + using CommandArgument = + cmCommandLineArgument<bool(std::string const& value)>; + + std::vector<CommandArgument> arguments = { + CommandArgument{ "--config", CommandArgument::Values::One, + [&](std::string const& value) -> bool { + config = value; + return true; + } }, + CommandArgument{ "--component", CommandArgument::Values::One, + [&](std::string const& value) -> bool { + component = value; + return true; + } }, + CommandArgument{ "--default-directory-permissions", + CommandArgument::Values::One, + [&](std::string const& value) -> bool { + defaultDirectoryPermissions = value; + return true; + } }, + CommandArgument{ "--prefix", CommandArgument::Values::One, + [&](std::string const& value) -> bool { + prefix = value; + return true; + } }, + CommandArgument{ "--strip", CommandArgument::Values::Zero, + [&](std::string const&) -> bool { + strip = true; + return true; + } }, + CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda }, + CommandArgument{ "--verbose", CommandArgument::Values::Zero, + verboseLambda } + }; - for (int i = 2; i < ac; ++i) { - if (strcmp(av[i], "--config") == 0) { - doing = DoingConfig; - } else if (strcmp(av[i], "--component") == 0) { - doing = DoingComponent; - } else if (strcmp(av[i], "--prefix") == 0) { - doing = DoingPrefix; - } else if (strcmp(av[i], "--strip") == 0) { - strip = true; - doing = DoingNone; - } else if ((strcmp(av[i], "--verbose") == 0) || - (strcmp(av[i], "-v") == 0)) { - verbose = true; - doing = DoingNone; - } else if (strcmp(av[i], "--default-directory-permissions") == 0) { - doing = DoingDefaultDirectoryPermissions; - } else { - switch (doing) { - case DoingDir: - dir = cmSystemTools::CollapseFullPath(av[i]); - doing = DoingNone; - break; - case DoingConfig: - config = av[i]; - doing = DoingNone; - break; - case DoingComponent: - component = av[i]; - doing = DoingNone; - break; - case DoingPrefix: - prefix = av[i]; - doing = DoingNone; - break; - case DoingDefaultDirectoryPermissions: - defaultDirectoryPermissions = av[i]; - doing = DoingNone; - break; - default: - std::cerr << "Unknown argument " << av[i] << std::endl; - dir.clear(); + if (ac >= 3) { + dir = cmSystemTools::CollapseFullPath(av[2]); + + std::vector<std::string> inputArgs; + inputArgs.reserve(ac - 3); + cm::append(inputArgs, av + 3, av + ac); + for (decltype(inputArgs.size()) i = 0; i < inputArgs.size(); ++i) { + + std::string const& arg = inputArgs[i]; + for (auto const& m : arguments) { + if (m.matches(arg) && m.parse(arg, i, inputArgs)) { break; + } } } } diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index 73fbfb6..f6d8901 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -231,11 +231,10 @@ private: bool ProcessLine() override { if (cmHasPrefix(this->Line, this->IncludePrefix)) { - this->DepFile << cmCMakePath( - cmTrimWhitespace(this->Line.c_str() + - this->IncludePrefix.size())) - .GenericString() - << std::endl; + auto path = + cmTrimWhitespace(this->Line.c_str() + this->IncludePrefix.size()); + cmSystemTools::ConvertToLongPath(path); + this->DepFile << cmCMakePath(path).GenericString() << std::endl; } else { this->Output << this->Line << std::endl << std::flush; } @@ -1523,20 +1522,42 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args, #endif // Internal depfile transformation - if (args[1] == "cmake_transform_depfile" && args.size() == 6) { + if (args[1] == "cmake_transform_depfile" && args.size() == 10) { auto format = cmDepfileFormat::GccDepfile; - if (args[2] == "gccdepfile") { + if (args[3] == "gccdepfile") { format = cmDepfileFormat::GccDepfile; - } else if (args[2] == "vstlog") { + } else if (args[3] == "vstlog") { format = cmDepfileFormat::VsTlog; } else { return 1; } - std::string prefix = args[3]; - if (prefix == "./") { - prefix.clear(); + // Create a cmake object instance to process dependencies. + // All we need is the `set` command. + cmake cm(cmake::RoleScript, cmState::Unknown); + std::string homeDir; + std::string startDir; + std::string homeOutDir; + std::string startOutDir; + homeDir = cmSystemTools::CollapseFullPath(args[4]); + startDir = cmSystemTools::CollapseFullPath(args[5]); + homeOutDir = cmSystemTools::CollapseFullPath(args[6]); + startOutDir = cmSystemTools::CollapseFullPath(args[7]); + cm.SetHomeDirectory(homeDir); + cm.SetHomeOutputDirectory(homeOutDir); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); + if (auto ggd = cm.CreateGlobalGenerator(args[2])) { + cm.SetGlobalGenerator(std::move(ggd)); + cmStateSnapshot snapshot = cm.GetCurrentSnapshot(); + snapshot.GetDirectory().SetCurrentBinary(startOutDir); + snapshot.GetDirectory().SetCurrentSource(startDir); + snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str()); + snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str()); + cmMakefile mf(cm.GetGlobalGenerator(), snapshot); + auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf); + + return cmTransformDepfile(format, *lgd, args[8], args[9]) ? 0 : 2; } - return cmTransformDepfile(format, prefix, args[4], args[5]) ? 0 : 1; + return 1; } } @@ -2227,7 +2248,7 @@ int cmVSLink::Link() if (this->Verbose) { std::cout << "Visual Studio Incremental Link with embedded manifests\n"; } - return LinkIncremental(); + return this->LinkIncremental(); } if (this->Verbose) { if (!this->Incremental) { @@ -2236,7 +2257,7 @@ int cmVSLink::Link() std::cout << "Visual Studio Incremental Link without manifests\n"; } } - return LinkNonIncremental(); + return this->LinkNonIncremental(); } static bool mtRetIsUpdate(int mtRet) diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx index 9c34a56..9607c00 100644 --- a/Source/kwsys/SystemInformation.cxx +++ b/Source/kwsys/SystemInformation.cxx @@ -447,6 +447,7 @@ public: Motorola, HP, Hygon, + Zhaoxin, UnknownManufacturer }; @@ -1731,7 +1732,8 @@ const char* SystemInformationImplementation::GetVendorID() case NexGen: return "NexGen Inc., Advanced Micro Devices"; case IDT: - return "IDT\\Centaur, Via Inc."; + return "IDT\\Centaur, Via Inc., Shanghai Zhaoxin Semiconductor Co., " + "Ltd."; case UMC: return "United Microelectronics Corp."; case Rise: @@ -1748,6 +1750,8 @@ const char* SystemInformationImplementation::GetVendorID() return "Hewlett-Packard"; case Hygon: return "Chengdu Haiguang IC Design Co., Ltd."; + case Zhaoxin: + return "Shanghai Zhaoxin Semiconductor Co., Ltd."; case UnknownManufacturer: default: return "Unknown Manufacturer"; @@ -2109,7 +2113,10 @@ void SystemInformationImplementation::FindManufacturer( else if (this->ChipID.Vendor == "NexGenDriven") this->ChipManufacturer = NexGen; // NexGen Inc. (now AMD) else if (this->ChipID.Vendor == "CentaurHauls") - this->ChipManufacturer = IDT; // IDT/Centaur (now VIA) + this->ChipManufacturer = IDT; // original IDT/Centaur/VIA (now Zhaoxin) + else if (this->ChipID.Vendor == " Shanghai ") + this->ChipManufacturer = + Zhaoxin; // Shanghai Zhaoxin Semiconductor Co., Ltd. else if (this->ChipID.Vendor == "RiseRiseRise") this->ChipManufacturer = Rise; // Rise else if (this->ChipID.Vendor == "GenuineTMx86") @@ -3223,7 +3230,8 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity() this->ChipID.ProcessorName = "C3"; break; default: - this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; + this->ChipID.ProcessorName = + "Unknown IDT\\Centaur\\VIA\\Zhaoxin family"; return false; } break; @@ -3232,13 +3240,63 @@ bool SystemInformationImplementation::RetrieveClassicalCPUIdentity() case 6: this->ChipID.ProcessorName = "VIA Cyrix III - Samuel"; break; + case 0xf: + this->ChipID.ProcessorName = "Zhaoxin zxc"; + break; + default: + this->ChipID.ProcessorName = + "Unknown IDT\\Centaur\\VIA\\Zhaoxin family"; + return false; + } + break; + case 7: + switch (this->ChipID.Model) { + case 0x1b: + this->ChipID.ProcessorName = "Zhaoxin kx5000"; + break; + case 0x3b: + this->ChipID.ProcessorName = "Zhaoxin kx6000"; + break; + default: + this->ChipID.ProcessorName = + "Unknown IDT\\Centaur\\VIA\\Zhaoxin family"; + return false; + } + break; + default: + this->ChipID.ProcessorName = + "Unknown IDT\\Centaur\\VIA\\Zhaoxin family"; + return false; + } + break; + + case Zhaoxin: + switch (this->ChipID.Family) { + case 6: + switch (this->ChipID.Model) { + case 0x19: + this->ChipID.ProcessorName = "Zhaoxin zxc"; + break; + default: + this->ChipID.ProcessorName = "Unknown Zhaoxin family"; + return false; + } + break; + case 7: + switch (this->ChipID.Model) { + case 0x1b: + this->ChipID.ProcessorName = "Zhaoxin kx5000"; + break; + case 0x3b: + this->ChipID.ProcessorName = "Zhaoxin kx6000"; + break; default: - this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; + this->ChipID.ProcessorName = "Unknown Zhaoxin family"; return false; } break; default: - this->ChipID.ProcessorName = "Unknown IDT\\Centaur family"; + this->ChipID.ProcessorName = "Unknown Zhaoxin family"; return false; } break; diff --git a/Tests/Architecture/CMakeLists.txt b/Tests/Architecture/CMakeLists.txt index ea5fc0b..96def00 100644 --- a/Tests/Architecture/CMakeLists.txt +++ b/Tests/Architecture/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(Architecture C) function(test_for_xcode4 result_var) diff --git a/Tests/ArgumentExpansion/CMakeLists.txt b/Tests/ArgumentExpansion/CMakeLists.txt index 1735400..da3bb4c 100644 --- a/Tests/ArgumentExpansion/CMakeLists.txt +++ b/Tests/ArgumentExpansion/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ArgumentExpansion) diff --git a/Tests/BundleUtilities/CMakeLists.txt b/Tests/BundleUtilities/CMakeLists.txt index 69ef535..6020644 100644 --- a/Tests/BundleUtilities/CMakeLists.txt +++ b/Tests/BundleUtilities/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(BundleUtilities) ###### the various types of dependencies we can have diff --git a/Tests/CFBundleTest/CMakeLists.txt b/Tests/CFBundleTest/CMakeLists.txt index b2b1b73..5f2e8ec 100644 --- a/Tests/CFBundleTest/CMakeLists.txt +++ b/Tests/CFBundleTest/CMakeLists.txt @@ -1,6 +1,6 @@ #this is adapted from FireBreath (http://www.firebreath.org) -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CFBundleTest) diff --git a/Tests/CMakeCommands/add_compile_options/CMakeLists.txt b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt index 995b32c..b28d0be 100644 --- a/Tests/CMakeCommands/add_compile_options/CMakeLists.txt +++ b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(add_compile_options) diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt index a5bc1e1..72b3502 100644 --- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(target_compile_definitions) diff --git a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt index a7055b1..268c7eb 100644 --- a/Tests/CMakeCommands/target_compile_options/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_options/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(target_compile_options) diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt index 8713d99..0702ab5 100644 --- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt +++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(target_include_directories) diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index 5c704ac..aa8e21a 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -1,3 +1,6 @@ +# Using 2.8 will trigger a deprecation warning. In this case it's explicitly +# intentional since the tests checks various policy implementations prior to +# 2.8.12 cmake_minimum_required(VERSION 2.8) project(target_link_libraries) diff --git a/Tests/CMakeLib/run_compile_commands.cxx b/Tests/CMakeLib/run_compile_commands.cxx index 2c77acc..0fd6cfb 100644 --- a/Tests/CMakeLib/run_compile_commands.cxx +++ b/Tests/CMakeLib/run_compile_commands.cxx @@ -36,8 +36,8 @@ public: void Parse() { - NextNonWhitespace(); - ParseTranslationUnits(); + this->NextNonWhitespace(); + this->ParseTranslationUnits(); } const TranslationUnitsType& GetTranslationUnits() @@ -49,51 +49,51 @@ private: void ParseTranslationUnits() { this->TranslationUnits = TranslationUnitsType(); - ExpectOrDie('[', "at start of compile command file\n"); + this->ExpectOrDie('[', "at start of compile command file\n"); do { - ParseTranslationUnit(); + this->ParseTranslationUnit(); this->TranslationUnits.push_back(this->Command); - } while (Expect(',')); - ExpectOrDie(']', "at end of array"); + } while (this->Expect(',')); + this->ExpectOrDie(']', "at end of array"); } void ParseTranslationUnit() { this->Command = CommandType(); - if (!Expect('{')) { + if (!this->Expect('{')) { return; } - if (Expect('}')) { + if (this->Expect('}')) { return; } do { - ParseString(); + this->ParseString(); std::string name = this->String; - ExpectOrDie(':', "between name and value"); - ParseString(); + this->ExpectOrDie(':', "between name and value"); + this->ParseString(); std::string value = this->String; this->Command[name] = value; - } while (Expect(',')); - ExpectOrDie('}', "at end of object"); + } while (this->Expect(',')); + this->ExpectOrDie('}', "at end of object"); } void ParseString() { this->String = ""; - if (!Expect('"')) { + if (!this->Expect('"')) { return; } - while (!Expect('"')) { - Expect('\\'); - this->String.append(1, C); - Next(); + while (!this->Expect('"')) { + this->Expect('\\'); + this->String.append(1, this->C); + this->Next(); } } bool Expect(char c) { if (this->C == c) { - NextNonWhitespace(); + this->NextNonWhitespace(); return true; } return false; @@ -101,23 +101,23 @@ private: void ExpectOrDie(char c, const std::string& message) { - if (!Expect(c)) { - ErrorExit(std::string("'") + c + "' expected " + message + "."); + if (!this->Expect(c)) { + this->ErrorExit(std::string("'") + c + "' expected " + message + "."); } } void NextNonWhitespace() { do { - Next(); - } while (IsWhitespace()); + this->Next(); + } while (this->IsWhitespace()); } void Next() { - this->C = char(Input.get()); + this->C = char(this->Input.get()); if (this->Input.bad()) { - ErrorExit("Unexpected end of file."); + this->ErrorExit("Unexpected end of file."); } } diff --git a/Tests/CMakeLib/testCMExtMemory.cxx b/Tests/CMakeLib/testCMExtMemory.cxx index 2aeaf7f..d8932ce 100644 --- a/Tests/CMakeLib/testCMExtMemory.cxx +++ b/Tests/CMakeLib/testCMExtMemory.cxx @@ -26,9 +26,9 @@ public: : value(v) { } - ~Wrapper() { delete value; } + ~Wrapper() { delete this->value; } - T* get() const { return value; } + T* get() const { return this->value; } private: T* value; diff --git a/Tests/CMakeLib/testRST.expect b/Tests/CMakeLib/testRST.expect index 970adaa..4870f65 100644 --- a/Tests/CMakeLib/testRST.expect +++ b/Tests/CMakeLib/testRST.expect @@ -20,6 +20,12 @@ Environment variable ``SOME_ENV_VAR``. Environment variable ``some env var`` with space and target. Generator ``Some Generator`` with space. Generator ``Some Generator`` with space. +Generator expression ``SOME_GENEX``. +Generator expression ``$<SOME_GENEX>`` with brackets. +Generator expression ``$<SOME_GENEX:...>`` with brackets and parameter. +Generator expression ``some genex`` with space and target. +Generator expression ``$<SOME_GENEX>`` with brackets, space, and target. +Generator expression ``$<SOME_GENEX:...>`` with brackets, parameter, space, and target. Inline literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``. Inline link Link Text. Inline link Link Text <With \-escaped Brackets>. @@ -48,6 +54,22 @@ Bracket Comment Content Command other_cmd description. +.. cmake:envvar:: some_var + + Environment variable some_var description. + +.. envvar:: other_var + + Environment variable other_var description. + +.. cmake:genex:: SOME_GENEX + + Generator expression SOME_GENEX description. + +.. genex:: $<OTHER_GENEX> + + Generator expression $<OTHER_GENEX> description. + .. cmake:variable:: some_var Variable some_var description. diff --git a/Tests/CMakeLib/testRST.rst b/Tests/CMakeLib/testRST.rst index 6462f1b..44931a7 100644 --- a/Tests/CMakeLib/testRST.rst +++ b/Tests/CMakeLib/testRST.rst @@ -27,6 +27,12 @@ Environment variable :envvar:`SOME_ENV_VAR`. Environment variable :envvar:`some env var <SOME_ENV_VAR>` with space and target. Generator :generator:`Some Generator` with space. Generator :cpack_gen:`Some Generator` with space. +Generator expression :genex:`SOME_GENEX`. +Generator expression :genex:`$<SOME_GENEX>` with brackets. +Generator expression :genex:`$<SOME_GENEX:...>` with brackets and parameter. +Generator expression :genex:`some genex <SOME_GENEX>` with space and target. +Generator expression :genex:`$<SOME_GENEX> <SOME_GENEX>` with brackets, space, and target. +Generator expression :genex:`$<SOME_GENEX:...> <SOME_GENEX>` with brackets, parameter, space, and target. Inline literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``. Inline link `Link Text <ExternalDest>`_. Inline link `Link Text \<With \\-escaped Brackets\> <ExternalDest>`_. @@ -51,6 +57,22 @@ Inline literal ``__`` followed by inline link `Link Text <InternalDest_>`_. Command other_cmd description. +.. cmake:envvar:: some_var + + Environment variable some_var description. + +.. envvar:: other_var + + Environment variable other_var description. + +.. cmake:genex:: SOME_GENEX + + Generator expression SOME_GENEX description. + +.. genex:: $<OTHER_GENEX> + + Generator expression $<OTHER_GENEX> description. + .. cmake:variable:: some_var Variable some_var description. diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2a59d66..5948911 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1279,21 +1279,6 @@ if(BUILD_TESTING) set_property(TEST CMakeTestAllGenerators PROPERTY RUN_SERIAL 1) endif() - if(NOT DEFINED CTEST_RUN_CMakeTestMultipleConfigures) - set(CTEST_RUN_CMakeTestMultipleConfigures ON) - endif() - - if(CTEST_RUN_CMakeTestMultipleConfigures) - add_test(CMakeTestMultipleConfigures ${CMAKE_CMAKE_COMMAND} - -D dir=${CMake_BINARY_DIR}/Tests/CMakeTestMultipleConfigures - -D gen=${CMAKE_GENERATOR} - -D CMake_SOURCE_DIR=${CMake_SOURCE_DIR} - -P ${CMake_SOURCE_DIR}/Tests/CMakeTestMultipleConfigures/RunCMake.cmake - ) - list(APPEND TEST_BUILD_DIRS - "${CMake_BINARY_DIR}/Tests/CMakeTestMultipleConfigures") - endif() - if(NOT CMake_TEST_EXTERNAL_CMAKE) add_test(LoadedCommandOneConfig ${CMAKE_CTEST_COMMAND} --build-and-test @@ -3394,6 +3379,9 @@ if(BUILD_TESTING) ${build_generator_args} --build-project helloJavaNativeHeaders --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/" + --build-target install + --build-options + "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/Install" --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders") endif() diff --git a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt index 1f9d3ac..7ca68ec 100644 --- a/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt +++ b/Tests/CMakeOnly/CheckCXXCompilerFlag/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CheckCXXCompilerFlag) message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") diff --git a/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt b/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt index 859ec41..4cbccd3 100644 --- a/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt +++ b/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CheckStructHasMember) diff --git a/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt b/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt index 2511064..9f30c7d 100644 --- a/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt +++ b/Tests/CMakeOnly/MajorVersionSelection/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) if (NOT MAJOR_TEST_MODULE OR NOT MAJOR_TEST_VERSION) message(FATAL_ERROR "test selection variables not set up") diff --git a/Tests/CMakeOnly/find_library/CMakeLists.txt b/Tests/CMakeOnly/find_library/CMakeLists.txt index fe3815e..b23d5e2 100644 --- a/Tests/CMakeOnly/find_library/CMakeLists.txt +++ b/Tests/CMakeOnly/find_library/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(FindLibraryTest NONE) set(CMAKE_FIND_DEBUG_MODE 1) diff --git a/Tests/CMakeOnly/find_path/CMakeLists.txt b/Tests/CMakeOnly/find_path/CMakeLists.txt index 0e64ed4..bf4e350 100644 --- a/Tests/CMakeOnly/find_path/CMakeLists.txt +++ b/Tests/CMakeOnly/find_path/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(FindPathTest NONE) set(CMAKE_FIND_DEBUG_MODE 1) diff --git a/Tests/CMakeTestMultipleConfigures/RunCMake.cmake b/Tests/CMakeTestMultipleConfigures/RunCMake.cmake deleted file mode 100644 index a79bfcb..0000000 --- a/Tests/CMakeTestMultipleConfigures/RunCMake.cmake +++ /dev/null @@ -1,165 +0,0 @@ -if(NOT DEFINED CMake_SOURCE_DIR) - message(FATAL_ERROR "CMake_SOURCE_DIR not defined") -endif() - -if(NOT DEFINED dir) - message(FATAL_ERROR "dir not defined") -endif() - -if(NOT DEFINED gen) - message(FATAL_ERROR "gen not defined") -endif() - -# Call cmake once to get a baseline/reference output build tree: "Build". -# Then call cmake N more times, each time making a copy of the entire -# build tree after cmake is done configuring/generating. At the end, -# analyze the diffs in the generated build trees. Expect no diffs. -# -message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") - -set(N 7) - -# First setup source and binary trees: -# -execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf - ${dir}/Source -) - -execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf - ${dir}/Build -) - -execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMake_SOURCE_DIR}/Tests/CTestTest/SmallAndFast - ${dir}/Source -) - -execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory - ${dir}/Build -) - -# Patch SmallAndFast to build a .cxx executable too: -# -execute_process(COMMAND ${CMAKE_COMMAND} -E copy - ${dir}/Source/echoargs.c - ${dir}/Source/echoargs.cxx -) -file(APPEND "${dir}/Source/CMakeLists.txt" "\nadd_executable(echoargsCXX echoargs.cxx)\n") - -# Loop N times, saving a copy of the configured/generated build tree each time: -# -foreach(i RANGE 1 ${N}) - # Equivalent sequence of shell commands: - # - message(STATUS "${i}: cd Build && cmake -G \"${gen}\" ../Source && cd .. && cp -r Build b${i}") - - # Run cmake: - # - execute_process(COMMAND ${CMAKE_COMMAND} -G ${gen} ../Source - RESULT_VARIABLE result - OUTPUT_VARIABLE stdout - ERROR_VARIABLE stderr - WORKING_DIRECTORY ${dir}/Build - ) - - message(STATUS "result='${result}'") - message(STATUS "stdout='${stdout}'") - message(STATUS "stderr='${stderr}'") - message(STATUS "") - - # Save this iteration of the Build directory: - # - execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf - ${dir}/b${i} - ) - execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory - ${dir}/Build - ${dir}/b${i} - RESULT_VARIABLE result - OUTPUT_VARIABLE stdout - ERROR_VARIABLE stderr - ) - - message(STATUS "result='${result}'") - message(STATUS "stdout='${stdout}'") - message(STATUS "stderr='${stderr}'") - message(STATUS "") -endforeach() - - -# Function to analyze diffs between two directories. -# Set DIFF_EXECUTABLE before calling if 'diff' is available. -# -function(analyze_directory_diffs d1 d2 diff_count_var) - set(diffs 0) - - message(STATUS "Analyzing directory diffs between:") - message(STATUS " d1='${d1}'") - message(STATUS " d2='${d2}'") - - if(NOT "${d1}" STREQUAL "" AND NOT "${d2}" STREQUAL "") - message(STATUS "info: analyzing directories") - - file(GLOB_RECURSE files1 RELATIVE "${d1}" "${d1}/*") - file(GLOB_RECURSE files2 RELATIVE "${d2}" "${d2}/*") - - if("${files1}" STREQUAL "${files2}") - message(STATUS "info: file lists the same") - #message(STATUS " files='${files1}'") - - foreach(f ${files1}) - execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files - ${d1}/${f} - ${d2}/${f} - RESULT_VARIABLE result - OUTPUT_VARIABLE stdout - ERROR_VARIABLE stderr - ) - if(result STREQUAL 0) - #message(STATUS "info: file '${f}' the same") - else() - math(EXPR diffs "${diffs} + 1") - message(STATUS "warning: file '${f}' differs from d1 to d2") - file(READ "${d1}/${f}" f1contents) - message(STATUS "contents of file '${d1}/${f}' -[===[${f1contents}]===]") - file(READ "${d2}/${f}" f2contents) - message(STATUS "contents of file '${d2}/${f}' -[===[${f2contents}]===]") - if(DIFF_EXECUTABLE) - message(STATUS "diff of files '${d1}/${f}' '${d2}/${f}'") - message(STATUS "[====[") - execute_process(COMMAND ${DIFF_EXECUTABLE} "${d1}/${f}" "${d2}/${f}") - message(STATUS "]====]") - endif() - endif() - endforeach() - else() - math(EXPR diffs "${diffs} + 1") - message(STATUS "warning: file *lists* differ - some files exist in d1/not-d2 or not-d1/d2...") - message(STATUS " files1='${files1}'") - message(STATUS " files2='${files2}'") - endif() - endif() - - set(${diff_count_var} ${diffs} PARENT_SCOPE) -endfunction() - - -# Analyze diffs between b1:b2, b2:b3, b3:b4, b4:b5 ... bN-1:bN. -# Expect no diffs. -# -find_program(DIFF_EXECUTABLE diff) -set(total_diffs 0) - -foreach(i RANGE 2 ${N}) - math(EXPR prev "${i} - 1") - set(count 0) - analyze_directory_diffs(${dir}/b${prev} ${dir}/b${i} count) - message(STATUS "diff count='${count}'") - message(STATUS "") - math(EXPR total_diffs "${total_diffs} + ${count}") -endforeach() - -message(STATUS "CMAKE_COMMAND='${CMAKE_COMMAND}'") -message(STATUS "total_diffs='${total_diffs}'") diff --git a/Tests/CMakeTests/EndStuffTestScript.cmake b/Tests/CMakeTests/EndStuffTestScript.cmake index 6a6b162..e0d826d 100644 --- a/Tests/CMakeTests/EndStuffTestScript.cmake +++ b/Tests/CMakeTests/EndStuffTestScript.cmake @@ -22,7 +22,7 @@ elseif(testname STREQUAL bad_endfunction) # fail do_end("endfunction()\n") elseif(testname STREQUAL bad_endif) # fail - do_end("cmake_minimum_required(VERSION 2.8)\nendif()\n") + do_end("cmake_minimum_required(VERSION 2.8.12)\nendif()\n") elseif(testname STREQUAL endif_low_min_version) # fail do_end("cmake_minimum_required(VERSION 1.2)\nendif()\n") diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in index 785f41d..76737e5 100644 --- a/Tests/CMakeTests/ListTest.cmake.in +++ b/Tests/CMakeTests/ListTest.cmake.in @@ -142,9 +142,8 @@ set(Find-List-Only-STDERR "three") set(Insert-List-Only-STDERR "at least three") set(Length-List-Only-STDERR "two") set(Remove_At-List-Only-STDERR "at least two") -set(Remove_Item-List-Only-STDERR "two or more") -foreach(cmd IN ITEMS Find Get Insert Length Remove_At Remove_Item) +foreach(cmd IN ITEMS Find Get Insert Length Remove_At) string(TOUPPER ${cmd} cmd_upper) set(${cmd}-List-Only-RESULT 1) set(${cmd}-List-Only-STDERR ".*CMake Error at List-${cmd}-List-Only.cmake:1 \\(list\\):.*list sub-command ${cmd_upper} requires ${${cmd}-List-Only-STDERR} arguments.*") diff --git a/Tests/CPackTestAllGenerators/CMakeLists.txt b/Tests/CPackTestAllGenerators/CMakeLists.txt index 5eeb7e9..95daabf 100644 --- a/Tests/CPackTestAllGenerators/CMakeLists.txt +++ b/Tests/CPackTestAllGenerators/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CPackTestAllGenerators) add_subdirectory(../CTestTest/SmallAndFast SmallAndFast) install(FILES RunCPack.cmake DESTINATION .) diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt index 940e849..2249d70 100644 --- a/Tests/CPackWiXGenerator/CMakeLists.txt +++ b/Tests/CPackWiXGenerator/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CPackWiXGenerator) diff --git a/Tests/CTestLimitDashJ/CMakeLists.txt b/Tests/CTestLimitDashJ/CMakeLists.txt index 5208d2d..d04b3ad 100644 --- a/Tests/CTestLimitDashJ/CMakeLists.txt +++ b/Tests/CTestLimitDashJ/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CTestLimitDashJ NONE) # This file demonstrates https://gitlab.kitware.com/cmake/cmake/-/issues/12904 diff --git a/Tests/CTestTest/SmallAndFast/CMakeLists.txt b/Tests/CTestTest/SmallAndFast/CMakeLists.txt index 85cb30c..06cbafd 100644 --- a/Tests/CTestTest/SmallAndFast/CMakeLists.txt +++ b/Tests/CTestTest/SmallAndFast/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(SmallAndFast) include(CTest) diff --git a/Tests/CheckCompilerRelatedVariables/CMakeLists.txt b/Tests/CheckCompilerRelatedVariables/CMakeLists.txt index 87b7f1a..69fa4b6 100644 --- a/Tests/CheckCompilerRelatedVariables/CMakeLists.txt +++ b/Tests/CheckCompilerRelatedVariables/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CheckCompilerRelatedVariables) diff --git a/Tests/CompileDefinitions/CMakeLists.txt b/Tests/CompileDefinitions/CMakeLists.txt index 1d8afbf..8347d5a 100644 --- a/Tests/CompileDefinitions/CMakeLists.txt +++ b/Tests/CompileDefinitions/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CompileDefinitions) # Use compile flags to tell executables which config is built diff --git a/Tests/CompileOptions/CMakeLists.txt b/Tests/CompileOptions/CMakeLists.txt index 1433462..cd6cacd 100644 --- a/Tests/CompileOptions/CMakeLists.txt +++ b/Tests/CompileOptions/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(CompileOptions) diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt index ab0b5d8..a3d98f6 100644 --- a/Tests/ConfigSources/CMakeLists.txt +++ b/Tests/ConfigSources/CMakeLists.txt @@ -5,6 +5,11 @@ if(NOT _isMultiConfig AND NOT CMAKE_BUILD_TYPE) endif() project(ConfigSources CXX) +if("${CMAKE_CXX_COMPILER_ID};${CMAKE_CXX_SIMULATE_ID}" STREQUAL "Intel;MSVC") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " -Z7") + string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -Z7") +endif() + # Source file(s) named with the configuration(s). file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/config_$<CONFIG>.cpp" diff --git a/Tests/Contracts/Trilinos/CMakeLists.txt b/Tests/Contracts/Trilinos/CMakeLists.txt index 4d7062b..6cc2d09 100644 --- a/Tests/Contracts/Trilinos/CMakeLists.txt +++ b/Tests/Contracts/Trilinos/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(Trilinos) include(ExternalProject) diff --git a/Tests/Contracts/VTK/CMakeLists.txt b/Tests/Contracts/VTK/CMakeLists.txt index 6ae2732..0d36323 100644 --- a/Tests/Contracts/VTK/CMakeLists.txt +++ b/Tests/Contracts/VTK/CMakeLists.txt @@ -1,6 +1,6 @@ # The VTK external project for CMake # --------------------------------------------------------------------------- -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(VTK) include(ExternalProject) diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index c1a7a57..80545c4 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -582,3 +582,7 @@ set_target_properties(mac_fw PROPERTIES ) add_custom_command(OUTPUT mac_fw.txt COMMAND ${CMAKE_COMMAND} -E touch mac_fw.txt DEPENDS mac_fw) add_custom_target(drive_mac_fw ALL DEPENDS mac_fw.txt) + +# Test empty COMMANDs are ommited +add_executable(empty_command empty_command.cxx) +add_custom_command(TARGET empty_command POST_BUILD COMMAND $<0:date>) diff --git a/Tests/CustomCommand/empty_command.cxx b/Tests/CustomCommand/empty_command.cxx new file mode 100644 index 0000000..f8b643a --- /dev/null +++ b/Tests/CustomCommand/empty_command.cxx @@ -0,0 +1,4 @@ +int main() +{ + return 0; +} diff --git a/Tests/EmptyDepends/CMakeLists.txt b/Tests/EmptyDepends/CMakeLists.txt index 832d9dc..272eff7 100644 --- a/Tests/EmptyDepends/CMakeLists.txt +++ b/Tests/EmptyDepends/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(EmptyDepends) include(CTest) diff --git a/Tests/ExportImport/Import/try_compile/CMakeLists.txt b/Tests/ExportImport/Import/try_compile/CMakeLists.txt index 1088461..813cf06 100644 --- a/Tests/ExportImport/Import/try_compile/CMakeLists.txt +++ b/Tests/ExportImport/Import/try_compile/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) find_package(testLibRequired 2.5 REQUIRED) diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt index 29cdcc9..8fd44b4 100644 --- a/Tests/ExternalProject/CMakeLists.txt +++ b/Tests/ExternalProject/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ExternalProjectTest NONE) if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12) cmake_policy(SET CMP0114 NEW) @@ -298,15 +298,9 @@ set(do_git_tests 0) if(GIT_EXECUTABLE) set(do_git_tests 1) - execute_process( - COMMAND "${GIT_EXECUTABLE}" --version - OUTPUT_VARIABLE ov - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}") - message(STATUS "git_version='${git_version}'") + message(STATUS "GIT_VERSION_STRING='${GIT_VERSION_STRING}'") - if(git_version VERSION_LESS 1.6.5) + if("${GIT_VERSION_STRING}" VERSION_LESS 1.6.5) message(STATUS "No ExternalProject git tests with git client less than version 1.6.5") set(do_git_tests 0) endif() diff --git a/Tests/ExternalProject/Example/CMakeLists.txt b/Tests/ExternalProject/Example/CMakeLists.txt index 4c12895..c3f2614 100644 --- a/Tests/ExternalProject/Example/CMakeLists.txt +++ b/Tests/ExternalProject/Example/CMakeLists.txt @@ -1,5 +1,5 @@ # This is the canonical simplest ExternalProject example CMakeLists.txt file: -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ExternalProjectExample NONE) include(ExternalProject) diff --git a/Tests/ExternalProjectLocal/CMakeLists.txt b/Tests/ExternalProjectLocal/CMakeLists.txt index 789e4fb..9a0241c 100644 --- a/Tests/ExternalProjectLocal/CMakeLists.txt +++ b/Tests/ExternalProjectLocal/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ExternalProjectLocalTest NONE) if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12) cmake_policy(SET CMP0114 NEW) diff --git a/Tests/ExternalProjectUpdate/CMakeLists.txt b/Tests/ExternalProjectUpdate/CMakeLists.txt index 563a6cf..b31a38b 100644 --- a/Tests/ExternalProjectUpdate/CMakeLists.txt +++ b/Tests/ExternalProjectUpdate/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ExternalProjectUpdateTest NONE) if(CMAKE_XCODE_BUILD_SYSTEM VERSION_GREATER_EQUAL 12) cmake_policy(SET CMP0114 NEW) @@ -51,15 +51,9 @@ set(do_git_tests 0) if(GIT_EXECUTABLE) set(do_git_tests 1) - execute_process( - COMMAND "${GIT_EXECUTABLE}" --version - OUTPUT_VARIABLE ov - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}") - message(STATUS "git_version='${git_version}'") + message(STATUS "GIT_VERSION_STRING='${GIT_VERSION_STRING}'") - if(git_version VERSION_LESS 1.6.5) + if("${GIT_VERSION_STRING}" VERSION_LESS 1.6.5) message(STATUS "No ExternalProject git tests with git client less than version 1.6.5") set(do_git_tests 0) endif() diff --git a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake index ddc513f..aaa05d7 100644 --- a/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake +++ b/Tests/ExternalProjectUpdate/ExternalProjectUpdateTest.cmake @@ -167,15 +167,9 @@ set(do_git_tests 0) if(GIT_EXECUTABLE) set(do_git_tests 1) - execute_process( - COMMAND "${GIT_EXECUTABLE}" --version - OUTPUT_VARIABLE ov - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - string(REGEX REPLACE "^git version (.+)$" "\\1" git_version "${ov}") - message(STATUS "git_version='${git_version}'") + message(STATUS "GIT_VERSION_STRING='${GIT_VERSION_STRING}'") - if(git_version VERSION_LESS 1.6.5) + if("${GIT_VERSION_STRING}" VERSION_LESS 1.6.5) message(STATUS "No ExternalProject git tests with git client less than version 1.6.5") set(do_git_tests 0) endif() @@ -185,17 +179,17 @@ endif() file(REMOVE_RECURSE ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals) if(do_git_tests) - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) + check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 REBASE) check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 1 REBASE) - # With the Git UPDATE_COMMAND performance patch, this will not required a + # With the Git UPDATE_COMMAND performance patch, this will not require a # 'git fetch' check_a_tag(tag1 d1970730310fe8bc07e73f15dc570071f9f9654a 0 REBASE) check_a_tag(tag2 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 1 REBASE) check_a_tag(d19707303 d1970730310fe8bc07e73f15dc570071f9f9654a 0 REBASE) - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) + check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 REBASE) # This is a remote symbolic ref, so it will always trigger a 'git fetch' - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 REBASE) + check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 REBASE) foreach(strategy IN ITEMS CHECKOUT REBASE_CHECKOUT) # Move local master back, then apply a change that will cause a conflict @@ -229,7 +223,19 @@ if(do_git_tests) message(FATAL_ERROR "Could not commit conflicting change.") endif() # This should discard our commit but leave behind an annotated tag - check_a_tag(origin/master 5842b503ba4113976d9bb28d57b5aee1ad2736b7 1 ${strategy}) + check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 ${strategy}) endforeach() + # This file matches a .gitignore rule that the last commit defines. We can't + # directly check that updates don't stash ignored contents because the stash + # and pop are both done within the update step. We don't have an opportunity + # to check things in between, but we can at least check that the update step + # doesn't choke on it. + set(ignoredFile ${ExternalProjectUpdate_BINARY_DIR}/CMakeExternals/Source/TutorialStep1-GIT/ignored_item) + file(TOUCH ${ignoredFile}) + check_a_tag(origin/master b5752a26ae448410926b35c275af3c192a53722e 1 REBASE) + if(NOT EXISTS ${ignoredFile}) + message(FATAL_ERROR "Ignored file is missing") + endif() + endif() diff --git a/Tests/ExternalProjectUpdate/gitrepo.tgz b/Tests/ExternalProjectUpdate/gitrepo.tgz Binary files differindex 87090ab..4dab56b 100644 --- a/Tests/ExternalProjectUpdate/gitrepo.tgz +++ b/Tests/ExternalProjectUpdate/gitrepo.tgz diff --git a/Tests/FindGTK2/atk/CMakeLists.txt b/Tests/FindGTK2/atk/CMakeLists.txt index be37957..0392d88 100644 --- a/Tests/FindGTK2/atk/CMakeLists.txt +++ b/Tests/FindGTK2/atk/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(atk C) diff --git a/Tests/FindGTK2/atkmm/CMakeLists.txt b/Tests/FindGTK2/atkmm/CMakeLists.txt index e8320b5..ec838de 100644 --- a/Tests/FindGTK2/atkmm/CMakeLists.txt +++ b/Tests/FindGTK2/atkmm/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(atkmm CXX) diff --git a/Tests/FindGTK2/cairo/CMakeLists.txt b/Tests/FindGTK2/cairo/CMakeLists.txt index 97a7369..3652ad6 100644 --- a/Tests/FindGTK2/cairo/CMakeLists.txt +++ b/Tests/FindGTK2/cairo/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(cairo C) diff --git a/Tests/FindGTK2/cairomm/CMakeLists.txt b/Tests/FindGTK2/cairomm/CMakeLists.txt index 47a156e..cde0f42 100644 --- a/Tests/FindGTK2/cairomm/CMakeLists.txt +++ b/Tests/FindGTK2/cairomm/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(cairomm CXX) diff --git a/Tests/FindGTK2/gdk/CMakeLists.txt b/Tests/FindGTK2/gdk/CMakeLists.txt index f485236..35ef337 100644 --- a/Tests/FindGTK2/gdk/CMakeLists.txt +++ b/Tests/FindGTK2/gdk/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gdk C) diff --git a/Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt b/Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt index 004e82e..ea1b05d 100644 --- a/Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt +++ b/Tests/FindGTK2/gdk_pixbuf/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gdk_pixbuf C) diff --git a/Tests/FindGTK2/gdkmm/CMakeLists.txt b/Tests/FindGTK2/gdkmm/CMakeLists.txt index a54fc4f..72fc6f4 100644 --- a/Tests/FindGTK2/gdkmm/CMakeLists.txt +++ b/Tests/FindGTK2/gdkmm/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gdkmm CXX) diff --git a/Tests/FindGTK2/gio/CMakeLists.txt b/Tests/FindGTK2/gio/CMakeLists.txt index db9cdd0..4835afa 100644 --- a/Tests/FindGTK2/gio/CMakeLists.txt +++ b/Tests/FindGTK2/gio/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gio C) diff --git a/Tests/FindGTK2/giomm/CMakeLists.txt b/Tests/FindGTK2/giomm/CMakeLists.txt index 46cfef5..b639979 100644 --- a/Tests/FindGTK2/giomm/CMakeLists.txt +++ b/Tests/FindGTK2/giomm/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(giomm CXX) diff --git a/Tests/FindGTK2/glib/CMakeLists.txt b/Tests/FindGTK2/glib/CMakeLists.txt index 1aa73ff..536fc67 100644 --- a/Tests/FindGTK2/glib/CMakeLists.txt +++ b/Tests/FindGTK2/glib/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(glib C) diff --git a/Tests/FindGTK2/glibmm/CMakeLists.txt b/Tests/FindGTK2/glibmm/CMakeLists.txt index af8ddcf..25d5518 100644 --- a/Tests/FindGTK2/glibmm/CMakeLists.txt +++ b/Tests/FindGTK2/glibmm/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(glibmm CXX) diff --git a/Tests/FindGTK2/gmodule/CMakeLists.txt b/Tests/FindGTK2/gmodule/CMakeLists.txt index 9717da8..2bfb81e 100644 --- a/Tests/FindGTK2/gmodule/CMakeLists.txt +++ b/Tests/FindGTK2/gmodule/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gmodule C) diff --git a/Tests/FindGTK2/gobject/CMakeLists.txt b/Tests/FindGTK2/gobject/CMakeLists.txt index c51fd4d..11520f8 100644 --- a/Tests/FindGTK2/gobject/CMakeLists.txt +++ b/Tests/FindGTK2/gobject/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gobject C) diff --git a/Tests/FindGTK2/gthread/CMakeLists.txt b/Tests/FindGTK2/gthread/CMakeLists.txt index a90294d0..5ecfd9b 100644 --- a/Tests/FindGTK2/gthread/CMakeLists.txt +++ b/Tests/FindGTK2/gthread/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gthread C) diff --git a/Tests/FindGTK2/gtk/CMakeLists.txt b/Tests/FindGTK2/gtk/CMakeLists.txt index 11603ae..2c67619 100644 --- a/Tests/FindGTK2/gtk/CMakeLists.txt +++ b/Tests/FindGTK2/gtk/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gtk C) diff --git a/Tests/FindGTK2/gtkmm/CMakeLists.txt b/Tests/FindGTK2/gtkmm/CMakeLists.txt index eb0b7aa..3375a55 100644 --- a/Tests/FindGTK2/gtkmm/CMakeLists.txt +++ b/Tests/FindGTK2/gtkmm/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(gtkmm CXX) diff --git a/Tests/FindGTK2/pango/CMakeLists.txt b/Tests/FindGTK2/pango/CMakeLists.txt index af382a4..bd6b13a 100644 --- a/Tests/FindGTK2/pango/CMakeLists.txt +++ b/Tests/FindGTK2/pango/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(pango C) diff --git a/Tests/FindGTK2/pangocairo/CMakeLists.txt b/Tests/FindGTK2/pangocairo/CMakeLists.txt index 8f61379..157b9c2 100644 --- a/Tests/FindGTK2/pangocairo/CMakeLists.txt +++ b/Tests/FindGTK2/pangocairo/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(pangocairo C) diff --git a/Tests/FindGTK2/pangoft2/CMakeLists.txt b/Tests/FindGTK2/pangoft2/CMakeLists.txt index 0f84c7f..76966e7 100644 --- a/Tests/FindGTK2/pangoft2/CMakeLists.txt +++ b/Tests/FindGTK2/pangoft2/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(pangoft2 C) diff --git a/Tests/FindGTK2/pangomm/CMakeLists.txt b/Tests/FindGTK2/pangomm/CMakeLists.txt index 3650c50..0bb49e2 100644 --- a/Tests/FindGTK2/pangomm/CMakeLists.txt +++ b/Tests/FindGTK2/pangomm/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(pangomm CXX) diff --git a/Tests/FindGTK2/pangoxft/CMakeLists.txt b/Tests/FindGTK2/pangoxft/CMakeLists.txt index 0db16b1..7051d35 100644 --- a/Tests/FindGTK2/pangoxft/CMakeLists.txt +++ b/Tests/FindGTK2/pangoxft/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(pangoxft C) diff --git a/Tests/FindGTK2/sigc++/CMakeLists.txt b/Tests/FindGTK2/sigc++/CMakeLists.txt index f830b81..9c1fff7 100644 --- a/Tests/FindGTK2/sigc++/CMakeLists.txt +++ b/Tests/FindGTK2/sigc++/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(sigc++ CXX) diff --git a/Tests/FindPostgreSQL/Test/CMakeLists.txt b/Tests/FindPostgreSQL/Test/CMakeLists.txt index 374e147..1bc5c56 100644 --- a/Tests/FindPostgreSQL/Test/CMakeLists.txt +++ b/Tests/FindPostgreSQL/Test/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10) project(TestFindPostgreSQL C) include(CTest) -find_package(PostgreSQL REQUIRED) +find_package(PostgreSQL REQUIRED COMPONENTS Server) add_definitions(-DCMAKE_EXPECTED_POSTGRESQL_VERSION="${PostgreSQL_VERSION_STRING}") diff --git a/Tests/FortranC/CMakeLists.txt b/Tests/FortranC/CMakeLists.txt index 79c670d..83c2729 100644 --- a/Tests/FortranC/CMakeLists.txt +++ b/Tests/FortranC/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(FortranC C Fortran) # Skip this test for compilers not known to be compatible. diff --git a/Tests/Fuzzing/README.rst b/Tests/Fuzzing/README.rst new file mode 100644 index 0000000..a869f9c --- /dev/null +++ b/Tests/Fuzzing/README.rst @@ -0,0 +1,8 @@ +The fuzzers in this directory are run continuously through OSS-fuzz. +All fuzzers are implemented by way of the `libFuzzer engine`_. + +The link to the OSS-fuzz integration can be found here: (pending) +All email addresses in the `project.yaml` file on OSS-fuzz will have access +to detailed bug reports and will be notified via email if/when bugs are found. + +.. _`libFuzzer Engine`: https://llvm.org/docs/LibFuzzer.html diff --git a/Tests/Fuzzing/xml_parser_fuzzer.cc b/Tests/Fuzzing/xml_parser_fuzzer.cc new file mode 100644 index 0000000..1faa918 --- /dev/null +++ b/Tests/Fuzzing/xml_parser_fuzzer.cc @@ -0,0 +1,27 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> + +#include "cmXMLParser.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ + char test_file[] = "libfuzzer.xml"; + + FILE* fp = fopen(test_file, "wb"); + if (!fp) + return 0; + fwrite(data, size, 1, fp); + fclose(fp); + + cmXMLParser parser; + if (!parser.ParseFile(test_file)) { + return 1; + } + + remove(test_file); + return 0; +} diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt index 20bd601..dee39c8 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(SystemIncludeDirectories) diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt index a9edf9a..3b994a2 100644 --- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(TargetIncludeDirectories) diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt index ec0a604..a302c7c 100644 --- a/Tests/InterfaceLibrary/CMakeLists.txt +++ b/Tests/InterfaceLibrary/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(InterfaceLibrary) diff --git a/Tests/JavaNativeHeaders/CMakeLists.txt b/Tests/JavaNativeHeaders/CMakeLists.txt index 2023d25..f3cc89d 100644 --- a/Tests/JavaNativeHeaders/CMakeLists.txt +++ b/Tests/JavaNativeHeaders/CMakeLists.txt @@ -11,7 +11,7 @@ include (UseJava) # JNI support find_package(JNI) -add_jar(B1 D.java GENERATE_NATIVE_HEADERS D1-native) +add_jar(B1 D.java GENERATE_NATIVE_HEADERS D1-native DESTINATION INSTALL include) add_jar(E1 E.java GENERATE_NATIVE_HEADERS E1-native) add_jar(hello4 HelloWorld3.java) @@ -19,6 +19,13 @@ add_jar(hello4 HelloWorld3.java) add_library(D SHARED D.cpp E.cpp) target_link_libraries (D PRIVATE D1-native E1-native) +install(TARGETS D1-native EXPORT native) +install(DIRECTORY "$<TARGET_PROPERTY:D1-native,NATIVE_HEADERS_DIRECTORY>/" DESTINATION include) +install(EXPORT native DESTINATION "${CMAKE_INSTALL_PREFIX}" NAMESPACE D1::) + add_test (NAME Java.NativeHeaders COMMAND "${Java_JAVA_EXECUTABLE}" -Djava.library.path=$<TARGET_FILE_DIR:D> -classpath hello4.jar HelloWorld3) + +add_test (NAME Java.ImportNativeHeaders + COMMAND "${CMAKE_COMMAND}" "-DNATIVE_HEADERS_IMPORT_DIR=${CMAKE_INSTALL_PREFIX}" -S "${CMAKE_CURRENT_SOURCE_DIR}/Import" -B "${CMAKE_CURRENT_BINARY_DIR}/Import") diff --git a/Tests/JavaNativeHeaders/Import/CMakeLists.txt b/Tests/JavaNativeHeaders/Import/CMakeLists.txt new file mode 100644 index 0000000..5486da9 --- /dev/null +++ b/Tests/JavaNativeHeaders/Import/CMakeLists.txt @@ -0,0 +1,19 @@ +project(ImportJavaNativeHeaders LANGUAGES NONE) + +cmake_minimum_required (VERSION 3.19...3.20) +set(CMAKE_VERBOSE_MAKEFILE 1) + +include(${NATIVE_HEADERS_IMPORT_DIR}/native.cmake) + +if(NOT TARGET D1::D1-native) + message(FATAL_ERROR "Target 'D1::D1-native' not found.") +endif() + +get_property(incs TARGET D1::D1-native PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +if (NOT incs MATCHES "${NATIVE_HEADERS_IMPORT_DIR}/include") + message(FATAL_ERROR "Target 'D1::D1-native', property 'INTERFACE_INCLUDE_DIRECTORIES' badly defined: ${incs}.") +endif() + +if (NOT EXISTS "${NATIVE_HEADERS_IMPORT_DIR}/include/D.h") + message(FATAL_ERROR "file '${NATIVE_HEADERS_IMPORT_DIR}/include/D.h' not found.") +endif() diff --git a/Tests/LinkDirectory/CMakeLists.txt b/Tests/LinkDirectory/CMakeLists.txt index c7a2700..d9a8ac8 100644 --- a/Tests/LinkDirectory/CMakeLists.txt +++ b/Tests/LinkDirectory/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(LinkDirectory C) # Put the subproject source tree in our build tree so it can refer to diff --git a/Tests/LinkDirectory/External/CMakeLists.txt b/Tests/LinkDirectory/External/CMakeLists.txt index c877913..e222929 100644 --- a/Tests/LinkDirectory/External/CMakeLists.txt +++ b/Tests/LinkDirectory/External/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(LinkDirectoryExternal C) diff --git a/Tests/LinkFlags/CMakeLists.txt b/Tests/LinkFlags/CMakeLists.txt index 4607035..31ff9b5 100644 --- a/Tests/LinkFlags/CMakeLists.txt +++ b/Tests/LinkFlags/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(LinkFlags C) string(TOUPPER "${TEST_CONFIG}" TEST_CONFIG_UPPER) diff --git a/Tests/MFC/CMakeLists.txt b/Tests/MFC/CMakeLists.txt index 62ff749..d17b955 100644 --- a/Tests/MFC/CMakeLists.txt +++ b/Tests/MFC/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(mfc_driver) include(CTest) diff --git a/Tests/MFC/CMakeLists.txt.in b/Tests/MFC/CMakeLists.txt.in index 3632e03..a600c63 100644 --- a/Tests/MFC/CMakeLists.txt.in +++ b/Tests/MFC/CMakeLists.txt.in @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(mfc1) macro(replace_flags var these those) diff --git a/Tests/MFC/try_compile/CMakeLists.txt b/Tests/MFC/try_compile/CMakeLists.txt index 8e5d746..768d2a6 100644 --- a/Tests/MFC/try_compile/CMakeLists.txt +++ b/Tests/MFC/try_compile/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(try_compile_mfc) set(files diff --git a/Tests/MacRuntimePath/A/CMakeLists.txt b/Tests/MacRuntimePath/A/CMakeLists.txt index bf937e6..c9d3f2c 100644 --- a/Tests/MacRuntimePath/A/CMakeLists.txt +++ b/Tests/MacRuntimePath/A/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(MacRuntimePath_A) # a shared library diff --git a/Tests/MacRuntimePath/B/CMakeLists.txt b/Tests/MacRuntimePath/B/CMakeLists.txt index 4317af6..85598c4 100644 --- a/Tests/MacRuntimePath/B/CMakeLists.txt +++ b/Tests/MacRuntimePath/B/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(MacRuntimePath_B) include(${MacRuntimePath_B_BINARY_DIR}/../Root/lib/exp.cmake) diff --git a/Tests/MissingSourceFile/CMakeLists.txt b/Tests/MissingSourceFile/CMakeLists.txt index a7206c8..b4f0033 100644 --- a/Tests/MissingSourceFile/CMakeLists.txt +++ b/Tests/MissingSourceFile/CMakeLists.txt @@ -1,3 +1,3 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(MissingSourceFile C) add_executable(MissingSourceFile DoesNotExist/MissingSourceFile.c) diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt index fca5f41..74f34e4 100644 --- a/Tests/ObjectLibrary/CMakeLists.txt +++ b/Tests/ObjectLibrary/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ObjectLibrary C) add_subdirectory(A) diff --git a/Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt b/Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt index 22c92a7..fb0ebc0 100644 --- a/Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt +++ b/Tests/ObjectLibrary/ExportLanguages/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ExportLanguages CXX) add_library(ExportLanguagesA OBJECT a.cxx) add_library(ExportLanguagesB STATIC a.c $<TARGET_OBJECTS:ExportLanguagesA>) diff --git a/Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt b/Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt index fc8dd2b..8544798 100644 --- a/Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt +++ b/Tests/ObjectLibrary/ExportLanguages/ExportLanguagesTest/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(ExportLanguagesTest) diff --git a/Tests/PDBDirectoryAndName/CMakeLists.txt b/Tests/PDBDirectoryAndName/CMakeLists.txt index 44194ca..95aa351 100644 --- a/Tests/PDBDirectoryAndName/CMakeLists.txt +++ b/Tests/PDBDirectoryAndName/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) cmake_policy(SET CMP0054 NEW) project(PDBDirectoryAndName C) diff --git a/Tests/Plugin/PluginTest/CMakeLists.txt b/Tests/Plugin/PluginTest/CMakeLists.txt index 5626dbc..f00122d 100644 --- a/Tests/Plugin/PluginTest/CMakeLists.txt +++ b/Tests/Plugin/PluginTest/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(PluginTest) diff --git a/Tests/PositionIndependentTargets/CMakeLists.txt b/Tests/PositionIndependentTargets/CMakeLists.txt index e79f3b7..ff779d3 100644 --- a/Tests/PositionIndependentTargets/CMakeLists.txt +++ b/Tests/PositionIndependentTargets/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(PositionIndependentTargets) diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt index 2ca11e4..3ddc345 100644 --- a/Tests/Qt4Targets/CMakeLists.txt +++ b/Tests/Qt4Targets/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(Qt4Targets) diff --git a/Tests/QtAutogen/RerunMocBasic/CMakeLists.txt b/Tests/QtAutogen/RerunMocBasic/CMakeLists.txt index 9b32e59..c53e857 100644 --- a/Tests/QtAutogen/RerunMocBasic/CMakeLists.txt +++ b/Tests/QtAutogen/RerunMocBasic/CMakeLists.txt @@ -47,19 +47,38 @@ macro(require_change_not) endmacro() -# Initial build +# Configure the test project configure_file("${mocBasicSrcDir}/test1a.h.in" "${mocBasicBinDir}/test1.h" COPYONLY) -try_compile(MOC_RERUN - "${mocBasicBinDir}" - "${mocBasicSrcDir}" - MocBasic - CMAKE_FLAGS "-DQT_TEST_VERSION=${QT_TEST_VERSION}" - "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}" - "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" +configure_file("${mocBasicSrcDir}/myobject3a.h.in" "${mocBasicBinDir}/myobject3.h" @ONLY) +if(CMAKE_GENERATOR_INSTANCE) + set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE=${CMAKE_GENERATOR_INSTANCE}") +else() + set(_D_CMAKE_GENERATOR_INSTANCE "") +endif() +execute_process( + COMMAND "${CMAKE_COMMAND}" -B "${mocBasicBinDir}" -S "${mocBasicSrcDir}" + -G "${CMAKE_GENERATOR}" + -A "${CMAKE_GENERATOR_PLATFORM}" + -T "${CMAKE_GENERATOR_TOOLSET}" + ${_D_CMAKE_GENERATOR_INSTANCE} + "-DQT_TEST_VERSION=${QT_TEST_VERSION}" + "-DCMAKE_AUTOGEN_VERBOSE=${CMAKE_AUTOGEN_VERBOSE}" + "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" + RESULT_VARIABLE exit_code OUTPUT_VARIABLE output ) -if (NOT MOC_RERUN) - message(FATAL_ERROR "Initial build of mocBasic failed. Output: ${output}") +if(NOT exit_code EQUAL 0) + message(FATAL_ERROR "Initial configuration of mocBasic failed. Output: ${output}") +endif() + +# Initial build +execute_process( + COMMAND "${CMAKE_COMMAND}" --build "${mocBasicBinDir}" + RESULT_VARIABLE exit_code + OUTPUT_VARIABLE output +) +if(NOT exit_code EQUAL 0) + message(FATAL_ERROR "Initial build of mocBasic failed. Output: ${output}") endif() # Get name of the output binary @@ -100,3 +119,43 @@ message(STATUS "Changing nothing for no MOC re-run") rebuild(3) acquire_timestamp(After) require_change_not() + + +# - Ensure that the timestamp will change +# - Remove Q_OBJECT from header +# - Rebuild +acquire_timestamp(Before) +sleep() +message(STATUS "Remove Q_OBJECT from header file for a MOC re-run") +configure_file("${mocBasicSrcDir}/test1c.h.in" "${mocBasicBinDir}/test1.h" COPYONLY) +sleep() +rebuild(4) +acquire_timestamp(After) +require_change() + + +# - Ensure that the timestamp will change +# - Add Q_OBJECT to header again +# - Rebuild +acquire_timestamp(Before) +sleep() +message(STATUS "Add Q_OBJECT to test1.h for a MOC re-run") +configure_file("${mocBasicSrcDir}/test1a.h.in" "${mocBasicBinDir}/test1.h" COPYONLY) +sleep() +rebuild(5) +acquire_timestamp(After) +require_change() + + +# - Ensure that the timestamp will change +# - Add Q_OBJECT to MyObject3 +# - Rebuild +acquire_timestamp(Before) +sleep() +message(STATUS "Add Q_OBJECT to myobject3.h file for a MOC re-run") +set(CLASS_CONTENT "Q_OBJECT") +configure_file("${mocBasicSrcDir}/myobject3a.h.in" "${mocBasicBinDir}/myobject3.h" @ONLY) +sleep() +rebuild(6) +acquire_timestamp(After) +require_change() diff --git a/Tests/QtAutogen/RerunMocBasic/MocBasic/CMakeLists.txt b/Tests/QtAutogen/RerunMocBasic/MocBasic/CMakeLists.txt index 6a9f550..42f2f57 100644 --- a/Tests/QtAutogen/RerunMocBasic/MocBasic/CMakeLists.txt +++ b/Tests/QtAutogen/RerunMocBasic/MocBasic/CMakeLists.txt @@ -13,10 +13,15 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/main.cpp add_executable(mocBasic ${CMAKE_CURRENT_BINARY_DIR}/test1.h + ${CMAKE_CURRENT_BINARY_DIR}/myobject3.h ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + plainobject.cpp res1.qrc ) -target_include_directories(mocBasic PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_include_directories(mocBasic PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) target_link_libraries(mocBasic ${QT_QTCORE_TARGET}) # Write target name to text file add_custom_command(TARGET mocBasic POST_BUILD COMMAND diff --git a/Tests/QtAutogen/RerunMocBasic/MocBasic/main.cpp.in b/Tests/QtAutogen/RerunMocBasic/MocBasic/main.cpp.in index 9d7ea37..5accfd6 100644 --- a/Tests/QtAutogen/RerunMocBasic/MocBasic/main.cpp.in +++ b/Tests/QtAutogen/RerunMocBasic/MocBasic/main.cpp.in @@ -1,4 +1,5 @@ #include "test1.h" +#include "plainobject.h" extern int qInitResources_res1(); @@ -16,6 +17,7 @@ int main() Test1 test1; Test2 test2; + PlainObject plainObject; return 0; } diff --git a/Tests/QtAutogen/RerunMocBasic/MocBasic/myobject3a.h.in b/Tests/QtAutogen/RerunMocBasic/MocBasic/myobject3a.h.in new file mode 100644 index 0000000..d62c314 --- /dev/null +++ b/Tests/QtAutogen/RerunMocBasic/MocBasic/myobject3a.h.in @@ -0,0 +1,13 @@ +#ifndef MYOBJECT3_H +#define MYOBJECT3_H + +#include <qobject.h> + +class MyObject3 : public QObject +{ + @CLASS_CONTENT@ +public: + MyObject3() {} +}; + +#endif diff --git a/Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.cpp b/Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.cpp new file mode 100644 index 0000000..0ca785e --- /dev/null +++ b/Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.cpp @@ -0,0 +1,12 @@ +#include "plainobject.h" + +#include "myobject3.h" + +PlainObject::PlainObject() +{ +} + +void PlainObject::doSomething() +{ + MyObject3 obj3; +} diff --git a/Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.h b/Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.h new file mode 100644 index 0000000..8037858 --- /dev/null +++ b/Tests/QtAutogen/RerunMocBasic/MocBasic/plainobject.h @@ -0,0 +1,12 @@ +#ifndef PLAINOBJECT_H +#define PLAINOBJECT_H + +// Class that is plain C++, no Qt involved. +class PlainObject +{ +public: + PlainObject(); + void doSomething(); +}; + +#endif diff --git a/Tests/QtAutogen/RerunMocBasic/MocBasic/test1c.h.in b/Tests/QtAutogen/RerunMocBasic/MocBasic/test1c.h.in new file mode 100644 index 0000000..d0b9868 --- /dev/null +++ b/Tests/QtAutogen/RerunMocBasic/MocBasic/test1c.h.in @@ -0,0 +1,6 @@ +#include <QObject> +class Test1 +{ +public: + void onTst1() {} +}; diff --git a/Tests/QtAutomocNoQt/CMakeLists.txt b/Tests/QtAutomocNoQt/CMakeLists.txt index b26e471..655f12b 100644 --- a/Tests/QtAutomocNoQt/CMakeLists.txt +++ b/Tests/QtAutomocNoQt/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(QtAutomocNoQt) diff --git a/Tests/RunCMake/BuildDepends/CMakeLists.txt b/Tests/RunCMake/BuildDepends/CMakeLists.txt index 74b3ff8..99f238b 100644 --- a/Tests/RunCMake/BuildDepends/CMakeLists.txt +++ b/Tests/RunCMake/BuildDepends/CMakeLists.txt @@ -1,3 +1,3 @@ cmake_minimum_required(VERSION 3.3) project(${RunCMake_TEST} NONE) -include(${RunCMake_TEST}.cmake) +include(${RunCMake_TEST}.cmake NO_POLICY_SCOPE) diff --git a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake index 6ac1291..01eac91 100644 --- a/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake +++ b/Tests/RunCMake/BuildDepends/CustomCommandDepfile.cmake @@ -4,7 +4,7 @@ enable_language(C) add_custom_command( OUTPUT topcc.c DEPFILE topcc.c.d - COMMAND ${CMAKE_COMMAND} -DOUTFILE=topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" + COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/topcc.c -DINFILE=topccdep.txt -DDEPFILE=topcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/WriteDepfile.cmake" ) add_custom_target(topcc ALL DEPENDS topcc.c) diff --git a/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt b/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt index 06db47c..f131751 100644 --- a/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt +++ b/Tests/RunCMake/BuildDepends/DepfileSubdir/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0116 NEW) add_custom_command( OUTPUT subcc.c DEPFILE subcc.c.d - COMMAND ${CMAKE_COMMAND} -DOUTFILE=subcc.c -DINFILE=subccdep.txt -DDEPFILE=subcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/../WriteDepfile.cmake" + COMMAND ${CMAKE_COMMAND} -DOUTFILE=${CMAKE_CURRENT_BINARY_DIR}/subcc.c -DINFILE=subccdep.txt -DDEPFILE=subcc.c.d -P "${CMAKE_CURRENT_LIST_DIR}/../WriteDepfile.cmake" ) add_custom_target(subcc ALL DEPENDS subcc.c) diff --git a/Tests/RunCMake/BuildDepends/MakeDependencies.cmake b/Tests/RunCMake/BuildDepends/MakeDependencies.cmake new file mode 100644 index 0000000..33e8c7e --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeDependencies.cmake @@ -0,0 +1,13 @@ +enable_language(C) + +add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c) + +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +set(check_pairs + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\" + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.h\" + ) +set(check_exes + \"$<TARGET_FILE:main>\" + ) +") diff --git a/Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake b/Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake new file mode 100644 index 0000000..c74f033 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake @@ -0,0 +1,18 @@ +file(TOUCH "${RunCMake_TEST_BINARY_DIR}/main.c") +foreach(i RANGE 1 20000) + file(WRITE "${RunCMake_TEST_BINARY_DIR}/temp_header_file_${i}.h" + "#define HEADER_${i} ${i}\n" + ) + file(APPEND "${RunCMake_TEST_BINARY_DIR}/main.c" + "#include \"temp_header_file_${i}.h\"\n" + ) +endforeach() +file(APPEND "${RunCMake_TEST_BINARY_DIR}/main.c" + "#include \"main.h\"\n" + ) +file(APPEND "${RunCMake_TEST_BINARY_DIR}/main.c" + "int main(void) { return COUNT; }\n" + ) +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.h" + "#define COUNT 1\n" + ) diff --git a/Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake b/Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake new file mode 100644 index 0000000..c826d3c --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.h" + "#define COUNT 2\n" + ) diff --git a/Tests/RunCMake/BuildDepends/RepeatCMake-Custom-Script.cmake b/Tests/RunCMake/BuildDepends/RepeatCMake-Custom-Script.cmake new file mode 100644 index 0000000..3e953b3 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/RepeatCMake-Custom-Script.cmake @@ -0,0 +1,4 @@ +if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/exists-for-build2") + message(FATAL_ERROR "Custom command incorrectly re-ran after CMake re-ran!") +endif() +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/out.txt") diff --git a/Tests/RunCMake/BuildDepends/RepeatCMake-Custom.cmake b/Tests/RunCMake/BuildDepends/RepeatCMake-Custom.cmake new file mode 100644 index 0000000..697e485 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/RepeatCMake-Custom.cmake @@ -0,0 +1,5 @@ +add_custom_command(OUTPUT out.txt + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/RepeatCMake-Custom-Script.cmake + DEPENDS ${CMAKE_CURRENT_LIST_DIR}/RepeatCMake-Custom-Script.cmake + ) +add_custom_target(drive ALL DEPENDS out.txt) diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index 1b7b8d9..6232634 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -79,6 +79,23 @@ if(RunCMake_GENERATOR MATCHES "Make") endif() endif() +function(run_RepeatCMake CASE) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build) + if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug) + else() + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug) + endif() + run_cmake(${CASE}) + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(${CASE}-build1 ${CMAKE_COMMAND} --build . --config Debug) + run_cmake_command(${CASE}-rerun1 ${CMAKE_COMMAND} .) + file(WRITE ${RunCMake_TEST_BINARY_DIR}/exists-for-build2 "") + run_cmake_command(${CASE}-build2 ${CMAKE_COMMAND} --build . --config Debug) +endfunction() + +run_RepeatCMake(RepeatCMake-Custom) + function(run_ReGeneration) # test re-generation of project even if CMakeLists.txt files disappeared @@ -143,3 +160,7 @@ if(RunCMake_GENERATOR MATCHES "Make|Ninja") run_BuildDepends(CustomCommandDepfile) set(run_BuildDepends_skip_step_3 1) endif() + +if(RunCMake_GENERATOR MATCHES "Make") + run_BuildDepends(MakeDependencies) +endif() diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 540a718..d1122d0 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -796,7 +796,10 @@ add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} add_RunCMake_test("UnityBuild") add_RunCMake_test(CMakePresets -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA}) -add_RunCMake_test(TransformDepfile) + +if(${CMAKE_GENERATOR} MATCHES "Make|Ninja") + add_RunCMake_test(TransformDepfile) +endif() if(WIN32) add_RunCMake_test(Win32GenEx) diff --git a/Tests/RunCMake/CPack/tests/EXTRA/DEB-stderr.txt b/Tests/RunCMake/CPack/tests/EXTRA/DEB-stderr.txt new file mode 100644 index 0000000..37360e8 --- /dev/null +++ b/Tests/RunCMake/CPack/tests/EXTRA/DEB-stderr.txt @@ -0,0 +1,6 @@ +CPack Warning: Adding file to tar: +#top level directory: .*/Tests/RunCMake/DEB.EXTRA/CPack/EXTRA-build/_CPack_Packages/Linux/DEB/extra-0.1.1-Linux/bas +#missing file: .*/Tests/RunCMake/DEB.EXTRA/CPack/EXTRA-build/conffiles +CPack Warning: Adding file to tar: +#top level directory: .*/Tests/RunCMake/DEB.EXTRA/CPack/EXTRA-build/_CPack_Packages/Linux/DEB/extra-0.1.1-Linux/foo +#missing file: .*/Tests/RunCMake/DEB.EXTRA/CPack/EXTRA-build/conffiles diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt index a8b6584..c76c92d 100644 --- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt +++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt @@ -1 +1 @@ -^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":2}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"version":{.*}}$ +^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":2}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"version":{.*}}$ diff --git a/Tests/RunCMake/CommandLine/cmake_depends-check.cmake b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake index 031478b..e0e3054 100644 --- a/Tests/RunCMake/CommandLine/cmake_depends-check.cmake +++ b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake @@ -3,8 +3,9 @@ if(EXISTS "${depend_make}") file(READ "${depend_make}" depend_make_content) string(REGEX REPLACE "\n+$" "" depend_make_content "${depend_make_content}") if(NOT depend_make_content MATCHES " -CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.c -CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.h$") +CMakeFiles/DepTarget.dir/test.c.o: \\\\ + .*/Tests/RunCMake/CommandLine/cmake_depends/test.c \\\\ + .*/Tests/RunCMake/CommandLine/cmake_depends/test.h$") string(REPLACE "\n" "\n " depend_make_content " ${depend_make_content}") set(RunCMake_TEST_FAILED "depend.make does not have expected content:\n${depend_make_content}") endif() diff --git a/Tests/RunCMake/CommandLine/trace-expand.cmake b/Tests/RunCMake/CommandLine/trace-expand.cmake index e69de29..24da02a 100644 --- a/Tests/RunCMake/CommandLine/trace-expand.cmake +++ b/Tests/RunCMake/CommandLine/trace-expand.cmake @@ -0,0 +1 @@ +set(a [[\B]]) diff --git a/Tests/RunCMake/ExportCompileCommands/Properties.cmake b/Tests/RunCMake/ExportCompileCommands/Properties.cmake new file mode 100644 index 0000000..c7a38b7 --- /dev/null +++ b/Tests/RunCMake/ExportCompileCommands/Properties.cmake @@ -0,0 +1,22 @@ +enable_language(C) + +add_library(Unset STATIC empty.c) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +add_library(SetOn STATIC empty.c) +set(CMAKE_EXPORT_COMPILE_COMMANDS OFF) +add_library(SetOff STATIC empty.c) + +get_property(_set TARGET Unset PROPERTY EXPORT_COMPILE_COMMANDS) +if(_set) + message(SEND_ERROR "EXPORT_COMPILE_COMMANDS property should be unset for Unset target (got \"${_set}\")") +endif() + +get_property(_on TARGET SetOn PROPERTY EXPORT_COMPILE_COMMANDS) +if(NOT _on STREQUAL "ON") + message(SEND_ERROR "EXPORT_COMPILE_COMMANDS property should be \"ON\" for SetOn target (got \"${_on}\")") +endif() + +get_property(_off TARGET SetOff PROPERTY EXPORT_COMPILE_COMMANDS) +if(NOT _off STREQUAL "OFF") + message(SEND_ERROR "EXPORT_COMPILE_COMMANDS property should be \"OFF\" for SetOff target (got \"${_off}\")") +endif() diff --git a/Tests/RunCMake/ExportCompileCommands/PropertiesGenerateCommand-check.cmake b/Tests/RunCMake/ExportCompileCommands/PropertiesGenerateCommand-check.cmake new file mode 100644 index 0000000..d698742 --- /dev/null +++ b/Tests/RunCMake/ExportCompileCommands/PropertiesGenerateCommand-check.cmake @@ -0,0 +1,32 @@ +if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json") + set(RunCMake_TEST_FAILED "compile_commands.json not generated") + return() +endif() + +file(READ "${RunCMake_TEST_BINARY_DIR}/compile_commands.json" compile_commands) + +macro(check_error) + if(error) + message(SEND_ERROR "Unexpected error \"${error}\"\nFor: ${compile_commands}") + endif() +endmacro() + +string(JSON num_commands ERROR_VARIABLE error LENGTH "${compile_commands}") +check_error() + +# Only one of the targets has the EXPORT_COMPILE_COMMANDS property enabled. +if(NOT num_commands STREQUAL 1) + message(SEND_ERROR "Expected 1 compile command, got ${num_commands} for ${compile_commands}") +endif() + +# Get the compile command generated. +string(JSON result ERROR_VARIABLE error GET "${compile_commands}" 0) +check_error() +string(JSON result ERROR_VARIABLE error GET "${result}" file) +check_error() + +# And ensure the correct target is in that compile command. +cmake_path(COMPARE "${result}" EQUAL "${RunCMake_TEST_SOURCE_DIR}/expected_file.c" good) +if(NOT good) + message(SEND_ERROR "Expected \"${result}\" in \"${RunCMake_TEST_SOURCE_DIR}/expected_file.c\"") +endif() diff --git a/Tests/RunCMake/ExportCompileCommands/PropertiesGenerateCommand.cmake b/Tests/RunCMake/ExportCompileCommands/PropertiesGenerateCommand.cmake new file mode 100644 index 0000000..46c8845 --- /dev/null +++ b/Tests/RunCMake/ExportCompileCommands/PropertiesGenerateCommand.cmake @@ -0,0 +1,7 @@ +enable_language(C) + +add_library(Unset STATIC empty.c) +add_library(ToBeSet STATIC expected_file.c) + +# Only one target with EXPORT_COMPILE_COMMANDS property. +set_property(TARGET ToBeSet PROPERTY EXPORT_COMPILE_COMMANDS TRUE) diff --git a/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake b/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake index 9e7e732..b691637 100644 --- a/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake @@ -1,4 +1,12 @@ include(RunCMake) +if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug) +else() + set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug) +endif() + run_cmake_with_options(BeforeProject -DCMAKE_PROJECT_INCLUDE_BEFORE=BeforeProjectBEFORE.cmake) run_cmake(CustomCompileRule) +run_cmake(Properties) +run_cmake(PropertiesGenerateCommand) diff --git a/Tests/RunCMake/ExportCompileCommands/expected_file.c b/Tests/RunCMake/ExportCompileCommands/expected_file.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/Tests/RunCMake/ExportCompileCommands/expected_file.c diff --git a/Tests/RunCMake/ExternalProject/CONFIGURE_HANDLED_BY_BUILD-rebuild-check.cmake b/Tests/RunCMake/ExternalProject/CONFIGURE_HANDLED_BY_BUILD-rebuild-check.cmake new file mode 100644 index 0000000..887da0f --- /dev/null +++ b/Tests/RunCMake/ExternalProject/CONFIGURE_HANDLED_BY_BUILD-rebuild-check.cmake @@ -0,0 +1,19 @@ +file(TIMESTAMP "${STAMP_DIR}/proj1-configure" PROJ1_CONFIGURE_TIMESTAMP_AFTER "%s") +# When BUILD_ALWAYS is set, the build stamp is never created. +file(TIMESTAMP "${STAMP_DIR}/proj2-configure" PROJ2_CONFIGURE_TIMESTAMP_AFTER "%s") +file(TIMESTAMP "${STAMP_DIR}/proj2-build" PROJ2_BUILD_TIMESTAMP_AFTER "%s") + +if(NOT PROJ1_CONFIGURE_TIMESTAMP_BEFORE EQUAL PROJ1_CONFIGURE_TIMESTAMP_AFTER) + set(RunCMake_TEST_FAILED "Unexpected rebuild of proj1 configure step (${PROJ1_CONFIGURE_TIMESTAMP_BEFORE} != ${PROJ1_CONFIGURE_TIMESTAMP_AFTER})") + return() +endif() + +if(NOT PROJ2_CONFIGURE_TIMESTAMP_BEFORE EQUAL PROJ2_CONFIGURE_TIMESTAMP_AFTER) + set(RunCMake_TEST_FAILED "Unexpected rebuild of proj2 configure step (${PROJ2_CONFIGURE_TIMESTAMP_BEFORE} != ${PROJ2_CONFIGURE_TIMESTAMP_AFTER})") + return() +endif() + +if(PROJ2_BUILD_TIMESTAMP_BEFORE EQUAL PROJ2_BUILD_TIMESTAMP_AFTER) + set(RunCMake_TEST_FAILED "proj2 build step did not rebuild (${PROJ2_BUILD_TIMESTAMP_BEFORE} != ${PROJ2_BUILD_TIMESTAMP_AFTER})") + return() +endif() diff --git a/Tests/RunCMake/ExternalProject/CONFIGURE_HANDLED_BY_BUILD.cmake b/Tests/RunCMake/ExternalProject/CONFIGURE_HANDLED_BY_BUILD.cmake new file mode 100644 index 0000000..c86a60e --- /dev/null +++ b/Tests/RunCMake/ExternalProject/CONFIGURE_HANDLED_BY_BUILD.cmake @@ -0,0 +1,28 @@ +include(ExternalProject) + +# Given this setup, on the first build, both configure steps and both build +# steps will run. On a noop rebuild, only the build steps will run. Without +# CONFIGURE_HANDLED_BY_BUILD, the configure step of proj2 would also run on a +# noop rebuild. + +ExternalProject_Add(proj1 + DOWNLOAD_COMMAND "" + SOURCE_DIR "" + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E echo "Doing something" + # file(TIMESTAMP) gives back the timestamp in seconds so we sleep a second to + # make sure we get a different timestamp on the stamp file + BUILD_COMMAND ${CMAKE_COMMAND} -E sleep 1 + INSTALL_COMMAND "" + BUILD_ALWAYS ON + STAMP_DIR "stamp" +) +ExternalProject_Add(proj2 + DOWNLOAD_COMMAND "" + SOURCE_DIR "" + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E echo "Doing something" + BUILD_COMMAND ${CMAKE_COMMAND} -E sleep 1 + INSTALL_COMMAND "" + CONFIGURE_HANDLED_BY_BUILD ON + DEPENDS proj1 + STAMP_DIR "stamp" +) diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake index 598671f..22b8d24 100644 --- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake @@ -151,3 +151,33 @@ endif() if(doSubstitutionTest) __ep_test_with_build(Substitutions) endif() + +function(__ep_test_CONFIGURE_HANDLED_BY_BUILD) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CONFIGURE_HANDLED_BY_BUILD-build) + run_cmake(CONFIGURE_HANDLED_BY_BUILD) + + if(RunCMake_GENERATOR_IS_MULTI_CONFIG) + set(BUILD_CONFIG --config Debug) + set(STAMP_DIR "${RunCMake_TEST_BINARY_DIR}/stamp/Debug") + else() + set(BUILD_CONFIG "") + set(STAMP_DIR "${RunCMake_TEST_BINARY_DIR}/stamp") + endif() + + set(RunCMake_TEST_NO_CLEAN 1) + run_cmake_command(CONFIGURE_HANDLED_BY_BUILD-build ${CMAKE_COMMAND} --build . ${BUILD_CONFIG}) + + # Calculate timestamps before rebuilding so we can compare before and after in + # CONFIGURE_HANDLED_BY_BUILD-rebuild-check.cmake + + file(TIMESTAMP "${STAMP_DIR}/proj1-configure" PROJ1_CONFIGURE_TIMESTAMP_BEFORE "%s") + # When BUILD_ALWAYS is set, the build stamp is never created. + file(TIMESTAMP "${STAMP_DIR}/proj2-configure" PROJ2_CONFIGURE_TIMESTAMP_BEFORE "%s") + file(TIMESTAMP "${STAMP_DIR}/proj2-build" PROJ2_BUILD_TIMESTAMP_BEFORE "%s") + + run_cmake_command(CONFIGURE_HANDLED_BY_BUILD-rebuild ${CMAKE_COMMAND} --build . ${BUILD_CONFIG}) +endfunction() + +if(NOT RunCMake_GENERATOR MATCHES "Visual Studio 9 ") + __ep_test_CONFIGURE_HANDLED_BY_BUILD() +endif() diff --git a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake index 2bb2765..ae3d179 100644 --- a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake +++ b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake @@ -24,6 +24,7 @@ function(check_python case) file(GLOB index ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/reply/index-*.json) execute_process( COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py" "${index}" "${CMAKE_CXX_COMPILER_ID}" + "${RunCMake_TEST_BINARY_DIR}" RESULT_VARIABLE result OUTPUT_VARIABLE output ERROR_VARIABLE output @@ -62,3 +63,4 @@ endfunction() run_object(codemodel-v2) run_object(cache-v2) run_object(cmakeFiles-v1) +run_object(toolchains-v1) diff --git a/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateful-check.cmake b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateful-check.cmake new file mode 100644 index 0000000..ce38461 --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateful-check.cmake @@ -0,0 +1,11 @@ +set(expect + query + query/client-foo + query/client-foo/query.json + reply + reply/index-[0-9.T-]+.json + reply/toolchains-v1-[0-9a-f]+.json + ) +check_api("^${expect}$") + +check_python(toolchains-v1) diff --git a/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateful-prep.cmake b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateful-prep.cmake new file mode 100644 index 0000000..ca62edf --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateful-prep.cmake @@ -0,0 +1,4 @@ +file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/query) +file(WRITE "${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/query/client-foo/query.json" [[ +{ "requests": [ { "kind": "toolchains", "version" : 1 } ] } +]]) diff --git a/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateless-check.cmake b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateless-check.cmake new file mode 100644 index 0000000..4676dd8 --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateless-check.cmake @@ -0,0 +1,11 @@ +set(expect + query + query/client-foo + query/client-foo/toolchains-v1 + reply + reply/index-[0-9.T-]+.json + reply/toolchains-v1-[0-9a-f]+.json + ) +check_api("^${expect}$") + +check_python(toolchains-v1) diff --git a/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateless-prep.cmake b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateless-prep.cmake new file mode 100644 index 0000000..7edff93 --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1-ClientStateless-prep.cmake @@ -0,0 +1,2 @@ +file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/query) +file(WRITE "${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/query/client-foo/toolchains-v1" "") diff --git a/Tests/RunCMake/FileAPI/toolchains-v1-SharedStateless-check.cmake b/Tests/RunCMake/FileAPI/toolchains-v1-SharedStateless-check.cmake new file mode 100644 index 0000000..8e83758 --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1-SharedStateless-check.cmake @@ -0,0 +1,10 @@ +set(expect + query + query/toolchains-v1 + reply + reply/index-[0-9.T-]+.json + reply/toolchains-v1-[0-9a-f]+.json + ) +check_api("^${expect}$") + +check_python(toolchains-v1) diff --git a/Tests/RunCMake/FileAPI/toolchains-v1-SharedStateless-prep.cmake b/Tests/RunCMake/FileAPI/toolchains-v1-SharedStateless-prep.cmake new file mode 100644 index 0000000..2db73a1 --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1-SharedStateless-prep.cmake @@ -0,0 +1,2 @@ +file(REMOVE_RECURSE ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/query) +file(WRITE "${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/query/toolchains-v1" "") diff --git a/Tests/RunCMake/FileAPI/toolchains-v1-check.py b/Tests/RunCMake/FileAPI/toolchains-v1-check.py new file mode 100644 index 0000000..a0e50c2 --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1-check.py @@ -0,0 +1,86 @@ +from check_index import * +import os + +class ExpectedVar(object): + def __init__(self, name): + self.name = name + +class ExpectedList(object): + def __init__(self, name): + self.name = name + +EXPECTED_TOOLCHAIN = { + "language": "CXX", + "compiler": { + "path": ExpectedVar("CMAKE_CXX_COMPILER"), + "id": ExpectedVar("CMAKE_CXX_COMPILER_ID"), + "version": ExpectedVar("CMAKE_CXX_COMPILER_VERSION"), + "target": ExpectedVar("CMAKE_CXX_COMPILER_TARGET"), + "implicit": { + "includeDirectories": \ + ExpectedList("CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES"), + "linkDirectories": \ + ExpectedList("CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES"), + "linkFrameworkDirectories": \ + ExpectedList( + "CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"), + "linkLibraries": \ + ExpectedList("CMAKE_CXX_IMPLICIT_LINK_LIBRARIES"), + } + }, + "sourceFileExtensions": \ + ExpectedList("CMAKE_CXX_SOURCE_FILE_EXTENSIONS"), +} + +def check_objects(o): + assert is_list(o) + assert len(o) == 1 + check_index_object(o[0], "toolchains", 1, 0, check_object_toolchains) + +def check_object_toolchains(o): + assert sorted(o.keys()) == ["kind", "toolchains", "version"] + # The "kind" and "version" members are handled by check_index_object. + toolchains = o["toolchains"] + assert is_list(toolchains) + + # Other platform-specific toolchains may exist (like RC on Windows). + has_cxx_toolchain = False + for toolchain in toolchains: + assert is_dict(toolchain) + assert "language" in toolchain + if toolchain["language"] == "CXX": + check_object_toolchain(toolchain, EXPECTED_TOOLCHAIN) + has_cxx_toolchain = True + + assert has_cxx_toolchain + +def check_object_toolchain(o, expected): + expected_keys = [ + key for (key, value) in expected.items() + if is_string(value) or is_dict(value) + or (type(value) in (ExpectedVar, ExpectedList) + and variables[value.name]["defined"])] + assert sorted(o.keys()) == sorted(expected_keys) + + for key in expected_keys: + value = expected[key] + if is_string(value): + assert o[key] == value + elif is_dict(value): + check_object_toolchain(o[key], value) + elif type(value) == ExpectedVar: + assert o[key] == variables[value.name]["value"] + elif type(value) == ExpectedList: + expected_items = filter( + None, variables[value.name]["value"].split(";")) + check_list_match(lambda a, b: a == b, o[key], expected_items) + else: + assert False + +with open(os.path.join(sys.argv[3], "toolchain_variables.json")) as f: + variables = json.load(f) + +assert is_dict(variables) +assert is_dict(index) +assert sorted(index.keys()) == ["cmake", "objects", "reply"] +check_objects(index["objects"]) diff --git a/Tests/RunCMake/FileAPI/toolchains-v1.cmake b/Tests/RunCMake/FileAPI/toolchains-v1.cmake new file mode 100644 index 0000000..367aade --- /dev/null +++ b/Tests/RunCMake/FileAPI/toolchains-v1.cmake @@ -0,0 +1,22 @@ +enable_language(CXX) + +set(variable_suffixes + COMPILER COMPILER_ID COMPILER_VERSION COMPILER_TARGET + IMPLICIT_INCLUDE_DIRECTORIES IMPLICIT_LINK_DIRECTORIES + IMPLICIT_LINK_FRAMEWORK_DIRECTORIES IMPLICIT_LINK_LIBRARIES + SOURCE_FILE_EXTENSIONS) +set(language CXX) +set(json "{}") + +foreach(variable_suffix ${variable_suffixes}) + set(variable "CMAKE_${language}_${variable_suffix}") + string(JSON json SET "${json}" "${variable}" "{}") + if(DEFINED "${variable}") + string(JSON json SET "${json}" "${variable}" "defined" "true") + string(JSON json SET "${json}" "${variable}" "value" "\"${${variable}}\"") + else() + string(JSON json SET "${json}" "${variable}" "defined" "false") + endif() +endforeach() + +file(WRITE ${CMAKE_BINARY_DIR}/toolchain_variables.json "${json}") diff --git a/Tests/RunCMake/NinjaMultiConfig/PostBuild-debug-in-release-graph-build-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/PostBuild-debug-in-release-graph-build-stdout.txt new file mode 100644 index 0000000..fad923a --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/PostBuild-debug-in-release-graph-build-stdout.txt @@ -0,0 +1,2 @@ +Running post-build command with Debug +Generating Debug\.txt diff --git a/Tests/RunCMake/NinjaMultiConfig/PostBuild-release-build-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/PostBuild-release-build-stdout.txt new file mode 100644 index 0000000..485a52c --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/PostBuild-release-build-stdout.txt @@ -0,0 +1,3 @@ +Running post-build command with Release +Generating out\.txt with Release +Generating Release\.txt diff --git a/Tests/RunCMake/NinjaMultiConfig/PostBuild.cmake b/Tests/RunCMake/NinjaMultiConfig/PostBuild.cmake new file mode 100644 index 0000000..5fcff74 --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/PostBuild.cmake @@ -0,0 +1,6 @@ +enable_language(C) + +add_executable(Exe main.c) +add_custom_command(TARGET Exe POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Running post-build command with $<CONFIG>") +add_custom_command(TARGET Exe POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Generating out.txt with $<CONFIG>" BYPRODUCTS out.txt) +add_custom_command(TARGET Exe POST_BUILD COMMAND ${CMAKE_COMMAND} -E echo "Generating $<CONFIG>.txt" BYPRODUCTS $<CONFIG>.txt) diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index dc2db57..480d628 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -187,6 +187,12 @@ run_ninja(SimpleCrossConfigs clean-all-in-release-graph build-Release.ninja clea run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all) run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo) +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostBuild-build) +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") +run_cmake_configure(PostBuild) +run_cmake_build(PostBuild release Release Exe) +run_cmake_build(PostBuild debug-in-release-graph Release Exe:Debug) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build) set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(Framework) diff --git a/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake b/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake index cb75eb0..9a38b95 100644 --- a/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake +++ b/Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake @@ -3,11 +3,11 @@ include(RunCMake) function(run_transform_depfile name) set(RunCMake-check-file gccdepfile.cmake) run_cmake_command(${name}-gcc - ${CMAKE_COMMAND} -E cmake_transform_depfile gccdepfile ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.d + ${CMAKE_COMMAND} -E cmake_transform_depfile "${RunCMake_GENERATOR}" gccdepfile "${RunCMake_SOURCE_DIR}" "${RunCMake_SOURCE_DIR}/subdir" "${RunCMake_BINARY_DIR}" "${RunCMake_BINARY_DIR}/subdir" "${CMAKE_CURRENT_LIST_DIR}/${name}.d" out.d ) set(RunCMake-check-file vstlog.cmake) run_cmake_command(${name}-tlog - ${CMAKE_COMMAND} -E cmake_transform_depfile vstlog ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.tlog + ${CMAKE_COMMAND} -E cmake_transform_depfile "${RunCMake_GENERATOR}" vstlog "${RunCMake_SOURCE_DIR}" "${RunCMake_SOURCE_DIR}/subdir" "${RunCMake_BINARY_DIR}" "${RunCMake_BINARY_DIR}/subdir" "${CMAKE_CURRENT_LIST_DIR}/${name}.d" out.tlog ) endfunction() diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.d.txt b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt index 58770f2..fbdecc0 100644 --- a/Tests/RunCMake/TransformDepfile/deps-unix.d.txt +++ b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt @@ -1,8 +1,8 @@ -../out1 \ +subdir/out1 \ /home/build/out2: \ - ../in1 \ + subdir/in1 \ /home/build/in2 -../out3 \ +subdir/out3 \ /home/build/out4: \ - ../in3 \ + subdir/in3 \ /home/build/in4 diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt b/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt index 2a26edf..70bac5d 100644 --- a/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt +++ b/Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt @@ -1,6 +1,6 @@ -^../out1|/home/build/out2 -../in1 +^subdir/out1|/home/build/out2 +subdir/in1 /home/build/in2 -^../out3|/home/build/out4 -../in3 +^subdir/out3|/home/build/out4 +subdir/in3 /home/build/in4 diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.d.txt b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt index 47b3ebf..e09ae37 100644 --- a/Tests/RunCMake/TransformDepfile/deps-windows.d.txt +++ b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt @@ -1,8 +1,8 @@ -../out1 \ +subdir/out1 \ C:/build/out2: \ - ../in1 \ + subdir/in1 \ C:/build/in2 -../out3 \ +subdir/out3 \ C:/build/out4: \ - ../in3 \ + subdir/in3 \ C:/build/in4 diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt b/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt index 1e6024d..09f9e97 100644 --- a/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt +++ b/Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt @@ -1,6 +1,6 @@ -^..\out1|C:\build\out2 -..\in1 +^subdir\out1|C:\build\out2 +subdir\in1 C:\build\in2 -^..\out3|C:\build\out4 -..\in3 +^subdir\out3|C:\build\out4 +subdir\in3 C:\build\in4 diff --git a/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt b/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt index d00491f..0cfbf08 100644 --- a/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt +++ b/Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt @@ -1 +1 @@ -1 +2 diff --git a/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt b/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt index d00491f..0cfbf08 100644 --- a/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt +++ b/Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt @@ -1 +1 @@ -1 +2 diff --git a/Tests/RunCMake/cmake_path/HASH.cmake b/Tests/RunCMake/cmake_path/HASH.cmake index dfcf2b2..eb04f7f 100644 --- a/Tests/RunCMake/cmake_path/HASH.cmake +++ b/Tests/RunCMake/cmake_path/HASH.cmake @@ -14,11 +14,6 @@ set (path1 "a///b/c/../d") cmake_path(HASH path1 hash1) set (path2 "a/b////d") cmake_path(HASH path2 hash2) -if (hash1 STREQUAL hash2) - list (APPEND errors "'hash values equal for '${path1}' and '${path2}'") -endif() -cmake_path(HASH path1 hash1 NORMALIZE) -cmake_path(HASH path2 NORMALIZE hash2) if (NOT hash1 STREQUAL hash2) list (APPEND errors "'hash values not equal for '${path1}' and '${path2}'") endif() diff --git a/Tests/RunCMake/cmake_path/IS_PREFIX.cmake b/Tests/RunCMake/cmake_path/IS_PREFIX.cmake index 53da93b..9160dab 100644 --- a/Tests/RunCMake/cmake_path/IS_PREFIX.cmake +++ b/Tests/RunCMake/cmake_path/IS_PREFIX.cmake @@ -18,5 +18,10 @@ if (NOT output) list (APPEND errors "'${path} is not prefix of 'a/b/d/e'") endif() +set(path "/a/b/..") +cmake_path(IS_PREFIX path "/a/c/../b" NORMALIZE output) +if (NOT output) + list (APPEND errors "'${path} is not prefix of '/a/c/../b'") +endif() check_errors (IS_PREFIX ${errors}) diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-all-check.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-all-check.cmake index e6f2623..e7cdbf6 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-all-check.cmake +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-all-check.cmake @@ -148,6 +148,27 @@ set(_check ) check_contents(deps/udeps6.txt "^${_check}$") +# Weak library reference should have exactly the same dependencies as a regular library reference (test 1) +set_with_libsystem(_check + [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/bin/../lib/executable_path/libexecutable_path\.dylib]] + [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/bin/../lib/rpath_executable_path/librpath_executable_path\.dylib]] + [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/libtestlib\.dylib]] + [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/loader_path/libloader_path\.dylib]] + [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/../rpath/librpath\.dylib]] + [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/normal/libnormal\.dylib]] + [[[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/rpath_loader_path/librpath_loader_path\.dylib]] + ) +check_contents(deps/deps7.txt "^${_check}$") + +set(_check + [[@executable_path/../lib/executable_path_bundle/libexecutable_path_bundle\.dylib]] + [[@loader_path/loader_path_unresolved/libloader_path_unresolved\.dylib]] + [[@rpath/librpath_executable_path_bundle\.dylib]] + [[@rpath/librpath_loader_path_unresolved\.dylib]] + [[@rpath/librpath_unresolved\.dylib]] + ) +check_contents(deps/udeps7.txt "^${_check}$") + set(_check "^libconflict\\.dylib:[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/conflict/libconflict\\.dylib;[^;]*/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos-build/root-all/executable/lib/conflict2/libconflict\\.dylib\n$" ) @@ -157,3 +178,4 @@ check_contents(deps/cdeps3.txt "${_check}") check_contents(deps/cdeps4.txt "${_check}") check_contents(deps/cdeps5.txt "${_check}") check_contents(deps/cdeps6.txt "${_check}") +check_contents(deps/cdeps7.txt "${_check}") diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos.cmake b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos.cmake index c56a14b..aab19b7 100644 --- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos.cmake +++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/macos.cmake @@ -128,16 +128,19 @@ endforeach() target_link_libraries(testlib PRIVATE ${testlib_names}) add_executable(topexe macos/topexe.c) +add_executable(topexe_weak macos/topexe.c) add_library(toplib SHARED macos/toplib.c) add_library(topmod MODULE macos/toplib.c) target_link_libraries(topexe PRIVATE testlib) +target_link_libraries(topexe_weak PRIVATE "-weak_library" testlib) target_link_libraries(toplib PRIVATE testlib) target_link_libraries(topmod PRIVATE testlib) set_property(TARGET topexe toplib topmod PROPERTY INSTALL_RPATH "${CMAKE_BINARY_DIR}/root-all/executable/lib") +set_property(TARGET topexe_weak toplib topmod PROPERTY INSTALL_RPATH "${CMAKE_BINARY_DIR}/root-all/executable/lib") -install(TARGETS topexe toplib topmod testlib testlib_conflict RUNTIME DESTINATION executable/bin LIBRARY DESTINATION executable/lib) -install(TARGETS topexe toplib topmod testlib testlib_conflict RUNTIME DESTINATION bundle_executable/bin LIBRARY DESTINATION bundle_executable/lib) +install(TARGETS topexe topexe_weak toplib topmod testlib testlib_conflict RUNTIME DESTINATION executable/bin LIBRARY DESTINATION executable/lib) +install(TARGETS topexe topexe_weak toplib topmod testlib testlib_conflict RUNTIME DESTINATION bundle_executable/bin LIBRARY DESTINATION bundle_executable/lib) install(CODE [[ function(exec_get_runtime_dependencies depsfile udepsfile cdepsfile) @@ -213,4 +216,12 @@ install(CODE [[ "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>" BUNDLE_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bundle_executable/bin/$<TARGET_FILE_NAME:topexe>" ) + + exec_get_runtime_dependencies( + deps7.txt udeps7.txt cdeps7.txt + EXECUTABLES + "${CMAKE_INSTALL_PREFIX}/executable/bin/$<TARGET_FILE_NAME:topexe_weak>" + LIBRARIES + "${CMAKE_INSTALL_PREFIX}/executable/lib/$<TARGET_FILE_NAME:testlib_conflict>" + ) ]]) diff --git a/Tests/RunCMake/install/FILES-RENAME-all-check.cmake b/Tests/RunCMake/install/FILES-RENAME-all-check.cmake new file mode 100644 index 0000000..7e9b103 --- /dev/null +++ b/Tests/RunCMake/install/FILES-RENAME-all-check.cmake @@ -0,0 +1 @@ +check_installed([[^src;src/script_Debug\.ps]]) diff --git a/Tests/RunCMake/install/FILES-RENAME-bad-result.txt b/Tests/RunCMake/install/FILES-RENAME-bad-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/install/FILES-RENAME-bad-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/install/FILES-RENAME-bad-stderr.txt b/Tests/RunCMake/install/FILES-RENAME-bad-stderr.txt new file mode 100644 index 0000000..9844158 --- /dev/null +++ b/Tests/RunCMake/install/FILES-RENAME-bad-stderr.txt @@ -0,0 +1,6 @@ +CMake Error: + Error evaluating generator expression: + + \$<NOTAGENEX> + + Expression did not evaluate to a known generator expression diff --git a/Tests/RunCMake/install/FILES-RENAME-bad.cmake b/Tests/RunCMake/install/FILES-RENAME-bad.cmake new file mode 100644 index 0000000..5be0bb2 --- /dev/null +++ b/Tests/RunCMake/install/FILES-RENAME-bad.cmake @@ -0,0 +1,4 @@ +install(FILES empty.c + DESTINATION mybin + RENAME $<NOTAGENEX> + ) diff --git a/Tests/RunCMake/install/FILES-RENAME.cmake b/Tests/RunCMake/install/FILES-RENAME.cmake new file mode 100644 index 0000000..5896e64 --- /dev/null +++ b/Tests/RunCMake/install/FILES-RENAME.cmake @@ -0,0 +1,4 @@ +install(FILES script.bat + DESTINATION src + RENAME script_$<CONFIG>.ps + ) diff --git a/Tests/RunCMake/install/RunCMakeTest.cmake b/Tests/RunCMake/install/RunCMakeTest.cmake index d64d88b..b067b3a 100644 --- a/Tests/RunCMake/install/RunCMakeTest.cmake +++ b/Tests/RunCMake/install/RunCMakeTest.cmake @@ -74,6 +74,7 @@ run_cmake(SkipInstallRulesNoWarning2) run_cmake(DIRECTORY-DIRECTORY-bad) run_cmake(DIRECTORY-DESTINATION-bad) run_cmake(FILES-DESTINATION-bad) +run_cmake(FILES-RENAME-bad) run_cmake(TARGETS-DESTINATION-bad) run_cmake(EXPORT-OldIFace) run_cmake(EXPORT-UnknownExport) @@ -91,6 +92,10 @@ run_cmake(TARGETS-NAMELINK_COMPONENT-bad-exc) run_cmake(FILES-DESTINATION-TYPE) run_cmake(DIRECTORY-DESTINATION-TYPE) +set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=Debug") +run_install_test(FILES-RENAME) +unset(RunCMake_TEST_OPTIONS) + if(APPLE) run_cmake(TARGETS-Apple-Defaults) endif() diff --git a/Tests/RunCMake/list/REMOVE_ITEM-NoItemArg.cmake b/Tests/RunCMake/list/REMOVE_ITEM-NoItemArg.cmake new file mode 100644 index 0000000..f69c024 --- /dev/null +++ b/Tests/RunCMake/list/REMOVE_ITEM-NoItemArg.cmake @@ -0,0 +1,5 @@ +set(ls "a" "b" "c") +list(REMOVE_ITEM ls alpha) +if (NOT ls STREQUAL "a;b;c") + message(FATAL_ERROR "list(REMOVE_ITEM) modified for empty item") +endif () diff --git a/Tests/RunCMake/list/RunCMakeTest.cmake b/Tests/RunCMake/list/RunCMakeTest.cmake index b4a91bc..c11891c 100644 --- a/Tests/RunCMake/list/RunCMakeTest.cmake +++ b/Tests/RunCMake/list/RunCMakeTest.cmake @@ -30,6 +30,7 @@ run_cmake(FILTER-NotList) run_cmake(REMOVE_AT-NotList) run_cmake(REMOVE_DUPLICATES-NotList) run_cmake(REMOVE_ITEM-NotList) +run_cmake(REMOVE_ITEM-NoItemArg) run_cmake(REVERSE-NotList) run_cmake(SORT-NotList) diff --git a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt index f68e38e..abd0628 100644 --- a/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt +++ b/Tests/VSGNUFortran/subdir/fortran/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(FortranHello Fortran C) # add a function to test for -lsunquad on sunpro sun systems. @@ -33,7 +33,7 @@ FortranCInterface_HEADER(HelloWorldFCMangle.h SYMBOLS hello world) add_library(hello SHARED hello.f) add_library(world SHARED world.f) -target_link_libraries(hello world) +target_link_libraries(hello PRIVATE world) if(CMAKE_Fortran_COMPILER_ID MATCHES SunPro) target_link_libraries(hello PRIVATE fsu) if(CMAKE_Fortran_PLATFORM_ID MATCHES SunOS) diff --git a/Tests/VSMidl/CMakeLists.txt b/Tests/VSMidl/CMakeLists.txt index 3ff7c27..342b8fb 100644 --- a/Tests/VSMidl/CMakeLists.txt +++ b/Tests/VSMidl/CMakeLists.txt @@ -12,7 +12,7 @@ endif() message(STATUS "CMAKE_BUILDNAME='${CMAKE_BUILDNAME}'") message(STATUS "THIS_TESTNAME='${THIS_TESTNAME}'") -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(${THIS_TESTNAME}) include(ExternalProject) diff --git a/Tests/VSMidl/src/CMakeLists.txt b/Tests/VSMidl/src/CMakeLists.txt index e745fdd..7e838b4 100644 --- a/Tests/VSMidl/src/CMakeLists.txt +++ b/Tests/VSMidl/src/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8.12) project(VSMidl) include_directories("${CMAKE_CURRENT_BINARY_DIR}/\$(IntDir)") diff --git a/Tests/VSWinStorePhone/CMakeLists.txt b/Tests/VSWinStorePhone/CMakeLists.txt index 56e4c1d..edd4330 100644 --- a/Tests/VSWinStorePhone/CMakeLists.txt +++ b/Tests/VSWinStorePhone/CMakeLists.txt @@ -119,13 +119,13 @@ set_property(SOURCE ${RELEASE_CONTENT_FILES} PROPERTY set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_TYPE Pixel) set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainPS) set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3) -set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_FLAGS "/DFLAGS_ADDED") +set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_FLAGS $<1:/DFLAGS_ADDED>) set_property(SOURCE ${PIXELSHADER_FILES} PROPERTY VS_SHADER_OUTPUT_HEADER_FILE "$(OutDir)%(Filename).h") set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_TYPE Vertex) set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_ENTRYPOINT mainVS) set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_MODEL 4.0_level_9_3) -set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_FLAGS "/DFLAGS_ADDED") +set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_FLAGS $<1:/DFLAGS_ADDED>) set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SHADER_OUTPUT_HEADER_FILE "$(OutDir)%(Filename).h") set_property(SOURCE ${VERTEXSHADER_FILES} PROPERTY VS_SETTINGS "$<$<CONFIG:DEBUG>:SourceProperty1=SourceProperty1Value>") diff --git a/Utilities/Release/macos/qt-5.15.2-macosx10.13-x86_64-arm64.bash b/Utilities/Release/macos/qt-5.15.2-macosx10.13-x86_64-arm64.bash new file mode 100755 index 0000000..bf92e62 --- /dev/null +++ b/Utilities/Release/macos/qt-5.15.2-macosx10.13-x86_64-arm64.bash @@ -0,0 +1,125 @@ +#!/usr/bin/env bash + +# Run this script on a macOS x86_64 host to generate Qt universal binaries. +# +# This script requires the 'makeuniversal' tool from: +# +# https://github.com/fizzyade/makeuniversal +# +# Build it with an existing local Qt installation first. +# +# Set the PATH environment variable to contain the location of 'makeuniversal'. + +set -e +set -x + +umask 022 + +# Verify that 'makeuniversal' is available in the PATH. +type -p makeuniversal >/dev/null + +# Download, verify, and extract sources. +curl -OL https://download.qt.io/archive/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz +shasum -a 256 qt-everywhere-src-5.15.2.tar.xz | grep -q 3a530d1b243b5dec00bc54937455471aaa3e56849d2593edb8ded07228202240 +tar xjf qt-everywhere-src-5.15.2.tar.xz + +# Build the x86_64 variant. +mkdir qt-5.15.2-x86_64 +cd qt-5.15.2-x86_64 +../qt-everywhere-src-5.15.2/configure \ + --prefix=/ \ + -platform macx-clang \ + -device-option QMAKE_APPLE_DEVICE_ARCHS=x86_64 \ + -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=10.13 \ + -release \ + -opensource -confirm-license \ + -gui \ + -widgets \ + -no-gif \ + -no-icu \ + -no-pch \ + -no-angle \ + -no-opengl \ + -no-dbus \ + -no-harfbuzz \ + -skip declarative \ + -skip multimedia \ + -skip qtcanvas3d \ + -skip qtcharts \ + -skip qtconnectivity \ + -skip qtdeclarative \ + -skip qtgamepad \ + -skip qtlocation \ + -skip qtmultimedia \ + -skip qtnetworkauth \ + -skip qtpurchasing \ + -skip qtremoteobjects \ + -skip qtscript \ + -skip qtsensors \ + -skip qtserialbus \ + -skip qtserialport \ + -skip qtsvg \ + -skip qtwebchannel \ + -skip qtwebengine \ + -skip qtwebsockets \ + -skip qtxmlpatterns \ + -nomake examples \ + -nomake tests \ + -nomake tools +make -j 8 +cd .. + +# Build the arm64 variant. +mkdir qt-5.15.2-arm64 +cd qt-5.15.2-arm64 +../qt-everywhere-src-5.15.2/configure \ + --prefix=/ \ + -platform macx-clang \ + -device-option QMAKE_APPLE_DEVICE_ARCHS=arm64 \ + -device-option QMAKE_MACOSX_DEPLOYMENT_TARGET=10.13 \ + -release \ + -opensource -confirm-license \ + -gui \ + -widgets \ + -no-gif \ + -no-icu \ + -no-pch \ + -no-angle \ + -no-opengl \ + -no-dbus \ + -no-harfbuzz \ + -skip declarative \ + -skip multimedia \ + -skip qtcanvas3d \ + -skip qtcharts \ + -skip qtconnectivity \ + -skip qtdeclarative \ + -skip qtgamepad \ + -skip qtlocation \ + -skip qtmultimedia \ + -skip qtnetworkauth \ + -skip qtpurchasing \ + -skip qtremoteobjects \ + -skip qtscript \ + -skip qtsensors \ + -skip qtserialbus \ + -skip qtserialport \ + -skip qtsvg \ + -skip qtwebchannel \ + -skip qtwebengine \ + -skip qtwebsockets \ + -skip qtxmlpatterns \ + -nomake examples \ + -nomake tests \ + -nomake tools +make -j 8 -k +cd .. + +# Combine the two builds into universal binaries. +makeuniversal qt-5.15.2-univ qt-5.15.2-x86_64 qt-5.15.2-arm64 +cd qt-5.15.2-univ +make install -j 8 INSTALL_ROOT=/tmp/qt-5.15.2-macosx10.13-x86_64-arm64 +cd .. + +# Create the final tarball containing universal binaries. +tar cjf qt-5.15.2-macosx10.13-x86_64-arm64.tar.xz -C /tmp qt-5.15.2-macosx10.13-x86_64-arm64 diff --git a/Utilities/Release/macos/qt-5.9.9-macosx10.10-x86_64-arm64.bash b/Utilities/Release/macos/qt-5.9.9-macosx10.10-x86_64-arm64.bash index a61e114..79931ec 100755 --- a/Utilities/Release/macos/qt-5.9.9-macosx10.10-x86_64-arm64.bash +++ b/Utilities/Release/macos/qt-5.9.9-macosx10.10-x86_64-arm64.bash @@ -13,6 +13,8 @@ set -e set -x +umask 022 + # Verify that 'makeuniversal' is available in the PATH. type -p makeuniversal >/dev/null diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index e175d0d..ece4bf5 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'), + 'genex': _cmake_index_entry('genex'), 'guide': _cmake_index_entry('guide'), 'manual': _cmake_index_entry('manual'), 'module': _cmake_index_entry('module'), @@ -224,7 +225,7 @@ class CMakeTransform(Transform): self.titles = {} def parse_title(self, docname): - """Parse a document title as the first line starting in [A-Za-z0-9<] + """Parse a document title as the first line starting in [A-Za-z0-9<$] or fall back to the document basename if no such line exists. The cmake --help-*-list commands also depend on this convention. Return the title or False if the document file does not exist. @@ -239,7 +240,7 @@ class CMakeTransform(Transform): title = False else: for line in f: - if len(line) > 0 and (line[0].isalnum() or line[0] == '<'): + if len(line) > 0 and (line[0].isalnum() or line[0] == '<' or line[0] == '$'): title = line.rstrip() break f.close() @@ -260,6 +261,10 @@ class CMakeTransform(Transform): if objtype == 'command': targetname = title.lower() else: + if objtype == 'genex': + m = CMakeXRefRole._re_genex.match(title) + if m: + title = m.group(1) targetname = title targetid = '%s:%s' % (objtype, targetname) targetnode = nodes.target('', '', ids=[targetid]) @@ -277,6 +282,10 @@ class CMakeObject(ObjectDescription): def handle_signature(self, sig, signode): # called from sphinx.directives.ObjectDescription.run() signode += addnodes.desc_name(sig, sig) + if self.objtype == 'genex': + m = CMakeXRefRole._re_genex.match(sig) + if m: + sig = m.group(1) return sig def add_target_and_index(self, name, sig, signode): @@ -302,6 +311,7 @@ class CMakeXRefRole(XRefRole): # See sphinx.util.nodes.explicit_title_re; \x00 escapes '<'. _re = re.compile(r'^(.+?)(\s*)(?<!\x00)<(.*?)>$', re.DOTALL) _re_sub = re.compile(r'^([^()\s]+)\s*\(([^()]*)\)$', re.DOTALL) + _re_genex = re.compile(r'^\$<([^<>:]+)(:[^<>]+)?>$', re.DOTALL) def __call__(self, typ, rawtext, text, *args, **keys): # Translate CMake command cross-references of the form: @@ -312,6 +322,10 @@ class CMakeXRefRole(XRefRole): m = CMakeXRefRole._re_sub.match(text) if m: text = '%s <%s>' % (text, m.group(1)) + elif typ == 'cmake:genex': + m = CMakeXRefRole._re_genex.match(text) + if m: + text = '%s <%s>' % (text, m.group(1)) # CMake cross-reference targets frequently contain '<' so escape # any explicit `<target>` with '<' not preceded by whitespace. while True: @@ -374,6 +388,7 @@ class CMakeDomain(Domain): 'cpack_gen': ObjType('cpack_gen', 'cpack_gen'), 'envvar': ObjType('envvar', 'envvar'), 'generator': ObjType('generator', 'generator'), + 'genex': ObjType('genex', 'genex'), 'guide': ObjType('guide', 'guide'), 'variable': ObjType('variable', 'variable'), 'module': ObjType('module', 'module'), @@ -390,6 +405,7 @@ class CMakeDomain(Domain): directives = { 'command': CMakeObject, 'envvar': CMakeObject, + 'genex': CMakeObject, 'variable': CMakeObject, # Other object types cannot be created except by the CMakeTransform # 'generator': CMakeObject, @@ -409,6 +425,7 @@ class CMakeDomain(Domain): 'cpack_gen': CMakeXRefRole(), 'envvar': CMakeXRefRole(), 'generator': CMakeXRefRole(), + 'genex': CMakeXRefRole(), 'guide': CMakeXRefRole(), 'variable': CMakeXRefRole(), 'module': CMakeXRefRole(), diff --git a/Utilities/Sphinx/create_identifiers.py b/Utilities/Sphinx/create_identifiers.py index e35f127..0ff39a0 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"), + ("genex", "genex"), ("guide", "guide"), ("target property", "prop_tgt"), ("test property", "prop_test"), diff --git a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp index 6eeba0e..8362fc4 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_reader.cpp @@ -2,74 +2,88 @@ // Copyright (C) 2016 InfoTeCS JSC. All rights reserved. // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE +// See file LICENSE for detail or copy at +// http://jsoncpp.sourceforge.net/LICENSE #if !defined(JSON_IS_AMALGAMATION) -#include <json/assertions.h> -#include <json/reader.h> -#include <json/value.h> -#include "json_tool.h" +# include <json/assertions.h> +# include <json/reader.h> +# include <json/value.h> + +# include "json_tool.h" #endif // if !defined(JSON_IS_AMALGAMATION) -#include <utility> -#include <stdio.h> -#include <assert.h> -#include <string.h> #include <istream> -#include <sstream> +#include <limits> #include <memory> #include <set> -#include <limits> +#include <sstream> +#include <utility> + +#include <assert.h> +#include <stdio.h> +#include <string.h> #if defined(_MSC_VER) -#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above -#define snprintf sprintf_s -#elif _MSC_VER >= 1900 // VC++ 14.0 and above -#define snprintf std::snprintf -#else -#define snprintf _snprintf -#endif +# if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && \ + _MSC_VER >= 1500 // VC++ 9.0 and above +# define snprintf sprintf_s +# elif _MSC_VER >= 1900 // VC++ 14.0 and above +# define snprintf std::snprintf +# else +# define snprintf _snprintf +# endif #elif defined(__ANDROID__) || defined(__QNXNTO__) -#define snprintf snprintf +# define snprintf snprintf #elif __cplusplus >= 201103L -#if !defined(__MINGW32__) && !defined(__CYGWIN__) -#define snprintf std::snprintf -#endif +# if !defined(__MINGW32__) && !defined(__CYGWIN__) +# define snprintf std::snprintf +# endif #endif #if defined(__QNXNTO__) -#define sscanf std::sscanf +# define sscanf std::sscanf #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 // Disable warning about strdup being deprecated. -#pragma warning(disable : 4996) +# pragma warning(disable : 4996) #endif -// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit +// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile +// time to change the stack limit #if !defined(JSONCPP_DEPRECATED_STACK_LIMIT) -#define JSONCPP_DEPRECATED_STACK_LIMIT 1000 +# define JSONCPP_DEPRECATED_STACK_LIMIT 1000 #endif -static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() +static size_t const stackLimit_g = + JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue() namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) typedef std::unique_ptr<CharReader> CharReaderPtr; #else -typedef std::auto_ptr<CharReader> CharReaderPtr; +typedef std::auto_ptr<CharReader> CharReaderPtr; #endif // Implementation of class Features // //////////////////////////////// Features::Features() - : allowComments_(true), strictRoot_(false), - allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {} + : allowComments_(true) + , strictRoot_(false) + , allowDroppedNullPlaceholders_(false) + , allowNumericKeys_(false) +{ +} -Features Features::all() { return Features(); } +Features Features::all() +{ + return Features(); +} -Features Features::strictMode() { +Features Features::strictMode() +{ Features features; features.allowComments_ = false; features.strictRoot_ = true; @@ -81,7 +95,8 @@ Features Features::strictMode() { // Implementation of class Reader // //////////////////////////////// -bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { +bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) +{ for (; begin < end; ++begin) if (*begin == '\n' || *begin == '\r') return true; @@ -92,24 +107,44 @@ bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) { // ////////////////////////////////////////////////////////////////// Reader::Reader() - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(Features::all()), - collectComments_() {} + : errors_() + , document_() + , begin_() + , end_() + , current_() + , lastValueEnd_() + , lastValue_() + , commentsBefore_() + , features_(Features::all()) + , collectComments_() +{ +} Reader::Reader(const Features& features) - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), features_(features), collectComments_() { + : errors_() + , document_() + , begin_() + , end_() + , current_() + , lastValueEnd_() + , lastValue_() + , commentsBefore_() + , features_(features) + , collectComments_() +{ } -bool -Reader::parse(const std::string& document, Value& root, bool collectComments) { - document_.assign(document.begin(), document.end()); - const char* begin = document_.c_str(); - const char* end = begin + document_.length(); - return parse(begin, end, root, collectComments); +bool Reader::parse(const std::string& document, Value& root, + bool collectComments) +{ + this->document_.assign(document.begin(), document.end()); + const char* begin = this->document_.c_str(); + const char* end = begin + this->document_.length(); + return this->parse(begin, end, root, collectComments); } -bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { +bool Reader::parse(std::istream& sin, Value& root, bool collectComments) +{ // std::istream_iterator<char> begin(sin); // std::istream_iterator<char> end; // Those would allow streamed input from a file, if parse() were a @@ -119,257 +154,263 @@ bool Reader::parse(std::istream& sin, Value& root, bool collectComments) { // create an extra copy. JSONCPP_STRING doc; std::getline(sin, doc, (char)EOF); - return parse(doc.data(), doc.data() + doc.size(), root, collectComments); + return this->parse(doc.data(), doc.data() + doc.size(), root, + collectComments); } -bool Reader::parse(const char* beginDoc, - const char* endDoc, - Value& root, - bool collectComments) { - if (!features_.allowComments_) { +bool Reader::parse(const char* beginDoc, const char* endDoc, Value& root, + bool collectComments) +{ + if (!this->features_.allowComments_) { collectComments = false; } - begin_ = beginDoc; - end_ = endDoc; - collectComments_ = collectComments; - current_ = begin_; - lastValueEnd_ = 0; - lastValue_ = 0; - commentsBefore_.clear(); - errors_.clear(); - while (!nodes_.empty()) - nodes_.pop(); - nodes_.push(&root); - - bool successful = readValue(); + this->begin_ = beginDoc; + this->end_ = endDoc; + this->collectComments_ = collectComments; + this->current_ = this->begin_; + this->lastValueEnd_ = 0; + this->lastValue_ = 0; + this->commentsBefore_.clear(); + this->errors_.clear(); + while (!this->nodes_.empty()) + this->nodes_.pop(); + this->nodes_.push(&root); + + bool successful = this->readValue(); Token token; - skipCommentTokens(token); - if (collectComments_ && !commentsBefore_.empty()) - root.setComment(commentsBefore_, commentAfter); - if (features_.strictRoot_) { + this->skipCommentTokens(token); + if (this->collectComments_ && !this->commentsBefore_.empty()) + root.setComment(this->commentsBefore_, commentAfter); + if (this->features_.strictRoot_) { if (!root.isArray() && !root.isObject()) { - // Set error location to start of doc, ideally should be first token found - // in doc + // Set error location to start of doc, ideally should be first token + // found in doc token.type_ = tokenError; token.start_ = beginDoc; token.end_ = endDoc; - addError( - "A valid JSON document must be either an array or an object value.", - token); + this->addError( + "A valid JSON document must be either an array or an object value.", + token); return false; } } return successful; } -bool Reader::readValue() { +bool Reader::readValue() +{ // readValue() may call itself only if it calls readObject() or ReadArray(). - // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue(). - // parse() executes one nodes_.push(), so > instead of >=. - if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue()."); + // These methods execute nodes_.push() just before and nodes_.pop)() just + // after calling readValue(). parse() executes one nodes_.push(), so > + // instead of >=. + if (this->nodes_.size() > stackLimit_g) + throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - skipCommentTokens(token); + this->skipCommentTokens(token); bool successful = true; - if (collectComments_ && !commentsBefore_.empty()) { - currentValue().setComment(commentsBefore_, commentBefore); - commentsBefore_.clear(); + if (this->collectComments_ && !this->commentsBefore_.empty()) { + this->currentValue().setComment(this->commentsBefore_, commentBefore); + this->commentsBefore_.clear(); } switch (token.type_) { - case tokenObjectBegin: - successful = readObject(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenArrayBegin: - successful = readArray(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenNumber: - successful = decodeNumber(token); - break; - case tokenString: - successful = decodeString(token); - break; - case tokenTrue: - { - Value v(true); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenFalse: - { - Value v(false); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNull: - { - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenArraySeparator: - case tokenObjectEnd: - case tokenArrayEnd: - if (features_.allowDroppedNullPlaceholders_) { - // "Un-read" the current token and mark the current value as a null - // token. - current_--; - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(current_ - begin_ - 1); - currentValue().setOffsetLimit(current_ - begin_); + case tokenObjectBegin: + successful = this->readObject(token); + this->currentValue().setOffsetLimit(this->current_ - this->begin_); + break; + case tokenArrayBegin: + successful = this->readArray(token); + this->currentValue().setOffsetLimit(this->current_ - this->begin_); + break; + case tokenNumber: + successful = this->decodeNumber(token); break; - } // Else, fall through... - default: - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return addError("Syntax error: value, object or array expected.", token); + case tokenString: + successful = this->decodeString(token); + break; + case tokenTrue: { + Value v(true); + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenFalse: { + Value v(false); + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenNull: { + Value v; + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (this->features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + this->current_--; + Value v; + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(this->current_ - this->begin_ - 1); + this->currentValue().setOffsetLimit(this->current_ - this->begin_); + break; + } // Else, fall through... + default: + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + return this->addError("Syntax error: value, object or array expected.", + token); } - if (collectComments_) { - lastValueEnd_ = current_; - lastValue_ = ¤tValue(); + if (this->collectComments_) { + this->lastValueEnd_ = this->current_; + this->lastValue_ = &this->currentValue(); } return successful; } -void Reader::skipCommentTokens(Token& token) { - if (features_.allowComments_) { +void Reader::skipCommentTokens(Token& token) +{ + if (this->features_.allowComments_) { do { - readToken(token); + this->readToken(token); } while (token.type_ == tokenComment); } else { - readToken(token); + this->readToken(token); } } -bool Reader::readToken(Token& token) { - skipSpaces(); - token.start_ = current_; - Char c = getNextChar(); +bool Reader::readToken(Token& token) +{ + this->skipSpaces(); + token.start_ = this->current_; + Char c = this->getNextChar(); bool ok = true; switch (c) { - case '{': - token.type_ = tokenObjectBegin; - break; - case '}': - token.type_ = tokenObjectEnd; - break; - case '[': - token.type_ = tokenArrayBegin; - break; - case ']': - token.type_ = tokenArrayEnd; - break; - case '"': - token.type_ = tokenString; - ok = readString(); - break; - case '/': - token.type_ = tokenComment; - ok = readComment(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - token.type_ = tokenNumber; - readNumber(); - break; - case 't': - token.type_ = tokenTrue; - ok = match("rue", 3); - break; - case 'f': - token.type_ = tokenFalse; - ok = match("alse", 4); - break; - case 'n': - token.type_ = tokenNull; - ok = match("ull", 3); - break; - case ',': - token.type_ = tokenArraySeparator; - break; - case ':': - token.type_ = tokenMemberSeparator; - break; - case 0: - token.type_ = tokenEndOfStream; - break; - default: - ok = false; - break; + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = this->readString(); + break; + case '/': + token.type_ = tokenComment; + ok = this->readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + token.type_ = tokenNumber; + this->readNumber(); + break; + case 't': + token.type_ = tokenTrue; + ok = this->match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = this->match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = this->match("ull", 3); + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: + ok = false; + break; } if (!ok) token.type_ = tokenError; - token.end_ = current_; + token.end_ = this->current_; return true; } -void Reader::skipSpaces() { - while (current_ != end_) { - Char c = *current_; +void Reader::skipSpaces() +{ + while (this->current_ != this->end_) { + Char c = *this->current_; if (c == ' ' || c == '\t' || c == '\r' || c == '\n') - ++current_; + ++this->current_; else break; } } -bool Reader::match(Location pattern, int patternLength) { - if (end_ - current_ < patternLength) +bool Reader::match(Location pattern, int patternLength) +{ + if (this->end_ - this->current_ < patternLength) return false; int index = patternLength; while (index--) - if (current_[index] != pattern[index]) + if (this->current_[index] != pattern[index]) return false; - current_ += patternLength; + this->current_ += patternLength; return true; } -bool Reader::readComment() { - Location commentBegin = current_ - 1; - Char c = getNextChar(); +bool Reader::readComment() +{ + Location commentBegin = this->current_ - 1; + Char c = this->getNextChar(); bool successful = false; if (c == '*') - successful = readCStyleComment(); + successful = this->readCStyleComment(); else if (c == '/') - successful = readCppStyleComment(); + successful = this->readCppStyleComment(); if (!successful) return false; - if (collectComments_) { + if (this->collectComments_) { CommentPlacement placement = commentBefore; - if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { - if (c != '*' || !containsNewLine(commentBegin, current_)) + if (this->lastValueEnd_ && + !containsNewLine(this->lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, this->current_)) placement = commentAfterOnSameLine; } - addComment(commentBegin, current_, placement); + this->addComment(commentBegin, this->current_, placement); } return true; } -JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end) { +JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, + Reader::Location end) +{ JSONCPP_STRING normalized; normalized.reserve(static_cast<size_t>(end - begin)); Reader::Location current = begin; @@ -377,8 +418,8 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end char c = *current++; if (c == '\r') { if (current != end && *current == '\n') - // convert dos EOL - ++current; + // convert dos EOL + ++current; // convert Mac EOL normalized += '\n'; } else { @@ -388,36 +429,39 @@ JSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end return normalized; } -void -Reader::addComment(Location begin, Location end, CommentPlacement placement) { - assert(collectComments_); +void Reader::addComment(Location begin, Location end, + CommentPlacement placement) +{ + assert(this->collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(lastValue_ != 0); - lastValue_->setComment(normalized, placement); + assert(this->lastValue_ != 0); + this->lastValue_->setComment(normalized, placement); } else { - commentsBefore_ += normalized; + this->commentsBefore_ += normalized; } } -bool Reader::readCStyleComment() { - while ((current_ + 1) < end_) { - Char c = getNextChar(); - if (c == '*' && *current_ == '/') +bool Reader::readCStyleComment() +{ + while ((this->current_ + 1) < this->end_) { + Char c = this->getNextChar(); + if (c == '*' && *this->current_ == '/') break; } - return getNextChar() == '/'; + return this->getNextChar() == '/'; } -bool Reader::readCppStyleComment() { - while (current_ != end_) { - Char c = getNextChar(); +bool Reader::readCppStyleComment() +{ + while (this->current_ != this->end_) { + Char c = this->getNextChar(); if (c == '\n') break; if (c == '\r') { // Consume DOS EOL. It will be normalized in addComment. - if (current_ != end_ && *current_ == '\n') - getNextChar(); + if (this->current_ != this->end_ && *this->current_ == '\n') + this->getNextChar(); // Break on Moc OS 9 EOL. break; } @@ -425,127 +469,132 @@ bool Reader::readCppStyleComment() { return true; } -void Reader::readNumber() { - const char *p = current_; +void Reader::readNumber() +{ + const char* p = this->current_; char c = '0'; // stopgap for already consumed character // integral part while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; // fractional part if (c == '.') { - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; } // exponential part if (c == 'e' || c == 'E') { - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; if (c == '+' || c == '-') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; } } -bool Reader::readString() { +bool Reader::readString() +{ Char c = '\0'; - while (current_ != end_) { - c = getNextChar(); + while (this->current_ != this->end_) { + c = this->getNextChar(); if (c == '\\') - getNextChar(); + this->getNextChar(); else if (c == '"') break; } return c == '"'; } -bool Reader::readObject(Token& tokenStart) { +bool Reader::readObject(Token& tokenStart) +{ Token tokenName; JSONCPP_STRING name; Value init(objectValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - while (readToken(tokenName)) { + this->currentValue().swapPayload(init); + this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); + while (this->readToken(tokenName)) { bool initialTokenOk = true; while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); + initialTokenOk = this->readToken(tokenName); if (!initialTokenOk) break; if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object return true; name.clear(); if (tokenName.type_ == tokenString) { - if (!decodeString(tokenName, name)) - return recoverFromError(tokenObjectEnd); - } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { + if (!this->decodeString(tokenName, name)) + return this->recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && + this->features_.allowNumericKeys_) { Value numberName; - if (!decodeNumber(tokenName, numberName)) - return recoverFromError(tokenObjectEnd); + if (!this->decodeNumber(tokenName, numberName)) + return this->recoverFromError(tokenObjectEnd); name = JSONCPP_STRING(numberName.asCString()); } else { break; } Token colon; - if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { - return addErrorAndRecover( - "Missing ':' after object member name", colon, tokenObjectEnd); + if (!this->readToken(colon) || colon.type_ != tokenMemberSeparator) { + return this->addErrorAndRecover("Missing ':' after object member name", + colon, tokenObjectEnd); } - Value& value = currentValue()[name]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); + Value& value = this->currentValue()[name]; + this->nodes_.push(&value); + bool ok = this->readValue(); + this->nodes_.pop(); if (!ok) // error already set - return recoverFromError(tokenObjectEnd); + return this->recoverFromError(tokenObjectEnd); Token comma; - if (!readToken(comma) || + if (!this->readToken(comma) || (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && comma.type_ != tokenComment)) { - return addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + return this->addErrorAndRecover( + "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } bool finalizeTokenOk = true; while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); + finalizeTokenOk = this->readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } - return addErrorAndRecover( - "Missing '}' or object member name", tokenName, tokenObjectEnd); + return this->addErrorAndRecover("Missing '}' or object member name", + tokenName, tokenObjectEnd); } -bool Reader::readArray(Token& tokenStart) { +bool Reader::readArray(Token& tokenStart) +{ Value init(arrayValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - skipSpaces(); - if (current_ != end_ && *current_ == ']') // empty array + this->currentValue().swapPayload(init); + this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); + this->skipSpaces(); + if (this->current_ != this->end_ && *this->current_ == ']') // empty array { Token endArray; - readToken(endArray); + this->readToken(endArray); return true; } int index = 0; for (;;) { - Value& value = currentValue()[index++]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); + Value& value = this->currentValue()[index++]; + this->nodes_.push(&value); + bool ok = this->readValue(); + this->nodes_.pop(); if (!ok) // error already set - return recoverFromError(tokenArrayEnd); + return this->recoverFromError(tokenArrayEnd); Token token; // Accept Comment after last item in the array. - ok = readToken(token); + ok = this->readToken(token); while (token.type_ == tokenComment && ok) { - ok = readToken(token); + ok = this->readToken(token); } bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { - return addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + return this->addErrorAndRecover( + "Missing ',' or ']' in array declaration", token, tokenArrayEnd); } if (token.type_ == tokenArrayEnd) break; @@ -553,17 +602,19 @@ bool Reader::readArray(Token& tokenStart) { return true; } -bool Reader::decodeNumber(Token& token) { +bool Reader::decodeNumber(Token& token) +{ Value decoded; - if (!decodeNumber(token, decoded)) + if (!this->decodeNumber(token, decoded)) return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); + this->currentValue().swapPayload(decoded); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); return true; } -bool Reader::decodeNumber(Token& token, Value& decoded) { +bool Reader::decodeNumber(Token& token, Value& decoded) +{ // Attempts to parse the number as an integer. If the number is // larger than the maximum supported value of an integer then // we decode the number as a double. @@ -571,16 +622,17 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { bool isNegative = *current == '-'; if (isNegative) ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of them. - Value::LargestUInt maxIntegerValue = - isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1 - : Value::maxLargestUInt; + // TODO: Help the compiler do the div and mod at compile time or get rid of + // them. + Value::LargestUInt maxIntegerValue = isNegative + ? Value::LargestUInt(Value::maxLargestInt) + 1 + : Value::maxLargestUInt; Value::LargestUInt threshold = maxIntegerValue / 10; Value::LargestUInt value = 0; while (current < token.end_) { Char c = *current++; if (c < '0' || c > '9') - return decodeDouble(token, decoded); + return this->decodeDouble(token, decoded); Value::UInt digit(static_cast<Value::UInt>(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If @@ -589,7 +641,7 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { // Otherwise treat this number as a double to avoid overflow. if (value > threshold || current != token.end_ || digit > maxIntegerValue % 10) { - return decodeDouble(token, decoded); + return this->decodeDouble(token, decoded); } } value = value * 10 + digit; @@ -605,40 +657,44 @@ bool Reader::decodeNumber(Token& token, Value& decoded) { return true; } -bool Reader::decodeDouble(Token& token) { +bool Reader::decodeDouble(Token& token) +{ Value decoded; - if (!decodeDouble(token, decoded)) + if (!this->decodeDouble(token, decoded)) return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); + this->currentValue().swapPayload(decoded); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); return true; } -bool Reader::decodeDouble(Token& token, Value& decoded) { +bool Reader::decodeDouble(Token& token, Value& decoded) +{ double value = 0; JSONCPP_STRING buffer(token.start_, token.end_); JSONCPP_ISTRINGSTREAM is(buffer); if (!(is >> value)) - return addError("'" + JSONCPP_STRING(token.start_, token.end_) + - "' is not a number.", - token); + return this->addError("'" + JSONCPP_STRING(token.start_, token.end_) + + "' is not a number.", + token); decoded = value; return true; } -bool Reader::decodeString(Token& token) { +bool Reader::decodeString(Token& token) +{ JSONCPP_STRING decoded_string; - if (!decodeString(token, decoded_string)) + if (!this->decodeString(token, decoded_string)) return false; Value decoded(decoded_string); - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); + this->currentValue().swapPayload(decoded); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); return true; } -bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) { +bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) +{ decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -648,41 +704,43 @@ bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) { break; else if (c == '\\') { if (current == end) - return addError("Empty escape sequence in string", token, current); + return this->addError("Empty escape sequence in string", token, + current); Char escape = *current++; switch (escape) { - case '"': - decoded += '"'; - break; - case '/': - decoded += '/'; - break; - case '\\': - decoded += '\\'; - break; - case 'b': - decoded += '\b'; - break; - case 'f': - decoded += '\f'; - break; - case 'n': - decoded += '\n'; - break; - case 'r': - decoded += '\r'; - break; - case 't': - decoded += '\t'; - break; - case 'u': { - unsigned int unicode; - if (!decodeUnicodeCodePoint(token, current, end, unicode)) - return false; - decoded += codePointToUTF8(unicode); - } break; - default: - return addError("Bad escape sequence in string", token, current); + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!this->decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return this->addError("Bad escape sequence in string", token, + current); } } else { decoded += c; @@ -691,44 +749,43 @@ bool Reader::decodeString(Token& token, JSONCPP_STRING& decoded) { return true; } -bool Reader::decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode) { +bool Reader::decodeUnicodeCodePoint(Token& token, Location& current, + Location end, unsigned int& unicode) +{ - if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) + if (!this->decodeUnicodeEscapeSequence(token, current, end, unicode)) return false; if (unicode >= 0xD800 && unicode <= 0xDBFF) { // surrogate pairs if (end - current < 6) - return addError( - "additional six characters expected to parse unicode surrogate pair.", - token, - current); + return this->addError( + "additional six characters expected to parse unicode surrogate pair.", + token, current); unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { - if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { - unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + if (this->decodeUnicodeEscapeSequence(token, current, end, + surrogatePair)) { + unicode = + 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); } else return false; } else - return addError("expecting another \\u token to begin the second half of " - "a unicode surrogate pair", - token, - current); + return this->addError( + "expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, current); } return true; } -bool Reader::decodeUnicodeEscapeSequence(Token& token, - Location& current, +bool Reader::decodeUnicodeEscapeSequence(Token& token, Location& current, Location end, - unsigned int& ret_unicode) { + unsigned int& ret_unicode) +{ if (end - current < 4) - return addError( - "Bad unicode escape sequence in string: four digits expected.", - token, - current); + return this->addError( + "Bad unicode escape sequence in string: four digits expected.", token, + current); int unicode = 0; for (int index = 0; index < 4; ++index) { Char c = *current++; @@ -740,60 +797,65 @@ bool Reader::decodeUnicodeEscapeSequence(Token& token, else if (c >= 'A' && c <= 'F') unicode += c - 'A' + 10; else - return addError( - "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, - current); + return this->addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, current); } ret_unicode = static_cast<unsigned int>(unicode); return true; } -bool -Reader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { +bool Reader::addError(const JSONCPP_STRING& message, Token& token, + Location extra) +{ ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = extra; - errors_.push_back(info); + this->errors_.push_back(info); return false; } -bool Reader::recoverFromError(TokenType skipUntilToken) { - size_t const errorCount = errors_.size(); +bool Reader::recoverFromError(TokenType skipUntilToken) +{ + size_t const errorCount = this->errors_.size(); Token skip; for (;;) { - if (!readToken(skip)) - errors_.resize(errorCount); // discard errors caused by recovery + if (!this->readToken(skip)) + this->errors_.resize(errorCount); // discard errors caused by recovery if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) break; } - errors_.resize(errorCount); + this->errors_.resize(errorCount); return false; } -bool Reader::addErrorAndRecover(const JSONCPP_STRING& message, - Token& token, - TokenType skipUntilToken) { - addError(message, token); - return recoverFromError(skipUntilToken); +bool Reader::addErrorAndRecover(const JSONCPP_STRING& message, Token& token, + TokenType skipUntilToken) +{ + this->addError(message, token); + return this->recoverFromError(skipUntilToken); } -Value& Reader::currentValue() { return *(nodes_.top()); } +Value& Reader::currentValue() +{ + return *(this->nodes_.top()); +} -Reader::Char Reader::getNextChar() { - if (current_ == end_) +Reader::Char Reader::getNextChar() +{ + if (this->current_ == this->end_) return 0; - return *current_++; + return *this->current_++; } -void Reader::getLocationLineAndColumn(Location location, - int& line, - int& column) const { - Location current = begin_; +void Reader::getLocationLineAndColumn(Location location, int& line, + int& column) const +{ + Location current = this->begin_; Location lastLineStart = current; line = 0; - while (current < location && current != end_) { + while (current < location && current != this->end_) { Char c = *current++; if (c == '\r') { if (*current == '\n') @@ -810,91 +872,96 @@ void Reader::getLocationLineAndColumn(Location location, ++line; } -JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const { +JSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const +{ int line, column; - getLocationLineAndColumn(location, line, column); + this->getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); return buffer; } // Deprecated. Preserved for backward compatibility -JSONCPP_STRING Reader::getFormatedErrorMessages() const { - return getFormattedErrorMessages(); +JSONCPP_STRING Reader::getFormatedErrorMessages() const +{ + return this->getFormattedErrorMessages(); } -JSONCPP_STRING Reader::getFormattedErrorMessages() const { +JSONCPP_STRING Reader::getFormattedErrorMessages() const +{ JSONCPP_STRING formattedMessage; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + for (Errors::const_iterator itError = this->errors_.begin(); + itError != this->errors_.end(); ++itError) { const ErrorInfo& error = *itError; formattedMessage += - "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; + "* " + this->getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; if (error.extra_) - formattedMessage += - "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; + formattedMessage += "See " + + this->getLocationLineAndColumn(error.extra_) + " for detail.\n"; } return formattedMessage; } -std::vector<Reader::StructuredError> Reader::getStructuredErrors() const { +std::vector<Reader::StructuredError> Reader::getStructuredErrors() const +{ std::vector<Reader::StructuredError> allErrors; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + for (Errors::const_iterator itError = this->errors_.begin(); + itError != this->errors_.end(); ++itError) { const ErrorInfo& error = *itError; Reader::StructuredError structured; - structured.offset_start = error.token_.start_ - begin_; - structured.offset_limit = error.token_.end_ - begin_; + structured.offset_start = error.token_.start_ - this->begin_; + structured.offset_limit = error.token_.end_ - this->begin_; structured.message = error.message_; allErrors.push_back(structured); } return allErrors; } -bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) { - ptrdiff_t const length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length) +bool Reader::pushError(const Value& value, const JSONCPP_STRING& message) +{ + ptrdiff_t const length = this->end_ - this->begin_; + if (value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = end_ + value.getOffsetLimit(); + token.start_ = this->begin_ + value.getOffsetStart(); + token.end_ = this->end_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = 0; - errors_.push_back(info); + this->errors_.push_back(info); return true; } -bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { - ptrdiff_t const length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length - || extra.getOffsetLimit() > length) +bool Reader::pushError(const Value& value, const JSONCPP_STRING& message, + const Value& extra) +{ + ptrdiff_t const length = this->end_ - this->begin_; + if (value.getOffsetStart() > length || value.getOffsetLimit() > length || + extra.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = begin_ + value.getOffsetLimit(); + token.start_ = this->begin_ + value.getOffsetStart(); + token.end_ = this->begin_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; - info.extra_ = begin_ + extra.getOffsetStart(); - errors_.push_back(info); + info.extra_ = this->begin_ + extra.getOffsetStart(); + this->errors_.push_back(info); return true; } -bool Reader::good() const { - return !errors_.size(); +bool Reader::good() const +{ + return !this->errors_.size(); } // exact copy of Features -class OurFeatures { +class OurFeatures +{ public: static OurFeatures all(); bool allowComments_; @@ -906,43 +973,48 @@ public: bool rejectDupKeys_; bool allowSpecialFloats_; int stackLimit_; -}; // OurFeatures +}; // OurFeatures // exact copy of Implementation of class Features // //////////////////////////////// -OurFeatures OurFeatures::all() { return OurFeatures(); } +OurFeatures OurFeatures::all() +{ + return OurFeatures(); +} // Implementation of class Reader // //////////////////////////////// // exact copy of Reader, renamed to OurReader -class OurReader { +class OurReader +{ public: typedef char Char; typedef const Char* Location; - struct StructuredError { + struct StructuredError + { ptrdiff_t offset_start; ptrdiff_t offset_limit; JSONCPP_STRING message; }; OurReader(OurFeatures const& features); - bool parse(const char* beginDoc, - const char* endDoc, - Value& root, + bool parse(const char* beginDoc, const char* endDoc, Value& root, bool collectComments = true); JSONCPP_STRING getFormattedErrorMessages() const; std::vector<StructuredError> getStructuredErrors() const; bool pushError(const Value& value, const JSONCPP_STRING& message); - bool pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra); + bool pushError(const Value& value, const JSONCPP_STRING& message, + const Value& extra); bool good() const; private: - OurReader(OurReader const&); // no impl - void operator=(OurReader const&); // no impl + OurReader(OurReader const&); // no impl + void operator=(OurReader const&); // no impl - enum TokenType { + enum TokenType + { tokenEndOfStream = 0, tokenObjectBegin, tokenObjectEnd, @@ -962,14 +1034,16 @@ private: tokenError }; - class Token { + class Token + { public: TokenType type_; Location start_; Location end_; }; - class ErrorInfo { + class ErrorInfo + { public: Token token_; JSONCPP_STRING message_; @@ -996,24 +1070,20 @@ private: bool decodeString(Token& token, JSONCPP_STRING& decoded); bool decodeDouble(Token& token); bool decodeDouble(Token& token, Value& decoded); - bool decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, + bool decodeUnicodeCodePoint(Token& token, Location& current, Location end, unsigned int& unicode); - bool decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& unicode); - bool addError(const JSONCPP_STRING& message, Token& token, Location extra = 0); + bool decodeUnicodeEscapeSequence(Token& token, Location& current, + Location end, unsigned int& unicode); + bool addError(const JSONCPP_STRING& message, Token& token, + Location extra = 0); bool recoverFromError(TokenType skipUntilToken); - bool addErrorAndRecover(const JSONCPP_STRING& message, - Token& token, + bool addErrorAndRecover(const JSONCPP_STRING& message, Token& token, TokenType skipUntilToken); void skipUntilSpace(); Value& currentValue(); Char getNextChar(); - void - getLocationLineAndColumn(Location location, int& line, int& column) const; + void getLocationLineAndColumn(Location location, int& line, + int& column) const; JSONCPP_STRING getLocationLineAndColumn(Location location) const; void addComment(Location begin, Location end, CommentPlacement placement); void skipCommentTokens(Token& token); @@ -1034,11 +1104,13 @@ private: OurFeatures const features_; bool collectComments_; -}; // OurReader +}; // OurReader // complete copy of Read impl, for OurReader -bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location end) { +bool OurReader::containsNewLine(OurReader::Location begin, + OurReader::Location end) +{ for (; begin < end; ++begin) if (*begin == '\n' || *begin == '\r') return true; @@ -1046,315 +1118,322 @@ bool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location e } OurReader::OurReader(OurFeatures const& features) - : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(), - lastValue_(), commentsBefore_(), - features_(features), collectComments_() { + : errors_() + , document_() + , begin_() + , end_() + , current_() + , lastValueEnd_() + , lastValue_() + , commentsBefore_() + , features_(features) + , collectComments_() +{ } -bool OurReader::parse(const char* beginDoc, - const char* endDoc, - Value& root, - bool collectComments) { - if (!features_.allowComments_) { +bool OurReader::parse(const char* beginDoc, const char* endDoc, Value& root, + bool collectComments) +{ + if (!this->features_.allowComments_) { collectComments = false; } - begin_ = beginDoc; - end_ = endDoc; - collectComments_ = collectComments; - current_ = begin_; - lastValueEnd_ = 0; - lastValue_ = 0; - commentsBefore_.clear(); - errors_.clear(); - while (!nodes_.empty()) - nodes_.pop(); - nodes_.push(&root); - - bool successful = readValue(); + this->begin_ = beginDoc; + this->end_ = endDoc; + this->collectComments_ = collectComments; + this->current_ = this->begin_; + this->lastValueEnd_ = 0; + this->lastValue_ = 0; + this->commentsBefore_.clear(); + this->errors_.clear(); + while (!this->nodes_.empty()) + this->nodes_.pop(); + this->nodes_.push(&root); + + bool successful = this->readValue(); Token token; - skipCommentTokens(token); - if (features_.failIfExtra_) { - if ((features_.strictRoot_ || token.type_ != tokenError) && token.type_ != tokenEndOfStream) { - addError("Extra non-whitespace after JSON value.", token); + this->skipCommentTokens(token); + if (this->features_.failIfExtra_) { + if ((this->features_.strictRoot_ || token.type_ != tokenError) && + token.type_ != tokenEndOfStream) { + this->addError("Extra non-whitespace after JSON value.", token); return false; } } - if (collectComments_ && !commentsBefore_.empty()) - root.setComment(commentsBefore_, commentAfter); - if (features_.strictRoot_) { + if (this->collectComments_ && !this->commentsBefore_.empty()) + root.setComment(this->commentsBefore_, commentAfter); + if (this->features_.strictRoot_) { if (!root.isArray() && !root.isObject()) { - // Set error location to start of doc, ideally should be first token found - // in doc + // Set error location to start of doc, ideally should be first token + // found in doc token.type_ = tokenError; token.start_ = beginDoc; token.end_ = endDoc; - addError( - "A valid JSON document must be either an array or an object value.", - token); + this->addError( + "A valid JSON document must be either an array or an object value.", + token); return false; } } return successful; } -bool OurReader::readValue() { +bool OurReader::readValue() +{ // To preserve the old behaviour we cast size_t to int. - if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue()."); + if (static_cast<int>(this->nodes_.size()) > this->features_.stackLimit_) + throwRuntimeError("Exceeded stackLimit in readValue()."); Token token; - skipCommentTokens(token); + this->skipCommentTokens(token); bool successful = true; - if (collectComments_ && !commentsBefore_.empty()) { - currentValue().setComment(commentsBefore_, commentBefore); - commentsBefore_.clear(); + if (this->collectComments_ && !this->commentsBefore_.empty()) { + this->currentValue().setComment(this->commentsBefore_, commentBefore); + this->commentsBefore_.clear(); } switch (token.type_) { - case tokenObjectBegin: - successful = readObject(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenArrayBegin: - successful = readArray(token); - currentValue().setOffsetLimit(current_ - begin_); - break; - case tokenNumber: - successful = decodeNumber(token); - break; - case tokenString: - successful = decodeString(token); - break; - case tokenTrue: - { - Value v(true); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenFalse: - { - Value v(false); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNull: - { - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNaN: - { - Value v(std::numeric_limits<double>::quiet_NaN()); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenPosInf: - { - Value v(std::numeric_limits<double>::infinity()); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenNegInf: - { - Value v(-std::numeric_limits<double>::infinity()); - currentValue().swapPayload(v); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - } - break; - case tokenArraySeparator: - case tokenObjectEnd: - case tokenArrayEnd: - if (features_.allowDroppedNullPlaceholders_) { - // "Un-read" the current token and mark the current value as a null - // token. - current_--; - Value v; - currentValue().swapPayload(v); - currentValue().setOffsetStart(current_ - begin_ - 1); - currentValue().setOffsetLimit(current_ - begin_); + case tokenObjectBegin: + successful = this->readObject(token); + this->currentValue().setOffsetLimit(this->current_ - this->begin_); + break; + case tokenArrayBegin: + successful = this->readArray(token); + this->currentValue().setOffsetLimit(this->current_ - this->begin_); + break; + case tokenNumber: + successful = this->decodeNumber(token); break; - } // else, fall through ... - default: - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); - return addError("Syntax error: value, object or array expected.", token); + case tokenString: + successful = this->decodeString(token); + break; + case tokenTrue: { + Value v(true); + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenFalse: { + Value v(false); + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenNull: { + Value v; + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenNaN: { + Value v(std::numeric_limits<double>::quiet_NaN()); + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenPosInf: { + Value v(std::numeric_limits<double>::infinity()); + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenNegInf: { + Value v(-std::numeric_limits<double>::infinity()); + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + } break; + case tokenArraySeparator: + case tokenObjectEnd: + case tokenArrayEnd: + if (this->features_.allowDroppedNullPlaceholders_) { + // "Un-read" the current token and mark the current value as a null + // token. + this->current_--; + Value v; + this->currentValue().swapPayload(v); + this->currentValue().setOffsetStart(this->current_ - this->begin_ - 1); + this->currentValue().setOffsetLimit(this->current_ - this->begin_); + break; + } // else, fall through ... + default: + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); + return this->addError("Syntax error: value, object or array expected.", + token); } - if (collectComments_) { - lastValueEnd_ = current_; - lastValue_ = ¤tValue(); + if (this->collectComments_) { + this->lastValueEnd_ = this->current_; + this->lastValue_ = &this->currentValue(); } return successful; } -void OurReader::skipCommentTokens(Token& token) { - if (features_.allowComments_) { +void OurReader::skipCommentTokens(Token& token) +{ + if (this->features_.allowComments_) { do { - readToken(token); + this->readToken(token); } while (token.type_ == tokenComment); } else { - readToken(token); + this->readToken(token); } } -bool OurReader::readToken(Token& token) { - skipSpaces(); - token.start_ = current_; - Char c = getNextChar(); +bool OurReader::readToken(Token& token) +{ + this->skipSpaces(); + token.start_ = this->current_; + Char c = this->getNextChar(); bool ok = true; switch (c) { - case '{': - token.type_ = tokenObjectBegin; - break; - case '}': - token.type_ = tokenObjectEnd; - break; - case '[': - token.type_ = tokenArrayBegin; - break; - case ']': - token.type_ = tokenArrayEnd; - break; - case '"': - token.type_ = tokenString; - ok = readString(); - break; - case '\'': - if (features_.allowSingleQuotes_) { - token.type_ = tokenString; - ok = readStringSingleQuote(); - break; - } // else continue - case '/': - token.type_ = tokenComment; - ok = readComment(); - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - token.type_ = tokenNumber; - readNumber(false); - break; - case '-': - if (readNumber(true)) { + case '{': + token.type_ = tokenObjectBegin; + break; + case '}': + token.type_ = tokenObjectEnd; + break; + case '[': + token.type_ = tokenArrayBegin; + break; + case ']': + token.type_ = tokenArrayEnd; + break; + case '"': + token.type_ = tokenString; + ok = this->readString(); + break; + case '\'': + if (this->features_.allowSingleQuotes_) { + token.type_ = tokenString; + ok = this->readStringSingleQuote(); + break; + } // else continue + case '/': + token.type_ = tokenComment; + ok = this->readComment(); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': token.type_ = tokenNumber; - } else { - token.type_ = tokenNegInf; - ok = features_.allowSpecialFloats_ && match("nfinity", 7); - } - break; - case 't': - token.type_ = tokenTrue; - ok = match("rue", 3); - break; - case 'f': - token.type_ = tokenFalse; - ok = match("alse", 4); - break; - case 'n': - token.type_ = tokenNull; - ok = match("ull", 3); - break; - case 'N': - if (features_.allowSpecialFloats_) { - token.type_ = tokenNaN; - ok = match("aN", 2); - } else { - ok = false; - } - break; - case 'I': - if (features_.allowSpecialFloats_) { - token.type_ = tokenPosInf; - ok = match("nfinity", 7); - } else { + this->readNumber(false); + break; + case '-': + if (this->readNumber(true)) { + token.type_ = tokenNumber; + } else { + token.type_ = tokenNegInf; + ok = this->features_.allowSpecialFloats_ && this->match("nfinity", 7); + } + break; + case 't': + token.type_ = tokenTrue; + ok = this->match("rue", 3); + break; + case 'f': + token.type_ = tokenFalse; + ok = this->match("alse", 4); + break; + case 'n': + token.type_ = tokenNull; + ok = this->match("ull", 3); + break; + case 'N': + if (this->features_.allowSpecialFloats_) { + token.type_ = tokenNaN; + ok = this->match("aN", 2); + } else { + ok = false; + } + break; + case 'I': + if (this->features_.allowSpecialFloats_) { + token.type_ = tokenPosInf; + ok = this->match("nfinity", 7); + } else { + ok = false; + } + break; + case ',': + token.type_ = tokenArraySeparator; + break; + case ':': + token.type_ = tokenMemberSeparator; + break; + case 0: + token.type_ = tokenEndOfStream; + break; + default: ok = false; - } - break; - case ',': - token.type_ = tokenArraySeparator; - break; - case ':': - token.type_ = tokenMemberSeparator; - break; - case 0: - token.type_ = tokenEndOfStream; - break; - default: - ok = false; - break; + break; } if (!ok) token.type_ = tokenError; - token.end_ = current_; + token.end_ = this->current_; return true; } -void OurReader::skipSpaces() { - while (current_ != end_) { - Char c = *current_; +void OurReader::skipSpaces() +{ + while (this->current_ != this->end_) { + Char c = *this->current_; if (c == ' ' || c == '\t' || c == '\r' || c == '\n') - ++current_; + ++this->current_; else break; } } -bool OurReader::match(Location pattern, int patternLength) { - if (end_ - current_ < patternLength) +bool OurReader::match(Location pattern, int patternLength) +{ + if (this->end_ - this->current_ < patternLength) return false; int index = patternLength; while (index--) - if (current_[index] != pattern[index]) + if (this->current_[index] != pattern[index]) return false; - current_ += patternLength; + this->current_ += patternLength; return true; } -bool OurReader::readComment() { - Location commentBegin = current_ - 1; - Char c = getNextChar(); +bool OurReader::readComment() +{ + Location commentBegin = this->current_ - 1; + Char c = this->getNextChar(); bool successful = false; if (c == '*') - successful = readCStyleComment(); + successful = this->readCStyleComment(); else if (c == '/') - successful = readCppStyleComment(); + successful = this->readCppStyleComment(); if (!successful) return false; - if (collectComments_) { + if (this->collectComments_) { CommentPlacement placement = commentBefore; - if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) { - if (c != '*' || !containsNewLine(commentBegin, current_)) + if (this->lastValueEnd_ && + !containsNewLine(this->lastValueEnd_, commentBegin)) { + if (c != '*' || !containsNewLine(commentBegin, this->current_)) placement = commentAfterOnSameLine; } - addComment(commentBegin, current_, placement); + this->addComment(commentBegin, this->current_, placement); } return true; } -JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Location end) { +JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, + OurReader::Location end) +{ JSONCPP_STRING normalized; normalized.reserve(static_cast<size_t>(end - begin)); OurReader::Location current = begin; @@ -1362,8 +1441,8 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Loc char c = *current++; if (c == '\r') { if (current != end && *current == '\n') - // convert dos EOL - ++current; + // convert dos EOL + ++current; // convert Mac EOL normalized += '\n'; } else { @@ -1373,36 +1452,39 @@ JSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Loc return normalized; } -void -OurReader::addComment(Location begin, Location end, CommentPlacement placement) { - assert(collectComments_); +void OurReader::addComment(Location begin, Location end, + CommentPlacement placement) +{ + assert(this->collectComments_); const JSONCPP_STRING& normalized = normalizeEOL(begin, end); if (placement == commentAfterOnSameLine) { - assert(lastValue_ != 0); - lastValue_->setComment(normalized, placement); + assert(this->lastValue_ != 0); + this->lastValue_->setComment(normalized, placement); } else { - commentsBefore_ += normalized; + this->commentsBefore_ += normalized; } } -bool OurReader::readCStyleComment() { - while ((current_ + 1) < end_) { - Char c = getNextChar(); - if (c == '*' && *current_ == '/') +bool OurReader::readCStyleComment() +{ + while ((this->current_ + 1) < this->end_) { + Char c = this->getNextChar(); + if (c == '*' && *this->current_ == '/') break; } - return getNextChar() == '/'; + return this->getNextChar() == '/'; } -bool OurReader::readCppStyleComment() { - while (current_ != end_) { - Char c = getNextChar(); +bool OurReader::readCppStyleComment() +{ + while (this->current_ != this->end_) { + Char c = this->getNextChar(); if (c == '\n') break; if (c == '\r') { // Consume DOS EOL. It will be normalized in addComment. - if (current_ != end_ && *current_ == '\n') - getNextChar(); + if (this->current_ != this->end_ && *this->current_ == '\n') + this->getNextChar(); // Break on Moc OS 9 EOL. break; } @@ -1410,150 +1492,156 @@ bool OurReader::readCppStyleComment() { return true; } -bool OurReader::readNumber(bool checkInf) { - const char *p = current_; - if (checkInf && p != end_ && *p == 'I') { - current_ = ++p; +bool OurReader::readNumber(bool checkInf) +{ + const char* p = this->current_; + if (checkInf && p != this->end_ && *p == 'I') { + this->current_ = ++p; return false; } char c = '0'; // stopgap for already consumed character // integral part while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; // fractional part if (c == '.') { - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; } // exponential part if (c == 'e' || c == 'E') { - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; if (c == '+' || c == '-') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; while (c >= '0' && c <= '9') - c = (current_ = p) < end_ ? *p++ : '\0'; + c = (this->current_ = p) < this->end_ ? *p++ : '\0'; } return true; } -bool OurReader::readString() { +bool OurReader::readString() +{ Char c = 0; - while (current_ != end_) { - c = getNextChar(); + while (this->current_ != this->end_) { + c = this->getNextChar(); if (c == '\\') - getNextChar(); + this->getNextChar(); else if (c == '"') break; } return c == '"'; } - -bool OurReader::readStringSingleQuote() { +bool OurReader::readStringSingleQuote() +{ Char c = 0; - while (current_ != end_) { - c = getNextChar(); + while (this->current_ != this->end_) { + c = this->getNextChar(); if (c == '\\') - getNextChar(); + this->getNextChar(); else if (c == '\'') break; } return c == '\''; } -bool OurReader::readObject(Token& tokenStart) { +bool OurReader::readObject(Token& tokenStart) +{ Token tokenName; JSONCPP_STRING name; Value init(objectValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - while (readToken(tokenName)) { + this->currentValue().swapPayload(init); + this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); + while (this->readToken(tokenName)) { bool initialTokenOk = true; while (tokenName.type_ == tokenComment && initialTokenOk) - initialTokenOk = readToken(tokenName); + initialTokenOk = this->readToken(tokenName); if (!initialTokenOk) break; if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object return true; name.clear(); if (tokenName.type_ == tokenString) { - if (!decodeString(tokenName, name)) - return recoverFromError(tokenObjectEnd); - } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) { + if (!this->decodeString(tokenName, name)) + return this->recoverFromError(tokenObjectEnd); + } else if (tokenName.type_ == tokenNumber && + this->features_.allowNumericKeys_) { Value numberName; - if (!decodeNumber(tokenName, numberName)) - return recoverFromError(tokenObjectEnd); + if (!this->decodeNumber(tokenName, numberName)) + return this->recoverFromError(tokenObjectEnd); name = numberName.asString(); } else { break; } Token colon; - if (!readToken(colon) || colon.type_ != tokenMemberSeparator) { - return addErrorAndRecover( - "Missing ':' after object member name", colon, tokenObjectEnd); + if (!this->readToken(colon) || colon.type_ != tokenMemberSeparator) { + return this->addErrorAndRecover("Missing ':' after object member name", + colon, tokenObjectEnd); } - if (name.length() >= (1U<<30)) throwRuntimeError("keylength >= 2^30"); - if (features_.rejectDupKeys_ && currentValue().isMember(name)) { + if (name.length() >= (1U << 30)) + throwRuntimeError("keylength >= 2^30"); + if (this->features_.rejectDupKeys_ && + this->currentValue().isMember(name)) { JSONCPP_STRING msg = "Duplicate key: '" + name + "'"; - return addErrorAndRecover( - msg, tokenName, tokenObjectEnd); + return this->addErrorAndRecover(msg, tokenName, tokenObjectEnd); } - Value& value = currentValue()[name]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); + Value& value = this->currentValue()[name]; + this->nodes_.push(&value); + bool ok = this->readValue(); + this->nodes_.pop(); if (!ok) // error already set - return recoverFromError(tokenObjectEnd); + return this->recoverFromError(tokenObjectEnd); Token comma; - if (!readToken(comma) || + if (!this->readToken(comma) || (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator && comma.type_ != tokenComment)) { - return addErrorAndRecover( - "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); + return this->addErrorAndRecover( + "Missing ',' or '}' in object declaration", comma, tokenObjectEnd); } bool finalizeTokenOk = true; while (comma.type_ == tokenComment && finalizeTokenOk) - finalizeTokenOk = readToken(comma); + finalizeTokenOk = this->readToken(comma); if (comma.type_ == tokenObjectEnd) return true; } - return addErrorAndRecover( - "Missing '}' or object member name", tokenName, tokenObjectEnd); + return this->addErrorAndRecover("Missing '}' or object member name", + tokenName, tokenObjectEnd); } -bool OurReader::readArray(Token& tokenStart) { +bool OurReader::readArray(Token& tokenStart) +{ Value init(arrayValue); - currentValue().swapPayload(init); - currentValue().setOffsetStart(tokenStart.start_ - begin_); - skipSpaces(); - if (current_ != end_ && *current_ == ']') // empty array + this->currentValue().swapPayload(init); + this->currentValue().setOffsetStart(tokenStart.start_ - this->begin_); + this->skipSpaces(); + if (this->current_ != this->end_ && *this->current_ == ']') // empty array { Token endArray; - readToken(endArray); + this->readToken(endArray); return true; } int index = 0; for (;;) { - Value& value = currentValue()[index++]; - nodes_.push(&value); - bool ok = readValue(); - nodes_.pop(); + Value& value = this->currentValue()[index++]; + this->nodes_.push(&value); + bool ok = this->readValue(); + this->nodes_.pop(); if (!ok) // error already set - return recoverFromError(tokenArrayEnd); + return this->recoverFromError(tokenArrayEnd); Token token; // Accept Comment after last item in the array. - ok = readToken(token); + ok = this->readToken(token); while (token.type_ == tokenComment && ok) { - ok = readToken(token); + ok = this->readToken(token); } bool badTokenType = - (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); + (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd); if (!ok || badTokenType) { - return addErrorAndRecover( - "Missing ',' or ']' in array declaration", token, tokenArrayEnd); + return this->addErrorAndRecover( + "Missing ',' or ']' in array declaration", token, tokenArrayEnd); } if (token.type_ == tokenArrayEnd) break; @@ -1561,17 +1649,19 @@ bool OurReader::readArray(Token& tokenStart) { return true; } -bool OurReader::decodeNumber(Token& token) { +bool OurReader::decodeNumber(Token& token) +{ Value decoded; - if (!decodeNumber(token, decoded)) + if (!this->decodeNumber(token, decoded)) return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); + this->currentValue().swapPayload(decoded); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); return true; } -bool OurReader::decodeNumber(Token& token, Value& decoded) { +bool OurReader::decodeNumber(Token& token, Value& decoded) +{ // Attempts to parse the number as an integer. If the number is // larger than the maximum supported value of an integer then // we decode the number as a double. @@ -1579,16 +1669,17 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { bool isNegative = *current == '-'; if (isNegative) ++current; - // TODO: Help the compiler do the div and mod at compile time or get rid of them. - Value::LargestUInt maxIntegerValue = - isNegative ? Value::LargestUInt(Value::minLargestInt) - : Value::maxLargestUInt; + // TODO: Help the compiler do the div and mod at compile time or get rid of + // them. + Value::LargestUInt maxIntegerValue = isNegative + ? Value::LargestUInt(Value::minLargestInt) + : Value::maxLargestUInt; Value::LargestUInt threshold = maxIntegerValue / 10; Value::LargestUInt value = 0; while (current < token.end_) { Char c = *current++; if (c < '0' || c > '9') - return decodeDouble(token, decoded); + return this->decodeDouble(token, decoded); Value::UInt digit(static_cast<Value::UInt>(c - '0')); if (value >= threshold) { // We've hit or exceeded the max value divided by 10 (rounded down). If @@ -1597,7 +1688,7 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { // Otherwise treat this number as a double to avoid overflow. if (value > threshold || current != token.end_ || digit > maxIntegerValue % 10) { - return decodeDouble(token, decoded); + return this->decodeDouble(token, decoded); } } value = value * 10 + digit; @@ -1611,17 +1702,19 @@ bool OurReader::decodeNumber(Token& token, Value& decoded) { return true; } -bool OurReader::decodeDouble(Token& token) { +bool OurReader::decodeDouble(Token& token) +{ Value decoded; - if (!decodeDouble(token, decoded)) + if (!this->decodeDouble(token, decoded)) return false; - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); + this->currentValue().swapPayload(decoded); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); return true; } -bool OurReader::decodeDouble(Token& token, Value& decoded) { +bool OurReader::decodeDouble(Token& token, Value& decoded) +{ double value = 0; const int bufferSize = 32; int count; @@ -1629,7 +1722,7 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { // Sanity check to avoid buffer overflow exploits. if (length < 0) { - return addError("Unable to parse token length", token); + return this->addError("Unable to parse token length", token); } size_t const ulength = static_cast<size_t>(length); @@ -1652,25 +1745,27 @@ bool OurReader::decodeDouble(Token& token, Value& decoded) { } if (count != 1) - return addError("'" + JSONCPP_STRING(token.start_, token.end_) + - "' is not a number.", - token); + return this->addError("'" + JSONCPP_STRING(token.start_, token.end_) + + "' is not a number.", + token); decoded = value; return true; } -bool OurReader::decodeString(Token& token) { +bool OurReader::decodeString(Token& token) +{ JSONCPP_STRING decoded_string; - if (!decodeString(token, decoded_string)) + if (!this->decodeString(token, decoded_string)) return false; Value decoded(decoded_string); - currentValue().swapPayload(decoded); - currentValue().setOffsetStart(token.start_ - begin_); - currentValue().setOffsetLimit(token.end_ - begin_); + this->currentValue().swapPayload(decoded); + this->currentValue().setOffsetStart(token.start_ - this->begin_); + this->currentValue().setOffsetLimit(token.end_ - this->begin_); return true; } -bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) { +bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) +{ decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2)); Location current = token.start_ + 1; // skip '"' Location end = token.end_ - 1; // do not include '"' @@ -1680,41 +1775,43 @@ bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) { break; else if (c == '\\') { if (current == end) - return addError("Empty escape sequence in string", token, current); + return this->addError("Empty escape sequence in string", token, + current); Char escape = *current++; switch (escape) { - case '"': - decoded += '"'; - break; - case '/': - decoded += '/'; - break; - case '\\': - decoded += '\\'; - break; - case 'b': - decoded += '\b'; - break; - case 'f': - decoded += '\f'; - break; - case 'n': - decoded += '\n'; - break; - case 'r': - decoded += '\r'; - break; - case 't': - decoded += '\t'; - break; - case 'u': { - unsigned int unicode; - if (!decodeUnicodeCodePoint(token, current, end, unicode)) - return false; - decoded += codePointToUTF8(unicode); - } break; - default: - return addError("Bad escape sequence in string", token, current); + case '"': + decoded += '"'; + break; + case '/': + decoded += '/'; + break; + case '\\': + decoded += '\\'; + break; + case 'b': + decoded += '\b'; + break; + case 'f': + decoded += '\f'; + break; + case 'n': + decoded += '\n'; + break; + case 'r': + decoded += '\r'; + break; + case 't': + decoded += '\t'; + break; + case 'u': { + unsigned int unicode; + if (!this->decodeUnicodeCodePoint(token, current, end, unicode)) + return false; + decoded += codePointToUTF8(unicode); + } break; + default: + return this->addError("Bad escape sequence in string", token, + current); } } else { decoded += c; @@ -1723,45 +1820,44 @@ bool OurReader::decodeString(Token& token, JSONCPP_STRING& decoded) { return true; } -bool OurReader::decodeUnicodeCodePoint(Token& token, - Location& current, - Location end, - unsigned int& unicode) { +bool OurReader::decodeUnicodeCodePoint(Token& token, Location& current, + Location end, unsigned int& unicode) +{ unicode = 0; // Convince scanbuild this is always initialized before use. - if (!decodeUnicodeEscapeSequence(token, current, end, unicode)) + if (!this->decodeUnicodeEscapeSequence(token, current, end, unicode)) return false; if (unicode >= 0xD800 && unicode <= 0xDBFF) { // surrogate pairs if (end - current < 6) - return addError( - "additional six characters expected to parse unicode surrogate pair.", - token, - current); + return this->addError( + "additional six characters expected to parse unicode surrogate pair.", + token, current); unsigned int surrogatePair; if (*(current++) == '\\' && *(current++) == 'u') { - if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) { - unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); + if (this->decodeUnicodeEscapeSequence(token, current, end, + surrogatePair)) { + unicode = + 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF); } else return false; } else - return addError("expecting another \\u token to begin the second half of " - "a unicode surrogate pair", - token, - current); + return this->addError( + "expecting another \\u token to begin the second half of " + "a unicode surrogate pair", + token, current); } return true; } -bool OurReader::decodeUnicodeEscapeSequence(Token& token, - Location& current, - Location end, - unsigned int& ret_unicode) { +bool OurReader::decodeUnicodeEscapeSequence(Token& token, Location& current, + Location end, + unsigned int& ret_unicode) +{ if (end - current < 4) - return addError( - "Bad unicode escape sequence in string: four digits expected.", - token, - current); + return this->addError( + "Bad unicode escape sequence in string: four digits expected.", token, + current); int unicode = 0; for (int index = 0; index < 4; ++index) { Char c = *current++; @@ -1773,60 +1869,65 @@ bool OurReader::decodeUnicodeEscapeSequence(Token& token, else if (c >= 'A' && c <= 'F') unicode += c - 'A' + 10; else - return addError( - "Bad unicode escape sequence in string: hexadecimal digit expected.", - token, - current); + return this->addError( + "Bad unicode escape sequence in string: hexadecimal digit expected.", + token, current); } ret_unicode = static_cast<unsigned int>(unicode); return true; } -bool -OurReader::addError(const JSONCPP_STRING& message, Token& token, Location extra) { +bool OurReader::addError(const JSONCPP_STRING& message, Token& token, + Location extra) +{ ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = extra; - errors_.push_back(info); + this->errors_.push_back(info); return false; } -bool OurReader::recoverFromError(TokenType skipUntilToken) { - size_t errorCount = errors_.size(); +bool OurReader::recoverFromError(TokenType skipUntilToken) +{ + size_t errorCount = this->errors_.size(); Token skip; for (;;) { - if (!readToken(skip)) - errors_.resize(errorCount); // discard errors caused by recovery + if (!this->readToken(skip)) + this->errors_.resize(errorCount); // discard errors caused by recovery if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream) break; } - errors_.resize(errorCount); + this->errors_.resize(errorCount); return false; } -bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message, - Token& token, - TokenType skipUntilToken) { - addError(message, token); - return recoverFromError(skipUntilToken); +bool OurReader::addErrorAndRecover(const JSONCPP_STRING& message, Token& token, + TokenType skipUntilToken) +{ + this->addError(message, token); + return this->recoverFromError(skipUntilToken); } -Value& OurReader::currentValue() { return *(nodes_.top()); } +Value& OurReader::currentValue() +{ + return *(this->nodes_.top()); +} -OurReader::Char OurReader::getNextChar() { - if (current_ == end_) +OurReader::Char OurReader::getNextChar() +{ + if (this->current_ == this->end_) return 0; - return *current_++; + return *this->current_++; } -void OurReader::getLocationLineAndColumn(Location location, - int& line, - int& column) const { - Location current = begin_; +void OurReader::getLocationLineAndColumn(Location location, int& line, + int& column) const +{ + Location current = this->begin_; Location lastLineStart = current; line = 0; - while (current < location && current != end_) { + while (current < location && current != this->end_) { Char c = *current++; if (c == '\r') { if (*current == '\n') @@ -1843,101 +1944,105 @@ void OurReader::getLocationLineAndColumn(Location location, ++line; } -JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const { +JSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const +{ int line, column; - getLocationLineAndColumn(location, line, column); + this->getLocationLineAndColumn(location, line, column); char buffer[18 + 16 + 16 + 1]; snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column); return buffer; } -JSONCPP_STRING OurReader::getFormattedErrorMessages() const { +JSONCPP_STRING OurReader::getFormattedErrorMessages() const +{ JSONCPP_STRING formattedMessage; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + for (Errors::const_iterator itError = this->errors_.begin(); + itError != this->errors_.end(); ++itError) { const ErrorInfo& error = *itError; formattedMessage += - "* " + getLocationLineAndColumn(error.token_.start_) + "\n"; + "* " + this->getLocationLineAndColumn(error.token_.start_) + "\n"; formattedMessage += " " + error.message_ + "\n"; if (error.extra_) - formattedMessage += - "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n"; + formattedMessage += "See " + + this->getLocationLineAndColumn(error.extra_) + " for detail.\n"; } return formattedMessage; } -std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const { +std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const +{ std::vector<OurReader::StructuredError> allErrors; - for (Errors::const_iterator itError = errors_.begin(); - itError != errors_.end(); - ++itError) { + for (Errors::const_iterator itError = this->errors_.begin(); + itError != this->errors_.end(); ++itError) { const ErrorInfo& error = *itError; OurReader::StructuredError structured; - structured.offset_start = error.token_.start_ - begin_; - structured.offset_limit = error.token_.end_ - begin_; + structured.offset_start = error.token_.start_ - this->begin_; + structured.offset_limit = error.token_.end_ - this->begin_; structured.message = error.message_; allErrors.push_back(structured); } return allErrors; } -bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) { - ptrdiff_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length) +bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message) +{ + ptrdiff_t length = this->end_ - this->begin_; + if (value.getOffsetStart() > length || value.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = end_ + value.getOffsetLimit(); + token.start_ = this->begin_ + value.getOffsetStart(); + token.end_ = this->end_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; info.extra_ = 0; - errors_.push_back(info); + this->errors_.push_back(info); return true; } -bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, const Value& extra) { - ptrdiff_t length = end_ - begin_; - if(value.getOffsetStart() > length - || value.getOffsetLimit() > length - || extra.getOffsetLimit() > length) +bool OurReader::pushError(const Value& value, const JSONCPP_STRING& message, + const Value& extra) +{ + ptrdiff_t length = this->end_ - this->begin_; + if (value.getOffsetStart() > length || value.getOffsetLimit() > length || + extra.getOffsetLimit() > length) return false; Token token; token.type_ = tokenError; - token.start_ = begin_ + value.getOffsetStart(); - token.end_ = begin_ + value.getOffsetLimit(); + token.start_ = this->begin_ + value.getOffsetStart(); + token.end_ = this->begin_ + value.getOffsetLimit(); ErrorInfo info; info.token_ = token; info.message_ = message; - info.extra_ = begin_ + extra.getOffsetStart(); - errors_.push_back(info); + info.extra_ = this->begin_ + extra.getOffsetStart(); + this->errors_.push_back(info); return true; } -bool OurReader::good() const { - return !errors_.size(); +bool OurReader::good() const +{ + return !this->errors_.size(); } - -class OurCharReader : public CharReader { +class OurCharReader : public CharReader +{ bool const collectComments_; OurReader reader_; + public: - OurCharReader( - bool collectComments, - OurFeatures const& features) - : collectComments_(collectComments) - , reader_(features) - {} - bool parse( - char const* beginDoc, char const* endDoc, - Value* root, JSONCPP_STRING* errs) JSONCPP_OVERRIDE { - bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_); + OurCharReader(bool collectComments, OurFeatures const& features) + : collectComments_(collectComments) + , reader_(features) + { + } + bool parse(char const* beginDoc, char const* endDoc, Value* root, + JSONCPP_STRING* errs) JSONCPP_OVERRIDE + { + bool ok = + this->reader_.parse(beginDoc, endDoc, *root, this->collectComments_); if (errs) { - *errs = reader_.getFormattedErrorMessages(); + *errs = this->reader_.getFormattedErrorMessages(); } return ok; } @@ -1945,23 +2050,26 @@ public: CharReaderBuilder::CharReaderBuilder() { - setDefaults(&settings_); + setDefaults(&this->settings_); } CharReaderBuilder::~CharReaderBuilder() -{} +{ +} CharReader* CharReaderBuilder::newCharReader() const { - bool collectComments = settings_["collectComments"].asBool(); + bool collectComments = this->settings_["collectComments"].asBool(); OurFeatures features = OurFeatures::all(); - features.allowComments_ = settings_["allowComments"].asBool(); - features.strictRoot_ = settings_["strictRoot"].asBool(); - features.allowDroppedNullPlaceholders_ = settings_["allowDroppedNullPlaceholders"].asBool(); - features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool(); - features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool(); - features.stackLimit_ = settings_["stackLimit"].asInt(); - features.failIfExtra_ = settings_["failIfExtra"].asBool(); - features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool(); - features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool(); + features.allowComments_ = this->settings_["allowComments"].asBool(); + features.strictRoot_ = this->settings_["strictRoot"].asBool(); + features.allowDroppedNullPlaceholders_ = + this->settings_["allowDroppedNullPlaceholders"].asBool(); + features.allowNumericKeys_ = this->settings_["allowNumericKeys"].asBool(); + features.allowSingleQuotes_ = this->settings_["allowSingleQuotes"].asBool(); + features.stackLimit_ = this->settings_["stackLimit"].asInt(); + features.failIfExtra_ = this->settings_["failIfExtra"].asBool(); + features.rejectDupKeys_ = this->settings_["rejectDupKeys"].asBool(); + features.allowSpecialFloats_ = + this->settings_["allowSpecialFloats"].asBool(); return new OurCharReader(collectComments, features); } static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys) @@ -1981,28 +2089,29 @@ static void getValidReaderKeys(std::set<JSONCPP_STRING>* valid_keys) bool CharReaderBuilder::validate(Json::Value* invalid) const { Json::Value my_invalid; - if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL + if (!invalid) + invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; std::set<JSONCPP_STRING> valid_keys; getValidReaderKeys(&valid_keys); - Value::Members keys = settings_.getMemberNames(); + Value::Members keys = this->settings_.getMemberNames(); size_t n = keys.size(); for (size_t i = 0; i < n; ++i) { JSONCPP_STRING const& key = keys[i]; if (valid_keys.find(key) == valid_keys.end()) { - inv[key] = settings_[key]; + inv[key] = this->settings_[key]; } } return 0u == inv.size(); } Value& CharReaderBuilder::operator[](JSONCPP_STRING key) { - return settings_[key]; + return this->settings_[key]; } // static void CharReaderBuilder::strictMode(Json::Value* settings) { -//! [CharReaderBuilderStrictMode] + //! [CharReaderBuilderStrictMode] (*settings)["allowComments"] = false; (*settings)["strictRoot"] = true; (*settings)["allowDroppedNullPlaceholders"] = false; @@ -2012,12 +2121,12 @@ void CharReaderBuilder::strictMode(Json::Value* settings) (*settings)["failIfExtra"] = true; (*settings)["rejectDupKeys"] = true; (*settings)["allowSpecialFloats"] = false; -//! [CharReaderBuilderStrictMode] + //! [CharReaderBuilderStrictMode] } // static void CharReaderBuilder::setDefaults(Json::Value* settings) { -//! [CharReaderBuilderDefaults] + //! [CharReaderBuilderDefaults] (*settings)["collectComments"] = true; (*settings)["allowComments"] = true; (*settings)["strictRoot"] = false; @@ -2028,15 +2137,14 @@ void CharReaderBuilder::setDefaults(Json::Value* settings) (*settings)["failIfExtra"] = false; (*settings)["rejectDupKeys"] = false; (*settings)["allowSpecialFloats"] = false; -//! [CharReaderBuilderDefaults] + //! [CharReaderBuilderDefaults] } ////////////////////////////////// // global functions -bool parseFromStream( - CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, - Value* root, JSONCPP_STRING* errs) +bool parseFromStream(CharReader::Factory const& fact, JSONCPP_ISTREAM& sin, + Value* root, JSONCPP_STRING* errs) { JSONCPP_OSTRINGSTREAM ssin; ssin << sin.rdbuf(); @@ -2048,14 +2156,13 @@ bool parseFromStream( return reader->parse(begin, end, root, errs); } -JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) { +JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM& sin, Value& root) +{ CharReaderBuilder b; JSONCPP_STRING errs; bool ok = parseFromStream(b, sin, &root, &errs); if (!ok) { - fprintf(stderr, - "Error from reader: %s", - errs.c_str()); + fprintf(stderr, "Error from reader: %s", errs.c_str()); throwRuntimeError(errs); } diff --git a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp index f271e57..eadb1c3 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_value.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_value.cpp @@ -1,23 +1,25 @@ // Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE +// See file LICENSE for detail or copy at +// http://jsoncpp.sourceforge.net/LICENSE #if !defined(JSON_IS_AMALGAMATION) -#include <json/assertions.h> -#include <json/value.h> -#include <json/writer.h> +# include <json/assertions.h> +# include <json/value.h> +# include <json/writer.h> #endif // if !defined(JSON_IS_AMALGAMATION) -#include <math.h> #include <sstream> #include <utility> -#include <string.h> + #include <assert.h> +#include <math.h> +#include <string.h> #ifdef JSON_USE_CPPTL -#include <cpptl/conststring.h> +# include <cpptl/conststring.h> #endif -#include <cstddef> // size_t #include <algorithm> // min() +#include <cstddef> // size_t #define JSON_ASSERT_UNREACHABLE assert(false) @@ -27,24 +29,24 @@ namespace Json { // kNull must be word-aligned to avoid crashing on ARM. We use an alignment of // 8 (instead of 4) as a bit of future-proofing. #if defined(__ARMEL__) -#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) +# define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) #else -#define ALIGNAS(byte_alignment) +# define ALIGNAS(byte_alignment) #endif -//static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; -//const unsigned char& kNullRef = kNull[0]; -//const Value& Value::null = reinterpret_cast<const Value&>(kNullRef); -//const Value& Value::nullRef = null; +// static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 }; +// const unsigned char& kNullRef = kNull[0]; +// const Value& Value::null = reinterpret_cast<const Value&>(kNullRef); +// const Value& Value::nullRef = null; // static Value const& Value::nullSingleton() { - static Value const nullStatic; - return nullStatic; + static Value const nullStatic; + return nullStatic; } -// for backwards compatibility, we'll leave these global references around, but DO NOT -// use them in JSONCPP library code any more! +// for backwards compatibility, we'll leave these global references around, but +// DO NOT use them in JSONCPP library code any more! Value const& Value::null = Value::nullSingleton(); Value const& Value::nullRef = Value::nullSingleton(); @@ -66,23 +68,29 @@ const LargestUInt Value::maxLargestUInt = LargestUInt(-1); #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) template <typename T, typename U> -static inline bool InRange(double d, T min, U max) { +static inline bool InRange(double d, T min, U max) +{ // The casts can lose precision, but we are looking only for // an approximate range. Might fail on edge cases though. ~cdunn - //return d >= static_cast<double>(min) && d <= static_cast<double>(max); + // return d >= static_cast<double>(min) && d <= static_cast<double>(max); return d >= min && d <= max; } #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) -static inline double integerToDouble(Json::UInt64 value) { - return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1)); +static inline double integerToDouble(Json::UInt64 value) +{ + return static_cast<double>(Int64(value / 2)) * 2.0 + + static_cast<double>(Int64(value & 1)); } -template <typename T> static inline double integerToDouble(T value) { +template <typename T> +static inline double integerToDouble(T value) +{ return static_cast<double>(value); } template <typename T, typename U> -static inline bool InRange(double d, T min, U max) { +static inline bool InRange(double d, T min, U max) +{ return d >= integerToDouble(min) && d <= integerToDouble(max); } #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) @@ -94,8 +102,7 @@ static inline bool InRange(double d, T min, U max) { * computed using strlen(value). * @return Pointer on the duplicate instance of string. */ -static inline char* duplicateStringValue(const char* value, - size_t length) +static inline char* duplicateStringValue(const char* value, size_t length) { // Avoid an integer overflow in the call to malloc below by limiting length // to a sane value. @@ -104,9 +111,8 @@ static inline char* duplicateStringValue(const char* value, char* newString = static_cast<char*>(malloc(length + 1)); if (newString == NULL) { - throwRuntimeError( - "in Json::Value::duplicateStringValue(): " - "Failed to allocate string value buffer"); + throwRuntimeError("in Json::Value::duplicateStringValue(): " + "Failed to allocate string value buffer"); } memcpy(newString, value, length); newString[length] = 0; @@ -115,30 +121,30 @@ static inline char* duplicateStringValue(const char* value, /* Record the length as a prefix. */ -static inline char* duplicateAndPrefixStringValue( - const char* value, - unsigned int length) +static inline char* duplicateAndPrefixStringValue(const char* value, + unsigned int length) { // Avoid an integer overflow in the call to malloc below by limiting length // to a sane value. - JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U, + JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - + sizeof(unsigned) - 1U, "in Json::Value::duplicateAndPrefixStringValue(): " "length too big for prefixing"); - unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U; + unsigned actualLength = + length + static_cast<unsigned>(sizeof(unsigned)) + 1U; char* newString = static_cast<char*>(malloc(actualLength)); if (newString == 0) { - throwRuntimeError( - "in Json::Value::duplicateAndPrefixStringValue(): " - "Failed to allocate string value buffer"); + throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): " + "Failed to allocate string value buffer"); } *reinterpret_cast<unsigned*>(newString) = length; memcpy(newString + sizeof(unsigned), value, length); - newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later + newString[actualLength - 1U] = + 0; // to avoid buffer over-run accidents by users later return newString; } -inline static void decodePrefixedString( - bool isPrefixed, char const* prefixed, - unsigned* length, char const** value) +inline static void decodePrefixedString(bool isPrefixed, char const* prefixed, + unsigned* length, char const** value) { if (!isPrefixed) { *length = static_cast<unsigned>(strlen(prefixed)); @@ -148,10 +154,12 @@ inline static void decodePrefixedString( *value = prefixed + sizeof(unsigned); } } -/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue(). +/** Free the string duplicated by + * duplicateStringValue()/duplicateAndPrefixStringValue(). */ #if JSONCPP_USING_SECURE_MEMORY -static inline void releasePrefixedStringValue(char* value) { +static inline void releasePrefixedStringValue(char* value) +{ unsigned length = 0; char const* valueDecoded; decodePrefixedString(true, value, &length, &valueDecoded); @@ -159,17 +167,20 @@ static inline void releasePrefixedStringValue(char* value) { memset(value, 0, size); free(value); } -static inline void releaseStringValue(char* value, unsigned length) { +static inline void releaseStringValue(char* value, unsigned length) +{ // length==0 => we allocated the strings memory - size_t size = (length==0) ? strlen(value) : length; + size_t size = (length == 0) ? strlen(value) : length; memset(value, 0, size); free(value); } -#else // !JSONCPP_USING_SECURE_MEMORY -static inline void releasePrefixedStringValue(char* value) { +#else // !JSONCPP_USING_SECURE_MEMORY +static inline void releasePrefixedStringValue(char* value) +{ free(value); } -static inline void releaseStringValue(char* value, unsigned) { +static inline void releaseStringValue(char* value, unsigned) +{ free(value); } #endif // JSONCPP_USING_SECURE_MEMORY @@ -185,26 +196,30 @@ static inline void releaseStringValue(char* value, unsigned) { // ////////////////////////////////////////////////////////////////// #if !defined(JSON_IS_AMALGAMATION) -#include "json_valueiterator.inl" +# include "json_valueiterator.inl" #endif // if !defined(JSON_IS_AMALGAMATION) namespace Json { Exception::Exception(JSONCPP_STRING const& msg) : msg_(msg) -{} +{ +} Exception::~Exception() JSONCPP_NOEXCEPT -{} +{ +} char const* Exception::what() const JSONCPP_NOEXCEPT { - return msg_.c_str(); + return this->msg_.c_str(); } RuntimeError::RuntimeError(JSONCPP_STRING const& msg) : Exception(msg) -{} +{ +} LogicError::LogicError(JSONCPP_STRING const& msg) : Exception(msg) -{} +{ +} JSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const& msg) { throw RuntimeError(msg); @@ -222,25 +237,29 @@ JSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const& msg) // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// -Value::CommentInfo::CommentInfo() : comment_(0) -{} +Value::CommentInfo::CommentInfo() + : comment_(0) +{ +} -Value::CommentInfo::~CommentInfo() { - if (comment_) - releaseStringValue(comment_, 0u); +Value::CommentInfo::~CommentInfo() +{ + if (this->comment_) + releaseStringValue(this->comment_, 0u); } -void Value::CommentInfo::setComment(const char* text, size_t len) { - if (comment_) { - releaseStringValue(comment_, 0u); - comment_ = 0; +void Value::CommentInfo::setComment(const char* text, size_t len) +{ + if (this->comment_) { + releaseStringValue(this->comment_, 0u); + this->comment_ = 0; } JSON_ASSERT(text != 0); JSON_ASSERT_MESSAGE( - text[0] == '\0' || text[0] == '/', - "in Json::Value::setComment(): Comments must start with /"); + text[0] == '\0' || text[0] == '/', + "in Json::Value::setComment(): Comments must start with /"); // It seems that /**/ style comments are acceptable as well. - comment_ = duplicateStringValue(text, len); + this->comment_ = duplicateStringValue(text, len); } // ////////////////////////////////////////////////////////////////// @@ -254,91 +273,130 @@ void Value::CommentInfo::setComment(const char* text, size_t len) { // Notes: policy_ indicates if the string was allocated when // a string is stored. -Value::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {} +Value::CZString::CZString(ArrayIndex aindex) + : cstr_(0) + , index_(aindex) +{ +} -Value::CZString::CZString(char const* str, unsigned ulength, DuplicationPolicy allocate) - : cstr_(str) { +Value::CZString::CZString(char const* str, unsigned ulength, + DuplicationPolicy allocate) + : cstr_(str) +{ // allocate != duplicate - storage_.policy_ = allocate & 0x3; - storage_.length_ = ulength & 0x3FFFFFFF; + this->storage_.policy_ = allocate & 0x3; + this->storage_.length_ = ulength & 0x3FFFFFFF; } -Value::CZString::CZString(const CZString& other) { - cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0 - ? duplicateStringValue(other.cstr_, other.storage_.length_) - : other.cstr_); - storage_.policy_ = static_cast<unsigned>(other.cstr_ - ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication - ? noDuplication : duplicate) - : static_cast<DuplicationPolicy>(other.storage_.policy_)) & 3U; - storage_.length_ = other.storage_.length_; +Value::CZString::CZString(const CZString& other) +{ + this->cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0 + ? duplicateStringValue(other.cstr_, other.storage_.length_) + : other.cstr_); + this->storage_.policy_ = + static_cast<unsigned>( + other.cstr_ ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == + noDuplication + ? noDuplication + : duplicate) + : static_cast<DuplicationPolicy>(other.storage_.policy_)) & + 3U; + this->storage_.length_ = other.storage_.length_; } #if JSON_HAS_RVALUE_REFERENCES Value::CZString::CZString(CZString&& other) - : cstr_(other.cstr_), index_(other.index_) { + : cstr_(other.cstr_) + , index_(other.index_) +{ other.cstr_ = nullptr; } #endif -Value::CZString::~CZString() { - if (cstr_ && storage_.policy_ == duplicate) { - releaseStringValue(const_cast<char*>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary +Value::CZString::~CZString() +{ + if (this->cstr_ && this->storage_.policy_ == duplicate) { + releaseStringValue(const_cast<char*>(this->cstr_), + this->storage_.length_ + + 1u); //+1 for null terminating character for sake of + //completeness but not actually necessary } } -void Value::CZString::swap(CZString& other) { - std::swap(cstr_, other.cstr_); - std::swap(index_, other.index_); +void Value::CZString::swap(CZString& other) +{ + std::swap(this->cstr_, other.cstr_); + std::swap(this->index_, other.index_); } -Value::CZString& Value::CZString::operator=(const CZString& other) { - cstr_ = other.cstr_; - index_ = other.index_; +Value::CZString& Value::CZString::operator=(const CZString& other) +{ + this->cstr_ = other.cstr_; + this->index_ = other.index_; return *this; } #if JSON_HAS_RVALUE_REFERENCES -Value::CZString& Value::CZString::operator=(CZString&& other) { - cstr_ = other.cstr_; - index_ = other.index_; +Value::CZString& Value::CZString::operator=(CZString&& other) +{ + this->cstr_ = other.cstr_; + this->index_ = other.index_; other.cstr_ = nullptr; return *this; } #endif -bool Value::CZString::operator<(const CZString& other) const { - if (!cstr_) return index_ < other.index_; - //return strcmp(cstr_, other.cstr_) < 0; +bool Value::CZString::operator<(const CZString& other) const +{ + if (!this->cstr_) + return this->index_ < other.index_; + // return strcmp(cstr_, other.cstr_) < 0; // Assume both are strings. unsigned this_len = this->storage_.length_; unsigned other_len = other.storage_.length_; unsigned min_len = std::min<unsigned>(this_len, other_len); JSON_ASSERT(this->cstr_ && other.cstr_); int comp = memcmp(this->cstr_, other.cstr_, min_len); - if (comp < 0) return true; - if (comp > 0) return false; + if (comp < 0) + return true; + if (comp > 0) + return false; return (this_len < other_len); } -bool Value::CZString::operator==(const CZString& other) const { - if (!cstr_) return index_ == other.index_; - //return strcmp(cstr_, other.cstr_) == 0; +bool Value::CZString::operator==(const CZString& other) const +{ + if (!this->cstr_) + return this->index_ == other.index_; + // return strcmp(cstr_, other.cstr_) == 0; // Assume both are strings. unsigned this_len = this->storage_.length_; unsigned other_len = other.storage_.length_; - if (this_len != other_len) return false; + if (this_len != other_len) + return false; JSON_ASSERT(this->cstr_ && other.cstr_); int comp = memcmp(this->cstr_, other.cstr_, this_len); return comp == 0; } -ArrayIndex Value::CZString::index() const { return index_; } +ArrayIndex Value::CZString::index() const +{ + return this->index_; +} -//const char* Value::CZString::c_str() const { return cstr_; } -const char* Value::CZString::data() const { return cstr_; } -unsigned Value::CZString::length() const { return storage_.length_; } -bool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; } +// const char* Value::CZString::c_str() const { return cstr_; } +const char* Value::CZString::data() const +{ + return this->cstr_; +} +unsigned Value::CZString::length() const +{ + return this->storage_.length_; +} +bool Value::CZString::isStaticString() const +{ + return this->storage_.policy_ == noDuplication; +} // ////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////// @@ -352,210 +410,238 @@ bool Value::CZString::isStaticString() const { return storage_.policy_ == noDupl * memset( this, 0, sizeof(Value) ) * This optimization is used in ValueInternalMap fast allocator. */ -Value::Value(ValueType vtype) { +Value::Value(ValueType vtype) +{ static char const emptyString[] = ""; - initBasic(vtype); + this->initBasic(vtype); switch (vtype) { - case nullValue: - break; - case intValue: - case uintValue: - value_.int_ = 0; - break; - case realValue: - value_.real_ = 0.0; - break; - case stringValue: - // allocated_ == false, so this is safe. - value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString)); - break; - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues(); - break; - case booleanValue: - value_.bool_ = false; - break; - default: - JSON_ASSERT_UNREACHABLE; + case nullValue: + break; + case intValue: + case uintValue: + this->value_.int_ = 0; + break; + case realValue: + this->value_.real_ = 0.0; + break; + case stringValue: + // allocated_ == false, so this is safe. + this->value_.string_ = + const_cast<char*>(static_cast<char const*>(emptyString)); + break; + case arrayValue: + case objectValue: + this->value_.map_ = new ObjectValues(); + break; + case booleanValue: + this->value_.bool_ = false; + break; + default: + JSON_ASSERT_UNREACHABLE; } } -Value::Value(Int value) { - initBasic(intValue); - value_.int_ = value; +Value::Value(Int value) +{ + this->initBasic(intValue); + this->value_.int_ = value; } -Value::Value(UInt value) { - initBasic(uintValue); - value_.uint_ = value; +Value::Value(UInt value) +{ + this->initBasic(uintValue); + this->value_.uint_ = value; } #if defined(JSON_HAS_INT64) -Value::Value(Int64 value) { - initBasic(intValue); - value_.int_ = value; +Value::Value(Int64 value) +{ + this->initBasic(intValue); + this->value_.int_ = value; } -Value::Value(UInt64 value) { - initBasic(uintValue); - value_.uint_ = value; +Value::Value(UInt64 value) +{ + this->initBasic(uintValue); + this->value_.uint_ = value; } #endif // defined(JSON_HAS_INT64) -Value::Value(double value) { - initBasic(realValue); - value_.real_ = value; +Value::Value(double value) +{ + this->initBasic(realValue); + this->value_.real_ = value; } -Value::Value(const char* value) { - initBasic(stringValue, true); +Value::Value(const char* value) +{ + this->initBasic(stringValue, true); JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor"); - value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value))); + this->value_.string_ = + duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value))); } -Value::Value(const char* beginValue, const char* endValue) { - initBasic(stringValue, true); - value_.string_ = - duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue)); +Value::Value(const char* beginValue, const char* endValue) +{ + this->initBasic(stringValue, true); + this->value_.string_ = duplicateAndPrefixStringValue( + beginValue, static_cast<unsigned>(endValue - beginValue)); } -Value::Value(const JSONCPP_STRING& value) { - initBasic(stringValue, true); - value_.string_ = - duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length())); +Value::Value(const JSONCPP_STRING& value) +{ + this->initBasic(stringValue, true); + this->value_.string_ = duplicateAndPrefixStringValue( + value.data(), static_cast<unsigned>(value.length())); } -Value::Value(const StaticString& value) { - initBasic(stringValue); - value_.string_ = const_cast<char*>(value.c_str()); +Value::Value(const StaticString& value) +{ + this->initBasic(stringValue); + this->value_.string_ = const_cast<char*>(value.c_str()); } #ifdef JSON_USE_CPPTL -Value::Value(const CppTL::ConstString& value) { +Value::Value(const CppTL::ConstString& value) +{ initBasic(stringValue, true); - value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length())); + value_.string_ = duplicateAndPrefixStringValue( + value, static_cast<unsigned>(value.length())); } #endif -Value::Value(bool value) { - initBasic(booleanValue); - value_.bool_ = value; +Value::Value(bool value) +{ + this->initBasic(booleanValue); + this->value_.bool_ = value; } Value::Value(Value const& other) - : type_(other.type_), allocated_(false) - , - comments_(0), start_(other.start_), limit_(other.limit_) -{ - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - value_ = other.value_; - break; - case stringValue: - if (other.value_.string_ && other.allocated_) { - unsigned len; - char const* str; - decodePrefixedString(other.allocated_, other.value_.string_, - &len, &str); - value_.string_ = duplicateAndPrefixStringValue(str, len); - allocated_ = true; - } else { - value_.string_ = other.value_.string_; - allocated_ = false; - } - break; - case arrayValue: - case objectValue: - value_.map_ = new ObjectValues(*other.value_.map_); - break; - default: - JSON_ASSERT_UNREACHABLE; + : type_(other.type_) + , allocated_(false) + , comments_(0) + , start_(other.start_) + , limit_(other.limit_) +{ + switch (this->type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + this->value_ = other.value_; + break; + case stringValue: + if (other.value_.string_ && other.allocated_) { + unsigned len; + char const* str; + decodePrefixedString(other.allocated_, other.value_.string_, &len, + &str); + this->value_.string_ = duplicateAndPrefixStringValue(str, len); + this->allocated_ = true; + } else { + this->value_.string_ = other.value_.string_; + this->allocated_ = false; + } + break; + case arrayValue: + case objectValue: + this->value_.map_ = new ObjectValues(*other.value_.map_); + break; + default: + JSON_ASSERT_UNREACHABLE; } if (other.comments_) { - comments_ = new CommentInfo[numberOfCommentPlacement]; + this->comments_ = new CommentInfo[numberOfCommentPlacement]; for (int comment = 0; comment < numberOfCommentPlacement; ++comment) { const CommentInfo& otherComment = other.comments_[comment]; if (otherComment.comment_) - comments_[comment].setComment( - otherComment.comment_, strlen(otherComment.comment_)); + this->comments_[comment].setComment(otherComment.comment_, + strlen(otherComment.comment_)); } } } #if JSON_HAS_RVALUE_REFERENCES // Move constructor -Value::Value(Value&& other) { - initBasic(nullValue); - swap(other); +Value::Value(Value&& other) +{ + this->initBasic(nullValue); + this->swap(other); } #endif -Value::~Value() { - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - break; - case stringValue: - if (allocated_) - releasePrefixedStringValue(value_.string_); - break; - case arrayValue: - case objectValue: - delete value_.map_; - break; - default: - JSON_ASSERT_UNREACHABLE; +Value::~Value() +{ + switch (this->type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + break; + case stringValue: + if (this->allocated_) + releasePrefixedStringValue(this->value_.string_); + break; + case arrayValue: + case objectValue: + delete this->value_.map_; + break; + default: + JSON_ASSERT_UNREACHABLE; } - delete[] comments_; + delete[] this->comments_; - value_.uint_ = 0; + this->value_.uint_ = 0; } -Value& Value::operator=(Value other) { - swap(other); +Value& Value::operator=(Value other) +{ + this->swap(other); return *this; } -void Value::swapPayload(Value& other) { - ValueType temp = type_; - type_ = other.type_; +void Value::swapPayload(Value& other) +{ + ValueType temp = this->type_; + this->type_ = other.type_; other.type_ = temp; - std::swap(value_, other.value_); - int temp2 = allocated_; - allocated_ = other.allocated_; + std::swap(this->value_, other.value_); + int temp2 = this->allocated_; + this->allocated_ = other.allocated_; other.allocated_ = temp2 & 0x1; } -void Value::copyPayload(const Value& other) { - type_ = other.type_; - value_ = other.value_; - allocated_ = other.allocated_; +void Value::copyPayload(const Value& other) +{ + this->type_ = other.type_; + this->value_ = other.value_; + this->allocated_ = other.allocated_; } -void Value::swap(Value& other) { - swapPayload(other); - std::swap(comments_, other.comments_); - std::swap(start_, other.start_); - std::swap(limit_, other.limit_); +void Value::swap(Value& other) +{ + this->swapPayload(other); + std::swap(this->comments_, other.comments_); + std::swap(this->start_, other.start_); + std::swap(this->limit_, other.limit_); } -void Value::copy(const Value& other) { - copyPayload(other); - comments_ = other.comments_; - start_ = other.start_; - limit_ = other.limit_; +void Value::copy(const Value& other) +{ + this->copyPayload(other); + this->comments_ = other.comments_; + this->start_ = other.start_; + this->limit_ = other.limit_; } -ValueType Value::type() const { return type_; } +ValueType Value::type() const +{ + return this->type_; +} -int Value::compare(const Value& other) const { +int Value::compare(const Value& other) const +{ if (*this < other) return -1; if (*this > other) @@ -563,509 +649,568 @@ int Value::compare(const Value& other) const { return 0; } -bool Value::operator<(const Value& other) const { - int typeDelta = type_ - other.type_; +bool Value::operator<(const Value& other) const +{ + int typeDelta = this->type_ - other.type_; if (typeDelta) return typeDelta < 0 ? true : false; - switch (type_) { - case nullValue: - return false; - case intValue: - return value_.int_ < other.value_.int_; - case uintValue: - return value_.uint_ < other.value_.uint_; - case realValue: - return value_.real_ < other.value_.real_; - case booleanValue: - return value_.bool_ < other.value_.bool_; - case stringValue: - { - if ((value_.string_ == 0) || (other.value_.string_ == 0)) { - if (other.value_.string_) return true; - else return false; + switch (this->type_) { + case nullValue: + return false; + case intValue: + return this->value_.int_ < other.value_.int_; + case uintValue: + return this->value_.uint_ < other.value_.uint_; + case realValue: + return this->value_.real_ < other.value_.real_; + case booleanValue: + return this->value_.bool_ < other.value_.bool_; + case stringValue: { + if ((this->value_.string_ == 0) || (other.value_.string_ == 0)) { + if (other.value_.string_) + return true; + else + return false; + } + unsigned this_len; + unsigned other_len; + char const* this_str; + char const* other_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); + decodePrefixedString(other.allocated_, other.value_.string_, &other_len, + &other_str); + unsigned min_len = std::min<unsigned>(this_len, other_len); + JSON_ASSERT(this_str && other_str); + int comp = memcmp(this_str, other_str, min_len); + if (comp < 0) + return true; + if (comp > 0) + return false; + return (this_len < other_len); } - unsigned this_len; - unsigned other_len; - char const* this_str; - char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); - unsigned min_len = std::min<unsigned>(this_len, other_len); - JSON_ASSERT(this_str && other_str); - int comp = memcmp(this_str, other_str, min_len); - if (comp < 0) return true; - if (comp > 0) return false; - return (this_len < other_len); - } - case arrayValue: - case objectValue: { - int delta = int(value_.map_->size() - other.value_.map_->size()); - if (delta) - return delta < 0; - return (*value_.map_) < (*other.value_.map_); - } - default: - JSON_ASSERT_UNREACHABLE; + case arrayValue: + case objectValue: { + int delta = int(this->value_.map_->size() - other.value_.map_->size()); + if (delta) + return delta < 0; + return (*this->value_.map_) < (*other.value_.map_); + } + default: + JSON_ASSERT_UNREACHABLE; } return false; // unreachable } -bool Value::operator<=(const Value& other) const { return !(other < *this); } +bool Value::operator<=(const Value& other) const +{ + return !(other < *this); +} -bool Value::operator>=(const Value& other) const { return !(*this < other); } +bool Value::operator>=(const Value& other) const +{ + return !(*this < other); +} -bool Value::operator>(const Value& other) const { return other < *this; } +bool Value::operator>(const Value& other) const +{ + return other < *this; +} -bool Value::operator==(const Value& other) const { +bool Value::operator==(const Value& other) const +{ // if ( type_ != other.type_ ) // GCC 2.95.3 says: // attempt to take address of bit-field structure member `Json::Value::type_' // Beats me, but a temp solves the problem. int temp = other.type_; - if (type_ != temp) + if (this->type_ != temp) return false; - switch (type_) { - case nullValue: - return true; - case intValue: - return value_.int_ == other.value_.int_; - case uintValue: - return value_.uint_ == other.value_.uint_; - case realValue: - return value_.real_ == other.value_.real_; - case booleanValue: - return value_.bool_ == other.value_.bool_; - case stringValue: - { - if ((value_.string_ == 0) || (other.value_.string_ == 0)) { - return (value_.string_ == other.value_.string_); + switch (this->type_) { + case nullValue: + return true; + case intValue: + return this->value_.int_ == other.value_.int_; + case uintValue: + return this->value_.uint_ == other.value_.uint_; + case realValue: + return this->value_.real_ == other.value_.real_; + case booleanValue: + return this->value_.bool_ == other.value_.bool_; + case stringValue: { + if ((this->value_.string_ == 0) || (other.value_.string_ == 0)) { + return (this->value_.string_ == other.value_.string_); + } + unsigned this_len; + unsigned other_len; + char const* this_str; + char const* other_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); + decodePrefixedString(other.allocated_, other.value_.string_, &other_len, + &other_str); + if (this_len != other_len) + return false; + JSON_ASSERT(this_str && other_str); + int comp = memcmp(this_str, other_str, this_len); + return comp == 0; } - unsigned this_len; - unsigned other_len; - char const* this_str; - char const* other_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str); - if (this_len != other_len) return false; - JSON_ASSERT(this_str && other_str); - int comp = memcmp(this_str, other_str, this_len); - return comp == 0; - } - case arrayValue: - case objectValue: - return value_.map_->size() == other.value_.map_->size() && - (*value_.map_) == (*other.value_.map_); - default: - JSON_ASSERT_UNREACHABLE; + case arrayValue: + case objectValue: + return this->value_.map_->size() == other.value_.map_->size() && + (*this->value_.map_) == (*other.value_.map_); + default: + JSON_ASSERT_UNREACHABLE; } return false; // unreachable } -bool Value::operator!=(const Value& other) const { return !(*this == other); } +bool Value::operator!=(const Value& other) const +{ + return !(*this == other); +} -const char* Value::asCString() const { +const char* Value::asCString() const +{ JSON_ASSERT_MESSAGE(type_ == stringValue, "in Json::Value::asCString(): requires stringValue"); - if (value_.string_ == 0) return 0; + if (this->value_.string_ == 0) + return 0; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); return this_str; } #if JSONCPP_USING_SECURE_MEMORY -unsigned Value::getCStringLength() const { +unsigned Value::getCStringLength() const +{ JSON_ASSERT_MESSAGE(type_ == stringValue, - "in Json::Value::asCString(): requires stringValue"); - if (value_.string_ == 0) return 0; + "in Json::Value::asCString(): requires stringValue"); + if (value_.string_ == 0) + return 0; unsigned this_len; char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); return this_len; } #endif -bool Value::getString(char const** str, char const** cend) const { - if (type_ != stringValue) return false; - if (value_.string_ == 0) return false; +bool Value::getString(char const** str, char const** cend) const +{ + if (this->type_ != stringValue) + return false; + if (this->value_.string_ == 0) + return false; unsigned length; decodePrefixedString(this->allocated_, this->value_.string_, &length, str); *cend = *str + length; return true; } -JSONCPP_STRING Value::asString() const { - switch (type_) { - case nullValue: - return ""; - case stringValue: - { - if (value_.string_ == 0) return ""; - unsigned this_len; - char const* this_str; - decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str); - return JSONCPP_STRING(this_str, this_len); - } - case booleanValue: - return value_.bool_ ? "true" : "false"; - case intValue: - return valueToString(value_.int_); - case uintValue: - return valueToString(value_.uint_); - case realValue: - return valueToString(value_.real_); - default: - JSON_FAIL_MESSAGE("Type is not convertible to string"); +JSONCPP_STRING Value::asString() const +{ + switch (this->type_) { + case nullValue: + return ""; + case stringValue: { + if (this->value_.string_ == 0) + return ""; + unsigned this_len; + char const* this_str; + decodePrefixedString(this->allocated_, this->value_.string_, &this_len, + &this_str); + return JSONCPP_STRING(this_str, this_len); + } + case booleanValue: + return this->value_.bool_ ? "true" : "false"; + case intValue: + return valueToString(this->value_.int_); + case uintValue: + return valueToString(this->value_.uint_); + case realValue: + return valueToString(this->value_.real_); + default: + JSON_FAIL_MESSAGE("Type is not convertible to string"); } } #ifdef JSON_USE_CPPTL -CppTL::ConstString Value::asConstString() const { +CppTL::ConstString Value::asConstString() const +{ unsigned len; char const* str; - decodePrefixedString(allocated_, value_.string_, - &len, &str); + decodePrefixedString(allocated_, value_.string_, &len, &str); return CppTL::ConstString(str, len); } #endif -Value::Int Value::asInt() const { - switch (type_) { - case intValue: - JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); - return Int(value_.int_); - case uintValue: - JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); - return Int(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), - "double out of Int range"); - return Int(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; +Value::Int Value::asInt() const +{ + switch (this->type_) { + case intValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range"); + return Int(this->value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range"); + return Int(this->value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt), + "double out of Int range"); + return Int(this->value_.real_); + case nullValue: + return 0; + case booleanValue: + return this->value_.bool_ ? 1 : 0; + default: + break; } JSON_FAIL_MESSAGE("Value is not convertible to Int."); } -Value::UInt Value::asUInt() const { - switch (type_) { - case intValue: - JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); - return UInt(value_.int_); - case uintValue: - JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); - return UInt(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), - "double out of UInt range"); - return UInt(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; +Value::UInt Value::asUInt() const +{ + switch (this->type_) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range"); + return UInt(this->value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range"); + return UInt(this->value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt), + "double out of UInt range"); + return UInt(this->value_.real_); + case nullValue: + return 0; + case booleanValue: + return this->value_.bool_ ? 1 : 0; + default: + break; } JSON_FAIL_MESSAGE("Value is not convertible to UInt."); } #if defined(JSON_HAS_INT64) -Value::Int64 Value::asInt64() const { - switch (type_) { - case intValue: - return Int64(value_.int_); - case uintValue: - JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); - return Int64(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), - "double out of Int64 range"); - return Int64(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; +Value::Int64 Value::asInt64() const +{ + switch (this->type_) { + case intValue: + return Int64(this->value_.int_); + case uintValue: + JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range"); + return Int64(this->value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64), + "double out of Int64 range"); + return Int64(this->value_.real_); + case nullValue: + return 0; + case booleanValue: + return this->value_.bool_ ? 1 : 0; + default: + break; } JSON_FAIL_MESSAGE("Value is not convertible to Int64."); } -Value::UInt64 Value::asUInt64() const { - switch (type_) { - case intValue: - JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); - return UInt64(value_.int_); - case uintValue: - return UInt64(value_.uint_); - case realValue: - JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), - "double out of UInt64 range"); - return UInt64(value_.real_); - case nullValue: - return 0; - case booleanValue: - return value_.bool_ ? 1 : 0; - default: - break; +Value::UInt64 Value::asUInt64() const +{ + switch (this->type_) { + case intValue: + JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range"); + return UInt64(this->value_.int_); + case uintValue: + return UInt64(this->value_.uint_); + case realValue: + JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64), + "double out of UInt64 range"); + return UInt64(this->value_.real_); + case nullValue: + return 0; + case booleanValue: + return this->value_.bool_ ? 1 : 0; + default: + break; } JSON_FAIL_MESSAGE("Value is not convertible to UInt64."); } #endif // if defined(JSON_HAS_INT64) -LargestInt Value::asLargestInt() const { +LargestInt Value::asLargestInt() const +{ #if defined(JSON_NO_INT64) return asInt(); #else - return asInt64(); + return this->asInt64(); #endif } -LargestUInt Value::asLargestUInt() const { +LargestUInt Value::asLargestUInt() const +{ #if defined(JSON_NO_INT64) return asUInt(); #else - return asUInt64(); + return this->asUInt64(); #endif } -double Value::asDouble() const { - switch (type_) { - case intValue: - return static_cast<double>(value_.int_); - case uintValue: +double Value::asDouble() const +{ + switch (this->type_) { + case intValue: + return static_cast<double>(this->value_.int_); + case uintValue: #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - return static_cast<double>(value_.uint_); + return static_cast<double>(this->value_.uint_); #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - return integerToDouble(value_.uint_); + return integerToDouble(value_.uint_); #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - case realValue: - return value_.real_; - case nullValue: - return 0.0; - case booleanValue: - return value_.bool_ ? 1.0 : 0.0; - default: - break; + case realValue: + return this->value_.real_; + case nullValue: + return 0.0; + case booleanValue: + return this->value_.bool_ ? 1.0 : 0.0; + default: + break; } JSON_FAIL_MESSAGE("Value is not convertible to double."); } -float Value::asFloat() const { - switch (type_) { - case intValue: - return static_cast<float>(value_.int_); - case uintValue: +float Value::asFloat() const +{ + switch (this->type_) { + case intValue: + return static_cast<float>(this->value_.int_); + case uintValue: #if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - return static_cast<float>(value_.uint_); + return static_cast<float>(this->value_.uint_); #else // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - // This can fail (silently?) if the value is bigger than MAX_FLOAT. - return static_cast<float>(integerToDouble(value_.uint_)); + // This can fail (silently?) if the value is bigger than MAX_FLOAT. + return static_cast<float>(integerToDouble(value_.uint_)); #endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION) - case realValue: - return static_cast<float>(value_.real_); - case nullValue: - return 0.0; - case booleanValue: - return value_.bool_ ? 1.0f : 0.0f; - default: - break; + case realValue: + return static_cast<float>(this->value_.real_); + case nullValue: + return 0.0; + case booleanValue: + return this->value_.bool_ ? 1.0f : 0.0f; + default: + break; } JSON_FAIL_MESSAGE("Value is not convertible to float."); } -bool Value::asBool() const { - switch (type_) { - case booleanValue: - return value_.bool_; - case nullValue: - return false; - case intValue: - return value_.int_ ? true : false; - case uintValue: - return value_.uint_ ? true : false; - case realValue: - // This is kind of strange. Not recommended. - return (value_.real_ != 0.0) ? true : false; - default: - break; +bool Value::asBool() const +{ + switch (this->type_) { + case booleanValue: + return this->value_.bool_; + case nullValue: + return false; + case intValue: + return this->value_.int_ ? true : false; + case uintValue: + return this->value_.uint_ ? true : false; + case realValue: + // This is kind of strange. Not recommended. + return (this->value_.real_ != 0.0) ? true : false; + default: + break; } JSON_FAIL_MESSAGE("Value is not convertible to bool."); } -bool Value::isConvertibleTo(ValueType other) const { +bool Value::isConvertibleTo(ValueType other) const +{ switch (other) { - case nullValue: - return (isNumeric() && asDouble() == 0.0) || - (type_ == booleanValue && value_.bool_ == false) || - (type_ == stringValue && asString().empty()) || - (type_ == arrayValue && value_.map_->size() == 0) || - (type_ == objectValue && value_.map_->size() == 0) || - type_ == nullValue; - case intValue: - return isInt() || - (type_ == realValue && InRange(value_.real_, minInt, maxInt)) || - type_ == booleanValue || type_ == nullValue; - case uintValue: - return isUInt() || - (type_ == realValue && InRange(value_.real_, 0, maxUInt)) || - type_ == booleanValue || type_ == nullValue; - case realValue: - return isNumeric() || type_ == booleanValue || type_ == nullValue; - case booleanValue: - return isNumeric() || type_ == booleanValue || type_ == nullValue; - case stringValue: - return isNumeric() || type_ == booleanValue || type_ == stringValue || - type_ == nullValue; - case arrayValue: - return type_ == arrayValue || type_ == nullValue; - case objectValue: - return type_ == objectValue || type_ == nullValue; + case nullValue: + return (this->isNumeric() && this->asDouble() == 0.0) || + (this->type_ == booleanValue && this->value_.bool_ == false) || + (this->type_ == stringValue && this->asString().empty()) || + (this->type_ == arrayValue && this->value_.map_->size() == 0) || + (this->type_ == objectValue && this->value_.map_->size() == 0) || + this->type_ == nullValue; + case intValue: + return this->isInt() || + (this->type_ == realValue && + InRange(this->value_.real_, minInt, maxInt)) || + this->type_ == booleanValue || this->type_ == nullValue; + case uintValue: + return this->isUInt() || + (this->type_ == realValue && + InRange(this->value_.real_, 0, maxUInt)) || + this->type_ == booleanValue || this->type_ == nullValue; + case realValue: + return this->isNumeric() || this->type_ == booleanValue || + this->type_ == nullValue; + case booleanValue: + return this->isNumeric() || this->type_ == booleanValue || + this->type_ == nullValue; + case stringValue: + return this->isNumeric() || this->type_ == booleanValue || + this->type_ == stringValue || this->type_ == nullValue; + case arrayValue: + return this->type_ == arrayValue || this->type_ == nullValue; + case objectValue: + return this->type_ == objectValue || this->type_ == nullValue; } JSON_ASSERT_UNREACHABLE; return false; } /// Number of values in array or object -ArrayIndex Value::size() const { - switch (type_) { - case nullValue: - case intValue: - case uintValue: - case realValue: - case booleanValue: - case stringValue: - return 0; - case arrayValue: // size of the array is highest index + 1 - if (!value_.map_->empty()) { - ObjectValues::const_iterator itLast = value_.map_->end(); - --itLast; - return (*itLast).first.index() + 1; - } - return 0; - case objectValue: - return ArrayIndex(value_.map_->size()); +ArrayIndex Value::size() const +{ + switch (this->type_) { + case nullValue: + case intValue: + case uintValue: + case realValue: + case booleanValue: + case stringValue: + return 0; + case arrayValue: // size of the array is highest index + 1 + if (!this->value_.map_->empty()) { + ObjectValues::const_iterator itLast = this->value_.map_->end(); + --itLast; + return (*itLast).first.index() + 1; + } + return 0; + case objectValue: + return ArrayIndex(this->value_.map_->size()); } JSON_ASSERT_UNREACHABLE; return 0; // unreachable; } -bool Value::empty() const { - if (isNull() || isArray() || isObject()) - return size() == 0u; +bool Value::empty() const +{ + if (this->isNull() || this->isArray() || this->isObject()) + return this->size() == 0u; else return false; } -bool Value::operator!() const { return isNull(); } +bool Value::operator!() const +{ + return this->isNull(); +} -void Value::clear() { +void Value::clear() +{ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue || - type_ == objectValue, + type_ == objectValue, "in Json::Value::clear(): requires complex value"); - start_ = 0; - limit_ = 0; - switch (type_) { - case arrayValue: - case objectValue: - value_.map_->clear(); - break; - default: - break; + this->start_ = 0; + this->limit_ = 0; + switch (this->type_) { + case arrayValue: + case objectValue: + this->value_.map_->clear(); + break; + default: + break; } } -void Value::resize(ArrayIndex newSize) { +void Value::resize(ArrayIndex newSize) +{ JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue, "in Json::Value::resize(): requires arrayValue"); - if (type_ == nullValue) + if (this->type_ == nullValue) *this = Value(arrayValue); - ArrayIndex oldSize = size(); + ArrayIndex oldSize = this->size(); if (newSize == 0) - clear(); + this->clear(); else if (newSize > oldSize) (*this)[newSize - 1]; else { for (ArrayIndex index = newSize; index < oldSize; ++index) { - value_.map_->erase(index); + this->value_.map_->erase(index); } JSON_ASSERT(size() == newSize); } } -Value& Value::operator[](ArrayIndex index) { +Value& Value::operator[](ArrayIndex index) +{ JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == arrayValue, - "in Json::Value::operator[](ArrayIndex): requires arrayValue"); - if (type_ == nullValue) + type_ == nullValue || type_ == arrayValue, + "in Json::Value::operator[](ArrayIndex): requires arrayValue"); + if (this->type_ == nullValue) *this = Value(arrayValue); CZString key(index); - ObjectValues::iterator it = value_.map_->lower_bound(key); - if (it != value_.map_->end() && (*it).first == key) + ObjectValues::iterator it = this->value_.map_->lower_bound(key); + if (it != this->value_.map_->end() && (*it).first == key) return (*it).second; ObjectValues::value_type defaultValue(key, nullSingleton()); - it = value_.map_->insert(it, defaultValue); + it = this->value_.map_->insert(it, defaultValue); return (*it).second; } -Value& Value::operator[](int index) { +Value& Value::operator[](int index) +{ JSON_ASSERT_MESSAGE( - index >= 0, - "in Json::Value::operator[](int index): index cannot be negative"); + index >= 0, + "in Json::Value::operator[](int index): index cannot be negative"); return (*this)[ArrayIndex(index)]; } -const Value& Value::operator[](ArrayIndex index) const { +const Value& Value::operator[](ArrayIndex index) const +{ JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == arrayValue, - "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); - if (type_ == nullValue) + type_ == nullValue || type_ == arrayValue, + "in Json::Value::operator[](ArrayIndex)const: requires arrayValue"); + if (this->type_ == nullValue) return nullSingleton(); CZString key(index); - ObjectValues::const_iterator it = value_.map_->find(key); - if (it == value_.map_->end()) + ObjectValues::const_iterator it = this->value_.map_->find(key); + if (it == this->value_.map_->end()) return nullSingleton(); return (*it).second; } -const Value& Value::operator[](int index) const { +const Value& Value::operator[](int index) const +{ JSON_ASSERT_MESSAGE( - index >= 0, - "in Json::Value::operator[](int index) const: index cannot be negative"); + index >= 0, + "in Json::Value::operator[](int index) const: index cannot be negative"); return (*this)[ArrayIndex(index)]; } -void Value::initBasic(ValueType vtype, bool allocated) { - type_ = vtype; - allocated_ = allocated; - comments_ = 0; - start_ = 0; - limit_ = 0; +void Value::initBasic(ValueType vtype, bool allocated) +{ + this->type_ = vtype; + this->allocated_ = allocated; + this->comments_ = 0; + this->start_ = 0; + this->limit_ = 0; } // Access an object value by name, create a null member if it does not exist. // @pre Type of '*this' is object or null. // @param key is null-terminated. -Value& Value::resolveReference(const char* key) { +Value& Value::resolveReference(const char* key) +{ JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::resolveReference(): requires objectValue"); - if (type_ == nullValue) + type_ == nullValue || type_ == objectValue, + "in Json::Value::resolveReference(): requires objectValue"); + if (this->type_ == nullValue) *this = Value(objectValue); - CZString actualKey( - key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE! - ObjectValues::iterator it = value_.map_->lower_bound(actualKey); - if (it != value_.map_->end() && (*it).first == actualKey) + CZString actualKey(key, static_cast<unsigned>(strlen(key)), + CZString::noDuplication); // NOTE! + ObjectValues::iterator it = this->value_.map_->lower_bound(actualKey); + if (it != this->value_.map_->end() && (*it).first == actualKey) return (*it).second; ObjectValues::value_type defaultValue(actualKey, nullSingleton()); - it = value_.map_->insert(it, defaultValue); + it = this->value_.map_->insert(it, defaultValue); Value& value = (*it).second; return value; } @@ -1074,198 +1219,223 @@ Value& Value::resolveReference(const char* key) { Value& Value::resolveReference(char const* key, char const* cend) { JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::resolveReference(key, end): requires objectValue"); - if (type_ == nullValue) + type_ == nullValue || type_ == objectValue, + "in Json::Value::resolveReference(key, end): requires objectValue"); + if (this->type_ == nullValue) *this = Value(objectValue); - CZString actualKey( - key, static_cast<unsigned>(cend-key), CZString::duplicateOnCopy); - ObjectValues::iterator it = value_.map_->lower_bound(actualKey); - if (it != value_.map_->end() && (*it).first == actualKey) + CZString actualKey(key, static_cast<unsigned>(cend - key), + CZString::duplicateOnCopy); + ObjectValues::iterator it = this->value_.map_->lower_bound(actualKey); + if (it != this->value_.map_->end() && (*it).first == actualKey) return (*it).second; ObjectValues::value_type defaultValue(actualKey, nullSingleton()); - it = value_.map_->insert(it, defaultValue); + it = this->value_.map_->insert(it, defaultValue); Value& value = (*it).second; return value; } -Value Value::get(ArrayIndex index, const Value& defaultValue) const { +Value Value::get(ArrayIndex index, const Value& defaultValue) const +{ const Value* value = &((*this)[index]); return value == &nullSingleton() ? defaultValue : *value; } -bool Value::isValidIndex(ArrayIndex index) const { return index < size(); } +bool Value::isValidIndex(ArrayIndex index) const +{ + return index < this->size(); +} Value const* Value::find(char const* key, char const* cend) const { - JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::find(key, end, found): requires objectValue or nullValue"); - if (type_ == nullValue) return NULL; - CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication); - ObjectValues::const_iterator it = value_.map_->find(actualKey); - if (it == value_.map_->end()) return NULL; + JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, + "in Json::Value::find(key, end, found): requires " + "objectValue or nullValue"); + if (this->type_ == nullValue) + return NULL; + CZString actualKey(key, static_cast<unsigned>(cend - key), + CZString::noDuplication); + ObjectValues::const_iterator it = this->value_.map_->find(actualKey); + if (it == this->value_.map_->end()) + return NULL; return &(*it).second; } const Value& Value::operator[](const char* key) const { - Value const* found = find(key, key + strlen(key)); - if (!found) return nullSingleton(); + Value const* found = this->find(key, key + strlen(key)); + if (!found) + return nullSingleton(); return *found; } Value const& Value::operator[](JSONCPP_STRING const& key) const { - Value const* found = find(key.data(), key.data() + key.length()); - if (!found) return nullSingleton(); + Value const* found = this->find(key.data(), key.data() + key.length()); + if (!found) + return nullSingleton(); return *found; } -Value& Value::operator[](const char* key) { - return resolveReference(key, key + strlen(key)); +Value& Value::operator[](const char* key) +{ + return this->resolveReference(key, key + strlen(key)); } -Value& Value::operator[](const JSONCPP_STRING& key) { - return resolveReference(key.data(), key.data() + key.length()); +Value& Value::operator[](const JSONCPP_STRING& key) +{ + return this->resolveReference(key.data(), key.data() + key.length()); } -Value& Value::operator[](const StaticString& key) { - return resolveReference(key.c_str()); +Value& Value::operator[](const StaticString& key) +{ + return this->resolveReference(key.c_str()); } #ifdef JSON_USE_CPPTL -Value& Value::operator[](const CppTL::ConstString& key) { +Value& Value::operator[](const CppTL::ConstString& key) +{ return resolveReference(key.c_str(), key.end_c_str()); } Value const& Value::operator[](CppTL::ConstString const& key) const { Value const* found = find(key.c_str(), key.end_c_str()); - if (!found) return nullSingleton(); + if (!found) + return nullSingleton(); return *found; } #endif -Value& Value::append(const Value& value) { return (*this)[size()] = value; } +Value& Value::append(const Value& value) +{ + return (*this)[this->size()] = value; +} #if JSON_HAS_RVALUE_REFERENCES - Value& Value::append(Value&& value) { return (*this)[size()] = value; } +Value& Value::append(Value&& value) +{ + return (*this)[this->size()] = value; +} #endif -Value Value::get(char const* key, char const* cend, Value const& defaultValue) const +Value Value::get(char const* key, char const* cend, + Value const& defaultValue) const { - Value const* found = find(key, cend); + Value const* found = this->find(key, cend); return !found ? defaultValue : *found; } Value Value::get(char const* key, Value const& defaultValue) const { - return get(key, key + strlen(key), defaultValue); + return this->get(key, key + strlen(key), defaultValue); } Value Value::get(JSONCPP_STRING const& key, Value const& defaultValue) const { - return get(key.data(), key.data() + key.length(), defaultValue); + return this->get(key.data(), key.data() + key.length(), defaultValue); } - bool Value::removeMember(const char* key, const char* cend, Value* removed) { - if (type_ != objectValue) { + if (this->type_ != objectValue) { return false; } - CZString actualKey(key, static_cast<unsigned>(cend-key), CZString::noDuplication); - ObjectValues::iterator it = value_.map_->find(actualKey); - if (it == value_.map_->end()) + CZString actualKey(key, static_cast<unsigned>(cend - key), + CZString::noDuplication); + ObjectValues::iterator it = this->value_.map_->find(actualKey); + if (it == this->value_.map_->end()) return false; *removed = it->second; - value_.map_->erase(it); + this->value_.map_->erase(it); return true; } bool Value::removeMember(const char* key, Value* removed) { - return removeMember(key, key + strlen(key), removed); + return this->removeMember(key, key + strlen(key), removed); } bool Value::removeMember(JSONCPP_STRING const& key, Value* removed) { - return removeMember(key.data(), key.data() + key.length(), removed); + return this->removeMember(key.data(), key.data() + key.length(), removed); } Value Value::removeMember(const char* key) { JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue, "in Json::Value::removeMember(): requires objectValue"); - if (type_ == nullValue) + if (this->type_ == nullValue) return nullSingleton(); - Value removed; // null - removeMember(key, key + strlen(key), &removed); + Value removed; // null + this->removeMember(key, key + strlen(key), &removed); return removed; // still null if removeMember() did nothing } Value Value::removeMember(const JSONCPP_STRING& key) { - return removeMember(key.c_str()); + return this->removeMember(key.c_str()); } -bool Value::removeIndex(ArrayIndex index, Value* removed) { - if (type_ != arrayValue) { +bool Value::removeIndex(ArrayIndex index, Value* removed) +{ + if (this->type_ != arrayValue) { return false; } CZString key(index); - ObjectValues::iterator it = value_.map_->find(key); - if (it == value_.map_->end()) { + ObjectValues::iterator it = this->value_.map_->find(key); + if (it == this->value_.map_->end()) { return false; } *removed = it->second; - ArrayIndex oldSize = size(); + ArrayIndex oldSize = this->size(); // shift left all items left, into the place of the "removed" - for (ArrayIndex i = index; i < (oldSize - 1); ++i){ + for (ArrayIndex i = index; i < (oldSize - 1); ++i) { CZString keey(i); - (*value_.map_)[keey] = (*this)[i + 1]; + (*this->value_.map_)[keey] = (*this)[i + 1]; } // erase the last one ("leftover") CZString keyLast(oldSize - 1); - ObjectValues::iterator itLast = value_.map_->find(keyLast); - value_.map_->erase(itLast); + ObjectValues::iterator itLast = this->value_.map_->find(keyLast); + this->value_.map_->erase(itLast); return true; } #ifdef JSON_USE_CPPTL Value Value::get(const CppTL::ConstString& key, - const Value& defaultValue) const { + const Value& defaultValue) const +{ return get(key.c_str(), key.end_c_str(), defaultValue); } #endif bool Value::isMember(char const* key, char const* cend) const { - Value const* value = find(key, cend); + Value const* value = this->find(key, cend); return NULL != value; } bool Value::isMember(char const* key) const { - return isMember(key, key + strlen(key)); + return this->isMember(key, key + strlen(key)); } bool Value::isMember(JSONCPP_STRING const& key) const { - return isMember(key.data(), key.data() + key.length()); + return this->isMember(key.data(), key.data() + key.length()); } #ifdef JSON_USE_CPPTL -bool Value::isMember(const CppTL::ConstString& key) const { +bool Value::isMember(const CppTL::ConstString& key) const +{ return isMember(key.c_str(), key.end_c_str()); } #endif -Value::Members Value::getMemberNames() const { +Value::Members Value::getMemberNames() const +{ JSON_ASSERT_MESSAGE( - type_ == nullValue || type_ == objectValue, - "in Json::Value::getMemberNames(), value must be objectValue"); - if (type_ == nullValue) + type_ == nullValue || type_ == objectValue, + "in Json::Value::getMemberNames(), value must be objectValue"); + if (this->type_ == nullValue) return Value::Members(); Members members; - members.reserve(value_.map_->size()); - ObjectValues::const_iterator it = value_.map_->begin(); - ObjectValues::const_iterator itEnd = value_.map_->end(); + members.reserve(this->value_.map_->size()); + ObjectValues::const_iterator it = this->value_.map_->begin(); + ObjectValues::const_iterator itEnd = this->value_.map_->end(); for (; it != itEnd; ++it) { - members.push_back(JSONCPP_STRING((*it).first.data(), - (*it).first.length())); + members.push_back( + JSONCPP_STRING((*it).first.data(), (*it).first.length())); } return members; } @@ -1277,8 +1447,8 @@ Value::Members Value::getMemberNames() const { // if ( type_ == objectValue ) // { // return CppTL::Enum::any( CppTL::Enum::transform( -// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ), -// MemberNamesTransform() ) ); +// CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() +// ), MemberNamesTransform() ) ); // } // return EnumMemberNames(); //} @@ -1295,99 +1465,114 @@ Value::Members Value::getMemberNames() const { // //# endif -static bool IsIntegral(double d) { +static bool IsIntegral(double d) +{ double integral_part; return modf(d, &integral_part) == 0.0; } -bool Value::isNull() const { return type_ == nullValue; } +bool Value::isNull() const +{ + return this->type_ == nullValue; +} -bool Value::isBool() const { return type_ == booleanValue; } +bool Value::isBool() const +{ + return this->type_ == booleanValue; +} -bool Value::isInt() const { - switch (type_) { - case intValue: +bool Value::isInt() const +{ + switch (this->type_) { + case intValue: #if defined(JSON_HAS_INT64) - return value_.int_ >= minInt && value_.int_ <= maxInt; + return this->value_.int_ >= minInt && this->value_.int_ <= maxInt; #else - return true; + return true; #endif - case uintValue: - return value_.uint_ <= UInt(maxInt); - case realValue: - return value_.real_ >= minInt && value_.real_ <= maxInt && - IsIntegral(value_.real_); - default: - break; + case uintValue: + return this->value_.uint_ <= UInt(maxInt); + case realValue: + return this->value_.real_ >= minInt && this->value_.real_ <= maxInt && + IsIntegral(this->value_.real_); + default: + break; } return false; } -bool Value::isUInt() const { - switch (type_) { - case intValue: +bool Value::isUInt() const +{ + switch (this->type_) { + case intValue: #if defined(JSON_HAS_INT64) - return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt); + return this->value_.int_ >= 0 && + LargestUInt(this->value_.int_) <= LargestUInt(maxUInt); #else - return value_.int_ >= 0; + return value_.int_ >= 0; #endif - case uintValue: + case uintValue: #if defined(JSON_HAS_INT64) - return value_.uint_ <= maxUInt; + return this->value_.uint_ <= maxUInt; #else - return true; + return true; #endif - case realValue: - return value_.real_ >= 0 && value_.real_ <= maxUInt && - IsIntegral(value_.real_); - default: - break; + case realValue: + return this->value_.real_ >= 0 && this->value_.real_ <= maxUInt && + IsIntegral(this->value_.real_); + default: + break; } return false; } -bool Value::isInt64() const { +bool Value::isInt64() const +{ #if defined(JSON_HAS_INT64) - switch (type_) { - case intValue: - return true; - case uintValue: - return value_.uint_ <= UInt64(maxInt64); - case realValue: - // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a - // double, so double(maxInt64) will be rounded up to 2^63. Therefore we - // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && - value_.real_ < double(maxInt64) && IsIntegral(value_.real_); - default: - break; + switch (this->type_) { + case intValue: + return true; + case uintValue: + return this->value_.uint_ <= UInt64(maxInt64); + case realValue: + // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a + // double, so double(maxInt64) will be rounded up to 2^63. Therefore we + // require the value to be strictly less than the limit. + return this->value_.real_ >= double(minInt64) && + this->value_.real_ < double(maxInt64) && + IsIntegral(this->value_.real_); + default: + break; } #endif // JSON_HAS_INT64 return false; } -bool Value::isUInt64() const { +bool Value::isUInt64() const +{ #if defined(JSON_HAS_INT64) - switch (type_) { - case intValue: - return value_.int_ >= 0; - case uintValue: - return true; - case realValue: - // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a - // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we - // require the value to be strictly less than the limit. - return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble && - IsIntegral(value_.real_); - default: - break; + switch (this->type_) { + case intValue: + return this->value_.int_ >= 0; + case uintValue: + return true; + case realValue: + // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a + // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we + // require the value to be strictly less than the limit. + return this->value_.real_ >= 0 && + this->value_.real_ < maxUInt64AsDouble && + IsIntegral(this->value_.real_); + default: + break; } #endif // JSON_HAS_INT64 return false; } -bool Value::isIntegral() const { - switch (type_) { +bool Value::isIntegral() const +{ + switch (this->type_) { case intValue: case uintValue: return true; @@ -1396,9 +1581,12 @@ bool Value::isIntegral() const { // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we // require the value to be strictly less than the limit. - return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_); + return this->value_.real_ >= double(minInt64) && + this->value_.real_ < maxUInt64AsDouble && + IsIntegral(this->value_.real_); #else - return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_); + return value_.real_ >= minInt && value_.real_ <= maxUInt && + IsIntegral(value_.real_); #endif // JSON_HAS_INT64 default: break; @@ -1406,53 +1594,89 @@ bool Value::isIntegral() const { return false; } -bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; } +bool Value::isDouble() const +{ + return this->type_ == intValue || this->type_ == uintValue || + this->type_ == realValue; +} -bool Value::isNumeric() const { return isDouble(); } +bool Value::isNumeric() const +{ + return this->isDouble(); +} -bool Value::isString() const { return type_ == stringValue; } +bool Value::isString() const +{ + return this->type_ == stringValue; +} -bool Value::isArray() const { return type_ == arrayValue; } +bool Value::isArray() const +{ + return this->type_ == arrayValue; +} -bool Value::isObject() const { return type_ == objectValue; } +bool Value::isObject() const +{ + return this->type_ == objectValue; +} -void Value::setComment(const char* comment, size_t len, CommentPlacement placement) { - if (!comments_) - comments_ = new CommentInfo[numberOfCommentPlacement]; - if ((len > 0) && (comment[len-1] == '\n')) { +void Value::setComment(const char* comment, size_t len, + CommentPlacement placement) +{ + if (!this->comments_) + this->comments_ = new CommentInfo[numberOfCommentPlacement]; + if ((len > 0) && (comment[len - 1] == '\n')) { // Always discard trailing newline, to aid indentation. len -= 1; } - comments_[placement].setComment(comment, len); + this->comments_[placement].setComment(comment, len); } -void Value::setComment(const char* comment, CommentPlacement placement) { - setComment(comment, strlen(comment), placement); +void Value::setComment(const char* comment, CommentPlacement placement) +{ + this->setComment(comment, strlen(comment), placement); } -void Value::setComment(const JSONCPP_STRING& comment, CommentPlacement placement) { - setComment(comment.c_str(), comment.length(), placement); +void Value::setComment(const JSONCPP_STRING& comment, + CommentPlacement placement) +{ + this->setComment(comment.c_str(), comment.length(), placement); } -bool Value::hasComment(CommentPlacement placement) const { - return comments_ != 0 && comments_[placement].comment_ != 0; +bool Value::hasComment(CommentPlacement placement) const +{ + return this->comments_ != 0 && this->comments_[placement].comment_ != 0; } -JSONCPP_STRING Value::getComment(CommentPlacement placement) const { - if (hasComment(placement)) - return comments_[placement].comment_; +JSONCPP_STRING Value::getComment(CommentPlacement placement) const +{ + if (this->hasComment(placement)) + return this->comments_[placement].comment_; return ""; } -void Value::setOffsetStart(ptrdiff_t start) { start_ = start; } +void Value::setOffsetStart(ptrdiff_t start) +{ + this->start_ = start; +} -void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; } +void Value::setOffsetLimit(ptrdiff_t limit) +{ + this->limit_ = limit; +} -ptrdiff_t Value::getOffsetStart() const { return start_; } +ptrdiff_t Value::getOffsetStart() const +{ + return this->start_; +} -ptrdiff_t Value::getOffsetLimit() const { return limit_; } +ptrdiff_t Value::getOffsetLimit() const +{ + return this->limit_; +} -JSONCPP_STRING Value::toStyledString() const { +JSONCPP_STRING Value::toStyledString() const +{ StreamWriterBuilder builder; JSONCPP_STRING out = this->hasComment(commentBefore) ? "\n" : ""; @@ -1462,54 +1686,58 @@ JSONCPP_STRING Value::toStyledString() const { return out; } -Value::const_iterator Value::begin() const { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return const_iterator(value_.map_->begin()); - break; - default: - break; +Value::const_iterator Value::begin() const +{ + switch (this->type_) { + case arrayValue: + case objectValue: + if (this->value_.map_) + return const_iterator(this->value_.map_->begin()); + break; + default: + break; } return const_iterator(); } -Value::const_iterator Value::end() const { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return const_iterator(value_.map_->end()); - break; - default: - break; +Value::const_iterator Value::end() const +{ + switch (this->type_) { + case arrayValue: + case objectValue: + if (this->value_.map_) + return const_iterator(this->value_.map_->end()); + break; + default: + break; } return const_iterator(); } -Value::iterator Value::begin() { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return iterator(value_.map_->begin()); - break; - default: - break; +Value::iterator Value::begin() +{ + switch (this->type_) { + case arrayValue: + case objectValue: + if (this->value_.map_) + return iterator(this->value_.map_->begin()); + break; + default: + break; } return iterator(); } -Value::iterator Value::end() { - switch (type_) { - case arrayValue: - case objectValue: - if (value_.map_) - return iterator(value_.map_->end()); - break; - default: - break; +Value::iterator Value::end() +{ + switch (this->type_) { + case arrayValue: + case objectValue: + if (this->value_.map_) + return iterator(this->value_.map_->end()); + break; + default: + break; } return iterator(); } @@ -1517,26 +1745,41 @@ Value::iterator Value::end() { // class PathArgument // ////////////////////////////////////////////////////////////////// -PathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {} +PathArgument::PathArgument() + : key_() + , index_() + , kind_(kindNone) +{ +} PathArgument::PathArgument(ArrayIndex index) - : key_(), index_(index), kind_(kindIndex) {} + : key_() + , index_(index) + , kind_(kindIndex) +{ +} PathArgument::PathArgument(const char* key) - : key_(key), index_(), kind_(kindKey) {} + : key_(key) + , index_() + , kind_(kindKey) +{ +} PathArgument::PathArgument(const JSONCPP_STRING& key) - : key_(key.c_str()), index_(), kind_(kindKey) {} + : key_(key.c_str()) + , index_() + , kind_(kindKey) +{ +} // class Path // ////////////////////////////////////////////////////////////////// -Path::Path(const JSONCPP_STRING& path, - const PathArgument& a1, - const PathArgument& a2, - const PathArgument& a3, - const PathArgument& a4, - const PathArgument& a5) { +Path::Path(const JSONCPP_STRING& path, const PathArgument& a1, + const PathArgument& a2, const PathArgument& a3, + const PathArgument& a4, const PathArgument& a5) +{ InArgs in; in.reserve(5); in.push_back(&a1); @@ -1544,10 +1787,11 @@ Path::Path(const JSONCPP_STRING& path, in.push_back(&a3); in.push_back(&a4); in.push_back(&a5); - makePath(path, in); + this->makePath(path, in); } -void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) { +void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) +{ const char* current = path.c_str(); const char* end = current + path.length(); InArgs::const_iterator itInArg = in.begin(); @@ -1555,17 +1799,17 @@ void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) { if (*current == '[') { ++current; if (*current == '%') - addPathInArg(path, in, itInArg, PathArgument::kindIndex); + this->addPathInArg(path, in, itInArg, PathArgument::kindIndex); else { ArrayIndex index = 0; for (; current != end && *current >= '0' && *current <= '9'; ++current) index = index * 10 + ArrayIndex(*current - '0'); - args_.push_back(index); + this->args_.push_back(index); } if (current == end || *++current != ']') - invalidPath(path, int(current - path.c_str())); + this->invalidPath(path, int(current - path.c_str())); } else if (*current == '%') { - addPathInArg(path, in, itInArg, PathArgument::kindKey); + this->addPathInArg(path, in, itInArg, PathArgument::kindKey); ++current; } else if (*current == '.' || *current == ']') { ++current; @@ -1573,31 +1817,34 @@ void Path::makePath(const JSONCPP_STRING& path, const InArgs& in) { const char* beginName = current; while (current != end && !strchr("[.", *current)) ++current; - args_.push_back(JSONCPP_STRING(beginName, current)); + this->args_.push_back(JSONCPP_STRING(beginName, current)); } } } -void Path::addPathInArg(const JSONCPP_STRING& /*path*/, - const InArgs& in, +void Path::addPathInArg(const JSONCPP_STRING& /*path*/, const InArgs& in, InArgs::const_iterator& itInArg, - PathArgument::Kind kind) { + PathArgument::Kind kind) +{ if (itInArg == in.end()) { // Error: missing argument %d } else if ((*itInArg)->kind_ != kind) { // Error: bad argument type } else { - args_.push_back(**itInArg++); + this->args_.push_back(**itInArg++); } } -void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) { +void Path::invalidPath(const JSONCPP_STRING& /*path*/, int /*location*/) +{ // Error: invalid path. } -const Value& Path::resolve(const Value& root) const { +const Value& Path::resolve(const Value& root) const +{ const Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + for (Args::const_iterator it = this->args_.begin(); it != this->args_.end(); + ++it) { const PathArgument& arg = *it; if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) { @@ -1621,9 +1868,11 @@ const Value& Path::resolve(const Value& root) const { return *node; } -Value Path::resolve(const Value& root, const Value& defaultValue) const { +Value Path::resolve(const Value& root, const Value& defaultValue) const +{ const Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + for (Args::const_iterator it = this->args_.begin(); it != this->args_.end(); + ++it) { const PathArgument& arg = *it; if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray() || !node->isValidIndex(arg.index_)) @@ -1640,9 +1889,11 @@ Value Path::resolve(const Value& root, const Value& defaultValue) const { return *node; } -Value& Path::make(Value& root) const { +Value& Path::make(Value& root) const +{ Value* node = &root; - for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it) { + for (Args::const_iterator it = this->args_.begin(); it != this->args_.end(); + ++it) { const PathArgument& arg = *it; if (arg.kind_ == PathArgument::kindIndex) { if (!node->isArray()) { diff --git a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp index fc86505..803cfab 100644 --- a/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp +++ b/Utilities/cmjsoncpp/src/lib_json/json_writer.cpp @@ -1,111 +1,115 @@ // Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors // Distributed under MIT license, or public domain if desired and // recognized in your jurisdiction. -// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE +// See file LICENSE for detail or copy at +// http://jsoncpp.sourceforge.net/LICENSE #if !defined(JSON_IS_AMALGAMATION) -#include <json/writer.h> -#include "json_tool.h" +# include <json/writer.h> + +# include "json_tool.h" #endif // if !defined(JSON_IS_AMALGAMATION) +#include <cassert> +#include <cstdio> +#include <cstring> #include <iomanip> #include <memory> +#include <set> #include <sstream> #include <utility> -#include <set> -#include <cassert> -#include <cstring> -#include <cstdio> -#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0 -#include <float.h> -#define isfinite _finite -#elif defined(__sun) && defined(__SVR4) //Solaris -#if !defined(isfinite) -#include <ieeefp.h> -#define isfinite finite -#endif +#if defined(_MSC_VER) && _MSC_VER >= 1200 && \ + _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0 +# include <float.h> +# define isfinite _finite +#elif defined(__sun) && defined(__SVR4) // Solaris +# if !defined(isfinite) +# include <ieeefp.h> +# define isfinite finite +# endif #elif defined(_AIX) -#if !defined(isfinite) -#include <math.h> -#define isfinite finite -#endif +# if !defined(isfinite) +# include <math.h> +# define isfinite finite +# endif #elif defined(__hpux) -#if !defined(isfinite) && !defined(__GNUC__) -#if defined(__ia64) && !defined(finite) -#define isfinite(x) ((sizeof(x) == sizeof(float) ? \ - _Isfinitef(x) : _IsFinite(x))) -#else -#include <math.h> -#define isfinite finite -#endif -#endif +# if !defined(isfinite) && !defined(__GNUC__) +# if defined(__ia64) && !defined(finite) +# define isfinite(x) \ + ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x))) +# else +# include <math.h> +# define isfinite finite +# endif +# endif #else -#include <cmath> -#if !(defined(__QNXNTO__)) // QNX already defines isfinite -#define isfinite std::isfinite -#endif +# include <cmath> +# if !(defined(__QNXNTO__)) // QNX already defines isfinite +# define isfinite std::isfinite +# endif #endif #if defined(_MSC_VER) -#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above -#define snprintf sprintf_s -#elif _MSC_VER >= 1900 // VC++ 14.0 and above -#define snprintf std::snprintf -#else -#define snprintf _snprintf -#endif +# if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && \ + _MSC_VER >= 1500 // VC++ 9.0 and above +# define snprintf sprintf_s +# elif _MSC_VER >= 1900 // VC++ 14.0 and above +# define snprintf std::snprintf +# else +# define snprintf _snprintf +# endif #elif defined(__ANDROID__) || defined(__QNXNTO__) -#define snprintf snprintf +# define snprintf snprintf #elif __cplusplus >= 201103L -#if !defined(__MINGW32__) && !defined(__CYGWIN__) -#define snprintf std::snprintf -#endif +# if !defined(__MINGW32__) && !defined(__CYGWIN__) +# define snprintf std::snprintf +# endif #endif -#if defined(__BORLANDC__) -#include <float.h> -#define isfinite _finite -#define snprintf _snprintf +#if defined(__BORLANDC__) +# include <float.h> +# define isfinite _finite +# define snprintf _snprintf #endif // Solaris #if defined(__sun) -# include <ieeefp.h> -# if !defined(isfinite) -# define isfinite finite -# endif +# include <ieeefp.h> +# if !defined(isfinite) +# define isfinite finite +# endif #endif // AIX #if defined(_AIX) -# if !defined(isfinite) -# define isfinite finite -# endif +# if !defined(isfinite) +# define isfinite finite +# endif #endif // HP-UX #if defined(__hpux) -# if !defined(isfinite) -# if defined(__ia64) && !defined(finite) && !defined(__GNUC__) -# define isfinite(x) ((sizeof(x) == sizeof(float) ? \ - _Isfinitef(x) : _Isfinite(x))) -# else -# include <math.h> -# define isfinite finite +# if !defined(isfinite) +# if defined(__ia64) && !defined(finite) && !defined(__GNUC__) +# define isfinite(x) \ + ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _Isfinite(x))) +# else +# include <math.h> +# define isfinite finite +# endif # endif -# endif #endif // Ancient glibc #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 2 -# if !defined(isfinite) -# define isfinite __finite -# endif +# if !defined(isfinite) +# define isfinite __finite +# endif #endif #if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0 // Disable warning about strdup being deprecated. -#pragma warning(disable : 4996) +# pragma warning(disable : 4996) #endif namespace Json { @@ -113,10 +117,11 @@ namespace Json { #if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520) typedef std::unique_ptr<StreamWriter> StreamWriterPtr; #else -typedef std::auto_ptr<StreamWriter> StreamWriterPtr; +typedef std::auto_ptr<StreamWriter> StreamWriterPtr; #endif -static bool containsControlCharacter(const char* str) { +static bool containsControlCharacter(const char* str) +{ while (*str) { if (isControlCharacter(*(str++))) return true; @@ -124,17 +129,19 @@ static bool containsControlCharacter(const char* str) { return false; } -static bool containsControlCharacter0(const char* str, unsigned len) { +static bool containsControlCharacter0(const char* str, unsigned len) +{ char const* end = str + len; while (end != str) { - if (isControlCharacter(*str) || 0==*str) + if (isControlCharacter(*str) || 0 == *str) return true; ++str; } return false; } -JSONCPP_STRING valueToString(LargestInt value) { +JSONCPP_STRING valueToString(LargestInt value) +{ UIntToStringBuffer buffer; char* current = buffer + sizeof(buffer); if (value == Value::minLargestInt) { @@ -150,7 +157,8 @@ JSONCPP_STRING valueToString(LargestInt value) { return current; } -JSONCPP_STRING valueToString(LargestUInt value) { +JSONCPP_STRING valueToString(LargestUInt value) +{ UIntToStringBuffer buffer; char* current = buffer + sizeof(buffer); uintToString(value, current); @@ -160,18 +168,22 @@ JSONCPP_STRING valueToString(LargestUInt value) { #if defined(JSON_HAS_INT64) -JSONCPP_STRING valueToString(Int value) { +JSONCPP_STRING valueToString(Int value) +{ return valueToString(LargestInt(value)); } -JSONCPP_STRING valueToString(UInt value) { +JSONCPP_STRING valueToString(UInt value) +{ return valueToString(LargestUInt(value)); } #endif // # if defined(JSON_HAS_INT64) namespace { -JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision) { +JSONCPP_STRING valueToString(double value, bool useSpecialFloats, + unsigned int precision) +{ // Allocate a buffer that is more than large enough to store the 16 digits of // precision requested below. char buffer[36]; @@ -187,7 +199,8 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p len = snprintf(buffer, sizeof(buffer), formatString, value); fixNumericLocale(buffer, buffer + len); - // try to ensure we preserve the fact that this was given to us as a double on input + // try to ensure we preserve the fact that this was given to us as a double + // on input if (!strchr(buffer, '.') && !strchr(buffer, 'e')) { strcat(buffer, ".0"); } @@ -195,11 +208,14 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p } else { // IEEE standard states that NaN values will not compare to themselves if (value != value) { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null"); + len = + snprintf(buffer, sizeof(buffer), useSpecialFloats ? "NaN" : "null"); } else if (value < 0) { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "-Infinity" : "-1e+9999"); + len = snprintf(buffer, sizeof(buffer), + useSpecialFloats ? "-Infinity" : "-1e+9999"); } else { - len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999"); + len = snprintf(buffer, sizeof(buffer), + useSpecialFloats ? "Infinity" : "1e+9999"); } } assert(len >= 0); @@ -207,11 +223,18 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p } } -JSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); } +JSONCPP_STRING valueToString(double value) +{ + return valueToString(value, false, 17); +} -JSONCPP_STRING valueToString(bool value) { return value ? "true" : "false"; } +JSONCPP_STRING valueToString(bool value) +{ + return value ? "true" : "false"; +} -JSONCPP_STRING valueToQuotedString(const char* value) { +JSONCPP_STRING valueToQuotedString(const char* value) +{ if (value == NULL) return ""; // Not sure how to handle unicode... @@ -222,51 +245,50 @@ JSONCPP_STRING valueToQuotedString(const char* value) { // Appending to JSONCPP_STRING is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) JSONCPP_STRING::size_type maxsize = - strlen(value) * 2 + 3; // allescaped+quotes+NULL + strlen(value) * 2 + 3; // allescaped+quotes+NULL JSONCPP_STRING result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; for (const char* c = value; *c != 0; ++c) { switch (*c) { - case '\"': - result += "\\\""; - break; - case '\\': - result += "\\\\"; - break; - case '\b': - result += "\\b"; - break; - case '\f': - result += "\\f"; - break; - case '\n': - result += "\\n"; - break; - case '\r': - result += "\\r"; - break; - case '\t': - result += "\\t"; - break; - // case '/': - // Even though \/ is considered a legal escape in JSON, a bare - // slash is also legal, so I see no reason to escape it. - // (I hope I am not misunderstanding something. - // blep notes: actually escaping \/ may be useful in javascript to avoid </ - // sequence. - // Should add a flag to allow this compatibility mode and prevent this - // sequence from occurring. - default: - if (isControlCharacter(*c)) { - JSONCPP_OSTRINGSTREAM oss; - oss << "\\u" << std::hex << std::uppercase << std::setfill('0') - << std::setw(4) << static_cast<int>(*c); - result += oss.str(); - } else { - result += *c; - } - break; + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\f': + result += "\\f"; + break; + case '\n': + result += "\\n"; + break; + case '\r': + result += "\\r"; + break; + case '\t': + result += "\\t"; + break; + // case '/': + // Even though \/ is considered a legal escape in JSON, a bare + // slash is also legal, so I see no reason to escape it. + // (I hope I am not misunderstanding something. + // blep notes: actually escaping \/ may be useful in javascript to avoid + // </ sequence. Should add a flag to allow this compatibility mode and + // prevent this sequence from occurring. + default: + if (isControlCharacter(*c)) { + JSONCPP_OSTRINGSTREAM oss; + oss << "\\u" << std::hex << std::uppercase << std::setfill('0') + << std::setw(4) << static_cast<int>(*c); + result += oss.str(); + } else { + result += *c; + } + break; } } result += "\""; @@ -274,7 +296,8 @@ JSONCPP_STRING valueToQuotedString(const char* value) { } // https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp -static char const* strnpbrk(char const* s, char const* accept, size_t n) { +static char const* strnpbrk(char const* s, char const* accept, size_t n) +{ assert((s || !n) && accept); char const* const end = s + n; @@ -288,7 +311,8 @@ static char const* strnpbrk(char const* s, char const* accept, size_t n) { } return NULL; } -static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { +static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) +{ if (value == NULL) return ""; // Not sure how to handle unicode... @@ -298,53 +322,51 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { // We have to walk value and escape any special characters. // Appending to JSONCPP_STRING is not efficient, but this should be rare. // (Note: forward slashes are *not* rare, but I am not escaping them.) - JSONCPP_STRING::size_type maxsize = - length * 2 + 3; // allescaped+quotes+NULL + JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL JSONCPP_STRING result; result.reserve(maxsize); // to avoid lots of mallocs result += "\""; char const* end = value + length; for (const char* c = value; c != end; ++c) { switch (*c) { - case '\"': - result += "\\\""; - break; - case '\\': - result += "\\\\"; - break; - case '\b': - result += "\\b"; - break; - case '\f': - result += "\\f"; - break; - case '\n': - result += "\\n"; - break; - case '\r': - result += "\\r"; - break; - case '\t': - result += "\\t"; - break; - // case '/': - // Even though \/ is considered a legal escape in JSON, a bare - // slash is also legal, so I see no reason to escape it. - // (I hope I am not misunderstanding something.) - // blep notes: actually escaping \/ may be useful in javascript to avoid </ - // sequence. - // Should add a flag to allow this compatibility mode and prevent this - // sequence from occurring. - default: - if ((isControlCharacter(*c)) || (*c == 0)) { - JSONCPP_OSTRINGSTREAM oss; - oss << "\\u" << std::hex << std::uppercase << std::setfill('0') - << std::setw(4) << static_cast<int>(*c); - result += oss.str(); - } else { - result += *c; - } - break; + case '\"': + result += "\\\""; + break; + case '\\': + result += "\\\\"; + break; + case '\b': + result += "\\b"; + break; + case '\f': + result += "\\f"; + break; + case '\n': + result += "\\n"; + break; + case '\r': + result += "\\r"; + break; + case '\t': + result += "\\t"; + break; + // case '/': + // Even though \/ is considered a legal escape in JSON, a bare + // slash is also legal, so I see no reason to escape it. + // (I hope I am not misunderstanding something.) + // blep notes: actually escaping \/ may be useful in javascript to avoid + // </ sequence. Should add a flag to allow this compatibility mode and + // prevent this sequence from occurring. + default: + if ((isControlCharacter(*c)) || (*c == 0)) { + JSONCPP_OSTRINGSTREAM oss; + oss << "\\u" << std::hex << std::uppercase << std::setfill('0') + << std::setw(4) << static_cast<int>(*c); + result += oss.str(); + } else { + result += *c; + } + break; } } result += "\""; @@ -353,80 +375,98 @@ static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) { // Class Writer // ////////////////////////////////////////////////////////////////// -Writer::~Writer() {} +Writer::~Writer() +{ +} // Class FastWriter // ////////////////////////////////////////////////////////////////// FastWriter::FastWriter() - : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false), - omitEndingLineFeed_(false) {} + : yamlCompatiblityEnabled_(false) + , dropNullPlaceholders_(false) + , omitEndingLineFeed_(false) +{ +} -void FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; } +void FastWriter::enableYAMLCompatibility() +{ + this->yamlCompatiblityEnabled_ = true; +} -void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; } +void FastWriter::dropNullPlaceholders() +{ + this->dropNullPlaceholders_ = true; +} -void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; } +void FastWriter::omitEndingLineFeed() +{ + this->omitEndingLineFeed_ = true; +} -JSONCPP_STRING FastWriter::write(const Value& root) { - document_.clear(); - writeValue(root); - if (!omitEndingLineFeed_) - document_ += "\n"; - return document_; +JSONCPP_STRING FastWriter::write(const Value& root) +{ + this->document_.clear(); + this->writeValue(root); + if (!this->omitEndingLineFeed_) + this->document_ += "\n"; + return this->document_; } -void FastWriter::writeValue(const Value& value) { +void FastWriter::writeValue(const Value& value) +{ switch (value.type()) { - case nullValue: - if (!dropNullPlaceholders_) - document_ += "null"; - break; - case intValue: - document_ += valueToString(value.asLargestInt()); - break; - case uintValue: - document_ += valueToString(value.asLargestUInt()); - break; - case realValue: - document_ += valueToString(value.asDouble()); - break; - case stringValue: - { - // Is NULL possible for value.string_? No. - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) document_ += valueToQuotedStringN(str, static_cast<unsigned>(end-str)); - break; - } - case booleanValue: - document_ += valueToString(value.asBool()); - break; - case arrayValue: { - document_ += '['; - ArrayIndex size = value.size(); - for (ArrayIndex index = 0; index < size; ++index) { - if (index > 0) - document_ += ','; - writeValue(value[index]); - } - document_ += ']'; - } break; - case objectValue: { - Value::Members members(value.getMemberNames()); - document_ += '{'; - for (Value::Members::iterator it = members.begin(); it != members.end(); - ++it) { - const JSONCPP_STRING& name = *it; - if (it != members.begin()) - document_ += ','; - document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())); - document_ += yamlCompatiblityEnabled_ ? ": " : ":"; - writeValue(value[name]); + case nullValue: + if (!this->dropNullPlaceholders_) + this->document_ += "null"; + break; + case intValue: + this->document_ += valueToString(value.asLargestInt()); + break; + case uintValue: + this->document_ += valueToString(value.asLargestUInt()); + break; + case realValue: + this->document_ += valueToString(value.asDouble()); + break; + case stringValue: { + // Is NULL possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + this->document_ += + valueToQuotedStringN(str, static_cast<unsigned>(end - str)); + break; } - document_ += '}'; - } break; + case booleanValue: + this->document_ += valueToString(value.asBool()); + break; + case arrayValue: { + this->document_ += '['; + ArrayIndex size = value.size(); + for (ArrayIndex index = 0; index < size; ++index) { + if (index > 0) + this->document_ += ','; + this->writeValue(value[index]); + } + this->document_ += ']'; + } break; + case objectValue: { + Value::Members members(value.getMemberNames()); + this->document_ += '{'; + for (Value::Members::iterator it = members.begin(); it != members.end(); + ++it) { + const JSONCPP_STRING& name = *it; + if (it != members.begin()) + this->document_ += ','; + this->document_ += valueToQuotedStringN( + name.data(), static_cast<unsigned>(name.length())); + this->document_ += this->yamlCompatiblityEnabled_ ? ": " : ":"; + this->writeValue(value[name]); + } + this->document_ += '}'; + } break; } } @@ -434,454 +474,498 @@ void FastWriter::writeValue(const Value& value) { // ////////////////////////////////////////////////////////////////// StyledWriter::StyledWriter() - : rightMargin_(74), indentSize_(3), addChildValues_() {} + : rightMargin_(74) + , indentSize_(3) + , addChildValues_() +{ +} -JSONCPP_STRING StyledWriter::write(const Value& root) { - document_.clear(); - addChildValues_ = false; - indentString_.clear(); - writeCommentBeforeValue(root); - writeValue(root); - writeCommentAfterValueOnSameLine(root); - document_ += "\n"; - return document_; +JSONCPP_STRING StyledWriter::write(const Value& root) +{ + this->document_.clear(); + this->addChildValues_ = false; + this->indentString_.clear(); + this->writeCommentBeforeValue(root); + this->writeValue(root); + this->writeCommentAfterValueOnSameLine(root); + this->document_ += "\n"; + return this->document_; } -void StyledWriter::writeValue(const Value& value) { +void StyledWriter::writeValue(const Value& value) +{ switch (value.type()) { - case nullValue: - pushValue("null"); - break; - case intValue: - pushValue(valueToString(value.asLargestInt())); - break; - case uintValue: - pushValue(valueToString(value.asLargestUInt())); - break; - case realValue: - pushValue(valueToString(value.asDouble())); - break; - case stringValue: - { - // Is NULL possible for value.string_? No. - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); - else pushValue(""); - break; - } - case booleanValue: - pushValue(valueToString(value.asBool())); - break; - case arrayValue: - writeArrayValue(value); - break; - case objectValue: { - Value::Members members(value.getMemberNames()); - if (members.empty()) - pushValue("{}"); - else { - writeWithIndent("{"); - indent(); - Value::Members::iterator it = members.begin(); - for (;;) { - const JSONCPP_STRING& name = *it; - const Value& childValue = value[name]; - writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); - document_ += " : "; - writeValue(childValue); - if (++it == members.end()) { - writeCommentAfterValueOnSameLine(childValue); - break; + case nullValue: + this->pushValue("null"); + break; + case intValue: + this->pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + this->pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + this->pushValue(valueToString(value.asDouble())); + break; + case stringValue: { + // Is NULL possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + this->pushValue( + valueToQuotedStringN(str, static_cast<unsigned>(end - str))); + else + this->pushValue(""); + break; + } + case booleanValue: + this->pushValue(valueToString(value.asBool())); + break; + case arrayValue: + this->writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + this->pushValue("{}"); + else { + this->writeWithIndent("{"); + this->indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + const JSONCPP_STRING& name = *it; + const Value& childValue = value[name]; + this->writeCommentBeforeValue(childValue); + this->writeWithIndent(valueToQuotedString(name.c_str())); + this->document_ += " : "; + this->writeValue(childValue); + if (++it == members.end()) { + this->writeCommentAfterValueOnSameLine(childValue); + break; + } + this->document_ += ','; + this->writeCommentAfterValueOnSameLine(childValue); } - document_ += ','; - writeCommentAfterValueOnSameLine(childValue); + this->unindent(); + this->writeWithIndent("}"); } - unindent(); - writeWithIndent("}"); - } - } break; + } break; } } -void StyledWriter::writeArrayValue(const Value& value) { +void StyledWriter::writeArrayValue(const Value& value) +{ unsigned size = value.size(); if (size == 0) - pushValue("[]"); + this->pushValue("[]"); else { - bool isArrayMultiLine = isMultineArray(value); + bool isArrayMultiLine = this->isMultineArray(value); if (isArrayMultiLine) { - writeWithIndent("["); - indent(); - bool hasChildValue = !childValues_.empty(); + this->writeWithIndent("["); + this->indent(); + bool hasChildValue = !this->childValues_.empty(); unsigned index = 0; for (;;) { const Value& childValue = value[index]; - writeCommentBeforeValue(childValue); + this->writeCommentBeforeValue(childValue); if (hasChildValue) - writeWithIndent(childValues_[index]); + this->writeWithIndent(this->childValues_[index]); else { - writeIndent(); - writeValue(childValue); + this->writeIndent(); + this->writeValue(childValue); } if (++index == size) { - writeCommentAfterValueOnSameLine(childValue); + this->writeCommentAfterValueOnSameLine(childValue); break; } - document_ += ','; - writeCommentAfterValueOnSameLine(childValue); + this->document_ += ','; + this->writeCommentAfterValueOnSameLine(childValue); } - unindent(); - writeWithIndent("]"); + this->unindent(); + this->writeWithIndent("]"); } else // output on a single line { - assert(childValues_.size() == size); - document_ += "[ "; + assert(this->childValues_.size() == size); + this->document_ += "[ "; for (unsigned index = 0; index < size; ++index) { if (index > 0) - document_ += ", "; - document_ += childValues_[index]; + this->document_ += ", "; + this->document_ += this->childValues_[index]; } - document_ += " ]"; + this->document_ += " ]"; } } } -bool StyledWriter::isMultineArray(const Value& value) { +bool StyledWriter::isMultineArray(const Value& value) +{ ArrayIndex const size = value.size(); - bool isMultiLine = size * 3 >= rightMargin_; - childValues_.clear(); + bool isMultiLine = size * 3 >= this->rightMargin_; + this->childValues_.clear(); for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + childValue.size() > 0); } if (!isMultiLine) // check if line length > max line length { - childValues_.reserve(size); - addChildValues_ = true; + this->childValues_.reserve(size); + this->addChildValues_ = true; ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' for (ArrayIndex index = 0; index < size; ++index) { - if (hasCommentForValue(value[index])) { + if (this->hasCommentForValue(value[index])) { isMultiLine = true; } - writeValue(value[index]); - lineLength += static_cast<ArrayIndex>(childValues_[index].length()); + this->writeValue(value[index]); + lineLength += + static_cast<ArrayIndex>(this->childValues_[index].length()); } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; + this->addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= this->rightMargin_; } return isMultiLine; } -void StyledWriter::pushValue(const JSONCPP_STRING& value) { - if (addChildValues_) - childValues_.push_back(value); +void StyledWriter::pushValue(const JSONCPP_STRING& value) +{ + if (this->addChildValues_) + this->childValues_.push_back(value); else - document_ += value; + this->document_ += value; } -void StyledWriter::writeIndent() { - if (!document_.empty()) { - char last = document_[document_.length() - 1]; +void StyledWriter::writeIndent() +{ + if (!this->document_.empty()) { + char last = this->document_[this->document_.length() - 1]; if (last == ' ') // already indented return; if (last != '\n') // Comments may add new-line - document_ += '\n'; + this->document_ += '\n'; } - document_ += indentString_; + this->document_ += this->indentString_; } -void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) { - writeIndent(); - document_ += value; +void StyledWriter::writeWithIndent(const JSONCPP_STRING& value) +{ + this->writeIndent(); + this->document_ += value; } -void StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); } +void StyledWriter::indent() +{ + this->indentString_ += JSONCPP_STRING(this->indentSize_, ' '); +} -void StyledWriter::unindent() { - assert(indentString_.size() >= indentSize_); - indentString_.resize(indentString_.size() - indentSize_); +void StyledWriter::unindent() +{ + assert(this->indentString_.size() >= this->indentSize_); + this->indentString_.resize(this->indentString_.size() - this->indentSize_); } -void StyledWriter::writeCommentBeforeValue(const Value& root) { +void StyledWriter::writeCommentBeforeValue(const Value& root) +{ if (!root.hasComment(commentBefore)) return; - document_ += "\n"; - writeIndent(); + this->document_ += "\n"; + this->writeIndent(); const JSONCPP_STRING& comment = root.getComment(commentBefore); JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { - document_ += *iter; - if (*iter == '\n' && - (iter != comment.end() && *(iter + 1) == '/')) - writeIndent(); + this->document_ += *iter; + if (*iter == '\n' && (iter != comment.end() && *(iter + 1) == '/')) + this->writeIndent(); ++iter; } // Comments are stripped of trailing newlines, so add one here - document_ += "\n"; + this->document_ += "\n"; } -void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) { +void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) +{ if (root.hasComment(commentAfterOnSameLine)) - document_ += " " + root.getComment(commentAfterOnSameLine); + this->document_ += " " + root.getComment(commentAfterOnSameLine); if (root.hasComment(commentAfter)) { - document_ += "\n"; - document_ += root.getComment(commentAfter); - document_ += "\n"; + this->document_ += "\n"; + this->document_ += root.getComment(commentAfter); + this->document_ += "\n"; } } -bool StyledWriter::hasCommentForValue(const Value& value) { +bool StyledWriter::hasCommentForValue(const Value& value) +{ return value.hasComment(commentBefore) || - value.hasComment(commentAfterOnSameLine) || - value.hasComment(commentAfter); + value.hasComment(commentAfterOnSameLine) || value.hasComment(commentAfter); } // Class StyledStreamWriter // ////////////////////////////////////////////////////////////////// StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation) - : document_(NULL), rightMargin_(74), indentation_(indentation), - addChildValues_() {} - -void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) { - document_ = &out; - addChildValues_ = false; - indentString_.clear(); - indented_ = true; - writeCommentBeforeValue(root); - if (!indented_) writeIndent(); - indented_ = true; - writeValue(root); - writeCommentAfterValueOnSameLine(root); - *document_ << "\n"; - document_ = NULL; // Forget the stream, for safety. -} - -void StyledStreamWriter::writeValue(const Value& value) { + : document_(NULL) + , rightMargin_(74) + , indentation_(indentation) + , addChildValues_() +{ +} + +void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) +{ + this->document_ = &out; + this->addChildValues_ = false; + this->indentString_.clear(); + this->indented_ = true; + this->writeCommentBeforeValue(root); + if (!this->indented_) + this->writeIndent(); + this->indented_ = true; + this->writeValue(root); + this->writeCommentAfterValueOnSameLine(root); + *this->document_ << "\n"; + this->document_ = NULL; // Forget the stream, for safety. +} + +void StyledStreamWriter::writeValue(const Value& value) +{ switch (value.type()) { - case nullValue: - pushValue("null"); - break; - case intValue: - pushValue(valueToString(value.asLargestInt())); - break; - case uintValue: - pushValue(valueToString(value.asLargestUInt())); - break; - case realValue: - pushValue(valueToString(value.asDouble())); - break; - case stringValue: - { - // Is NULL possible for value.string_? No. - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); - else pushValue(""); - break; - } - case booleanValue: - pushValue(valueToString(value.asBool())); - break; - case arrayValue: - writeArrayValue(value); - break; - case objectValue: { - Value::Members members(value.getMemberNames()); - if (members.empty()) - pushValue("{}"); - else { - writeWithIndent("{"); - indent(); - Value::Members::iterator it = members.begin(); - for (;;) { - const JSONCPP_STRING& name = *it; - const Value& childValue = value[name]; - writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedString(name.c_str())); - *document_ << " : "; - writeValue(childValue); - if (++it == members.end()) { - writeCommentAfterValueOnSameLine(childValue); - break; + case nullValue: + this->pushValue("null"); + break; + case intValue: + this->pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + this->pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + this->pushValue(valueToString(value.asDouble())); + break; + case stringValue: { + // Is NULL possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + this->pushValue( + valueToQuotedStringN(str, static_cast<unsigned>(end - str))); + else + this->pushValue(""); + break; + } + case booleanValue: + this->pushValue(valueToString(value.asBool())); + break; + case arrayValue: + this->writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + this->pushValue("{}"); + else { + this->writeWithIndent("{"); + this->indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + const JSONCPP_STRING& name = *it; + const Value& childValue = value[name]; + this->writeCommentBeforeValue(childValue); + this->writeWithIndent(valueToQuotedString(name.c_str())); + *this->document_ << " : "; + this->writeValue(childValue); + if (++it == members.end()) { + this->writeCommentAfterValueOnSameLine(childValue); + break; + } + *this->document_ << ","; + this->writeCommentAfterValueOnSameLine(childValue); } - *document_ << ","; - writeCommentAfterValueOnSameLine(childValue); + this->unindent(); + this->writeWithIndent("}"); } - unindent(); - writeWithIndent("}"); - } - } break; + } break; } } -void StyledStreamWriter::writeArrayValue(const Value& value) { +void StyledStreamWriter::writeArrayValue(const Value& value) +{ unsigned size = value.size(); if (size == 0) - pushValue("[]"); + this->pushValue("[]"); else { - bool isArrayMultiLine = isMultineArray(value); + bool isArrayMultiLine = this->isMultineArray(value); if (isArrayMultiLine) { - writeWithIndent("["); - indent(); - bool hasChildValue = !childValues_.empty(); + this->writeWithIndent("["); + this->indent(); + bool hasChildValue = !this->childValues_.empty(); unsigned index = 0; for (;;) { const Value& childValue = value[index]; - writeCommentBeforeValue(childValue); + this->writeCommentBeforeValue(childValue); if (hasChildValue) - writeWithIndent(childValues_[index]); + this->writeWithIndent(this->childValues_[index]); else { - if (!indented_) writeIndent(); - indented_ = true; - writeValue(childValue); - indented_ = false; + if (!this->indented_) + this->writeIndent(); + this->indented_ = true; + this->writeValue(childValue); + this->indented_ = false; } if (++index == size) { - writeCommentAfterValueOnSameLine(childValue); + this->writeCommentAfterValueOnSameLine(childValue); break; } - *document_ << ","; - writeCommentAfterValueOnSameLine(childValue); + *this->document_ << ","; + this->writeCommentAfterValueOnSameLine(childValue); } - unindent(); - writeWithIndent("]"); + this->unindent(); + this->writeWithIndent("]"); } else // output on a single line { - assert(childValues_.size() == size); - *document_ << "[ "; + assert(this->childValues_.size() == size); + *this->document_ << "[ "; for (unsigned index = 0; index < size; ++index) { if (index > 0) - *document_ << ", "; - *document_ << childValues_[index]; + *this->document_ << ", "; + *this->document_ << this->childValues_[index]; } - *document_ << " ]"; + *this->document_ << " ]"; } } } -bool StyledStreamWriter::isMultineArray(const Value& value) { +bool StyledStreamWriter::isMultineArray(const Value& value) +{ ArrayIndex const size = value.size(); - bool isMultiLine = size * 3 >= rightMargin_; - childValues_.clear(); + bool isMultiLine = size * 3 >= this->rightMargin_; + this->childValues_.clear(); for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { const Value& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + childValue.size() > 0); } if (!isMultiLine) // check if line length > max line length { - childValues_.reserve(size); - addChildValues_ = true; + this->childValues_.reserve(size); + this->addChildValues_ = true; ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' for (ArrayIndex index = 0; index < size; ++index) { - if (hasCommentForValue(value[index])) { + if (this->hasCommentForValue(value[index])) { isMultiLine = true; } - writeValue(value[index]); - lineLength += static_cast<ArrayIndex>(childValues_[index].length()); + this->writeValue(value[index]); + lineLength += + static_cast<ArrayIndex>(this->childValues_[index].length()); } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; + this->addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= this->rightMargin_; } return isMultiLine; } -void StyledStreamWriter::pushValue(const JSONCPP_STRING& value) { - if (addChildValues_) - childValues_.push_back(value); +void StyledStreamWriter::pushValue(const JSONCPP_STRING& value) +{ + if (this->addChildValues_) + this->childValues_.push_back(value); else - *document_ << value; + *this->document_ << value; } -void StyledStreamWriter::writeIndent() { +void StyledStreamWriter::writeIndent() +{ // blep intended this to look at the so-far-written string // to determine whether we are already indented, but // with a stream we cannot do that. So we rely on some saved state. // The caller checks indented_. - *document_ << '\n' << indentString_; + *this->document_ << '\n' << this->indentString_; } -void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) { - if (!indented_) writeIndent(); - *document_ << value; - indented_ = false; +void StyledStreamWriter::writeWithIndent(const JSONCPP_STRING& value) +{ + if (!this->indented_) + this->writeIndent(); + *this->document_ << value; + this->indented_ = false; } -void StyledStreamWriter::indent() { indentString_ += indentation_; } +void StyledStreamWriter::indent() +{ + this->indentString_ += this->indentation_; +} -void StyledStreamWriter::unindent() { - assert(indentString_.size() >= indentation_.size()); - indentString_.resize(indentString_.size() - indentation_.size()); +void StyledStreamWriter::unindent() +{ + assert(this->indentString_.size() >= this->indentation_.size()); + this->indentString_.resize(this->indentString_.size() - + this->indentation_.size()); } -void StyledStreamWriter::writeCommentBeforeValue(const Value& root) { +void StyledStreamWriter::writeCommentBeforeValue(const Value& root) +{ if (!root.hasComment(commentBefore)) return; - if (!indented_) writeIndent(); + if (!this->indented_) + this->writeIndent(); const JSONCPP_STRING& comment = root.getComment(commentBefore); JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { - *document_ << *iter; - if (*iter == '\n' && - (iter != comment.end() && *(iter + 1) == '/')) + *this->document_ << *iter; + if (*iter == '\n' && (iter != comment.end() && *(iter + 1) == '/')) // writeIndent(); // would include newline - *document_ << indentString_; + *this->document_ << this->indentString_; ++iter; } - indented_ = false; + this->indented_ = false; } -void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) { +void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) +{ if (root.hasComment(commentAfterOnSameLine)) - *document_ << ' ' << root.getComment(commentAfterOnSameLine); + *this->document_ << ' ' << root.getComment(commentAfterOnSameLine); if (root.hasComment(commentAfter)) { - writeIndent(); - *document_ << root.getComment(commentAfter); + this->writeIndent(); + *this->document_ << root.getComment(commentAfter); } - indented_ = false; + this->indented_ = false; } -bool StyledStreamWriter::hasCommentForValue(const Value& value) { +bool StyledStreamWriter::hasCommentForValue(const Value& value) +{ return value.hasComment(commentBefore) || - value.hasComment(commentAfterOnSameLine) || - value.hasComment(commentAfter); + value.hasComment(commentAfterOnSameLine) || value.hasComment(commentAfter); } ////////////////////////// // BuiltStyledStreamWriter /// Scoped enums are not available until C++11. -struct CommentStyle { +struct CommentStyle +{ /// Decide whether to write comments. - enum Enum { - None, ///< Drop all comments. - Most, ///< Recover odd behavior of previous versions (not implemented yet). - All ///< Keep all comments. + enum Enum + { + None, ///< Drop all comments. + Most, ///< Recover odd behavior of previous versions (not implemented yet). + All ///< Keep all comments. }; }; struct BuiltStyledStreamWriter : public StreamWriter { - BuiltStyledStreamWriter( - JSONCPP_STRING const& indentation, - CommentStyle::Enum cs, - JSONCPP_STRING const& colonSymbol, - JSONCPP_STRING const& nullSymbol, - JSONCPP_STRING const& endingLineFeedSymbol, - bool useSpecialFloats, - unsigned int precision); + BuiltStyledStreamWriter(JSONCPP_STRING const& indentation, + CommentStyle::Enum cs, + JSONCPP_STRING const& colonSymbol, + JSONCPP_STRING const& nullSymbol, + JSONCPP_STRING const& endingLineFeedSymbol, + bool useSpecialFloats, unsigned int precision); int write(Value const& root, JSONCPP_OSTREAM* sout) JSONCPP_OVERRIDE; + private: void writeValue(Value const& value); void writeArrayValue(Value const& value); @@ -911,13 +995,10 @@ private: unsigned int precision_; }; BuiltStyledStreamWriter::BuiltStyledStreamWriter( - JSONCPP_STRING const& indentation, - CommentStyle::Enum cs, - JSONCPP_STRING const& colonSymbol, - JSONCPP_STRING const& nullSymbol, - JSONCPP_STRING const& endingLineFeedSymbol, - bool useSpecialFloats, - unsigned int precision) + JSONCPP_STRING const& indentation, CommentStyle::Enum cs, + JSONCPP_STRING const& colonSymbol, JSONCPP_STRING const& nullSymbol, + JSONCPP_STRING const& endingLineFeedSymbol, bool useSpecialFloats, + unsigned int precision) : rightMargin_(74) , indentation_(indentation) , cs_(cs) @@ -932,247 +1013,276 @@ BuiltStyledStreamWriter::BuiltStyledStreamWriter( } int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout) { - sout_ = sout; - addChildValues_ = false; - indented_ = true; - indentString_.clear(); - writeCommentBeforeValue(root); - if (!indented_) writeIndent(); - indented_ = true; - writeValue(root); - writeCommentAfterValueOnSameLine(root); - *sout_ << endingLineFeedSymbol_; - sout_ = NULL; + this->sout_ = sout; + this->addChildValues_ = false; + this->indented_ = true; + this->indentString_.clear(); + this->writeCommentBeforeValue(root); + if (!this->indented_) + this->writeIndent(); + this->indented_ = true; + this->writeValue(root); + this->writeCommentAfterValueOnSameLine(root); + *this->sout_ << this->endingLineFeedSymbol_; + this->sout_ = NULL; return 0; } -void BuiltStyledStreamWriter::writeValue(Value const& value) { +void BuiltStyledStreamWriter::writeValue(Value const& value) +{ switch (value.type()) { - case nullValue: - pushValue(nullSymbol_); - break; - case intValue: - pushValue(valueToString(value.asLargestInt())); - break; - case uintValue: - pushValue(valueToString(value.asLargestUInt())); - break; - case realValue: - pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_)); - break; - case stringValue: - { - // Is NULL is possible for value.string_? No. - char const* str; - char const* end; - bool ok = value.getString(&str, &end); - if (ok) pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end-str))); - else pushValue(""); - break; - } - case booleanValue: - pushValue(valueToString(value.asBool())); - break; - case arrayValue: - writeArrayValue(value); - break; - case objectValue: { - Value::Members members(value.getMemberNames()); - if (members.empty()) - pushValue("{}"); - else { - writeWithIndent("{"); - indent(); - Value::Members::iterator it = members.begin(); - for (;;) { - JSONCPP_STRING const& name = *it; - Value const& childValue = value[name]; - writeCommentBeforeValue(childValue); - writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()))); - *sout_ << colonSymbol_; - writeValue(childValue); - if (++it == members.end()) { - writeCommentAfterValueOnSameLine(childValue); - break; + case nullValue: + this->pushValue(this->nullSymbol_); + break; + case intValue: + this->pushValue(valueToString(value.asLargestInt())); + break; + case uintValue: + this->pushValue(valueToString(value.asLargestUInt())); + break; + case realValue: + this->pushValue(valueToString(value.asDouble(), this->useSpecialFloats_, + this->precision_)); + break; + case stringValue: { + // Is NULL is possible for value.string_? No. + char const* str; + char const* end; + bool ok = value.getString(&str, &end); + if (ok) + this->pushValue( + valueToQuotedStringN(str, static_cast<unsigned>(end - str))); + else + this->pushValue(""); + break; + } + case booleanValue: + this->pushValue(valueToString(value.asBool())); + break; + case arrayValue: + this->writeArrayValue(value); + break; + case objectValue: { + Value::Members members(value.getMemberNames()); + if (members.empty()) + this->pushValue("{}"); + else { + this->writeWithIndent("{"); + this->indent(); + Value::Members::iterator it = members.begin(); + for (;;) { + JSONCPP_STRING const& name = *it; + Value const& childValue = value[name]; + this->writeCommentBeforeValue(childValue); + this->writeWithIndent(valueToQuotedStringN( + name.data(), static_cast<unsigned>(name.length()))); + *this->sout_ << this->colonSymbol_; + this->writeValue(childValue); + if (++it == members.end()) { + this->writeCommentAfterValueOnSameLine(childValue); + break; + } + *this->sout_ << ","; + this->writeCommentAfterValueOnSameLine(childValue); } - *sout_ << ","; - writeCommentAfterValueOnSameLine(childValue); + this->unindent(); + this->writeWithIndent("}"); } - unindent(); - writeWithIndent("}"); - } - } break; + } break; } } -void BuiltStyledStreamWriter::writeArrayValue(Value const& value) { +void BuiltStyledStreamWriter::writeArrayValue(Value const& value) +{ unsigned size = value.size(); if (size == 0) - pushValue("[]"); + this->pushValue("[]"); else { - bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value); + bool isMultiLine = + (this->cs_ == CommentStyle::All) || this->isMultineArray(value); if (isMultiLine) { - writeWithIndent("["); - indent(); - bool hasChildValue = !childValues_.empty(); + this->writeWithIndent("["); + this->indent(); + bool hasChildValue = !this->childValues_.empty(); unsigned index = 0; for (;;) { Value const& childValue = value[index]; - writeCommentBeforeValue(childValue); + this->writeCommentBeforeValue(childValue); if (hasChildValue) - writeWithIndent(childValues_[index]); + this->writeWithIndent(this->childValues_[index]); else { - if (!indented_) writeIndent(); - indented_ = true; - writeValue(childValue); - indented_ = false; + if (!this->indented_) + this->writeIndent(); + this->indented_ = true; + this->writeValue(childValue); + this->indented_ = false; } if (++index == size) { - writeCommentAfterValueOnSameLine(childValue); + this->writeCommentAfterValueOnSameLine(childValue); break; } - *sout_ << ","; - writeCommentAfterValueOnSameLine(childValue); + *this->sout_ << ","; + this->writeCommentAfterValueOnSameLine(childValue); } - unindent(); - writeWithIndent("]"); + this->unindent(); + this->writeWithIndent("]"); } else // output on a single line { - assert(childValues_.size() == size); - *sout_ << "["; - if (!indentation_.empty()) *sout_ << " "; + assert(this->childValues_.size() == size); + *this->sout_ << "["; + if (!this->indentation_.empty()) + *this->sout_ << " "; for (unsigned index = 0; index < size; ++index) { if (index > 0) - *sout_ << ((!indentation_.empty()) ? ", " : ","); - *sout_ << childValues_[index]; + *this->sout_ << ((!this->indentation_.empty()) ? ", " : ","); + *this->sout_ << this->childValues_[index]; } - if (!indentation_.empty()) *sout_ << " "; - *sout_ << "]"; + if (!this->indentation_.empty()) + *this->sout_ << " "; + *this->sout_ << "]"; } } } -bool BuiltStyledStreamWriter::isMultineArray(Value const& value) { +bool BuiltStyledStreamWriter::isMultineArray(Value const& value) +{ ArrayIndex const size = value.size(); - bool isMultiLine = size * 3 >= rightMargin_; - childValues_.clear(); + bool isMultiLine = size * 3 >= this->rightMargin_; + this->childValues_.clear(); for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) { Value const& childValue = value[index]; isMultiLine = ((childValue.isArray() || childValue.isObject()) && - childValue.size() > 0); + childValue.size() > 0); } if (!isMultiLine) // check if line length > max line length { - childValues_.reserve(size); - addChildValues_ = true; + this->childValues_.reserve(size); + this->addChildValues_ = true; ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]' for (ArrayIndex index = 0; index < size; ++index) { if (hasCommentForValue(value[index])) { isMultiLine = true; } - writeValue(value[index]); - lineLength += static_cast<ArrayIndex>(childValues_[index].length()); + this->writeValue(value[index]); + lineLength += + static_cast<ArrayIndex>(this->childValues_[index].length()); } - addChildValues_ = false; - isMultiLine = isMultiLine || lineLength >= rightMargin_; + this->addChildValues_ = false; + isMultiLine = isMultiLine || lineLength >= this->rightMargin_; } return isMultiLine; } -void BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const& value) { - if (addChildValues_) - childValues_.push_back(value); +void BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const& value) +{ + if (this->addChildValues_) + this->childValues_.push_back(value); else - *sout_ << value; + *this->sout_ << value; } -void BuiltStyledStreamWriter::writeIndent() { +void BuiltStyledStreamWriter::writeIndent() +{ // blep intended this to look at the so-far-written string // to determine whether we are already indented, but // with a stream we cannot do that. So we rely on some saved state. // The caller checks indented_. - if (!indentation_.empty()) { + if (!this->indentation_.empty()) { // In this case, drop newlines too. - *sout_ << '\n' << indentString_; + *this->sout_ << '\n' << this->indentString_; } } -void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) { - if (!indented_) writeIndent(); - *sout_ << value; - indented_ = false; +void BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const& value) +{ + if (!this->indented_) + this->writeIndent(); + *this->sout_ << value; + this->indented_ = false; } -void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; } +void BuiltStyledStreamWriter::indent() +{ + this->indentString_ += this->indentation_; +} -void BuiltStyledStreamWriter::unindent() { - assert(indentString_.size() >= indentation_.size()); - indentString_.resize(indentString_.size() - indentation_.size()); +void BuiltStyledStreamWriter::unindent() +{ + assert(this->indentString_.size() >= this->indentation_.size()); + this->indentString_.resize(this->indentString_.size() - + this->indentation_.size()); } -void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) { - if (cs_ == CommentStyle::None) return; +void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) +{ + if (this->cs_ == CommentStyle::None) + return; if (!root.hasComment(commentBefore)) return; - if (!indented_) writeIndent(); + if (!this->indented_) + this->writeIndent(); const JSONCPP_STRING& comment = root.getComment(commentBefore); JSONCPP_STRING::const_iterator iter = comment.begin(); while (iter != comment.end()) { - *sout_ << *iter; - if (*iter == '\n' && - (iter != comment.end() && *(iter + 1) == '/')) + *this->sout_ << *iter; + if (*iter == '\n' && (iter != comment.end() && *(iter + 1) == '/')) // writeIndent(); // would write extra newline - *sout_ << indentString_; + *this->sout_ << this->indentString_; ++iter; } - indented_ = false; + this->indented_ = false; } -void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const& root) { - if (cs_ == CommentStyle::None) return; +void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine( + Value const& root) +{ + if (this->cs_ == CommentStyle::None) + return; if (root.hasComment(commentAfterOnSameLine)) - *sout_ << " " + root.getComment(commentAfterOnSameLine); + *this->sout_ << " " + root.getComment(commentAfterOnSameLine); if (root.hasComment(commentAfter)) { - writeIndent(); - *sout_ << root.getComment(commentAfter); + this->writeIndent(); + *this->sout_ << root.getComment(commentAfter); } } // static -bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) { +bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) +{ return value.hasComment(commentBefore) || - value.hasComment(commentAfterOnSameLine) || - value.hasComment(commentAfter); + value.hasComment(commentAfterOnSameLine) || value.hasComment(commentAfter); } /////////////// // StreamWriter StreamWriter::StreamWriter() - : sout_(NULL) + : sout_(NULL) { } StreamWriter::~StreamWriter() { } StreamWriter::Factory::~Factory() -{} +{ +} StreamWriterBuilder::StreamWriterBuilder() { - setDefaults(&settings_); + setDefaults(&this->settings_); } StreamWriterBuilder::~StreamWriterBuilder() -{} +{ +} StreamWriter* StreamWriterBuilder::newStreamWriter() const { - JSONCPP_STRING indentation = settings_["indentation"].asString(); - JSONCPP_STRING cs_str = settings_["commentStyle"].asString(); - bool eyc = settings_["enableYAMLCompatibility"].asBool(); - bool dnp = settings_["dropNullPlaceholders"].asBool(); - bool usf = settings_["useSpecialFloats"].asBool(); - unsigned int pre = settings_["precision"].asUInt(); + JSONCPP_STRING indentation = this->settings_["indentation"].asString(); + JSONCPP_STRING cs_str = this->settings_["commentStyle"].asString(); + bool eyc = this->settings_["enableYAMLCompatibility"].asBool(); + bool dnp = this->settings_["dropNullPlaceholders"].asBool(); + bool usf = this->settings_["useSpecialFloats"].asBool(); + unsigned int pre = this->settings_["precision"].asUInt(); CommentStyle::Enum cs = CommentStyle::All; if (cs_str == "All") { cs = CommentStyle::All; @@ -1191,11 +1301,11 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const if (dnp) { nullSymbol.clear(); } - if (pre > 17) pre = 17; + if (pre > 17) + pre = 17; JSONCPP_STRING endingLineFeedSymbol; - return new BuiltStyledStreamWriter( - indentation, cs, - colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre); + return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol, + endingLineFeedSymbol, usf, pre); } static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys) { @@ -1210,23 +1320,24 @@ static void getValidWriterKeys(std::set<JSONCPP_STRING>* valid_keys) bool StreamWriterBuilder::validate(Json::Value* invalid) const { Json::Value my_invalid; - if (!invalid) invalid = &my_invalid; // so we do not need to test for NULL + if (!invalid) + invalid = &my_invalid; // so we do not need to test for NULL Json::Value& inv = *invalid; std::set<JSONCPP_STRING> valid_keys; getValidWriterKeys(&valid_keys); - Value::Members keys = settings_.getMemberNames(); + Value::Members keys = this->settings_.getMemberNames(); size_t n = keys.size(); for (size_t i = 0; i < n; ++i) { JSONCPP_STRING const& key = keys[i]; if (valid_keys.find(key) == valid_keys.end()) { - inv[key] = settings_[key]; + inv[key] = this->settings_[key]; } } return 0u == inv.size(); } Value& StreamWriterBuilder::operator[](JSONCPP_STRING key) { - return settings_[key]; + return this->settings_[key]; } // static void StreamWriterBuilder::setDefaults(Json::Value* settings) @@ -1241,14 +1352,17 @@ void StreamWriterBuilder::setDefaults(Json::Value* settings) //! [StreamWriterBuilderDefaults] } -JSONCPP_STRING writeString(StreamWriter::Factory const& builder, Value const& root) { +JSONCPP_STRING writeString(StreamWriter::Factory const& builder, + Value const& root) +{ JSONCPP_OSTRINGSTREAM sout; StreamWriterPtr const writer(builder.newStreamWriter()); writer->write(root, &sout); return sout.str(); } -JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) { +JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM& sout, Value const& root) +{ StreamWriterBuilder builder; StreamWriterPtr const writer(builder.newStreamWriter()); writer->write(root, &sout); @@ -944,11 +944,10 @@ while test $# != 0; do done # Make sure the generator is valid -if test "${cmake_bootstrap_generator}" != "MSYS Makefiles" -a \ - "${cmake_bootstrap_generator}" != "Unix Makefiles" -a \ - "${cmake_bootstrap_generator}" != "Ninja"; then - cmake_error 10 "Invalid generator: ${cmake_bootstrap_generator}" -fi +case "${cmake_bootstrap_generator}" in + 'MSYS Makefiles'|'Unix Makefiles'|'Ninja') ;; + *) cmake_error 10 "Invalid generator: ${cmake_bootstrap_generator}" +esac # If verbose, display some information about bootstrap if test -n "${cmake_verbose}"; then @@ -1196,8 +1195,8 @@ for std in 11 99 90; do for compiler in ${cmake_c_compilers}; do for std_flag in '' $std_flags; do for thread_flag in '' $thread_flags; do - echo "Checking whether '${compiler} ${cmake_c_flags} ${std_flag} ${thread_flag}' works." >> cmake_bootstrap.log 2>&1 - if cmake_try_run "${compiler}" "${cmake_c_flags} ${std_flag} ${thread_flag}" \ + echo "Checking whether '${compiler} ${cmake_c_flags} ${cmake_ld_flags} ${std_flag} ${thread_flag}' works." >> cmake_bootstrap.log 2>&1 + if cmake_try_run "${compiler}" "${cmake_c_flags} ${cmake_ld_flags} ${std_flag} ${thread_flag}" \ "${TMPFILE}.c" >> cmake_bootstrap.log 2>&1; then cmake_c_compiler="${compiler}" cmake_c_flags="${cmake_c_flags} ${std_flag} ${thread_flag}" @@ -1317,8 +1316,8 @@ for std in 17 14 11; do for compiler in ${cmake_cxx_compilers}; do for std_flag in '' $std_flags; do for thread_flag in '' $thread_flags; do - echo "Checking whether '${compiler} ${cmake_cxx_flags} ${std_flag} ${thread_flag}' works." >> cmake_bootstrap.log 2>&1 - if cmake_try_run "${compiler}" "${cmake_cxx_flags} ${std_flag} ${thread_flag}" \ + echo "Checking whether '${compiler} ${cmake_cxx_flags} ${cmake_ld_flags} ${std_flag} ${thread_flag}' works." >> cmake_bootstrap.log 2>&1 + if cmake_try_run "${compiler}" "${cmake_cxx_flags} ${cmake_ld_flags} ${std_flag} ${thread_flag}" \ "${TMPFILE}.cxx" >> cmake_bootstrap.log 2>&1; then cmake_cxx_compiler="${compiler}" cmake_cxx_flags="${cmake_cxx_flags} ${std_flag} ${thread_flag} " @@ -1346,8 +1345,8 @@ cmake_cxx_features="make_unique filesystem" for feature in ${cmake_cxx_features}; do eval "cmake_have_cxx_${feature}=0" - echo "Checking whether '${cmake_cxx_compiler} ${cmake_cxx_flags}' supports '${feature}'." >> cmake_bootstrap.log 2>&1 - if cmake_try_run "${cmake_cxx_compiler}" "${cmake_cxx_flags}" \ + echo "Checking whether '${cmake_cxx_compiler} ${cmake_cxx_flags} ${cmake_ld_flags}' supports '${feature}'." >> cmake_bootstrap.log 2>&1 + if cmake_try_run "${cmake_cxx_compiler}" "${cmake_cxx_flags} ${cmake_ld_flags}" \ "${cmake_source_dir}/Source/Checks/cm_cxx_${feature}.cxx" >> cmake_bootstrap.log 2>&1; then eval "cmake_have_cxx_${feature}=1" fi |