Merge topic 'support_CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS'
8f1d22c2d9 CUDA: Support CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS global variable
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3636
diff --git a/.clang-tidy b/.clang-tidy
index bfcb67c..2b7c9ae 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -3,29 +3,36 @@
bugprone-*,\
-bugprone-macro-parentheses,\
-bugprone-misplaced-widening-cast,\
+-bugprone-narrowing-conversions,\
+-bugprone-too-small-loop-variable,\
google-readability-casting,\
misc-*,\
-misc-incorrect-roundings,\
-misc-macro-parentheses,\
-misc-misplaced-widening-cast,\
+-misc-non-private-member-variables-in-classes,\
-misc-static-assert,\
modernize-*,\
+-modernize-avoid-c-arrays,\
-modernize-deprecated-headers,\
-modernize-return-braced-init-list,\
-modernize-use-auto,\
+-modernize-use-nodiscard,\
-modernize-use-noexcept,\
-modernize-use-transparent-functors,\
-modernize-use-using,\
performance-*,\
--performance-inefficient-string-concatenation,\
readability-*,\
-readability-function-size,\
-readability-identifier-naming,\
-readability-implicit-bool-cast,\
-readability-implicit-bool-conversion,\
-readability-inconsistent-declaration-parameter-name,\
+-readability-isolate-declaration,\
+-readability-magic-numbers,\
-readability-named-parameter,\
-readability-redundant-declaration,\
+-readability-uppercase-literal-suffix,\
"
HeaderFilterRegex: 'Source/cm[^/]*\.(h|hxx|cxx)$'
CheckOptions:
diff --git a/.gitattributes b/.gitattributes
index 24fd9c2..3854b73 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,4 +1,4 @@
-.gitattributes export-ignore
+.git* export-ignore
.hooks* export-ignore
# Custom attribute to mark sources as using our C code style.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5efa077..75ac8bf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -626,8 +626,7 @@
# The main section of the CMakeLists file
#
#-----------------------------------------------------------------------
-# Compute CMake_VERSION, etc.
-include(Source/CMakeVersionCompute.cmake)
+include(Source/CMakeVersion.cmake)
# Include the standard Dart testing module
enable_testing()
diff --git a/Help/command/if.rst b/Help/command/if.rst
index d8e3a45..be992df 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -29,6 +29,8 @@
repeat of the argument of the opening
``if`` command.
+.. _`Condition Syntax`:
+
Condition Syntax
^^^^^^^^^^^^^^^^
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 75a1d68..37a1d3a 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -92,6 +92,45 @@
.. _`CMake Review Process`: review.rst
.. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake
+Create Release Version
+======================
+
+When the ``release`` branch is ready to create a new release, follow the
+steps in the above `Maintain Current Release`_ section to checkout a local
+``release-$ver`` branch, where ``$ver`` is the version number of the
+current release in the form ``$major.$minor``.
+
+Edit ``Source/CMakeVersion.cmake`` to set the full version:
+
+.. code-block:: cmake
+
+ # CMake version number components.
+ set(CMake_VERSION_MAJOR $major)
+ set(CMake_VERSION_MINOR $minor)
+ set(CMake_VERSION_PATCH $patch)
+ #set(CMake_VERSION_RC $rc) # uncomment for release candidates
+
+In the following we use the placeholder ``$fullver`` for the full version
+number of the new release with the form ``$major.$minor.$patch[-rc$rc]``.
+If the version is not a release candidate, comment out the RC version
+component above and leave off the ``-rc$rc`` suffix from ``$fullver``.
+
+Commit the release version with the **exact** message ``CMake $fullver``:
+
+.. code-block:: shell
+
+ git commit -m "CMake $fullver"
+
+Tag the release using an annotated tag with the same message as the
+commit and named with the **exact** form ``v$fullver``:
+
+.. code-block:: shell
+
+ git tag -s -m "CMake $fullver" "v$fullver"
+
+Follow the steps in the above `Maintain Current Release`_ section to
+merge the ``release-$ver`` branch into ``master`` and publish both.
+
Branch a New Release
====================
diff --git a/Help/guide/tutorial/Complete/CMakeLists.txt b/Help/guide/tutorial/Complete/CMakeLists.txt
index bea611c..4541392 100644
--- a/Help/guide/tutorial/Complete/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/CMakeLists.txt
@@ -1,8 +1,17 @@
-cmake_minimum_required(VERSION 3.3)
+cmake_minimum_required(VERSION 3.15)
project(Tutorial)
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
# set the version number
set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
index 63c0f5f..c12955d 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
@@ -21,6 +21,7 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
+ target_link_libraries(MakeTable tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
@@ -44,14 +45,18 @@
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
- target_compile_definitions(SqrtLibrary PRIVATE
- "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
- "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
- )
+ target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
+
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+ if(HAVE_LOG AND HAVE_EXP)
+ target_compile_definitions(SqrtLibrary
+ PRIVATE "HAVE_LOG" "HAVE_EXP")
+ endif()
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
-target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>")
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
# building on windows
@@ -62,7 +67,7 @@
set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
# install rules
-install(TARGETS MathFunctions
+install(TARGETS MathFunctions tutorial_compiler_flags
DESTINATION lib
EXPORT MathFunctionsTargets)
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/MultiPackage/CMakeLists.txt b/Help/guide/tutorial/MultiPackage/CMakeLists.txt
index 067e807..bea611c 100644
--- a/Help/guide/tutorial/MultiPackage/CMakeLists.txt
+++ b/Help/guide/tutorial/MultiPackage/CMakeLists.txt
@@ -1,19 +1,26 @@
cmake_minimum_required(VERSION 3.3)
project(Tutorial)
-# control how we mark up Debug libraries compared to Release libraries
-set(CMAKE_DEBUG_POSTFIX "-d")
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
+
+# set the version number
+set(Tutorial_VERSION_MAJOR 1)
+set(Tutorial_VERSION_MINOR 0)
# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
-# the version number.
-set(Tutorial_VERSION_MAJOR 1)
-set(Tutorial_VERSION_MINOR 0)
+if(APPLE)
+ set(CMAKE_INSTALL_RPATH "@executable_path/../lib")
+elseif(UNIX)
+ set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib")
+endif()
# configure a header file to pass the version number only
configure_file(
diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt
index 161ad64..63c0f5f 100644
--- a/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt
@@ -1,4 +1,3 @@
-
# add the library that runs
add_library(MathFunctions MathFunctions.cxx)
@@ -62,6 +61,7 @@
set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0")
set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
+# install rules
install(TARGETS MathFunctions
DESTINATION lib
EXPORT MathFunctionsTargets)
diff --git a/Help/guide/tutorial/Step11/CMakeLists.txt b/Help/guide/tutorial/Step11/CMakeLists.txt
index 8f29fe2..e54bdde 100644
--- a/Help/guide/tutorial/Step11/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/CMakeLists.txt
@@ -1,8 +1,17 @@
-cmake_minimum_required(VERSION 3.3)
+cmake_minimum_required(VERSION 3.15)
project(Tutorial)
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
# set the version number
set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index ea42770..daaaa55 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -19,6 +19,7 @@
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
+ target_link_libraries(MakeTable tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
@@ -42,14 +43,17 @@
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
- target_compile_definitions(SqrtLibrary PRIVATE
- "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
- "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
- )
+ target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
+ target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+ if(HAVE_LOG AND HAVE_EXP)
+ target_compile_definitions(SqrtLibrary
+ PRIVATE "HAVE_LOG" "HAVE_EXP")
+ endif()
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
-target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>")
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
#building on windows
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index 41ed0c4..068499e 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -598,27 +598,47 @@
string, and ``<1:...>`` results in the content of "...". They can also be
nested.
-For example:
+A common usage of generator expressions is to conditionally add compiler
+flags, such as those as language levels or warnings. A nice pattern is
+to associate this information to an ``INTERFACE`` target allowing this
+information to propagate. Lets start by constructing an ``INTERFACE``
+target and specifying the required C++ standard level of ``11`` instead
+of using ``CMAKE_CXX_STANDARD``.
-.. code-block:: cmake
+So the following code:
- if(HAVE_LOG AND HAVE_EXP)
- target_compile_definitions(SqrtLibrary
- PRIVATE "HAVE_LOG" "HAVE_EXP")
- endif()
+.. literalinclude:: Step10/CMakeLists.txt
+ :language: cmake
+ :start-after: project(Tutorial)
+ :end-before: # Set the version number
-Can be rewritten with generator expressions:
+Would be replaced with:
-.. code-block:: cmake
+.. literalinclude:: Step11/CMakeLists.txt
+ :language: cmake
+ :start-after: project(Tutorial)
+ :end-before: # add compiler warning flags just when building this project via
- target_compile_definitions(SqrtLibrary PRIVATE
- "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
- "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
- )
-Note that ``${HAVE_LOG}`` is evaluated at CMake configure time while
-``$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>`` is evaluated at build system generation
-time.
+Next we add the desired compiler warning flags that we want for our
+project. As warning flags vary based on the compiler we use
+the ``COMPILE_LANG_AND_ID`` generator expression to control which
+flags to apply given a language and a set of compiler ids as seen
+below:
+
+.. literalinclude:: Step11/CMakeLists.txt
+ :language: cmake
+ :start-after: # the BUILD_INTERFACE genex
+ :end-before: # set the version number
+
+Looking at this we see that the warning flags are encapsulated inside a
+``BUILD_INTERFACE`` condition. This is done so that consumers of our installed
+project will not inherit our warning flags.
+
+
+**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that
+all targets have a ``target_link_libraries()`` call to ``tutorial_compiler_flags``.
+
Adding Export Configuration (Step 11)
=====================================
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
index 7435d9a..f233d08 100644
--- a/Help/manual/cmake-toolchains.7.rst
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -399,8 +399,10 @@
be false unless using a NDK that does not provide unified headers.
:variable:`CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION`
- Set to the version of the NDK toolchain to be selected as the compiler.
- If not specified, the default will be the latest available GCC toolchain.
+ On NDK r19 or above, this variable must be unset or set to ``clang``.
+ On NDK r18 or below, set this to the version of the NDK toolchain to
+ be selected as the compiler. If not specified, the default will be
+ the latest available GCC toolchain.
:variable:`CMAKE_ANDROID_STL_TYPE`
Set to specify which C++ standard library to use. If not specified,
diff --git a/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
index ef74ae2..dae960f 100644
--- a/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
+++ b/Help/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS.rst
@@ -1,12 +1,16 @@
CUDA_RESOLVE_DEVICE_SYMBOLS
---------------------------
-CUDA only: Enables device linking for the specific library target
+CUDA only: Enables device linking for the specific library target where
+required.
-If set this will enable device linking on the library target. Normally
-device linking is deferred until a shared library or executable is generated,
-allowing for multiple static libraries to resolve device symbols at the same
-time when they are used by a shared library or executable.
+If set, this will tell the required compilers to enable device linking
+on the library target. Device linking is an additional link step
+required by some CUDA compilers when :prop_tgt:`CUDA_SEPARABLE_COMPILATION` is
+enabled. Normally device linking is deferred until a shared library or
+executable is generated, allowing for multiple static libraries to resolve
+device symbols at the same time when they are used by a shared library or
+executable.
By default static library targets have this property is disabled,
while shared, module, and executable targets have this property enabled.
diff --git a/Help/release/3.15.rst b/Help/release/3.15.rst
index 4f53466..b0365ba 100644
--- a/Help/release/3.15.rst
+++ b/Help/release/3.15.rst
@@ -362,3 +362,10 @@
always runs in a mode aware of C++14.
* Preliminary Swift support added in 3.15.0 has been updated.
+
+3.15.2
+------
+
+* In CMake 3.15.0 and 3.15.1 the :variable:`CMAKE_FIND_PACKAGE_PREFER_CONFIG`
+ variable caused the :command:`find_package` command to fail on a missing
+ package even without the ``REQUIRED`` option. This has been fixed.
diff --git a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
index 5ae55d1..22808e3 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
@@ -3,7 +3,11 @@
When :ref:`Cross Compiling for Android with the NDK`, this variable
may be set to specify the version of the toolchain to be used
-as the compiler. The variable must be set to one of these forms:
+as the compiler.
+
+On NDK r19 or above, this variable must be unset or set to ``clang``.
+
+On NDK r18 or below, this variable must be set to one of these forms:
* ``<major>.<minor>``: GCC of specified version
* ``clang<major>.<minor>``: Clang of specified version
diff --git a/Help/variable/CMAKE_MESSAGE_INDENT.rst b/Help/variable/CMAKE_MESSAGE_INDENT.rst
index f7975ab..7e44a4c 100644
--- a/Help/variable/CMAKE_MESSAGE_INDENT.rst
+++ b/Help/variable/CMAKE_MESSAGE_INDENT.rst
@@ -23,8 +23,10 @@
Which results in the following output:
+.. code-block:: none
+
-- Collected items in the "listVar":
-- one
-- two
- -- tree
+ -- three
-- No more indent
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake
index 43ae989..b0d80d1 100644
--- a/Modules/CMakeCUDAInformation.cmake
+++ b/Modules/CMakeCUDAInformation.cmake
@@ -171,7 +171,8 @@
"<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}")
endif()
-if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0")
+if( CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" AND
+ CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0")
set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets")
else()
set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "")
diff --git a/Modules/CMakeDependentOption.cmake b/Modules/CMakeDependentOption.cmake
index 6046d85..99d5070 100644
--- a/Modules/CMakeDependentOption.cmake
+++ b/Modules/CMakeDependentOption.cmake
@@ -12,7 +12,7 @@
is used, but any value set by the user is preserved for when the
option is presented again. Example invocation:
-::
+.. code-block:: cmake
CMAKE_DEPENDENT_OPTION(USE_FOO "Use Foo" ON
"USE_BAR;NOT USE_ZOT" OFF)
@@ -21,7 +21,8 @@
called USE_FOO that defaults to ON. Otherwise, it sets USE_FOO to
OFF. If the status of USE_BAR or USE_ZOT ever changes, any value for
the USE_FOO option is saved so that when the option is re-enabled it
-retains its old value.
+retains its old value. Each element in the fourth parameter is
+evaluated as an if-condition, so :ref:`Condition Syntax` can be used.
#]=======================================================================]
macro(CMAKE_DEPENDENT_OPTION option doc default depends force)
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index 8be781a..037c33b 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -124,6 +124,22 @@
elseif(CMAKE_C_PLATFORM_ID MATCHES "Cygwin")
set(CMAKE_COMPILER_IS_CYGWIN 1)
endif()
+else()
+ if(NOT DEFINED CMAKE_C_COMPILER_FRONTEND_VARIANT)
+ # Some toolchain files set our internal CMAKE_C_COMPILER_ID_RUN
+ # variable but are not aware of CMAKE_C_COMPILER_FRONTEND_VARIANT.
+ # They pre-date our support for the GNU-like variant targeting the
+ # MSVC ABI so we do not consider that here.
+ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
+ set(CMAKE_C_COMPILER_FRONTEND_VARIANT "MSVC")
+ else()
+ set(CMAKE_C_COMPILER_FRONTEND_VARIANT "GNU")
+ endif()
+ else()
+ set(CMAKE_C_COMPILER_FRONTEND_VARIANT "")
+ endif()
+ endif()
endif()
if (NOT _CMAKE_TOOLCHAIN_LOCATION)
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index 00ef5b9..7274eec 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -119,6 +119,22 @@
elseif(CMAKE_CXX_PLATFORM_ID MATCHES "Cygwin")
set(CMAKE_COMPILER_IS_CYGWIN 1)
endif()
+else()
+ if(NOT DEFINED CMAKE_CXX_COMPILER_FRONTEND_VARIANT)
+ # Some toolchain files set our internal CMAKE_CXX_COMPILER_ID_RUN
+ # variable but are not aware of CMAKE_CXX_COMPILER_FRONTEND_VARIANT.
+ # They pre-date our support for the GNU-like variant targeting the
+ # MSVC ABI so we do not consider that here.
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+ set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "MSVC")
+ else()
+ set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "GNU")
+ endif()
+ else()
+ set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "")
+ endif()
+ endif()
endif()
if (NOT _CMAKE_TOOLCHAIN_LOCATION)
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 1914f52..0fcbbb7 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -138,7 +138,7 @@
set(_variant "")
if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xClang")
- if(CMAKE_HOST_WIN32 AND "x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
+ if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
if(CMAKE_GENERATOR MATCHES "Visual Studio")
set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "MSVC")
else()
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index 0e84116..773ee53 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -72,7 +72,7 @@
find_program(CMAKE_LINKER NAMES link HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_MT NAMES mt HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
- list(APPEND _CMAKE_TOOL_VARS CMAKE_LINKER CMAKE_MT)
+ list(APPEND _CMAKE_TOOL_VARS LINKER MT)
# in all other cases search for ar, ranlib, etc.
else()
@@ -84,27 +84,36 @@
endif()
if("${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_ID}" STREQUAL Clang)
- set(LLVM_OBJDUMP "llvm-objdump")
- set(LLVM_LLD "ld.lld")
- set(LLVM_RANLIB "llvm-ranlib")
- set(LLVM_AR "llvm-ar")
+ set(_CMAKE_ADDITIONAL_AR_NAMES "llvm-ar")
+ set(_CMAKE_ADDITIONAL_RANLIB_NAMES "llvm-ranlib")
+ set(_CMAKE_ADDITIONAL_STRIP_NAMES "llvm-strip")
+ set(_CMAKE_ADDITIONAL_LINKER_NAMES "ld.lld")
+ 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")
endif()
- find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar${_CMAKE_TOOLCHAIN_SUFFIX} ${LLVM_AR} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ find_program(CMAKE_AR NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ar${_CMAKE_TOOLCHAIN_SUFFIX} ${_CMAKE_ADDITIONAL_AR_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
- find_program(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib ${LLVM_RANLIB} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ find_program(CMAKE_RANLIB NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ranlib ${_CMAKE_ADDITIONAL_RANLIB_NAMES} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
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} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
- find_program(CMAKE_LINKER NAMES ${_CMAKE_TOOLCHAIN_PREFIX}ld ${LLVM_LLD} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
- find_program(CMAKE_NM NAMES ${_CMAKE_TOOLCHAIN_PREFIX}nm HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
- find_program(CMAKE_OBJDUMP NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objdump ${LLVM_OBJDUMP} HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
- find_program(CMAKE_OBJCOPY NAMES ${_CMAKE_TOOLCHAIN_PREFIX}objcopy HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ 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 CMAKE_AR CMAKE_RANLIB CMAKE_STRIP CMAKE_LINKER CMAKE_NM CMAKE_OBJDUMP CMAKE_OBJCOPY)
+ list(APPEND _CMAKE_TOOL_VARS AR RANLIB STRIP LINKER NM OBJDUMP OBJCOPY READELF DLLTOOL ADDR2LINE)
endif()
@@ -115,15 +124,16 @@
message(FATAL_ERROR "Could not find install_name_tool, please check your installation.")
endif()
- list(APPEND _CMAKE_TOOL_VARS CMAKE_INSTALL_NAME_TOOL)
+ list(APPEND _CMAKE_TOOL_VARS INSTALL_NAME_TOOL)
endif()
# Mark any tool cache entries as advanced.
foreach(var IN LISTS _CMAKE_TOOL_VARS)
- get_property(_CMAKE_TOOL_CACHED CACHE ${var} PROPERTY TYPE)
+ get_property(_CMAKE_TOOL_CACHED CACHE CMAKE_${var} PROPERTY TYPE)
if(_CMAKE_TOOL_CACHED)
- mark_as_advanced(${var})
+ mark_as_advanced(CMAKE_${var})
endif()
+ unset(_CMAKE_ADDITIONAL_${var}_NAMES)
endforeach()
unset(_CMAKE_TOOL_VARS)
unset(_CMAKE_TOOL_CACHED)
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 58b0813..54e441c 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -18,7 +18,9 @@
endif()
set(CMAKE_INCLUDE_FLAG_Swift "-I ")
-if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
+if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -install_name -Xlinker ")
+elseif(NOT CMAKE_SYSTEM_NAME STREQUAL Windows)
set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -soname -Xlinker ")
endif()
diff --git a/Modules/CheckCXXSymbolExists.cmake b/Modules/CheckCXXSymbolExists.cmake
index b112094..5c9079d 100644
--- a/Modules/CheckCXXSymbolExists.cmake
+++ b/Modules/CheckCXXSymbolExists.cmake
@@ -27,6 +27,17 @@
not be recognized: consider using the :module:`CheckTypeSize`
or :module:`CheckCXXSourceCompiles` module instead.
+.. note::
+
+ This command is unreliable when ``<symbol>`` is (potentially) an overloaded
+ function. Since there is no reliable way to predict whether a given function
+ in the system environment may be defined as an overloaded function or may be
+ an overloaded function on other systems or will become so in the future, it
+ is generally advised to use the :module:`CheckCXXSourceCompiles` module for
+ checking any function symbol (unless somehow you surely know the checked
+ function is not overloaded on other systems or will not be so in the
+ future).
+
The following variables may be set before calling this macro to modify
the way the check is run:
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index c2f488a..1053383 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -99,8 +99,28 @@
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT
"#include <${FILE}>\n")
endforeach()
- string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT
- "\nint main(int argc, char** argv)\n{\n (void)argv;\n#ifndef ${SYMBOL}\n return ((int*)(&${SYMBOL}))[argc];\n#else\n (void)argc;\n return 0;\n#endif\n}\n")
+ string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
+int main(int argc, char** argv)
+{
+ (void)argv;")
+ set(_CSE_CHECK_NON_MACRO "return ((int*)(&${SYMBOL}))[argc];")
+ if("${SYMBOL}" MATCHES "^[a-zA-Z_][a-zA-Z0-9_]*$")
+ # The SYMBOL has a legal macro name. Test whether it exists as a macro.
+ string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
+#ifndef ${SYMBOL}
+ ${_CSE_CHECK_NON_MACRO}
+#else
+ (void)argc;
+ return 0;
+#endif")
+ else()
+ # The SYMBOL cannot be a macro (e.g., a template function).
+ string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
+ ${_CSE_CHECK_NON_MACRO}")
+ endif()
+ string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT "
+}")
+ unset(_CSE_CHECK_NON_MACRO)
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
"${SOURCEFILE}" @ONLY)
@@ -139,6 +159,7 @@
"${OUTPUT}\nFile ${SOURCEFILE}:\n"
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
endif()
+ unset(CMAKE_CONFIGURABLE_FILE_CONTENT)
endif()
endmacro()
diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index c0ccb71..b59deda 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -1,3 +1,4 @@
+set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True)
set(CMAKE_CUDA_VERBOSE_FLAG "-v")
set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v")
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 14fc231..e55ed46 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -1079,7 +1079,7 @@
message(FATAL_ERROR "Tag for git checkout should not be empty.")
endif()
- set(git_clone_options)
+ set(git_clone_options "--no-checkout")
if(git_shallow)
if(NOT GIT_VERSION_STRING VERSION_LESS 1.7.10)
list(APPEND git_clone_options "--depth 1 --no-single-branch")
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index 2e9a052..bd69819 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -70,11 +70,27 @@
message(STATUS "FindGLEW: did not find GLEW CMake config file. Searching for libraries.")
endif()
+if(APPLE)
+ find_package(OpenGL QUIET)
+
+ if(OpenGL_FOUND)
+ if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: Found OpenGL Framework.")
+ message(STATUS "FindGLEW: OPENGL_LIBRARIES: ${OPENGL_LIBRARIES}")
+ endif()
+ else()
+ if(GLEW_VERBOSE)
+ message(STATUS "FindGLEW: could not find GLEW library.")
+ endif()
+ return()
+ endif()
+endif()
+
function(__glew_set_find_library_suffix shared_or_static)
- if(UNIX AND "${shared_or_static}" MATCHES "SHARED")
+ if((UNIX AND NOT APPLE) AND "${shared_or_static}" MATCHES "SHARED")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" PARENT_SCOPE)
- elseif(UNIX AND "${shared_or_static}" MATCHES "STATIC")
+ elseif((UNIX AND NOT APPLE) AND "${shared_or_static}" MATCHES "STATIC")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
elseif(APPLE AND "${shared_or_static}" MATCHES "SHARED")
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib;.so" PARENT_SCOPE)
@@ -194,7 +210,7 @@
if(NOT GLEW_FOUND)
if(GLEW_VERBOSE)
- message(STATUS "FindGLEW: could not found GLEW library.")
+ message(STATUS "FindGLEW: could not find GLEW library.")
endif()
return()
endif()
@@ -210,6 +226,11 @@
set_target_properties(GLEW::glew
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+ if(APPLE)
+ set_target_properties(GLEW::glew
+ PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ endif()
+
if(GLEW_SHARED_LIBRARY_RELEASE)
set_property(TARGET GLEW::glew
APPEND
@@ -238,6 +259,11 @@
set_target_properties(GLEW::glew_s
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+ if(APPLE)
+ set_target_properties(GLEW::glew_s
+ PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ endif()
+
if(GLEW_STATIC_LIBRARY_RELEASE)
set_property(TARGET GLEW::glew_s
APPEND
@@ -267,6 +293,11 @@
set_target_properties(GLEW::GLEW
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLEW_INCLUDE_DIRS}")
+ if(APPLE)
+ set_target_properties(GLEW::GLEW
+ PROPERTIES INTERFACE_LINK_LIBRARIES OpenGL::GL)
+ endif()
+
if(TARGET GLEW::glew)
if(GLEW_SHARED_LIBRARY_RELEASE)
set_property(TARGET GLEW::GLEW
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index 1722d6a..a2999fc 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -264,14 +264,14 @@
if(${_NAME}_${comp}_FOUND)
if(NOT DEFINED FOUND_COMPONENTS_MSG)
- set(FOUND_COMPONENTS_MSG "found components: ")
+ set(FOUND_COMPONENTS_MSG "found components:")
endif()
string(APPEND FOUND_COMPONENTS_MSG " ${comp}")
else()
if(NOT DEFINED MISSING_COMPONENTS_MSG)
- set(MISSING_COMPONENTS_MSG "missing components: ")
+ set(MISSING_COMPONENTS_MSG "missing components:")
endif()
string(APPEND MISSING_COMPONENTS_MSG " ${comp}")
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 6a9decb..2056e93 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -237,6 +237,12 @@
``NEVER`` to select preferably the interpreter from the virtual
environment.
+ .. note::
+
+ If the component ``Development`` is requested, it is **strongly**
+ recommended to also include the component ``Interpreter`` to get expected
+ result.
+
Commands
^^^^^^^^
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 8faec03..90a8264 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -241,6 +241,85 @@
set (${_PYTHON_PGN_NAMES} ${names} PARENT_SCOPE)
endfunction()
+function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
+ unset (${_PYTHON_PGCV_VALUE} PARENT_SCOPE)
+
+ if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS)$")
+ return()
+ endif()
+
+ if (_${_PYTHON_PREFIX}_CONFIG)
+ set (config_flag "--${NAME}")
+ string (TOLOWER "${config_flag}" config_flag)
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" ${config_flag}
+ RESULT_VARIABLE _result
+ OUTPUT_VARIABLE _values
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_result)
+ unset (_values)
+ else()
+ if (NAME STREQUAL "INCLUDES")
+ # do some clean-up
+ string (REGEX MATCHALL "-I[^ ]+" _values "${_values}")
+ string (REPLACE "-I" "" _values "${_values}")
+ list (REMOVE_DUPLICATES _values)
+ endif()
+ endif()
+ endif()
+
+ if (${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING)
+ if (NAME STREQUAL "PREFIX")
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))"
+ RESULT_VARIABLE _result
+ OUTPUT_VARIABLE _values
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_result)
+ unset (_values)
+ else()
+ list (REMOVE_DUPLICATES _values)
+ endif()
+ elseif (NAME STREQUAL "INCLUDES")
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))"
+ RESULT_VARIABLE _result
+ OUTPUT_VARIABLE _values
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_result)
+ unset (_values)
+ endif()
+ else()
+ set (config_flag "${NAME}")
+ if (NAME STREQUAL "CONFIGDIR")
+ set (config_flag "LIBPL")
+ endif()
+ execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
+ RESULT_VARIABLE _result
+ OUTPUT_VARIABLE _values
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_result)
+ unset (_values)
+ endif()
+ endif()
+ endif()
+
+ if (NOT _values OR _values STREQUAL "None")
+ return()
+ endif()
+
+ if (NAME STREQUAL "LIBS")
+ # do some clean-up
+ string (REGEX MATCHALL "-[l][^ ]+" _values "${_values}")
+ # remove elements relative to python library itself
+ list (FILTER _values EXCLUDE REGEX "-lpython")
+ list (REMOVE_DUPLICATES _values)
+ endif()
+
+ set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE)
+endfunction()
+
function (_PYTHON_VALIDATE_INTERPRETER)
if (NOT ${_PYTHON_PREFIX}_EXECUTABLE)
@@ -1147,114 +1226,90 @@
endif()
endif()
- # if python interpreter is found, use its location and version to ensure consistency
- # between interpreter and development environment
- unset (_${_PYTHON_PREFIX}_PREFIX)
- unset (_${_PYTHON_PREFIX}_EXEC_PREFIX)
- unset (_${_PYTHON_PREFIX}_BASE_EXEC_PREFIX)
- if (${_PYTHON_PREFIX}_Interpreter_FOUND)
- execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.EXEC_PREFIX)"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_EXEC_PREFIX
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- unset (_${_PYTHON_PREFIX}_EXEC_PREFIX)
+ # if python interpreter is found, use it to ensure consistency
+ # between interpreter and development environment.
+ # If not, try to locate a compatible config tool
+ if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING)
+ set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+ unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
+ if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+ set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV)
endif()
+ unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- if (NOT ${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "STANDARD")
- execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.BASE_EXEC_PREFIX)"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_BASE_EXEC_PREFIX
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- unset (_${_PYTHON_PREFIX}_BASE_EXEC_PREFIX)
+ if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
+ set (_${_PYTHON_PREFIX}_CONFIG_NAMES)
+
+ foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+ _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
+ list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
+
+ # Framework Paths
+ _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+ list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
+ endforeach()
+
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+ find_program (${_PYTHON_PREFIX}_CONFIG
+ NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES bin
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
endif()
- endif()
- endif()
- set (_${_PYTHON_PREFIX}_BASE_HINTS "${_${_PYTHON_PREFIX}_EXEC_PREFIX}" "${_${_PYTHON_PREFIX}_BASE_EXEC_PREFIX}" "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
- set (_${_PYTHON_PREFIX}_HINTS ${_${_PYTHON_PREFIX}_BASE_HINTS})
- if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- set (_${_PYTHON_PREFIX}_CONFIG_NAMES)
-
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
- list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
- endforeach()
-
- find_program (_${_PYTHON_PREFIX}_CONFIG
- NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin)
-
- if (_${_PYTHON_PREFIX}_CONFIG)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assume ABI is not supported
- set (__${_PYTHON_PREFIX}_ABIFLAGS "")
- endif()
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
- # Wrong ABI
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- endif()
- endif()
-
- if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- # check that config tool match library architecture
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- else()
- string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
- if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- endif()
- endif()
- endif()
- else()
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # try to use pythonX.Y-config tool
- _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
find_program (_${_PYTHON_PREFIX}_CONFIG
NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
PATH_SUFFIXES bin)
- unset (_${_PYTHON_PREFIX}_CONFIG_NAMES)
- if (NOT _${_PYTHON_PREFIX}_CONFIG)
- continue()
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+ find_program (_${_PYTHON_PREFIX}_CONFIG
+ NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
+ NAMES_PER_DIR
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES bin
+ NO_DEFAULT_PATH)
endif()
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assume ABI is not supported
- set (__${_PYTHON_PREFIX}_ABIFLAGS "")
- endif()
- if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
- # Wrong ABI
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- continue()
+ if (_${_PYTHON_PREFIX}_CONFIG)
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ # assume config tool is not usable
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ endif()
endif()
- if (DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+ if (_${_PYTHON_PREFIX}_CONFIG)
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ # assume ABI is not supported
+ set (__${_PYTHON_PREFIX}_ABIFLAGS "")
+ endif()
+ if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
+ # Wrong ABI
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ endif()
+ endif()
+
+ if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
# check that config tool match library architecture
execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
@@ -1263,62 +1318,132 @@
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_${_PYTHON_PREFIX}_RESULT)
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ else()
+ string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
+ if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ endif()
+ endif()
+ endif()
+ else()
+ foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+ # try to use pythonX.Y-config tool
+ _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
+
+ # Framework Paths
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+ find_program (${_PYTHON_PREFIX}_CONFIG
+ NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES bin
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+
+ find_program (_${_PYTHON_PREFIX}_CONFIG
+ NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ PATH_SUFFIXES bin)
+
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+ find_program (_${_PYTHON_PREFIX}_CONFIG
+ NAMES ${_${_PYTHON_PREFIX}_CONFIG_NAMES}
+ NAMES_PER_DIR
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES bin
+ NO_DEFAULT_PATH)
+ endif()
+
+ unset (_${_PYTHON_PREFIX}_CONFIG_NAMES)
+
+ if (_${_PYTHON_PREFIX}_CONFIG)
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --help
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE __${_PYTHON_PREFIX}_HELP
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ # assume config tool is not usable
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ endif()
+ endif()
+
+ if (NOT _${_PYTHON_PREFIX}_CONFIG)
continue()
endif()
- string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
- if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
+
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE __${_PYTHON_PREFIX}_ABIFLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ # assume ABI is not supported
+ set (__${_PYTHON_PREFIX}_ABIFLAGS "")
+ endif()
+ if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT __${_PYTHON_PREFIX}_ABIFLAGS IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
+ # Wrong ABI
unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
continue()
endif()
- endif()
- if (_${_PYTHON_PREFIX}_CONFIG)
- break()
- endif()
- endforeach()
+ if (_${_PYTHON_PREFIX}_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+ # check that config tool match library architecture
+ execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ continue()
+ endif()
+ string(FIND "${_${_PYTHON_PREFIX}_CONFIGDIR}" "${CMAKE_LIBRARY_ARCHITECTURE}" _${_PYTHON_PREFIX}_RESULT)
+ if (_${_PYTHON_PREFIX}_RESULT EQUAL -1)
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ continue()
+ endif()
+ endif()
+
+ if (_${_PYTHON_PREFIX}_CONFIG)
+ break()
+ endif()
+ endforeach()
+ endif()
endif()
- if (_${_PYTHON_PREFIX}_CONFIG)
+ if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
# retrieve root install directory
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --prefix
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PREFIX
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # python-config is not usable
- unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
- endif()
- endif()
+ _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX)
- if (_${_PYTHON_PREFIX}_CONFIG)
# enforce current ABI
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --abiflags
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_ABIFLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assume ABI is not supported
- set (_${_PYTHON_PREFIX}_ABIFLAGS "")
- endif()
+ _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS)
set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
# retrieve library
## compute some paths and artifact names
- string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_CONFIG_VERSION "${_${_PYTHON_PREFIX}_CONFIG}")
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_CONFIG_VERSION} LIBRARY)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_CONFIG_VERSION} POSIX LIBRARY)
-
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --configdir
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_CONFIGDIR
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}")
+ if (_${_PYTHON_PREFIX}_CONFIG)
+ string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_LIB_VERSION "${_${_PYTHON_PREFIX}_CONFIG}")
+ else()
+ set (_${_PYTHON_PREFIX}_LIB_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
endif()
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} POSIX LIBRARY)
+
+ _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR)
+ list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}")
list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
@@ -1344,28 +1469,23 @@
endif()
# retrieve include directory
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --includes
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- # retrieve include directory
- string (REGEX MATCHALL "-I[^ ]+" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_FLAGS}")
- string (REPLACE "-I" "" _${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIRS}")
- list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_INCLUDE_DIRS)
+ _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
- find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
+ find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
+ NAMES Python.h
+ HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
endif()
- # Rely on HINTS and standard paths if config tool failed to locate artifacts
+ # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
if (NOT ${_PYTHON_PREFIX}_LIBRARY_RELEASE OR NOT ${_PYTHON_PREFIX}_INCLUDE_DIR)
- set (_${_PYTHON_PREFIX}_HINTS ${_${_PYTHON_PREFIX}_BASE_HINTS})
+ set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+
+ unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
+ if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+ set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV)
+ endif()
if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
unset (_${_PYTHON_PREFIX}_LIB_NAMES)
@@ -1399,7 +1519,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
@@ -1412,7 +1533,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
@@ -1423,6 +1545,7 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
@@ -1474,7 +1597,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES lib libs
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
@@ -1484,7 +1608,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES lib libs)
# extract version from library name
@@ -1510,7 +1635,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
@@ -1523,7 +1649,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
@@ -1534,6 +1661,7 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
@@ -1575,7 +1703,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES lib libs
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
@@ -1585,7 +1714,8 @@
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES lib libs)
endif()
endif()
@@ -1623,20 +1753,6 @@
if (${_PYTHON_PREFIX}_LIBRARY_RELEASE OR ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
- if (${_PYTHON_PREFIX}_EXECUTABLE)
- # pick up include directory from configuration
- execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; import sysconfig; sys.stdout.write(sysconfig.get_path('include'))"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_PATH
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- file (TO_CMAKE_PATH "${_${_PYTHON_PREFIX}_PATH}" _${_PYTHON_PREFIX}_PATH)
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PATH}")
- endif()
- endif()
-
foreach (_${_PYTHON_PREFIX}_LIB IN ITEMS ${_PYTHON_PREFIX}_LIBRARY_RELEASE ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
if (${_${_PYTHON_PREFIX}_LIB})
# Use the library's install prefix as a hint
@@ -1664,7 +1780,8 @@
find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
NAMES Python.h
HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
@@ -1676,7 +1793,8 @@
find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
NAMES Python.h
HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
@@ -1697,7 +1815,8 @@
find_path (${_PYTHON_PREFIX}_INCLUDE_DIR
NAMES Python.h
HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
@@ -1896,20 +2015,10 @@
endif()
endif()
- if (_${_PYTHON_PREFIX}_CONFIG AND _${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC")
+ if (_${_PYTHON_PREFIX}_LIBRARY_TYPE STREQUAL "STATIC")
# extend link information with dependent libraries
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" --ldflags
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_FLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- string (REGEX MATCHALL "-[Ll][^ ]+" _${_PYTHON_PREFIX}_LINK_LIBRARIES "${_${_PYTHON_PREFIX}_FLAGS}")
- # remove elements relative to python library itself
- list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-lpython")
- foreach (_${_PYTHON_PREFIX}_DIR IN LISTS ${_PYTHON_PREFIX}_LIBRARY_DIRS)
- list (FILTER _${_PYTHON_PREFIX}_LINK_LIBRARIES EXCLUDE REGEX "-L${${_PYTHON_PREFIX}_DIR}")
- endforeach()
+ _python_get_config_var (_${_PYTHON_PREFIX}_LINK_LIBRARIES LIBS)
+ if (_${_PYTHON_PREFIX}_LINK_LIBRARIES)
set_property (TARGET ${__name}
PROPERTY INTERFACE_LINK_LIBRARIES ${_${_PYTHON_PREFIX}_LINK_LIBRARIES})
endif()
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 8372ce7..82878ea 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -193,6 +193,12 @@
``NEVER`` to select preferably the interpreter from the virtual
environment.
+ .. note::
+
+ If the component ``Development`` is requested, it is **strongly**
+ recommended to also include the component ``Interpreter`` to get expected
+ result.
+
Commands
^^^^^^^^
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index c8d9f24..417a789 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -234,6 +234,12 @@
``NEVER`` to select preferably the interpreter from the virtual
environment.
+ .. note::
+
+ If the component ``Development`` is requested, it is **strongly**
+ recommended to also include the component ``Interpreter`` to get expected
+ result.
+
Commands
^^^^^^^^
diff --git a/Modules/FindPythonInterp.cmake b/Modules/FindPythonInterp.cmake
index da33301..ccc7d5b 100644
--- a/Modules/FindPythonInterp.cmake
+++ b/Modules/FindPythonInterp.cmake
@@ -39,6 +39,15 @@
``find_package(PythonLibs)``, call ``find_package(PythonInterp)`` first to
get the currently active Python version by default with a consistent version
of PYTHON_LIBRARIES.
+
+.. note::
+
+ A call to ``find_package(PythonInterp ${V})`` for python version ``V``
+ may find a ``python`` executable with no version suffix. In this case
+ no attempt is made to avoid python executables from other versions.
+ Use :module:`FindPython3`, :module:`FindPython2` or :module:`FindPython`
+ instead.
+
#]=======================================================================]
unset(_Python_NAMES)
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 9ed1e01..847178f 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -40,6 +40,9 @@
endif()
if(NOT CMAKE_${lang}_COMPILER_TARGET)
set(CMAKE_${lang}_COMPILER_TARGET "${_ANDROID_ABI_CLANG_TARGET}")
+ if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+ string(APPEND CMAKE_${lang}_COMPILER_TARGET "${CMAKE_SYSTEM_VERSION}")
+ endif()
list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
endif()
endmacro()
diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake
index f8b9346..1affcd0 100644
--- a/Modules/Platform/Android-Common.cmake
+++ b/Modules/Platform/Android-Common.cmake
@@ -47,7 +47,41 @@
endif()
if(CMAKE_ANDROID_STL_TYPE)
- if(CMAKE_ANDROID_NDK)
+ if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+ if(CMAKE_ANDROID_STL_TYPE STREQUAL "system")
+ set(_ANDROID_STL_EXCEPTIONS 0)
+ set(_ANDROID_STL_RTTI 0)
+ macro(__android_stl lang)
+ string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libstdc++")
+ endmacro()
+ elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_static")
+ set(_ANDROID_STL_EXCEPTIONS 1)
+ set(_ANDROID_STL_RTTI 1)
+ macro(__android_stl lang)
+ string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++")
+ string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -static-libstdc++")
+ endmacro()
+ elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_shared")
+ set(_ANDROID_STL_EXCEPTIONS 1)
+ set(_ANDROID_STL_RTTI 1)
+ macro(__android_stl lang)
+ string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++")
+ endmacro()
+ elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "none")
+ set(_ANDROID_STL_RTTI 0)
+ set(_ANDROID_STL_EXCEPTIONS 0)
+ macro(__android_stl lang)
+ # FIXME: Add a way to add project-wide language-specific compile-only flags.
+ set(CMAKE_CXX_COMPILE_OBJECT
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++")
+ string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -nostdlib++")
+ endmacro()
+ else()
+ message(FATAL_ERROR
+ "Android: STL '${CMAKE_ANDROID_STL_TYPE}' not supported by this NDK."
+ )
+ endif()
+ elseif(CMAKE_ANDROID_NDK)
macro(__android_stl_inc lang dir req)
if(EXISTS "${dir}")
@@ -152,6 +186,10 @@
__android_stl(CXX)
endif()
+ if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+ string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -latomic -lm")
+ endif()
+
# <ndk>/build/core/definitions.mk appends the sysroot's include directory
# explicitly at the end of the command-line include path so that it
# precedes the toolchain's builtin include directories. This is
@@ -161,7 +199,7 @@
#
# Do not do this for a standalone toolchain because it is already
# tied to a specific API version.
- if(CMAKE_ANDROID_NDK)
+ if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
if(CMAKE_SYSROOT_COMPILE)
set(_cmake_sysroot_compile "${CMAKE_SYSROOT_COMPILE}")
else()
@@ -170,7 +208,7 @@
if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES
"${_cmake_sysroot_compile}/usr/include"
- "${_cmake_sysroot_compile}/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}"
+ "${_cmake_sysroot_compile}/usr/include/${CMAKE_ANDROID_ARCH_TRIPLE}"
)
else()
list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${_cmake_sysroot_compile}/usr/include")
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index bb42eed..e7c1b48 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -198,32 +198,66 @@
message(FATAL_ERROR "Android: The API specified by CMAKE_SYSTEM_VERSION='${CMAKE_SYSTEM_VERSION}' is not an integer.")
endif()
+if(CMAKE_ANDROID_NDK)
+ # Identify the host platform.
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+ if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "darwin-x86_64")
+ else()
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "darwin-x86")
+ endif()
+ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
+ if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "linux-x86_64")
+ else()
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "linux-x86")
+ endif()
+ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+ if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "windows-x86_64")
+ else()
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "windows")
+ endif()
+ else()
+ message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.")
+ endif()
+
+ # Look for a unified toolchain/sysroot provided with the NDK.
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}")
+ if(NOT IS_DIRECTORY "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/sysroot")
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "")
+ endif()
+else()
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "")
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "")
+endif()
+
# https://developer.android.com/ndk/guides/abis.html
set(_ANDROID_ABI_arm64-v8a_PROC "aarch64")
set(_ANDROID_ABI_arm64-v8a_ARCH "arm64")
-set(_ANDROID_ABI_arm64-v8a_HEADER "aarch64-linux-android")
+set(_ANDROID_ABI_arm64-v8a_TRIPLE "aarch64-linux-android")
set(_ANDROID_ABI_armeabi-v7a_PROC "armv7-a")
set(_ANDROID_ABI_armeabi-v7a_ARCH "arm")
-set(_ANDROID_ABI_armeabi-v7a_HEADER "arm-linux-androideabi")
+set(_ANDROID_ABI_armeabi-v7a_TRIPLE "arm-linux-androideabi")
set(_ANDROID_ABI_armeabi-v6_PROC "armv6")
set(_ANDROID_ABI_armeabi-v6_ARCH "arm")
-set(_ANDROID_ABI_armeabi-v6_HEADER "arm-linux-androideabi")
+set(_ANDROID_ABI_armeabi-v6_TRIPLE "arm-linux-androideabi")
set(_ANDROID_ABI_armeabi_PROC "armv5te")
set(_ANDROID_ABI_armeabi_ARCH "arm")
-set(_ANDROID_ABI_armeabi_HEADER "arm-linux-androideabi")
+set(_ANDROID_ABI_armeabi_TRIPLE "arm-linux-androideabi")
set(_ANDROID_ABI_mips_PROC "mips")
set(_ANDROID_ABI_mips_ARCH "mips")
-set(_ANDROID_ABI_mips_HEADER "mipsel-linux-android")
+set(_ANDROID_ABI_mips_TRIPLE "mipsel-linux-android")
set(_ANDROID_ABI_mips64_PROC "mips64")
set(_ANDROID_ABI_mips64_ARCH "mips64")
-set(_ANDROID_ABI_mips64_HEADER "mips64el-linux-android")
+set(_ANDROID_ABI_mips64_TRIPLE "mips64el-linux-android")
set(_ANDROID_ABI_x86_PROC "i686")
set(_ANDROID_ABI_x86_ARCH "x86")
-set(_ANDROID_ABI_x86_HEADER "i686-linux-android")
+set(_ANDROID_ABI_x86_TRIPLE "i686-linux-android")
set(_ANDROID_ABI_x86_64_PROC "x86_64")
set(_ANDROID_ABI_x86_64_ARCH "x86_64")
-set(_ANDROID_ABI_x86_64_HEADER "x86_64-linux-android")
+set(_ANDROID_ABI_x86_64_TRIPLE "x86_64-linux-android")
set(_ANDROID_PROC_aarch64_ARCH_ABI "arm64-v8a")
set(_ANDROID_PROC_armv7-a_ARCH_ABI "armeabi-v7a")
@@ -308,7 +342,7 @@
"does not match architecture '${CMAKE_ANDROID_ARCH}' for the ABI '${CMAKE_ANDROID_ARCH_ABI}'."
)
endif()
-set(CMAKE_ANDROID_ARCH_HEADER_TRIPLE "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_HEADER}")
+set(CMAKE_ANDROID_ARCH_TRIPLE "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_TRIPLE}")
# Select a processor.
if(NOT CMAKE_SYSTEM_PROCESSOR)
@@ -321,7 +355,7 @@
endif()
if(CMAKE_ANDROID_NDK AND NOT DEFINED CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
- if(IS_DIRECTORY "${CMAKE_ANDROID_NDK}/sysroot/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}")
+ if(IS_DIRECTORY "${CMAKE_ANDROID_NDK}/sysroot/usr/include/${CMAKE_ANDROID_ARCH_TRIPLE}")
# Unified headers exist so we use them by default.
set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS 0)
else()
@@ -340,8 +374,10 @@
if(CMAKE_ANDROID_NDK)
string(APPEND CMAKE_SYSTEM_CUSTOM_CODE
- "set(CMAKE_ANDROID_ARCH_HEADER_TRIPLE \"${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}\")\n"
+ "set(CMAKE_ANDROID_ARCH_TRIPLE \"${CMAKE_ANDROID_ARCH_TRIPLE}\")\n"
"set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS \"${CMAKE_ANDROID_NDK_DEPRECATED_HEADERS}\")\n"
+ "set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG \"${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}\")\n"
+ "set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED \"${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}\")\n"
)
endif()
diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake
index a434f90..a5d2820 100644
--- a/Modules/Platform/Android-Initialize.cmake
+++ b/Modules/Platform/Android-Initialize.cmake
@@ -17,6 +17,13 @@
return()
endif()
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+# Skip sysroot selection if the NDK has a unified toolchain.
+if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+ return()
+endif()
+
if(NOT CMAKE_SYSROOT)
if(CMAKE_ANDROID_NDK)
set(CMAKE_SYSROOT "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}")
@@ -40,5 +47,3 @@
"Android: No CMAKE_SYSROOT was selected."
)
endif()
-
-set(CMAKE_BUILD_TYPE_INIT Debug)
diff --git a/Modules/Platform/Android/Determine-Compiler-NDK.cmake b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
index 5f2cc52..e009c10 100644
--- a/Modules/Platform/Android/Determine-Compiler-NDK.cmake
+++ b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
@@ -1,6 +1,31 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
+# In Android NDK r19 and above there is a single clang toolchain.
+if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+ if(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION STREQUAL "clang")
+ message(FATAL_ERROR
+ "Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value '${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}' "
+ "is not supported by this NDK. It must be 'clang' or not set at all."
+ )
+ endif()
+ message(STATUS "Android: Selected unified Clang toolchain")
+ set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "clang")
+ set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/clang${_ANDROID_HOST_EXT}")
+ set(_ANDROID_TOOL_C_TOOLCHAIN_MACHINE "${CMAKE_ANDROID_ARCH_TRIPLE}")
+ set(_ANDROID_TOOL_C_TOOLCHAIN_VERSION "")
+ set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN "")
+ set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/${CMAKE_ANDROID_ARCH_TRIPLE}-")
+ set(_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}")
+ set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/clang++${_ANDROID_HOST_EXT}")
+ set(_ANDROID_TOOL_CXX_TOOLCHAIN_MACHINE "${CMAKE_ANDROID_ARCH_TRIPLE}")
+ set(_ANDROID_TOOL_CXX_TOOLCHAIN_VERSION "")
+ set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "")
+ set(_ANDROID_TOOL_CXX_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/${CMAKE_ANDROID_ARCH_TRIPLE}-")
+ set(_ANDROID_TOOL_CXX_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}")
+ return()
+endif()
+
# In Android NDK releases there is build system toolchain selection logic in
# these files:
#
@@ -195,40 +220,16 @@
set(_ANDROID_TOOL_PREFIX "${CMAKE_MATCH_1}")
endif()
-# Identify the host platform.
-if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
- if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
- set(_ANDROID_HOST_DIR "darwin-x86_64")
- else()
- set(_ANDROID_HOST_DIR "darwin-x86")
- endif()
-elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
- if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
- set(_ANDROID_HOST_DIR "linux-x86_64")
- else()
- set(_ANDROID_HOST_DIR "linux-x86")
- endif()
-elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
- if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
- set(_ANDROID_HOST_DIR "windows-x86_64")
- else()
- set(_ANDROID_HOST_DIR "windows")
- endif()
-else()
- message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.")
-endif()
-
# Help CMakeFindBinUtils locate things.
set(_CMAKE_TOOLCHAIN_PREFIX "${_ANDROID_TOOL_PREFIX}")
-set(_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG "${_ANDROID_HOST_DIR}")
set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "${_ANDROID_TOOL_VERS_NDK}")
# _ANDROID_TOOL_PREFIX should now match `gcc -dumpmachine`.
string(REGEX REPLACE "-$" "" _ANDROID_TOOL_C_TOOLCHAIN_MACHINE "${_ANDROID_TOOL_PREFIX}")
set(_ANDROID_TOOL_C_TOOLCHAIN_VERSION "${_ANDROID_TOOL_VERS}")
-set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${_ANDROID_HOST_DIR}/bin/${_ANDROID_TOOL_PREFIX}")
+set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}/bin/${_ANDROID_TOOL_PREFIX}")
set(_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}")
set(_ANDROID_TOOL_CXX_TOOLCHAIN_MACHINE "${_ANDROID_TOOL_C_TOOLCHAIN_MACHINE}")
@@ -238,9 +239,9 @@
if(_ANDROID_TOOL_CLANG_NAME)
message(STATUS "Android: Selected Clang toolchain '${_ANDROID_TOOL_CLANG_NAME}' with GCC toolchain '${_ANDROID_TOOL_NAME}'")
- set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${_ANDROID_HOST_DIR}/bin/clang${_ANDROID_HOST_EXT}")
- set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN ${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${_ANDROID_HOST_DIR})
- set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${_ANDROID_HOST_DIR}/bin/clang++${_ANDROID_HOST_EXT}")
+ set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}/bin/clang${_ANDROID_HOST_EXT}")
+ set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN ${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG})
+ set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}/bin/clang++${_ANDROID_HOST_EXT}")
set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN}")
else()
message(STATUS "Android: Selected GCC toolchain '${_ANDROID_TOOL_NAME}'")
@@ -267,4 +268,3 @@
unset(_ANDROID_TOOL_CLANG_NAME)
unset(_ANDROID_TOOL_CLANG_VERS)
unset(_ANDROID_TOOL_LLVM_NAME)
-unset(_ANDROID_HOST_DIR)
diff --git a/Modules/Platform/Android/Determine-Compiler-Standalone.cmake b/Modules/Platform/Android/Determine-Compiler-Standalone.cmake
index 4c1ac1f..5095aff 100644
--- a/Modules/Platform/Android/Determine-Compiler-Standalone.cmake
+++ b/Modules/Platform/Android/Determine-Compiler-Standalone.cmake
@@ -62,5 +62,4 @@
set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "")
endif()
-set(_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG "")
set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "")
diff --git a/Modules/Platform/Android/Determine-Compiler.cmake b/Modules/Platform/Android/Determine-Compiler.cmake
index a03ebcc..5c6b97b 100644
--- a/Modules/Platform/Android/Determine-Compiler.cmake
+++ b/Modules/Platform/Android/Determine-Compiler.cmake
@@ -40,7 +40,6 @@
elseif(CMAKE_ANDROID_STANDALONE_TOOLCHAIN)
include(Platform/Android/Determine-Compiler-Standalone)
else()
- set(_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG "")
set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "")
set(_ANDROID_TOOL_C_COMPILER "")
set(_ANDROID_TOOL_C_TOOLCHAIN_MACHINE "")
@@ -65,7 +64,6 @@
# Save the Android-specific information in CMake${lang}Compiler.cmake.
set(CMAKE_${lang}_COMPILER_CUSTOM_CODE "
-set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG \"${_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG}\")
set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION \"${_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION}\")
set(CMAKE_${lang}_ANDROID_TOOLCHAIN_MACHINE \"${_ANDROID_TOOL_${lang}_TOOLCHAIN_MACHINE}\")
set(CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION \"${_ANDROID_TOOL_${lang}_TOOLCHAIN_VERSION}\")
diff --git a/Modules/Platform/Android/abi-common.cmake b/Modules/Platform/Android/abi-common.cmake
index 6bce3c7..b01ef61 100644
--- a/Modules/Platform/Android/abi-common.cmake
+++ b/Modules/Platform/Android/abi-common.cmake
@@ -3,7 +3,7 @@
" -no-canonical-prefixes"
)
-if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
+if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED AND NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
string(APPEND _ANDROID_ABI_INIT_CFLAGS " -D__ANDROID_API__=${CMAKE_SYSTEM_VERSION}")
endif()
diff --git a/Modules/Platform/Windows-OpenWatcom.cmake b/Modules/Platform/Windows-OpenWatcom.cmake
index d38d616..76cd28b 100644
--- a/Modules/Platform/Windows-OpenWatcom.cmake
+++ b/Modules/Platform/Windows-OpenWatcom.cmake
@@ -10,7 +10,7 @@
set(CMAKE_LIBRARY_PATH_FLAG "libpath ")
set(CMAKE_LINK_LIBRARY_FLAG "library ")
-set(CMAKE_LINK_LIBRARY_FILE_FLAG "library")
+set(CMAKE_LINK_LIBRARY_FILE_FLAG "library ")
if(CMAKE_VERBOSE_MAKEFILE)
set(CMAKE_WCL_QUIET)
diff --git a/Source/.gitattributes b/Source/.gitattributes
index 7c160cc..d0aedc2 100644
--- a/Source/.gitattributes
+++ b/Source/.gitattributes
@@ -1,2 +1,4 @@
+CMakeVersion.cmake export-subst
+
# Do not format third-party sources.
/kwsys/** -format.clang-format-6.0
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 8117916..7cd07a8 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -95,9 +95,6 @@
${CMake_HAIKU_INCLUDE_DIRS}
)
-# let cmake know it is supposed to use it
-add_definitions(-DCMAKE_BUILD_WITH_CMAKE)
-
# Check if we can build the ELF parser.
if(CMAKE_USE_ELF_PARSER)
set(ELF_SRCS cmELF.h cmELF.cxx)
@@ -142,6 +139,7 @@
cmAffinity.cxx
cmAffinity.h
+ cmAlgorithms.h
cmArchiveWrite.cxx
cmArgumentParser.cxx
cmArgumentParser.h
@@ -403,6 +401,8 @@
cmStateSnapshot.cxx
cmStateSnapshot.h
cmStateTypes.h
+ cmStringAlgorithms.cxx
+ cmStringAlgorithms.h
cmSystemTools.cxx
cmSystemTools.h
cmTarget.cxx
@@ -529,6 +529,8 @@
cmFindProgramCommand.h
cmForEachCommand.cxx
cmForEachCommand.h
+ cmFunctionBlocker.cxx
+ cmFunctionBlocker.h
cmFunctionCommand.cxx
cmFunctionCommand.h
cmGetCMakePropertyCommand.cxx
@@ -634,6 +636,8 @@
cmStringReplaceHelper.cxx
cmStringCommand.cxx
cmStringCommand.h
+ cmSubcommandTable.cxx
+ cmSubcommandTable.h
cmSubdirCommand.cxx
cmSubdirCommand.h
cmSubdirDependsCommand.cxx
@@ -1159,6 +1163,21 @@
include (${CMake_SOURCE_DIR}/Source/LocalUserOptions.cmake OPTIONAL)
if(WIN32)
+ # Compute the binary version that appears in the RC file. Version
+ # components in the RC file are 16-bit integers so we may have to
+ # split the patch component.
+ if(CMake_VERSION_PATCH MATCHES "^([0-9]+)([0-9][0-9][0-9][0-9])$")
+ set(CMake_RCVERSION_YEAR "${CMAKE_MATCH_1}")
+ set(CMake_RCVERSION_MONTH_DAY "${CMAKE_MATCH_2}")
+ string(REGEX REPLACE "^0+" "" CMake_RCVERSION_MONTH_DAY "${CMake_RCVERSION_MONTH_DAY}")
+ set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_RCVERSION_YEAR},${CMake_RCVERSION_MONTH_DAY})
+ unset(CMake_RCVERSION_MONTH_DAY)
+ unset(CMake_RCVERSION_YEAR)
+ else()
+ set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_VERSION_PATCH})
+ endif()
+ set(CMake_RCVERSION_STR ${CMake_VERSION})
+
# Add Windows executable version information.
configure_file("CMakeVersion.rc.in" "CMakeVersion.rc" @ONLY)
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index ea3b43a..40a4ee6 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,82 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 15)
-set(CMake_VERSION_PATCH 20190726)
+set(CMake_VERSION_PATCH 20190813)
#set(CMake_VERSION_RC 0)
+set(CMake_VERSION_IS_DIRTY 0)
+
+# Start with the full version number used in tags. It has no dev info.
+set(CMake_VERSION
+ "${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}")
+if(DEFINED CMake_VERSION_RC)
+ set(CMake_VERSION "${CMake_VERSION}-rc${CMake_VERSION_RC}")
+endif()
+
+# Releases define a small patch level.
+if("${CMake_VERSION_PATCH}" VERSION_LESS 20000000)
+ set(CMake_VERSION_IS_RELEASE 1)
+else()
+ set(CMake_VERSION_IS_RELEASE 0)
+endif()
+
+if(EXISTS ${CMake_SOURCE_DIR}/.git)
+ find_package(Git QUIET)
+ if(GIT_FOUND)
+ macro(_git)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} ${ARGN}
+ WORKING_DIRECTORY ${CMake_SOURCE_DIR}
+ RESULT_VARIABLE _git_res
+ OUTPUT_VARIABLE _git_out OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _git_err ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ endmacro()
+ endif()
+endif()
+
+# Try to identify the current development source version.
+if(COMMAND _git)
+ # Get the commit checked out in this work tree.
+ _git(log -n 1 HEAD "--pretty=format:%h %s" --)
+ set(git_info "${_git_out}")
+else()
+ # Get the commit exported by 'git archive'.
+ set(git_info [==[$Format:%h %s$]==])
+endif()
+
+# Extract commit information if available.
+if(git_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]?[0-9a-f]?)[0-9a-f]* (.*)$")
+ # Have commit information.
+ set(git_hash "${CMAKE_MATCH_1}")
+ set(git_subject "${CMAKE_MATCH_2}")
+
+ # If this is not the exact commit of a release, add dev info.
+ if(NOT "${git_subject}" MATCHES "^[Cc][Mm]ake ${CMake_VERSION}$")
+ set(CMake_VERSION "${CMake_VERSION}-g${git_hash}")
+ endif()
+
+ # If this is a work tree, check whether it is dirty.
+ if(COMMAND _git)
+ _git(update-index -q --refresh)
+ _git(diff-index --name-only HEAD --)
+ if(_git_out)
+ set(CMake_VERSION_IS_DIRTY 1)
+ endif()
+ endif()
+else()
+ # No commit information.
+ if(NOT CMake_VERSION_IS_RELEASE)
+ # Generic development version.
+ set(CMake_VERSION "${CMake_VERSION}-git")
+ endif()
+endif()
+
+# Extract the version suffix component.
+if(CMake_VERSION MATCHES "-(.*)$")
+ set(CMake_VERSION_SUFFIX "${CMAKE_MATCH_1}")
+else()
+ set(CMake_VERSION_SUFFIX "")
+endif()
+if(CMake_VERSION_IS_DIRTY)
+ set(CMake_VERSION ${CMake_VERSION}-dirty)
+endif()
diff --git a/Source/CMakeVersionCompute.cmake b/Source/CMakeVersionCompute.cmake
deleted file mode 100644
index 160f470..0000000
--- a/Source/CMakeVersionCompute.cmake
+++ /dev/null
@@ -1,44 +0,0 @@
-# Load version number components.
-include(${CMake_SOURCE_DIR}/Source/CMakeVersion.cmake)
-
-# Releases define a small patch level.
-if("${CMake_VERSION_PATCH}" VERSION_LESS 20000000)
- set(CMake_VERSION_IS_DIRTY 0)
- set(CMake_VERSION_IS_RELEASE 1)
- set(CMake_VERSION_SOURCE "")
-else()
- set(CMake_VERSION_IS_DIRTY 0) # may be set to 1 by CMakeVersionSource
- set(CMake_VERSION_IS_RELEASE 0)
- include(${CMake_SOURCE_DIR}/Source/CMakeVersionSource.cmake)
-endif()
-
-# Compute the full version string.
-set(CMake_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
-if(CMake_VERSION_SOURCE)
- set(CMake_VERSION_SUFFIX "${CMake_VERSION_SOURCE}")
-elseif(DEFINED CMake_VERSION_RC)
- set(CMake_VERSION_SUFFIX "rc${CMake_VERSION_RC}")
-else()
- set(CMake_VERSION_SUFFIX "")
-endif()
-if(CMake_VERSION_SUFFIX)
- set(CMake_VERSION ${CMake_VERSION}-${CMake_VERSION_SUFFIX})
-endif()
-if(CMake_VERSION_IS_DIRTY)
- set(CMake_VERSION ${CMake_VERSION}-dirty)
-endif()
-
-# Compute the binary version that appears in the RC file. Version
-# components in the RC file are 16-bit integers so we may have to
-# split the patch component.
-if(CMake_VERSION_PATCH MATCHES "^([0-9]+)([0-9][0-9][0-9][0-9])$")
- set(CMake_RCVERSION_YEAR "${CMAKE_MATCH_1}")
- set(CMake_RCVERSION_MONTH_DAY "${CMAKE_MATCH_2}")
- string(REGEX REPLACE "^0+" "" CMake_RCVERSION_MONTH_DAY "${CMake_RCVERSION_MONTH_DAY}")
- set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_RCVERSION_YEAR},${CMake_RCVERSION_MONTH_DAY})
- unset(CMake_RCVERSION_MONTH_DAY)
- unset(CMake_RCVERSION_YEAR)
-else()
- set(CMake_RCVERSION ${CMake_VERSION_MAJOR},${CMake_VERSION_MINOR},${CMake_VERSION_PATCH})
-endif()
-set(CMake_RCVERSION_STR ${CMake_VERSION})
diff --git a/Source/CMakeVersionSource.cmake b/Source/CMakeVersionSource.cmake
deleted file mode 100644
index 5ea1de3..0000000
--- a/Source/CMakeVersionSource.cmake
+++ /dev/null
@@ -1,30 +0,0 @@
-# Try to identify the current development source version.
-set(CMake_VERSION_SOURCE "")
-if(EXISTS ${CMake_SOURCE_DIR}/.git/HEAD)
- find_program(GIT_EXECUTABLE NAMES git git.cmd)
- mark_as_advanced(GIT_EXECUTABLE)
- if(GIT_EXECUTABLE)
- execute_process(
- COMMAND ${GIT_EXECUTABLE} rev-parse --verify -q --short=4 HEAD
- OUTPUT_VARIABLE head
- OUTPUT_STRIP_TRAILING_WHITESPACE
- WORKING_DIRECTORY ${CMake_SOURCE_DIR}
- )
- if(head)
- set(CMake_VERSION_SOURCE "g${head}")
- execute_process(
- COMMAND ${GIT_EXECUTABLE} update-index -q --refresh
- WORKING_DIRECTORY ${CMake_SOURCE_DIR}
- )
- execute_process(
- COMMAND ${GIT_EXECUTABLE} diff-index --name-only HEAD --
- OUTPUT_VARIABLE dirty
- OUTPUT_STRIP_TRAILING_WHITESPACE
- WORKING_DIRECTORY ${CMake_SOURCE_DIR}
- )
- if(dirty)
- set(CMake_VERSION_IS_DIRTY 1)
- endif()
- endif()
- endif()
-endif()
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index a075a17..f130e05 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -8,6 +8,7 @@
#include "cmCPackIFWRepository.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmXMLWriter.h"
@@ -292,7 +293,7 @@
{
if (this->file) {
std::string content(data, data + length);
- content = cmSystemTools::TrimWhitespace(content);
+ content = cmTrimWhitespace(content);
std::string source = this->basePath + "/" + content;
std::string destination = this->path + "/" + content;
if (!cmSystemTools::CopyFileIfDifferent(source, destination)) {
diff --git a/Source/CPack/WiX/cmCMakeToWixPath.cxx b/Source/CPack/WiX/cmCMakeToWixPath.cxx
index b3889cf..630a8f8 100644
--- a/Source/CPack/WiX/cmCMakeToWixPath.cxx
+++ b/Source/CPack/WiX/cmCMakeToWixPath.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakeToWixPath.h"
-#include "cmSystemTools.h"
+#include "cmStringAlgorithms.h"
#include <string>
#include <vector>
@@ -29,7 +29,7 @@
return cygpath;
}
- return cmSystemTools::TrimWhitespace(winpath_chars.data());
+ return cmTrimWhitespace(winpath_chars.data());
}
#else
std::string CMakeToWixPath(const std::string& path)
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 563de02..b5e287d 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -4,6 +4,7 @@
#include "cmCPackGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmWIXAccessControlList::cmWIXAccessControlList(
@@ -48,8 +49,7 @@
user = user_and_domain;
}
- std::vector<std::string> permissions =
- cmSystemTools::tokenize(permission_string, ",");
+ std::vector<std::string> permissions = cmTokenize(permission_string, ",");
this->SourceWriter.BeginElement("Permission");
this->SourceWriter.AddAttribute("User", user);
@@ -57,8 +57,7 @@
this->SourceWriter.AddAttribute("Domain", domain);
}
for (std::string const& permission : permissions) {
- this->EmitBooleanAttribute(entry,
- cmSystemTools::TrimWhitespace(permission));
+ this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission));
}
this->SourceWriter.EndElement("Permission");
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 512ac7a..3fd124b 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmVersion.h"
#include "cmWorkingDirectory.h"
#include "cmXMLSafe.h"
@@ -772,7 +773,7 @@
// Make sure that DESTDIR + CPACK_INSTALL_PREFIX directory
// exists:
//
- if (cmSystemTools::StringStartsWith(dir.c_str(), "/")) {
+ if (cmHasLiteralPrefix(dir, "/")) {
dir = tempInstallDirectory + dir;
} else {
dir = tempInstallDirectory + "/" + dir;
diff --git a/Source/CPack/cmCPackNuGetGenerator.cxx b/Source/CPack/cmCPackNuGetGenerator.cxx
index 76f0699..19a3a0a 100644
--- a/Source/CPack/cmCPackNuGetGenerator.cxx
+++ b/Source/CPack/cmCPackNuGetGenerator.cxx
@@ -2,9 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackNuGetGenerator.h"
-#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include <algorithm>
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 89c3b1c..ae56adb 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -11,7 +11,7 @@
#include <utility>
#include <vector>
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
# include "cmsys/ConsoleBuf.hxx"
#endif
@@ -100,7 +100,7 @@
int main(int argc, char const* const* argv)
{
cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
// Replace streambuf so we can output Unicode to console
cmsys::ConsoleBuf::Manager consoleOut(std::cout);
consoleOut.SetUTF8Pipes();
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index c8e4fa1..b98a4e3 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -9,6 +9,7 @@
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
@@ -384,11 +385,8 @@
if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) {
std::string srcdir =
this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
- std::string srcdirrep;
for (cc = srcdir.size() - 2; cc > 0; cc--) {
if (srcdir[cc] == '/') {
- srcdirrep = srcdir.substr(cc);
- srcdirrep = "/..." + srcdirrep;
srcdir = srcdir.substr(0, cc + 1);
break;
}
@@ -398,11 +396,8 @@
if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) {
std::string bindir =
this->CTest->GetCTestConfiguration("BuildDirectory") + "/";
- std::string bindirrep;
for (cc = bindir.size() - 2; cc > 0; cc--) {
if (bindir[cc] == '/') {
- bindirrep = bindir.substr(cc);
- bindirrep = "/..." + bindirrep;
bindir = bindir.substr(0, cc + 1);
break;
}
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index f6028c4..54fe612 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -13,6 +13,7 @@
#include "cmParseGTMCoverage.h"
#include "cmParseJacocoCoverage.h"
#include "cmParsePHPCoverage.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
@@ -1181,7 +1182,7 @@
// gcov 4.7 can have output lines saying "No executable lines" and
// "Removing 'filename.gcov'"... Don't log those as "errors."
if (line != "No executable lines" &&
- !cmSystemTools::StringStartsWith(line.c_str(), "Removing ")) {
+ !cmHasLiteralPrefix(line, "Removing ")) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Unknown gcov output line: [" << line << "]"
<< std::endl);
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 9d9761c..093017c 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -10,11 +10,11 @@
#include <time.h>
#include <vector>
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessOutput.h"
#include "cmProcessTools.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
static unsigned int cmCTestGITVersion(unsigned int epic, unsigned int major,
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 237ca82..739cc58 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -16,6 +16,7 @@
#include "cmProcessOutput.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -493,9 +494,9 @@
continue;
}
if (this->Match(line, this->RegexWarningSuppress)) {
- line = "[CTest: warning suppressed] " + line;
+ line = cmStrCat("[CTest: warning suppressed] ", line);
} else if (this->Match(line, this->RegexWarning)) {
- line = "[CTest: warning matched] " + line;
+ line = cmStrCat("[CTest: warning matched] ", line);
}
e4.Content(sep);
e4.Content(line);
@@ -594,7 +595,7 @@
bool cmCTestLaunch::MatchesFilterPrefix(std::string const& line) const
{
return !this->OptionFilterPrefix.empty() &&
- cmSystemTools::StringStartsWith(line, this->OptionFilterPrefix.c_str());
+ cmHasPrefix(line, this->OptionFilterPrefix);
}
int cmCTestLaunch::Main(int argc, const char* const argv[])
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 65cf646..fb91322 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -689,7 +689,7 @@
this->TestProcess->SetTimeout(timeout);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmSystemTools::SaveRestoreEnvironment sre;
#endif
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 7a5b8d1..58f88be 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -24,13 +24,13 @@
#include "cmCTestUploadCommand.h"
#include "cmCommand.h"
#include "cmDuration.h"
-#include "cmFunctionBlocker.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -49,32 +49,8 @@
# include <unistd.h>
#endif
-class cmExecutionStatus;
-struct cmListFileFunction;
-
#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
-// used to keep elapsed time up to date
-class cmCTestScriptFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus& /*status*/) override;
- // virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
- // virtual void ScopeEnded(cmMakefile &mf);
-
- cmCTestScriptHandler* CTestScriptHandler;
-};
-
-// simply update the time and don't block anything
-bool cmCTestScriptFunctionBlocker::IsFunctionBlocked(
- const cmListFileFunction& /*lff*/, cmMakefile& /*mf*/,
- cmExecutionStatus& /*status*/)
-{
- this->CTestScriptHandler->UpdateElapsedTime();
- return false;
-}
-
cmCTestScriptHandler::cmCTestScriptHandler()
{
this->Backup = false;
@@ -373,12 +349,8 @@
this->Makefile->AddDefinition("CMAKE_LEGACY_CYGWIN_WIN32", "0");
#endif
- // always add a function blocker to update the elapsed time
- {
- auto fb = cm::make_unique<cmCTestScriptFunctionBlocker>();
- fb->CTestScriptHandler = this;
- this->Makefile->AddFunctionBlocker(std::move(fb));
- }
+ // set a callback function to update the elapsed time
+ this->Makefile->OnExecuteCommand([this] { this->UpdateElapsedTime(); });
/* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and
CMakeSystemSpecificInformation, so
@@ -523,7 +495,7 @@
int cmCTestScriptHandler::RunConfigurationScript(
const std::string& total_script_arg, bool pscope)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmSystemTools::SaveRestoreEnvironment sre;
#endif
@@ -692,8 +664,8 @@
fullCommand, &output, &output, &retVal, cvsArgs[0].c_str(),
this->HandlerVerbose, cmDuration::zero() /*this->TimeOut*/);
if (!res || retVal != 0) {
- cmSystemTools::Error("Unable to perform extra updates:\n" + eu +
- "\nWith output:\n" + output);
+ cmSystemTools::Error(cmStrCat("Unable to perform extra updates:\n", eu,
+ "\nWith output:\n", output));
return 0;
}
}
@@ -963,7 +935,7 @@
continue;
}
- std::string fullPath = directoryPath + std::string("/") + path;
+ std::string fullPath = cmStrCat(directoryPath, "/", path);
bool isDirectory = cmSystemTools::FileIsDirectory(fullPath) &&
!cmSystemTools::FileIsSymlink(fullPath);
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 54c4bae..17ef350 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -19,6 +19,7 @@
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmake.h"
@@ -224,7 +225,7 @@
std::string local_file = file;
bool initialize_cdash_buildid = false;
if (!cmSystemTools::FileExists(local_file)) {
- local_file = localprefix + "/" + file;
+ local_file = cmStrCat(localprefix, "/", file);
// If this file exists within the local Testing directory we assume
// that it will be associated with the current build in CDash.
initialize_cdash_buildid = true;
@@ -236,9 +237,9 @@
<< remote_file << std::endl;
std::string ofile = cmSystemTools::EncodeURL(remote_file);
- std::string upload_as = url +
- ((url.find('?') == std::string::npos) ? '?' : '&') +
- "FileName=" + ofile;
+ std::string upload_as =
+ cmStrCat(url, ((url.find('?') == std::string::npos) ? '?' : '&'),
+ "FileName=", ofile);
if (initialize_cdash_buildid) {
// Provide extra arguments to CDash so that it can initialize and
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 5134407..67c24ca 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -20,7 +20,6 @@
#include "cm_memory.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCommand.h"
@@ -30,6 +29,7 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmWorkingDirectory.h"
#include "cmXMLWriter.h"
diff --git a/Source/CTest/cmParseBlanketJSCoverage.cxx b/Source/CTest/cmParseBlanketJSCoverage.cxx
index 63d6a15..b74decb 100644
--- a/Source/CTest/cmParseBlanketJSCoverage.cxx
+++ b/Source/CTest/cmParseBlanketJSCoverage.cxx
@@ -110,7 +110,8 @@
{
}
-bool cmParseBlanketJSCoverage::LoadCoverageData(std::vector<std::string> files)
+bool cmParseBlanketJSCoverage::LoadCoverageData(
+ std::vector<std::string> const& files)
{
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Found " << files.size() << " Files" << std::endl,
diff --git a/Source/CTest/cmParseBlanketJSCoverage.h b/Source/CTest/cmParseBlanketJSCoverage.h
index 696121f..cd1b225 100644
--- a/Source/CTest/cmParseBlanketJSCoverage.h
+++ b/Source/CTest/cmParseBlanketJSCoverage.h
@@ -29,7 +29,7 @@
public:
cmParseBlanketJSCoverage(cmCTestCoverageHandlerContainer& cont,
cmCTest* ctest);
- bool LoadCoverageData(std::vector<std::string> files);
+ bool LoadCoverageData(std::vector<std::string> const& files);
// Read the JSON output
bool ReadJSONFile(std::string const& file);
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 848a034..e0186c9 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -2,6 +2,7 @@
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
@@ -75,7 +76,7 @@
// Check if this is a path that is relative to our source or
// binary directories.
for (std::string const& filePath : FilePaths) {
- finalpath = filePath + "/" + filename;
+ finalpath = cmStrCat(filePath, "/", filename);
if (cmSystemTools::FileExists(finalpath)) {
this->CurFileName = finalpath;
break;
@@ -86,7 +87,7 @@
cmsys::ifstream fin(this->CurFileName.c_str());
if (this->CurFileName.empty() || !fin) {
this->CurFileName =
- this->Coverage.BinaryDir + "/" + atts[tagCount + 1];
+ cmStrCat(this->Coverage.BinaryDir, "/", atts[tagCount + 1]);
fin.open(this->CurFileName.c_str());
if (!fin) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 0722753..881bf2d 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -1,8 +1,8 @@
#include "cmParseGTMCoverage.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmsys/Directory.hxx"
diff --git a/Source/CTest/cmParseJacocoCoverage.cxx b/Source/CTest/cmParseJacocoCoverage.cxx
index b78142a..5f1e712 100644
--- a/Source/CTest/cmParseJacocoCoverage.cxx
+++ b/Source/CTest/cmParseJacocoCoverage.cxx
@@ -2,6 +2,7 @@
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
@@ -118,7 +119,7 @@
// Check if any of the locations found match our package.
for (std::string const& f : files) {
std::string dir = cmsys::SystemTools::GetParentDirectory(f);
- if (cmsys::SystemTools::StringEndsWith(dir, this->PackageName.c_str())) {
+ if (cmHasSuffix(dir, this->PackageName)) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Found package directory for " << fileName << ": "
<< dir << std::endl,
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index c9ebba8..287a482 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -6,6 +6,7 @@
#include "cmAlgorithms.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
+#include "cmStringAlgorithms.h"
#include "cmVersion.h"
#include "cmake.h"
#include "cmsys/CommandLineArguments.hxx"
diff --git a/Source/cmAddCompileDefinitionsCommand.cxx b/Source/cmAddCompileDefinitionsCommand.cxx
index 0474819..b00a4a7 100644
--- a/Source/cmAddCompileDefinitionsCommand.cxx
+++ b/Source/cmAddCompileDefinitionsCommand.cxx
@@ -2,19 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddCompileDefinitionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-bool cmAddCompileDefinitionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCompileDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddCompileDefinition(i);
+ mf.AddCompileDefinition(i);
}
return true;
}
diff --git a/Source/cmAddCompileDefinitionsCommand.h b/Source/cmAddCompileDefinitionsCommand.h
index 5f90ed9..4bd621c 100644
--- a/Source/cmAddCompileDefinitionsCommand.h
+++ b/Source/cmAddCompileDefinitionsCommand.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmAddCompileDefinitionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddCompileDefinitionsCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddCompileDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddCompileOptionsCommand.cxx b/Source/cmAddCompileOptionsCommand.cxx
index 412fb38..8ccb512 100644
--- a/Source/cmAddCompileOptionsCommand.cxx
+++ b/Source/cmAddCompileOptionsCommand.cxx
@@ -2,19 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddCompileOptionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-bool cmAddCompileOptionsCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCompileOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddCompileOption(i);
+ mf.AddCompileOption(i);
}
return true;
}
diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h
index b34b7fc..b172412 100644
--- a/Source/cmAddCompileOptionsCommand.h
+++ b/Source/cmAddCompileOptionsCommand.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmAddCompileOptionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddCompileOptionsCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddCompileOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 6eb38bd..e502a64 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -8,6 +8,7 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
+#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -16,21 +17,22 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
-class cmExecutionStatus;
+static bool cmAddCustomCommandCommandCheckOutputs(
+ const std::vector<std::string>& outputs, cmExecutionStatus& status);
-// cmAddCustomCommandCommand
-bool cmAddCustomCommandCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
/* Let's complain at the end of this function about the lack of a particular
arg. For the moment, let's say that COMMAND, and either TARGET or SOURCE
are required.
*/
if (args.size() < 4) {
- this->SetError("called with wrong number of arguments.");
+ status.SetError("called with wrong number of arguments.");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
std::string source, target, main_dependency, working, depfile, job_pool;
std::string comment_buffer;
const char* comment = nullptr;
@@ -167,9 +169,9 @@
doing = doing_comment;
} else if (copy == keyDEPFILE) {
doing = doing_depfile;
- if (this->Makefile->GetGlobalGenerator()->GetName() != "Ninja") {
- this->SetError("Option DEPFILE not supported by " +
- this->Makefile->GetGlobalGenerator()->GetName());
+ if (mf.GetGlobalGenerator()->GetName() != "Ninja") {
+ status.SetError("Option DEPFILE not supported by " +
+ mf.GetGlobalGenerator()->GetName());
return false;
}
} else if (copy == keyJOB_POOL) {
@@ -192,7 +194,7 @@
// and later references "${CMAKE_CURRENT_SOURCE_DIR}/out.txt".
// This is fairly obscure so we can wait for someone to
// complain.
- filename = this->Makefile->GetCurrentBinaryDirectory();
+ filename = mf.GetCurrentBinaryDirectory();
filename += "/";
}
filename += copy;
@@ -269,7 +271,7 @@
comment = comment_buffer.c_str();
break;
default:
- this->SetError("Wrong syntax. Unknown type of argument.");
+ status.SetError("Wrong syntax. Unknown type of argument.");
return false;
}
}
@@ -284,31 +286,31 @@
// At this point we could complain about the lack of arguments. For
// the moment, let's say that COMMAND, TARGET are always required.
if (output.empty() && target.empty()) {
- this->SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
+ status.SetError("Wrong syntax. A TARGET or OUTPUT must be specified.");
return false;
}
if (source.empty() && !target.empty() && !output.empty()) {
- this->SetError(
+ status.SetError(
"Wrong syntax. A TARGET and OUTPUT can not both be specified.");
return false;
}
if (append && output.empty()) {
- this->SetError("given APPEND option with no OUTPUT.");
+ status.SetError("given APPEND option with no OUTPUT.");
return false;
}
// Make sure the output names and locations are safe.
- if (!this->CheckOutputs(output) || !this->CheckOutputs(outputs) ||
- !this->CheckOutputs(byproducts)) {
+ if (!cmAddCustomCommandCommandCheckOutputs(output, status) ||
+ !cmAddCustomCommandCommandCheckOutputs(outputs, status) ||
+ !cmAddCustomCommandCommandCheckOutputs(byproducts, status)) {
return false;
}
// Check for an append request.
if (append) {
// Lookup an existing command.
- if (cmSourceFile* sf =
- this->Makefile->GetSourceFileWithOutput(output[0])) {
+ if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) {
if (cmCustomCommand* cc = sf->GetCustomCommand()) {
cc->AppendCommands(commandLines);
cc->AppendDepends(depends);
@@ -321,12 +323,12 @@
std::ostringstream e;
e << "given APPEND option with output\n\"" << output[0]
<< "\"\nwhich is not already a custom command output.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
if (uses_terminal && !job_pool.empty()) {
- this->SetError("JOB_POOL is shadowed by USES_TERMINAL.");
+ status.SetError("JOB_POOL is shadowed by USES_TERMINAL.");
return false;
}
@@ -335,22 +337,21 @@
if (source.empty() && output.empty()) {
// Source is empty, use the target.
std::vector<std::string> no_depends;
- this->Makefile->AddCustomCommandToTarget(
- target, byproducts, no_depends, commandLines, cctype, comment,
- working.c_str(), escapeOldStyle, uses_terminal, depfile, job_pool,
- command_expand_lists);
+ mf.AddCustomCommandToTarget(target, byproducts, no_depends, commandLines,
+ cctype, comment, working.c_str(),
+ escapeOldStyle, uses_terminal, depfile,
+ job_pool, command_expand_lists);
} else if (target.empty()) {
// Target is empty, use the output.
- this->Makefile->AddCustomCommandToOutput(
- output, byproducts, depends, main_dependency, commandLines, comment,
- working.c_str(), false, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool);
+ mf.AddCustomCommandToOutput(output, byproducts, depends, main_dependency,
+ commandLines, comment, working.c_str(), false,
+ escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool);
// Add implicit dependency scanning requests if any were given.
if (!implicit_depends.empty()) {
bool okay = false;
- if (cmSourceFile* sf =
- this->Makefile->GetSourceFileWithOutput(output[0])) {
+ if (cmSourceFile* sf = mf.GetSourceFileWithOutput(output[0])) {
if (cmCustomCommand* cc = sf->GetCustomCommand()) {
okay = true;
cc->SetImplicitDepends(implicit_depends);
@@ -360,21 +361,21 @@
std::ostringstream e;
e << "could not locate source file with a custom command producing \""
<< output[0] << "\" even though this command tried to create it!";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
} else if (!byproducts.empty()) {
- this->SetError("BYPRODUCTS may not be specified with SOURCE signatures");
+ status.SetError("BYPRODUCTS may not be specified with SOURCE signatures");
return false;
} else if (uses_terminal) {
- this->SetError("USES_TERMINAL may not be used with SOURCE signatures");
+ status.SetError("USES_TERMINAL may not be used with SOURCE signatures");
return false;
} else {
bool issueMessage = true;
std::ostringstream e;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0050)) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0050)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0050) << "\n";
break;
@@ -391,30 +392,31 @@
if (issueMessage) {
e << "The SOURCE signatures of add_custom_command are no longer "
"supported.";
- this->Makefile->IssueMessage(messageType, e.str());
+ mf.IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
}
// Use the old-style mode for backward compatibility.
- this->Makefile->AddCustomCommandOldStyle(target, outputs, depends, source,
- commandLines, comment);
+ mf.AddCustomCommandOldStyle(target, outputs, depends, source, commandLines,
+ comment);
}
return true;
}
-bool cmAddCustomCommandCommand::CheckOutputs(
- const std::vector<std::string>& outputs)
+bool cmAddCustomCommandCommandCheckOutputs(
+ const std::vector<std::string>& outputs, cmExecutionStatus& status)
{
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& o : outputs) {
// Make sure the file will not be generated into the source
// directory during an out of source build.
- if (!this->Makefile->CanIWriteThisFile(o)) {
+ if (!mf.CanIWriteThisFile(o)) {
std::string e = "attempted to have a file \"" + o +
"\" in a source directory as an output of custom command.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -425,7 +427,7 @@
std::ostringstream msg;
msg << "called with OUTPUT containing a \"" << o[pos]
<< "\". This character is not allowed.";
- this->SetError(msg.str());
+ status.SetError(msg.str());
return false;
}
}
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index 931aeab..4f8c58f 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -8,38 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddCustomCommandCommand
- * \brief cmAddCustomCommandCommand defines a new command (rule) that can
- * be executed within the build process
- *
- */
-
-class cmAddCustomCommandCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddCustomCommandCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- bool CheckOutputs(const std::vector<std::string>& outputs);
-};
+bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index 0ecd5f5..f812ab5 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -6,6 +6,7 @@
#include <utility>
#include "cmCustomCommandLines.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -14,17 +15,15 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmAddCustomTargetCommand
-bool cmAddCustomTargetCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
std::string const& targetName = args[0];
// Check the target name.
@@ -33,7 +32,7 @@
e << "called with invalid target name \"" << targetName
<< "\". Target names may not contain a slash. "
<< "Use ADD_CUSTOM_COMMAND to generate files.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -122,7 +121,7 @@
case doing_byproducts: {
std::string filename;
if (!cmSystemTools::FileIsFullPath(copy)) {
- filename = this->Makefile->GetCurrentBinaryDirectory();
+ filename = mf.GetCurrentBinaryDirectory();
filename += "/";
}
filename += copy;
@@ -145,7 +144,7 @@
job_pool = copy;
break;
default:
- this->SetError("Wrong syntax. Unknown type of argument.");
+ status.SetError("Wrong syntax. Unknown type of argument.");
return false;
}
}
@@ -156,7 +155,7 @@
std::ostringstream msg;
msg << "called with target name containing a \"" << targetName[pos]
<< "\". This character is not allowed.";
- this->SetError(msg.str());
+ status.SetError(msg.str());
return false;
}
@@ -168,8 +167,7 @@
if (nameOk) {
nameOk = targetName.find(':') == std::string::npos;
}
- if (!nameOk &&
- !this->Makefile->CheckCMP0037(targetName, cmStateEnums::UTILITY)) {
+ if (!nameOk && !mf.CheckCMP0037(targetName, cmStateEnums::UTILITY)) {
return false;
}
@@ -182,39 +180,37 @@
// Enforce name uniqueness.
{
std::string msg;
- if (!this->Makefile->EnforceUniqueName(targetName, msg, true)) {
- this->SetError(msg);
+ if (!mf.EnforceUniqueName(targetName, msg, true)) {
+ status.SetError(msg);
return false;
}
}
if (commandLines.empty() && !byproducts.empty()) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "BYPRODUCTS may not be specified without any COMMAND");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "BYPRODUCTS may not be specified without any COMMAND");
return true;
}
if (commandLines.empty() && uses_terminal) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "USES_TERMINAL may not be specified without any COMMAND");
+ mf.IssueMessage(MessageType::FATAL_ERROR,
+ "USES_TERMINAL may not be specified without any COMMAND");
return true;
}
if (commandLines.empty() && command_expand_lists) {
- this->Makefile->IssueMessage(
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"COMMAND_EXPAND_LISTS may not be specified without any COMMAND");
return true;
}
if (uses_terminal && !job_pool.empty()) {
- this->SetError("JOB_POOL is shadowed by USES_TERMINAL.");
+ status.SetError("JOB_POOL is shadowed by USES_TERMINAL.");
return false;
}
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
- cmTarget* target = this->Makefile->AddUtilityCommand(
+ cmTarget* target = mf.AddUtilityCommand(
targetName, cmMakefile::TargetOrigin::Project, excludeFromAll,
working_directory.c_str(), byproducts, depends, commandLines,
escapeOldStyle, comment, uses_terminal, command_expand_lists, job_pool);
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index db577bc..e23ef9f 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -8,36 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddCustomTargetCommand
- * \brief Command that adds a target to the build system.
- *
- * cmAddCustomTargetCommand adds an extra target to the build system.
- * This is useful when you would like to add special
- * targets like "install,", "clean," and so on.
- */
-class cmAddCustomTargetCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddCustomTargetCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddDefinitionsCommand.cxx b/Source/cmAddDefinitionsCommand.cxx
index 62e57a3..0b10aee 100644
--- a/Source/cmAddDefinitionsCommand.cxx
+++ b/Source/cmAddDefinitionsCommand.cxx
@@ -2,21 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddDefinitionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-// cmAddDefinitionsCommand
-bool cmAddDefinitionsCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- // it is OK to have no arguments
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddDefineFlag(i);
+ mf.AddDefineFlag(i);
}
return true;
}
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
index 0e32c83..a67f095 100644
--- a/Source/cmAddDefinitionsCommand.h
+++ b/Source/cmAddDefinitionsCommand.h
@@ -8,35 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddDefinitionsCommand
- * \brief Specify a list of compiler defines
- *
- * cmAddDefinitionsCommand specifies a list of compiler defines. These defines
- * will be added to the compile command.
- */
-class cmAddDefinitionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddDefinitionsCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddDefinitionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
index 4956a47..0ddbda8 100644
--- a/Source/cmAddDependenciesCommand.cxx
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -4,34 +4,33 @@
#include <sstream>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmDependenciesCommand
-bool cmAddDependenciesCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
std::string const& target_name = args[0];
- if (this->Makefile->IsAlias(target_name)) {
+ if (mf.IsAlias(target_name)) {
std::ostringstream e;
e << "Cannot add target-level dependencies to alias target \""
<< target_name << "\".\n";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
}
- if (cmTarget* target = this->Makefile->FindTargetToUse(target_name)) {
+ if (cmTarget* target = mf.FindTargetToUse(target_name)) {
// skip over target_name
for (std::string const& arg : cmMakeRange(args).advance(1)) {
- target->AddUtility(arg, this->Makefile);
+ target->AddUtility(arg, &mf);
}
} else {
std::ostringstream e;
@@ -41,7 +40,7 @@
<< "by the add_executable, add_library, or add_custom_target commands. "
<< "If you want to add file-level dependencies see the DEPENDS option "
<< "of the add_custom_target and add_custom_command commands.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ mf.IssueMessage(MessageType::FATAL_ERROR, e.str());
}
return true;
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
index ce912d3..0c60e3a 100644
--- a/Source/cmAddDependenciesCommand.h
+++ b/Source/cmAddDependenciesCommand.h
@@ -8,34 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddDependenciesCommand
- * \brief Add a dependency to a target
- *
- * cmAddDependenciesCommand adds a dependency to a target
- */
-class cmAddDependenciesCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddDependenciesCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 5685fdf..59d6be3 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -4,22 +4,22 @@
#include <sstream>
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmExecutableCommand
-bool cmAddExecutableCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddExecutableCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+
+ cmMakefile& mf = status.GetMakefile();
std::vector<std::string>::const_iterator s = args.begin();
std::string const& exename = *s;
@@ -61,59 +61,58 @@
if (nameOk && !importTarget && !isAlias) {
nameOk = exename.find(':') == std::string::npos;
}
- if (!nameOk &&
- !this->Makefile->CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
+ if (!nameOk && !mf.CheckCMP0037(exename, cmStateEnums::EXECUTABLE)) {
return false;
}
// Special modifiers are not allowed with IMPORTED signature.
if (importTarget && (use_win32 || use_macbundle || excludeFromAll)) {
if (use_win32) {
- this->SetError("may not be given WIN32 for an IMPORTED target.");
+ status.SetError("may not be given WIN32 for an IMPORTED target.");
} else if (use_macbundle) {
- this->SetError("may not be given MACOSX_BUNDLE for an IMPORTED target.");
+ status.SetError(
+ "may not be given MACOSX_BUNDLE for an IMPORTED target.");
} else // if(excludeFromAll)
{
- this->SetError(
+ status.SetError(
"may not be given EXCLUDE_FROM_ALL for an IMPORTED target.");
}
return false;
}
if (isAlias) {
if (!cmGeneratorExpression::IsValidTargetName(exename)) {
- this->SetError("Invalid name for ALIAS: " + exename);
+ status.SetError("Invalid name for ALIAS: " + exename);
return false;
}
if (excludeFromAll) {
- this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+ status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
return false;
}
if (importTarget || importGlobal) {
- this->SetError("IMPORTED with ALIAS is not allowed.");
+ status.SetError("IMPORTED with ALIAS is not allowed.");
return false;
}
if (args.size() != 3) {
std::ostringstream e;
e << "ALIAS requires exactly one target argument.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
std::string const& aliasedName = *s;
- if (this->Makefile->IsAlias(aliasedName)) {
+ if (mf.IsAlias(aliasedName)) {
std::ostringstream e;
e << "cannot create ALIAS target \"" << exename << "\" because target \""
<< aliasedName << "\" is itself an ALIAS.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- cmTarget* aliasedTarget =
- this->Makefile->FindTargetToUse(aliasedName, true);
+ cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
if (!aliasedTarget) {
std::ostringstream e;
e << "cannot create ALIAS target \"" << exename << "\" because target \""
<< aliasedName << "\" does not already exist.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
cmStateEnums::TargetType type = aliasedTarget->GetType();
@@ -121,7 +120,7 @@
std::ostringstream e;
e << "cannot create ALIAS target \"" << exename << "\" because target \""
<< aliasedName << "\" is not an executable.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
if (aliasedTarget->IsImported() &&
@@ -129,42 +128,40 @@
std::ostringstream e;
e << "cannot create ALIAS target \"" << exename << "\" because target \""
<< aliasedName << "\" is imported but not globally visible.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- this->Makefile->AddAlias(exename, aliasedName);
+ mf.AddAlias(exename, aliasedName);
return true;
}
// Handle imported target creation.
if (importTarget) {
// Make sure the target does not already exist.
- if (this->Makefile->FindTargetToUse(exename)) {
+ if (mf.FindTargetToUse(exename)) {
std::ostringstream e;
e << "cannot create imported target \"" << exename
<< "\" because another target with the same name already exists.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
// Create the imported target.
- this->Makefile->AddImportedTarget(exename, cmStateEnums::EXECUTABLE,
- importGlobal);
+ mf.AddImportedTarget(exename, cmStateEnums::EXECUTABLE, importGlobal);
return true;
}
// Enforce name uniqueness.
{
std::string msg;
- if (!this->Makefile->EnforceUniqueName(exename, msg)) {
- this->SetError(msg);
+ if (!mf.EnforceUniqueName(exename, msg)) {
+ status.SetError(msg);
return false;
}
}
std::vector<std::string> srclists(s, args.end());
- cmTarget* tgt =
- this->Makefile->AddExecutable(exename, srclists, excludeFromAll);
+ cmTarget* tgt = mf.AddExecutable(exename, srclists, excludeFromAll);
if (use_win32) {
tgt->SetProperty("WIN32_EXECUTABLE", "ON");
}
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
index ec57c3f..f7bc273 100644
--- a/Source/cmAddExecutableCommand.h
+++ b/Source/cmAddExecutableCommand.h
@@ -8,35 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmExecutablesCommand
- * \brief Defines a list of executables to build.
- *
- * cmExecutablesCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmAddExecutableCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddExecutableCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddExecutableCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index ad12e89..626b7c9 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -5,6 +5,7 @@
#include <sstream>
#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -14,21 +15,19 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
-class cmExecutionStatus;
-
-// cmLibraryCommand
-bool cmAddLibraryCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddLibraryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+
+ cmMakefile& mf = status.GetMakefile();
// Library type defaults to value of BUILD_SHARED_LIBS, if it exists,
// otherwise it defaults to static library.
cmStateEnums::TargetType type = cmStateEnums::SHARED_LIBRARY;
- if (cmSystemTools::IsOff(
- this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
+ if (cmSystemTools::IsOff(mf.GetDefinition("BUILD_SHARED_LIBS"))) {
type = cmStateEnums::STATIC_LIBRARY;
}
bool excludeFromAll = false;
@@ -52,7 +51,7 @@
if (type == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting STATIC type.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -62,7 +61,7 @@
if (type == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting SHARED type.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -72,7 +71,7 @@
if (type == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting MODULE type.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -82,7 +81,7 @@
if (type == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting OBJECT type.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -92,7 +91,7 @@
if (type == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting UNKNOWN type.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -102,7 +101,7 @@
if (type == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting ALIAS type.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -111,19 +110,19 @@
if (haveSpecifiedType) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting/multiple types.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
if (isAlias) {
std::ostringstream e;
e << "INTERFACE library specified with conflicting ALIAS type.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
if (excludeFromAll) {
std::ostringstream e;
e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -133,7 +132,7 @@
if (type == cmStateEnums::INTERFACE_LIBRARY) {
std::ostringstream e;
e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
++s;
@@ -147,7 +146,7 @@
} else if (type == cmStateEnums::INTERFACE_LIBRARY && *s == "GLOBAL") {
std::ostringstream e;
e << "GLOBAL option may only be used with IMPORTED libraries.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
} else {
break;
@@ -158,13 +157,13 @@
if (s != args.end()) {
std::ostringstream e;
e << "INTERFACE library requires no source arguments.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
if (importGlobal && !importTarget) {
std::ostringstream e;
e << "INTERFACE library specified as GLOBAL, but not as IMPORTED.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
@@ -175,47 +174,46 @@
if (nameOk && !importTarget && !isAlias) {
nameOk = libName.find(':') == std::string::npos;
}
- if (!nameOk && !this->Makefile->CheckCMP0037(libName, type)) {
+ if (!nameOk && !mf.CheckCMP0037(libName, type)) {
return false;
}
if (isAlias) {
if (!cmGeneratorExpression::IsValidTargetName(libName)) {
- this->SetError("Invalid name for ALIAS: " + libName);
+ status.SetError("Invalid name for ALIAS: " + libName);
return false;
}
if (excludeFromAll) {
- this->SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
+ status.SetError("EXCLUDE_FROM_ALL with ALIAS makes no sense.");
return false;
}
if (importTarget || importGlobal) {
- this->SetError("IMPORTED with ALIAS is not allowed.");
+ status.SetError("IMPORTED with ALIAS is not allowed.");
return false;
}
if (args.size() != 3) {
std::ostringstream e;
e << "ALIAS requires exactly one target argument.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
std::string const& aliasedName = *s;
- if (this->Makefile->IsAlias(aliasedName)) {
+ if (mf.IsAlias(aliasedName)) {
std::ostringstream e;
e << "cannot create ALIAS target \"" << libName << "\" because target \""
<< aliasedName << "\" is itself an ALIAS.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- cmTarget* aliasedTarget =
- this->Makefile->FindTargetToUse(aliasedName, true);
+ cmTarget* aliasedTarget = mf.FindTargetToUse(aliasedName, true);
if (!aliasedTarget) {
std::ostringstream e;
e << "cannot create ALIAS target \"" << libName << "\" because target \""
<< aliasedName
<< "\" does not already "
"exist.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
cmStateEnums::TargetType aliasedType = aliasedTarget->GetType();
@@ -229,7 +227,7 @@
std::ostringstream e;
e << "cannot create ALIAS target \"" << libName << "\" because target \""
<< aliasedName << "\" is not a library.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
if (aliasedTarget->IsImported() &&
@@ -237,15 +235,15 @@
std::ostringstream e;
e << "cannot create ALIAS target \"" << libName << "\" because target \""
<< aliasedName << "\" is imported but not globally visible.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- this->Makefile->AddAlias(libName, aliasedName);
+ mf.AddAlias(libName, aliasedName);
return true;
}
if (importTarget && excludeFromAll) {
- this->SetError("excludeFromAll with IMPORTED target makes no sense.");
+ status.SetError("excludeFromAll with IMPORTED target makes no sense.");
return false;
}
@@ -255,14 +253,13 @@
yet its linker language. */
if ((type == cmStateEnums::SHARED_LIBRARY ||
type == cmStateEnums::MODULE_LIBRARY) &&
- !this->Makefile->GetState()->GetGlobalPropertyAsBool(
- "TARGET_SUPPORTS_SHARED_LIBS")) {
+ !mf.GetState()->GetGlobalPropertyAsBool("TARGET_SUPPORTS_SHARED_LIBS")) {
std::ostringstream w;
w << "ADD_LIBRARY called with "
<< (type == cmStateEnums::SHARED_LIBRARY ? "SHARED" : "MODULE")
<< " option but the target platform does not support dynamic linking. "
"Building a STATIC library instead. This may lead to problems.";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, w.str());
type = cmStateEnums::STATIC_LIBRARY;
}
@@ -270,14 +267,13 @@
if (importTarget) {
// The IMPORTED signature requires a type to be specified explicitly.
if (!haveSpecifiedType) {
- this->SetError("called with IMPORTED argument but no library type.");
+ status.SetError("called with IMPORTED argument but no library type.");
return false;
}
if (type == cmStateEnums::OBJECT_LIBRARY) {
std::string reason;
- if (!this->Makefile->GetGlobalGenerator()->HasKnownObjectFileLocation(
- &reason)) {
- this->Makefile->IssueMessage(
+ if (!mf.GetGlobalGenerator()->HasKnownObjectFileLocation(&reason)) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The OBJECT library type may not be used for IMPORTED libraries" +
reason + ".");
@@ -288,28 +284,28 @@
if (!cmGeneratorExpression::IsValidTargetName(libName)) {
std::ostringstream e;
e << "Invalid name for IMPORTED INTERFACE library target: " << libName;
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
// Make sure the target does not already exist.
- if (this->Makefile->FindTargetToUse(libName)) {
+ if (mf.FindTargetToUse(libName)) {
std::ostringstream e;
e << "cannot create imported target \"" << libName
<< "\" because another target with the same name already exists.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
// Create the imported target.
- this->Makefile->AddImportedTarget(libName, type, importGlobal);
+ mf.AddImportedTarget(libName, type, importGlobal);
return true;
}
// A non-imported target may not have UNKNOWN type.
if (type == cmStateEnums::UNKNOWN_LIBRARY) {
- this->Makefile->IssueMessage(
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The UNKNOWN library type may be used only for IMPORTED libraries.");
return true;
@@ -318,8 +314,8 @@
// Enforce name uniqueness.
{
std::string msg;
- if (!this->Makefile->EnforceUniqueName(libName, msg)) {
- this->SetError(msg);
+ if (!mf.EnforceUniqueName(libName, msg)) {
+ status.SetError(msg);
return false;
}
}
@@ -331,17 +327,17 @@
libName.find("::") != std::string::npos) {
std::ostringstream e;
e << "Invalid name for INTERFACE library target: " << libName;
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
+ mf.AddLibrary(libName, type, srclists, excludeFromAll);
return true;
}
cmAppend(srclists, s, args.end());
- this->Makefile->AddLibrary(libName, type, srclists, excludeFromAll);
+ mf.AddLibrary(libName, type, srclists, excludeFromAll);
return true;
}
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index 56dab41..609449c 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -8,35 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmLibrarysCommand
- * \brief Defines a list of executables to build.
- *
- * cmLibrarysCommand defines a list of executable (i.e., test)
- * programs to create.
- */
-class cmAddLibraryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddLibraryCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddLibraryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddLinkOptionsCommand.cxx b/Source/cmAddLinkOptionsCommand.cxx
index 10ebd12..7ed31bd 100644
--- a/Source/cmAddLinkOptionsCommand.cxx
+++ b/Source/cmAddLinkOptionsCommand.cxx
@@ -2,19 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddLinkOptionsCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-class cmExecutionStatus;
-
-bool cmAddLinkOptionsCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddLinkOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (args.empty()) {
- return true;
- }
-
+ cmMakefile& mf = status.GetMakefile();
for (std::string const& i : args) {
- this->Makefile->AddLinkOption(i);
+ mf.AddLinkOption(i);
}
return true;
}
diff --git a/Source/cmAddLinkOptionsCommand.h b/Source/cmAddLinkOptionsCommand.h
index 8e46be6..466fc32 100644
--- a/Source/cmAddLinkOptionsCommand.h
+++ b/Source/cmAddLinkOptionsCommand.h
@@ -8,29 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-class cmAddLinkOptionsCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddLinkOptionsCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddLinkOptionsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 7947188..50c682f 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -5,21 +5,20 @@
#include <sstream>
#include <string.h>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSystemTools.h"
-class cmExecutionStatus;
-
-// cmAddSubDirectoryCommand
-bool cmAddSubDirectoryCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.empty()) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
// store the binpath
std::string const& srcArg = args.front();
std::string binArg;
@@ -35,7 +34,7 @@
if (binArg.empty()) {
binArg = arg;
} else {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
}
@@ -46,7 +45,7 @@
if (cmSystemTools::FileIsFullPath(srcArg)) {
srcPath = srcArg;
} else {
- srcPath = this->Makefile->GetCurrentSourceDirectory();
+ srcPath = mf.GetCurrentSourceDirectory();
srcPath += "/";
srcPath += srcArg;
}
@@ -54,7 +53,7 @@
std::string error = "given source \"";
error += srcArg;
error += "\" which is not an existing directory.";
- this->SetError(error);
+ status.SetError(error);
return false;
}
srcPath = cmSystemTools::CollapseFullPath(srcPath);
@@ -65,22 +64,22 @@
// No binary directory was specified. If the source directory is
// not a subdirectory of the current directory then it is an
// error.
- if (!cmSystemTools::IsSubDirectory(
- srcPath, this->Makefile->GetCurrentSourceDirectory())) {
+ if (!cmSystemTools::IsSubDirectory(srcPath,
+ mf.GetCurrentSourceDirectory())) {
std::ostringstream e;
e << "not given a binary directory but the given source directory "
<< "\"" << srcPath << "\" is not a subdirectory of \""
- << this->Makefile->GetCurrentSourceDirectory() << "\". "
+ << mf.GetCurrentSourceDirectory() << "\". "
<< "When specifying an out-of-tree source a binary directory "
<< "must be explicitly specified.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
// Remove the CurrentDirectory from the srcPath and replace it
// with the CurrentOutputDirectory.
- const std::string& src = this->Makefile->GetCurrentSourceDirectory();
- const std::string& bin = this->Makefile->GetCurrentBinaryDirectory();
+ const std::string& src = mf.GetCurrentSourceDirectory();
+ const std::string& bin = mf.GetCurrentBinaryDirectory();
size_t srcLen = src.length();
size_t binLen = bin.length();
if (srcLen > 0 && src.back() == '/') {
@@ -96,7 +95,7 @@
if (cmSystemTools::FileIsFullPath(binArg)) {
binPath = binArg;
} else {
- binPath = this->Makefile->GetCurrentBinaryDirectory();
+ binPath = mf.GetCurrentBinaryDirectory();
binPath += "/";
binPath += binArg;
}
@@ -104,7 +103,7 @@
binPath = cmSystemTools::CollapseFullPath(binPath);
// Add the subdirectory using the computed full paths.
- this->Makefile->AddSubDirectory(srcPath, binPath, excludeFromAll, true);
+ mf.AddSubDirectory(srcPath, binPath, excludeFromAll, true);
return true;
}
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index 664334e..87da840 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -8,36 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddSubDirectoryCommand
- * \brief Specify a subdirectory to build
- *
- * cmAddSubDirectoryCommand specifies a subdirectory to process
- * by CMake. CMake will descend
- * into the specified source directory and process any CMakeLists.txt found.
- */
-class cmAddSubDirectoryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddSubDirectoryCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index b0c462b..7904bf5 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -4,34 +4,36 @@
#include <sstream>
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmTest.h"
#include "cmTestGenerator.h"
-class cmExecutionStatus;
+static bool cmAddTestCommandHandleNameMode(
+ std::vector<std::string> const& args, cmExecutionStatus& status);
-// cmExecutableCommand
-bool cmAddTestCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
+bool cmAddTestCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (!args.empty() && args[0] == "NAME") {
- return this->HandleNameMode(args);
+ return cmAddTestCommandHandleNameMode(args, status);
}
// First argument is the name of the test Second argument is the name of
// the executable to run (a target or external program) Remaining arguments
// are the arguments to pass to the executable
if (args.size() < 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
// Collect the command with arguments.
std::vector<std::string> command(args.begin() + 1, args.end());
// Create the test but add a generator only the first time it is
// seen. This preserves behavior from before test generators.
- cmTest* test = this->Makefile->GetTest(args[0]);
+ cmTest* test = mf.GetTest(args[0]);
if (test) {
// If the test was already added by a new-style signature do not
// allow it to be duplicated.
@@ -39,20 +41,21 @@
std::ostringstream e;
e << " given test name \"" << args[0]
<< "\" which already exists in this directory.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
} else {
- test = this->Makefile->CreateTest(args[0]);
+ test = mf.CreateTest(args[0]);
test->SetOldStyle(true);
- this->Makefile->AddTestGenerator(new cmTestGenerator(test));
+ mf.AddTestGenerator(new cmTestGenerator(test));
}
test->SetCommand(command);
return true;
}
-bool cmAddTestCommand::HandleNameMode(std::vector<std::string> const& args)
+bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
std::string name;
std::vector<std::string> configurations;
@@ -73,25 +76,25 @@
for (unsigned int i = 1; i < args.size(); ++i) {
if (args[i] == "COMMAND") {
if (!command.empty()) {
- this->SetError(" may be given at most one COMMAND.");
+ status.SetError(" may be given at most one COMMAND.");
return false;
}
doing = DoingCommand;
} else if (args[i] == "CONFIGURATIONS") {
if (!configurations.empty()) {
- this->SetError(" may be given at most one set of CONFIGURATIONS.");
+ status.SetError(" may be given at most one set of CONFIGURATIONS.");
return false;
}
doing = DoingConfigs;
} else if (args[i] == "WORKING_DIRECTORY") {
if (!working_directory.empty()) {
- this->SetError(" may be given at most one WORKING_DIRECTORY.");
+ status.SetError(" may be given at most one WORKING_DIRECTORY.");
return false;
}
doing = DoingWorkingDirectory;
} else if (args[i] == "COMMAND_EXPAND_LISTS") {
if (command_expand_lists) {
- this->SetError(" may be given at most one COMMAND_EXPAND_LISTS.");
+ status.SetError(" may be given at most one COMMAND_EXPAND_LISTS.");
return false;
}
command_expand_lists = true;
@@ -109,41 +112,43 @@
} else {
std::ostringstream e;
e << " given unknown argument:\n " << args[i] << "\n";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
// Require a test name.
if (name.empty()) {
- this->SetError(" must be given non-empty NAME.");
+ status.SetError(" must be given non-empty NAME.");
return false;
}
// Require a command.
if (command.empty()) {
- this->SetError(" must be given non-empty COMMAND.");
+ status.SetError(" must be given non-empty COMMAND.");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
+
// Require a unique test name within the directory.
- if (this->Makefile->GetTest(name)) {
+ if (mf.GetTest(name)) {
std::ostringstream e;
e << " given test NAME \"" << name
<< "\" which already exists in this directory.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
// Add the test.
- cmTest* test = this->Makefile->CreateTest(name);
+ cmTest* test = mf.CreateTest(name);
test->SetOldStyle(false);
test->SetCommand(command);
if (!working_directory.empty()) {
test->SetProperty("WORKING_DIRECTORY", working_directory.c_str());
}
test->SetCommandExpandLists(command_expand_lists);
- this->Makefile->AddTestGenerator(new cmTestGenerator(test, configurations));
+ mf.AddTestGenerator(new cmTestGenerator(test, configurations));
return true;
}
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
index 3d37d2b..5877547 100644
--- a/Source/cmAddTestCommand.h
+++ b/Source/cmAddTestCommand.h
@@ -8,37 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAddTestCommand
- * \brief Add a test to the lists of tests to run.
- *
- * cmAddTestCommand adds a test to the list of tests to run .
- */
-class cmAddTestCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAddTestCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- bool HandleNameMode(std::vector<std::string> const& args);
-};
+bool cmAddTestCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index cf71052..d7ea483 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -6,41 +6,14 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmRange.h"
-
#include "cm_kwiml.h"
-#include "cm_string_view.hxx"
#include <algorithm>
#include <functional>
#include <iterator>
-#include <sstream>
-#include <string.h>
-#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
-struct cmStrCmp
-{
- cmStrCmp(const char* test)
- : m_test(test)
- {
- }
- cmStrCmp(std::string test)
- : m_test(std::move(test))
- {
- }
-
- bool operator()(const std::string& input) const { return m_test == input; }
-
- bool operator()(const char* input) const
- {
- return strcmp(input, m_test.c_str()) == 0;
- }
-
-private:
- const std::string m_test;
-};
-
template <typename FwdIt>
FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
{
@@ -120,8 +93,6 @@
};
}
-typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange;
-
class cmListFileBacktrace;
typedef cmRange<std::vector<cmListFileBacktrace>::const_iterator>
cmBacktraceRange;
@@ -146,31 +117,6 @@
}
template <typename Range>
-std::string cmJoin(Range const& r, const char* delimiter)
-{
- if (r.empty()) {
- return std::string();
- }
- std::ostringstream os;
- typedef typename Range::value_type ValueType;
- typedef typename Range::const_iterator InputIt;
- const InputIt first = r.begin();
- InputIt last = r.end();
- --last;
- std::copy(first, last, std::ostream_iterator<ValueType>(os, delimiter));
-
- os << *last;
-
- return os.str();
-}
-
-template <typename Range>
-std::string cmJoin(Range const& r, std::string const& delimiter)
-{
- return cmJoin(r, delimiter.c_str());
-}
-
-template <typename Range>
typename Range::const_iterator cmRemoveN(Range& r, size_t n)
{
return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n);
@@ -248,23 +194,6 @@
return cmRemoveDuplicates(r.begin(), r.end());
}
-template <typename Range>
-std::string cmWrap(std::string const& prefix, Range const& r,
- std::string const& suffix, std::string const& sep)
-{
- if (r.empty()) {
- return std::string();
- }
- return prefix + cmJoin(r, suffix + sep + prefix) + suffix;
-}
-
-template <typename Range>
-std::string cmWrap(char prefix, Range const& r, char suffix,
- std::string const& sep)
-{
- return cmWrap(std::string(1, prefix), r, std::string(1, suffix), sep);
-}
-
template <typename Range, typename T>
typename Range::const_iterator cmFindNot(Range const& r, T const& t)
{
@@ -277,61 +206,6 @@
return std::reverse_iterator<Iter>(it);
}
-/** Returns true if string @a str starts with the character @a prefix. **/
-inline bool cmHasPrefix(cm::string_view str, char prefix)
-{
- return !str.empty() && (str.front() == prefix);
-}
-
-/** Returns true if string @a str starts with string @a prefix. **/
-inline bool cmHasPrefix(cm::string_view str, cm::string_view prefix)
-{
- return str.compare(0, prefix.size(), prefix) == 0;
-}
-
-/** Returns true if string @a str starts with string @a prefix. **/
-template <size_t N>
-inline bool cmHasLiteralPrefix(cm::string_view str, const char (&prefix)[N])
-{
- return cmHasPrefix(str, cm::string_view(prefix, N - 1));
-}
-
-/** Returns true if string @a str ends with the character @a suffix. **/
-inline bool cmHasSuffix(cm::string_view str, char suffix)
-{
- return !str.empty() && (str.back() == suffix);
-}
-
-/** Returns true if string @a str ends with string @a suffix. **/
-inline bool cmHasSuffix(cm::string_view str, cm::string_view suffix)
-{
- return str.size() >= suffix.size() &&
- str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
-}
-
-/** Returns true if string @a str ends with string @a suffix. **/
-template <size_t N>
-inline bool cmHasLiteralSuffix(cm::string_view str, const char (&suffix)[N])
-{
- return cmHasSuffix(str, cm::string_view(suffix, N - 1));
-}
-
-/** Removes an existing suffix character of from the string @a str. **/
-inline void cmStripSuffixIfExists(std::string& str, char suffix)
-{
- if (cmHasSuffix(str, suffix)) {
- str.pop_back();
- }
-}
-
-/** Removes an existing suffix string of from the string @a str. **/
-inline void cmStripSuffixIfExists(std::string& str, cm::string_view suffix)
-{
- if (cmHasSuffix(str, suffix)) {
- str.resize(str.size() - suffix.size());
- }
-}
-
namespace cm {
#if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index 9ea88d3..e90a603 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -9,7 +9,7 @@
#include <stddef.h>
#include <string>
-#if !defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(CMAKE_BOOTSTRAP)
# error "cmArchiveWrite not allowed during bootstrap build!"
#endif
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index c1a6e7f..83199b4 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -7,28 +7,27 @@
#include <stddef.h>
#include <utility>
-#include "cmAlgorithms.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
-class cmExecutionStatus;
-
-// cmAuxSourceDirectoryCommand
-bool cmAuxSourceDirectoryCommand::InitialPass(
- std::vector<std::string> const& args, cmExecutionStatus&)
+bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 2) {
- this->SetError("called with incorrect number of arguments");
+ status.SetError("called with incorrect number of arguments");
return false;
}
+ cmMakefile& mf = status.GetMakefile();
std::string sourceListValue;
std::string const& templateDirectory = args[0];
std::string tdir;
if (!cmSystemTools::FileIsFullPath(templateDirectory)) {
- tdir = this->Makefile->GetCurrentSourceDirectory();
+ tdir = mf.GetCurrentSourceDirectory();
tdir += "/";
tdir += templateDirectory;
} else {
@@ -36,7 +35,7 @@
}
// was the list already populated
- const char* def = this->Makefile->GetDefinition(args[1]);
+ const char* def = mf.GetDefinition(args[1]);
if (def) {
sourceListValue = def;
}
@@ -55,14 +54,14 @@
std::string ext = file.substr(dotpos + 1);
std::string base = file.substr(0, dotpos);
// Process only source files
- auto cm = this->Makefile->GetCMakeInstance();
+ auto cm = mf.GetCMakeInstance();
if (!base.empty() && cm->IsSourceExtension(ext)) {
std::string fullname = templateDirectory;
fullname += "/";
fullname += file;
// add the file as a class file so
// depends can be done
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(fullname);
+ cmSourceFile* sf = mf.GetOrCreateSource(fullname);
sf->SetProperty("ABSTRACT", "0");
files.push_back(std::move(fullname));
}
@@ -74,6 +73,6 @@
sourceListValue += ";";
}
sourceListValue += cmJoin(files, ";");
- this->Makefile->AddDefinition(args[1], sourceListValue);
+ mf.AddDefinition(args[1], sourceListValue);
return true;
}
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
index 973a464..ae26092 100644
--- a/Source/cmAuxSourceDirectoryCommand.h
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -8,38 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmAuxSourceDirectoryCommand
- * \brief Specify auxiliary source code directories.
- *
- * cmAuxSourceDirectoryCommand specifies source code directories
- * that must be built as part of this build process. This directories
- * are not recursively processed like the SUBDIR command (cmSubdirCommand).
- * A side effect of this command is to create a subdirectory in the build
- * directory structure.
- */
-class cmAuxSourceDirectoryCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmAuxSourceDirectoryCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index 86846cb..6316a29 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -8,6 +8,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include <cmsys/RegularExpression.hxx>
@@ -151,7 +152,7 @@
std::string& path, bool& resolved)
{
for (auto const& searchPath : searchPaths) {
- path = searchPath + '/' + name;
+ path = cmStrCat(searchPath, '/', name);
if (cmSystemTools::PathExists(path)) {
resolved = true;
return true;
@@ -159,7 +160,7 @@
}
for (auto const& searchPath : this->Archive->GetSearchDirectories()) {
- path = searchPath + '/' + name;
+ path = cmStrCat(searchPath, '/', name);
if (cmSystemTools::PathExists(path)) {
std::ostringstream warning;
warning << "Dependency " << name << " found in search directory:\n "
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index ac93155..0c73ac8 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -3,9 +3,9 @@
#include "cmBinUtilsMacOSMachOLinker.h"
-#include "cmAlgorithms.h"
#include "cmBinUtilsMacOSMachOOToolGetRuntimeDependenciesTool.h"
#include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include <sstream>
diff --git a/Source/cmBinUtilsWindowsPELinker.cxx b/Source/cmBinUtilsWindowsPELinker.cxx
index 31602c4..5a9ad66 100644
--- a/Source/cmBinUtilsWindowsPELinker.cxx
+++ b/Source/cmBinUtilsWindowsPELinker.cxx
@@ -6,6 +6,7 @@
#include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h"
#include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h"
#include "cmRuntimeDependencyArchive.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include <sstream>
@@ -110,7 +111,7 @@
dirs.insert(dirs.begin(), origin);
for (auto const& searchPath : dirs) {
- path = searchPath + '/' + name;
+ path = cmStrCat(searchPath, '/', name);
if (cmSystemTools::PathExists(path)) {
resolved = true;
return true;
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 83e3eff..c0ca73b 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -52,6 +52,7 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmVersionConfig.h"
@@ -1964,7 +1965,7 @@
if (this->CheckArgument(arg, "-N", "--show-only")) {
this->Impl->ShowOnly = true;
}
- if (cmSystemTools::StringStartsWith(arg.c_str(), "--show-only=")) {
+ if (cmHasLiteralPrefix(arg, "--show-only=")) {
this->Impl->ShowOnly = true;
// Check if a specific format is requested. Defaults to human readable
@@ -2226,7 +2227,7 @@
// attempts are simply ignored since previous ctest versions ignore
// this too. (As well as many other unknown command line args.)
//
- if (arg != "-D" && cmSystemTools::StringStartsWith(arg.c_str(), "-D")) {
+ if (arg != "-D" && cmHasLiteralPrefix(arg, "-D")) {
std::string input = arg.substr(2);
this->AddVariableDefinition(input);
}
@@ -2422,7 +2423,7 @@
cmCTestBuildAndTestHandler* handler = this->GetBuildAndTestHandler();
int retv = handler->ProcessHandler();
*output = handler->GetOutput();
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmDynamicLoader::FlushCache();
#endif
if (retv != 0) {
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index f7a2244..9e152ff 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -4,6 +4,7 @@
#include <sstream>
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#if defined(_MSC_VER)
@@ -328,8 +329,7 @@
if (SUCCEEDED(hr)) {
std::map<std::string, IUnknownPtr>::iterator it;
for (it = mrot.begin(); it != mrot.end(); ++it) {
- if (cmSystemTools::StringStartsWith(it->first.c_str(),
- "!VisualStudio.DTE.")) {
+ if (cmHasLiteralPrefix(it->first, "!VisualStudio.DTE.")) {
IDispatchPtr disp(it->second);
if (disp != (IDispatch*)0) {
std::string slnName;
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index ca29967..5583520 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -5,6 +5,7 @@
#include "cmCommandArgumentLexer.h"
#include "cmMakefile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include <iostream>
@@ -58,7 +59,7 @@
std::string str;
if (cmSystemTools::GetEnv(var, str)) {
if (this->EscapeQuotes) {
- return this->AddString(cmSystemTools::EscapeQuotes(str));
+ return this->AddString(cmEscapeQuotes(str));
}
return this->AddString(str);
}
@@ -68,7 +69,7 @@
if (const std::string* c =
this->Makefile->GetState()->GetInitializedCacheValue(var)) {
if (this->EscapeQuotes) {
- return this->AddString(cmSystemTools::EscapeQuotes(*c));
+ return this->AddString(cmEscapeQuotes(*c));
}
return this->AddString(*c);
}
@@ -99,7 +100,7 @@
}
}
if (this->EscapeQuotes && value) {
- return this->AddString(cmSystemTools::EscapeQuotes(value));
+ return this->AddString(cmEscapeQuotes(value));
}
return this->AddString(value ? value : "");
}
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index f351ff8..8565e1c 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -84,7 +84,7 @@
#include "cmUnsetCommand.h"
#include "cmWhileCommand.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmAddCompileOptionsCommand.h"
# include "cmAddLinkOptionsCommand.h"
# include "cmAuxSourceDirectoryCommand.h"
@@ -128,7 +128,7 @@
cm::make_unique<cmExecProgramCommand>());
state->AddBuiltinCommand("execute_process",
cm::make_unique<cmExecuteProcessCommand>());
- state->AddBuiltinCommand("file", cm::make_unique<cmFileCommand>());
+ state->AddBuiltinCommand("file", cmFileCommand);
state->AddBuiltinCommand("find_file", cm::make_unique<cmFindFileCommand>());
state->AddBuiltinCommand("find_library",
cm::make_unique<cmFindLibraryCommand>());
@@ -210,7 +210,7 @@
"WHILE ENDWHILE structure. Or its arguments did not "
"match the opening WHILE command.");
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand(
"cmake_host_system_information",
cm::make_unique<cmCMakeHostSystemInformationCommand>());
@@ -233,21 +233,14 @@
void GetProjectCommands(cmState* state)
{
- state->AddBuiltinCommand("add_custom_command",
- cm::make_unique<cmAddCustomCommandCommand>());
- state->AddBuiltinCommand("add_custom_target",
- cm::make_unique<cmAddCustomTargetCommand>());
- state->AddBuiltinCommand("add_definitions",
- cm::make_unique<cmAddDefinitionsCommand>());
- state->AddBuiltinCommand("add_dependencies",
- cm::make_unique<cmAddDependenciesCommand>());
- state->AddBuiltinCommand("add_executable",
- cm::make_unique<cmAddExecutableCommand>());
- state->AddBuiltinCommand("add_library",
- cm::make_unique<cmAddLibraryCommand>());
- state->AddBuiltinCommand("add_subdirectory",
- cm::make_unique<cmAddSubDirectoryCommand>());
- state->AddBuiltinCommand("add_test", cm::make_unique<cmAddTestCommand>());
+ state->AddBuiltinCommand("add_custom_command", cmAddCustomCommandCommand);
+ state->AddBuiltinCommand("add_custom_target", cmAddCustomTargetCommand);
+ state->AddBuiltinCommand("add_definitions", cmAddDefinitionsCommand);
+ state->AddBuiltinCommand("add_dependencies", cmAddDependenciesCommand);
+ state->AddBuiltinCommand("add_executable", cmAddExecutableCommand);
+ state->AddBuiltinCommand("add_library", cmAddLibraryCommand);
+ state->AddBuiltinCommand("add_subdirectory", cmAddSubDirectoryCommand);
+ state->AddBuiltinCommand("add_test", cmAddTestCommand);
state->AddBuiltinCommand("build_command", cm::make_unique<cmBuildCommand>());
state->AddBuiltinCommand("create_test_sourcelist",
cm::make_unique<cmCreateTestSourceList>());
@@ -301,13 +294,12 @@
cm::make_unique<cmTryCompileCommand>());
state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>());
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand("add_compile_definitions",
- cm::make_unique<cmAddCompileDefinitionsCommand>());
- state->AddBuiltinCommand("add_compile_options",
- cm::make_unique<cmAddCompileOptionsCommand>());
+ cmAddCompileDefinitionsCommand);
+ state->AddBuiltinCommand("add_compile_options", cmAddCompileOptionsCommand);
state->AddBuiltinCommand("aux_source_directory",
- cm::make_unique<cmAuxSourceDirectoryCommand>());
+ cmAuxSourceDirectoryCommand);
state->AddBuiltinCommand("export", cm::make_unique<cmExportCommand>());
state->AddBuiltinCommand("fltk_wrap_ui",
cm::make_unique<cmFLTKWrapUICommand>());
@@ -316,8 +308,7 @@
cm::make_unique<cmIncludeExternalMSProjectCommand>());
state->AddBuiltinCommand("install_programs",
cm::make_unique<cmInstallProgramsCommand>());
- state->AddBuiltinCommand("add_link_options",
- cm::make_unique<cmAddLinkOptionsCommand>());
+ state->AddBuiltinCommand("add_link_options", cmAddLinkOptionsCommand);
state->AddBuiltinCommand("link_libraries",
cm::make_unique<cmLinkLibrariesCommand>());
state->AddBuiltinCommand("target_link_options",
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 66250f3..61880c2 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -6,7 +6,6 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
@@ -17,6 +16,7 @@
#include "cmOutputConverter.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
: GeneratorTarget(gt)
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 54fc54c..f8b78b4 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -11,6 +11,7 @@
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index f696f28..4aa18f2 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmComputeLinkInformation.h"
-#include "cmAlgorithms.h"
#include "cmComputeLinkDepends.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -14,6 +13,7 @@
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -990,11 +990,6 @@
return;
}
- // If this platform wants a flag before the full path, add it.
- if (!this->LibLinkFileFlag.empty()) {
- this->Items.emplace_back(this->LibLinkFileFlag, false);
- }
-
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
@@ -1057,11 +1052,6 @@
this->OldLinkDirItems.push_back(item);
}
- // If this platform wants a flag before the full path, add it.
- if (!this->LibLinkFileFlag.empty()) {
- this->Items.emplace_back(this->LibLinkFileFlag, false);
- }
-
// Now add the full path to the library.
this->Items.emplace_back(item, true);
}
@@ -1764,7 +1754,7 @@
cmSystemTools::IsSubDirectory(d, topBinaryDir)) {
d = cmSystemTools::RelativePath(targetOutputDir, d);
if (!d.empty()) {
- d = originToken + "/" + d;
+ d = cmStrCat(originToken, "/", d);
} else {
d = originToken;
}
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 3be2c7f..784d3fa 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -56,6 +56,11 @@
std::string GetChrpathString() const;
std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
+ std::string const& GetLibLinkFileFlag() const
+ {
+ return this->LibLinkFileFlag;
+ }
+
std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
std::string GetRPathLinkString() const;
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 2907f4a..5b88807 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -15,6 +15,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index d780af6..85ff0a6 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -9,7 +9,6 @@
#include <string.h>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -17,6 +16,7 @@
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmVersion.h"
@@ -238,7 +238,7 @@
} else if (doing == DoingLinkOptions) {
linkOptions.push_back(argv[i]);
} else if (doing == DoingLinkLibraries) {
- libsToLink += "\"" + cmSystemTools::TrimWhitespace(argv[i]) + "\" ";
+ libsToLink += "\"" + cmTrimWhitespace(argv[i]) + "\" ";
if (cmTarget* tgt = this->Makefile->FindTargetToUse(argv[i])) {
switch (tgt->GetType()) {
case cmStateEnums::SHARED_LIBRARY:
@@ -514,7 +514,7 @@
for (std::string const& li : testLangs) {
projectLangs += " " + li;
std::string rulesOverrideBase = "CMAKE_USER_MAKE_RULES_OVERRIDE";
- std::string rulesOverrideLang = rulesOverrideBase + "_" + li;
+ std::string rulesOverrideLang = cmStrCat(rulesOverrideBase, "_", li);
if (const char* rulesOverridePath =
this->Makefile->GetDefinition(rulesOverrideLang)) {
fprintf(fout, "set(%s \"%s\")\n", rulesOverrideLang.c_str(),
@@ -574,7 +574,8 @@
std::string const cfg =
!tcConfig.empty() ? cmSystemTools::UpperCase(tcConfig) : cfgDefault;
for (std::string const& li : testLangs) {
- std::string const langFlagsCfg = "CMAKE_" + li + "_FLAGS_" + cfg;
+ std::string const langFlagsCfg =
+ cmStrCat("CMAKE_", li, "_FLAGS_", cfg);
const char* flagsCfg = this->Makefile->GetDefinition(langFlagsCfg);
fprintf(fout, "set(%s %s)\n", langFlagsCfg.c_str(),
cmOutputConverter::EscapeForCMake(flagsCfg ? flagsCfg : "")
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 42e70d6..cc38d84 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -2,8 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDefinitions.h"
+#include "cm_string_view.hxx"
+
#include <assert.h>
-#include <set>
+#include <functional>
+#include <unordered_set>
#include <utility>
cmDefinitions::Def cmDefinitions::NoDef;
@@ -14,7 +17,7 @@
{
assert(begin != end);
{
- MapType::iterator it = begin->Map.find(key);
+ auto it = begin->Map.find(key);
if (it != begin->Map.end()) {
it->second.Used = true;
return it->second;
@@ -56,6 +59,46 @@
return false;
}
+cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end)
+{
+ cmDefinitions closure;
+ std::unordered_set<cm::string_view> undefined;
+ for (StackIter it = begin; it != end; ++it) {
+ // Consider local definitions.
+ for (auto const& mi : it->Map) {
+ // Use this key if it is not already set or unset.
+ if (closure.Map.find(mi.first) == closure.Map.end() &&
+ undefined.find(mi.first) == undefined.end()) {
+ if (mi.second.Exists) {
+ closure.Map.insert(mi);
+ } else {
+ undefined.emplace(mi.first);
+ }
+ }
+ }
+ }
+ return closure;
+}
+
+std::vector<std::string> cmDefinitions::ClosureKeys(StackIter begin,
+ StackIter end)
+{
+ std::vector<std::string> defined;
+ std::unordered_set<cm::string_view> bound;
+
+ for (StackIter it = begin; it != end; ++it) {
+ defined.reserve(defined.size() + it->Map.size());
+ for (auto const& mi : it->Map) {
+ // Use this key if it is not already set or unset.
+ if (bound.emplace(mi.first).second && mi.second.Exists) {
+ defined.push_back(mi.first);
+ }
+ }
+ }
+
+ return defined;
+}
+
void cmDefinitions::Set(const std::string& key, cm::string_view value)
{
this->Map[key] = Def(value);
@@ -78,43 +121,3 @@
}
return keys;
}
-
-cmDefinitions cmDefinitions::MakeClosure(StackIter begin, StackIter end)
-{
- cmDefinitions closure;
- std::set<std::string> undefined;
- for (StackIter it = begin; it != end; ++it) {
- // Consider local definitions.
- for (auto const& mi : it->Map) {
- // Use this key if it is not already set or unset.
- if (closure.Map.find(mi.first) == closure.Map.end() &&
- undefined.find(mi.first) == undefined.end()) {
- if (mi.second.Exists) {
- closure.Map.insert(mi);
- } else {
- undefined.insert(mi.first);
- }
- }
- }
- }
- return closure;
-}
-
-std::vector<std::string> cmDefinitions::ClosureKeys(StackIter begin,
- StackIter end)
-{
- std::vector<std::string> defined;
- std::set<std::string> bound;
-
- for (StackIter it = begin; it != end; ++it) {
- defined.reserve(defined.size() + it->Map.size());
- for (auto const& mi : it->Map) {
- // Use this key if it is not already set or unset.
- if (bound.insert(mi.first).second && mi.second.Exists) {
- defined.push_back(mi.first);
- }
- }
- }
-
- return defined;
-}
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 4d8810a..787471a 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -25,6 +25,8 @@
typedef cmLinkedTree<cmDefinitions>::iterator StackIter;
public:
+ // -- Static member functions
+
static const std::string* Get(const std::string& key, StackIter begin,
StackIter end);
@@ -32,18 +34,21 @@
static bool HasKey(const std::string& key, StackIter begin, StackIter end);
+ static std::vector<std::string> ClosureKeys(StackIter begin, StackIter end);
+
+ static cmDefinitions MakeClosure(StackIter begin, StackIter end);
+
+ // -- Member functions
+
/** Set a value associated with a key. */
void Set(const std::string& key, cm::string_view value);
/** Unset a definition. */
void Unset(const std::string& key);
+ /** List of unused keys. */
std::vector<std::string> UnusedKeys() const;
- static std::vector<std::string> ClosureKeys(StackIter begin, StackIter end);
-
- static cmDefinitions MakeClosure(StackIter begin, StackIter end);
-
private:
/** String with existence boolean. */
struct Def
@@ -61,8 +66,7 @@
};
static Def NoDef;
- typedef std::unordered_map<std::string, Def> MapType;
- MapType Map;
+ std::unordered_map<std::string, Def> Map;
static Def const& GetInternal(const std::string& key, StackIter begin,
StackIter end, bool raise);
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 178e18b..764ba30 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -9,7 +9,6 @@
#include <stdlib.h>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
#include "cmLocalGenerator.h"
@@ -17,6 +16,7 @@
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
// TODO: Test compiler for the case of the mod file. Some always
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 8d91f43..465f4b3 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -16,6 +16,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index bcacc2f..654922c 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -22,15 +22,6 @@
{
}
- void Clear()
- {
- this->Error = "unknown error.";
- this->ReturnInvoked = false;
- this->BreakInvoked = false;
- this->ContinueInvoked = false;
- this->NestedError = false;
- }
-
cmMakefile& GetMakefile() { return this->Makefile; }
void SetError(std::string const& e) { this->Error = e; }
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index e693155..5edf7ca 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -6,13 +6,13 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index de3e0e2..33806f2 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportBuildFileGenerator.h"
-#include "cmAlgorithms.h"
#include "cmExportSet.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -12,6 +11,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
#include "cmake.h"
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 29afc9f..87f9b4c 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportFileGenerator.h"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -14,6 +13,7 @@
#include "cmPolicies.h"
#include "cmPropertyMap.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
@@ -1209,8 +1209,8 @@
targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) {
for (auto& prop : cmSystemTools::ExpandedListArgument(exportProperties)) {
/* Black list reserved properties */
- if (cmSystemTools::StringStartsWith(prop, "IMPORTED_") ||
- cmSystemTools::StringStartsWith(prop, "INTERFACE_")) {
+ if (cmHasLiteralPrefix(prop, "IMPORTED_") ||
+ cmHasLiteralPrefix(prop, "INTERFACE_")) {
std::ostringstream e;
e << "Target \"" << gte->Target->GetName() << "\" contains property \""
<< prop << "\" in EXPORT_PROPERTIES but IMPORTED_* and INTERFACE_* "
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index f8bc0ab..4bc2d1b 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmExportInstallFileGenerator.h"
-#include "cmAlgorithms.h"
#include "cmExportSet.h"
#include "cmExportSetMap.h"
#include "cmGeneratedFileStream.h"
@@ -15,6 +14,7 @@
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
@@ -412,7 +412,7 @@
std::vector<std::string> objects;
itgen->GetInstallObjectNames(config, objects);
for (std::string& obj : objects) {
- obj = value + obj;
+ obj = cmStrCat(value, obj);
}
// Store the property.
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index f47744b..4146db8 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -178,18 +179,18 @@
{
for (std::string const& f : files) {
xml.StartElement("Unit");
- xml.Attribute("filename", fsPath + path + "/" + f);
+ xml.Attribute("filename", cmStrCat(fsPath, path, "/", f));
xml.StartElement("Option");
xml.Attribute("virtualFolder",
- "CMake Files\\" + virtualFolderPath + path + "\\");
+ cmStrCat("CMake Files\\", virtualFolderPath, path, "\\"));
xml.EndElement();
xml.EndElement();
}
for (Tree const& folder : folders) {
- folder.BuildUnitImpl(xml, virtualFolderPath + path + "\\",
- fsPath + path + "/");
+ folder.BuildUnitImpl(xml, cmStrCat(virtualFolderPath, path, "\\"),
+ cmStrCat(fsPath, path, "/"));
}
}
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index 30b3f0d..70e9a36 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -9,6 +9,7 @@
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLWriter.h"
#include "cmake.h"
@@ -121,7 +122,7 @@
cmStateEnums::TargetType type = lt->GetType();
std::string const& outputDir = lg->GetCurrentBinaryDirectory();
std::string targetName = lt->GetName();
- std::string filename = outputDir + "/" + targetName + ".project";
+ std::string filename = cmStrCat(outputDir, "/", targetName, ".project");
retval.push_back(targetName);
// Make the project file relative to the workspace
std::string relafilename =
@@ -131,7 +132,7 @@
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
- visualname = "lib" + visualname;
+ visualname = cmStrCat("lib", visualname);
CM_FALLTHROUGH;
case cmStateEnums::EXECUTABLE:
xml->StartElement("Project");
@@ -161,7 +162,7 @@
std::string const& outputDir = it.second[0]->GetCurrentBinaryDirectory();
std::string projectName = it.second[0]->GetProjectName();
retval.push_back(projectName);
- std::string filename = outputDir + "/" + projectName + ".project";
+ std::string filename = cmStrCat(outputDir, "/", projectName, ".project");
// Make the project file relative to the workspace
filename = cmSystemTools::RelativePath(this->WorkspacePath, filename);
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 71c8fcd..67773e0 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmMessageType.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -266,7 +267,7 @@
R"((^|[ ])-[DIOUWfgs][^= ]+(=\"[^"]+\"|=[^"][^ ]+)?)";
flagRegex.compile(regexString);
std::string workString =
- flagsString + " " + definesString + " " + includesString;
+ cmStrCat(flagsString, " ", definesString, " ", includesString);
while (flagRegex.find(workString)) {
std::string::size_type start = flagRegex.start();
if (workString[start] == ' ') {
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index b7a2b27..ccd6be9 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -8,6 +8,7 @@
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
@@ -66,18 +67,15 @@
// if we should use the source GUI
// to generate .cxx and .h files
if (!curr || !curr->GetPropertyAsBool("WRAP_EXCLUDE")) {
- std::string outName = outputDirectory;
- outName += "/";
- outName += cmSystemTools::GetFilenameWithoutExtension(arg);
- std::string hname = outName;
- hname += ".h";
- std::string origname = cdir + "/" + arg;
+ std::string outName = cmStrCat(
+ outputDirectory, "/", cmSystemTools::GetFilenameWithoutExtension(arg));
+ std::string hname = cmStrCat(outName, ".h");
+ std::string origname = cmStrCat(cdir, "/", arg);
// add starting depends
std::vector<std::string> depends;
depends.push_back(origname);
depends.push_back(fluid_exe);
- std::string cxxres = outName;
- cxxres += ".cxx";
+ std::string cxxres = cmStrCat(outName, ".cxx");
cmCustomCommandLine commandLine;
commandLine.push_back(fluid_exe);
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index ba42669..aee42d7 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -2,12 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileAPI.h"
-#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFileAPICMakeFiles.h"
#include "cmFileAPICache.h"
#include "cmFileAPICodemodel.h"
#include "cmGlobalGenerator.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmake.h"
@@ -94,7 +94,7 @@
std::vector<std::string> files = this->LoadDir(reply_dir);
for (std::string const& f : files) {
if (this->ReplyFiles.find(f) == this->ReplyFiles.end()) {
- std::string file = reply_dir + "/" + f;
+ std::string file = cmStrCat(reply_dir, "/", f);
cmSystemTools::RemoveFile(file);
}
}
@@ -684,7 +684,6 @@
Json::Value cmFileAPI::BuildCodeModel(Object const& object)
{
- using namespace std::placeholders;
Json::Value codemodel = cmFileAPICodemodelDump(*this, object.Version);
codemodel["kind"] = this->ObjectKindName(object.Kind);
@@ -719,7 +718,6 @@
Json::Value cmFileAPI::BuildCache(Object const& object)
{
- using namespace std::placeholders;
Json::Value cache = cmFileAPICacheDump(*this, object.Version);
cache["kind"] = this->ObjectKindName(object.Kind);
@@ -754,7 +752,6 @@
Json::Value cmFileAPI::BuildCMakeFiles(Object const& object)
{
- using namespace std::placeholders;
Json::Value cmakeFiles = cmFileAPICMakeFilesDump(*this, object.Version);
cmakeFiles["kind"] = this->ObjectKindName(object.Kind);
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 7b916cd..e4b7670 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -21,6 +21,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
@@ -30,6 +31,9 @@
#include <algorithm>
#include <cassert>
+#include <cstddef>
+#include <functional>
+#include <limits>
#include <map>
#include <memory>
#include <set>
@@ -135,6 +139,40 @@
return gt->GetName() + CMAKE_DIRECTORY_ID_SEP + hash;
}
+class JBTIndex
+{
+public:
+ JBTIndex() = default;
+ explicit operator bool() const { return Index != None; }
+ Json::ArrayIndex Index = None;
+ static Json::ArrayIndex const None = static_cast<Json::ArrayIndex>(-1);
+};
+
+template <typename T>
+class JBT
+{
+public:
+ JBT(T v = T(), JBTIndex bt = JBTIndex())
+ : Value(std::move(v))
+ , Backtrace(bt)
+ {
+ }
+ T Value;
+ JBTIndex Backtrace;
+ friend bool operator==(JBT<T> const& l, JBT<T> const& r)
+ {
+ return l.Value == r.Value && l.Backtrace.Index == r.Backtrace.Index;
+ }
+ static bool ValueEq(JBT<T> const& l, JBT<T> const& r)
+ {
+ return l.Value == r.Value;
+ }
+ static bool ValueLess(JBT<T> const& l, JBT<T> const& r)
+ {
+ return l.Value < r.Value;
+ }
+};
+
class BacktraceData
{
std::string TopSource;
@@ -169,7 +207,7 @@
public:
BacktraceData(std::string topSource);
- bool Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index);
+ JBTIndex Add(cmListFileBacktrace const& bt);
Json::Value Dump();
};
@@ -178,16 +216,17 @@
{
}
-bool BacktraceData::Add(cmListFileBacktrace const& bt, Json::ArrayIndex& index)
+JBTIndex BacktraceData::Add(cmListFileBacktrace const& bt)
{
+ JBTIndex index;
if (bt.Empty()) {
- return false;
+ return index;
}
cmListFileContext const* top = &bt.Top();
auto found = this->NodeMap.find(top);
if (found != this->NodeMap.end()) {
- index = found->second;
- return true;
+ index.Index = found->second;
+ return index;
}
Json::Value entry = Json::objectValue;
entry["file"] = this->AddFile(top->FilePath);
@@ -197,13 +236,12 @@
if (!top->Name.empty()) {
entry["command"] = this->AddCommand(top->Name);
}
- Json::ArrayIndex parent;
- if (this->Add(bt.Pop(), parent)) {
- entry["parent"] = parent;
+ if (JBTIndex parent = this->Add(bt.Pop())) {
+ entry["parent"] = parent.Index;
}
- index = this->NodeMap[top] = this->Nodes.size();
+ index.Index = this->NodeMap[top] = this->Nodes.size();
this->Nodes.append(std::move(entry)); // NOLINT(*)
- return true;
+ return index;
}
Json::Value BacktraceData::Dump()
@@ -222,32 +260,65 @@
{
struct IncludeEntry
{
- BT<std::string> Path;
+ JBT<std::string> Path;
bool IsSystem = false;
- IncludeEntry(BT<std::string> path, bool isSystem)
+ IncludeEntry(JBT<std::string> path, bool isSystem)
: Path(std::move(path))
, IsSystem(isSystem)
{
}
+ friend bool operator==(IncludeEntry const& l, IncludeEntry const& r)
+ {
+ return l.Path == r.Path && l.IsSystem == r.IsSystem;
+ }
};
- void SetDefines(std::set<BT<std::string>> const& defines);
-
std::string Language;
std::string Sysroot;
- std::vector<BT<std::string>> Flags;
- std::vector<BT<std::string>> Defines;
+ std::vector<JBT<std::string>> Flags;
+ std::vector<JBT<std::string>> Defines;
std::vector<IncludeEntry> Includes;
-};
-void CompileData::SetDefines(std::set<BT<std::string>> const& defines)
-{
- this->Defines.reserve(defines.size());
- for (BT<std::string> const& d : defines) {
- this->Defines.push_back(d);
+ friend bool operator==(CompileData const& l, CompileData const& r)
+ {
+ return (l.Language == r.Language && l.Sysroot == r.Sysroot &&
+ l.Flags == r.Flags && l.Defines == r.Defines &&
+ l.Includes == r.Includes);
}
+};
}
+namespace std {
+
+template <>
+struct hash<CompileData>
+{
+ std::size_t operator()(CompileData const& in) const
+ {
+ using std::hash;
+ size_t result =
+ hash<std::string>()(in.Language) ^ hash<std::string>()(in.Sysroot);
+ for (auto const& i : in.Includes) {
+ result = result ^
+ (hash<std::string>()(i.Path.Value) ^
+ hash<Json::ArrayIndex>()(i.Path.Backtrace.Index) ^
+ (i.IsSystem ? std::numeric_limits<size_t>::max() : 0));
+ }
+ for (auto const& i : in.Flags) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
+ for (auto const& i : in.Defines) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
+ return result;
+ }
+};
+
+} // namespace std
+
+namespace {
class Target
{
cmGeneratorTarget* GT;
@@ -272,24 +343,32 @@
struct CompileGroup
{
- std::map<Json::Value, Json::ArrayIndex>::iterator Entry;
+ std::unordered_map<CompileData, Json::ArrayIndex>::iterator Entry;
Json::Value SourceIndexes = Json::arrayValue;
};
- std::map<Json::Value, Json::ArrayIndex> CompileGroupMap;
+ std::unordered_map<CompileData, Json::ArrayIndex> CompileGroupMap;
std::vector<CompileGroup> CompileGroups;
+ template <typename T>
+ JBT<T> ToJBT(BT<T> const& bt)
+ {
+ return JBT<T>(bt.Value, this->Backtraces.Add(bt.Backtrace));
+ }
+
void ProcessLanguages();
void ProcessLanguage(std::string const& lang);
Json::ArrayIndex AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si);
CompileData BuildCompileData(cmSourceFile* sf);
+ CompileData MergeCompileData(CompileData const& fd);
Json::ArrayIndex AddSourceCompileGroup(cmSourceFile* sf,
Json::ArrayIndex si);
void AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt);
+ void AddBacktrace(Json::Value& object, JBTIndex bt);
Json::Value DumpPaths();
- Json::Value DumpCompileData(CompileData cd);
+ Json::Value DumpCompileData(CompileData const& cd);
Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
- Json::Value DumpDefine(BT<std::string> const& def);
+ Json::Value DumpDefine(JBT<std::string> const& def);
Json::Value DumpSources();
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
Json::ArrayIndex si);
@@ -306,8 +385,8 @@
Json::Value DumpLink();
Json::Value DumpArchive();
Json::Value DumpLinkCommandFragments();
- Json::Value DumpCommandFragments(std::vector<BT<std::string>> const& frags);
- Json::Value DumpCommandFragment(BT<std::string> const& frag,
+ Json::Value DumpCommandFragments(std::vector<JBT<std::string>> const& frags);
+ Json::Value DumpCommandFragment(JBT<std::string> const& frag,
std::string const& role = std::string());
Json::Value DumpDependencies();
Json::Value DumpDependency(cmTargetDepend const& td);
@@ -722,16 +801,20 @@
// which may need to be factored out.
std::string flags;
lg->GetTargetCompileFlags(this->GT, this->Config, lang, flags);
- cd.Flags.emplace_back(std::move(flags), cmListFileBacktrace());
+ cd.Flags.emplace_back(std::move(flags), JBTIndex());
}
std::set<BT<std::string>> defines =
lg->GetTargetDefines(this->GT, this->Config, lang);
- cd.SetDefines(defines);
+ cd.Defines.reserve(defines.size());
+ for (BT<std::string> const& d : defines) {
+ cd.Defines.emplace_back(this->ToJBT(d));
+ }
std::vector<BT<std::string>> includePathList =
lg->GetIncludeDirectories(this->GT, lang, this->Config);
for (BT<std::string> const& i : includePathList) {
cd.Includes.emplace_back(
- i, this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang));
+ this->ToJBT(i),
+ this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang));
}
}
@@ -758,26 +841,22 @@
if (fd.Language.empty()) {
return fd;
}
- CompileData const& cd = this->CompileDataMap.at(fd.Language);
-
- fd.Sysroot = cd.Sysroot;
cmLocalGenerator* lg = this->GT->GetLocalGenerator();
cmGeneratorExpressionInterpreter genexInterpreter(lg, this->Config, this->GT,
fd.Language);
- fd.Flags = cd.Flags;
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
std::string flags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
- fd.Flags.emplace_back(std::move(flags), cmListFileBacktrace());
+ fd.Flags.emplace_back(std::move(flags), JBTIndex());
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) {
std::string flags;
lg->AppendCompileOptions(
flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
- fd.Flags.emplace_back(std::move(flags), cmListFileBacktrace());
+ fd.Flags.emplace_back(std::move(flags), JBTIndex());
}
// Add include directories from source file properties.
@@ -796,8 +875,6 @@
}
}
}
- fd.Includes.insert(fd.Includes.end(), cd.Includes.begin(),
- cd.Includes.end());
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
std::set<std::string> fileDefines;
@@ -814,27 +891,62 @@
genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
}
- std::set<BT<std::string>> defines;
- defines.insert(fileDefines.begin(), fileDefines.end());
- defines.insert(cd.Defines.begin(), cd.Defines.end());
-
- fd.SetDefines(defines);
+ fd.Defines.reserve(fileDefines.size());
+ for (std::string const& d : fileDefines) {
+ fd.Defines.emplace_back(d, JBTIndex());
+ }
return fd;
}
+CompileData Target::MergeCompileData(CompileData const& fd)
+{
+ CompileData cd;
+ cd.Language = fd.Language;
+ if (cd.Language.empty()) {
+ return cd;
+ }
+ CompileData const& td = this->CompileDataMap.at(cd.Language);
+
+ // All compile groups share the sysroot of the target.
+ cd.Sysroot = td.Sysroot;
+
+ // Use target-wide flags followed by source-specific flags.
+ cd.Flags.reserve(td.Flags.size() + fd.Flags.size());
+ cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end());
+ cd.Flags.insert(cd.Flags.end(), fd.Flags.begin(), fd.Flags.end());
+
+ // Use source-specific includes followed by target-wide includes.
+ cd.Includes.reserve(fd.Includes.size() + td.Includes.size());
+ cd.Includes.insert(cd.Includes.end(), fd.Includes.begin(),
+ fd.Includes.end());
+ cd.Includes.insert(cd.Includes.end(), td.Includes.begin(),
+ td.Includes.end());
+
+ // Use target-wide defines followed by source-specific defines.
+ cd.Defines.reserve(td.Defines.size() + fd.Defines.size());
+ cd.Defines.insert(cd.Defines.end(), td.Defines.begin(), td.Defines.end());
+ cd.Defines.insert(cd.Defines.end(), fd.Defines.begin(), fd.Defines.end());
+
+ // De-duplicate defines.
+ std::stable_sort(cd.Defines.begin(), cd.Defines.end(),
+ JBT<std::string>::ValueLess);
+ auto end = std::unique(cd.Defines.begin(), cd.Defines.end(),
+ JBT<std::string>::ValueEq);
+ cd.Defines.erase(end, cd.Defines.end());
+
+ return cd;
+}
+
Json::ArrayIndex Target::AddSourceCompileGroup(cmSourceFile* sf,
Json::ArrayIndex si)
{
- Json::Value compileDataJson =
- this->DumpCompileData(this->BuildCompileData(sf));
- std::map<Json::Value, Json::ArrayIndex>::iterator i =
- this->CompileGroupMap.find(compileDataJson);
+ CompileData compileData = this->BuildCompileData(sf);
+ auto i = this->CompileGroupMap.find(compileData);
if (i == this->CompileGroupMap.end()) {
Json::ArrayIndex cgIndex =
static_cast<Json::ArrayIndex>(this->CompileGroups.size());
- i =
- this->CompileGroupMap.emplace(std::move(compileDataJson), cgIndex).first;
+ i = this->CompileGroupMap.emplace(std::move(compileData), cgIndex).first;
CompileGroup g;
g.Entry = i;
this->CompileGroups.push_back(std::move(g));
@@ -845,9 +957,15 @@
void Target::AddBacktrace(Json::Value& object, cmListFileBacktrace const& bt)
{
- Json::ArrayIndex backtrace;
- if (this->Backtraces.Add(bt, backtrace)) {
- object["backtrace"] = backtrace;
+ if (JBTIndex backtrace = this->Backtraces.Add(bt)) {
+ object["backtrace"] = backtrace.Index;
+ }
+}
+
+void Target::AddBacktrace(Json::Value& object, JBTIndex bt)
+{
+ if (bt) {
+ object["backtrace"] = bt.Index;
}
}
@@ -915,7 +1033,7 @@
return source;
}
-Json::Value Target::DumpCompileData(CompileData cd)
+Json::Value Target::DumpCompileData(CompileData const& cd)
{
Json::Value result = Json::objectValue;
@@ -937,7 +1055,7 @@
}
if (!cd.Defines.empty()) {
Json::Value defines = Json::arrayValue;
- for (BT<std::string> const& d : cd.Defines) {
+ for (JBT<std::string> const& d : cd.Defines) {
defines.append(this->DumpDefine(d));
}
result["defines"] = std::move(defines);
@@ -957,7 +1075,7 @@
return include;
}
-Json::Value Target::DumpDefine(BT<std::string> const& def)
+Json::Value Target::DumpDefine(JBT<std::string> const& def)
{
Json::Value define = Json::objectValue;
define["define"] = def.Value;
@@ -993,7 +1111,8 @@
Json::Value Target::DumpCompileGroup(CompileGroup& cg)
{
- Json::Value group = cg.Entry->first;
+ Json::Value group =
+ this->DumpCompileData(this->MergeCompileData(cg.Entry->first));
group["sourceIndexes"] = std::move(cg.SourceIndexes);
return group;
}
@@ -1026,12 +1145,9 @@
Json::Value Target::DumpInstallDestinations()
{
Json::Value destinations = Json::arrayValue;
- auto installGens = this->GT->Makefile->GetInstallGenerators();
- for (auto iGen : installGens) {
- auto itGen = dynamic_cast<cmInstallTargetGenerator*>(iGen);
- if (itGen != nullptr && itGen->GetTarget() == this->GT) {
- destinations.append(this->DumpInstallDestination(itGen));
- }
+ auto installGens = this->GT->Target->GetInstallGenerators();
+ for (auto itGen : installGens) {
+ destinations.append(this->DumpInstallDestination(itGen));
}
return destinations;
}
@@ -1155,11 +1271,11 @@
lg->GetTargetFlags(&linkLineComputer, this->Config, linkLibs,
linkLanguageFlags, linkFlags, frameworkPath, linkPath,
this->GT);
- linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags);
- linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
- frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath);
- linkPath = cmSystemTools::TrimWhitespace(linkPath);
- linkLibs = cmSystemTools::TrimWhitespace(linkLibs);
+ linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags);
+ linkFlags = cmTrimWhitespace(linkFlags);
+ frameworkPath = cmTrimWhitespace(frameworkPath);
+ linkPath = cmTrimWhitespace(linkPath);
+ linkLibs = cmTrimWhitespace(linkLibs);
if (!linkLanguageFlags.empty()) {
linkFragments.append(
@@ -1190,16 +1306,16 @@
}
Json::Value Target::DumpCommandFragments(
- std::vector<BT<std::string>> const& frags)
+ std::vector<JBT<std::string>> const& frags)
{
Json::Value commandFragments = Json::arrayValue;
- for (BT<std::string> const& f : frags) {
+ for (JBT<std::string> const& f : frags) {
commandFragments.append(this->DumpCommandFragment(f));
}
return commandFragments;
}
-Json::Value Target::DumpCommandFragment(BT<std::string> const& frag,
+Json::Value Target::DumpCommandFragment(JBT<std::string> const& frag,
std::string const& role)
{
Json::Value fragment = Json::objectValue;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index a8ee6a8..fd319f6 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -25,6 +25,7 @@
#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmCryptoHash.h"
+#include "cmExecutionStatus.h"
#include "cmFileCopier.h"
#include "cmFileInstaller.h"
#include "cmFileLockPool.h"
@@ -39,12 +40,14 @@
#include "cmRange.h"
#include "cmRuntimeDependencyArchive.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
+#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cm_sys_stat.h"
#include "cmake.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmCurl.h"
# include "cmFileLockResult.h"
# include "cm_curl.h"
@@ -58,10 +61,12 @@
# include <windows.h>
#endif
+namespace {
+
#if defined(_WIN32)
// libcurl doesn't support file:// urls for unicode filenames on Windows.
// Convert string from UTF-8 to ACP if this is a file:// URL.
-static std::string fix_file_url_windows(const std::string& url)
+std::string fix_file_url_windows(const std::string& url)
{
std::string ret = url;
if (strncmp(url.c_str(), "file://", 7) == 0) {
@@ -83,123 +88,8 @@
}
#endif
-// cmLibraryCommand
-bool cmFileCommand::InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus&)
-{
- if (args.size() < 2) {
- this->SetError("must be called with at least two arguments.");
- return false;
- }
- std::string const& subCommand = args[0];
- if (subCommand == "WRITE") {
- return this->HandleWriteCommand(args, false);
- }
- if (subCommand == "APPEND") {
- return this->HandleWriteCommand(args, true);
- }
- if (subCommand == "DOWNLOAD") {
- return this->HandleDownloadCommand(args);
- }
- if (subCommand == "UPLOAD") {
- return this->HandleUploadCommand(args);
- }
- if (subCommand == "READ") {
- return this->HandleReadCommand(args);
- }
- if (subCommand == "MD5" || subCommand == "SHA1" || subCommand == "SHA224" ||
- subCommand == "SHA256" || subCommand == "SHA384" ||
- subCommand == "SHA512" || subCommand == "SHA3_224" ||
- subCommand == "SHA3_256" || subCommand == "SHA3_384" ||
- subCommand == "SHA3_512") {
- return this->HandleHashCommand(args);
- }
- if (subCommand == "STRINGS") {
- return this->HandleStringsCommand(args);
- }
- if (subCommand == "GLOB") {
- return this->HandleGlobCommand(args, false);
- }
- if (subCommand == "GLOB_RECURSE") {
- return this->HandleGlobCommand(args, true);
- }
- if (subCommand == "MAKE_DIRECTORY") {
- return this->HandleMakeDirectoryCommand(args);
- }
- if (subCommand == "RENAME") {
- return this->HandleRename(args);
- }
- if (subCommand == "REMOVE") {
- return this->HandleRemove(args, false);
- }
- if (subCommand == "REMOVE_RECURSE") {
- return this->HandleRemove(args, true);
- }
- if (subCommand == "COPY") {
- return this->HandleCopyCommand(args);
- }
- if (subCommand == "INSTALL") {
- return this->HandleInstallCommand(args);
- }
- if (subCommand == "DIFFERENT") {
- return this->HandleDifferentCommand(args);
- }
- if (subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH") {
- return this->HandleRPathChangeCommand(args);
- }
- if (subCommand == "RPATH_CHECK") {
- return this->HandleRPathCheckCommand(args);
- }
- if (subCommand == "RPATH_REMOVE") {
- return this->HandleRPathRemoveCommand(args);
- }
- if (subCommand == "READ_ELF") {
- return this->HandleReadElfCommand(args);
- }
- if (subCommand == "RELATIVE_PATH") {
- return this->HandleRelativePathCommand(args);
- }
- if (subCommand == "TO_CMAKE_PATH") {
- return this->HandleCMakePathCommand(args, false);
- }
- if (subCommand == "TO_NATIVE_PATH") {
- return this->HandleCMakePathCommand(args, true);
- }
- if (subCommand == "TOUCH") {
- return this->HandleTouchCommand(args, true);
- }
- if (subCommand == "TOUCH_NOCREATE") {
- return this->HandleTouchCommand(args, false);
- }
- if (subCommand == "TIMESTAMP") {
- return this->HandleTimestampCommand(args);
- }
- if (subCommand == "GENERATE") {
- return this->HandleGenerateCommand(args);
- }
- if (subCommand == "LOCK") {
- return this->HandleLockCommand(args);
- }
- if (subCommand == "SIZE") {
- return this->HandleSizeCommand(args);
- }
- if (subCommand == "READ_SYMLINK") {
- return this->HandleReadSymlinkCommand(args);
- }
- if (subCommand == "CREATE_LINK") {
- return this->HandleCreateLinkCommand(args);
- }
- if (subCommand == "GET_RUNTIME_DEPENDENCIES") {
- return this->HandleGetRuntimeDependenciesCommand(args);
- }
-
- std::string e = "does not recognize sub-command " + subCommand;
- this->SetError(e);
- return false;
-}
-
-bool cmFileCommand::HandleWriteCommand(std::vector<std::string> const& args,
- bool append)
+bool HandleWriteImpl(std::vector<std::string> const& args, bool append,
+ cmExecutionStatus& status)
{
std::vector<std::string>::const_iterator i = args.begin();
@@ -207,16 +97,16 @@
std::string fileName = *i;
if (!cmsys::SystemTools::FileIsFullPath(*i)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
+ fileName = status.GetMakefile().GetCurrentSourceDirectory();
fileName += "/" + *i;
}
i++;
- if (!this->Makefile->CanIWriteThisFile(fileName)) {
+ if (!status.GetMakefile().CanIWriteThisFile(fileName)) {
std::string e =
"attempted to write a file: " + fileName + " into a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -248,7 +138,7 @@
error += cmSystemTools::GetLastSystemError();
error += "):\n ";
error += fileName;
- this->SetError(error);
+ status.SetError(error);
return false;
}
std::string message = cmJoin(cmMakeRange(i, args.end()), std::string());
@@ -258,7 +148,7 @@
error += cmSystemTools::GetLastSystemError();
error += "):\n ";
error += fileName;
- this->SetError(error);
+ status.SetError(error);
return false;
}
file.close();
@@ -268,11 +158,24 @@
return true;
}
-bool cmFileCommand::HandleReadCommand(std::vector<std::string> const& args)
+bool HandleWriteCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleWriteImpl(args, false, status);
+}
+
+bool HandleAppendCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleWriteImpl(args, true, status);
+}
+
+bool HandleReadCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("READ must be called with at least two additional "
- "arguments");
+ status.SetError("READ must be called with at least two additional "
+ "arguments");
return false;
}
@@ -295,7 +198,7 @@
std::string fileName = fileNameArg;
if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
+ fileName = status.GetMakefile().GetCurrentSourceDirectory();
fileName += "/" + fileNameArg;
}
@@ -313,7 +216,7 @@
error += cmSystemTools::GetLastSystemError();
error += "):\n ";
error += fileName;
- this->SetError(error);
+ status.SetError(error);
return false;
}
@@ -365,17 +268,18 @@
}
}
}
- this->Makefile->AddDefinition(variable, output);
+ status.GetMakefile().AddDefinition(variable, output);
return true;
}
-bool cmFileCommand::HandleHashCommand(std::vector<std::string> const& args)
+bool HandleHashCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args.size() != 3) {
std::ostringstream e;
e << args[0] << " requires a file name and output variable";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -383,34 +287,35 @@
if (hash) {
std::string out = hash->HashFile(args[1]);
if (!out.empty()) {
- this->Makefile->AddDefinition(args[2], out);
+ status.GetMakefile().AddDefinition(args[2], out);
return true;
}
std::ostringstream e;
e << args[0] << " failed to read file \"" << args[1]
<< "\": " << cmSystemTools::GetLastSystemError();
- this->SetError(e.str());
+ status.SetError(e.str());
}
return false;
#else
std::ostringstream e;
e << args[0] << " not available during bootstrap";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
#endif
}
-bool cmFileCommand::HandleStringsCommand(std::vector<std::string> const& args)
+bool HandleStringsCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("STRINGS requires a file name and output variable");
+ status.SetError("STRINGS requires a file name and output variable");
return false;
}
// Get the file to read.
std::string fileName = args[1];
if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
+ fileName = status.GetMakefile().GetCurrentSourceDirectory();
fileName += "/" + args[1];
}
@@ -477,7 +382,7 @@
std::ostringstream e;
e << "STRINGS option LIMIT_INPUT value \"" << args[i]
<< "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
arg_mode = arg_none;
@@ -487,7 +392,7 @@
std::ostringstream e;
e << "STRINGS option LIMIT_OUTPUT value \"" << args[i]
<< "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
arg_mode = arg_none;
@@ -497,7 +402,7 @@
std::ostringstream e;
e << "STRINGS option LIMIT_COUNT value \"" << args[i]
<< "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
limit_count = count;
@@ -508,7 +413,7 @@
std::ostringstream e;
e << "STRINGS option LENGTH_MINIMUM value \"" << args[i]
<< "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
minlen = len;
@@ -519,7 +424,7 @@
std::ostringstream e;
e << "STRINGS option LENGTH_MAXIMUM value \"" << args[i]
<< "\" is not an unsigned integer.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
maxlen = len;
@@ -529,7 +434,7 @@
std::ostringstream e;
e << "STRINGS option REGEX value \"" << args[i]
<< "\" could not be compiled.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
have_regex = true;
@@ -548,21 +453,22 @@
} else {
std::ostringstream e;
e << "STRINGS option ENCODING \"" << args[i] << "\" not recognized.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
arg_mode = arg_none;
} else {
std::ostringstream e;
e << "STRINGS given unknown argument \"" << args[i] << "\"";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
if (hex_conversion_enabled) {
// TODO: should work without temp file, but just on a memory buffer
- std::string binaryFileName = this->Makefile->GetCurrentBinaryDirectory();
+ std::string binaryFileName =
+ status.GetMakefile().GetCurrentBinaryDirectory();
binaryFileName += "/CMakeFiles";
binaryFileName += "/FileCommandStringsBinaryFile";
if (cmHexFileConverter::TryConvert(fileName, binaryFileName)) {
@@ -579,7 +485,7 @@
if (!fin) {
std::ostringstream e;
e << "STRINGS file \"" << fileName << "\" cannot be read.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -751,12 +657,12 @@
}
// Save the output in a makefile variable.
- this->Makefile->AddDefinition(outVar, output);
+ status.GetMakefile().AddDefinition(outVar, output);
return true;
}
-bool cmFileCommand::HandleGlobCommand(std::vector<std::string> const& args,
- bool recurse)
+bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
+ cmExecutionStatus& status)
{
// File commands has at least one argument
assert(args.size() > 1);
@@ -771,10 +677,10 @@
g.SetRecurse(recurse);
bool explicitFollowSymlinks = false;
- cmPolicies::PolicyStatus status =
- this->Makefile->GetPolicyStatus(cmPolicies::CMP0009);
+ cmPolicies::PolicyStatus policyStatus =
+ status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0009);
if (recurse) {
- switch (status) {
+ switch (policyStatus) {
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
@@ -792,7 +698,7 @@
bool warnConfigureLate = false;
bool warnFollowedSymlinks = false;
const cmake::WorkingMode workingMode =
- this->Makefile->GetCMakeInstance()->GetWorkingMode();
+ status.GetMakefile().GetCMakeInstance()->GetWorkingMode();
while (i != args.end()) {
if (*i == "LIST_DIRECTORIES") {
++i; // skip LIST_DIRECTORIES
@@ -804,12 +710,12 @@
g.SetListDirs(false);
g.SetRecurseListDirs(false);
} else {
- this->SetError("LIST_DIRECTORIES missing bool value.");
+ status.SetError("LIST_DIRECTORIES missing bool value.");
return false;
}
++i;
} else {
- this->SetError("LIST_DIRECTORIES missing bool value.");
+ status.SetError("LIST_DIRECTORIES missing bool value.");
return false;
}
} else if (*i == "FOLLOW_SYMLINKS") {
@@ -818,7 +724,7 @@
explicitFollowSymlinks = true;
g.RecurseThroughSymlinksOn();
if (i == args.end()) {
- this->SetError(
+ status.SetError(
"GLOB_RECURSE requires a glob expression after FOLLOW_SYMLINKS.");
return false;
}
@@ -826,25 +732,26 @@
} else if (*i == "RELATIVE") {
++i; // skip RELATIVE
if (i == args.end()) {
- this->SetError("GLOB requires a directory after the RELATIVE tag.");
+ status.SetError("GLOB requires a directory after the RELATIVE tag.");
return false;
}
g.SetRelative(i->c_str());
++i;
if (i == args.end()) {
- this->SetError("GLOB requires a glob expression after the directory.");
+ status.SetError(
+ "GLOB requires a glob expression after the directory.");
return false;
}
} else if (*i == "CONFIGURE_DEPENDS") {
// Generated build system depends on glob results
if (!configureDepends && warnConfigureLate) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
"CONFIGURE_DEPENDS flag was given after a glob expression was "
"already evaluated.");
}
if (workingMode != cmake::NORMAL_MODE) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"CONFIGURE_DEPENDS is invalid for script and find package modes.");
return false;
@@ -852,14 +759,14 @@
configureDepends = true;
++i;
if (i == args.end()) {
- this->SetError(
+ status.SetError(
"GLOB requires a glob expression after CONFIGURE_DEPENDS.");
return false;
}
} else {
std::string expr = *i;
if (!cmsys::SystemTools::FileIsFullPath(*i)) {
- expr = this->Makefile->GetCurrentSourceDirectory();
+ expr = status.GetMakefile().GetCurrentSourceDirectory();
// Handle script mode
if (!expr.empty()) {
expr += "/" + *i;
@@ -875,12 +782,12 @@
bool shouldExit = false;
for (cmsys::Glob::Message const& globMessage : globMessages) {
if (globMessage.type == cmsys::Glob::cyclicRecursion) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
"Cyclic recursion detected while globbing for '" + *i + "':\n" +
globMessage.content);
} else {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"Error has occurred while globbing for '" + *i + "' - " +
globMessage.content);
@@ -904,11 +811,11 @@
std::sort(foundFiles.begin(), foundFiles.end());
foundFiles.erase(std::unique(foundFiles.begin(), foundFiles.end()),
foundFiles.end());
- this->Makefile->GetCMakeInstance()->AddGlobCacheEntry(
+ status.GetMakefile().GetCMakeInstance()->AddGlobCacheEntry(
recurse, (recurse ? g.GetRecurseListDirs() : g.GetListDirs()),
(recurse ? g.GetRecurseThroughSymlinks() : false),
(g.GetRelative() ? g.GetRelative() : ""), expr, foundFiles, variable,
- this->Makefile->GetBacktrace());
+ status.GetMakefile().GetBacktrace());
} else {
warnConfigureLate = true;
}
@@ -916,7 +823,7 @@
}
}
- switch (status) {
+ switch (policyStatus) {
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
case cmPolicies::NEW:
@@ -929,7 +836,7 @@
// Possibly unexpected old behavior *and* we actually traversed
// symlinks without being explicitly asked to: warn the author.
if (warnFollowedSymlinks) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::AUTHOR_WARNING,
cmPolicies::GetPolicyWarning(cmPolicies::CMP0009));
}
@@ -938,12 +845,24 @@
std::sort(files.begin(), files.end());
files.erase(std::unique(files.begin(), files.end()), files.end());
- this->Makefile->AddDefinition(variable, cmJoin(files, ";"));
+ status.GetMakefile().AddDefinition(variable, cmJoin(files, ";"));
return true;
}
-bool cmFileCommand::HandleMakeDirectoryCommand(
- std::vector<std::string> const& args)
+bool HandleGlobCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleGlobImpl(args, false, status);
+}
+
+bool HandleGlobRecurseCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleGlobImpl(args, true, status);
+}
+
+bool HandleMakeDirectoryCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// File command has at least one argument
assert(args.size() > 1);
@@ -954,28 +873,28 @@
{
const std::string* cdir = &arg;
if (!cmsys::SystemTools::FileIsFullPath(arg)) {
- expr = this->Makefile->GetCurrentSourceDirectory();
+ expr = status.GetMakefile().GetCurrentSourceDirectory();
expr += "/" + arg;
cdir = &expr;
}
- if (!this->Makefile->CanIWriteThisFile(*cdir)) {
+ if (!status.GetMakefile().CanIWriteThisFile(*cdir)) {
std::string e = "attempted to create a directory: " + *cdir +
" into a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
if (!cmSystemTools::MakeDirectory(*cdir)) {
std::string error = "problem creating directory: " + *cdir;
- this->SetError(error);
+ status.SetError(error);
return false;
}
}
return true;
}
-bool cmFileCommand::HandleTouchCommand(std::vector<std::string> const& args,
- bool create)
+bool HandleTouchImpl(std::vector<std::string> const& args, bool create,
+ cmExecutionStatus& status)
{
// File command has at least one argument
assert(args.size() > 1);
@@ -985,27 +904,39 @@
{
std::string tfile = arg;
if (!cmsys::SystemTools::FileIsFullPath(tfile)) {
- tfile = this->Makefile->GetCurrentSourceDirectory();
+ tfile = status.GetMakefile().GetCurrentSourceDirectory();
tfile += "/" + arg;
}
- if (!this->Makefile->CanIWriteThisFile(tfile)) {
+ if (!status.GetMakefile().CanIWriteThisFile(tfile)) {
std::string e =
"attempted to touch a file: " + tfile + " in a source directory.";
- this->SetError(e);
+ status.SetError(e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
if (!cmSystemTools::Touch(tfile, create)) {
std::string error = "problem touching file: " + tfile;
- this->SetError(error);
+ status.SetError(error);
return false;
}
}
return true;
}
-bool cmFileCommand::HandleDifferentCommand(
- std::vector<std::string> const& args)
+bool HandleTouchCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleTouchImpl(args, true, status);
+}
+
+bool HandleTouchNocreateCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleTouchImpl(args, false, status);
+}
+
+bool HandleDifferentCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
/*
FILE(DIFFERENT <variable> FILES <lhs> <rhs>)
@@ -1038,34 +969,35 @@
} else {
std::ostringstream e;
e << "DIFFERENT given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
if (!var) {
- this->SetError("DIFFERENT not given result variable name.");
+ status.SetError("DIFFERENT not given result variable name.");
return false;
}
if (!file_lhs || !file_rhs) {
- this->SetError("DIFFERENT not given FILES option with two file names.");
+ status.SetError("DIFFERENT not given FILES option with two file names.");
return false;
}
// Compare the files.
const char* result =
cmSystemTools::FilesDiffer(file_lhs, file_rhs) ? "1" : "0";
- this->Makefile->AddDefinition(var, result);
+ status.GetMakefile().AddDefinition(var, result);
return true;
}
-bool cmFileCommand::HandleCopyCommand(std::vector<std::string> const& args)
+bool HandleCopyCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- cmFileCopier copier(this);
+ cmFileCopier copier(status);
return copier.Run(args);
}
-bool cmFileCommand::HandleRPathChangeCommand(
- std::vector<std::string> const& args)
+bool HandleRPathChangeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Evaluate arguments.
std::string file;
@@ -1101,26 +1033,26 @@
} else {
std::ostringstream e;
e << "RPATH_CHANGE given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
if (file.empty()) {
- this->SetError("RPATH_CHANGE not given FILE option.");
+ status.SetError("RPATH_CHANGE not given FILE option.");
return false;
}
if (!oldRPath) {
- this->SetError("RPATH_CHANGE not given OLD_RPATH option.");
+ status.SetError("RPATH_CHANGE not given OLD_RPATH option.");
return false;
}
if (!newRPath) {
- this->SetError("RPATH_CHANGE not given NEW_RPATH option.");
+ status.SetError("RPATH_CHANGE not given NEW_RPATH option.");
return false;
}
if (!cmSystemTools::FileExists(file, true)) {
std::ostringstream e;
e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
bool success = true;
@@ -1138,7 +1070,7 @@
<< " " << file << "\n"
<< emsg;
/* clang-format on */
- this->SetError(e.str());
+ status.SetError(e.str());
success = false;
}
if (success) {
@@ -1148,15 +1080,15 @@
message += "\" to \"";
message += newRPath;
message += "\"";
- this->Makefile->DisplayStatus(message, -1);
+ status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
}
return success;
}
-bool cmFileCommand::HandleRPathRemoveCommand(
- std::vector<std::string> const& args)
+bool HandleRPathRemoveCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Evaluate arguments.
std::string file;
@@ -1175,18 +1107,18 @@
} else {
std::ostringstream e;
e << "RPATH_REMOVE given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
if (file.empty()) {
- this->SetError("RPATH_REMOVE not given FILE option.");
+ status.SetError("RPATH_REMOVE not given FILE option.");
return false;
}
if (!cmSystemTools::FileExists(file, true)) {
std::ostringstream e;
e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
bool success = true;
@@ -1200,7 +1132,7 @@
<< " " << file << "\n"
<< emsg;
/* clang-format on */
- this->SetError(e.str());
+ status.SetError(e.str());
success = false;
}
if (success) {
@@ -1208,15 +1140,15 @@
std::string message = "Removed runtime path from \"";
message += file;
message += "\"";
- this->Makefile->DisplayStatus(message, -1);
+ status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
}
return success;
}
-bool cmFileCommand::HandleRPathCheckCommand(
- std::vector<std::string> const& args)
+bool HandleRPathCheckCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
// Evaluate arguments.
std::string file;
@@ -1242,16 +1174,16 @@
} else {
std::ostringstream e;
e << "RPATH_CHECK given unknown argument " << args[i];
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
}
if (file.empty()) {
- this->SetError("RPATH_CHECK not given FILE option.");
+ status.SetError("RPATH_CHECK not given FILE option.");
return false;
}
if (!rpath) {
- this->SetError("RPATH_CHECK not given RPATH option.");
+ status.SetError("RPATH_CHECK not given RPATH option.");
return false;
}
@@ -1266,11 +1198,12 @@
return true;
}
-bool cmFileCommand::HandleReadElfCommand(std::vector<std::string> const& args)
+bool HandleReadElfCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 4) {
- this->SetError("READ_ELF must be called with at least three additional "
- "arguments.");
+ status.SetError("READ_ELF must be called with at least three additional "
+ "arguments.");
return false;
}
@@ -1292,7 +1225,7 @@
if (!cmSystemTools::FileExists(fileNameArg, true)) {
std::ostringstream e;
e << "READ_ELF given FILE \"" << fileNameArg << "\" that does not exist.";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -1303,14 +1236,14 @@
if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
std::string rpath(se_rpath->Value);
std::replace(rpath.begin(), rpath.end(), ':', ';');
- this->Makefile->AddDefinition(arguments.RPath, rpath);
+ status.GetMakefile().AddDefinition(arguments.RPath, rpath);
}
}
if (!arguments.RunPath.empty()) {
if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
std::string runpath(se_runpath->Value);
std::replace(runpath.begin(), runpath.end(), ':', ';');
- this->Makefile->AddDefinition(arguments.RunPath, runpath);
+ status.GetMakefile().AddDefinition(arguments.RunPath, runpath);
}
}
@@ -1318,25 +1251,26 @@
#else
std::string error = "ELF parser not available on this platform.";
if (arguments.Error.empty()) {
- this->SetError(error);
+ status.SetError(error);
return false;
}
- this->Makefile->AddDefinition(arguments.Error, error);
+ status.GetMakefile().AddDefinition(arguments.Error, error);
return true;
#endif
}
-bool cmFileCommand::HandleInstallCommand(std::vector<std::string> const& args)
+bool HandleInstallCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- cmFileInstaller installer(this);
+ cmFileInstaller installer(status);
return installer.Run(args);
}
-bool cmFileCommand::HandleRelativePathCommand(
- std::vector<std::string> const& args)
+bool HandleRelativePathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 4) {
- this->SetError("RELATIVE_PATH called with incorrect number of arguments");
+ status.SetError("RELATIVE_PATH called with incorrect number of arguments");
return false;
}
@@ -1348,37 +1282,38 @@
std::string errstring =
"RELATIVE_PATH must be passed a full path to the directory: " +
directoryName;
- this->SetError(errstring);
+ status.SetError(errstring);
return false;
}
if (!cmSystemTools::FileIsFullPath(fileName)) {
std::string errstring =
"RELATIVE_PATH must be passed a full path to the file: " + fileName;
- this->SetError(errstring);
+ status.SetError(errstring);
return false;
}
std::string res = cmSystemTools::RelativePath(directoryName, fileName);
- this->Makefile->AddDefinition(outVar, res);
+ status.GetMakefile().AddDefinition(outVar, res);
return true;
}
-bool cmFileCommand::HandleRename(std::vector<std::string> const& args)
+bool HandleRename(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("RENAME given incorrect number of arguments.");
+ status.SetError("RENAME given incorrect number of arguments.");
return false;
}
// Compute full path for old and new names.
std::string oldname = args[1];
if (!cmsys::SystemTools::FileIsFullPath(oldname)) {
- oldname = this->Makefile->GetCurrentSourceDirectory();
+ oldname = status.GetMakefile().GetCurrentSourceDirectory();
oldname += "/" + args[1];
}
std::string newname = args[2];
if (!cmsys::SystemTools::FileIsFullPath(newname)) {
- newname = this->Makefile->GetCurrentSourceDirectory();
+ newname = status.GetMakefile().GetCurrentSourceDirectory();
newname += "/" + args[2];
}
@@ -1392,14 +1327,14 @@
<< " " << newname << "\n"
<< "because: " << err << "\n";
/* clang-format on */
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
return true;
}
-bool cmFileCommand::HandleRemove(std::vector<std::string> const& args,
- bool recurse)
+bool HandleRemoveImpl(std::vector<std::string> const& args, bool recurse,
+ cmExecutionStatus& status)
{
std::string message;
@@ -1410,12 +1345,12 @@
std::string fileName = arg;
if (fileName.empty()) {
std::string const r = recurse ? "REMOVE_RECURSE" : "REMOVE";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING,
- "Ignoring empty file name in " + r + ".");
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING, "Ignoring empty file name in " + r + ".");
continue;
}
if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
- fileName = this->Makefile->GetCurrentSourceDirectory();
+ fileName = status.GetMakefile().GetCurrentSourceDirectory();
fileName += "/" + arg;
}
@@ -1429,7 +1364,18 @@
return true;
}
-namespace {
+bool HandleRemove(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleRemoveImpl(args, false, status);
+}
+
+bool HandleRemoveRecurse(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandleRemoveImpl(args, true, status);
+}
+
std::string ToNativePath(const std::string& path)
{
const auto& outPath = cmSystemTools::ConvertToOutputPath(path);
@@ -1446,14 +1392,14 @@
cmSystemTools::ConvertToUnixSlashes(temp);
return temp;
}
-}
-bool cmFileCommand::HandleCMakePathCommand(
- std::vector<std::string> const& args, bool nativePath)
+bool HandlePathCommand(std::vector<std::string> const& args,
+ std::string (*convert)(std::string const&),
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
- this->SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
- "called with exactly three arguments.");
+ status.SetError("FILE([TO_CMAKE_PATH|TO_NATIVE_PATH] path result) must be "
+ "called with exactly three arguments.");
return false;
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1463,19 +1409,28 @@
#endif
std::vector<std::string> path = cmSystemTools::SplitString(args[1], pathSep);
- std::string value = cmJoin(
- cmMakeRange(path).transform(nativePath ? ToNativePath : ToCMakePath), ";");
- this->Makefile->AddDefinition(args[2], value);
+ std::string value = cmJoin(cmMakeRange(path).transform(convert), ";");
+ status.GetMakefile().AddDefinition(args[2], value);
return true;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+bool HandleCMakePathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandlePathCommand(args, ToCMakePath, status);
+}
+
+bool HandleNativePathCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ return HandlePathCommand(args, ToNativePath, status);
+}
+
+#if !defined(CMAKE_BOOTSTRAP)
// Stuff for curl download/upload
typedef std::vector<char> cmFileCommandVectorOfChar;
-namespace {
-
size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data)
{
int realsize = static_cast<int>(size * nmemb);
@@ -1526,11 +1481,10 @@
class cURLProgressHelper
{
public:
- cURLProgressHelper(cmFileCommand* fc, const char* text)
+ cURLProgressHelper(cmMakefile* mf, const char* text)
+ : Makefile(mf)
+ , Text(text)
{
- this->CurrentPercentage = -1;
- this->FileCommand = fc;
- this->Text = text;
}
bool UpdatePercentage(double value, double total, std::string& status)
@@ -1557,11 +1511,11 @@
return updated;
}
- cmFileCommand* GetFileCommand() { return this->FileCommand; }
+ cmMakefile* GetMakefile() { return this->Makefile; }
private:
- long CurrentPercentage;
- cmFileCommand* FileCommand;
+ long CurrentPercentage = -1;
+ cmMakefile* Makefile;
std::string Text;
};
@@ -1575,8 +1529,7 @@
std::string status;
if (helper->UpdatePercentage(dlnow, dltotal, status)) {
- cmFileCommand* fc = helper->GetFileCommand();
- cmMakefile* mf = fc->GetMakefile();
+ cmMakefile* mf = helper->GetMakefile();
mf->DisplayStatus(status, -1);
}
@@ -1593,16 +1546,12 @@
std::string status;
if (helper->UpdatePercentage(ulnow, ultotal, status)) {
- cmFileCommand* fc = helper->GetFileCommand();
- cmMakefile* mf = fc->GetMakefile();
+ cmMakefile* mf = helper->GetMakefile();
mf->DisplayStatus(status, -1);
}
return 0;
}
-}
-
-namespace {
class cURLEasyGuard
{
@@ -1627,7 +1576,7 @@
private:
::CURL* Easy;
};
-}
+
#endif
#define check_curl_result(result, errstr) \
@@ -1635,17 +1584,18 @@
if (result != CURLE_OK) { \
std::string e(errstr); \
e += ::curl_easy_strerror(result); \
- this->SetError(e); \
+ status.SetError(e); \
return false; \
} \
} while (false)
-bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
+bool HandleDownloadCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::vector<std::string>::const_iterator i = args.begin();
if (args.size() < 3) {
- this->SetError("DOWNLOAD must be called with at least three arguments.");
+ status.SetError("DOWNLOAD must be called with at least three arguments.");
return false;
}
++i; // Get rid of subcommand
@@ -1658,11 +1608,12 @@
long inactivity_timeout = 0;
std::string logVar;
std::string statusVar;
- bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY");
- const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO");
- std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
+ bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY");
+ const char* cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO");
+ std::string netrc_level =
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
std::string netrc_file =
- this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE");
std::string expectedHash;
std::string hashMatchMSG;
std::unique_ptr<cmCryptoHash> hash;
@@ -1677,7 +1628,7 @@
if (i != args.end()) {
timeout = atol(i->c_str());
} else {
- this->SetError("DOWNLOAD missing time for TIMEOUT.");
+ status.SetError("DOWNLOAD missing time for TIMEOUT.");
return false;
}
} else if (*i == "INACTIVITY_TIMEOUT") {
@@ -1685,20 +1636,20 @@
if (i != args.end()) {
inactivity_timeout = atol(i->c_str());
} else {
- this->SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
+ status.SetError("DOWNLOAD missing time for INACTIVITY_TIMEOUT.");
return false;
}
} else if (*i == "LOG") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing VAR for LOG.");
+ status.SetError("DOWNLOAD missing VAR for LOG.");
return false;
}
logVar = *i;
} else if (*i == "STATUS") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing VAR for STATUS.");
+ status.SetError("DOWNLOAD missing VAR for STATUS.");
return false;
}
statusVar = *i;
@@ -1707,7 +1658,7 @@
if (i != args.end()) {
tls_verify = cmSystemTools::IsOn(*i);
} else {
- this->SetError("TLS_VERIFY missing bool value.");
+ status.SetError("TLS_VERIFY missing bool value.");
return false;
}
} else if (*i == "TLS_CAINFO") {
@@ -1715,7 +1666,7 @@
if (i != args.end()) {
cainfo = i->c_str();
} else {
- this->SetError("TLS_CAFILE missing file value.");
+ status.SetError("TLS_CAFILE missing file value.");
return false;
}
} else if (*i == "NETRC_FILE") {
@@ -1723,7 +1674,7 @@
if (i != args.end()) {
netrc_file = *i;
} else {
- this->SetError("DOWNLOAD missing file value for NETRC_FILE.");
+ status.SetError("DOWNLOAD missing file value for NETRC_FILE.");
return false;
}
} else if (*i == "NETRC") {
@@ -1731,13 +1682,13 @@
if (i != args.end()) {
netrc_level = *i;
} else {
- this->SetError("DOWNLOAD missing level value for NETRC.");
+ status.SetError("DOWNLOAD missing level value for NETRC.");
return false;
}
} else if (*i == "EXPECTED_MD5") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
+ status.SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
return false;
}
hash = cm::make_unique<cmCryptoHash>(cmCryptoHash::AlgoMD5);
@@ -1748,7 +1699,7 @@
} else if (*i == "EXPECTED_HASH") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH.");
+ status.SetError("DOWNLOAD missing ALGO=value for EXPECTED_HASH.");
return false;
}
std::string::size_type pos = i->find("=");
@@ -1756,7 +1707,7 @@
std::string err =
"DOWNLOAD EXPECTED_HASH expects ALGO=value but got: ";
err += *i;
- this->SetError(err);
+ status.SetError(err);
return false;
}
std::string algo = i->substr(0, pos);
@@ -1765,21 +1716,21 @@
if (!hash) {
std::string err = "DOWNLOAD EXPECTED_HASH given unknown ALGO: ";
err += algo;
- this->SetError(err);
+ status.SetError(err);
return false;
}
hashMatchMSG = algo + " hash";
} else if (*i == "USERPWD") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing string for USERPWD.");
+ status.SetError("DOWNLOAD missing string for USERPWD.");
return false;
}
userpwd = *i;
} else if (*i == "HTTPHEADER") {
++i;
if (i == args.end()) {
- this->SetError("DOWNLOAD missing string for HTTPHEADER.");
+ status.SetError("DOWNLOAD missing string for HTTPHEADER.");
return false;
}
curl_headers.push_back(*i);
@@ -1787,7 +1738,7 @@
// Do not return error for compatibility reason.
std::string err = "Unexpected argument: ";
err += *i;
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, err);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err);
}
++i;
}
@@ -1805,7 +1756,7 @@
if (!statusVar.empty()) {
std::ostringstream result;
result << 0 << ";\"" << msg;
- this->Makefile->AddDefinition(statusVar, result.str());
+ status.GetMakefile().AddDefinition(statusVar, result.str());
}
return true;
}
@@ -1818,13 +1769,13 @@
std::string errstring = "DOWNLOAD error: cannot create directory '" + dir +
"' - Specify file by full path name and verify that you "
"have directory creation and file write privileges.";
- this->SetError(errstring);
+ status.SetError(errstring);
return false;
}
cmsys::ofstream fout(file.c_str(), std::ios::binary);
if (!fout) {
- this->SetError("DOWNLOAD cannot open file for write.");
+ status.SetError("DOWNLOAD cannot open file for write.");
return false;
}
@@ -1836,7 +1787,7 @@
::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init();
if (!curl) {
- this->SetError("DOWNLOAD error initializing curl.");
+ status.SetError("DOWNLOAD error initializing curl.");
return false;
}
@@ -1870,7 +1821,7 @@
// command arg comes first
std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
if (!cainfo_err.empty()) {
- this->SetError(cainfo_err);
+ status.SetError(cainfo_err);
return false;
}
@@ -1880,7 +1831,7 @@
std::string const& netrc_option_err =
cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
if (!netrc_option_err.empty()) {
- this->SetError(netrc_option_err);
+ status.SetError(netrc_option_err);
return false;
}
@@ -1916,7 +1867,7 @@
// scope intentionally, rather than inside the "if(showProgress)"
// block...
//
- cURLProgressHelper helper(this, "download");
+ cURLProgressHelper helper(&status.GetMakefile(), "download");
if (showProgress) {
res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
@@ -1954,7 +1905,7 @@
std::ostringstream result;
result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res)
<< "\"";
- this->Makefile->AddDefinition(statusVar, result.str());
+ status.GetMakefile().AddDefinition(statusVar, result.str());
}
::curl_global_cleanup();
@@ -1969,7 +1920,7 @@
if (hash) {
std::string actualHash = hash->HashFile(file);
if (actualHash.empty()) {
- this->SetError("DOWNLOAD cannot compute hash on downloaded file");
+ status.SetError("DOWNLOAD cannot compute hash on downloaded file");
return false;
}
@@ -1983,34 +1934,36 @@
<< ::curl_easy_strerror(res) << "\"]" << std::endl;
if (!statusVar.empty() && res == 0) {
- std::string status = "1;HASH mismatch: "
- "expected: " +
- expectedHash + " actual: " + actualHash;
- this->Makefile->AddDefinition(statusVar, status);
+ status.GetMakefile().AddDefinition(statusVar,
+ "1;HASH mismatch: "
+ "expected: " +
+ expectedHash +
+ " actual: " + actualHash);
}
- this->SetError(oss.str());
+ status.SetError(oss.str());
return false;
}
}
if (!logVar.empty()) {
chunkDebug.push_back(0);
- this->Makefile->AddDefinition(logVar, chunkDebug.data());
+ status.GetMakefile().AddDefinition(logVar, chunkDebug.data());
}
return true;
#else
- this->SetError("DOWNLOAD not supported by bootstrap cmake.");
+ status.SetError("DOWNLOAD not supported by bootstrap cmake.");
return false;
#endif
}
-bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
+bool HandleUploadCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args.size() < 3) {
- this->SetError("UPLOAD must be called with at least three arguments.");
+ status.SetError("UPLOAD must be called with at least three arguments.");
return false;
}
std::vector<std::string>::const_iterator i = args.begin();
@@ -2026,9 +1979,10 @@
std::string statusVar;
bool showProgress = false;
std::string userpwd;
- std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
+ std::string netrc_level =
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
std::string netrc_file =
- this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
+ status.GetMakefile().GetSafeDefinition("CMAKE_NETRC_FILE");
std::vector<std::string> curl_headers;
@@ -2038,7 +1992,7 @@
if (i != args.end()) {
timeout = atol(i->c_str());
} else {
- this->SetError("UPLOAD missing time for TIMEOUT.");
+ status.SetError("UPLOAD missing time for TIMEOUT.");
return false;
}
} else if (*i == "INACTIVITY_TIMEOUT") {
@@ -2046,20 +2000,20 @@
if (i != args.end()) {
inactivity_timeout = atol(i->c_str());
} else {
- this->SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
+ status.SetError("UPLOAD missing time for INACTIVITY_TIMEOUT.");
return false;
}
} else if (*i == "LOG") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing VAR for LOG.");
+ status.SetError("UPLOAD missing VAR for LOG.");
return false;
}
logVar = *i;
} else if (*i == "STATUS") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing VAR for STATUS.");
+ status.SetError("UPLOAD missing VAR for STATUS.");
return false;
}
statusVar = *i;
@@ -2070,7 +2024,7 @@
if (i != args.end()) {
netrc_file = *i;
} else {
- this->SetError("UPLOAD missing file value for NETRC_FILE.");
+ status.SetError("UPLOAD missing file value for NETRC_FILE.");
return false;
}
} else if (*i == "NETRC") {
@@ -2078,20 +2032,20 @@
if (i != args.end()) {
netrc_level = *i;
} else {
- this->SetError("UPLOAD missing level value for NETRC.");
+ status.SetError("UPLOAD missing level value for NETRC.");
return false;
}
} else if (*i == "USERPWD") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing string for USERPWD.");
+ status.SetError("UPLOAD missing string for USERPWD.");
return false;
}
userpwd = *i;
} else if (*i == "HTTPHEADER") {
++i;
if (i == args.end()) {
- this->SetError("UPLOAD missing string for HTTPHEADER.");
+ status.SetError("UPLOAD missing string for HTTPHEADER.");
return false;
}
curl_headers.push_back(*i);
@@ -2099,7 +2053,7 @@
// Do not return error for compatibility reason.
std::string err = "Unexpected argument: ";
err += *i;
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, err);
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, err);
}
++i;
@@ -2111,7 +2065,7 @@
if (!fin) {
std::string errStr = "UPLOAD cannot open file '";
errStr += filename + "' for reading.";
- this->SetError(errStr);
+ status.SetError(errStr);
return false;
}
@@ -2125,7 +2079,7 @@
::curl_global_init(CURL_GLOBAL_DEFAULT);
curl = ::curl_easy_init();
if (!curl) {
- this->SetError("UPLOAD error initializing curl.");
+ status.SetError("UPLOAD error initializing curl.");
fclose(fin);
return false;
}
@@ -2184,7 +2138,7 @@
// scope intentionally, rather than inside the "if(showProgress)"
// block...
//
- cURLProgressHelper helper(this, "upload");
+ cURLProgressHelper helper(&status.GetMakefile(), "upload");
if (showProgress) {
res = ::curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
@@ -2219,7 +2173,7 @@
std::string const& netrc_option_err =
cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
if (!netrc_option_err.empty()) {
- this->SetError(netrc_option_err);
+ status.SetError(netrc_option_err);
return false;
}
@@ -2241,7 +2195,7 @@
std::ostringstream result;
result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res)
<< "\"";
- this->Makefile->AddDefinition(statusVar, result.str());
+ status.GetMakefile().AddDefinition(statusVar, result.str());
}
::curl_global_cleanup();
@@ -2266,22 +2220,22 @@
log += "\n";
}
- this->Makefile->AddDefinition(logVar, log);
+ status.GetMakefile().AddDefinition(logVar, log);
}
return true;
#else
- this->SetError("UPLOAD not supported by bootstrap cmake.");
+ status.SetError("UPLOAD not supported by bootstrap cmake.");
return false;
#endif
}
-void cmFileCommand::AddEvaluationFile(const std::string& inputName,
- const std::string& outputExpr,
- const std::string& condition,
- bool inputIsContent)
+void AddEvaluationFile(const std::string& inputName,
+ const std::string& outputExpr,
+ const std::string& condition, bool inputIsContent,
+ cmExecutionStatus& status)
{
- cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = status.GetMakefile().GetBacktrace();
cmGeneratorExpression outputGe(lfbt);
std::unique_ptr<cmCompiledGeneratorExpression> outputCge =
@@ -2291,52 +2245,54 @@
std::unique_ptr<cmCompiledGeneratorExpression> conditionCge =
conditionGe.Parse(condition);
- this->Makefile->AddEvaluationFile(inputName, std::move(outputCge),
- std::move(conditionCge), inputIsContent);
+ status.GetMakefile().AddEvaluationFile(
+ inputName, std::move(outputCge), std::move(conditionCge), inputIsContent);
}
-bool cmFileCommand::HandleGenerateCommand(std::vector<std::string> const& args)
+bool HandleGenerateCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 5) {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
if (args[1] != "OUTPUT") {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
std::string condition;
if (args.size() > 5) {
if (args[5] != "CONDITION") {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
if (args.size() != 7) {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
condition = args[6];
if (condition.empty()) {
- this->SetError("CONDITION of sub-command GENERATE must not be empty if "
- "specified.");
+ status.SetError("CONDITION of sub-command GENERATE must not be empty if "
+ "specified.");
return false;
}
}
std::string output = args[2];
const bool inputIsContent = args[3] != "INPUT";
if (inputIsContent && args[3] != "CONTENT") {
- this->SetError("Incorrect arguments to GENERATE subcommand.");
+ status.SetError("Incorrect arguments to GENERATE subcommand.");
return false;
}
std::string input = args[4];
- this->AddEvaluationFile(input, output, condition, inputIsContent);
+ AddEvaluationFile(input, output, condition, inputIsContent, status);
return true;
}
-bool cmFileCommand::HandleLockCommand(std::vector<std::string> const& args)
+bool HandleLockCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Default values
bool directory = false;
bool release = false;
@@ -2352,7 +2308,7 @@
// Parse arguments
if (args.size() < 2) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"sub-command LOCK requires at least two arguments.");
return false;
@@ -2368,7 +2324,7 @@
++i;
const char* merr = "expected FUNCTION, FILE or PROCESS after GUARD";
if (i >= args.size()) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, merr);
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, merr);
return false;
}
if (args[i] == "FUNCTION") {
@@ -2380,14 +2336,14 @@
} else {
std::ostringstream e;
e << merr << ", but got:\n \"" << args[i] << "\".";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
return false;
}
} else if (args[i] == "RESULT_VARIABLE") {
++i;
if (i >= args.size()) {
- this->Makefile->IssueMessage(
+ status.GetMakefile().IssueMessage(
MessageType::FATAL_ERROR,
"expected variable name after RESULT_VARIABLE");
return false;
@@ -2396,8 +2352,8 @@
} else if (args[i] == "TIMEOUT") {
++i;
if (i >= args.size()) {
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
- "expected timeout value after TIMEOUT");
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR, "expected timeout value after TIMEOUT");
return false;
}
long scanned;
@@ -2405,7 +2361,7 @@
scanned < 0) {
std::ostringstream e;
e << "TIMEOUT value \"" << args[i] << "\" is not an unsigned integer.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
return false;
}
timeout = static_cast<unsigned long>(scanned);
@@ -2413,7 +2369,7 @@
std::ostringstream e;
e << "expected DIRECTORY, RELEASE, GUARD, RESULT_VARIABLE or TIMEOUT\n";
e << "but got: \"" << args[i] << "\".";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
return false;
}
}
@@ -2423,7 +2379,7 @@
}
if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
+ path = status.GetMakefile().GetCurrentSourceDirectory() + "/" + path;
}
// Unify path (remove '//', '/../', ...)
@@ -2435,7 +2391,7 @@
std::ostringstream e;
e << "directory\n \"" << parentDir << "\"\ncreation failed ";
e << "(check permissions).";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -2443,7 +2399,7 @@
if (!file) {
std::ostringstream e;
e << "file\n \"" << path << "\"\ncreation failed (check permissions).";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -2451,7 +2407,7 @@
// Actual lock/unlock
cmFileLockPool& lockPool =
- this->Makefile->GetGlobalGenerator()->GetFileLockPool();
+ status.GetMakefile().GetGlobalGenerator()->GetFileLockPool();
cmFileLockResult fileLockResult(cmFileLockResult::MakeOk());
if (release) {
@@ -2478,32 +2434,32 @@
if (resultVariable.empty() && !fileLockResult.IsOk()) {
std::ostringstream e;
e << "error locking file\n \"" << path << "\"\n" << result << ".";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ status.GetMakefile().IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
if (!resultVariable.empty()) {
- this->Makefile->AddDefinition(resultVariable, result);
+ status.GetMakefile().AddDefinition(resultVariable, result);
}
return true;
#else
static_cast<void>(args);
- this->SetError("sub-command LOCK not implemented in bootstrap cmake");
+ status.SetError("sub-command LOCK not implemented in bootstrap cmake");
return false;
#endif
}
-bool cmFileCommand::HandleTimestampCommand(
- std::vector<std::string> const& args)
+bool HandleTimestampCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("sub-command TIMESTAMP requires at least two arguments.");
+ status.SetError("sub-command TIMESTAMP requires at least two arguments.");
return false;
}
if (args.size() > 5) {
- this->SetError("sub-command TIMESTAMP takes at most four arguments.");
+ status.SetError("sub-command TIMESTAMP takes at most four arguments.");
return false;
}
@@ -2525,7 +2481,7 @@
} else {
std::string e = " TIMESTAMP sub-command does not recognize option " +
args[argsIndex] + ".";
- this->SetError(e);
+ status.SetError(e);
return false;
}
}
@@ -2533,17 +2489,18 @@
cmTimestamp timestamp;
std::string result =
timestamp.FileModificationTime(filename.c_str(), formatString, utcFlag);
- this->Makefile->AddDefinition(outputVariable, result);
+ status.GetMakefile().AddDefinition(outputVariable, result);
return true;
}
-bool cmFileCommand::HandleSizeCommand(std::vector<std::string> const& args)
+bool HandleSizeCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
std::ostringstream e;
e << args[0] << " requires a file name and output variable";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -2556,23 +2513,23 @@
if (!cmSystemTools::FileExists(filename, true)) {
std::ostringstream e;
e << "SIZE requested of path that is not readable:\n " << filename;
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- this->Makefile->AddDefinition(
+ status.GetMakefile().AddDefinition(
outputVariable, std::to_string(cmSystemTools::FileLength(filename)));
return true;
}
-bool cmFileCommand::HandleReadSymlinkCommand(
- std::vector<std::string> const& args)
+bool HandleReadSymlinkCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() != 3) {
std::ostringstream e;
e << args[0] << " requires a file name and output variable";
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -2584,21 +2541,21 @@
std::ostringstream e;
e << "READ_SYMLINK requested of path that is not a symlink:\n "
<< filename;
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
- this->Makefile->AddDefinition(outputVariable, result);
+ status.GetMakefile().AddDefinition(outputVariable, result);
return true;
}
-bool cmFileCommand::HandleCreateLinkCommand(
- std::vector<std::string> const& args)
+bool HandleCreateLinkCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
if (args.size() < 3) {
- this->SetError("CREATE_LINK must be called with at least two additional "
- "arguments");
+ status.SetError("CREATE_LINK must be called with at least two additional "
+ "arguments");
return false;
}
@@ -2623,7 +2580,7 @@
parser.Parse(cmMakeRange(args).advance(3), &unconsumedArgs);
if (!unconsumedArgs.empty()) {
- this->SetError("unknown argument: \"" + unconsumedArgs.front() + '\"');
+ status.SetError("unknown argument: \"" + unconsumedArgs.front() + '\"');
return false;
}
@@ -2634,10 +2591,10 @@
if (fileName == newFileName) {
result = "CREATE_LINK cannot use same file and newfile";
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, result);
+ status.GetMakefile().AddDefinition(arguments.Result, result);
return true;
}
- this->SetError(result);
+ status.SetError(result);
return false;
}
@@ -2645,10 +2602,10 @@
if (!arguments.Symbolic && !cmSystemTools::FileExists(fileName)) {
result = "Cannot hard link \'" + fileName + "\' as it does not exist.";
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, result);
+ status.GetMakefile().AddDefinition(arguments.Result, result);
return true;
}
- this->SetError(result);
+ status.SetError(result);
return false;
}
@@ -2662,10 +2619,10 @@
<< cmSystemTools::GetLastSystemError() << "\n";
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, e.str());
+ status.GetMakefile().AddDefinition(arguments.Result, e.str());
return true;
}
- this->SetError(e.str());
+ status.SetError(e.str());
return false;
}
@@ -2692,45 +2649,46 @@
result = "0";
} else if (arguments.Result.empty()) {
// The operation failed and the result is not reported in a variable.
- this->SetError(result);
+ status.SetError(result);
return false;
}
if (!arguments.Result.empty()) {
- this->Makefile->AddDefinition(arguments.Result, result);
+ status.GetMakefile().AddDefinition(arguments.Result, result);
}
return true;
}
-bool cmFileCommand::HandleGetRuntimeDependenciesCommand(
- std::vector<std::string> const& args)
+bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
static const std::set<std::string> supportedPlatforms = { "Windows", "Linux",
"Darwin" };
std::string platform =
- this->Makefile->GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");
+ status.GetMakefile().GetSafeDefinition("CMAKE_HOST_SYSTEM_NAME");
if (!supportedPlatforms.count(platform)) {
std::ostringstream e;
e << "GET_RUNTIME_DEPENDENCIES is not supported on system \"" << platform
<< "\"";
- this->SetError(e.str());
+ status.SetError(e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
- if (this->Makefile->GetState()->GetMode() == cmState::Project) {
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING,
- "You have used file(GET_RUNTIME_DEPENDENCIES)"
- " in project mode. This is probably not what "
- "you intended to do. Instead, please consider"
- " using it in an install(CODE) or "
- "install(SCRIPT) command. For example:"
- "\n install(CODE [["
- "\n file(GET_RUNTIME_DEPENDENCIES"
- "\n # ..."
- "\n )"
- "\n ]])");
+ if (status.GetMakefile().GetState()->GetMode() == cmState::Project) {
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ "You have used file(GET_RUNTIME_DEPENDENCIES)"
+ " in project mode. This is probably not what "
+ "you intended to do. Instead, please consider"
+ " using it in an install(CODE) or "
+ "install(SCRIPT) command. For example:"
+ "\n install(CODE [["
+ "\n file(GET_RUNTIME_DEPENDENCIES"
+ "\n # ..."
+ "\n )"
+ "\n ]])");
}
struct Arguments
@@ -2775,7 +2733,7 @@
if (argIt != unrecognizedArguments.end()) {
std::ostringstream e;
e << "Unrecognized argument: \"" << *argIt << "\"";
- this->SetError(e.str());
+ status.SetError(e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -2783,13 +2741,13 @@
if (argIt != keywordsMissingValues.end()) {
std::ostringstream e;
e << "Keyword missing value: " << *argIt;
- this->SetError(e.str());
+ status.SetError(e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
cmRuntimeDependencyArchive archive(
- this, parsedArgs.Directories, parsedArgs.BundleExecutable,
+ status, parsedArgs.Directories, parsedArgs.BundleExecutable,
parsedArgs.PreIncludeRegexes, parsedArgs.PreExcludeRegexes,
parsedArgs.PostIncludeRegexes, parsedArgs.PostExcludeRegexes);
if (!archive.Prepare()) {
@@ -2825,14 +2783,14 @@
std::string varName =
parsedArgs.ConflictingDependenciesPrefix + "_" + val.first;
std::string pathsStr = cmJoin(paths, ";");
- this->Makefile->AddDefinition(varName, pathsStr);
+ status.GetMakefile().AddDefinition(varName, pathsStr);
} else {
std::ostringstream e;
e << "Multiple conflicting paths found for " << val.first << ":";
for (auto const& path : val.second) {
e << "\n " << path;
}
- this->SetError(e.str());
+ status.SetError(e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -2847,7 +2805,7 @@
assert(it != archive.GetUnresolvedPaths().end());
std::ostringstream e;
e << "Could not resolve file " << *it;
- this->SetError(e.str());
+ status.SetError(e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -2855,16 +2813,76 @@
if (!parsedArgs.ResolvedDependenciesVar.empty()) {
std::string val = cmJoin(deps, ";");
- this->Makefile->AddDefinition(parsedArgs.ResolvedDependenciesVar, val);
+ status.GetMakefile().AddDefinition(parsedArgs.ResolvedDependenciesVar,
+ val);
}
if (!parsedArgs.UnresolvedDependenciesVar.empty()) {
std::string val = cmJoin(unresolvedDeps, ";");
- this->Makefile->AddDefinition(parsedArgs.UnresolvedDependenciesVar, val);
+ status.GetMakefile().AddDefinition(parsedArgs.UnresolvedDependenciesVar,
+ val);
}
if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
std::string val = cmJoin(conflictingDeps, ";");
- this->Makefile->AddDefinition(
+ status.GetMakefile().AddDefinition(
parsedArgs.ConflictingDependenciesPrefix + "_FILENAMES", val);
}
return true;
}
+
+} // namespace
+
+bool cmFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 2) {
+ status.SetError("must be called with at least two arguments.");
+ return false;
+ }
+
+ static cmSubcommandTable const subcommand{
+ { "WRITE"_s, HandleWriteCommand },
+ { "APPEND"_s, HandleAppendCommand },
+ { "DOWNLOAD"_s, HandleDownloadCommand },
+ { "UPLOAD"_s, HandleUploadCommand },
+ { "READ"_s, HandleReadCommand },
+ { "MD5"_s, HandleHashCommand },
+ { "SHA1"_s, HandleHashCommand },
+ { "SHA224"_s, HandleHashCommand },
+ { "SHA256"_s, HandleHashCommand },
+ { "SHA384"_s, HandleHashCommand },
+ { "SHA512"_s, HandleHashCommand },
+ { "SHA3_224"_s, HandleHashCommand },
+ { "SHA3_256"_s, HandleHashCommand },
+ { "SHA3_384"_s, HandleHashCommand },
+ { "SHA3_512"_s, HandleHashCommand },
+ { "STRINGS"_s, HandleStringsCommand },
+ { "GLOB"_s, HandleGlobCommand },
+ { "GLOB_RECURSE"_s, HandleGlobRecurseCommand },
+ { "MAKE_DIRECTORY"_s, HandleMakeDirectoryCommand },
+ { "RENAME"_s, HandleRename },
+ { "REMOVE"_s, HandleRemove },
+ { "REMOVE_RECURSE"_s, HandleRemoveRecurse },
+ { "COPY"_s, HandleCopyCommand },
+ { "INSTALL"_s, HandleInstallCommand },
+ { "DIFFERENT"_s, HandleDifferentCommand },
+ { "RPATH_CHANGE"_s, HandleRPathChangeCommand },
+ { "CHRPATH"_s, HandleRPathChangeCommand },
+ { "RPATH_CHECK"_s, HandleRPathCheckCommand },
+ { "RPATH_REMOVE"_s, HandleRPathRemoveCommand },
+ { "READ_ELF"_s, HandleReadElfCommand },
+ { "RELATIVE_PATH"_s, HandleRelativePathCommand },
+ { "TO_CMAKE_PATH"_s, HandleCMakePathCommand },
+ { "TO_NATIVE_PATH"_s, HandleNativePathCommand },
+ { "TOUCH"_s, HandleTouchCommand },
+ { "TOUCH_NOCREATE"_s, HandleTouchNocreateCommand },
+ { "TIMESTAMP"_s, HandleTimestampCommand },
+ { "GENERATE"_s, HandleGenerateCommand },
+ { "LOCK"_s, HandleLockCommand },
+ { "SIZE"_s, HandleSizeCommand },
+ { "READ_SYMLINK"_s, HandleReadSymlinkCommand },
+ { "CREATE_LINK"_s, HandleCreateLinkCommand },
+ { "GET_RUNTIME_DEPENDENCIES"_s, HandleGetRuntimeDependenciesCommand },
+ };
+
+ return subcommand(args[0], args, status);
+}
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index d4b980e..8c9b219 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -8,72 +8,9 @@
#include <string>
#include <vector>
-#include "cm_memory.hxx"
-
-#include "cmCommand.h"
-
class cmExecutionStatus;
-/** \class cmFileCommand
- * \brief Command for manipulation of files
- *
- */
-class cmFileCommand : public cmCommand
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmFileCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-protected:
- bool HandleRename(std::vector<std::string> const& args);
- bool HandleRemove(std::vector<std::string> const& args, bool recurse);
- bool HandleWriteCommand(std::vector<std::string> const& args, bool append);
- bool HandleReadCommand(std::vector<std::string> const& args);
- bool HandleHashCommand(std::vector<std::string> const& args);
- bool HandleStringsCommand(std::vector<std::string> const& args);
- bool HandleGlobCommand(std::vector<std::string> const& args, bool recurse);
- bool HandleTouchCommand(std::vector<std::string> const& args, bool create);
- bool HandleMakeDirectoryCommand(std::vector<std::string> const& args);
-
- bool HandleRelativePathCommand(std::vector<std::string> const& args);
- bool HandleCMakePathCommand(std::vector<std::string> const& args,
- bool nativePath);
- bool HandleReadElfCommand(std::vector<std::string> const& args);
- bool HandleRPathChangeCommand(std::vector<std::string> const& args);
- bool HandleRPathCheckCommand(std::vector<std::string> const& args);
- bool HandleRPathRemoveCommand(std::vector<std::string> const& args);
- bool HandleDifferentCommand(std::vector<std::string> const& args);
-
- bool HandleCopyCommand(std::vector<std::string> const& args);
- bool HandleInstallCommand(std::vector<std::string> const& args);
- bool HandleDownloadCommand(std::vector<std::string> const& args);
- bool HandleUploadCommand(std::vector<std::string> const& args);
-
- bool HandleTimestampCommand(std::vector<std::string> const& args);
- bool HandleGenerateCommand(std::vector<std::string> const& args);
- bool HandleLockCommand(std::vector<std::string> const& args);
- bool HandleSizeCommand(std::vector<std::string> const& args);
- bool HandleReadSymlinkCommand(std::vector<std::string> const& args);
- bool HandleCreateLinkCommand(std::vector<std::string> const& args);
- bool HandleGetRuntimeDependenciesCommand(
- std::vector<std::string> const& args);
-
-private:
- void AddEvaluationFile(const std::string& inputName,
- const std::string& outputExpr,
- const std::string& condition, bool inputIsContent);
-};
+bool cmFileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
#endif
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 4f1a158..62f132d 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -3,10 +3,11 @@
#include "cmFileCopier.h"
+#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
-#include "cmFileCommand.h"
#include "cmFileTimes.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmsys/Directory.hxx"
#include "cmsys/Glob.hxx"
@@ -20,9 +21,9 @@
using namespace cmFSPermissions;
-cmFileCopier::cmFileCopier(cmFileCommand* command, const char* name)
- : FileCommand(command)
- , Makefile(command->GetMakefile())
+cmFileCopier::cmFileCopier(cmExecutionStatus& status, const char* name)
+ : Status(status)
+ , Makefile(&status.GetMakefile())
, Name(name)
, Always(false)
, MatchlessFiles(true)
@@ -91,7 +92,7 @@
if (!cmSystemTools::SetPermissions(toFile, permissions)) {
std::ostringstream e;
e << this->Name << " cannot set permissions on \"" << toFile << "\"";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
}
@@ -105,7 +106,7 @@
if (!cmFSPermissions::stringToModeT(arg, permissions)) {
std::ostringstream e;
e << this->Name << " given invalid permission \"" << arg << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
return true;
@@ -121,7 +122,7 @@
// The input file does not exist and installation is not optional.
std::ostringstream e;
e << this->Name << " cannot find \"" << fromFile << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -129,7 +130,7 @@
{
std::ostringstream e;
e << "option " << arg << " may not appear before PATTERN or REGEX.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
@@ -137,7 +138,7 @@
{
std::ostringstream e;
e << "option " << arg << " may not appear after PATTERN or REGEX.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
@@ -174,7 +175,7 @@
cmSystemTools::ExpandListArgument(default_dir_install_permissions, items);
for (const auto& arg : items) {
if (!this->CheckPermissions(arg, **mode)) {
- this->FileCommand->SetError(
+ this->Status.SetError(
" Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable.");
return false;
}
@@ -194,7 +195,7 @@
if (!this->CheckKeyword(args[i]) && !this->CheckValue(args[i])) {
std::ostringstream e;
e << "called with unknown argument \"" << args[i] << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -208,7 +209,7 @@
if (this->Destination.empty()) {
std::ostringstream e;
e << this->Name << " given no DESTINATION";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -341,7 +342,7 @@
} else {
std::ostringstream e;
e << "could not compile PATTERN \"" << arg << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
} break;
@@ -353,7 +354,7 @@
} else {
std::ostringstream e;
e << "could not compile REGEX \"" << arg << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
}
break;
@@ -396,8 +397,8 @@
file += "/";
file += f;
} else if (!this->FilesFromDir.empty()) {
- this->FileCommand->SetError("option FILES_FROM_DIR requires all files "
- "to be specified as relative paths.");
+ this->Status.SetError("option FILES_FROM_DIR requires all files "
+ "to be specified as relative paths.");
return false;
} else {
file = f;
@@ -446,7 +447,7 @@
if (fromFile.empty()) {
std::ostringstream e;
e << "INSTALL encountered an empty string input file name.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -490,7 +491,7 @@
while (cmSystemTools::ReadSymlink(fromFile, newFromFile)) {
if (!cmSystemTools::FileIsFullPath(newFromFile)) {
std::string fromFilePath = cmSystemTools::GetFilenamePath(fromFile);
- newFromFile = fromFilePath + "/" + newFromFile;
+ newFromFile = cmStrCat(fromFilePath, "/", newFromFile);
}
std::string symlinkTarget = cmSystemTools::GetFilenameName(newFromFile);
@@ -514,13 +515,13 @@
if (!cmSystemTools::CreateSymlink(symlinkTarget, toFile)) {
std::ostringstream e;
e << this->Name << " cannot create symlink \"" << toFile << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
}
fromFile = newFromFile;
- toFile = toFilePath + "/" + symlinkTarget;
+ toFile = cmStrCat(toFilePath, "/", symlinkTarget);
}
return true;
@@ -535,7 +536,7 @@
std::ostringstream e;
e << this->Name << " cannot read symlink \"" << fromFile
<< "\" to duplicate at \"" << toFile << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -566,7 +567,7 @@
std::ostringstream e;
e << this->Name << " cannot duplicate symlink \"" << fromFile
<< "\" at \"" << toFile << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
}
@@ -595,7 +596,7 @@
std::ostringstream e;
e << this->Name << " cannot copy file \"" << fromFile << "\" to \""
<< toFile << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
@@ -611,7 +612,7 @@
std::ostringstream e;
e << this->Name << " cannot set modification time on \"" << toFile
<< "\"";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
}
@@ -648,7 +649,7 @@
std::ostringstream e;
e << this->Name << " cannot make directory \"" << destination
<< "\": " << cmSystemTools::GetLastSystemError();
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index a79a60b..263a365 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -12,19 +12,19 @@
#include <string>
#include <vector>
-class cmFileCommand;
+class cmExecutionStatus;
class cmMakefile;
// File installation helper class.
struct cmFileCopier
{
- cmFileCopier(cmFileCommand* command, const char* name = "COPY");
+ cmFileCopier(cmExecutionStatus& status, const char* name = "COPY");
virtual ~cmFileCopier();
bool Run(std::vector<std::string> const& args);
protected:
- cmFileCommand* FileCommand;
+ cmExecutionStatus& Status;
cmMakefile* Makefile;
const char* Name;
bool Always;
diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx
index 9378439..d28ef41 100644
--- a/Source/cmFileInstaller.cxx
+++ b/Source/cmFileInstaller.cxx
@@ -3,8 +3,8 @@
#include "cmFileInstaller.h"
+#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
-#include "cmFileCommand.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
@@ -14,8 +14,8 @@
using namespace cmFSPermissions;
-cmFileInstaller::cmFileInstaller(cmFileCommand* command)
- : cmFileCopier(command, "INSTALL")
+cmFileInstaller::cmFileInstaller(cmExecutionStatus& status)
+ : cmFileCopier(status, "INSTALL")
, InstallType(cmInstallType_FILES)
, Optional(false)
, MessageAlways(false)
@@ -111,19 +111,19 @@
if (!this->Rename.empty()) {
if (!this->FilesFromDir.empty()) {
- this->FileCommand->SetError("INSTALL option RENAME may not be "
- "combined with FILES_FROM_DIR.");
+ this->Status.SetError("INSTALL option RENAME may not be "
+ "combined with FILES_FROM_DIR.");
return false;
}
if (this->InstallType != cmInstallType_FILES &&
this->InstallType != cmInstallType_PROGRAMS) {
- this->FileCommand->SetError("INSTALL option RENAME may be used "
- "only with FILES or PROGRAMS.");
+ this->Status.SetError("INSTALL option RENAME may be used "
+ "only with FILES or PROGRAMS.");
return false;
}
if (this->Files.size() > 1) {
- this->FileCommand->SetError("INSTALL option RENAME may be used "
- "only with one file.");
+ this->Status.SetError("INSTALL option RENAME may be used "
+ "only with one file.");
return false;
}
}
@@ -134,9 +134,9 @@
if (((this->MessageAlways ? 1 : 0) + (this->MessageLazy ? 1 : 0) +
(this->MessageNever ? 1 : 0)) > 1) {
- this->FileCommand->SetError("INSTALL options MESSAGE_ALWAYS, "
- "MESSAGE_LAZY, and MESSAGE_NEVER "
- "are mutually exclusive.");
+ this->Status.SetError("INSTALL options MESSAGE_ALWAYS, "
+ "MESSAGE_LAZY, and MESSAGE_NEVER "
+ "are mutually exclusive.");
return false;
}
@@ -213,7 +213,7 @@
e << "INSTALL called with old-style " << arg << " argument. "
<< "This script was generated with an older version of CMake. "
<< "Re-run this cmake version on your build tree.";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
this->Doing = DoingError;
} else {
return this->cmFileCopier::CheckKeyword(arg);
@@ -257,7 +257,7 @@
} else {
std::ostringstream e;
e << "Option TYPE given unknown value \"" << stype << "\".";
- this->FileCommand->SetError(e.str());
+ this->Status.SetError(e.str());
return false;
}
return true;
@@ -269,8 +269,8 @@
// allow for / to be a valid destination
if (destination.size() < 2 && destination != "/") {
- this->FileCommand->SetError("called with inappropriate arguments. "
- "No DESTINATION provided or .");
+ this->Status.SetError("called with inappropriate arguments. "
+ "No DESTINATION provided or .");
return false;
}
@@ -300,7 +300,7 @@
if (relative) {
// This is relative path on unix or windows. Since we are doing
// destdir, this case does not make sense.
- this->FileCommand->SetError(
+ this->Status.SetError(
"called with relative DESTINATION. This "
"does not make sense when using DESTDIR. Specify "
"absolute path or remove DESTDIR environment variable.");
@@ -315,7 +315,7 @@
"absolute path or remove DESTDIR environment variable."
"\nDESTINATION=\n";
message += destination;
- this->FileCommand->SetError(message);
+ this->Status.SetError(message);
return false;
}
}
@@ -335,14 +335,14 @@
if (!cmSystemTools::MakeDirectory(destination, default_dir_mode)) {
std::string errstring = "cannot create directory: " + destination +
". Maybe need administrative privileges.";
- this->FileCommand->SetError(errstring);
+ this->Status.SetError(errstring);
return false;
}
}
if (!cmSystemTools::FileIsDirectory(destination)) {
std::string errstring =
"INSTALL destination: " + destination + " is not a directory.";
- this->FileCommand->SetError(errstring);
+ this->Status.SetError(errstring);
return false;
}
}
diff --git a/Source/cmFileInstaller.h b/Source/cmFileInstaller.h
index 312529a..fd883ea 100644
--- a/Source/cmFileInstaller.h
+++ b/Source/cmFileInstaller.h
@@ -12,11 +12,11 @@
#include <string>
#include <vector>
-class cmFileCommand;
+class cmExecutionStatus;
struct cmFileInstaller : public cmFileCopier
{
- cmFileInstaller(cmFileCommand* command);
+ cmFileInstaller(cmExecutionStatus& status);
~cmFileInstaller() override;
protected:
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index be7964a..b1ccc83 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -13,6 +13,7 @@
#include "cmSearchPath.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmFindBase::cmFindBase()
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index db3f4ef..0159ca5 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -28,6 +28,7 @@
#include "cmSearchPath.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmVersion.h"
#if defined(__HAIKU__)
@@ -516,7 +517,9 @@
loadedPackage = true;
} else {
// The package was not loaded. Report errors.
- HandlePackageMode(HandlePackageModeType::Module);
+ if (HandlePackageMode(HandlePackageModeType::Module)) {
+ loadedPackage = true;
+ }
}
}
} else {
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index 782f746..8fcf1ac 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -4,6 +4,7 @@
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
@@ -71,7 +72,7 @@
bool CheckDirectoryForName(std::string const& path, std::string const& name)
{
for (std::string const& ext : this->Extensions) {
- if (!ext.empty() && cmSystemTools::StringEndsWith(name, ext.c_str())) {
+ if (!ext.empty() && cmHasSuffix(name, ext)) {
continue;
}
this->TestNameExt = name;
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 06dce2c..a565786 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -8,16 +8,40 @@
#include <utility>
#include "cm_memory.hxx"
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
#include "cmExecutionStatus.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmSystemTools.h"
+class cmForEachFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmForEachFunctionBlocker(cmMakefile* mf);
+ ~cmForEachFunctionBlocker() override;
+
+ cm::string_view StartCommandName() const override { return "foreach"_s; }
+ cm::string_view EndCommandName() const override { return "endforeach"_s; }
+
+ bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus) override;
+
+ std::vector<std::string> Args;
+
+private:
+ cmMakefile* Makefile;
+};
+
cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf)
: Makefile(mf)
- , Depth(0)
{
this->Makefile->PushLoopBlock();
}
@@ -27,87 +51,55 @@
this->Makefile->PopLoopBlock();
}
-bool cmForEachFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus& inStatus)
+bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const
{
- if (lff.Name.Lower == "foreach") {
- // record the number of nested foreach commands
- this->Depth++;
- } else if (lff.Name.Lower == "endforeach") {
- // if this is the endofreach for this statement
- if (!this->Depth) {
- // Remove the function blocker for this scope or bail.
- std::unique_ptr<cmFunctionBlocker> fb(
- mf.RemoveFunctionBlocker(this, lff));
- if (!fb) {
- return false;
- }
-
- // at end of for each execute recorded commands
- // store the old value
- std::string oldDef;
- if (mf.GetDefinition(this->Args[0])) {
- oldDef = mf.GetDefinition(this->Args[0]);
- }
-
- for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
- // set the variable to the loop value
- mf.AddDefinition(this->Args[0], arg);
- // Invoke all the functions that were collected in the block.
- cmExecutionStatus status(mf);
- for (cmListFileFunction const& func : this->Functions) {
- status.Clear();
- mf.ExecuteCommand(func, status);
- if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
- return true;
- }
- if (status.GetBreakInvoked()) {
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
- return true;
- }
- if (status.GetContinueInvoked()) {
- break;
- }
- if (cmSystemTools::GetFatalErrorOccured()) {
- return true;
- }
- }
- }
-
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
- return true;
- }
- // close out a nested foreach
- this->Depth--;
- }
-
- // record the command
- this->Functions.push_back(lff);
-
- // always return true
- return true;
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments);
+ return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
}
-bool cmForEachFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile& mf)
+bool cmForEachFunctionBlocker::Replay(
+ std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus)
{
- if (lff.Name.Lower == "endforeach") {
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments);
- // if the endforeach has arguments then make sure
- // they match the begin foreach arguments
- if ((expandedArguments.empty() ||
- (expandedArguments[0] == this->Args[0]))) {
- return true;
+ cmMakefile& mf = inStatus.GetMakefile();
+ // at end of for each execute recorded commands
+ // store the old value
+ std::string oldDef;
+ if (mf.GetDefinition(this->Args[0])) {
+ oldDef = mf.GetDefinition(this->Args[0]);
+ }
+
+ for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
+ // set the variable to the loop value
+ mf.AddDefinition(this->Args[0], arg);
+ // Invoke all the functions that were collected in the block.
+ for (cmListFileFunction const& func : functions) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(func, status);
+ if (status.GetReturnInvoked()) {
+ inStatus.SetReturnInvoked();
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0], oldDef);
+ return true;
+ }
+ if (status.GetBreakInvoked()) {
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0], oldDef);
+ return true;
+ }
+ if (status.GetContinueInvoked()) {
+ break;
+ }
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ return true;
+ }
}
}
- return false;
+
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args[0], oldDef);
+ return true;
}
bool cmForEachCommand::InitialPass(std::vector<std::string> const& args,
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index cd112b8..135abf0 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -11,28 +11,8 @@
#include "cm_memory.hxx"
#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
class cmExecutionStatus;
-class cmMakefile;
-
-class cmForEachFunctionBlocker : public cmFunctionBlocker
-{
-public:
- cmForEachFunctionBlocker(cmMakefile* mf);
- ~cmForEachFunctionBlocker() override;
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
-
- std::vector<std::string> Args;
- std::vector<cmListFileFunction> Functions;
-
-private:
- cmMakefile* Makefile;
- int Depth;
-};
/// Starts foreach() ... endforeach() block
class cmForEachCommand : public cmCommand
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
new file mode 100644
index 0000000..5778a71
--- /dev/null
+++ b/Source/cmFunctionBlocker.cxx
@@ -0,0 +1,46 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmFunctionBlocker.h"
+
+#include <cassert>
+#include <sstream>
+#include <utility>
+
+#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+
+bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
+ cmExecutionStatus& status)
+{
+ if (lff.Name.Lower == this->StartCommandName()) {
+ this->ScopeDepth++;
+ } else if (lff.Name.Lower == this->EndCommandName()) {
+ this->ScopeDepth--;
+ if (this->ScopeDepth == 0U) {
+ cmMakefile& mf = status.GetMakefile();
+ auto self = mf.RemoveFunctionBlocker();
+ assert(self.get() == this);
+
+ if (!this->ArgumentsMatch(lff, mf)) {
+ cmListFileContext const& lfc = this->GetStartingContext();
+ cmListFileContext closingContext =
+ cmListFileContext::FromCommandContext(lff, lfc.FilePath);
+ std::ostringstream e;
+ /* clang-format off */
+ e << "A logical block opening on the line\n"
+ << " " << lfc << "\n"
+ << "closes on the line\n"
+ << " " << closingContext << "\n"
+ << "with mis-matching arguments.";
+ /* clang-format on */
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
+ }
+
+ return this->Replay(std::move(this->Functions), status);
+ }
+ }
+
+ this->Functions.push_back(lff);
+ return true;
+}
diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h
index cd6b05d..87bdccd 100644
--- a/Source/cmFunctionBlocker.h
+++ b/Source/cmFunctionBlocker.h
@@ -3,6 +3,12 @@
#ifndef cmFunctionBlocker_h
#define cmFunctionBlocker_h
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <vector>
+
+#include "cm_string_view.hxx"
+
#include "cmListFileCache.h"
class cmExecutionStatus;
@@ -14,17 +20,8 @@
/**
* should a function be blocked
*/
- virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus& status) = 0;
-
- /**
- * should this function blocker be removed, useful when one function adds a
- * blocker and another must remove it
- */
- virtual bool ShouldRemove(const cmListFileFunction&, cmMakefile&)
- {
- return false;
- }
+ bool IsFunctionBlocked(cmListFileFunction const& lff,
+ cmExecutionStatus& status);
virtual ~cmFunctionBlocker() = default;
@@ -39,7 +36,19 @@
}
private:
+ virtual cm::string_view StartCommandName() const = 0;
+ virtual cm::string_view EndCommandName() const = 0;
+
+ virtual bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const = 0;
+
+ virtual bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status) = 0;
+
+private:
cmListFileContext StartingContext;
+ std::vector<cmListFileFunction> Functions;
+ unsigned int ScopeDepth = 1;
};
#endif
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 6afd31a..610f516 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -5,12 +5,18 @@
#include <sstream>
#include <utility>
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
+
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
// define the class for function commands
class cmFunctionHelperCommand
@@ -101,53 +107,42 @@
return true;
}
-bool cmFunctionFunctionBlocker::IsFunctionBlocked(
- const cmListFileFunction& lff, cmMakefile& mf, cmExecutionStatus&)
+class cmFunctionFunctionBlocker : public cmFunctionBlocker
{
- // record commands until we hit the ENDFUNCTION
- // at the ENDFUNCTION call we shift gears and start looking for invocations
- if (lff.Name.Lower == "function") {
- this->Depth++;
- } else if (lff.Name.Lower == "endfunction") {
- // if this is the endfunction for this function then execute
- if (!this->Depth) {
- // create a new command and add it to cmake
- cmFunctionHelperCommand f;
- f.Args = this->Args;
- f.Functions = this->Functions;
- f.FilePath = this->GetStartingContext().FilePath;
- mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
- // remove the function blocker now that the function is defined
- mf.RemoveFunctionBlocker(this, lff);
- return true;
- }
- // decrement for each nested function that ends
- this->Depth--;
- }
+public:
+ cm::string_view StartCommandName() const override { return "function"_s; }
+ cm::string_view EndCommandName() const override { return "endfunction"_s; }
- // if it wasn't an endfunction and we are not executing then we must be
- // recording
- this->Functions.push_back(lff);
- return true;
+ bool ArgumentsMatch(cmListFileFunction const&,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status) override;
+
+ std::vector<std::string> Args;
+};
+
+bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const
+{
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
+ return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
}
-bool cmFunctionFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile& mf)
+bool cmFunctionFunctionBlocker::Replay(
+ std::vector<cmListFileFunction> functions, cmExecutionStatus& status)
{
- if (lff.Name.Lower == "endfunction") {
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments,
- this->GetStartingContext().FilePath.c_str());
- // if the endfunction has arguments then make sure
- // they match the ones in the opening function command
- if ((expandedArguments.empty() ||
- (expandedArguments[0] == this->Args[0]))) {
- return true;
- }
- }
-
- return false;
+ cmMakefile& mf = status.GetMakefile();
+ // create a new command and add it to cmake
+ cmFunctionHelperCommand f;
+ f.Args = this->Args;
+ f.Functions = std::move(functions);
+ f.FilePath = this->GetStartingContext().FilePath;
+ mf.RecordPolicies(f.Policies);
+ mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
+ return true;
}
bool cmFunctionCommand::InitialPass(std::vector<std::string> const& args,
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index 449a180..b334525 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -11,23 +11,8 @@
#include "cm_memory.hxx"
#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
class cmExecutionStatus;
-class cmMakefile;
-
-class cmFunctionFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
-
- std::vector<std::string> Args;
- std::vector<cmListFileFunction> Functions;
- int Depth = 0;
-};
/// Starts function() ... endfunction() block
class cmFunctionCommand : public cmCommand
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2f47788..7475e9f 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -6,14 +6,14 @@
#include "cmSystemTools.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cm_codecvt.hxx"
# include "cm_zlib.h"
#endif
cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if (encoding != codecvt::None) {
imbue(std::locale(getloc(), new codecvt(encoding)));
}
@@ -32,7 +32,7 @@
cmSystemTools::Error("Cannot open file for write: " + this->TempName);
cmSystemTools::ReportLastSystemError("");
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if (encoding != codecvt::None) {
imbue(std::locale(getloc(), new codecvt(encoding)));
}
@@ -169,7 +169,7 @@
return replaced;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname,
std::string const& newname)
{
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 817f41e..df2227f 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -2,12 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionDAGChecker.h"
-#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmake.h"
#include <sstream>
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 49d0c47..f78c72e 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -19,6 +19,7 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cm_static_string_view.hxx"
@@ -1440,7 +1441,7 @@
}
for (std::string& o : objects) {
- o = obj_dir + o;
+ o = cmStrCat(obj_dir, o);
}
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7c41045..c07d7af 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -34,6 +34,7 @@
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
@@ -2525,7 +2526,7 @@
info.WindowsExportAllSymbols =
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS");
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
info.DefFileGenerated =
info.WindowsExportAllSymbols || info.Sources.size() > 1;
#else
@@ -3409,8 +3410,7 @@
cmSystemTools::ParseUnixCommandLine(
value.c_str() + LINKER_SHELL.length(), linkerOptions);
} else {
- linkerOptions =
- cmSystemTools::tokenize(value.substr(LINKER.length()), ",");
+ linkerOptions = cmTokenize(value.substr(LINKER.length()), ",");
}
if (linkerOptions.empty() ||
@@ -4191,7 +4191,7 @@
if (stripResources) {
flags.MacFolder = "";
}
- } else if (cmSystemTools::StringStartsWith(location, "Resources/")) {
+ } else if (cmHasLiteralPrefix(location, "Resources/")) {
flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
if (stripResources) {
flags.MacFolder += strlen("Resources/");
@@ -5218,7 +5218,7 @@
const std::string& config, cmOptionalLinkInterface& iface,
cmGeneratorTarget const* headTarget) const
{
- if (iface.ExplicitLibraries) {
+ if (iface.Explicit) {
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -5602,8 +5602,9 @@
// libraries and executables that export symbols.
const char* explicitLibraries = nullptr;
std::string linkIfaceProp;
- if (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
- this->GetPolicyStatusCMP0022() != cmPolicies::WARN) {
+ bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
+ this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
+ if (cmp0022NEW) {
// CMP0022 NEW behavior is to use INTERFACE_LINK_LIBRARIES.
linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
explicitLibraries = this->GetProperty(linkIfaceProp);
@@ -5658,15 +5659,14 @@
return;
}
iface.Exists = true;
- iface.ExplicitLibraries = explicitLibraries;
+ iface.Explicit = cmp0022NEW || explicitLibraries != nullptr;
if (explicitLibraries) {
// The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
usage_requirements_only, iface.Libraries,
iface.HadHeadSensitiveCondition);
- } else if (this->GetPolicyStatusCMP0022() == cmPolicies::WARN ||
- this->GetPolicyStatusCMP0022() == cmPolicies::OLD)
+ } else if (!cmp0022NEW)
// If CMP0022 is NEW then the plain tll signature sets the
// INTERFACE_LINK_LIBRARIES, so if we get here then the project
// cleared the property explicitly and we should not fall back
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index 8538944..38fee28 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -4,10 +4,10 @@
#include <set>
-#include "cmAlgorithms.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
class cmExecutionStatus;
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index fc82535..c948b2a 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -4,6 +4,7 @@
#include "cmMakefile.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
@@ -64,7 +65,7 @@
// First assume the path to the program was specified with no
// arguments and with no quoting or escaping for spaces.
// Only bother doing this if there is non-whitespace.
- if (!cmSystemTools::TrimWhitespace(filename).empty()) {
+ if (!cmTrimWhitespace(filename).empty()) {
result = cmSystemTools::FindProgram(filename);
}
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 997595b..00ebbb5 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -442,12 +443,12 @@
// This command was specified as a path to a file in the
// current directory. Add a leading "./" so it can run
// without the current directory being in the search path.
- cmd = "./" + cmd;
+ cmd = cmStrCat("./", cmd);
}
cmd = this->LocalGenerator->ConvertToOutputFormat(
cmd, cmOutputConverter::SHELL);
if (useCall) {
- cmd = "call " + cmd;
+ cmd = cmStrCat("call ", cmd);
}
ccg.AppendArguments(c, cmd);
cmdLines.push_back(std::move(cmd));
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 7b8ffc5..4db5ca8 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -44,7 +44,7 @@
#include "cmWorkingDirectory.h"
#include "cmake.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmCryptoHash.h"
# include "cmQtAutoGenGlobalInitializer.h"
# include "cm_jsoncpp_value.h"
@@ -114,7 +114,7 @@
this->ClearGeneratorMembers();
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmGlobalGenerator::GetJson() const
{
Json::Value generator = Json::objectValue;
@@ -337,15 +337,16 @@
bool failed = false;
for (cmLocalGenerator* generator : this->LocalGenerators) {
for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
- std::vector<std::string> configs;
- target->Makefile->GetConfigurations(configs);
- if (configs.empty()) {
- configs.emplace_back();
- }
+ if (target->GetType() == cmStateEnums::EXECUTABLE &&
+ target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+ std::vector<std::string> configs;
+ target->Makefile->GetConfigurations(configs);
+ if (configs.empty()) {
+ configs.emplace_back();
+ }
- for (std::string const& config : configs) {
- if (target->GetLinkerLanguage(config) == "Swift") {
- if (target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
+ for (std::string const& config : configs) {
+ if (target->GetLinkerLanguage(config) == "Swift") {
this->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
"WIN32_EXECUTABLE property is not supported on Swift "
@@ -1546,7 +1547,7 @@
bool cmGlobalGenerator::QtAutoGen()
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmQtAutoGenGlobalInitializer initializer(this->LocalGenerators);
return initializer.generate();
#else
@@ -2269,14 +2270,6 @@
return false;
}
-inline std::string removeQuotes(const std::string& s)
-{
- if (s.front() == '\"' && s.back() == '\"') {
- return s.substr(1, s.size() - 2);
- }
- return s;
-}
-
bool cmGlobalGenerator::CheckCMP0037(std::string const& targetName,
std::string const& reason) const
{
@@ -2828,7 +2821,7 @@
void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
std::string const& content)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Ignore if there are no outputs.
if (outputs.empty()) {
return;
@@ -2858,7 +2851,7 @@
void cmGlobalGenerator::CheckRuleHashes()
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory();
std::string pfile = home;
pfile += "/CMakeFiles";
@@ -2962,7 +2955,7 @@
file += "/Labels.txt";
std::string json_file = dir + "/Labels.json";
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// Check whether labels are enabled for this target.
const char* targetLabels = target->GetProperty("LABELS");
const char* directoryLabels =
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index e36825c..830974d 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -19,12 +19,13 @@
#include "cmDuration.h"
#include "cmExportSetMap.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
#include "cm_codecvt.hxx"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmFileLockPool.h"
# include "cm_jsoncpp_value.h"
#endif
@@ -108,7 +109,7 @@
return codecvt::None;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
/** Get a JSON object describing the generator. */
virtual Json::Value GetJson() const;
#endif
@@ -461,7 +462,7 @@
const std::set<const cmGeneratorTarget*>& GetFilenameTargetDepends(
cmSourceFile* sf) const;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmFileLockPool& GetFileLockPool() { return FileLockPool; }
#endif
@@ -664,7 +665,7 @@
mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
FilenameTargetDepends;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Pool of file locks
cmFileLockPool FileLockPool;
#endif
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 7cfbea6..9f3dab7 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -11,6 +11,7 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmake.h"
@@ -418,17 +419,17 @@
}
// create target build file
- std::string name = target->GetName() + ".tgt" + FILE_EXTENSION;
- std::string fname = rootBinaryDir + "/" + name;
+ std::string name = cmStrCat(target->GetName(), ".tgt", FILE_EXTENSION);
+ std::string fname = cmStrCat(rootBinaryDir, "/", name);
cmGeneratedFileStream fbld(fname);
fbld.SetCopyIfDifferent(true);
this->WriteFileHeader(fbld);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld);
std::vector<cmGeneratorTarget const*> build;
if (ComputeTargetBuildOrder(target, build)) {
- std::string message = "The inter-target dependency graph for target [" +
- target->GetName() + "] had a cycle.\n";
- cmSystemTools::Error(message);
+ 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);
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 7e81a54..addb0c7 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -32,6 +32,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetDepend.h"
@@ -382,7 +383,7 @@
}
// Do not add a variable if the value is empty.
- std::string val = cmSystemTools::TrimWhitespace(value);
+ std::string val = cmTrimWhitespace(value);
if (val.empty()) {
return;
}
@@ -414,14 +415,6 @@
cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
: cmGlobalCommonGenerator(cm)
- , UsingGCCOnWindows(false)
- , ComputingUnknownDependencies(false)
- , PolicyCMP0058(cmPolicies::WARN)
- , NinjaSupportsConsolePool(false)
- , NinjaSupportsImplicitOuts(false)
- , NinjaSupportsManifestRestat(false)
- , NinjaSupportsMultilineDepfile(false)
- , NinjaSupportsDyndeps(0)
{
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
@@ -535,7 +528,7 @@
cmSystemTools::SetFatalErrorOccured();
return false;
}
- this->NinjaVersion = cmSystemTools::TrimWhitespace(version);
+ this->NinjaVersion = cmTrimWhitespace(version);
this->CheckNinjaFeatures();
}
return true;
@@ -555,14 +548,22 @@
this->NinjaSupportsMultilineDepfile = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForMultilineDepfile().c_str());
- {
+ this->NinjaSupportsDyndeps = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForDyndeps().c_str());
+ if (!this->NinjaSupportsDyndeps) {
+ // The ninja version number is not new enough to have upstream support.
// Our ninja branch adds ".dyndep-#" to its version number,
// where '#' is a feature-specific version number. Extract it.
static std::string const k_DYNDEP_ = ".dyndep-";
std::string::size_type pos = this->NinjaVersion.find(k_DYNDEP_);
if (pos != std::string::npos) {
const char* fv = &this->NinjaVersion[pos + k_DYNDEP_.size()];
- cmSystemTools::StringToULong(fv, &this->NinjaSupportsDyndeps);
+ unsigned long dyndep = 0;
+ cmSystemTools::StringToULong(fv, &dyndep);
+ if (dyndep == 1) {
+ this->NinjaSupportsDyndeps = true;
+ }
}
}
}
@@ -579,37 +580,25 @@
bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
{
- if (this->NinjaSupportsDyndeps == 1) {
+ if (this->NinjaSupportsDyndeps) {
return true;
}
std::ostringstream e;
- if (this->NinjaSupportsDyndeps == 0) {
- /* clang-format off */
- e <<
- "The Ninja generator does not support Fortran using Ninja version\n"
- " " + this->NinjaVersion + "\n"
- "due to lack of required features. "
- "Kitware has implemented the required features but as of this version "
- "of CMake they have not been integrated to upstream ninja. "
- "Pending integration, Kitware maintains a branch at:\n"
- " https://github.com/Kitware/ninja/tree/features-for-fortran#readme\n"
- "with the required features. "
- "One may build ninja from that branch to get support for Fortran."
- ;
- /* clang-format on */
- } else {
- /* clang-format off */
- e <<
- "The Ninja generator in this version of CMake does not support Fortran "
- "using Ninja version\n"
- " " + this->NinjaVersion + "\n"
- "because its 'dyndep' feature version is " <<
- this->NinjaSupportsDyndeps << ". "
- "This version of CMake is aware only of 'dyndep' feature version 1."
- ;
- /* clang-format on */
- }
+ /* clang-format off */
+ e <<
+ "The Ninja generator does not support Fortran using Ninja version\n"
+ " " + this->NinjaVersion + "\n"
+ "due to lack of required features. "
+ "Kitware has implemented the required features and they have been "
+ "merged to upstream ninja for inclusion in Ninja 1.10 and higher. "
+ "As of this version of CMake, Ninja 1.10 has not been released. "
+ "Meanwhile, Kitware maintains a branch of Ninja at:\n"
+ " https://github.com/Kitware/ninja/tree/features-for-fortran#readme\n"
+ "with the required features. "
+ "One may build ninja from that branch to get support for Fortran."
+ ;
+ /* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
@@ -1742,8 +1731,9 @@
if (arg_lang == "Fortran") {
info = cmcmd_cmake_ninja_depends_fortran(arg_tdi, arg_pp);
} else {
- cmSystemTools::Error("-E cmake_ninja_depends does not understand the " +
- arg_lang + " language");
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends does not understand the ", arg_lang,
+ " language"));
return 1;
}
@@ -1797,8 +1787,9 @@
cmsys::ifstream tdif(arg_tdi.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (!reader.parse(tdif, tdio, false)) {
- cmSystemTools::Error("-E cmake_ninja_depends failed to parse " +
- arg_tdi + reader.getFormattedErrorMessages());
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends failed to parse ", arg_tdi,
+ reader.getFormattedErrorMessages()));
return nullptr;
}
}
@@ -1877,8 +1868,9 @@
cmsys::ifstream ddif(arg_ddi.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (!reader.parse(ddif, ddio, false)) {
- cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " + arg_ddi +
- reader.getFormattedErrorMessages());
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_ddi,
+ reader.getFormattedErrorMessages()));
return false;
}
@@ -1905,14 +1897,14 @@
// Populate the module map with those provided by linked targets first.
for (std::string const& linked_target_dir : linked_target_dirs) {
std::string const ltmn =
- linked_target_dir + "/" + arg_lang + "Modules.json";
+ cmStrCat(linked_target_dir, "/", arg_lang, "Modules.json");
Json::Value ltm;
cmsys::ifstream ltmf(ltmn.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (ltmf && !reader.parse(ltmf, ltm, false)) {
- cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " +
- linked_target_dir +
- reader.getFormattedErrorMessages());
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ linked_target_dir,
+ reader.getFormattedErrorMessages()));
return false;
}
if (ltm.isObject()) {
@@ -2016,8 +2008,9 @@
cmsys::ifstream tdif(arg_tdi.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
if (!reader.parse(tdif, tdio, false)) {
- cmSystemTools::Error("-E cmake_ninja_dyndep failed to parse " + arg_tdi +
- reader.getFormattedErrorMessages());
+ cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+ arg_tdi,
+ reader.getFormattedErrorMessages()));
return 1;
}
}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 99afc1d..db64031 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -322,6 +322,7 @@
{
return "1.9";
}
+ static std::string RequiredNinjaVersionForDyndeps() { return "1.10"; }
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
@@ -402,7 +403,7 @@
/// The set of dependencies to add to the "all" target.
cmNinjaDeps AllDependencies;
- bool UsingGCCOnWindows;
+ bool UsingGCCOnWindows = false;
/// The set of custom commands we have seen.
std::set<cmCustomCommand const*> CustomCommands;
@@ -412,8 +413,8 @@
/// Whether we are collecting known build outputs and needed
/// dependencies to determine unknown dependencies.
- bool ComputingUnknownDependencies;
- cmPolicies::PolicyStatus PolicyCMP0058;
+ bool ComputingUnknownDependencies = false;
+ cmPolicies::PolicyStatus PolicyCMP0058 = cmPolicies::WARN;
/// The combined explicit dependencies of custom build commands
std::set<std::string> CombinedCustomCommandExplicitDependencies;
@@ -435,11 +436,11 @@
std::string NinjaCommand;
std::string NinjaVersion;
- bool NinjaSupportsConsolePool;
- bool NinjaSupportsImplicitOuts;
- bool NinjaSupportsManifestRestat;
- bool NinjaSupportsMultilineDepfile;
- unsigned long NinjaSupportsDyndeps;
+ bool NinjaSupportsConsolePool = false;
+ bool NinjaSupportsImplicitOuts = false;
+ bool NinjaSupportsManifestRestat = false;
+ bool NinjaSupportsMultilineDepfile = false;
+ bool NinjaSupportsDyndeps = false;
private:
void InitOutputPathPrefix();
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 4a3cadd..720b6c5 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -325,7 +325,7 @@
bool cmGlobalVisualStudio10Generator::ParseGeneratorToolset(
std::string const& ts, cmMakefile* mf)
{
- std::vector<std::string> const fields = cmSystemTools::tokenize(ts, ",");
+ std::vector<std::string> const fields = cmTokenize(ts, ",");
std::vector<std::string>::const_iterator fi = fields.begin();
if (fi == fields.end()) {
return true;
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 8401efb..cd1ff61 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -8,7 +8,9 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmUuid.h"
+#include "cm_string_view.hxx"
#include "cmake.h"
#include "cmsys/Encoding.hxx"
@@ -254,7 +256,7 @@
return lg;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmGlobalVisualStudio7Generator::GetJson() const
{
Json::Value generator = this->cmGlobalVisualStudioGenerator::GetJson();
@@ -432,16 +434,15 @@
void cmGlobalVisualStudio7Generator::WriteFolders(std::ostream& fout)
{
- const char* prefix = "CMAKE_FOLDER_GUID_";
- const std::string::size_type skip_prefix = strlen(prefix);
+ cm::string_view const prefix = "CMAKE_FOLDER_GUID_";
std::string guidProjectTypeFolder = "2150E333-8FDC-42A3-9474-1A3956D46DE8";
for (auto const& iter : VisualStudioFolders) {
std::string fullName = iter.first;
std::string guid = this->GetGUID(fullName);
std::replace(fullName.begin(), fullName.end(), '/', '\\');
- if (cmSystemTools::StringStartsWith(fullName.c_str(), prefix)) {
- fullName = fullName.substr(skip_prefix);
+ if (cmHasPrefix(fullName, prefix)) {
+ fullName = fullName.substr(prefix.size());
}
std::string nameOnly = cmSystemTools::GetFilenameName(fullName);
@@ -517,9 +518,9 @@
const std::string::size_type posEqual = itPair.find('=');
if (posEqual != std::string::npos) {
const std::string key =
- cmSystemTools::TrimWhitespace(itPair.substr(0, posEqual));
+ cmTrimWhitespace(itPair.substr(0, posEqual));
const std::string value =
- cmSystemTools::TrimWhitespace(itPair.substr(posEqual + 1));
+ cmTrimWhitespace(itPair.substr(posEqual + 1));
fout << "\t\t" << key << " = " << value << "\n";
if (key == "SolutionGuid") {
addGuid = false;
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index f004afb..9b84732 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -23,7 +23,7 @@
//! Create a local generator appropriate to this Global Generator
cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value GetJson() const override;
#endif
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 8f4ae62..e3cafe3 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -38,12 +38,12 @@
struct cmLinkImplementation;
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(__APPLE__)
+#if !defined(CMAKE_BOOTSTRAP) && defined(__APPLE__)
# define HAVE_APPLICATION_SERVICES
# include <ApplicationServices/ApplicationServices.h>
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmXMLParser.h"
// parse the xml file storing the installed version of Xcode on
@@ -188,7 +188,7 @@
if (name != GetActualName()) {
return nullptr;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmXcodeVersionParser parser;
std::string versionFile;
{
@@ -2945,8 +2945,7 @@
if (it != this->TargetGroup.end()) {
tgroup = it->second;
} else {
- std::vector<std::string> tgt_folders =
- cmSystemTools::tokenize(target, "/");
+ std::vector<std::string> tgt_folders = cmTokenize(target, "/");
std::string curr_tgt_folder;
for (std::vector<std::string>::size_type i = 0; i < tgt_folders.size();
i++) {
@@ -2980,8 +2979,7 @@
if (sg->GetFullName() != sg->GetName()) {
std::string curr_folder = target;
curr_folder += "/";
- for (auto const& folder :
- cmSystemTools::tokenize(sg->GetFullName(), "\\")) {
+ for (auto const& folder : cmTokenize(sg->GetFullName(), "\\")) {
curr_folder += folder;
std::map<std::string, cmXCodeObject*>::iterator i_folder =
this->GroupNameMap.find(curr_folder);
@@ -2993,7 +2991,7 @@
} else {
tgroup = i_folder->second;
}
- curr_folder = curr_folder + "\\";
+ curr_folder += "\\";
}
return tgroup;
}
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 385022c..7b49ae7 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -3,10 +3,14 @@
#include "cmIfCommand.h"
#include "cm_memory.hxx"
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
@@ -28,152 +32,137 @@
return err;
}
-//=========================================================================
-bool cmIfFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus& inStatus)
+class cmIfFunctionBlocker : public cmFunctionBlocker
{
- // we start by recording all the functions
- if (lff.Name.Lower == "if") {
- this->ScopeDepth++;
- } else if (lff.Name.Lower == "endif") {
- this->ScopeDepth--;
- // if this is the endif for this if statement, then start executing
- if (!this->ScopeDepth) {
- // Remove the function blocker for this scope or bail.
- std::unique_ptr<cmFunctionBlocker> fb(
- mf.RemoveFunctionBlocker(this, lff));
- if (!fb) {
- return false;
- }
+public:
+ cm::string_view StartCommandName() const override { return "if"_s; }
+ cm::string_view EndCommandName() const override { return "endif"_s; }
- // execute the functions for the true parts of the if statement
- cmExecutionStatus status(mf);
- int scopeDepth = 0;
- for (cmListFileFunction const& func : this->Functions) {
- // keep track of scope depth
- if (func.Name.Lower == "if") {
- scopeDepth++;
- }
- if (func.Name.Lower == "endif") {
- scopeDepth--;
- }
- // watch for our state change
- if (scopeDepth == 0 && func.Name.Lower == "else") {
+ bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile&) const override;
- if (this->ElseSeen) {
- cmListFileBacktrace bt = mf.GetBacktrace(func);
- mf.GetCMakeInstance()->IssueMessage(
- MessageType::FATAL_ERROR,
- "A duplicate ELSE command was found inside an IF block.", bt);
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus) override;
- this->IsBlocking = this->HasRun;
- this->HasRun = true;
- this->ElseSeen = true;
+ std::vector<cmListFileArgument> Args;
+ bool IsBlocking;
+ bool HasRun = false;
+ bool ElseSeen = false;
+};
- // if trace is enabled, print a (trivially) evaluated "else"
- // statement
- if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
- }
- } else if (scopeDepth == 0 && func.Name.Lower == "elseif") {
- if (this->ElseSeen) {
- cmListFileBacktrace bt = mf.GetBacktrace(func);
- mf.GetCMakeInstance()->IssueMessage(
- MessageType::FATAL_ERROR,
- "An ELSEIF command was found after an ELSE command.", bt);
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
-
- if (this->HasRun) {
- this->IsBlocking = true;
- } else {
- // if trace is enabled, print the evaluated "elseif" statement
- if (mf.GetCMakeInstance()->GetTrace()) {
- mf.PrintCommandTrace(func);
- }
-
- std::string errorString;
-
- std::vector<cmExpandedCommandArgument> expandedArguments;
- mf.ExpandArguments(func.Arguments, expandedArguments);
-
- MessageType messType;
-
- cmListFileContext conditionContext =
- cmListFileContext::FromCommandContext(
- func, this->GetStartingContext().FilePath);
-
- cmConditionEvaluator conditionEvaluator(mf, conditionContext,
- mf.GetBacktrace(func));
-
- bool isTrue = conditionEvaluator.IsTrue(expandedArguments,
- errorString, messType);
-
- if (!errorString.empty()) {
- std::string err = cmIfCommandError(expandedArguments);
- err += errorString;
- cmListFileBacktrace bt = mf.GetBacktrace(func);
- mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
- if (messType == MessageType::FATAL_ERROR) {
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
- }
-
- if (isTrue) {
- this->IsBlocking = false;
- this->HasRun = true;
- }
- }
- }
-
- // should we execute?
- else if (!this->IsBlocking) {
- status.Clear();
- mf.ExecuteCommand(func, status);
- if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
- return true;
- }
- if (status.GetBreakInvoked()) {
- inStatus.SetBreakInvoked();
- return true;
- }
- if (status.GetContinueInvoked()) {
- inStatus.SetContinueInvoked();
- return true;
- }
- }
- }
- return true;
- }
- }
-
- // record the command
- this->Functions.push_back(lff);
-
- // always return true
- return true;
+bool cmIfFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile&) const
+{
+ return lff.Arguments.empty() || lff.Arguments == this->Args;
}
-//=========================================================================
-bool cmIfFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile&)
+bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus)
{
- if (lff.Name.Lower == "endif") {
- // if the endif has arguments, then make sure
- // they match the arguments of the matching if
- if (lff.Arguments.empty() || lff.Arguments == this->Args) {
- return true;
+ cmMakefile& mf = inStatus.GetMakefile();
+ // execute the functions for the true parts of the if statement
+ int scopeDepth = 0;
+ for (cmListFileFunction const& func : functions) {
+ // keep track of scope depth
+ if (func.Name.Lower == "if") {
+ scopeDepth++;
+ }
+ if (func.Name.Lower == "endif") {
+ scopeDepth--;
+ }
+ // watch for our state change
+ if (scopeDepth == 0 && func.Name.Lower == "else") {
+
+ if (this->ElseSeen) {
+ cmListFileBacktrace bt = mf.GetBacktrace(func);
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "A duplicate ELSE command was found inside an IF block.", bt);
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ this->IsBlocking = this->HasRun;
+ this->HasRun = true;
+ this->ElseSeen = true;
+
+ // if trace is enabled, print a (trivially) evaluated "else"
+ // statement
+ if (!this->IsBlocking && mf.GetCMakeInstance()->GetTrace()) {
+ mf.PrintCommandTrace(func);
+ }
+ } else if (scopeDepth == 0 && func.Name.Lower == "elseif") {
+ if (this->ElseSeen) {
+ cmListFileBacktrace bt = mf.GetBacktrace(func);
+ mf.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "An ELSEIF command was found after an ELSE command.", bt);
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+
+ if (this->HasRun) {
+ this->IsBlocking = true;
+ } else {
+ // if trace is enabled, print the evaluated "elseif" statement
+ if (mf.GetCMakeInstance()->GetTrace()) {
+ mf.PrintCommandTrace(func);
+ }
+
+ std::string errorString;
+
+ std::vector<cmExpandedCommandArgument> expandedArguments;
+ mf.ExpandArguments(func.Arguments, expandedArguments);
+
+ MessageType messType;
+
+ cmListFileContext conditionContext =
+ cmListFileContext::FromCommandContext(
+ func, this->GetStartingContext().FilePath);
+
+ cmConditionEvaluator conditionEvaluator(mf, conditionContext,
+ mf.GetBacktrace(func));
+
+ bool isTrue =
+ conditionEvaluator.IsTrue(expandedArguments, errorString, messType);
+
+ if (!errorString.empty()) {
+ std::string err = cmIfCommandError(expandedArguments);
+ err += errorString;
+ cmListFileBacktrace bt = mf.GetBacktrace(func);
+ mf.GetCMakeInstance()->IssueMessage(messType, err, bt);
+ if (messType == MessageType::FATAL_ERROR) {
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
+ }
+
+ if (isTrue) {
+ this->IsBlocking = false;
+ this->HasRun = true;
+ }
+ }
+ }
+
+ // should we execute?
+ else if (!this->IsBlocking) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(func, status);
+ if (status.GetReturnInvoked()) {
+ inStatus.SetReturnInvoked();
+ return true;
+ }
+ if (status.GetBreakInvoked()) {
+ inStatus.SetBreakInvoked();
+ return true;
+ }
+ if (status.GetContinueInvoked()) {
+ inStatus.SetContinueInvoked();
+ return true;
+ }
}
}
-
- return false;
+ return true;
}
//=========================================================================
@@ -208,7 +197,6 @@
{
auto fb = cm::make_unique<cmIfFunctionBlocker>();
// if is isn't true block the commands
- fb->ScopeDepth = 1;
fb->IsBlocking = !isTrue;
if (isTrue) {
fb->HasRun = true;
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index 775e609..820ffa4 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -7,26 +7,8 @@
#include <vector>
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmIfFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
-
- std::vector<cmListFileArgument> Args;
- std::vector<cmListFileFunction> Functions;
- bool IsBlocking;
- bool HasRun = false;
- bool ElseSeen = false;
- unsigned int ScopeDepth = 0;
-};
+struct cmListFileArgument;
/// Starts an if block
bool cmIfCommand(std::vector<cmListFileArgument> const& args,
diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx
index 3b126b0..e560910 100644
--- a/Source/cmIncludeGuardCommand.cxx
+++ b/Source/cmIncludeGuardCommand.cxx
@@ -21,7 +21,7 @@
std::string GetIncludeGuardVariableName(std::string const& filePath)
{
std::string result = "__INCGUARD_";
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
result += cmSystemTools::ComputeStringMD5(filePath);
#else
result += cmSystemTools::MakeCidentifier(filePath);
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 3b0659c..76dafd9 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -9,7 +9,6 @@
#include <stddef.h>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmExportSet.h"
#include "cmExportSetMap.h"
@@ -27,6 +26,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
@@ -43,11 +43,13 @@
target.SetHaveInstallRule(true);
const char* component = namelink ? args.GetNamelinkComponent().c_str()
: args.GetComponent().c_str();
- return new cmInstallTargetGenerator(
+ auto g = new cmInstallTargetGenerator(
target.GetName(), destination.c_str(), impLib,
args.GetPermissions().c_str(), args.GetConfigurations(), component,
message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt,
backtrace);
+ target.AddInstallGenerator(g);
+ return g;
}
static cmInstallTargetGenerator* CreateInstallTargetGenerator(
@@ -1266,7 +1268,7 @@
bool cmInstallCommand::HandleExportAndroidMKMode(
std::vector<std::string> const& args)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// This is the EXPORT mode.
cmInstallCommandArguments ica(this->DefaultComponentName);
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index c8ebc8c..9357a5c 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -6,6 +6,7 @@
#include "cmInstallType.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include <memory>
@@ -74,7 +75,7 @@
cmMakefile const& mf = *this->LocalGenerator->GetMakefile();
for (std::string& d : dirs) {
if (!cmSystemTools::FileIsFullPath(d)) {
- d = mf.GetCurrentSourceDirectory() + "/" + d;
+ d = cmStrCat(mf.GetCurrentSourceDirectory(), "/", d);
}
}
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index f5bedab..af06b9d 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -7,7 +7,7 @@
#include <sstream>
#include <utility>
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmExportInstallAndroidMKGenerator.h"
#endif
#include "cmExportInstallFileGenerator.h"
@@ -31,7 +31,7 @@
, LocalGenerator(nullptr)
{
if (android) {
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->EFGen = new cmExportInstallAndroidMKGenerator(this);
#endif
} else {
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index a61239e..4e0be5e 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -20,6 +20,7 @@
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -369,7 +370,7 @@
{
this->Target->GetTargetObjectNames(config, objects);
for (std::string& o : objects) {
- o = computeInstallObjectDir(this->Target, config) + "/" + o;
+ o = cmStrCat(computeInstallObjectDir(this->Target, config), "/", o);
}
}
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index 2423faf..b8eed13 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -20,6 +20,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTest.h"
@@ -500,9 +501,9 @@
if (!dest.empty() && cmSystemTools::FileIsFullPath(dest)) {
installPath = dest;
} else {
- std::string installPrefix =
- target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
- installPath = installPrefix + '/' + dest;
+ installPath = cmStrCat(
+ target->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX"), '/',
+ dest);
}
installPaths.append(installPath);
@@ -541,19 +542,19 @@
lg->GetTargetFlags(&linkLineComputer, config, linkLibs, linkLanguageFlags,
linkFlags, frameworkPath, linkPath, target);
- linkLibs = cmSystemTools::TrimWhitespace(linkLibs);
- linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
- linkLanguageFlags = cmSystemTools::TrimWhitespace(linkLanguageFlags);
- frameworkPath = cmSystemTools::TrimWhitespace(frameworkPath);
- linkPath = cmSystemTools::TrimWhitespace(linkPath);
+ linkLibs = cmTrimWhitespace(linkLibs);
+ linkFlags = cmTrimWhitespace(linkFlags);
+ linkLanguageFlags = cmTrimWhitespace(linkLanguageFlags);
+ frameworkPath = cmTrimWhitespace(frameworkPath);
+ linkPath = cmTrimWhitespace(linkPath);
- if (!cmSystemTools::TrimWhitespace(linkLibs).empty()) {
+ if (!cmTrimWhitespace(linkLibs).empty()) {
result[kLINK_LIBRARIES_KEY] = linkLibs;
}
- if (!cmSystemTools::TrimWhitespace(linkFlags).empty()) {
+ if (!cmTrimWhitespace(linkFlags).empty()) {
result[kLINK_FLAGS_KEY] = linkFlags;
}
- if (!cmSystemTools::TrimWhitespace(linkLanguageFlags).empty()) {
+ if (!cmTrimWhitespace(linkLanguageFlags).empty()) {
result[kLINK_LANGUAGE_FLAGS_KEY] = linkLanguageFlags;
}
if (!frameworkPath.empty()) {
diff --git a/Source/cmLinkDirectoriesCommand.cxx b/Source/cmLinkDirectoriesCommand.cxx
index 7850977..a278925 100644
--- a/Source/cmLinkDirectoriesCommand.cxx
+++ b/Source/cmLinkDirectoriesCommand.cxx
@@ -4,11 +4,11 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 6450c62..d71ff49 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -87,7 +87,7 @@
bool LibrariesDone = false;
bool AllDone = false;
bool Exists = false;
- const char* ExplicitLibraries = nullptr;
+ bool Explicit = false;
};
struct cmHeadToLinkInterfaceMap
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 8746b35..5e3c790 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -11,6 +11,7 @@
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
@@ -63,6 +64,7 @@
continue;
}
if (item.IsPath) {
+ linkLibs += cli.GetLibLinkFileFlag();
linkLibs +=
this->ConvertToOutputFormat(this->ConvertToLinkReference(item.Value));
} else {
@@ -114,16 +116,17 @@
type = cmStateEnums::ImportLibraryArtifact;
}
- linkPath += " " + libPathFlag +
- item.Target->GetDirectory(cli.GetConfig(), type) +
- libPathTerminator + " ";
+ linkPath += cmStrCat(" ", libPathFlag,
+ item.Target->GetDirectory(cli.GetConfig(), type),
+ libPathTerminator, " ");
}
}
}
for (std::string const& libDir : cli.GetDirectories()) {
- linkPath += " " + libPathFlag + this->ConvertToOutputForExisting(libDir) +
- libPathTerminator + " ";
+ linkPath +=
+ cmStrCat(" ", libPathFlag, this->ConvertToOutputForExisting(libDir),
+ libPathTerminator, " ");
}
return linkPath;
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 8d2add6..7cacb24 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -9,14 +9,15 @@
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmOutputConverter;
@@ -156,6 +157,10 @@
return false;
}
+ if (!lg.GetMakefile()->IsOn("CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE")) {
+ return false;
+ }
+
if (const char* resolveDeviceSymbols =
target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
// If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index d024256..868f564 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -23,6 +23,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
@@ -854,7 +855,7 @@
{ "STRIP", 0,
[&command](const std::string& s) -> std::string {
if (command.Selector->InSelection(s)) {
- return cmSystemTools::TrimWhitespace(s);
+ return cmTrimWhitespace(s);
}
return s;
@@ -1188,8 +1189,8 @@
const std::string option = args[argumentIndex++];
if (option == "COMPARE") {
if (sortCompare != cmStringSorter::Compare::UNINITIALIZED) {
- std::string error = messageHint + "option \"" + option +
- "\" has been specified multiple times.";
+ std::string error = cmStrCat(messageHint, "option \"", option,
+ "\" has been specified multiple times.");
this->SetError(error);
return false;
}
@@ -1200,23 +1201,22 @@
} else if (argument == "FILE_BASENAME") {
sortCompare = cmStringSorter::Compare::FILE_BASENAME;
} else {
- std::string error = messageHint + "value \"" + argument +
- "\" for option \"" + option + "\" is invalid.";
+ std::string error =
+ cmStrCat(messageHint, "value \"", argument, "\" for option \"",
+ option, "\" is invalid.");
this->SetError(error);
return false;
}
} else {
- std::string error =
- messageHint + "missing argument for option \"" + option + "\".";
- this->SetError(error);
+ this->SetError(cmStrCat(messageHint, "missing argument for option \"",
+ option, "\"."));
return false;
}
} else if (option == "CASE") {
if (sortCaseSensitivity !=
cmStringSorter::CaseSensitivity::UNINITIALIZED) {
- std::string error = messageHint + "option \"" + option +
- "\" has been specified multiple times.";
- this->SetError(error);
+ this->SetError(cmStrCat(messageHint, "option \"", option,
+ "\" has been specified multiple times."));
return false;
}
if (argumentIndex < args.size()) {
@@ -1226,23 +1226,21 @@
} else if (argument == "INSENSITIVE") {
sortCaseSensitivity = cmStringSorter::CaseSensitivity::INSENSITIVE;
} else {
- std::string error = messageHint + "value \"" + argument +
- "\" for option \"" + option + "\" is invalid.";
- this->SetError(error);
+ this->SetError(cmStrCat(messageHint, "value \"", argument,
+ "\" for option \"", option,
+ "\" is invalid."));
return false;
}
} else {
- std::string error =
- messageHint + "missing argument for option \"" + option + "\".";
- this->SetError(error);
+ this->SetError(cmStrCat(messageHint, "missing argument for option \"",
+ option, "\"."));
return false;
}
} else if (option == "ORDER") {
if (sortOrder != cmStringSorter::Order::UNINITIALIZED) {
- std::string error = messageHint + "option \"" + option +
- "\" has been specified multiple times.";
- this->SetError(error);
+ this->SetError(cmStrCat(messageHint, "option \"", option,
+ "\" has been specified multiple times."));
return false;
}
if (argumentIndex < args.size()) {
@@ -1252,21 +1250,19 @@
} else if (argument == "DESCENDING") {
sortOrder = cmStringSorter::Order::DESCENDING;
} else {
- std::string error = messageHint + "value \"" + argument +
- "\" for option \"" + option + "\" is invalid.";
- this->SetError(error);
+ this->SetError(cmStrCat(messageHint, "value \"", argument,
+ "\" for option \"", option,
+ "\" is invalid."));
return false;
}
} else {
- std::string error =
- messageHint + "missing argument for option \"" + option + "\".";
- this->SetError(error);
+ this->SetError(cmStrCat(messageHint, "missing argument for option \"",
+ option, "\"."));
return false;
}
} else {
- std::string error =
- messageHint + "option \"" + option + "\" is unknown.";
- this->SetError(error);
+ this->SetError(
+ cmStrCat(messageHint, "option \"", option, "\" is unknown."));
return false;
}
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 242ffe3..228495b 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTestGenerator.h"
@@ -28,7 +29,7 @@
#include "cmake.h"
#include "cmsys/RegularExpression.hxx"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# define CM_LG_ENCODE_OBJECT_NAMES
# include "cmCryptoHash.h"
#endif
@@ -744,12 +745,10 @@
OutputFormat shellFormat = forResponseFile ? RESPONSE : SHELL;
std::ostringstream includeFlags;
- std::string flagVar = "CMAKE_INCLUDE_FLAG_";
- flagVar += lang;
- std::string const& includeFlag = this->Makefile->GetSafeDefinition(flagVar);
- flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
- flagVar += lang;
- const char* sep = this->Makefile->GetDefinition(flagVar);
+ std::string const& includeFlag =
+ this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_", lang));
+ const char* sep =
+ this->Makefile->GetDefinition(cmStrCat("CMAKE_INCLUDE_FLAG_SEP_", lang));
bool quotePaths = false;
if (this->Makefile->GetDefinition("CMAKE_QUOTE_INCLUDE_PATHS")) {
quotePaths = true;
@@ -766,23 +765,16 @@
// Support special system include flag if it is available and the
// normal flag is repeated for each directory.
- std::string sysFlagVar = "CMAKE_INCLUDE_SYSTEM_FLAG_";
- sysFlagVar += lang;
const char* sysIncludeFlag = nullptr;
if (repeatFlag) {
- sysIncludeFlag = this->Makefile->GetDefinition(sysFlagVar);
+ sysIncludeFlag = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang));
}
- std::string fwSearchFlagVar = "CMAKE_";
- fwSearchFlagVar += lang;
- fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
- const char* fwSearchFlag = this->Makefile->GetDefinition(fwSearchFlagVar);
-
- std::string sysFwSearchFlagVar = "CMAKE_";
- sysFwSearchFlagVar += lang;
- sysFwSearchFlagVar += "_SYSTEM_FRAMEWORK_SEARCH_FLAG";
- const char* sysFwSearchFlag =
- this->Makefile->GetDefinition(sysFwSearchFlagVar);
+ const char* fwSearchFlag = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_FRAMEWORK_SEARCH_FLAG"));
+ const char* sysFwSearchFlag = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG"));
bool flagUsed = false;
std::set<std::string> emitted;
@@ -792,9 +784,8 @@
for (std::string const& i : includes) {
if (fwSearchFlag && *fwSearchFlag && this->Makefile->IsOn("APPLE") &&
cmSystemTools::IsPathToFramework(i)) {
- std::string frameworkDir = i;
- frameworkDir += "/../";
- frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir);
+ std::string const frameworkDir =
+ cmSystemTools::CollapseFullPath(cmStrCat(i, "/../"));
if (emitted.insert(frameworkDir).second) {
if (sysFwSearchFlag && target &&
target->IsSystemIncludeDirectory(i, config, lang)) {
@@ -962,10 +953,8 @@
// These are intended to simulate additional implicit include directories.
std::vector<std::string> userStandardDirs;
{
- std::string key = "CMAKE_";
- key += lang;
- key += "_STANDARD_INCLUDE_DIRECTORIES";
- std::string const value = this->Makefile->GetSafeDefinition(key);
+ std::string const value = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_STANDARD_INCLUDE_DIRECTORIES"));
cmSystemTools::ExpandListArgument(value, userStandardDirs);
for (std::string& usd : userStandardDirs) {
cmSystemTools::ConvertToUnixSlashes(usd);
@@ -988,10 +977,9 @@
// * Compilers like gfortran do not search their own implicit include
// directories for modules ('.mod' files).
if (lang != "Fortran") {
- std::string key = "CMAKE_";
- key += lang;
- key += "_IMPLICIT_INCLUDE_DIRECTORIES";
- if (const char* value = this->Makefile->GetDefinition(key)) {
+ const char* value = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"));
+ if (value != nullptr) {
size_t const impDirVecOldSize = impDirVec.size();
cmSystemTools::ExpandListArgument(value, impDirVec);
// FIXME: Use cmRange with 'advance()' when it supports non-const.
@@ -1209,9 +1197,8 @@
linkFlags += " ";
}
if (!buildType.empty()) {
- std::string configLinkFlags = "LINK_FLAGS_";
- configLinkFlags += buildType;
- targetLinkFlags = target->GetProperty(configLinkFlags);
+ targetLinkFlags =
+ target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
if (targetLinkFlags) {
linkFlags += targetLinkFlags;
linkFlags += " ";
@@ -1233,9 +1220,8 @@
this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
linkFlags += " ";
if (!buildType.empty()) {
- std::string build = "CMAKE_EXE_LINKER_FLAGS_";
- build += buildType;
- linkFlags += this->Makefile->GetSafeDefinition(build);
+ linkFlags += this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_EXE_LINKER_FLAGS_", buildType));
linkFlags += " ";
}
if (linkLanguage.empty()) {
@@ -1256,11 +1242,8 @@
}
if (target->IsExecutableWithExports()) {
- std::string exportFlagVar = "CMAKE_EXE_EXPORTS_";
- exportFlagVar += linkLanguage;
- exportFlagVar += "_FLAG";
-
- linkFlags += this->Makefile->GetSafeDefinition(exportFlagVar);
+ linkFlags += this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG"));
linkFlags += " ";
}
}
@@ -1292,9 +1275,8 @@
linkFlags += " ";
}
if (!buildType.empty()) {
- std::string configLinkFlags = "LINK_FLAGS_";
- configLinkFlags += buildType;
- targetLinkFlags = target->GetProperty(configLinkFlags);
+ targetLinkFlags =
+ target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
if (targetLinkFlags) {
linkFlags += targetLinkFlags;
linkFlags += " ";
@@ -1469,20 +1451,12 @@
}
// Add standard libraries for this language.
- std::string standardLibsVar = "CMAKE_";
- standardLibsVar += cli.GetLinkLanguage();
- standardLibsVar += "_STANDARD_LIBRARIES";
- std::string stdLibString;
- if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) {
- stdLibString = stdLibs;
- }
+ std::string stdLibString = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", cli.GetLinkLanguage(), "_STANDARD_LIBRARIES"));
// Append the framework search path flags.
- std::string fwSearchFlagVar = "CMAKE_";
- fwSearchFlagVar += linkLanguage;
- fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
- std::string fwSearchFlag =
- this->Makefile->GetSafeDefinition(fwSearchFlagVar);
+ std::string fwSearchFlag = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", linkLanguage, "_FRAMEWORK_SEARCH_FLAG"));
frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag);
linkPath =
@@ -1537,10 +1511,8 @@
}
if (add_shlib_flags) {
- std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
- linkFlagsVar += linkLanguage;
- linkFlagsVar += "_FLAGS";
- linkFlags = this->Makefile->GetSafeDefinition(linkFlagsVar);
+ linkFlags = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_SHARED_LIBRARY_LINK_", linkLanguage, "_FLAGS"));
}
}
return linkFlags;
@@ -1598,10 +1570,8 @@
const std::string& config)
{
// Add language-specific flags.
- std::string flagsVar = "CMAKE_";
- flagsVar += lang;
- flagsVar += "_FLAGS";
- this->AddConfigVariableFlags(flags, flagsVar, config);
+ this->AddConfigVariableFlags(flags, cmStrCat("CMAKE_", lang, "_FLAGS"),
+ config);
// Add MSVC runtime library flags. This is activated by the presence
// of a default selection whether or not it is overridden by a property.
@@ -1772,10 +1742,9 @@
// Add flags for dealing with shared libraries for this language.
if (shared) {
- flagsVar = "CMAKE_SHARED_LIBRARY_";
- flagsVar += lang;
- flagsVar += "_FLAGS";
- this->AppendFlags(flags, this->Makefile->GetDefinition(flagsVar));
+ this->AppendFlags(flags,
+ this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS")));
}
}
@@ -1911,7 +1880,7 @@
// for which a flag is defined.
for (; stdIt < defaultStdIt; ++stdIt) {
std::string option_flag =
- "CMAKE_" + lang + *stdIt + "_" + type + "_COMPILE_OPTION";
+ cmStrCat("CMAKE_", lang, *stdIt, "_", type, "_COMPILE_OPTION");
if (const char* opt =
target->Target->GetMakefile()->GetDefinition(option_flag)) {
@@ -2064,9 +2033,7 @@
std::string originalFlags =
this->GlobalGenerator->GetSharedLibFlagsForLanguage(lang);
if (shared) {
- std::string flagsVar = "CMAKE_SHARED_LIBRARY_";
- flagsVar += lang;
- flagsVar += "_FLAGS";
+ std::string flagsVar = cmStrCat("CMAKE_SHARED_LIBRARY_", lang, "_FLAGS");
std::string const& flags = this->Makefile->GetSafeDefinition(flagsVar);
if (flags != originalFlags) {
@@ -2105,16 +2072,12 @@
std::string picFlags;
if (targetType == cmStateEnums::EXECUTABLE) {
- std::string flagsVar = "CMAKE_";
- flagsVar += lang;
- flagsVar += "_COMPILE_OPTIONS_PIE";
- picFlags = this->Makefile->GetSafeDefinition(flagsVar);
+ picFlags = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIE"));
}
if (picFlags.empty()) {
- std::string flagsVar = "CMAKE_";
- flagsVar += lang;
- flagsVar += "_COMPILE_OPTIONS_PIC";
- picFlags = this->Makefile->GetSafeDefinition(flagsVar);
+ picFlags = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIC"));
}
if (!picFlags.empty()) {
std::vector<std::string> options;
@@ -2355,10 +2318,8 @@
// Lookup the define flag for the current language.
std::string dflag = "-D";
if (!lang.empty()) {
- std::string defineFlagVar = "CMAKE_";
- defineFlagVar += lang;
- defineFlagVar += "_DEFINE_FLAG";
- const char* df = this->Makefile->GetDefinition(defineFlagVar);
+ const char* df =
+ this->Makefile->GetDefinition(cmStrCat("CMAKE_", lang, "_DEFINE_FLAG"));
if (df && *df) {
dflag = df;
}
@@ -2404,11 +2365,9 @@
const std::string& lang,
const char* feature)
{
- std::string optVar = "CMAKE_";
- optVar += lang;
- optVar += "_COMPILE_OPTIONS_";
- optVar += feature;
- if (const char* optionList = this->Makefile->GetDefinition(optVar)) {
+ const char* optionList = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature));
+ if (optionList != nullptr) {
std::vector<std::string> options;
cmSystemTools::ExpandListArgument(optionList, options);
for (std::string const& o : options) {
@@ -2761,10 +2720,8 @@
if (!replaceExt) {
std::string lang = source.GetLanguage();
if (!lang.empty()) {
- std::string repVar = "CMAKE_";
- repVar += lang;
- repVar += "_OUTPUT_EXTENSION_REPLACE";
- replaceExt = this->Makefile->IsOn(repVar);
+ replaceExt = this->Makefile->IsOn(
+ cmStrCat("CMAKE_", lang, "_OUTPUT_EXTENSION_REPLACE"));
}
}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index f0c6806..455e491 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -461,7 +461,7 @@
void ComputeObjectMaxPath();
};
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
bool cmLocalGeneratorCheckObjectName(std::string& objName,
std::string::size_type dir_len,
std::string::size_type max_total_len);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 1ec1fd9..cfad31a 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -32,6 +32,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmake.h"
@@ -39,7 +40,7 @@
// Include dependency scanners for supported languages. Only the
// C/C++ scanner is needed for bootstrapping CMake.
#include "cmDependsC.h"
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmDependsFortran.h"
# include "cmDependsJava.h"
#endif
@@ -962,7 +963,7 @@
// This command was specified as a path to a file in the
// current directory. Add a leading "./" so it can run
// without the current directory being in the search path.
- cmd = "./" + cmd;
+ cmd = cmStrCat("./", cmd);
}
std::string launcher;
@@ -1016,18 +1017,16 @@
std::string::size_type rcurly = cmd.find('}');
if (rcurly == std::string::npos || rcurly > lcurly) {
// The first curly is a left curly. Use the hack.
- std::string hack_cmd = cmd.substr(0, lcurly);
- hack_cmd += "{{}";
- hack_cmd += cmd.substr(lcurly + 1);
- cmd = hack_cmd;
+ cmd =
+ cmStrCat(cmd.substr(0, lcurly), "{{}", cmd.substr(lcurly + 1));
}
}
}
if (launcher.empty()) {
if (useCall) {
- cmd = "call " + cmd;
+ cmd = cmStrCat("call ", cmd);
} else if (this->IsNMake() && cmd[0] == '"') {
- cmd = "echo >nul && " + cmd;
+ cmd = cmStrCat("echo >nul && ", cmd);
}
}
commands1.push_back(std::move(cmd));
@@ -1478,7 +1477,7 @@
// TODO: Handle RC (resource files) dependencies correctly.
scanner = cm::make_unique<cmDependsC>(this, targetDir, lang, &validDeps);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
else if (lang == "Fortran") {
ruleFileStream << "# Note that incremental build could trigger "
<< "a call to cmake_copy_f90_mod on each re-build\n";
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index 22748b4..8689c8f 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -7,13 +7,18 @@
#include <utility>
#include "cm_memory.hxx"
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
// define the class for macro commands
@@ -135,55 +140,43 @@
return true;
}
-bool cmMacroFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus&)
+class cmMacroFunctionBlocker : public cmFunctionBlocker
{
- // record commands until we hit the ENDMACRO
- // at the ENDMACRO call we shift gears and start looking for invocations
- if (lff.Name.Lower == "macro") {
- this->Depth++;
- } else if (lff.Name.Lower == "endmacro") {
- // if this is the endmacro for this macro then execute
- if (!this->Depth) {
- mf.AppendProperty("MACROS", this->Args[0].c_str());
- // create a new command and add it to cmake
- cmMacroHelperCommand f;
- f.Args = this->Args;
- f.Functions = this->Functions;
- f.FilePath = this->GetStartingContext().FilePath;
- mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
- // remove the function blocker now that the macro is defined
- mf.RemoveFunctionBlocker(this, lff);
- return true;
- }
- // decrement for each nested macro that ends
- this->Depth--;
- }
+public:
+ cm::string_view StartCommandName() const override { return "macro"_s; }
+ cm::string_view EndCommandName() const override { return "endmacro"_s; }
- // if it wasn't an endmacro and we are not executing then we must be
- // recording
- this->Functions.push_back(lff);
- return true;
+ bool ArgumentsMatch(cmListFileFunction const&,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status) override;
+
+ std::vector<std::string> Args;
+};
+
+bool cmMacroFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const
+{
+ std::vector<std::string> expandedArguments;
+ mf.ExpandArguments(lff.Arguments, expandedArguments,
+ this->GetStartingContext().FilePath.c_str());
+ return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
}
-bool cmMacroFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile& mf)
+bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& status)
{
- if (lff.Name.Lower == "endmacro") {
- std::vector<std::string> expandedArguments;
- mf.ExpandArguments(lff.Arguments, expandedArguments,
- this->GetStartingContext().FilePath.c_str());
- // if the endmacro has arguments make sure they
- // match the arguments of the macro
- if ((expandedArguments.empty() ||
- (expandedArguments[0] == this->Args[0]))) {
- return true;
- }
- }
-
- return false;
+ cmMakefile& mf = status.GetMakefile();
+ mf.AppendProperty("MACROS", this->Args[0].c_str());
+ // create a new command and add it to cmake
+ cmMacroHelperCommand f;
+ f.Args = this->Args;
+ f.Functions = std::move(functions);
+ f.FilePath = this->GetStartingContext().FilePath;
+ mf.RecordPolicies(f.Policies);
+ mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
+ return true;
}
bool cmMacroCommand::InitialPass(std::vector<std::string> const& args,
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index 3ebd959..0d7083a 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -11,23 +11,8 @@
#include "cm_memory.hxx"
#include "cmCommand.h"
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
class cmExecutionStatus;
-class cmMakefile;
-
-class cmMacroFunctionBlocker : public cmFunctionBlocker
-{
-public:
- bool IsFunctionBlocked(const cmListFileFunction&, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction&, cmMakefile& mf) override;
-
- std::vector<std::string> Args;
- std::vector<cmListFileFunction> Functions;
- int Depth = 0;
-};
/// Starts macro() ... endmacro() block
class cmMacroCommand : public cmCommand
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 0fb3237..f6f4737 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -47,7 +47,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmVariableWatch.h"
#endif
@@ -97,7 +97,7 @@
// cmListFileCache in the top level if necessary.
this->CheckCMP0000 = false;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->AddSourceGroup("", "^.*$");
this->AddSourceGroup("Source Files", CM_SOURCE_REGEX);
this->AddSourceGroup("Header Files", CM_HEADER_REGEX);
@@ -353,6 +353,11 @@
cmMakefile* Makefile;
};
+void cmMakefile::OnExecuteCommand(std::function<void()> callback)
+{
+ this->ExecuteCommandCallback = std::move(callback);
+}
+
bool cmMakefile::ExecuteCommand(const cmListFileFunction& lff,
cmExecutionStatus& status)
{
@@ -364,6 +369,10 @@
return result;
}
+ if (this->ExecuteCommandCallback) {
+ this->ExecuteCommandCallback();
+ }
+
// Place this call on the call stack.
cmMakefileCall stack_manager(this, lff, status);
static_cast<void>(stack_manager);
@@ -1416,7 +1425,7 @@
this->PushLoopBlockBarrier();
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
#endif
@@ -1433,7 +1442,7 @@
this->PopFunctionBlockerBarrier(reportError);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
#endif
@@ -1488,7 +1497,7 @@
this->Snapshot = this->GG->GetCMakeInstance()->GetCurrentSnapshot();
this->GG->GetCMakeInstance()->SetCurrentSnapshot(this->Snapshot);
this->GG->SetCurrentMakefile(mf);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GG->GetFileLockPool().PushFileScope();
#endif
}
@@ -1497,7 +1506,7 @@
{
this->Makefile->PopFunctionBlockerBarrier(this->ReportError);
this->Makefile->PopSnapshot(this->ReportError);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GG->GetFileLockPool().PopFileScope();
#endif
this->GG->SetCurrentMakefile(this->CurrentMakefile);
@@ -1791,7 +1800,7 @@
}
this->StateSnapshot.SetDefinition(name, value);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv) {
vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
@@ -1912,7 +1921,7 @@
this->LogUnused("unsetting", name);
}
this->StateSnapshot.RemoveDefinition(name);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv) {
vv->VariableAccessed(name, cmVariableWatch::VARIABLE_REMOVED_ACCESS,
@@ -2070,7 +2079,7 @@
return nullptr;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmSourceGroup* cmMakefile::GetSourceGroup(
const std::vector<std::string>& name) const
{
@@ -2166,8 +2175,7 @@
if (delimiter == nullptr) {
delimiter = "\\";
}
- return this->GetOrCreateSourceGroup(
- cmSystemTools::tokenize(name, delimiter));
+ return this->GetOrCreateSourceGroup(cmTokenize(name, delimiter));
}
/**
@@ -2452,7 +2460,7 @@
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if (cmVariableWatch* vv = this->GetVariableWatch()) {
if (!def) {
vv->VariableAccessed(
@@ -2469,7 +2477,7 @@
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv && !this->SuppressSideEffects) {
bool const watch_function_executed =
@@ -2659,7 +2667,7 @@
if (const char* val = this->GetDefinition(var)) {
// Store the value in the output escaping as requested.
if (escapeQuotes) {
- source.append(cmSystemTools::EscapeQuotes(val));
+ source.append(cmEscapeQuotes(val));
} else {
source.append(val);
}
@@ -2823,7 +2831,7 @@
// Get the string we're meant to append to.
if (value) {
if (escapeQuotes) {
- varresult = cmSystemTools::EscapeQuotes(value);
+ varresult = cmEscapeQuotes(value);
} else {
varresult = value;
}
@@ -2949,7 +2957,7 @@
}
if (escapeQuotes) {
- varresult = cmSystemTools::EscapeQuotes(varresult);
+ varresult = cmEscapeQuotes(varresult);
}
// Skip over the variable.
result.append(last, in - last);
@@ -3061,15 +3069,7 @@
return false;
}
- // loop over all function blockers to see if any block this command
- // evaluate in reverse, this is critical for balanced IF statements etc
- for (auto const& pos : cmReverseRange(this->FunctionBlockers)) {
- if (pos->IsFunctionBlocked(lff, *this, status)) {
- return true;
- }
- }
-
- return false;
+ return this->FunctionBlockers.top()->IsFunctionBlocked(lff, status);
}
void cmMakefile::PushFunctionBlockerBarrier()
@@ -3084,8 +3084,8 @@
this->FunctionBlockerBarriers.back();
while (this->FunctionBlockers.size() > barrier) {
std::unique_ptr<cmFunctionBlocker> fb(
- std::move(this->FunctionBlockers.back()));
- this->FunctionBlockers.pop_back();
+ std::move(this->FunctionBlockers.top()));
+ this->FunctionBlockers.pop();
if (reportError) {
// Report the context in which the unclosed block was opened.
cmListFileContext const& lfc = fb->GetStartingContext();
@@ -3216,46 +3216,18 @@
fb->SetStartingContext(this->GetExecutionContext());
}
- this->FunctionBlockers.push_back(std::move(fb));
+ this->FunctionBlockers.push(std::move(fb));
}
-std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
- cmFunctionBlocker* fb, const cmListFileFunction& lff)
+std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker()
{
- // Find the function blocker stack barrier for the current scope.
- // We only remove a blocker whose index is not less than the barrier.
- FunctionBlockersType::size_type barrier = 0;
- if (!this->FunctionBlockerBarriers.empty()) {
- barrier = this->FunctionBlockerBarriers.back();
- }
+ assert(!this->FunctionBlockers.empty());
+ assert(this->FunctionBlockerBarriers.empty() ||
+ this->FunctionBlockers.size() > this->FunctionBlockerBarriers.back());
- // Search for the function blocker whose scope this command ends.
- for (FunctionBlockersType::size_type i = this->FunctionBlockers.size();
- i > barrier; --i) {
- auto pos = this->FunctionBlockers.begin() + (i - 1);
- if (pos->get() == fb) {
- // Warn if the arguments do not match, but always remove.
- if (!(*pos)->ShouldRemove(lff, *this)) {
- cmListFileContext const& lfc = fb->GetStartingContext();
- cmListFileContext closingContext =
- cmListFileContext::FromCommandContext(lff, lfc.FilePath);
- std::ostringstream e;
- /* clang-format off */
- e << "A logical block opening on the line\n"
- << " " << lfc << "\n"
- << "closes on the line\n"
- << " " << closingContext << "\n"
- << "with mis-matching arguments.";
- /* clang-format on */
- this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
- }
- std::unique_ptr<cmFunctionBlocker> b = std::move(*pos);
- this->FunctionBlockers.erase(pos);
- return b;
- }
- }
-
- return std::unique_ptr<cmFunctionBlocker>();
+ auto b = std::move(this->FunctionBlockers.top());
+ this->FunctionBlockers.pop();
+ return b;
}
std::string const& cmMakefile::GetHomeDirectory() const
@@ -3355,7 +3327,7 @@
cmSourceFile* sf = this->GetOrCreateSource(objFile, true);
sf->SetObjectLibrary(tgtName);
sf->SetProperty("EXTERNAL_OBJECT", "1");
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->SourceGroups[this->ObjectLibrariesSourceGroupIndex].AddGroupFile(
sf->GetFullPath());
#endif
@@ -3537,7 +3509,7 @@
return this->GlobalGenerator;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* cmMakefile::GetVariableWatch() const
{
if (this->GetCMakeInstance() &&
@@ -3959,14 +3931,14 @@
this->GetState()->CreateVariableScopeSnapshot(this->StateSnapshot);
this->PushLoopBlockBarrier();
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PushFunctionScope();
#endif
}
void cmMakefile::PopScope()
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->GetGlobalGenerator()->GetFileLockPool().PopFunctionScope();
#endif
@@ -3990,7 +3962,7 @@
return;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* vv = this->GetVariableWatch();
if (vv) {
vv->VariableAccessed(var, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 18b81d4..a6d1757 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -20,7 +20,6 @@
#include "cm_string_view.hxx"
#include "cmAlgorithms.h"
-#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmNewLineStyle.h"
@@ -28,9 +27,10 @@
#include "cmSourceFileLocationKind.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmSourceGroup.h"
#endif
@@ -39,6 +39,7 @@
class cmExecutionStatus;
class cmExpandedCommandArgument;
class cmExportBuildFileGenerator;
+class cmFunctionBlocker;
class cmGeneratorExpressionEvaluationFile;
class cmGlobalGenerator;
class cmInstallGenerator;
@@ -106,8 +107,7 @@
* Remove the function blocker whose scope ends with the given command.
* This returns ownership of the function blocker object.
*/
- std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker(
- cmFunctionBlocker* fb, const cmListFileFunction& lff);
+ std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
/**
* Try running cmake and building a file. This is used for dynalically
@@ -503,7 +503,7 @@
*/
bool CanIWriteThisFile(std::string const& fileName) const;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
/**
* Get the vector source groups.
*/
@@ -627,6 +627,11 @@
void PrintCommandTrace(const cmListFileFunction& lff) const;
/**
+ * Set a callback that is invoked whenever ExecuteCommand is called.
+ */
+ void OnExecuteCommand(std::function<void()> callback);
+
+ /**
* Execute a single CMake command. Returns true if the command
* succeeded or false if it failed.
*/
@@ -644,7 +649,7 @@
* Get the variable watch. This is used to determine when certain variables
* are accessed.
*/
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmVariableWatch* GetVariableWatch() const;
#endif
@@ -940,7 +945,7 @@
// Track the value of the computed DEFINITIONS property.
std::string DefineFlagsOrig;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::vector<cmSourceGroup> SourceGroups;
size_t ObjectLibrariesSourceGroupIndex;
#endif
@@ -963,7 +968,10 @@
bool EnforceUniqueDir(const std::string& srcPath,
const std::string& binPath) const;
- typedef std::vector<std::unique_ptr<cmFunctionBlocker>> FunctionBlockersType;
+ std::function<void()> ExecuteCommandCallback;
+ using FunctionBlockerPtr = std::unique_ptr<cmFunctionBlocker>;
+ using FunctionBlockersType =
+ std::stack<FunctionBlockerPtr, std::vector<FunctionBlockerPtr>>;
FunctionBlockersType FunctionBlockers;
std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
void PushFunctionBlockerBarrier();
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index a7f2a97..31ee4fa 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -26,6 +26,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
@@ -82,7 +83,7 @@
void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
bool relink)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
const bool requiresDeviceLinking = requireDeviceLinking(
*this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
if (!requiresDeviceLinking) {
@@ -243,7 +244,7 @@
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutputReal);
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
@@ -612,7 +613,7 @@
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index bdde4b8..4621da4 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -26,6 +26,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
@@ -235,7 +236,7 @@
void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
const std::string& linkRuleVar, bool relink)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// TODO: Merge the methods that call this method to avoid
// code duplication.
std::vector<std::string> commands;
@@ -373,7 +374,7 @@
// Expand placeholders.
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
@@ -891,7 +892,7 @@
// Expand placeholders.
for (std::string& real_link_command : real_link_commands) {
- real_link_command = launcher + real_link_command;
+ real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
}
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index b5a6246..7b26324 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -28,6 +28,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -805,7 +806,7 @@
// Expand placeholders in the commands.
for (std::string& compileCommand : compileCommands) {
- compileCommand = launcher + compileCommand;
+ compileCommand = cmStrCat(launcher, compileCommand);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
compileCommand, vars);
}
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 58f3b2f..66d3c88 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMessageCommand.h"
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx
index 0d2b21f..af83478 100644
--- a/Source/cmMessenger.cxx
+++ b/Source/cmMessenger.cxx
@@ -2,11 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMessenger.h"
-#include "cmAlgorithms.h"
#include "cmDocumentationFormatter.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmsys/SystemInformation.hxx"
#endif
@@ -106,7 +106,7 @@
// Add a terminating blank line.
msg << "\n";
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Add a C++ stack trace to internal errors.
if (t == MessageType::INTERNAL_ERROR) {
std::string stack = cmsys::SystemInformation::GetProgramStack(0, 0);
diff --git a/Source/cmNewLineStyle.cxx b/Source/cmNewLineStyle.cxx
index 3f6523e..1ff741e 100644
--- a/Source/cmNewLineStyle.cxx
+++ b/Source/cmNewLineStyle.cxx
@@ -41,7 +41,7 @@
return true;
}
-const std::string cmNewLineStyle::GetCharacters() const
+std::string cmNewLineStyle::GetCharacters() const
{
switch (NewLineStyle) {
case Invalid:
diff --git a/Source/cmNewLineStyle.h b/Source/cmNewLineStyle.h
index f1a7bc6..ab9002e 100644
--- a/Source/cmNewLineStyle.h
+++ b/Source/cmNewLineStyle.h
@@ -30,7 +30,7 @@
bool ReadFromArguments(const std::vector<std::string>& args,
std::string& errorString);
- const std::string GetCharacters() const;
+ std::string GetCharacters() const;
private:
Style NewLineStyle = Invalid;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 88040f8..865ae7d 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -33,6 +33,7 @@
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
@@ -227,7 +228,7 @@
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeDeviceLinkCmd();
for (std::string& linkCmd : linkCmds) {
- linkCmd = launcher + linkCmd;
+ linkCmd = cmStrCat(launcher, linkCmd);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
linkCmd, vars);
}
@@ -366,7 +367,7 @@
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeLinkCmd();
for (std::string& linkCmd : linkCmds) {
- linkCmd = launcher + linkCmd;
+ linkCmd = cmStrCat(launcher, linkCmd);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
linkCmd, vars);
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 08c92ff..c3459be 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -31,6 +31,7 @@
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -552,7 +553,7 @@
}
for (std::string& i : ppCmds) {
- i = launcher + i;
+ i = cmStrCat(launcher, i);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
i, ppVars);
}
@@ -769,7 +770,7 @@
}
for (std::string& i : compileCmds) {
- i = launcher + i;
+ i = cmStrCat(launcher, i);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
vars);
}
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index 52f63a3..3724ba7 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -4,13 +4,13 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index d7bcf7e..da7f8bc 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -6,7 +6,6 @@
#include <assert.h>
#include <ctype.h>
#include <set>
-#include <string.h>
#include <vector>
#include "cmState.h"
@@ -38,10 +37,10 @@
return this->ConvertToOutputFormat(remote, format);
}
-std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
+std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source,
OutputFormat output) const
{
- std::string result = source;
+ std::string result(source);
// Convert it to an output path.
if (output == SHELL || output == WATCOMQUOTE) {
result = this->ConvertDirectorySeparatorsForShell(source);
@@ -53,9 +52,9 @@
}
std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
- const std::string& source) const
+ cm::string_view source) const
{
- std::string result = source;
+ std::string result(source);
// For the MSYS shell convert drive letters to posix paths, so
// that c:/some/path becomes /c/some/path. This is needed to
// avoid problems with the shell path translation.
@@ -71,21 +70,21 @@
return result;
}
-static bool cmOutputConverterIsShellOperator(const std::string& str)
+static bool cmOutputConverterIsShellOperator(cm::string_view str)
{
- static std::set<std::string> const shellOperators{
+ static std::set<cm::string_view> const shellOperators{
"<", ">", "<<", ">>", "|", "||", "&&", "&>", "1>", "2>", "2>&1", "1>&2"
};
return (shellOperators.count(str) != 0);
}
-std::string cmOutputConverter::EscapeForShell(const std::string& str,
+std::string cmOutputConverter::EscapeForShell(cm::string_view str,
bool makeVars, bool forEcho,
bool useWatcomQuote) const
{
// Do not escape shell operators.
if (cmOutputConverterIsShellOperator(str)) {
- return str;
+ return std::string(str);
}
// Compute the flags for the target shell environment.
@@ -117,46 +116,44 @@
flags |= Shell_Flag_IsUnix;
}
- return Shell__GetArgument(str.c_str(), flags);
+ return Shell__GetArgument(str, flags);
}
-std::string cmOutputConverter::EscapeForCMake(const std::string& str)
+std::string cmOutputConverter::EscapeForCMake(cm::string_view str)
{
// Always double-quote the argument to take care of most escapes.
std::string result = "\"";
- for (const char* c = str.c_str(); *c; ++c) {
- if (*c == '"') {
+ for (const char c : str) {
+ if (c == '"') {
// Escape the double quote to avoid ending the argument.
result += "\\\"";
- } else if (*c == '$') {
+ } else if (c == '$') {
// Escape the dollar to avoid expanding variables.
result += "\\$";
- } else if (*c == '\\') {
+ } else if (c == '\\') {
// Escape the backslash to avoid other escapes.
result += "\\\\";
} else {
// Other characters will be parsed correctly.
- result += *c;
+ result += c;
}
}
result += "\"";
return result;
}
-std::string cmOutputConverter::EscapeWindowsShellArgument(const char* arg,
+std::string cmOutputConverter::EscapeWindowsShellArgument(cm::string_view arg,
int shell_flags)
{
return Shell__GetArgument(arg, shell_flags);
}
cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
- const char* value)
+ cm::string_view value)
{
FortranFormat format = FortranFormatNone;
- if (value && *value) {
- std::vector<std::string> fmt;
- cmSystemTools::ExpandListArgument(value, fmt);
- for (std::string const& fi : fmt) {
+ if (!value.empty()) {
+ for (std::string const& fi : cmSystemTools::ExpandedListArgument(value)) {
if (fi == "FIXED") {
format = FortranFormatFixed;
}
@@ -168,6 +165,15 @@
return format;
}
+cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
+ const char* value)
+{
+ if (!value) {
+ return FortranFormatNone;
+ }
+ return GetFortranFormat(cm::string_view(value));
+}
+
void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
{
this->LinkScriptShell = linkScriptShell;
@@ -213,12 +219,12 @@
*/
/* Some helpers to identify character classes */
-static int Shell__CharIsWhitespace(char c)
+static bool Shell__CharIsWhitespace(char c)
{
return ((c == ' ') || (c == '\t'));
}
-static int Shell__CharNeedsQuotesOnUnix(char c)
+static bool Shell__CharNeedsQuotesOnUnix(char c)
{
return ((c == '\'') || (c == '`') || (c == ';') || (c == '#') ||
(c == '&') || (c == '$') || (c == '(') || (c == ')') || (c == '~') ||
@@ -226,51 +232,52 @@
(c == '\\'));
}
-static int Shell__CharNeedsQuotesOnWindows(char c)
+static bool Shell__CharNeedsQuotesOnWindows(char c)
{
return ((c == '\'') || (c == '#') || (c == '&') || (c == '<') ||
(c == '>') || (c == '|') || (c == '^'));
}
-static int Shell__CharIsMakeVariableName(char c)
+static bool Shell__CharIsMakeVariableName(char c)
{
return c && (c == '_' || isalpha((static_cast<int>(c))));
}
-int cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
+bool cmOutputConverter::Shell__CharNeedsQuotes(char c, int flags)
{
/* On Windows the built-in command shell echo never needs quotes. */
if (!(flags & Shell_Flag_IsUnix) && (flags & Shell_Flag_EchoWindows)) {
- return 0;
+ return false;
}
/* On all platforms quotes are needed to preserve whitespace. */
if (Shell__CharIsWhitespace(c)) {
- return 1;
+ return true;
}
if (flags & Shell_Flag_IsUnix) {
/* On UNIX several special characters need quotes to preserve them. */
if (Shell__CharNeedsQuotesOnUnix(c)) {
- return 1;
+ return true;
}
} else {
/* On Windows several special characters need quotes to preserve them. */
if (Shell__CharNeedsQuotesOnWindows(c)) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-const char* cmOutputConverter::Shell__SkipMakeVariables(const char* c)
+cm::string_view::iterator cmOutputConverter::Shell__SkipMakeVariables(
+ cm::string_view::iterator c, cm::string_view::iterator end)
{
- while (*c == '$' && *(c + 1) == '(') {
- const char* skip = c + 2;
- while (Shell__CharIsMakeVariableName(*skip)) {
+ while ((c != end && (c + 1) != end) && (*c == '$' && *(c + 1) == '(')) {
+ cm::string_view::iterator skip = c + 2;
+ while ((skip != end) && Shell__CharIsMakeVariableName(*skip)) {
++skip;
}
- if (*skip == ')') {
+ if ((skip != end) && *skip == ')') {
c = skip + 1;
} else {
break;
@@ -302,63 +309,60 @@
*/
#define KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES 0
-int cmOutputConverter::Shell__ArgumentNeedsQuotes(const char* in, int flags)
+bool cmOutputConverter::Shell__ArgumentNeedsQuotes(cm::string_view in,
+ int flags)
{
/* The empty string needs quotes. */
- if (!*in) {
- return 1;
+ if (in.empty()) {
+ return true;
}
/* Scan the string for characters that require quoting. */
- {
- const char* c;
- for (c = in; *c; ++c) {
- /* Look for $(MAKEVAR) syntax if requested. */
- if (flags & Shell_Flag_AllowMakeVariables) {
+ for (cm::string_view::iterator cit = in.begin(), cend = in.end();
+ cit != cend; ++cit) {
+ /* Look for $(MAKEVAR) syntax if requested. */
+ if (flags & Shell_Flag_AllowMakeVariables) {
#if KWSYS_SYSTEM_SHELL_QUOTE_MAKE_VARIABLES
- const char* skip = Shell__SkipMakeVariables(c);
- if (skip != c) {
- /* We need to quote make variable references to preserve the
- string with contents substituted in its place. */
- return 1;
- }
+ cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend);
+ if (skip != cit) {
+ /* We need to quote make variable references to preserve the
+ string with contents substituted in its place. */
+ return true;
+ }
#else
- /* Skip over the make variable references if any are present. */
- c = Shell__SkipMakeVariables(c);
+ /* Skip over the make variable references if any are present. */
+ cit = Shell__SkipMakeVariables(cit, cend);
- /* Stop if we have reached the end of the string. */
- if (!*c) {
- break;
- }
+ /* Stop if we have reached the end of the string. */
+ if (cit == cend) {
+ break;
+ }
#endif
- }
+ }
- /* Check whether this character needs quotes. */
- if (Shell__CharNeedsQuotes(*c, flags)) {
- return 1;
- }
+ /* Check whether this character needs quotes. */
+ if (Shell__CharNeedsQuotes(*cit, flags)) {
+ return true;
}
}
/* On Windows some single character arguments need quotes. */
- if (flags & Shell_Flag_IsUnix && *in && !*(in + 1)) {
- char c = *in;
+ if (flags & Shell_Flag_IsUnix && in.size() == 1) {
+ char c = in[0];
if ((c == '?') || (c == '&') || (c == '^') || (c == '|') || (c == '#')) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-std::string cmOutputConverter::Shell__GetArgument(const char* in, int flags)
+std::string cmOutputConverter::Shell__GetArgument(cm::string_view in,
+ int flags)
{
/* Output will be at least as long as input string. */
std::string out;
- out.reserve(strlen(in));
-
- /* String iterator. */
- const char* c;
+ out.reserve(in.size());
/* Keep track of how many backslashes have been encountered in a row. */
int windows_backslashes = 0;
@@ -378,14 +382,15 @@
}
/* Scan the string for characters that require escaping or quoting. */
- for (c = in; *c; ++c) {
+ for (cm::string_view::iterator cit = in.begin(), cend = in.end();
+ cit != cend; ++cit) {
/* Look for $(MAKEVAR) syntax if requested. */
if (flags & Shell_Flag_AllowMakeVariables) {
- const char* skip = Shell__SkipMakeVariables(c);
- if (skip != c) {
+ cm::string_view::iterator skip = Shell__SkipMakeVariables(cit, cend);
+ if (skip != cit) {
/* Copy to the end of the make variable references. */
- while (c != skip) {
- out += *c++;
+ while (cit != skip) {
+ out += *cit++;
}
/* The make variable reference eliminates any escaping needed
@@ -393,7 +398,7 @@
windows_backslashes = 0;
/* Stop if we have reached the end of the string. */
- if (!*c) {
+ if (cit == cend) {
break;
}
}
@@ -403,7 +408,7 @@
if (flags & Shell_Flag_IsUnix) {
/* On Unix a few special characters need escaping even inside a
quoted argument. */
- if (*c == '\\' || *c == '"' || *c == '`' || *c == '$') {
+ if (*cit == '\\' || *cit == '"' || *cit == '`' || *cit == '$') {
/* This character needs a backslash to escape it. */
out += '\\';
}
@@ -411,10 +416,10 @@
/* On Windows the built-in command shell echo never needs escaping. */
} else {
/* On Windows only backslashes and double-quotes need escaping. */
- if (*c == '\\') {
+ if (*cit == '\\') {
/* Found a backslash. It may need to be escaped later. */
++windows_backslashes;
- } else if (*c == '"') {
+ } else if (*cit == '"') {
/* Found a double-quote. Escape all immediately preceding
backslashes. */
while (windows_backslashes > 0) {
@@ -432,7 +437,7 @@
}
/* Check whether this character needs escaping for a make tool. */
- if (*c == '$') {
+ if (*cit == '$') {
if (flags & Shell_Flag_Make) {
/* In Makefiles a dollar is written $$. The make tool will
replace it with just $ before passing it to the shell. */
@@ -449,7 +454,7 @@
/* Otherwise a dollar is written just $. */
out += '$';
}
- } else if (*c == '#') {
+ } else if (*cit == '#') {
if ((flags & Shell_Flag_Make) && (flags & Shell_Flag_WatcomWMake)) {
/* In Watcom WMake makefiles a pound is written $#. The make
tool will replace it with just # before passing it to the
@@ -459,7 +464,7 @@
/* Otherwise a pound is written just #. */
out += '#';
}
- } else if (*c == '%') {
+ } else if (*cit == '%') {
if ((flags & Shell_Flag_VSIDE) ||
((flags & Shell_Flag_Make) &&
((flags & Shell_Flag_MinGWMake) || (flags & Shell_Flag_NMake)))) {
@@ -469,7 +474,7 @@
/* Otherwise a percent is written just %. */
out += '%';
}
- } else if (*c == ';') {
+ } else if (*cit == ';') {
if (flags & Shell_Flag_VSIDE) {
/* In a VS IDE a semicolon is written ";". If this is written
in an un-quoted argument it starts a quoted segment,
@@ -483,7 +488,7 @@
}
} else {
/* Store this character. */
- out += *c;
+ out += *cit;
}
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index deca767..671efe7 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -5,9 +5,10 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <string>
-
#include "cmStateSnapshot.h"
+#include "cm_string_view.hxx"
+
+#include <string>
class cmState;
@@ -22,10 +23,9 @@
WATCOMQUOTE,
RESPONSE
};
- std::string ConvertToOutputFormat(const std::string& source,
+ std::string ConvertToOutputFormat(cm::string_view source,
OutputFormat output) const;
- std::string ConvertDirectorySeparatorsForShell(
- const std::string& source) const;
+ std::string ConvertDirectorySeparatorsForShell(cm::string_view source) const;
//! for existing files convert to output path and short path if spaces
std::string ConvertToOutputForExisting(const std::string& remote,
@@ -72,15 +72,15 @@
Shell_Flag_IsUnix = (1 << 8)
};
- std::string EscapeForShell(const std::string& str, bool makeVars = false,
+ std::string EscapeForShell(cm::string_view str, bool makeVars = false,
bool forEcho = false,
bool useWatcomQuote = false) const;
- static std::string EscapeForCMake(const std::string& str);
+ static std::string EscapeForCMake(cm::string_view str);
/** Compute an escaped version of the given argument for use in a
windows shell. */
- static std::string EscapeWindowsShellArgument(const char* arg,
+ static std::string EscapeWindowsShellArgument(cm::string_view arg,
int shell_flags);
enum FortranFormat
@@ -89,15 +89,17 @@
FortranFormatFixed,
FortranFormatFree
};
+ static FortranFormat GetFortranFormat(cm::string_view value);
static FortranFormat GetFortranFormat(const char* value);
private:
cmState* GetState() const;
- static int Shell__CharNeedsQuotes(char c, int flags);
- static const char* Shell__SkipMakeVariables(const char* c);
- static int Shell__ArgumentNeedsQuotes(const char* in, int flags);
- static std::string Shell__GetArgument(const char* in, int flags);
+ static bool Shell__CharNeedsQuotes(char c, int flags);
+ static cm::string_view::iterator Shell__SkipMakeVariables(
+ cm::string_view::iterator begin, cm::string_view::iterator end);
+ static bool Shell__ArgumentNeedsQuotes(cm::string_view in, int flags);
+ static std::string Shell__GetArgument(cm::string_view in, int flags);
private:
cmStateSnapshot StateSnapshot;
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index f3276ec..587e21c 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -11,6 +11,7 @@
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -214,10 +215,8 @@
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -226,10 +225,8 @@
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -239,10 +236,8 @@
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -252,10 +247,8 @@
if (cmSystemTools::FileExists(cxxFile)) {
found = true;
}
- for (std::string path : this->IncludeDirectories) {
- path = path + "/";
- path = path + cxxFile;
- if (cmSystemTools::FileExists(path)) {
+ for (std::string const& path : this->IncludeDirectories) {
+ if (cmSystemTools::FileExists(cmStrCat(path, "/", cxxFile))) {
found = true;
}
}
@@ -339,9 +332,9 @@
// try to guess which include path to use
for (std::string incpath : this->IncludeDirectories) {
if (!incpath.empty() && incpath.back() != '/') {
- incpath = incpath + "/";
+ incpath += "/";
}
- incpath = incpath + path;
+ incpath += path;
if (srcFile->GetFullPath() == incpath) {
// set the path to the guessed path
info->FullPath = incpath;
@@ -420,9 +413,9 @@
for (std::string path : this->IncludeDirectories) {
if (!path.empty() && path.back() != '/') {
- path = path + "/";
+ path += "/";
}
- path = path + fname;
+ path += fname;
if (cmSystemTools::FileExists(path, true) &&
!cmSystemTools::FileIsDirectory(path)) {
std::string fp = cmSystemTools::CollapseFullPath(path);
@@ -485,9 +478,7 @@
// write them out
FILE* fout = cmsys::SystemTools::Fopen(this->OutputFile, "w");
if (!fout) {
- std::string err = "Can not open output file: ";
- err += this->OutputFile;
- this->SetError(err);
+ this->SetError(cmStrCat("Can not open output file: ", this->OutputFile));
return false;
}
std::set<cmDependInformation const*> visited;
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 0f8aef7..04fa0fb 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -7,11 +7,11 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cm_string_view.hxx"
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index ec40136..51a61dc 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -1,10 +1,10 @@
#include "cmPolicies.h"
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 1159ef7..96d9843 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -10,11 +10,11 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index 3683edd..3026b33 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -5,6 +5,7 @@
#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
@@ -352,9 +353,8 @@
// Log command
if (verbose) {
- std::string msg = "Running command:\n";
- msg += QuotedCommand(cmd);
- msg += '\n';
+ std::string msg =
+ cmStrCat("Running command:\n", QuotedCommand(cmd), '\n');
cmSystemTools::Stdout(msg);
}
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index f172b77..ca5a587 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -1,8 +1,6 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenGlobalInitializer.h"
-#include "cmQtAutoGen.h"
-#include "cmQtAutoGenInitializer.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
@@ -11,15 +9,18 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProcessOutput.h"
+#include "cmQtAutoGen.h"
+#include "cmQtAutoGenInitializer.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include <utility>
-
#include "cm_memory.hxx"
+#include <utility>
+
cmQtAutoGenGlobalInitializer::Keywords::Keywords()
: AUTOMOC("AUTOMOC")
, AUTOUIC("AUTOUIC")
@@ -119,23 +120,17 @@
bool const uicDisabled = (uic && !uicAvailable);
bool const rccDisabled = (rcc && !rccAvailable);
if (mocDisabled || uicDisabled || rccDisabled) {
- std::string msg = "AUTOGEN: No valid Qt version found for target ";
- msg += target->GetName();
- msg += ". ";
- msg += cmQtAutoGen::Tools(mocDisabled, uicDisabled, rccDisabled);
- msg += " disabled. Consider adding:\n";
- {
- std::string version = (qtVersion.second == 0)
- ? std::string("<QTVERSION>")
- : std::to_string(qtVersion.second);
- std::string comp = uicDisabled ? "Widgets" : "Core";
- msg += " find_package(Qt";
- msg += version;
- msg += " COMPONENTS ";
- msg += comp;
- msg += ")\n";
- }
- msg += "to your CMakeLists.txt file.";
+ cmAlphaNum version = (qtVersion.second == 0)
+ ? cmAlphaNum("<QTVERSION>")
+ : cmAlphaNum(qtVersion.second);
+ cmAlphaNum component = uicDisabled ? "Widgets" : "Core";
+
+ std::string const msg = cmStrCat(
+ "AUTOGEN: No valid Qt version found for target ",
+ target->GetName(), ". ",
+ cmQtAutoGen::Tools(mocDisabled, uicDisabled, rccDisabled),
+ " disabled. Consider adding:\n", " find_package(Qt", version,
+ " COMPONENTS ", component, ")\n", "to your CMakeLists.txt file.");
target->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, msg);
}
if (mocIsValid || uicIsValid || rccIsValid) {
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 4b12419..360df25 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -4,7 +4,6 @@
#include "cmQtAutoGen.h"
#include "cmQtAutoGenGlobalInitializer.h"
-#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmFilePathChecksum.h"
@@ -23,6 +22,7 @@
#include "cmSourceGroup.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"
@@ -156,30 +156,27 @@
return res;
}
-std::string cmQtAutoGenInitializer::InfoWriter::ConfigKey(
- const char* key, std::string const& config)
+inline std::string cmQtAutoGenInitializer::InfoWriter::ConfigKey(
+ cm::string_view key, std::string const& config)
{
- std::string ckey = key;
- ckey += '_';
- ckey += config;
- return ckey;
+ return cmStrCat(key, "_", config);
}
-void cmQtAutoGenInitializer::InfoWriter::Write(const char* key,
+void cmQtAutoGenInitializer::InfoWriter::Write(cm::string_view key,
std::string const& value)
{
Ofs_ << "set(" << key << " " << cmOutputConverter::EscapeForCMake(value)
<< ")\n";
};
-void cmQtAutoGenInitializer::InfoWriter::WriteUInt(const char* key,
+void cmQtAutoGenInitializer::InfoWriter::WriteUInt(cm::string_view key,
unsigned int value)
{
Ofs_ << "set(" << key << " " << value << ")\n";
};
template <class C>
-void cmQtAutoGenInitializer::InfoWriter::WriteStrings(const char* key,
+void cmQtAutoGenInitializer::InfoWriter::WriteStrings(cm::string_view key,
C const& container)
{
Ofs_ << "set(" << key << " \""
@@ -187,31 +184,29 @@
}
void cmQtAutoGenInitializer::InfoWriter::WriteConfig(
- const char* key, std::map<std::string, std::string> const& map)
+ cm::string_view key, std::map<std::string, std::string> const& map)
{
for (auto const& item : map) {
- Write(ConfigKey(key, item.first).c_str(), item.second);
+ Write(ConfigKey(key, item.first), item.second);
}
};
template <class C>
void cmQtAutoGenInitializer::InfoWriter::WriteConfigStrings(
- const char* key, std::map<std::string, C> const& map)
+ cm::string_view key, std::map<std::string, C> const& map)
{
for (auto const& item : map) {
- WriteStrings(ConfigKey(key, item.first).c_str(), item.second);
+ WriteStrings(ConfigKey(key, item.first), item.second);
}
}
void cmQtAutoGenInitializer::InfoWriter::WriteNestedLists(
- const char* key, std::vector<std::vector<std::string>> const& lists)
+ cm::string_view key, std::vector<std::vector<std::string>> const& lists)
{
std::vector<std::string> seplist;
- for (const std::vector<std::string>& list : lists) {
- std::string blist = "{";
- blist += ListJoin(list.begin(), list.end());
- blist += "}";
- seplist.push_back(std::move(blist));
+ seplist.reserve(lists.size());
+ for (std::vector<std::string> const& list : lists) {
+ seplist.push_back(cmStrCat("{", ListJoin(list.begin(), list.end()), "}"));
}
Write(key, cmJoin(seplist, cmQtAutoGen::ListSep));
};
@@ -721,14 +716,13 @@
if (muf.MocIt || muf.UicIt) {
// Search for the default header file and a private header
std::string const& srcPath = muf.SF->GetFullPath();
- std::string basePath = cmQtAutoGen::SubDirPrefix(srcPath);
- basePath += cmSystemTools::GetFilenameWithoutLastExtension(srcPath);
+ std::string basePath =
+ cmStrCat(cmQtAutoGen::SubDirPrefix(srcPath),
+ cmSystemTools::GetFilenameWithoutLastExtension(srcPath));
for (auto const& suffix : suffixes) {
std::string const suffixedPath = basePath + suffix;
for (auto const& ext : exts) {
- std::string fullPath = suffixedPath;
- fullPath += '.';
- fullPath += ext;
+ std::string fullPath = cmStrCat(suffixedPath, '.', ext);
auto constexpr locationKind = cmSourceFileLocationKind::Known;
cmSourceFile* sf = makefile->GetSource(fullPath, locationKind);
@@ -833,9 +827,8 @@
this->AutogenTarget.DependFiles.insert(muf->RealPath);
}
} else if (this->CMP0071Warn) {
- std::string msg;
- msg += cmPolicies::GetPolicyWarning(cmPolicies::CMP0071);
- msg += '\n';
+ std::string msg =
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0071), '\n');
std::string property;
if (this->Moc.Enabled && this->Uic.Enabled) {
property = kw.SKIP_AUTOGEN;
@@ -888,18 +881,10 @@
for (Qrc& qrc : this->Rcc.Qrcs) {
qrc.PathChecksum = fpathCheckSum.getPart(qrc.QrcFile);
// RCC output file name
+ qrc.RccFile = cmStrCat(this->Dir.Build + "/", qrc.PathChecksum,
+ "/qrc_", qrc.QrcName, ".cpp");
{
- std::string rccFile = this->Dir.Build + "/";
- rccFile += qrc.PathChecksum;
- rccFile += "/qrc_";
- rccFile += qrc.QrcName;
- rccFile += ".cpp";
- qrc.RccFile = std::move(rccFile);
- }
- {
- std::string base = this->Dir.Info;
- base += "/RCC";
- base += qrc.QrcName;
+ std::string base = cmStrCat(this->Dir.Info, "/RCC", qrc.QrcName);
if (!qrc.Unique) {
base += qrc.PathChecksum;
}
@@ -932,8 +917,7 @@
// Replace '-' with '_'. The former is not valid for symbol names.
std::replace(name.begin(), name.end(), '-', '_');
if (!qrc.Unique) {
- name += "_";
- name += qrc.PathChecksum;
+ name += cmStrCat("_", qrc.PathChecksum);
}
std::vector<std::string> nameOpts;
nameOpts.emplace_back("-name");
@@ -1157,8 +1141,8 @@
currentLine.push_back("$<CONFIG>");
commandLines.push_back(std::move(currentLine));
}
- std::string ccComment = "Automatic RCC for ";
- ccComment += FileProjectRelativePath(makefile, qrc.QrcFile);
+ std::string ccComment = cmStrCat(
+ "Automatic RCC for ", FileProjectRelativePath(makefile, qrc.QrcFile));
if (qrc.Generated || this->Rcc.GlobalTarget) {
// Create custom rcc target
@@ -1226,9 +1210,8 @@
{
// Create info directory on demand
if (!cmSystemTools::MakeDirectory(this->Dir.Info)) {
- std::string emsg = ("AutoGen: Could not create directory: ");
- emsg += Quoted(this->Dir.Info);
- cmSystemTools::Error(emsg);
+ cmSystemTools::Error(cmStrCat("AutoGen: Could not create directory: ",
+ Quoted(this->Dir.Info)));
return false;
}
@@ -1311,10 +1294,8 @@
}
if (muf->MocIt || muf->UicIt) {
headers.emplace_back(muf->RealPath);
- std::string flags;
- flags += muf->MocIt ? 'M' : 'm';
- flags += muf->UicIt ? 'U' : 'u';
- headersFlags.emplace_back(std::move(flags));
+ headersFlags.emplace_back(
+ cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u"));
}
}
}
@@ -1323,14 +1304,13 @@
cmFilePathChecksum const fpathCheckSum(makefile);
std::unordered_set<std::string> emitted;
for (std::string const& hdr : headers) {
- std::string basePath = fpathCheckSum.getPart(hdr);
- basePath += "/moc_";
- basePath += cmSystemTools::GetFilenameWithoutLastExtension(hdr);
- for (unsigned int ii = 1; ii != 1024; ++ii) {
+ std::string basePath =
+ cmStrCat(fpathCheckSum.getPart(hdr), "/moc_",
+ cmSystemTools::GetFilenameWithoutLastExtension(hdr));
+ for (int ii = 1; ii != 1024; ++ii) {
std::string path = basePath;
if (ii > 1) {
- path += '_';
- path += std::to_string(ii);
+ path += cmStrCat("_", ii);
}
path += ".cpp";
if (emitted.emplace(path).second) {
@@ -1369,10 +1349,8 @@
}
if (muf->MocIt || muf->UicIt) {
sources.emplace_back(muf->RealPath);
- std::string flags;
- flags += muf->MocIt ? 'M' : 'm';
- flags += muf->UicIt ? 'U' : 'u';
- sourcesFlags.emplace_back(std::move(flags));
+ sourcesFlags.emplace_back(
+ cmStrCat(muf->MocIt ? "M" : "m", muf->UicIt ? "U" : "u"));
}
}
}
@@ -1426,9 +1404,8 @@
ofs.WriteStrings("AM_UIC_SEARCH_PATHS", this->Uic.SearchPaths);
}
} else {
- std::string err = "AutoGen: Could not write file ";
- err += this->AutogenTarget.InfoFile;
- cmSystemTools::Error(err);
+ cmSystemTools::Error(cmStrCat("AutoGen: Could not write file ",
+ this->AutogenTarget.InfoFile));
return false;
}
@@ -1467,9 +1444,8 @@
ofs.WriteStrings("ARCC_OPTIONS", qrc.Options);
ofs.WriteStrings("ARCC_INPUTS", qrc.Resources);
} else {
- std::string err = "AutoRcc: Could not write file ";
- err += qrc.InfoFile;
- cmSystemTools::Error(err);
+ cmSystemTools::Error(
+ cmStrCat("AutoRcc: Could not write file ", qrc.InfoFile));
return false;
}
}
@@ -1524,13 +1500,10 @@
if (!groupName.empty()) {
sourceGroup = makefile->GetOrCreateSourceGroup(groupName);
if (sourceGroup == nullptr) {
- std::string err;
- err += genNameUpper;
- err += " error in ";
- err += property;
- err += ": Could not find or create the source group ";
- err += cmQtAutoGen::Quoted(groupName);
- cmSystemTools::Error(err);
+ cmSystemTools::Error(
+ cmStrCat(genNameUpper, " error in ", property,
+ ": Could not find or create the source group ",
+ cmQtAutoGen::Quoted(groupName)));
return false;
}
}
@@ -1622,12 +1595,8 @@
bool ignoreMissingTarget) const
{
auto print_err = [this, &genVars](std::string const& err) {
- std::string msg = genVars.GenNameUpper;
- msg += " for target ";
- msg += this->Target->GetName();
- msg += ": ";
- msg += err;
- cmSystemTools::Error(msg);
+ cmSystemTools::Error(cmStrCat(genVars.GenNameUpper, " for target ",
+ this->Target->GetName(), ": ", err));
};
// Custom executable
@@ -1687,11 +1656,8 @@
std::make_shared<cmQtAutoGen::CompilerFeatures>();
return true;
}
- std::string err = "Could not find ";
- err += executable;
- err += " executable target ";
- err += targetName;
- print_err(err);
+ print_err(cmStrCat("Could not find ", executable, " executable target ",
+ targetName));
return false;
}
}
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index eb0d35e..7d72cad 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
#include "cmQtAutoGen.h"
+#include "cm_string_view.hxx"
#include <map>
#include <memory>
@@ -85,24 +86,24 @@
/// @return True if the file is open
explicit operator bool() const { return static_cast<bool>(Ofs_); }
- void Write(const char* text) { Ofs_ << text; }
- void Write(const char* key, std::string const& value);
- void WriteUInt(const char* key, unsigned int value);
+ void Write(cm::string_view text) { Ofs_ << text; }
+ void Write(cm::string_view, std::string const& value);
+ void WriteUInt(cm::string_view, unsigned int value);
template <class C>
- void WriteStrings(const char* key, C const& container);
- void WriteConfig(const char* key,
+ void WriteStrings(cm::string_view, C const& container);
+ void WriteConfig(cm::string_view,
std::map<std::string, std::string> const& map);
template <class C>
- void WriteConfigStrings(const char* key,
+ void WriteConfigStrings(cm::string_view,
std::map<std::string, C> const& map);
- void WriteNestedLists(const char* key,
+ void WriteNestedLists(cm::string_view,
std::vector<std::vector<std::string>> const& lists);
private:
template <class IT>
static std::string ListJoin(IT it_begin, IT it_end);
- static std::string ConfigKey(const char* key, std::string const& config);
+ static std::string ConfigKey(cm::string_view, std::string const& config);
private:
cmGeneratedFileStream Ofs_;
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index 2516d84..0ad87b1 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -1,17 +1,17 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenerator.h"
-#include "cmQtAutoGen.h"
-
-#include "cmsys/FStream.hxx"
#include "cm_memory.hxx"
+#include "cmsys/FStream.hxx"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmQtAutoGen.h"
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -60,19 +60,13 @@
std::string cmQtAutoGenerator::Logger::HeadLine(std::string const& title)
{
- std::string head = title;
- head += '\n';
- head.append(head.size() - 1, '-');
- head += '\n';
- return head;
+ return cmStrCat(title, "\n", std::string(title.size(), '-'), "\n");
}
void cmQtAutoGenerator::Logger::Info(GenT genType,
std::string const& message) const
{
- std::string msg = GeneratorName(genType);
- msg += ": ";
- msg += message;
+ std::string msg = cmStrCat(GeneratorName(genType), ": ", message);
if (msg.back() != '\n') {
msg.push_back('\n');
}
@@ -110,19 +104,13 @@
std::string const& filename,
std::string const& message) const
{
- std::string msg = " ";
- msg += Quoted(filename);
- msg.push_back('\n');
- // Message
- msg += message;
- Warning(genType, msg);
+ Warning(genType, cmStrCat(" ", Quoted(filename), "\n", message));
}
void cmQtAutoGenerator::Logger::Error(GenT genType,
std::string const& message) const
{
- std::string msg;
- msg += HeadLine(GeneratorName(genType) + " error");
+ std::string msg = HeadLine(GeneratorName(genType) + " error");
// Message
msg += message;
if (msg.back() != '\n') {
@@ -139,12 +127,7 @@
std::string const& filename,
std::string const& message) const
{
- std::string emsg = " ";
- emsg += Quoted(filename);
- emsg += '\n';
- // Message
- emsg += message;
- Error(genType, emsg);
+ Error(genType, cmStrCat(" ", Quoted(filename), '\n', message));
}
void cmQtAutoGenerator::Logger::ErrorCommand(
@@ -280,10 +263,8 @@
InfoFile_ = infoFile;
cmSystemTools::ConvertToUnixSlashes(InfoFile_);
if (!InfoFileTime_.Load(InfoFile_)) {
- std::string msg = "AutoGen: The info file ";
- msg += Quoted(InfoFile_);
- msg += " is not readable\n";
- cmSystemTools::Stderr(msg);
+ cmSystemTools::Stderr(cmStrCat("AutoGen: The info file ",
+ Quoted(InfoFile_), " is not readable\n"));
return false;
}
InfoDir_ = cmSystemTools::GetFilenamePath(infoFile);
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 44d2db0..e693816 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -16,6 +16,7 @@
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmQtAutoGen.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
#include "cmsys/FStream.hxx"
@@ -301,10 +302,9 @@
}
// Execute command
if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
- std::string msg = "The content generation command for ";
- msg += Quoted(predefsFileRel);
- msg += " failed.\n";
- msg += result.ErrorMessage;
+ std::string msg =
+ cmStrCat("The content generation command for ",
+ Quoted(predefsFileRel), " failed.\n", result.ErrorMessage);
LogCommandError(GenT::MOC, msg, cmd, result.StdOut);
return;
}
@@ -313,9 +313,8 @@
// (Re)write predefs file only on demand
if (cmQtAutoGenerator::FileDiffers(predefsFileAbs, result.StdOut)) {
if (!cmQtAutoGenerator::FileWrite(predefsFileAbs, result.StdOut)) {
- std::string msg = "Writing ";
- msg += Quoted(predefsFileRel);
- msg += " failed.";
+ std::string msg =
+ cmStrCat("Writing ", Quoted(predefsFileRel), " failed.");
LogFileError(GenT::MOC, predefsFileAbs, msg);
return;
}
@@ -325,9 +324,8 @@
Log().Info(GenT::MOC, "Touching " + Quoted(predefsFileRel));
}
if (!cmSystemTools::Touch(predefsFileAbs, false)) {
- std::string msg = "Touching ";
- msg += Quoted(predefsFileAbs);
- msg += " failed.";
+ std::string msg =
+ cmStrCat("Touching ", Quoted(predefsFileAbs), " failed.");
LogFileError(GenT::MOC, predefsFileAbs, msg);
return;
}
@@ -662,13 +660,11 @@
if (!sourceIncludesDotMoc && !parseData.Macro.empty() &&
!(relaxedMode && sourceIncludesMocUnderscore)) {
{
- std::string emsg = "The file contains a ";
- emsg += Quoted(parseData.Macro);
- emsg += " macro, but does not include ";
- emsg += Quoted(sourceBase + ".moc");
- emsg += "!\nConsider to\n - add #include \"";
- emsg += sourceBase;
- emsg += ".moc\"\n - enable SKIP_AUTOMOC for this file";
+ std::string emsg =
+ cmStrCat("The file contains a ", Quoted(parseData.Macro),
+ " macro, but does not include ", Quoted(sourceBase + ".moc"),
+ "!\nConsider to\n - add #include \"", sourceBase,
+ ".moc\"\n - enable SKIP_AUTOMOC for this file");
LogFileError(GenT::MOC, sourceFile.FileName, emsg);
}
return false;
@@ -699,18 +695,14 @@
// used. This is for KDE4 compatibility.
{
// Issue a warning
- std::string msg = "The file contains a ";
- msg += Quoted(parseData.Macro);
- msg += " macro, but does not include ";
- msg += Quoted(sourceBase + ".moc");
- msg += ".\nInstead it includes ";
- msg += Quoted(incKey.Key);
- msg += ".\nRunning moc on the source\n ";
- msg += Quoted(sourceFile.FileName);
- msg += "!\nBetter include ";
- msg += Quoted(sourceBase + ".moc");
- msg += " for compatibility with regular mode.\n";
- msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n";
+ std::string msg = cmStrCat(
+ "The file contains a ", Quoted(parseData.Macro),
+ " macro, but does not include ", Quoted(sourceBase + ".moc"),
+ ".\nInstead it includes ", Quoted(incKey.Key),
+ ".\nRunning moc on the source\n ", Quoted(sourceFile.FileName),
+ "!\nBetter include ", Quoted(sourceBase + ".moc"),
+ " for compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
}
// Create mapping
@@ -763,28 +755,22 @@
}
// Issue a warning
if (ownMoc && parseData.Macro.empty()) {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += ", but does not contain a\n";
- msg += MocConst().MacrosString();
- msg += " macro.\nRunning moc on the header\n ";
- msg += Quoted(header->FileName);
- msg += "!\nBetter include ";
- msg += Quoted("moc_" + incKey.Base + ".cpp");
- msg += " for a compatibility with regular mode.\n";
- msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n";
+ std::string msg = cmStrCat(
+ "The file includes the moc file ", Quoted(incKey.Key),
+ ", but does not contain a\n", MocConst().MacrosString(),
+ " macro.\nRunning moc on the header\n ", Quoted(header->FileName),
+ "!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"),
+ " for a compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
} else {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += " instead of ";
- msg += Quoted("moc_" + incKey.Base + ".cpp");
- msg += ".\nRunning moc on the header\n ";
- msg += Quoted(header->FileName);
- msg += "!\nBetter include ";
- msg += Quoted("moc_" + incKey.Base + ".cpp");
- msg += " for compatibility with regular mode.\n";
- msg += "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n";
+ std::string msg = cmStrCat(
+ "The file includes the moc file ", Quoted(incKey.Key),
+ " instead of ", Quoted("moc_" + incKey.Base + ".cpp"),
+ ".\nRunning moc on the header\n ", Quoted(header->FileName),
+ "!\nBetter include ", Quoted("moc_" + incKey.Base + ".cpp"),
+ " for compatibility with regular mode.\n",
+ "This is a CMAKE_AUTOMOC_RELAXED_MODE warning.\n");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
}
// Create mapping
@@ -810,11 +796,9 @@
}
// Accept but issue a warning if moc isn't required
if (parseData.Macro.empty()) {
- std::string msg = "The file includes the moc file ";
- msg += Quoted(incKey.Key);
- msg += ", but does not contain a ";
- msg += MocConst().MacrosString();
- msg += " macro.";
+ std::string msg = cmStrCat(
+ "The file includes the moc file ", Quoted(incKey.Key),
+ ", but does not contain a ", MocConst().MacrosString(), " macro.");
Log().WarningFile(GenT::MOC, sourceFile.FileName, msg);
}
// Create mapping
@@ -840,9 +824,7 @@
}
// Search in include directories
for (std::string const& path : MocConst().IncludePaths) {
- std::string testPath = path;
- testPath += '/';
- testPath += includeBase;
+ std::string testPath = cmStrCat(path, '/', includeBase);
SourceFileHandleT res = MocFindHeader(testPath);
if (res) {
return res;
@@ -892,10 +874,9 @@
{
std::ostringstream res;
{
- std::string exts = ".{";
- exts += cmJoin(BaseConst().HeaderExtensions, ",");
- exts += '}';
- // Compose result string
+ std::string exts =
+ cmStrCat(".{", cmJoin(BaseConst().HeaderExtensions, ","),
+ '}'); // Compose result string
res << " " << fileBase << exts << '\n';
for (std::string const& path : MocConst().IncludePaths) {
res << " " << path << '/' << fileBase << exts << '\n';
@@ -913,9 +894,8 @@
if (handle) {
// Check if the output file would be generated from different source files
if (handle->SourceFile != sourceFileHandle) {
- std::string msg = "The source files\n ";
- msg += Quoted(includerFileHandle->FileName);
- msg += '\n';
+ std::string msg = cmStrCat("The source files\n ",
+ Quoted(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
msg += " ";
msg += Quoted(item->FileName);
@@ -1019,9 +999,8 @@
MappingHandleT const& handle = it->second;
if (handle->SourceFile != uiFileHandle) {
// The output file already gets generated - from a different .ui file!
- std::string msg = "The source files\n ";
- msg += Quoted(includerFileHandle->FileName);
- msg += '\n';
+ std::string msg = cmStrCat("The source files\n ",
+ Quoted(includerFileHandle->FileName), '\n');
for (auto const& item : handle->IncluderFiles) {
msg += " ";
msg += Quoted(item->FileName);
@@ -1062,8 +1041,7 @@
std::string const& sourceFile, std::string const& sourceDir,
IncludeKeyT const& incKey) const
{
- std::string searchFileName = incKey.Base;
- searchFileName += ".ui";
+ std::string searchFileName = cmStrCat(incKey.Base, ".ui");
// Collect search paths list
std::vector<std::string> testFiles;
{
@@ -1073,26 +1051,17 @@
// Vicinity of the source
testFiles.emplace_back(sourceDir + searchFileName);
if (!incKey.Dir.empty()) {
- std::string path = sourceDir;
- path += incKey.Dir;
- path += searchFileName;
- testFiles.emplace_back(path);
+ testFiles.emplace_back(cmStrCat(sourceDir, incKey.Dir, searchFileName));
}
// AUTOUIC search paths
if (!searchPaths.empty()) {
for (std::string const& sPath : searchPaths) {
- std::string path = sPath;
- path += '/';
- path += searchFileName;
- testFiles.emplace_back(std::move(path));
+ testFiles.emplace_back(cmStrCat(sPath, '/', searchFileName));
}
if (!incKey.Dir.empty()) {
for (std::string const& sPath : searchPaths) {
- std::string path = sPath;
- path += '/';
- path += incKey.Dir;
- path += searchFileName;
- testFiles.emplace_back(std::move(path));
+ testFiles.emplace_back(
+ cmStrCat(sPath, '/', incKey.Dir, searchFileName));
}
}
}
@@ -1117,11 +1086,10 @@
// Log error
{
- std::string msg = "The file includes the uic file ";
- msg += Quoted(incKey.Key);
- msg += ",\nbut the user interface file ";
- msg += Quoted(searchFileName);
- msg += "\ncould not be found in the following locations\n";
+ std::string msg =
+ cmStrCat("The file includes the uic file ", Quoted(incKey.Key),
+ ",\nbut the user interface file ", Quoted(searchFileName),
+ "\ncould not be found in the following locations\n");
for (std::string const& testFile : testFiles) {
msg += " ";
msg += Quoted(testFile);
@@ -1417,10 +1385,9 @@
}
} else {
// Moc command failed
- std::string msg = "The moc process failed to compile\n ";
- msg += Quoted(sourceFile);
- msg += "\ninto\n ";
- msg += Quoted(outputFile);
+ std::string msg =
+ cmStrCat("The moc process failed to compile\n ", Quoted(sourceFile),
+ "\ninto\n ", Quoted(outputFile));
if (Mapping->IncluderFiles.empty()) {
msg += ".\n";
} else {
@@ -1466,11 +1433,9 @@
}
} else {
// Uic command failed
- std::string msg = "The uic process failed to compile\n ";
- msg += Quoted(sourceFile);
- msg += "\ninto\n ";
- msg += Quoted(outputFile);
- msg += "\nincluded by\n";
+ std::string msg =
+ cmStrCat("The uic process failed to compile\n ", Quoted(sourceFile),
+ "\ninto\n ", Quoted(outputFile), "\nincluded by\n");
for (auto const& item : Mapping->IncluderFiles) {
msg += " ";
msg += Quoted(item->FileName);
@@ -1563,12 +1528,8 @@
if (length >= 2) {
std::string::const_iterator itBeg = value.begin() + (pos + 1);
std::string::const_iterator itEnd = itBeg + (length - 2);
- {
- std::string subValue(itBeg, itEnd);
- std::vector<std::string> list;
- cmSystemTools::ExpandListArgument(subValue, list);
- lists.push_back(std::move(list));
- }
+ lists.emplace_back(
+ cmSystemTools::ExpandedListArgument(std::string(itBeg, itEnd)));
}
pos += length;
pos += ListSep.size();
@@ -1579,9 +1540,7 @@
auto InfoGetConfig = [makefile, this](const char* key) -> std::string {
const char* valueConf = nullptr;
{
- std::string keyConf = key;
- keyConf += '_';
- keyConf += InfoConfig();
+ std::string keyConf = cmStrCat(key, '_', InfoConfig());
valueConf = makefile->GetDefinition(keyConf);
}
if (valueConf == nullptr) {
@@ -1652,9 +1611,9 @@
return LogInfoError("CMake executable file name missing.");
}
if (!BaseConst_.CMakeExecutableTime.Load(BaseConst_.CMakeExecutable)) {
- std::string error = "The CMake executable ";
- error += Quoted(BaseConst_.CMakeExecutable);
- error += " does not exist.";
+ std::string error =
+ cmStrCat("The CMake executable ", Quoted(BaseConst_.CMakeExecutable),
+ " does not exist.");
return LogInfoError(error);
}
BaseConst_.ParseCacheFile = InfoGetConfig("AM_PARSE_CACHE_FILE");
@@ -1683,9 +1642,9 @@
MocConst_.Enabled = true;
// Load the executable file time
if (!MocConst_.ExecutableTime.Load(MocConst_.Executable)) {
- std::string error = "The moc executable ";
- error += Quoted(MocConst_.Executable);
- error += " does not exist.";
+ std::string error =
+ cmStrCat("The moc executable ", Quoted(MocConst_.Executable),
+ " does not exist.");
return LogInfoError(error);
}
for (std::string& sfl : InfoGetList("AM_MOC_SKIP")) {
@@ -1751,9 +1710,9 @@
UicConst_.Enabled = true;
// Load the executable file time
if (!UicConst_.ExecutableTime.Load(UicConst_.Executable)) {
- std::string error = "The uic executable ";
- error += Quoted(UicConst_.Executable);
- error += " does not exist.";
+ std::string error =
+ cmStrCat("The uic executable ", Quoted(UicConst_.Executable),
+ " does not exist.");
return LogInfoError(error);
}
for (std::string& sfl : InfoGetList("AM_UIC_SKIP")) {
@@ -1893,7 +1852,7 @@
std::list<std::string>::iterator it = includes.begin();
while (it != includes.end()) {
std::string const& path = *it;
- if (cmSystemTools::StringStartsWith(path, ppath->c_str())) {
+ if (cmHasPrefix(path, *ppath)) {
MocConst_.IncludePaths.push_back(path);
it = includes.erase(it);
} else {
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index 20885df..c75b2ca 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -11,6 +11,7 @@
#include "cmFileLockResult.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
// -- Class methods
@@ -35,9 +36,7 @@
this](std::string const& key) -> std::string {
const char* valueConf = nullptr;
{
- std::string keyConf = key;
- keyConf += '_';
- keyConf += InfoConfig();
+ std::string keyConf = cmStrCat(key, '_', InfoConfig());
valueConf = makefile->GetDefinition(keyConf);
}
if (valueConf == nullptr) {
@@ -81,9 +80,8 @@
// - Rcc executable
RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE");
if (!RccExecutableTime_.Load(RccExecutable_)) {
- std::string error = "The rcc executable ";
- error += Quoted(RccExecutable_);
- error += " does not exist.";
+ std::string error = cmStrCat("The rcc executable ", Quoted(RccExecutable_),
+ " does not exist.");
return LogInfoError(error);
}
RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS");
@@ -178,10 +176,8 @@
std::string cmQtAutoRcc::MultiConfigOutput() const
{
static std::string const suffix = "_CMAKE_";
- std::string res;
- res += RccPathChecksum_;
- res += '/';
- res += AppendFilenameSuffix(RccFileName_, suffix);
+ std::string res = cmStrCat(RccPathChecksum_, '/',
+ AppendFilenameSuffix(RccFileName_, suffix));
return res;
}
@@ -272,9 +268,7 @@
Log().Info(GenT::RCC, "Writing settings file " + Quoted(SettingsFile_));
}
// Write settings file
- std::string content = "rcc:";
- content += SettingsString_;
- content += '\n';
+ std::string content = cmStrCat("rcc:", SettingsString_, '\n');
std::string error;
if (!FileWrite(SettingsFile_, content, &error)) {
Log().ErrorFile(GenT::RCC, SettingsFile_,
@@ -402,10 +396,9 @@
// Test if the rcc output file is older than the info file
if (RccFileTime_.Older(InfoFileTime())) {
if (Log().Verbose()) {
- std::string reason = "Touching ";
- reason += Quoted(RccFileOutput_);
- reason += " because it is older than ";
- reason += Quoted(InfoFile());
+ std::string reason =
+ cmStrCat("Touching ", Quoted(RccFileOutput_),
+ " because it is older than ", Quoted(InfoFile()));
Log().Info(GenT::RCC, reason);
}
// Touch build file
@@ -456,10 +449,9 @@
if (!result || (retVal != 0)) {
// rcc process failed
{
- std::string err = "The rcc process failed to compile\n ";
- err += Quoted(QrcFile_);
- err += "\ninto\n ";
- err += Quoted(RccFileOutput_);
+ std::string err =
+ cmStrCat("The rcc process failed to compile\n ", Quoted(QrcFile_),
+ "\ninto\n ", Quoted(RccFileOutput_));
Log().ErrorCommand(GenT::RCC, err, cmd, rccStdOut + rccStdErr);
}
cmSystemTools::RemoveFile(RccFileOutput_);
@@ -481,12 +473,10 @@
// Generate a wrapper source file on demand
if (IsMultiConfig()) {
// Wrapper file content
- std::string content;
- content += "// This is an autogenerated configuration wrapper file.\n";
- content += "// Changes will be overwritten.\n";
- content += "#include <";
- content += MultiConfigOutput();
- content += ">\n";
+ std::string content =
+ cmStrCat("// This is an autogenerated configuration wrapper file.\n",
+ "// Changes will be overwritten.\n", "#include <",
+ MultiConfigOutput(), ">\n");
// Compare with existing file content
bool fileDiffers = true;
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 2064275..1f9aae8 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -4,6 +4,7 @@
#include "cmAlgorithms.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
@@ -341,7 +342,7 @@
{
for (auto line : this->MarkupLines) {
if (!line.empty()) {
- line = " " + line;
+ line = cmStrCat(" ", line);
}
this->OutputLine(line, inlineMarkup);
}
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 45aff69..37a87e5 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -6,14 +6,14 @@
#include "cmBinUtilsLinuxELFLinker.h"
#include "cmBinUtilsMacOSMachOLinker.h"
#include "cmBinUtilsWindowsPELinker.h"
-#include "cmCommand.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#if defined(_WIN32)
# include "cmGlobalGenerator.h"
-# ifdef CMAKE_BUILD_WITH_CMAKE
+# ifndef CMAKE_BOOTSTRAP
# include "cmGlobalVisualStudioVersionedGenerator.h"
# endif
# include "cmVSSetupHelper.h"
@@ -36,7 +36,7 @@
// If generating for the VS IDE, use the same instance.
std::string vsloc;
bool found = false;
-# ifdef CMAKE_BUILD_WITH_CMAKE
+# ifndef CMAKE_BOOTSTRAP
if (gg->GetName().find(prefix) == 0) {
cmGlobalVisualStudioVersionedGenerator* vsgen =
static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
@@ -108,13 +108,13 @@
}
cmRuntimeDependencyArchive::cmRuntimeDependencyArchive(
- cmCommand* command, std::vector<std::string> searchDirectories,
+ cmExecutionStatus& status, std::vector<std::string> searchDirectories,
std::string bundleExecutable,
const std::vector<std::string>& preIncludeRegexes,
const std::vector<std::string>& preExcludeRegexes,
const std::vector<std::string>& postIncludeRegexes,
const std::vector<std::string>& postExcludeRegexes)
- : Command(command)
+ : Status(status)
, SearchDirectories(std::move(searchDirectories))
, BundleExecutable(std::move(bundleExecutable))
, PreIncludeRegexes(preIncludeRegexes.size())
@@ -190,7 +190,7 @@
void cmRuntimeDependencyArchive::SetError(const std::string& e)
{
- this->Command->SetError(e);
+ this->Status.SetError(e);
}
std::string cmRuntimeDependencyArchive::GetBundleExecutable()
@@ -361,7 +361,7 @@
cmMakefile* cmRuntimeDependencyArchive::GetMakefile()
{
- return this->Command->GetMakefile();
+ return &this->Status.GetMakefile();
}
const std::map<std::string, std::set<std::string>>&
diff --git a/Source/cmRuntimeDependencyArchive.h b/Source/cmRuntimeDependencyArchive.h
index 67efec7..e063121 100644
--- a/Source/cmRuntimeDependencyArchive.h
+++ b/Source/cmRuntimeDependencyArchive.h
@@ -14,14 +14,14 @@
#include <string>
#include <vector>
-class cmCommand;
+class cmExecutionStatus;
class cmMakefile;
class cmRuntimeDependencyArchive
{
public:
explicit cmRuntimeDependencyArchive(
- cmCommand* command, std::vector<std::string> searchDirectories,
+ cmExecutionStatus& status, std::vector<std::string> searchDirectories,
std::string bundleExecutable,
const std::vector<std::string>& preIncludeRegexes,
const std::vector<std::string>& preExcludeRegexes,
@@ -51,7 +51,7 @@
const std::set<std::string>& GetUnresolvedPaths();
private:
- cmCommand* Command;
+ cmExecutionStatus& Status;
std::unique_ptr<cmBinUtilsLinker> Linker;
std::string GetRuntimeDependenciesTool;
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index f98984e..879cc95 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -6,9 +6,9 @@
#include <cassert>
#include <utility>
-#include "cmAlgorithms.h"
#include "cmFindCommon.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmSearchPath::cmSearchPath(cmFindCommon* findCmd)
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index c5de742..8fcb710 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -378,8 +378,7 @@
SendSignal(kFILE_CHANGE_SIGNAL, obj);
}
-const cmServerResponse cmServerProtocol1::Process(
- const cmServerRequest& request)
+cmServerResponse cmServerProtocol1::Process(const cmServerRequest& request)
{
assert(this->m_State >= STATE_ACTIVE);
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 2f55a20..5da4344 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -80,7 +80,7 @@
virtual std::pair<int, int> ProtocolVersion() const = 0;
virtual bool IsExperimental() const = 0;
- virtual const cmServerResponse Process(const cmServerRequest& request) = 0;
+ virtual cmServerResponse Process(const cmServerRequest& request) = 0;
bool Activate(cmServer* server, const cmServerRequest& request,
std::string* errorMessage);
@@ -106,7 +106,7 @@
public:
std::pair<int, int> ProtocolVersion() const override;
bool IsExperimental() const override;
- const cmServerResponse Process(const cmServerRequest& request) override;
+ cmServerResponse Process(const cmServerRequest& request) override;
private:
bool DoActivate(const cmServerRequest& request,
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index b36878c..1a12785 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -2,12 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetCommand.h"
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index d887627..6e2e820 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -2,10 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSourceFileLocation.h"
-#include "cmAlgorithms.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index 5cdacaa..880773b 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -9,6 +9,7 @@
#include "cmMakefile.h"
#include "cmSourceGroup.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
namespace {
@@ -20,7 +21,7 @@
std::vector<std::string> tokenizePath(const std::string& path)
{
- return cmSystemTools::tokenize(path, "\\/");
+ return cmTokenize(path, "\\/");
}
std::string getFullFilePath(const std::string& currentPath,
@@ -54,8 +55,8 @@
const std::vector<std::string>& files, std::string& error)
{
for (std::string const& file : files) {
- if (!cmSystemTools::StringStartsWith(file, root.c_str())) {
- error = "ROOT: " + root + " is not a prefix of file: " + file;
+ if (!cmHasPrefix(file, root)) {
+ error = cmStrCat("ROOT: ", root, " is not a prefix of file: ", file);
return false;
}
}
@@ -63,15 +64,6 @@
return true;
}
-std::string prepareFilePathForTree(const std::string& path,
- const std::string& currentSourceDir)
-{
- if (!cmSystemTools::FileIsFullPath(path)) {
- return cmSystemTools::CollapseFullPath(currentSourceDir + "/" + path);
- }
- return cmSystemTools::CollapseFullPath(path);
-}
-
std::vector<std::string> prepareFilesPathsForTree(
const std::vector<std::string>& filesPaths,
const std::string& currentSourceDir)
@@ -80,9 +72,11 @@
prepared.reserve(filesPaths.size());
for (auto const& filePath : filesPaths) {
+ std::string fullPath =
+ cmSystemTools::CollapseFullPath(filePath, currentSourceDir);
// If provided file path is actually not a file, silently ignore it.
- if (cmSystemTools::FileExists(filePath, /*isFile=*/true)) {
- prepared.push_back(prepareFilePathForTree(filePath, currentSourceDir));
+ if (cmSystemTools::FileExists(fullPath, /*isFile=*/true)) {
+ prepared.emplace_back(std::move(fullPath));
}
}
@@ -100,7 +94,7 @@
std::vector<std::string> tokenizedPath;
if (!prefix.empty()) {
- tokenizedPath = tokenizePath(prefix + '/' + sgFilesPath);
+ tokenizedPath = tokenizePath(cmStrCat(prefix, '/', sgFilesPath));
} else {
tokenizedPath = tokenizePath(sgFilesPath);
}
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 6f9c935..1ea72e1 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -11,7 +11,6 @@
#include "cm_memory.hxx"
-#include "cmAlgorithms.h"
#include "cmCacheManager.h"
#include "cmCommand.h"
#include "cmDefinitions.h"
@@ -22,6 +21,7 @@
#include "cmMakefile.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index 6956594..fe15563 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -14,6 +14,7 @@
#include "cmListFileCache.h"
#include "cmStatePrivate.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
class cmStateDirectory
{
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
new file mode 100644
index 0000000..eca761b
--- /dev/null
+++ b/Source/cmStringAlgorithms.cxx
@@ -0,0 +1,140 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmStringAlgorithms.h"
+
+#include <algorithm>
+#include <cstdio>
+
+std::string cmTrimWhitespace(cm::string_view str)
+{
+ auto start = str.begin();
+ while (start != str.end() && cmIsSpace(*start)) {
+ ++start;
+ }
+ if (start == str.end()) {
+ return std::string();
+ }
+ auto stop = str.end() - 1;
+ while (cmIsSpace(*stop)) {
+ --stop;
+ }
+ return std::string(start, stop + 1);
+}
+
+std::string cmRemoveQuotes(cm::string_view str)
+{
+ // We process only strings that have two quotes at least.
+ // Also front() and back() are only defined behavior on non empty strings.
+ if (str.size() >= 2 && //
+ str.front() == '"' && //
+ str.back() == '"') {
+ // Remove a quote from the front and back
+ str.remove_prefix(1);
+ str.remove_suffix(1);
+ }
+ return std::string(str);
+}
+
+std::string cmEscapeQuotes(cm::string_view str)
+{
+ std::string result;
+ result.reserve(str.size());
+ for (const char ch : str) {
+ if (ch == '"') {
+ result += '\\';
+ }
+ result += ch;
+ }
+ return result;
+}
+
+std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep)
+{
+ std::vector<std::string> tokens;
+ cm::string_view::size_type tokend = 0;
+
+ do {
+ cm::string_view::size_type tokstart = str.find_first_not_of(sep, tokend);
+ if (tokstart == cm::string_view::npos) {
+ break; // no more tokens
+ }
+ tokend = str.find_first_of(sep, tokstart);
+ if (tokend == cm::string_view::npos) {
+ tokens.emplace_back(str.substr(tokstart));
+ } else {
+ tokens.emplace_back(str.substr(tokstart, tokend - tokstart));
+ }
+ } while (tokend != cm::string_view::npos);
+
+ if (tokens.empty()) {
+ tokens.emplace_back();
+ }
+ return tokens;
+}
+
+namespace {
+template <std::size_t N, typename T>
+inline void MakeDigits(cm::string_view& view, char (&digits)[N],
+ const char* pattern, T value)
+{
+ int res = std::snprintf(digits, N, pattern, value);
+ if (res > 0 && res < static_cast<int>(N)) {
+ view = cm::string_view(digits, static_cast<std::size_t>(res));
+ }
+}
+} // unnamed namespace
+
+cmAlphaNum::cmAlphaNum(int val)
+{
+ MakeDigits(View_, Digits_, "%i", val);
+}
+
+cmAlphaNum::cmAlphaNum(unsigned int val)
+{
+ MakeDigits(View_, Digits_, "%u", val);
+}
+
+cmAlphaNum::cmAlphaNum(long int val)
+{
+ MakeDigits(View_, Digits_, "%li", val);
+}
+
+cmAlphaNum::cmAlphaNum(unsigned long int val)
+{
+ MakeDigits(View_, Digits_, "%lu", val);
+}
+
+cmAlphaNum::cmAlphaNum(long long int val)
+{
+ MakeDigits(View_, Digits_, "%lli", val);
+}
+
+cmAlphaNum::cmAlphaNum(unsigned long long int val)
+{
+ MakeDigits(View_, Digits_, "%llu", val);
+}
+
+cmAlphaNum::cmAlphaNum(float val)
+{
+ MakeDigits(View_, Digits_, "%g", static_cast<double>(val));
+}
+
+cmAlphaNum::cmAlphaNum(double val)
+{
+ MakeDigits(View_, Digits_, "%g", val);
+}
+
+std::string cmCatViews(std::initializer_list<cm::string_view> views)
+{
+ std::size_t total_size = 0;
+ for (cm::string_view const& view : views) {
+ total_size += view.size();
+ }
+
+ std::string result(total_size, '\0');
+ std::string::iterator sit = result.begin();
+ for (cm::string_view const& view : views) {
+ sit = std::copy_n(view.data(), view.size(), sit);
+ }
+ return result;
+}
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
new file mode 100644
index 0000000..44b01b8
--- /dev/null
+++ b/Source/cmStringAlgorithms.h
@@ -0,0 +1,196 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmStringAlgorithms_h
+#define cmStringAlgorithms_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cmRange.h"
+#include "cm_string_view.hxx"
+#include <cctype>
+#include <initializer_list>
+#include <sstream>
+#include <string.h>
+#include <string>
+#include <utility>
+#include <vector>
+
+/** String range type. */
+typedef cmRange<std::vector<std::string>::const_iterator> cmStringRange;
+
+/** Callable string comparison struct. */
+struct cmStrCmp
+{
+ cmStrCmp(std::string str)
+ : Test_(std::move(str))
+ {
+ }
+
+ bool operator()(cm::string_view sv) const { return Test_ == sv; }
+
+private:
+ std::string const Test_;
+};
+
+/** Returns true if the character @a ch is a whitespace character. **/
+inline bool cmIsSpace(char ch)
+{
+ return ((ch & 0x80) == 0) && std::isspace(ch);
+}
+
+/** Returns a string that has whitespace removed from the start and the end. */
+std::string cmTrimWhitespace(cm::string_view str);
+
+/** Returns a string that has quotes removed from the start and the end. */
+std::string cmRemoveQuotes(cm::string_view str);
+
+/** Escape quotes in a string. */
+std::string cmEscapeQuotes(cm::string_view str);
+
+/** Joins elements of a range with separator into a single string. */
+template <typename Range>
+std::string cmJoin(Range const& rng, cm::string_view separator)
+{
+ if (rng.empty()) {
+ return std::string();
+ }
+
+ std::ostringstream os;
+ auto it = rng.begin();
+ auto const end = rng.end();
+ os << *it;
+ while (++it != end) {
+ os << separator << *it;
+ }
+ return os.str();
+}
+
+/** Extract tokens that are separated by any of the characters in @a sep. */
+std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
+
+/** Concatenate string pieces into a single string. */
+std::string cmCatViews(std::initializer_list<cm::string_view> views);
+
+/** Utility class for cmStrCat. */
+class cmAlphaNum
+{
+public:
+ cmAlphaNum(cm::string_view view)
+ : View_(view)
+ {
+ }
+ cmAlphaNum(std::string const& str)
+ : View_(str)
+ {
+ }
+ cmAlphaNum(const char* str)
+ : View_(str)
+ {
+ }
+ cmAlphaNum(char ch)
+ : View_(Digits_, 1)
+ {
+ Digits_[0] = ch;
+ }
+ cmAlphaNum(int val);
+ cmAlphaNum(unsigned int val);
+ cmAlphaNum(long int val);
+ cmAlphaNum(unsigned long int val);
+ cmAlphaNum(long long int val);
+ cmAlphaNum(unsigned long long int val);
+ cmAlphaNum(float val);
+ cmAlphaNum(double val);
+
+ cm::string_view View() const { return View_; }
+
+private:
+ cm::string_view View_;
+ char Digits_[32];
+};
+
+/** Concatenate string pieces and numbers into a single string. */
+template <typename... AV>
+inline std::string cmStrCat(cmAlphaNum const& a, cmAlphaNum const& b,
+ AV const&... args)
+{
+ return cmCatViews(
+ { a.View(), b.View(), static_cast<cmAlphaNum const&>(args).View()... });
+}
+
+/** Joins wrapped elements of a range with separator into a single string. */
+template <typename Range>
+std::string cmWrap(cm::string_view prefix, Range const& rng,
+ cm::string_view suffix, cm::string_view sep)
+{
+ if (rng.empty()) {
+ return std::string();
+ }
+ return cmCatViews(
+ { prefix, cmJoin(rng, cmCatViews({ suffix, sep, prefix })), suffix });
+}
+
+/** Joins wrapped elements of a range with separator into a single string. */
+template <typename Range>
+std::string cmWrap(char prefix, Range const& rng, char suffix,
+ cm::string_view sep)
+{
+ return cmWrap(cm::string_view(&prefix, 1), rng, cm::string_view(&suffix, 1),
+ sep);
+}
+
+/** Returns true if string @a str starts with the character @a prefix. */
+inline bool cmHasPrefix(cm::string_view str, char prefix)
+{
+ return !str.empty() && (str.front() == prefix);
+}
+
+/** Returns true if string @a str starts with string @a prefix. */
+inline bool cmHasPrefix(cm::string_view str, cm::string_view prefix)
+{
+ return str.compare(0, prefix.size(), prefix) == 0;
+}
+
+/** Returns true if string @a str starts with string @a prefix. */
+template <size_t N>
+inline bool cmHasLiteralPrefix(cm::string_view str, const char (&prefix)[N])
+{
+ return cmHasPrefix(str, cm::string_view(prefix, N - 1));
+}
+
+/** Returns true if string @a str ends with the character @a suffix. */
+inline bool cmHasSuffix(cm::string_view str, char suffix)
+{
+ return !str.empty() && (str.back() == suffix);
+}
+
+/** Returns true if string @a str ends with string @a suffix. */
+inline bool cmHasSuffix(cm::string_view str, cm::string_view suffix)
+{
+ return str.size() >= suffix.size() &&
+ str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+/** Returns true if string @a str ends with string @a suffix. */
+template <size_t N>
+inline bool cmHasLiteralSuffix(cm::string_view str, const char (&suffix)[N])
+{
+ return cmHasSuffix(str, cm::string_view(suffix, N - 1));
+}
+
+/** Removes an existing suffix character of from the string @a str. */
+inline void cmStripSuffixIfExists(std::string& str, char suffix)
+{
+ if (cmHasSuffix(str, suffix)) {
+ str.pop_back();
+ }
+}
+
+/** Removes an existing suffix string of from the string @a str. */
+inline void cmStripSuffixIfExists(std::string& str, cm::string_view suffix)
+{
+ if (cmHasSuffix(str, suffix)) {
+ str.resize(str.size() - suffix.size());
+ }
+}
+
+#endif
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 259d92a..46d9459 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -18,6 +18,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cmStringReplaceHelper.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
@@ -112,7 +113,7 @@
bool cmStringCommand::HandleHashCommand(std::vector<std::string> const& args)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args.size() != 3) {
std::ostringstream e;
e << args[0] << " requires an output variable and an input string";
@@ -877,7 +878,7 @@
bool cmStringCommand::HandleUuidCommand(std::vector<std::string> const& args)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
unsigned int argsIndex = 1;
if (args.size() < 2) {
diff --git a/Source/cmSubcommandTable.cxx b/Source/cmSubcommandTable.cxx
new file mode 100644
index 0000000..f6194f8
--- /dev/null
+++ b/Source/cmSubcommandTable.cxx
@@ -0,0 +1,31 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmSubcommandTable.h"
+
+#include <algorithm>
+
+#include "cmExecutionStatus.h"
+#include "cmStringAlgorithms.h"
+
+cmSubcommandTable::cmSubcommandTable(std::initializer_list<InitElem> init)
+ : Impl(init.begin(), init.end())
+{
+ std::sort(this->Impl.begin(), this->Impl.end(),
+ [](Elem const& left, Elem const& right) {
+ return left.first < right.first;
+ });
+}
+
+bool cmSubcommandTable::operator()(cm::string_view key,
+ std::vector<std::string> const& args,
+ cmExecutionStatus& status) const
+{
+ auto const it = std::lower_bound(
+ this->Impl.begin(), this->Impl.end(), key,
+ [](Elem const& elem, cm::string_view k) { return elem.first < k; });
+ if (it != this->Impl.end() && it->first == key) {
+ return it->second(args, status);
+ }
+ status.SetError(cmStrCat("does not recognize sub-command ", key));
+ return false;
+}
diff --git a/Source/cmSubcommandTable.h b/Source/cmSubcommandTable.h
new file mode 100644
index 0000000..21342bb
--- /dev/null
+++ b/Source/cmSubcommandTable.h
@@ -0,0 +1,36 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmSubcommandTable_h
+#define cmSubcommandTable_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
+
+#include <initializer_list>
+#include <string>
+#include <utility>
+#include <vector>
+
+class cmExecutionStatus;
+
+class cmSubcommandTable
+{
+public:
+ using Command = bool (*)(std::vector<std::string> const&,
+ cmExecutionStatus&);
+
+ using Elem = std::pair<cm::string_view, Command>;
+ using InitElem = std::pair<cm::static_string_view, Command>;
+
+ cmSubcommandTable(std::initializer_list<InitElem> init);
+
+ bool operator()(cm::string_view key, std::vector<std::string> const& args,
+ cmExecutionStatus& status) const;
+
+private:
+ std::vector<Elem> Impl;
+};
+
+#endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 3ba3640..785e221 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -6,9 +6,10 @@
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
+#include "cmStringAlgorithms.h"
#include "cm_uv.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmArchiveWrite.h"
# include "cmLocale.h"
# include "cm_libarchive.h"
@@ -20,7 +21,7 @@
# endif
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmCryptoHash.h"
#endif
@@ -83,11 +84,6 @@
} // namespace
-static bool cm_isspace(char c)
-{
- return ((c & 0x80) == 0) && isspace(c);
-}
-
#if !defined(HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE)
// For GetEnvironmentVariables
# if defined(_WIN32)
@@ -97,7 +93,7 @@
# endif
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
static std::string cm_archive_entry_pathname(struct archive_entry* entry)
{
# if cmsys_STL_HAS_WSTRING
@@ -176,42 +172,14 @@
}
#endif
-std::string cmSystemTools::EscapeQuotes(const std::string& str)
+std::string cmSystemTools::HelpFileName(cm::string_view str)
{
- std::string result;
- result.reserve(str.size());
- for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
- if (*ch == '"') {
- result += '\\';
- }
- result += *ch;
- }
- return result;
-}
-
-std::string cmSystemTools::HelpFileName(std::string name)
-{
+ std::string name(str);
cmSystemTools::ReplaceString(name, "<", "");
cmSystemTools::ReplaceString(name, ">", "");
return name;
}
-std::string cmSystemTools::TrimWhitespace(const std::string& s)
-{
- std::string::const_iterator start = s.begin();
- while (start != s.end() && cm_isspace(*start)) {
- ++start;
- }
- if (start == s.end()) {
- return "";
- }
- std::string::const_iterator stop = s.end() - 1;
- while (cm_isspace(*stop)) {
- --stop;
- }
- return std::string(start, stop + 1);
-}
-
void cmSystemTools::Error(const std::string& m)
{
std::string message = "CMake Error: " + m;
@@ -394,7 +362,7 @@
} else {
arg.append(backslashes, '\\');
backslashes = 0;
- if (cm_isspace(*c)) {
+ if (cmIsSpace(*c)) {
if (in_quotes) {
arg.append(1, *c);
} else if (in_argument) {
@@ -833,7 +801,7 @@
cmSystemTools::ConvertToUnixSlashes(dir);
std::string prevDir;
while (dir != prevDir) {
- std::string path = dir + "/" + file;
+ std::string path = cmStrCat(dir, "/", file);
if (cmSystemTools::FileExists(path)) {
return path;
}
@@ -976,7 +944,7 @@
std::string cmSystemTools::ComputeFileHash(const std::string& source,
cmCryptoHash::Algo algo)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmCryptoHash hash(algo);
return hash.HashFile(source);
#else
@@ -989,7 +957,7 @@
std::string cmSystemTools::ComputeStringMD5(const std::string& input)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmCryptoHash md5(cmCryptoHash::AlgoMD5);
return md5.HashString(input);
#else
@@ -1005,7 +973,7 @@
{
std::string thumbprint;
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32)
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
BYTE* certData = NULL;
CRYPT_INTEGER_BLOB cryptBlob;
HCERTSTORE certStore = NULL;
@@ -1121,7 +1089,7 @@
}
}
-void cmSystemTools::ExpandListArgument(const std::string& arg,
+void cmSystemTools::ExpandListArgument(cm::string_view arg,
std::vector<std::string>& argsOut,
bool emptyArgs)
{
@@ -1129,25 +1097,29 @@
if (!emptyArgs && arg.empty()) {
return;
}
+
// if there are no ; in the name then just copy the current string
- if (arg.find(';') == std::string::npos) {
- argsOut.push_back(arg);
+ if (arg.find(';') == cm::string_view::npos) {
+ argsOut.emplace_back(arg);
return;
}
+
std::string newArg;
- const char* last = arg.c_str();
// Break the string at non-escaped semicolons not nested in [].
int squareNesting = 0;
- for (const char* c = last; *c; ++c) {
+ cm::string_view::iterator last = arg.begin();
+ cm::string_view::iterator const cend = arg.end();
+ for (cm::string_view::iterator c = last; c != cend; ++c) {
switch (*c) {
case '\\': {
// We only want to allow escaping of semicolons. Other
// escapes should not be processed here.
- const char* next = c + 1;
- if (*next == ';') {
- newArg.append(last, c - last);
+ cm::string_view::iterator cnext = c + 1;
+ if ((cnext != cend) && *cnext == ';') {
+ newArg.append(last, c);
// Skip over the escape character
- last = c = next;
+ last = cnext;
+ c = cnext;
}
} break;
case '[': {
@@ -1160,7 +1132,7 @@
// Break the string here if we are not nested inside square
// brackets.
if (squareNesting == 0) {
- newArg.append(last, c - last);
+ newArg.append(last, c);
// Skip over the semicolon
last = c + 1;
if (!newArg.empty() || emptyArgs) {
@@ -1175,15 +1147,15 @@
} break;
}
}
- newArg.append(last);
+ newArg.append(last, cend);
if (!newArg.empty() || emptyArgs) {
// Add the last argument if the string is not empty.
- argsOut.push_back(newArg);
+ argsOut.push_back(std::move(newArg));
}
}
std::vector<std::string> cmSystemTools::ExpandedListArgument(
- const std::string& arg, bool emptyArgs)
+ cm::string_view arg, bool emptyArgs)
{
std::vector<std::string> argsOut;
ExpandListArgument(arg, argsOut, emptyArgs);
@@ -1359,7 +1331,7 @@
return relative;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
bool cmSystemTools::UnsetEnv(const char* value)
{
# if !defined(HAVE_UNSETENV)
@@ -1424,7 +1396,7 @@
// output and allow it to be captured on the fly.
cmSystemTools::PutEnv("vsconsoleoutput=1");
-# ifdef CMAKE_BUILD_WITH_CMAKE
+# ifndef CMAKE_BOOTSTRAP
// VS sets an environment variable to tell MS tools like "cl" to report
// output through a backdoor pipe instead of stdout/stderr. Unset the
// environment variable to close this backdoor for any path of process
@@ -1446,7 +1418,7 @@
std::string const& mtime,
std::string const& format)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
cmsys::ofstream fout(outFileName.c_str(), std::ios::out | std::ios::binary);
if (!fout) {
@@ -1500,7 +1472,7 @@
#endif
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
namespace {
# define BSDTAR_FILESIZE_PRINTF "%lu"
# define BSDTAR_FILESIZE_TYPE unsigned long
@@ -1796,7 +1768,7 @@
const std::vector<std::string>& files,
bool verbose)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
return extract_tar(outFileName, files, verbose, true);
#else
(void)outFileName;
@@ -1810,7 +1782,7 @@
const std::vector<std::string>& files,
bool verbose)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
return extract_tar(outFileName, files, verbose, false);
#else
(void)outFileName;
@@ -2139,7 +2111,7 @@
cmSystemToolsCMakeCommand = exe_dir;
cmSystemToolsCMakeCommand += "/cmake";
cmSystemToolsCMakeCommand += cmSystemTools::GetExecutableExtension();
-#ifndef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMAKE_BOOTSTRAP
// The bootstrap cmake does not provide the other tools,
// so use the directory where they are about to be built.
exe_dir = CMAKE_BOOTSTRAP_BINARY_DIR "/bin";
@@ -2169,7 +2141,7 @@
cmSystemToolsCMClDepsCommand.clear();
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// Install tree has
// - "<prefix><CMAKE_BIN_DIR>/cmake"
// - "<prefix><CMAKE_DATA_DIR>"
@@ -2876,31 +2848,6 @@
return false;
}
-std::vector<std::string> cmSystemTools::tokenize(const std::string& str,
- const std::string& sep)
-{
- std::vector<std::string> tokens;
- std::string::size_type tokend = 0;
-
- do {
- std::string::size_type tokstart = str.find_first_not_of(sep, tokend);
- if (tokstart == std::string::npos) {
- break; // no more tokens
- }
- tokend = str.find_first_of(sep, tokstart);
- if (tokend == std::string::npos) {
- tokens.push_back(str.substr(tokstart));
- } else {
- tokens.push_back(str.substr(tokstart, tokend - tokstart));
- }
- } while (tokend != std::string::npos);
-
- if (tokens.empty()) {
- tokens.emplace_back();
- }
- return tokens;
-}
-
bool cmSystemTools::StringToLong(const char* str, long* value)
{
errno = 0;
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index 1962389..4f76b00 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -32,7 +32,7 @@
* Expand the ; separated string @a arg into multiple arguments.
* All found arguments are appended to @a argsOut.
*/
- static void ExpandListArgument(const std::string& arg,
+ static void ExpandListArgument(cm::string_view arg,
std::vector<std::string>& argsOut,
bool emptyArgs = false);
@@ -54,7 +54,7 @@
* Same as ExpandListArgument but a new vector is created containing
* the expanded arguments from the string @a arg.
*/
- static std::vector<std::string> ExpandedListArgument(const std::string& arg,
+ static std::vector<std::string> ExpandedListArgument(cm::string_view arg,
bool emptyArgs = false);
/**
@@ -77,16 +77,8 @@
static void ExpandRegistryValues(std::string& source,
KeyWOW64 view = KeyWOW64_Default);
- //! Escape quotes in a string.
- static std::string EscapeQuotes(const std::string& str);
-
/** Map help document name to file name. */
- static std::string HelpFileName(std::string);
-
- /**
- * Returns a string that has whitespace removed from the start and the end.
- */
- static std::string TrimWhitespace(const std::string& s);
+ static std::string HelpFileName(cm::string_view);
using MessageCallback = std::function<void(const std::string&, const char*)>;
/**
@@ -395,7 +387,7 @@
static std::string ForceToRelativePath(std::string const& local_path,
std::string const& remote_path);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
/** Remove an environment variable */
static bool UnsetEnv(const char* value);
@@ -508,10 +500,6 @@
/** Remove a directory; repeat a few times in case of locked files. */
static bool RepeatedRemoveDirectory(const std::string& dir);
- /** Tokenize a string */
- static std::vector<std::string> tokenize(const std::string& str,
- const std::string& sep);
-
/** Convert string to long. Expected that the whole string is an integer */
static bool StringToLong(const char* str, long* value);
static bool StringToULong(const char* str, unsigned long* value);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 96cfe5e..bf2419a 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -180,6 +180,7 @@
std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
+ std::vector<cmInstallTargetGenerator*> InstallGenerators;
std::set<std::string> SystemIncludeDirectories;
cmTarget::LinkLibraryVectorType OriginalLinkLibraries;
std::vector<std::string> IncludeDirectoriesEntries;
@@ -874,6 +875,17 @@
impl->HaveInstallRule = hir;
}
+void cmTarget::AddInstallGenerator(cmInstallTargetGenerator* g)
+{
+ impl->InstallGenerators.emplace_back(g);
+}
+
+std::vector<cmInstallTargetGenerator*> const& cmTarget::GetInstallGenerators()
+ const
+{
+ return impl->InstallGenerators;
+}
+
bool cmTarget::GetIsGeneratorProvided() const
{
return impl->IsGeneratorProvided;
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index a808bb4..2b75879 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -16,10 +16,12 @@
#include "cmListFileCache.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmTargetLinkLibraryType.h"
class cmCustomCommand;
class cmGlobalGenerator;
+class cmInstallTargetGenerator;
class cmMakefile;
class cmMessenger;
class cmPropertyMap;
@@ -146,6 +148,9 @@
bool GetHaveInstallRule() const;
void SetHaveInstallRule(bool hir);
+ void AddInstallGenerator(cmInstallTargetGenerator* g);
+ std::vector<cmInstallTargetGenerator*> const& GetInstallGenerators() const;
+
/**
* Get/Set whether this target was auto-created by a generator.
*/
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index c4dc838..b64646a 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -4,9 +4,9 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
class cmExecutionStatus;
diff --git a/Source/cmTargetCompileFeaturesCommand.cxx b/Source/cmTargetCompileFeaturesCommand.cxx
index c9e394b..976c8cb 100644
--- a/Source/cmTargetCompileFeaturesCommand.cxx
+++ b/Source/cmTargetCompileFeaturesCommand.cxx
@@ -4,9 +4,9 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
class cmExecutionStatus;
class cmTarget;
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index 8b4763a..7dadb82 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -4,10 +4,10 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
class cmExecutionStatus;
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 5ea0085..4ca78fa 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -31,7 +31,7 @@
operator cmGeneratorTarget const*() const { return this->Target; }
cmGeneratorTarget const* operator->() const { return this->Target; }
cmGeneratorTarget const& operator*() const { return *this->Target; }
- friend bool operator<(cmTargetDepend l, cmTargetDepend r)
+ friend bool operator<(cmTargetDepend const& l, cmTargetDepend const& r)
{
return l.Target < r.Target;
}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index d6918c0..d099349 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -9,6 +9,7 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -39,9 +40,9 @@
for (std::string const& it : content) {
if (cmSystemTools::FileIsFullPath(it) ||
cmGeneratorExpression::Find(it) == 0) {
- dirs += sep + it;
+ dirs += cmStrCat(sep, it);
} else {
- dirs += sep + prefix + it;
+ dirs += cmStrCat(sep, prefix, it);
}
sep = ";";
}
diff --git a/Source/cmTargetLinkDirectoriesCommand.cxx b/Source/cmTargetLinkDirectoriesCommand.cxx
index 269f751..435c392 100644
--- a/Source/cmTargetLinkDirectoriesCommand.cxx
+++ b/Source/cmTargetLinkDirectoriesCommand.cxx
@@ -4,11 +4,11 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
diff --git a/Source/cmTargetLinkOptionsCommand.cxx b/Source/cmTargetLinkOptionsCommand.cxx
index 5366486..2866cf1 100644
--- a/Source/cmTargetLinkOptionsCommand.cxx
+++ b/Source/cmTargetLinkOptionsCommand.cxx
@@ -4,10 +4,10 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
#include "cmTarget.h"
class cmExecutionStatus;
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index eac300f..baab8da 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -11,6 +11,7 @@
#include "cmMessenger.h"
#include "cmPolicies.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
bool cmTargetPropertyComputer::HandleLocationPropertyPolicy(
std::string const& tgtName, cmMessenger* messenger,
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index efbf95f..3b11acd 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -7,9 +7,9 @@
#include <string>
-#include "cmAlgorithms.h"
#include "cmListFileCache.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmMessenger;
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index 11e288f..eb5f37c 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -4,11 +4,11 @@
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index da5d21e..0915986 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -109,7 +109,7 @@
time_t result = mktime(&tm);
-# ifdef CMAKE_BUILD_WITH_CMAKE
+# ifndef CMAKE_BOOTSTRAP
if (tz_was_set) {
cmSystemTools::PutEnv(tz_old);
} else {
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index db67463..97c27cb 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -122,7 +122,7 @@
return this->handle.get();
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
template <>
struct uv_handle_deleter<uv_async_t>
{
@@ -230,7 +230,7 @@
return uv_timer_start(*this, cb, timeout, repeat);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
uv_tty_ptr::operator uv_stream_t*() const
{
return reinterpret_cast<uv_stream_t*>(handle.get());
@@ -259,7 +259,7 @@
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(timer)
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty)
diff --git a/Source/cmUnsetCommand.cxx b/Source/cmUnsetCommand.cxx
index cfaa1fd2..3eb293a 100644
--- a/Source/cmUnsetCommand.cxx
+++ b/Source/cmUnsetCommand.cxx
@@ -2,8 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmUnsetCommand.h"
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
class cmExecutionStatus;
@@ -24,7 +24,7 @@
// what is the variable name
auto const& envVarName = variable.substr(4, variable.size() - 5);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmSystemTools::UnsetEnv(envVarName.c_str());
#endif
return true;
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index 51ecbd1..0dc6ca7 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -114,14 +114,12 @@
std::string cmUuid::ByteToHex(unsigned char byte) const
{
- std::string result;
+ std::string result(" ");
for (int i = 0; i < 2; ++i) {
unsigned char rest = byte % 16;
byte /= 16;
-
char c = (rest < 0xA) ? char('0' + rest) : char('a' + (rest - 0xA));
-
- result = c + result;
+ result.at(1 - i) = c;
}
return result;
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index c78361e..20f5e2f 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVSSetupHelper.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
@@ -195,7 +196,7 @@
if (!fin || !cmSystemTools::GetLineFromStream(fin, vcToolsVersion)) {
return false;
}
- vcToolsVersion = cmSystemTools::TrimWhitespace(vcToolsVersion);
+ vcToolsVersion = cmTrimWhitespace(vcToolsVersion);
std::string const vcToolsDir = vcRoot + "/VC/Tools/MSVC/" + vcToolsVersion;
if (!cmSystemTools::FileIsDirectory(vcToolsDir)) {
return false;
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4a151b3..ed6e4d9 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1235,8 +1235,11 @@
if (this->IPOEnabledConfigurations.count(config) > 0) {
e1.Element("WholeProgramOptimization", "true");
}
- if (this->SpectreMitigationConfigurations.count(config) > 0) {
- e1.Element("SpectreMitigation", "Spectre");
+ {
+ auto s = this->SpectreMitigation.find(config);
+ if (s != this->SpectreMitigation.end()) {
+ e1.Element("SpectreMitigation", s->second);
+ }
}
}
@@ -2766,8 +2769,8 @@
}
}
- if (clOptions.HasFlag("SpectreMitigation")) {
- this->SpectreMitigationConfigurations.insert(configName);
+ if (const char* s = clOptions.GetFlag("SpectreMitigation")) {
+ this->SpectreMitigation[configName] = s;
clOptions.RemoveFlag("SpectreMitigation");
}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 860b809..6607e77 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -215,7 +215,7 @@
unsigned int NsightTegraVersion[4];
bool TargetCompileAsWinRT;
std::set<std::string> IPOEnabledConfigurations;
- std::set<std::string> SpectreMitigationConfigurations;
+ std::map<std::string, std::string> SpectreMitigation;
cmGlobalVisualStudio10Generator* const GlobalGenerator;
cmLocalVisualStudio10Generator* const LocalGenerator;
std::set<std::string> CSharpCustomCommandNames;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index e1b0c70..6c28996 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -193,7 +193,7 @@
std::string arch_name = arch[0];
std::vector<std::string> codes;
if (!code.empty()) {
- codes = cmSystemTools::tokenize(code[0], ",");
+ codes = cmTokenize(code[0], ",");
}
if (codes.empty()) {
codes.push_back(arch_name);
@@ -220,7 +220,7 @@
cmSystemTools::ReplaceString(entry, "]", "");
cmSystemTools::ReplaceString(entry, "\"", "");
- std::vector<std::string> codes = cmSystemTools::tokenize(entry, ",");
+ std::vector<std::string> codes = cmTokenize(entry, ",");
if (codes.size() >= 2) {
auto gencode_arch = cm::cbegin(codes);
for (auto ci = gencode_arch + 1; ci != cm::cend(codes); ++ci) {
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 9353276..9eaee11 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVisualStudioSlnParser.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVisualStudioSlnData.h"
#include "cmsys/FStream.hxx"
@@ -192,8 +193,8 @@
assert(!line.IsComment());
switch (this->Stack.top()) {
case FileStateStart:
- if (!cmSystemTools::StringStartsWith(
- line.GetTag().c_str(), "Microsoft Visual Studio Solution File")) {
+ if (!cmHasLiteralPrefix(line.GetTag(),
+ "Microsoft Visual Studio Solution File")) {
result.SetError(ResultErrorInputStructure, this->GetCurrentLine());
return false;
}
@@ -462,7 +463,7 @@
if (!this->ParseBOM(input, line, state))
return false;
do {
- line = cmSystemTools::TrimWhitespace(line);
+ line = cmTrimWhitespace(line);
if (line.empty())
continue;
ParsedLine parsedLine;
@@ -578,9 +579,9 @@
return true;
}
const std::string& key = line.substr(0, idxEqualSign);
- parsedLine.SetTag(cmSystemTools::TrimWhitespace(key));
+ parsedLine.SetTag(cmTrimWhitespace(key));
const std::string& value = line.substr(idxEqualSign + 1);
- parsedLine.AddValue(cmSystemTools::TrimWhitespace(value));
+ parsedLine.AddValue(cmTrimWhitespace(value));
return true;
}
@@ -589,18 +590,17 @@
{
size_t idxLeftParen = fullTag.find('(');
if (idxLeftParen == fullTag.npos) {
- parsedLine.SetTag(cmSystemTools::TrimWhitespace(fullTag));
+ parsedLine.SetTag(cmTrimWhitespace(fullTag));
return true;
}
- parsedLine.SetTag(
- cmSystemTools::TrimWhitespace(fullTag.substr(0, idxLeftParen)));
+ parsedLine.SetTag(cmTrimWhitespace(fullTag.substr(0, idxLeftParen)));
size_t idxRightParen = fullTag.rfind(')');
if (idxRightParen == fullTag.npos) {
this->LastResult.SetError(ResultErrorInputStructure,
state.GetCurrentLine());
return false;
}
- const std::string& arg = cmSystemTools::TrimWhitespace(
+ const std::string& arg = cmTrimWhitespace(
fullTag.substr(idxLeftParen + 1, idxRightParen - idxLeftParen - 1));
if (arg.front() == '"') {
if (arg.back() != '"') {
@@ -617,7 +617,7 @@
bool cmVisualStudioSlnParser::ParseValue(const std::string& value,
ParsedLine& parsedLine)
{
- const std::string& trimmed = cmSystemTools::TrimWhitespace(value);
+ const std::string& trimmed = cmTrimWhitespace(value);
if (trimmed.empty())
parsedLine.AddValue(trimmed);
else if (trimmed.front() == '"' && trimmed.back() == '"')
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 37d1c74..a396852 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -3,10 +3,14 @@
#include "cmWhileCommand.h"
#include "cm_memory.hxx"
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
@@ -14,9 +18,29 @@
#include <string>
#include <utility>
+class cmWhileFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmWhileFunctionBlocker(cmMakefile* mf);
+ ~cmWhileFunctionBlocker() override;
+
+ cm::string_view StartCommandName() const override { return "while"_s; }
+ cm::string_view EndCommandName() const override { return "endwhile"_s; }
+
+ bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus) override;
+
+ std::vector<cmListFileArgument> Args;
+
+private:
+ cmMakefile* Makefile;
+};
+
cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf)
: Makefile(mf)
- , Depth(0)
{
this->Makefile->PushLoopBlock();
}
@@ -26,108 +50,77 @@
this->Makefile->PopLoopBlock();
}
-bool cmWhileFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
- cmMakefile& mf,
- cmExecutionStatus& inStatus)
+bool cmWhileFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile&) const
{
- // at end of for each execute recorded commands
- if (lff.Name.Lower == "while") {
- // record the number of while commands past this one
- this->Depth++;
- } else if (lff.Name.Lower == "endwhile") {
- // if this is the endwhile for this while loop then execute
- if (!this->Depth) {
- // Remove the function blocker for this scope or bail.
- std::unique_ptr<cmFunctionBlocker> fb(
- mf.RemoveFunctionBlocker(this, lff));
- if (!fb) {
- return false;
- }
-
- std::string errorString;
-
- std::vector<cmExpandedCommandArgument> expandedArguments;
- mf.ExpandArguments(this->Args, expandedArguments);
- MessageType messageType;
-
- cmListFileContext execContext = this->GetStartingContext();
-
- cmCommandContext commandContext;
- commandContext.Line = execContext.Line;
- commandContext.Name = execContext.Name;
-
- cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
- mf.GetBacktrace(commandContext));
-
- bool isTrue =
- conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
-
- while (isTrue) {
- if (!errorString.empty()) {
- std::string err = "had incorrect arguments: ";
- for (cmListFileArgument const& arg : this->Args) {
- err += (arg.Delim ? "\"" : "");
- err += arg.Value;
- err += (arg.Delim ? "\"" : "");
- err += " ";
- }
- err += "(";
- err += errorString;
- err += ").";
- mf.IssueMessage(messageType, err);
- if (messageType == MessageType::FATAL_ERROR) {
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
- }
-
- // Invoke all the functions that were collected in the block.
- for (cmListFileFunction const& fn : this->Functions) {
- cmExecutionStatus status(mf);
- mf.ExecuteCommand(fn, status);
- if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
- return true;
- }
- if (status.GetBreakInvoked()) {
- return true;
- }
- if (status.GetContinueInvoked()) {
- break;
- }
- if (cmSystemTools::GetFatalErrorOccured()) {
- return true;
- }
- }
- expandedArguments.clear();
- mf.ExpandArguments(this->Args, expandedArguments);
- isTrue = conditionEvaluator.IsTrue(expandedArguments, errorString,
- messageType);
- }
- return true;
- }
- // decrement for each nested while that ends
- this->Depth--;
- }
-
- // record the command
- this->Functions.push_back(lff);
-
- // always return true
- return true;
+ return lff.Arguments.empty() || lff.Arguments == this->Args;
}
-bool cmWhileFunctionBlocker::ShouldRemove(const cmListFileFunction& lff,
- cmMakefile&)
+bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus)
{
- if (lff.Name.Lower == "endwhile") {
- // if the endwhile has arguments, then make sure
- // they match the arguments of the matching while
- if (lff.Arguments.empty() || lff.Arguments == this->Args) {
- return true;
+ cmMakefile& mf = inStatus.GetMakefile();
+ std::string errorString;
+
+ std::vector<cmExpandedCommandArgument> expandedArguments;
+ mf.ExpandArguments(this->Args, expandedArguments);
+ MessageType messageType;
+
+ cmListFileContext execContext = this->GetStartingContext();
+
+ cmCommandContext commandContext;
+ commandContext.Line = execContext.Line;
+ commandContext.Name = execContext.Name;
+
+ cmConditionEvaluator conditionEvaluator(mf, this->GetStartingContext(),
+ mf.GetBacktrace(commandContext));
+
+ bool isTrue =
+ conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
+
+ while (isTrue) {
+ if (!errorString.empty()) {
+ std::string err = "had incorrect arguments: ";
+ for (cmListFileArgument const& arg : this->Args) {
+ err += (arg.Delim ? "\"" : "");
+ err += arg.Value;
+ err += (arg.Delim ? "\"" : "");
+ err += " ";
+ }
+ err += "(";
+ err += errorString;
+ err += ").";
+ mf.IssueMessage(messageType, err);
+ if (messageType == MessageType::FATAL_ERROR) {
+ cmSystemTools::SetFatalErrorOccured();
+ return true;
+ }
}
+
+ // Invoke all the functions that were collected in the block.
+ for (cmListFileFunction const& fn : functions) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(fn, status);
+ if (status.GetReturnInvoked()) {
+ inStatus.SetReturnInvoked();
+ return true;
+ }
+ if (status.GetBreakInvoked()) {
+ return true;
+ }
+ if (status.GetContinueInvoked()) {
+ break;
+ }
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ return true;
+ }
+ }
+ expandedArguments.clear();
+ mf.ExpandArguments(this->Args, expandedArguments);
+ isTrue =
+ conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
}
- return false;
+ return true;
}
bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
index 2257799..beca652 100644
--- a/Source/cmWhileCommand.h
+++ b/Source/cmWhileCommand.h
@@ -7,28 +7,8 @@
#include <vector>
-#include "cmFunctionBlocker.h"
-#include "cmListFileCache.h"
-
class cmExecutionStatus;
-class cmMakefile;
-
-class cmWhileFunctionBlocker : public cmFunctionBlocker
-{
-public:
- cmWhileFunctionBlocker(cmMakefile* mf);
- ~cmWhileFunctionBlocker() override;
- bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
- cmExecutionStatus&) override;
- bool ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf) override;
-
- std::vector<cmListFileArgument> Args;
- std::vector<cmListFileFunction> Functions;
-
-private:
- cmMakefile* Makefile;
- int Depth;
-};
+struct cmListFileArgument;
/// \brief Starts a while loop
bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx
index 2df3961..2060584 100644
--- a/Source/cm_codecvt.hxx
+++ b/Source/cm_codecvt.hxx
@@ -18,7 +18,7 @@
ANSI
};
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
codecvt(Encoding e);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 7250e51..af73c8d 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -21,15 +21,17 @@
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"
#include "cmUtils.hxx"
#include "cmVersionConfig.h"
#include "cmWorkingDirectory.h"
+#include "cm_string_view.hxx"
#include "cm_sys_stat.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cm_jsoncpp_writer.h"
# include "cmFileAPI.h"
@@ -38,11 +40,11 @@
# include <unordered_map>
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# define CMAKE_USE_ECLIPSE
#endif
-#if defined(__MINGW32__) && !defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(__MINGW32__) && defined(CMAKE_BOOTSTRAP)
# define CMAKE_BOOT_MINGW
#endif
@@ -70,7 +72,7 @@
# include "cmGlobalWatcomWMakeGenerator.h"
#endif
#include "cmGlobalUnixMakefileGenerator3.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmGlobalNinjaGenerator.h"
#endif
#include "cmExtraCodeLiteGenerator.h"
@@ -90,7 +92,7 @@
#endif
#if defined(__APPLE__)
-# if defined(CMAKE_BUILD_WITH_CMAKE)
+# if !defined(CMAKE_BOOTSTRAP)
# include "cmGlobalXCodeGenerator.h"
# define CMAKE_USE_XCODE 1
@@ -113,7 +115,7 @@
namespace {
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
typedef std::unordered_map<std::string, Json::Value> JsonValueMapType;
#endif
@@ -131,22 +133,15 @@
}
cmake::cmake(Role role, cmState::Mode mode)
+ : FileTimeCache(cm::make_unique<cmFileTimeCache>())
+#ifndef CMAKE_BOOTSTRAP
+ , VariableWatch(cm::make_unique<cmVariableWatch>())
+#endif
+ , State(cm::make_unique<cmState>())
+ , Messenger(cm::make_unique<cmMessenger>())
{
- this->Trace = false;
- this->TraceExpand = false;
- this->WarnUninitialized = false;
- this->WarnUnused = false;
- this->WarnUnusedCli = true;
- this->CheckSystemVars = false;
- this->DebugOutput = false;
- this->DebugTryCompile = false;
- this->ClearBuildSystem = false;
- this->FileTimeCache = cm::make_unique<cmFileTimeCache>();
-
- this->State = cm::make_unique<cmState>();
this->State->SetMode(mode);
this->CurrentSnapshot = this->State->CreateBaseSnapshot();
- this->Messenger = cm::make_unique<cmMessenger>();
#ifdef __APPLE__
struct rlimit rlp;
@@ -158,16 +153,6 @@
}
#endif
- this->GlobalGenerator = nullptr;
- this->GeneratorInstanceSet = false;
- this->GeneratorPlatformSet = false;
- this->GeneratorToolsetSet = false;
- this->CurrentWorkingMode = NORMAL_MODE;
-
-#ifdef CMAKE_BUILD_WITH_CMAKE
- this->VariableWatch = cm::make_unique<cmVariableWatch>();
-#endif
-
this->AddDefaultGenerators();
this->AddDefaultExtraGenerators();
if (role == RoleScript || role == RoleProject) {
@@ -187,32 +172,25 @@
// Set up a list of source and header extensions.
// These are used to find files when the extension is not given.
{
- auto fillExts = [](FileExtensions& exts,
- std::initializer_list<const char*> extList) {
+ auto setupExts = [](FileExtensions& exts,
+ std::initializer_list<cm::string_view> extList) {
// Fill ordered vector
exts.ordered.reserve(extList.size());
- for (const char* ext : extList) {
+ for (cm::string_view ext : extList) {
exts.ordered.emplace_back(ext);
};
// Fill unordered set
exts.unordered.insert(exts.ordered.begin(), exts.ordered.end());
};
- // Source extensions
// The "c" extension MUST precede the "C" extension.
- fillExts(this->SourceFileExtensions,
- { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
-
- // Header extensions
- fillExts(this->HeaderFileExtensions,
- { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
-
- // Cuda extensions
- fillExts(this->CudaFileExtensions, { "cu" });
-
- // Fortran extensions
- fillExts(this->FortranFileExtensions,
- { "f", "F", "for", "f77", "f90", "f95", "f03" });
+ setupExts(this->SourceFileExtensions,
+ { "c", "C", "c++", "cc", "cpp", "cxx", "cu", "m", "M", "mm" });
+ setupExts(this->HeaderFileExtensions,
+ { "h", "hh", "h++", "hm", "hpp", "hxx", "in", "txx" });
+ setupExts(this->CudaFileExtensions, { "cu" });
+ setupExts(this->FortranFileExtensions,
+ { "f", "F", "for", "f77", "f90", "f95", "f03" });
}
}
@@ -225,7 +203,7 @@
cmDeleteAll(this->Generators);
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmake::ReportVersionJson() const
{
Json::Value version = Json::objectValue;
@@ -284,7 +262,7 @@
std::string cmake::ReportCapabilities() const
{
std::string result;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::FastWriter writer;
result = writer.write(this->ReportCapabilitiesJson());
#else
@@ -619,7 +597,7 @@
this->EnvironmentGenerator = envGenVar;
}
- auto readGeneratorVar = [&](std::string name, std::string& key) {
+ auto readGeneratorVar = [&](std::string const& name, std::string& key) {
std::string varValue;
if (cmSystemTools::GetEnv(name, varValue)) {
if (hasEnvironmentGenerator) {
@@ -830,8 +808,8 @@
kdevError = "\nThe KDevelop3 generator is not supported anymore.";
}
- cmSystemTools::Error("Could not create named generator " + value +
- kdevError);
+ cmSystemTools::Error(
+ cmStrCat("Could not create named generator ", value, kdevError));
this->PrintGeneratorList();
return;
}
@@ -990,7 +968,7 @@
this->AddCacheEntry("CMAKE_COMMAND",
cmSystemTools::GetCMakeCommand().c_str(),
"Path to CMake executable.", cmStateEnums::INTERNAL);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->AddCacheEntry(
"CMAKE_CTEST_COMMAND", cmSystemTools::GetCTestCommand().c_str(),
"Path to ctest program executable.", cmStateEnums::INTERNAL);
@@ -1016,7 +994,7 @@
void cmake::AddDefaultExtraGenerators()
{
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->ExtraGenerators.push_back(cmExtraCodeBlocksGenerator::GetFactory());
this->ExtraGenerators.push_back(cmExtraCodeLiteGenerator::GetFactory());
this->ExtraGenerators.push_back(cmExtraSublimeTextGenerator::GetFactory());
@@ -1543,7 +1521,7 @@
this->TruncateOutputLog("CMakeError.log");
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->FileAPI = cm::make_unique<cmFileAPI>(this);
this->FileAPI->ReadQueries();
#endif
@@ -1811,7 +1789,7 @@
// for the Visual Studio and Xcode generators.)
this->SaveCache(this->GetHomeOutputDirectory());
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
this->FileAPI->WriteReplies();
#endif
@@ -1917,7 +1895,7 @@
this->Generators.push_back(cmGlobalMinGWMakefileGenerator::NewFactory());
#endif
this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory());
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# if defined(__linux__) || defined(_WIN32)
this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory());
# endif
@@ -2030,8 +2008,7 @@
for (cmGlobalGeneratorFactory* g : this->Generators) {
cmDocumentationEntry e;
g->GetDocumentation(e);
- if (!foundDefaultOne &&
- cmSystemTools::StringStartsWith(e.Name, defaultName.c_str())) {
+ if (!foundDefaultOne && cmHasPrefix(e.Name, defaultName)) {
e.CustomNamePrefix = '*';
foundDefaultOne = true;
}
@@ -2077,7 +2054,7 @@
void cmake::PrintGeneratorList()
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmDocumentation doc;
auto generators = this->GetGeneratorsDocumentation();
doc.AppendSection("Generators", generators);
@@ -2293,14 +2270,6 @@
}
}
-inline std::string removeQuotes(const std::string& s)
-{
- if (s.front() == '\"' && s.back() == '\"') {
- return s.substr(1, s.size() - 2);
- }
- return s;
-}
-
void cmake::MarkCliAsUsed(const std::string& variable)
{
this->UsedCliVariables[variable] = true;
@@ -2308,7 +2277,7 @@
void cmake::GenerateGraphViz(const std::string& fileName) const
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmGraphVizWriter gvWriter(this->GetGlobalGenerator());
std::string settingsFile = this->GetHomeOutputDirectory();
@@ -2767,7 +2736,7 @@
void cmake::WatchUnusedCli(const std::string& var)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
if (this->UsedCliVariables.find(var) == this->UsedCliVariables.end()) {
this->UsedCliVariables[var] = false;
@@ -2777,7 +2746,7 @@
void cmake::UnwatchUnusedCli(const std::string& var)
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
this->VariableWatch->RemoveWatch(var, cmWarnUnusedCliWarning);
this->UsedCliVariables.erase(var);
#endif
@@ -2785,7 +2754,7 @@
void cmake::RunCheckForUnusedVariables()
{
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
bool haveUnused = false;
std::ostringstream msg;
msg << "Manually-specified variables were not used by the project:";
diff --git a/Source/cmake.h b/Source/cmake.h
index 6aa00e1..4c73519 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -20,7 +20,7 @@
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cm_jsoncpp_value.h"
#endif
@@ -145,7 +145,7 @@
cmake(cmake const&) = delete;
cmake& operator=(cmake const&) = delete;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
Json::Value ReportVersionJson() const;
Json::Value ReportCapabilitiesJson() const;
#endif
@@ -334,7 +334,7 @@
//! this is called by generators to update the progress
void UpdateProgress(const std::string& msg, float prog);
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
//! Get the variable watch object
cmVariableWatch* GetVariableWatch() { return this->VariableWatch.get(); }
#endif
@@ -509,14 +509,14 @@
void AddDefaultGenerators();
void AddDefaultExtraGenerators();
- cmGlobalGenerator* GlobalGenerator;
+ cmGlobalGenerator* GlobalGenerator = nullptr;
std::map<std::string, DiagLevel> DiagLevels;
std::string GeneratorInstance;
std::string GeneratorPlatform;
std::string GeneratorToolset;
- bool GeneratorInstanceSet;
- bool GeneratorPlatformSet;
- bool GeneratorToolsetSet;
+ bool GeneratorInstanceSet = false;
+ bool GeneratorPlatformSet = false;
+ bool GeneratorToolsetSet = false;
//! read in a cmake list file to initialize the cache
void ReadListFile(const std::vector<std::string>& args,
@@ -543,14 +543,14 @@
private:
ProgressCallbackType ProgressCallback;
- WorkingMode CurrentWorkingMode;
- bool DebugOutput;
- bool Trace;
- bool TraceExpand;
- bool WarnUninitialized;
- bool WarnUnused;
- bool WarnUnusedCli;
- bool CheckSystemVars;
+ WorkingMode CurrentWorkingMode = NORMAL_MODE;
+ bool DebugOutput = false;
+ bool Trace = false;
+ bool TraceExpand = false;
+ bool WarnUninitialized = false;
+ bool WarnUnused = false;
+ bool WarnUnusedCli = true;
+ bool CheckSystemVars = false;
std::map<std::string, bool> UsedCliVariables;
std::string CMakeEditCommand;
std::string CXXEnvironment;
@@ -564,13 +564,13 @@
FileExtensions HeaderFileExtensions;
FileExtensions CudaFileExtensions;
FileExtensions FortranFileExtensions;
- bool ClearBuildSystem;
- bool DebugTryCompile;
+ bool ClearBuildSystem = false;
+ bool DebugTryCompile = false;
std::unique_ptr<cmFileTimeCache> FileTimeCache;
std::string GraphVizFile;
InstalledFilesMap InstalledFiles;
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
std::unique_ptr<cmVariableWatch> VariableWatch;
std::unique_ptr<cmFileAPI> FileAPI;
#endif
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index cfb3cee..522f9a4 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -7,11 +7,12 @@
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
#include "cmcmd.h"
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
# include "cmDocumentation.h"
# include "cmDynamicLoader.h"
#endif
@@ -19,7 +20,7 @@
#include "cm_uv.h"
#include "cmsys/Encoding.hxx"
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
# include "cmsys/ConsoleBuf.hxx"
#endif
@@ -32,7 +33,7 @@
#include <vector>
namespace {
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
const char* cmDocumentationName[][2] = {
{ nullptr, " cmake - Cross-Platform Makefile Generator." },
{ nullptr, nullptr }
@@ -155,7 +156,7 @@
return 1;
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmDocumentation doc;
doc.addCMakeStandardDocSections();
if (doc.CheckOptions(ac, av)) {
@@ -338,7 +339,7 @@
int do_build(int ac, char const* const* av)
{
-#ifndef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMAKE_BOOTSTRAP
std::cerr << "This cmake does not support --build\n";
return -1;
#else
@@ -502,7 +503,7 @@
int do_install(int ac, char const* const* av)
{
-#ifndef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMAKE_BOOTSTRAP
std::cerr << "This cmake does not support --install\n";
return -1;
#else
@@ -623,7 +624,7 @@
int do_open(int ac, char const* const* av)
{
-#ifndef CMAKE_BUILD_WITH_CMAKE
+#ifdef CMAKE_BOOTSTRAP
std::cerr << "This cmake does not support --open\n";
return -1;
#else
@@ -668,7 +669,7 @@
int main(int ac, char const* const* av)
{
cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
// Replace streambuf so we can output Unicode to console
cmsys::ConsoleBuf::Manager consoleOut(std::cout);
consoleOut.SetUTF8Pipes();
@@ -698,7 +699,7 @@
}
}
int ret = do_cmake(ac, av);
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
cmDynamicLoader::FlushCache();
#endif
uv_loop_close(uv_default_loop());
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 503dce1..69d5fcd 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -13,23 +13,24 @@
#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUtils.hxx"
#include "cmVersion.h"
#include "cmake.h"
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
# include "cmServer.h"
# include "cmServerConnection.h"
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32)
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
# include "bindexplib.h"
# include "cmsys/ConsoleBuf.hxx"
#endif
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) && !defined(__CYGWIN__)
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
# include "cmVisualStudioWCEPlatformParser.h"
#endif
@@ -60,7 +61,7 @@
{
std::ostringstream errorStream;
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
/* clang-format off */
errorStream
<< "cmake version " << cmVersion::GetCMakeVersion() << "\n";
@@ -560,7 +561,7 @@
return 0;
}
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
else if (args[1] == "__create_def") {
if (args.size() < 4) {
std::cerr
@@ -653,7 +654,7 @@
return 1;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
if (args[1] == "environment") {
for (auto const& env : cmSystemTools::GetEnvironmentVariables()) {
std::cout << env << std::endl;
@@ -993,7 +994,7 @@
return cmcmd::ExecuteLinkScript(args);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
// Internal CMake ninja dependency scanning support.
if (args[1] == "cmake_ninja_depends") {
return cmcmd_cmake_ninja_depends(args.begin() + 2, args.end());
@@ -1028,7 +1029,7 @@
return cmcmd::ExecuteEchoColor(args);
}
-#ifdef CMAKE_BUILD_WITH_CMAKE
+#ifndef CMAKE_BOOTSTRAP
if ((args[1] == "cmake_autogen") && (args.size() >= 4)) {
cmQtAutoMocUic autoGen;
std::string const& infoDir = args[2];
@@ -1209,7 +1210,7 @@
return 1;
}
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
cmConnection* conn;
if (isDebug) {
conn = new cmServerStdIoConnection;
@@ -1230,7 +1231,7 @@
return 1;
}
-#if defined(CMAKE_BUILD_WITH_CMAKE)
+#if !defined(CMAKE_BOOTSTRAP)
// Internal CMake Fortran module support.
if (args[1] == "cmake_copy_f90_mod" && args.size() >= 4) {
return cmDependsFortran::CopyModule(args) ? 0 : 1;
@@ -1546,7 +1547,7 @@
int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
{
-#if defined(CMAKE_BUILD_WITH_CMAKE) && defined(_WIN32) && !defined(__CYGWIN__)
+#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
cmVisualStudioWCEPlatformParser parser(name.c_str());
parser.ParseVersion(version);
if (parser.Found()) {
@@ -1604,7 +1605,7 @@
// still works.
int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type)
{
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
// Replace streambuf so we output in the system codepage. CMake is set up
// to output in Unicode (see SetUTF8Pipes) but the Visual Studio linker
// outputs using the system codepage so we need to change behavior when
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 3b3630f..77a84fd 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -8,7 +8,7 @@
#include "cmSystemTools.h"
#include "cmsys/Encoding.hxx"
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
# include "cmsys/ConsoleBuf.hxx"
#endif
#include <iostream>
@@ -144,7 +144,7 @@
int main(int argc, char const* const* argv)
{
cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
// Replace streambuf so we can output Unicode to console
cmsys::ConsoleBuf::Manager consoleOut(std::cout);
consoleOut.SetUTF8Pipes();
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index a25f25a..cd4dbc8 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -10,6 +10,7 @@
testRST.cxx
testRange.cxx
testString.cxx
+ testStringAlgorithms.cxx
testSystemTools.cxx
testUTF8.cxx
testXMLParser.cxx
diff --git a/Tests/CMakeLib/testStringAlgorithms.cxx b/Tests/CMakeLib/testStringAlgorithms.cxx
new file mode 100644
index 0000000..f833502
--- /dev/null
+++ b/Tests/CMakeLib/testStringAlgorithms.cxx
@@ -0,0 +1,194 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include <cmConfigure.h> // IWYU pragma: keep
+
+#include "cm_string_view.hxx"
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "cmStringAlgorithms.h"
+
+int testStringAlgorithms(int /*unused*/, char* /*unused*/ [])
+{
+ int failed = 0;
+
+ auto assert_ok = [&failed](bool test, cm::string_view title) {
+ if (test) {
+ std::cout << "Passed: " << title << "\n";
+ } else {
+ std::cout << "Failed: " << title << "\n";
+ ++failed;
+ }
+ };
+
+ auto assert_string = [&failed](cm::string_view generated,
+ cm::string_view expected,
+ cm::string_view title) {
+ if (generated == expected) {
+ std::cout << "Passed: " << title << "\n";
+ } else {
+ std::cout << "Failed: " << title << "\n";
+ std::cout << "Expected: " << expected << "\n";
+ std::cout << "Got: " << generated << "\n";
+ ++failed;
+ }
+ };
+
+ // ----------------------------------------------------------------------
+ // Test cmTrimWhitespace
+ {
+ std::string base = "base";
+ std::string spaces = " \f\f\n\n\r\r\t\t\v\v";
+ assert_string(cmTrimWhitespace(spaces + base), base,
+ "cmTrimWhitespace front");
+ assert_string(cmTrimWhitespace(base + spaces), base,
+ "cmTrimWhitespace back");
+ assert_string(cmTrimWhitespace(spaces + base + spaces), base,
+ "cmTrimWhitespace front and back");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test cmRemoveQuotes
+ {
+ auto test = [&assert_string](cm::string_view source,
+ cm::string_view expected,
+ cm::string_view title) {
+ assert_string(cmRemoveQuotes(source), expected, title);
+ };
+
+ test("", "", "cmRemoveQuotes empty");
+ test("\"", "\"", "cmRemoveQuotes single quote");
+ test("\"\"", "", "cmRemoveQuotes double quote");
+ test("\"a", "\"a", "cmRemoveQuotes quote char");
+ test("\"ab", "\"ab", "cmRemoveQuotes quote char char");
+ test("a\"", "a\"", "cmRemoveQuotes char quote");
+ test("ab\"", "ab\"", "cmRemoveQuotes char char quote");
+ test("a", "a", "cmRemoveQuotes single char");
+ test("ab", "ab", "cmRemoveQuotes two chars");
+ test("abc", "abc", "cmRemoveQuotes three chars");
+ test("\"abc\"", "abc", "cmRemoveQuotes quoted chars");
+ test("\"\"abc\"\"", "\"abc\"", "cmRemoveQuotes quoted quoted chars");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test cmEscapeQuotes
+ {
+ assert_string(cmEscapeQuotes("plain"), "plain", "cmEscapeQuotes plain");
+ std::string base = "\"base\"\"";
+ std::string result = "\\\"base\\\"\\\"";
+ assert_string(cmEscapeQuotes(base), result, "cmEscapeQuotes escaped");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test cmJoin
+ {
+ typedef std::string ST;
+ typedef std::vector<std::string> VT;
+ assert_string(cmJoin(ST("abc"), ";"), "a;b;c", "cmJoin std::string");
+ assert_string(cmJoin(VT{}, ";"), "", "cmJoin std::vector empty");
+ assert_string(cmJoin(VT{ "a" }, ";"), "a", "cmJoin std::vector single");
+ assert_string(cmJoin(VT{ "a", "b", "c" }, ";"), "a;b;c",
+ "cmJoin std::vector multiple");
+ assert_string(cmJoin(VT{ "a", "b", "c" }, "<=>"), "a<=>b<=>c",
+ "cmJoin std::vector long sep");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test cmTokenize
+ {
+ typedef std::vector<std::string> VT;
+ assert_ok(cmTokenize("", ";") == VT{ "" }, "cmTokenize empty");
+ assert_ok(cmTokenize(";", ";") == VT{ "" }, "cmTokenize sep");
+ assert_ok(cmTokenize("abc", ";") == VT{ "abc" }, "cmTokenize item");
+ assert_ok(cmTokenize("abc;", ";") == VT{ "abc" }, "cmTokenize item sep");
+ assert_ok(cmTokenize(";abc", ";") == VT{ "abc" }, "cmTokenize sep item");
+ assert_ok(cmTokenize("abc;;efg", ";") == VT{ "abc", "efg" },
+ "cmTokenize item sep sep item");
+ assert_ok(cmTokenize("a1;a2;a3;a4", ";") == VT{ "a1", "a2", "a3", "a4" },
+ "cmTokenize multiple items");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test cmStrCat
+ {
+ int ni = -1100;
+ unsigned int nui = 1100u;
+ long int nli = -12000l;
+ unsigned long int nuli = 12000ul;
+ long long int nlli = -130000ll;
+ unsigned long long int nulli = 130000ull;
+ std::string val =
+ cmStrCat("<test>", ni, ',', nui, ',', nli, ",", nuli, ", ", nlli,
+ std::string(", "), nulli, cm::string_view("</test>"));
+ std::string expect =
+ "<test>-1100,1100,-12000,12000, -130000, 130000</test>";
+ assert_string(val, expect, "cmStrCat strings and integers");
+ }
+ {
+ float const val = 1.5f;
+ float const div = 0.00001f;
+ float f = 0.0f;
+ std::istringstream(cmStrCat("", val)) >> f;
+ f -= val;
+ assert_ok((f < div) && (f > -div), "cmStrCat float");
+ }
+ {
+ double const val = 1.5;
+ double const div = 0.00001;
+ double d = 0.0;
+ std::istringstream(cmStrCat("", val)) >> d;
+ d -= val;
+ assert_ok((d < div) && (d > -div), "cmStrCat double");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test cmWrap
+ {
+ typedef std::vector<std::string> VT;
+ assert_string(cmWrap("<", VT{}, ">", "; "), //
+ "", //
+ "cmWrap empty, string prefix and suffix");
+ assert_string(cmWrap("<", VT{ "abc" }, ">", "; "), //
+ "<abc>", //
+ "cmWrap single, string prefix and suffix");
+ assert_string(cmWrap("<", VT{ "a1", "a2", "a3" }, ">", "; "), //
+ "<a1>; <a2>; <a3>", //
+ "cmWrap multiple, string prefix and suffix");
+
+ assert_string(cmWrap('<', VT{}, '>', "; "), //
+ "", //
+ "cmWrap empty, char prefix and suffix");
+ assert_string(cmWrap('<', VT{ "abc" }, '>', "; "), //
+ "<abc>", //
+ "cmWrap single, char prefix and suffix");
+ assert_string(cmWrap('<', VT{ "a1", "a2", "a3" }, '>', "; "), //
+ "<a1>; <a2>; <a3>", //
+ "cmWrap multiple, char prefix and suffix");
+ }
+
+ // ----------------------------------------------------------------------
+ // Test cmHas(Literal)Prefix and cmHas(Literal)Suffix
+ {
+ std::string str("abc");
+ assert_ok(cmHasPrefix(str, 'a'), "cmHasPrefix char");
+ assert_ok(!cmHasPrefix(str, 'c'), "cmHasPrefix char not");
+ assert_ok(cmHasPrefix(str, "ab"), "cmHasPrefix string");
+ assert_ok(!cmHasPrefix(str, "bc"), "cmHasPrefix string not");
+ assert_ok(cmHasPrefix(str, str), "cmHasPrefix complete string");
+ assert_ok(cmHasLiteralPrefix(str, "ab"), "cmHasLiteralPrefix string");
+ assert_ok(!cmHasLiteralPrefix(str, "bc"), "cmHasLiteralPrefix string not");
+
+ assert_ok(cmHasSuffix(str, 'c'), "cmHasSuffix char");
+ assert_ok(!cmHasSuffix(str, 'a'), "cmHasSuffix char not");
+ assert_ok(cmHasSuffix(str, "bc"), "cmHasSuffix string");
+ assert_ok(!cmHasSuffix(str, "ab"), "cmHasSuffix string not");
+ assert_ok(cmHasSuffix(str, str), "cmHasSuffix complete string");
+ assert_ok(cmHasLiteralSuffix(str, "bc"), "cmHasLiteralSuffix string");
+ assert_ok(!cmHasLiteralSuffix(str, "ab"), "cmHasLiteralPrefix string not");
+ }
+
+ return failed;
+}
diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt
index 1aeab8b..19f3f79 100644
--- a/Tests/CMakeOnly/CMakeLists.txt
+++ b/Tests/CMakeOnly/CMakeLists.txt
@@ -84,5 +84,5 @@
endfunction()
add_major_test(PythonLibs VERSIONS 2 3 VERSION_VAR PYTHONLIBS_VERSION_STRING)
-add_major_test(PythonInterp NOLANG VERSIONS 2 3 VERSION_VAR PYTHON_VERSION_STRING)
+add_major_test(PythonInterp NOLANG VERSIONS 3 VERSION_VAR PYTHON_VERSION_STRING)
add_major_test(Qt VERSIONS 3 4 VERSION_VAR QT_VERSION_STRING)
diff --git a/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt b/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt
index f058c19..2028a13 100644
--- a/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt
+++ b/Tests/CMakeOnly/CheckCXXSymbolExists/CMakeLists.txt
@@ -49,6 +49,15 @@
message(STATUS "errno found in <cerrno>")
endif ()
+check_cxx_symbol_exists("std::fopen" "cstdio" CSE_RESULT_FOPEN)
+if (NOT CSE_RESULT_FOPEN)
+ if(NOT ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.10))
+ message(SEND_ERROR "CheckCXXSymbolExists did not find std::fopen in <cstdio>")
+ endif()
+else()
+ message(STATUS "std::fopen found in <cstdio>")
+endif()
+
if (CMAKE_COMPILER_IS_GNUCXX)
string(APPEND CMAKE_CXX_FLAGS " -O3")
unset(CSE_RESULT_O3 CACHE)
@@ -60,3 +69,8 @@
message(SEND_ERROR "CheckCXXSymbolExists reported a nonexistent symbol as existing with optimization -O3")
endif ()
endif ()
+
+check_cxx_symbol_exists("std::non_existent_function_for_symbol_test<int*>" "algorithm" CSE_RESULT_NON_SYMBOL)
+if (CSE_RESULT_NON_SYMBOL)
+ message(SEND_ERROR "CheckCXXSymbolExists reported a nonexistent symbol.")
+endif()
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index 519608c..7217f43 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -653,3 +653,9 @@
if(ACME_FOUND)
message(SEND_ERROR "Should not find ACME package")
endif()
+
+############################################################################
+##Test find_package CMAKE_FIND_PACKAGE_PREFER_CONFIG with unknown package
+
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
+find_package(DoesNotExist)
diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake
index aaa7c89..d96ab86 100644
--- a/Tests/RunCMake/Android/common.cmake
+++ b/Tests/RunCMake/Android/common.cmake
@@ -6,8 +6,6 @@
endif()
foreach(f
- "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}"
- "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}g++${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
"${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}ar${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
"${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}ld${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
)
@@ -51,23 +49,26 @@
endif()
endif()
-execute_process(
- COMMAND "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}" -dumpmachine
- OUTPUT_VARIABLE _out OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE _err
- RESULT_VARIABLE _res
- )
-if(NOT _res EQUAL 0)
- message(SEND_ERROR "Failed to run 'gcc -dumpmachine':\n ${_res}")
-endif()
-string(REPLACE "--" "-" _out_check "${_out}")
-if(NOT _out_check STREQUAL "${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
- AND NOT (_out STREQUAL "arm--linux-android" AND CMAKE_C_ANDROID_TOOLCHAIN_MACHINE STREQUAL "arm-linux-androideabi"))
- message(SEND_ERROR "'gcc -dumpmachine' produced:\n"
- " ${_out}\n"
- "which does not match CMAKE_C_ANDROID_TOOLCHAIN_MACHINE:\n"
- " ${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
+set(gcc ${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX})
+if(EXISTS "${gcc}")
+ execute_process(
+ COMMAND "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}" -dumpmachine
+ OUTPUT_VARIABLE _out OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _err
+ RESULT_VARIABLE _res
)
+ if(NOT _res EQUAL 0)
+ message(SEND_ERROR "Failed to run 'gcc -dumpmachine':\n ${_res}")
+ endif()
+ string(REPLACE "--" "-" _out_check "${_out}")
+ if(NOT _out_check STREQUAL "${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
+ AND NOT (_out STREQUAL "arm--linux-android" AND CMAKE_C_ANDROID_TOOLCHAIN_MACHINE STREQUAL "arm-linux-androideabi"))
+ message(SEND_ERROR "'gcc -dumpmachine' produced:\n"
+ " ${_out}\n"
+ "which does not match CMAKE_C_ANDROID_TOOLCHAIN_MACHINE:\n"
+ " ${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
+ )
+ endif()
endif()
if(CMAKE_ANDROID_STL_TYPE STREQUAL "none")
diff --git a/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt b/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt
index 8d0bdc2..a228ccc 100644
--- a/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt
@@ -1,2 +1,2 @@
-- Android: Targeting API '[0-9]+' with architecture 'arm64', ABI 'arm64-v8a', and processor 'aarch64'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt
index 3741da3..72ec00e 100644
--- a/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt
@@ -1,3 +1,3 @@
-- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi', and processor 'armv5te'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
.*-- CMAKE_ANDROID_ARM_MODE=1
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt
index ac2bfd5..8bd87fa 100644
--- a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt
@@ -1,3 +1,3 @@
-- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
.*-- CMAKE_ANDROID_ARM_NEON=1
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt
index 0edb4f7..554548e 100644
--- a/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt
@@ -1,3 +1,3 @@
-- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
.*-- CMAKE_ANDROID_ARM_NEON=0
diff --git a/Tests/RunCMake/Android/ndk-badver-stderr.txt b/Tests/RunCMake/Android/ndk-badver-stderr.txt
index df2c5e6..ce6bc4e 100644
--- a/Tests/RunCMake/Android/ndk-badver-stderr.txt
+++ b/Tests/RunCMake/Android/ndk-badver-stderr.txt
@@ -1,11 +1,12 @@
^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):
- Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value 'badver' is not one
+ Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value 'badver' is not(
+ supported by this NDK. It must be 'clang' or not set at all\.| one
of the allowed forms:
<major>.<minor> = GCC of specified version
clang<major>.<minor> = Clang of specified version
clang = Clang of most recent available version
-
+)
Call Stack \(most recent call first\):
.*
ndk-badver.cmake:1 \(enable_language\)
diff --git a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
index adacaf1..aec91d9 100644
--- a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
+++ b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
@@ -1,4 +1,6 @@
-^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):
+^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):(
+ Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value '1.0' is not
+ supported by this NDK. It must be 'clang' or not set at all.|
Android: No toolchain for ABI 'armeabi(-v7a)?' found in the NDK:
.*
@@ -6,7 +8,7 @@
of the version specified by CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION:
1\.0
-
+)
Call Stack \(most recent call first\):
.*
ndk-badvernum.cmake:1 \(enable_language\)
diff --git a/Tests/RunCMake/Android/ndk-mips-stdout.txt b/Tests/RunCMake/Android/ndk-mips-stdout.txt
index c744683..8ce544d 100644
--- a/Tests/RunCMake/Android/ndk-mips-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-mips-stdout.txt
@@ -1,2 +1,2 @@
-- Android: Targeting API '[0-9]+' with architecture 'mips', ABI 'mips', and processor 'mips'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-mips64-stdout.txt b/Tests/RunCMake/Android/ndk-mips64-stdout.txt
index 839ddfd..1d7edea 100644
--- a/Tests/RunCMake/Android/ndk-mips64-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-mips64-stdout.txt
@@ -1,2 +1,2 @@
-- Android: Targeting API '[0-9]+' with architecture 'mips64', ABI 'mips64', and processor 'mips64'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-x86-stdout.txt b/Tests/RunCMake/Android/ndk-x86-stdout.txt
index 2dbb2f0..8d710fe 100644
--- a/Tests/RunCMake/Android/ndk-x86-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-x86-stdout.txt
@@ -1,2 +1,2 @@
-- Android: Targeting API '[0-9]+' with architecture 'x86', ABI 'x86', and processor 'i686'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-x86_64-stdout.txt b/Tests/RunCMake/Android/ndk-x86_64-stdout.txt
index a7ae91d..695a088 100644
--- a/Tests/RunCMake/Android/ndk-x86_64-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-x86_64-stdout.txt
@@ -1,2 +1,2 @@
-- Android: Targeting API '[0-9]+' with architecture 'x86_64', ABI 'x86_64', and processor 'x86_64'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index 3b0ec6e..89f63d0 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -2092,7 +2092,40 @@
],
"build": "^cxx$",
"source": "^cxx$",
- "install": None,
+ "install": {
+ "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+ "destinations": [
+ {
+ "path": "bin",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 37,
+ "command": "install",
+ "hasParent": True,
+ },
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": None,
+ "command": None,
+ "hasParent": True,
+ },
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": 3,
+ "command": "include",
+ "hasParent": True,
+ },
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ ],
+ },
"link": {
"language": "CXX",
"lto": None,
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index 72073d5..c98a84c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -33,3 +33,5 @@
set_property(TARGET c_static_lib PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
file(WRITE "${CMAKE_BINARY_DIR}/ipo_enabled.txt" "")
endif()
+
+install(TARGETS cxx_exe)
diff --git a/Tests/RunCMake/FindBoost/CMakePackage-stdout.txt b/Tests/RunCMake/FindBoost/CMakePackage-stdout.txt
index 0a67488..ebd7232 100644
--- a/Tests/RunCMake/FindBoost/CMakePackage-stdout.txt
+++ b/Tests/RunCMake/FindBoost/CMakePackage-stdout.txt
@@ -1,2 +1,2 @@
-- Found Boost: [^
-]* \(found suitable version "1\.12345", minimum required is "1\.12345"\) found components: date_time
+]* \(found suitable version "1\.12345", minimum required is "1\.12345"\) found components: date_time
diff --git a/Tests/RunCMake/FindBoost/LegacyVars-LowercaseTargetPrefix-stdout.txt b/Tests/RunCMake/FindBoost/LegacyVars-LowercaseTargetPrefix-stdout.txt
index a781dce..1175425 100644
--- a/Tests/RunCMake/FindBoost/LegacyVars-LowercaseTargetPrefix-stdout.txt
+++ b/Tests/RunCMake/FindBoost/LegacyVars-LowercaseTargetPrefix-stdout.txt
@@ -1,5 +1,5 @@
-- Found Boost: [^
-]* \(found suitable version "1\.70\.42", minimum required is "1\.70"\) found components: date_time python37 mpi_python2 *
+]* \(found suitable version "1\.70\.42", minimum required is "1\.70"\) found components: date_time python37 mpi_python2 *
-- Boost_FOUND: TRUE
-- Boost_INCLUDE_DIRS: [^
]*/Tests/RunCMake/FindBoost/CMakePackage[^/]*/include
diff --git a/Tests/RunCMake/FindBoost/LegacyVars-TargetsDefined-stdout.txt b/Tests/RunCMake/FindBoost/LegacyVars-TargetsDefined-stdout.txt
index a4e9c6a..101d60e 100644
--- a/Tests/RunCMake/FindBoost/LegacyVars-TargetsDefined-stdout.txt
+++ b/Tests/RunCMake/FindBoost/LegacyVars-TargetsDefined-stdout.txt
@@ -1,5 +1,5 @@
-- Found Boost: [^
-]* \(found suitable version "1\.70\.42", minimum required is "1\.70"\) found components: date_time python37 mpi_python2 *
+]* \(found suitable version "1\.70\.42", minimum required is "1\.70"\) found components: date_time python37 mpi_python2 *
-- Boost_FOUND: TRUE
-- Boost_INCLUDE_DIRS: [^
]*/Tests/RunCMake/FindBoost/CMakePackage[^/]*/include
diff --git a/Tests/RunCMake/FindBoost/MissingTarget-stdout.txt b/Tests/RunCMake/FindBoost/MissingTarget-stdout.txt
index 8e9d684..9853c01 100644
--- a/Tests/RunCMake/FindBoost/MissingTarget-stdout.txt
+++ b/Tests/RunCMake/FindBoost/MissingTarget-stdout.txt
@@ -1,5 +1,5 @@
-- Found Boost: [^
-]* \(found suitable version "1\.70\.42", minimum required is "1\.70"\) found components: date_time *
+]* \(found suitable version "1\.70\.42", minimum required is "1\.70"\) found components: date_time *
-- Boost_FOUND: TRUE
-- Boost_INCLUDE_DIRS: [^
]*/Tests/RunCMake/FindBoost/CMakePackage_MissingTarget/include
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 5b2c7cb..1cb4ce5 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -28,3 +28,7 @@
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
run_cmake(VsJustMyCode)
endif()
+
+if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.20)
+ run_cmake(VsSpectreMitigation)
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsSpectreMitigation-check.cmake b/Tests/RunCMake/VS10Project/VsSpectreMitigation-check.cmake
new file mode 100644
index 0000000..6117763
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSpectreMitigation-check.cmake
@@ -0,0 +1,30 @@
+macro(VsSpectreMitigation_check tgt spectre_expect)
+ set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/${tgt}.vcxproj")
+ if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not exist.")
+ return()
+ endif()
+
+ set(HAVE_SpectreMitigation 0)
+
+ file(STRINGS "${vcProjectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<SpectreMitigation>([^<>]+)</SpectreMitigation>")
+ set(spectre_actual "${CMAKE_MATCH_1}")
+ if(NOT "${spectre_actual}" STREQUAL "${spectre_expect}")
+ set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj has <SpectreMitigation> '${spectre_actual}', not '${spectre_expect}'.")
+ return()
+ endif()
+ set(HAVE_SpectreMitigation 1)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT HAVE_SpectreMitigation AND NOT "${spectre_expect}" STREQUAL "")
+ set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <SpectreMitigation> field.")
+ return()
+ endif()
+endmacro()
+
+VsSpectreMitigation_check(SpectreMitigationOn-C "Spectre")
+VsSpectreMitigation_check(SpectreMitigationOff-C "false")
diff --git a/Tests/RunCMake/VS10Project/VsSpectreMitigation.cmake b/Tests/RunCMake/VS10Project/VsSpectreMitigation.cmake
new file mode 100644
index 0000000..b3779d7
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSpectreMitigation.cmake
@@ -0,0 +1,8 @@
+set(CMAKE_CONFIGURATION_TYPES Debug)
+enable_language(C)
+
+add_library(SpectreMitigationOn-C empty.c)
+target_compile_options(SpectreMitigationOn-C PRIVATE -Qspectre)
+
+add_library(SpectreMitigationOff-C empty.c)
+target_compile_options(SpectreMitigationOff-C PRIVATE -Qspectre-)
diff --git a/Tests/RunCMake/find_program/RelAndAbsPath.cmake b/Tests/RunCMake/find_program/RelAndAbsPath.cmake
index 3c60a20..6b61980 100644
--- a/Tests/RunCMake/find_program/RelAndAbsPath.cmake
+++ b/Tests/RunCMake/find_program/RelAndAbsPath.cmake
@@ -10,7 +10,6 @@
strip_windows_path_prefix("${CMAKE_CURRENT_SOURCE_DIR}" srcdir)
-file(MAKE_DIRECTORY "tmp${srcdir}")
configure_file(testCWD "tmp${srcdir}/testNoSuchFile" COPYONLY)
find_program(PROG_ABS
diff --git a/Tests/RuntimePath/CMakeLists.txt b/Tests/RuntimePath/CMakeLists.txt
index 6583a87..bb87440 100644
--- a/Tests/RuntimePath/CMakeLists.txt
+++ b/Tests/RuntimePath/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 3.15)
project(RuntimePath C)
# Add a simple chain of shared libraries that must be found.
@@ -31,3 +31,14 @@
set_property(TARGET bar2 PROPERTY LIBRARY_OUTPUT_DIRECTORY A)
target_link_libraries(bar2 foo2)
endif()
+
+# Add a library that is missing the rpath for its dependency.
+add_library(bar1_no_rpath SHARED bar1.c)
+set_property(TARGET bar1_no_rpath PROPERTY LIBRARY_OUTPUT_DIRECTORY B)
+set_property(TARGET bar1_no_rpath PROPERTY SKIP_BUILD_RPATH 1)
+target_link_libraries(bar1_no_rpath PRIVATE foo1)
+
+# Add an executable linking to the library with a missing dependency rpath.
+# CMake should generate the proper rpath-link flag to find it at build time.
+add_executable(main_with_bar1_no_rpath main.c)
+target_link_libraries(main_with_bar1_no_rpath bar1_no_rpath)
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index e5f8588..f4cbac2 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -8,3 +8,6 @@
endif()
add_executable(SwiftOnly main.swift)
+
+# Dummy to make sure generation works with such targets.
+add_library(SwiftIface INTERFACE)
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index ce4cfaf..f52caed 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -7,7 +7,7 @@
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
- include(${CMake_SOURCE_DIR}/Source/CMakeVersionCompute.cmake)
+ include(${CMake_SOURCE_DIR}/Source/CMakeVersion.cmake)
include(${CMake_SOURCE_DIR}/Source/CMakeInstallDestinations.cmake)
unset(CMAKE_DATA_DIR)
unset(CMAKE_DATA_DIR CACHE)
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index e4e6e05..736a7c0 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -7,7 +7,7 @@
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
- include(${CMake_SOURCE_DIR}/Source/CMakeVersionCompute.cmake)
+ include(${CMake_SOURCE_DIR}/Source/CMakeVersion.cmake)
include(${CMake_SOURCE_DIR}/Source/CMakeInstallDestinations.cmake)
unset(CMAKE_DATA_DIR)
unset(CMAKE_DATA_DIR CACHE)
diff --git a/bootstrap b/bootstrap
index 7d9631c..4581239 100755
--- a/bootstrap
+++ b/bootstrap
@@ -326,6 +326,7 @@
cmFindPathCommand \
cmFindProgramCommand \
cmForEachCommand \
+ cmFunctionBlocker \
cmFunctionCommand \
cmFSPermissions \
cmGeneratedFileStream \
@@ -422,8 +423,10 @@
cmState \
cmStateDirectory \
cmStateSnapshot \
+ cmStringAlgorithms \
cmStringReplaceHelper \
cmStringCommand \
+ cmSubcommandTable \
cmSubdirCommand \
cmSystemTools \
cmTarget \
@@ -1359,7 +1362,6 @@
cmake_report cmConfigure.h${_tmp} "#define CMake_DEFAULT_RECURSION_LIMIT 400"
cmake_report cmConfigure.h${_tmp} "#define CMAKE_BIN_DIR \"/bootstrap-not-insalled\""
cmake_report cmConfigure.h${_tmp} "#define CMAKE_DATA_DIR \"/bootstrap-not-insalled\""
-cmake_report cmConfigure.h${_tmp} "#define CMAKE_BOOTSTRAP"
cmake_report cmConfigure.h${_tmp} "#define CM_FALLTHROUGH"
# Regenerate configured headers
@@ -1405,7 +1407,6 @@
uv_c_flags="${uv_c_flags} -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600"
libs="${libs} -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -lole32 -loleaut32"
else
- uv_c_flags="${uv_c_flags} -DCMAKE_BOOTSTRAP"
case "${cmake_system}" in
*AIX*)
uv_c_flags="${uv_c_flags} -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT"
@@ -1466,11 +1467,13 @@
-DKWSYS_CXX_HAS_UTIMES=${KWSYS_CXX_HAS_UTIMES}
"
cmake_c_flags="${cmake_c_flags} \
+ -DCMAKE_BOOTSTRAP \
-I`cmake_escape \"${cmake_bootstrap_dir}\"` \
-I`cmake_escape \"${cmake_source_dir}/Source\"` \
-I`cmake_escape \"${cmake_source_dir}/Source/LexerParser\"` \
-I`cmake_escape \"${cmake_source_dir}/Utilities\"`"
cmake_cxx_flags="${cmake_cxx_flags} \
+ -DCMAKE_BOOTSTRAP \
-I`cmake_escape \"${cmake_bootstrap_dir}\"` \
-I`cmake_escape \"${cmake_source_dir}/Source\"` \
-I`cmake_escape \"${cmake_source_dir}/Source/LexerParser\"` \