This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, master has been updated
       via  bbf4a5771f8113ce5b88968c4dd3def2fbcd9354 (commit)
       via  dd53122be5b142e97ac02d1dec62719db29bc39e (commit)
       via  7ed84b1e8fc9a5bb7a7fe0b0b1a6077b2498d6c7 (commit)
       via  18b0330b86cae2771a54021e390f157a097c8a99 (commit)
      from  ddb1759b3e2b5c1b2c56734cd2ae0fa6dcf3a815 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bbf4a5771f8113ce5b88968c4dd3def2fbcd9354
commit bbf4a5771f8113ce5b88968c4dd3def2fbcd9354
Merge: dd53122 18b0330
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Wed Aug 7 15:45:02 2019 +0000
Commit:     Kitware Robot <kwro...@kitware.com>
CommitDate: Wed Aug 7 11:54:53 2019 -0400

    Merge topic 'tidy_inefficient_string'
    
    18b0330b86 clang-tidy: Enable performance-inefficient-string-concatenation
    
    Acked-by: Kitware Robot <kwro...@kitware.com>
    Merge-request: !3648


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=dd53122be5b142e97ac02d1dec62719db29bc39e
commit dd53122be5b142e97ac02d1dec62719db29bc39e
Merge: ddb1759 7ed84b1
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Wed Aug 7 15:44:52 2019 +0000
Commit:     Kitware Robot <kwro...@kitware.com>
CommitDate: Wed Aug 7 11:52:57 2019 -0400

    Merge topic 'FindPython-virtual-env'
    
    7ed84b1e8f FindPython: ensure virtual environments are correctly handled
    
    Acked-by: Kitware Robot <kwro...@kitware.com>
    Merge-request: !3649


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=7ed84b1e8fc9a5bb7a7fe0b0b1a6077b2498d6c7
commit 7ed84b1e8fc9a5bb7a7fe0b0b1a6077b2498d6c7
Author:     Marc Chevrier <marc.chevr...@gmail.com>
AuthorDate: Sat Aug 3 16:24:20 2019 +0200
Commit:     Marc Chevrier <marc.chevr...@gmail.com>
CommitDate: Mon Aug 5 18:20:29 2019 +0200

    FindPython: ensure virtual environments are correctly handled
    
    Fixes: #19525

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 @@ Hints
     ``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 @@ function (_PYTHON_GET_NAMES _PYTHON_PGN_NAMES)
   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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
     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)
-      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)
 
-  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})
 
-    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)
+        # Framework Paths
+        _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS 
${_${_PYTHON_PREFIX}_VERSION})
+        list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS 
${_${_PYTHON_PREFIX}_VERSION_PATHS})
+      endforeach()
 
-    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)
+      # 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()
 
-    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 "")
+      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 _${_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}" --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 (DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+      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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                          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()
-  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)
+            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)
-    # 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)
+        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
+    _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX)
+
     # 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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
     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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                       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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                       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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                     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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                           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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                         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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                         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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                         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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                       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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                             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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
                           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 ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
     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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
         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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
         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 @@ if ("Development" IN_LIST 
${_PYTHON_PREFIX}_FIND_COMPONENTS
       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 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
         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 @@ Hints
     ``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 @@ Hints
     ``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
 ^^^^^^^^
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=18b0330b86cae2771a54021e390f157a097c8a99
commit 18b0330b86cae2771a54021e390f157a097c8a99
Author:     Sebastian Holtermann <sebh...@xwmw.org>
AuthorDate: Sat Aug 3 13:20:31 2019 +0200
Commit:     Sebastian Holtermann <sebh...@xwmw.org>
CommitDate: Mon Aug 5 17:21:00 2019 +0200

    clang-tidy: Enable performance-inefficient-string-concatenation
    
    Enables the clang-tidy test performance-inefficient-string-concatenation
    and replaces all inefficient string concatenations with `cmStrCat`.
    
    Closes: #19555

diff --git a/.clang-tidy b/.clang-tidy
index 57e571a..2b7c9ae 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -22,7 +22,6 @@ modernize-*,\
 -modernize-use-transparent-functors,\
 -modernize-use-using,\
 performance-*,\
--performance-inefficient-string-concatenation,\
 readability-*,\
 -readability-function-size,\
 -readability-identifier-naming,\
diff --git a/Source/CTest/cmCTestBuildHandler.cxx 
b/Source/CTest/cmCTestBuildHandler.cxx
index 407e9f8..b98a4e3 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -385,11 +385,8 @@ int cmCTestBuildHandler::ProcessHandler()
   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;
       }
@@ -399,11 +396,8 @@ int cmCTestBuildHandler::ProcessHandler()
   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/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index bbf490e..739cc58 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -494,9 +494,9 @@ void cmCTestLaunch::DumpFileToXML(cmXMLElement& e3, const 
char* tag,
       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);
diff --git a/Source/CTest/cmCTestScriptHandler.cxx 
b/Source/CTest/cmCTestScriptHandler.cxx
index f8d9f1b..4288b25 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -30,6 +30,7 @@
 #include "cmState.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmake.h"
 
@@ -663,8 +664,8 @@ int cmCTestScriptHandler::PerformExtraUpdates()
         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;
       }
     }
@@ -934,7 +935,7 @@ bool cmCTestScriptHandler::TryToRemoveBinaryDirectoryOnce(
       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 2c6ff83..17ef350 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -225,7 +225,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
       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;
@@ -237,9 +237,9 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
                      << 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/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 @@ protected:
             // 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 @@ protected:
           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/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 @@ bool cmBinUtilsLinuxELFLinker::ResolveDependency(
   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 @@ bool cmBinUtilsLinuxELFLinker::ResolveDependency(
   }
 
   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/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 @@ bool 
cmBinUtilsWindowsPELinker::ResolveDependency(std::string const& name,
   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/cmComputeLinkInformation.cxx 
b/Source/cmComputeLinkInformation.cxx
index 5f46631..4aa18f2 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -1754,7 +1754,7 @@ void 
cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
               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/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index d2a4148..edd8d46 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -514,7 +514,7 @@ int 
cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     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 @@ int 
cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
         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/cmExportInstallFileGenerator.cxx 
b/Source/cmExportInstallFileGenerator.cxx
index ab4a62b..4bc2d1b 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -412,7 +412,7 @@ void 
cmExportInstallFileGenerator::SetImportLocationProperty(
     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 @@ void Tree::BuildUnitImpl(cmXMLWriter& xml,
 {
   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 @@ std::vector<std::string> 
cmExtraCodeLiteGenerator::CreateProjectsByTarget(
       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 @@ std::vector<std::string> 
cmExtraCodeLiteGenerator::CreateProjectsByTarget(
         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::vector<std::string> 
cmExtraCodeLiteGenerator::CreateProjectsByProjectMaps(
     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 @@ void cmExtraSublimeTextGenerator::AppendTarget(
         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 @@ bool 
cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args,
     // 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 2594287..aee42d7 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -94,7 +94,7 @@ void cmFileAPI::RemoveOldReplyFiles()
   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);
     }
   }
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 4f1a158..71493bb 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -7,6 +7,7 @@
 #include "cmFileCommand.h"
 #include "cmFileTimes.h"
 #include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmsys/Directory.hxx"
 #include "cmsys/Glob.hxx"
@@ -490,7 +491,7 @@ bool cmFileCopier::InstallSymlinkChain(std::string& 
fromFile,
   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);
@@ -520,7 +521,7 @@ bool cmFileCopier::InstallSymlinkChain(std::string& 
fromFile,
     }
 
     fromFile = newFromFile;
-    toFile = toFilePath + "/" + symlinkTarget;
+    toFile = cmStrCat(toFilePath, "/", symlinkTarget);
   }
 
   return true;
diff --git a/Source/cmGeneratorExpressionNode.cxx 
b/Source/cmGeneratorExpressionNode.cxx
index 14dc7b8..f78c72e 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1441,7 +1441,7 @@ static const struct TargetObjectsNode : public 
cmGeneratorExpressionNode
       }
 
       for (std::string& o : objects) {
-        o = obj_dir + o;
+        o = cmStrCat(obj_dir, o);
       }
     }
 
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 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
         // 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/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 @@ void 
cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
     }
 
     // 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 0b68966..c3c44be 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1731,8 +1731,9 @@ int 
cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
   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;
   }
 
@@ -1786,8 +1787,9 @@ std::unique_ptr<cmSourceInfo> 
cmcmd_cmake_ninja_depends_fortran(
       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;
       }
     }
@@ -1866,8 +1868,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
     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;
     }
 
@@ -1894,14 +1897,14 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
   // 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()) {
@@ -2005,8 +2008,9 @@ int 
cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
     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/cmGlobalXCodeGenerator.cxx 
b/Source/cmGlobalXCodeGenerator.cxx
index 8f4ae62..c46856a 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2993,7 +2993,7 @@ cmXCodeObject* 
cmGlobalXCodeGenerator::CreateOrGetPBXGroup(
       } else {
         tgroup = i_folder->second;
       }
-      curr_folder = curr_folder + "\\";
+      curr_folder += "\\";
     }
     return tgroup;
   }
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 @@ void cmInstallDirectoryGenerator::GenerateScriptForConfig(
   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/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 @@ void cmInstallTargetGenerator::GetInstallObjectNames(
 {
   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..dc5f477 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 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
         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);
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 4430f97..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,
@@ -115,16 +116,17 @@ std::string cmLinkLineComputer::ComputeLinkPath(
           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/cmListCommand.cxx b/Source/cmListCommand.cxx
index 8c14596..29c17fa 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -1189,8 +1189,8 @@ bool 
cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
     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;
       }
@@ -1201,23 +1201,22 @@ bool 
cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
         } 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()) {
@@ -1227,23 +1226,21 @@ bool 
cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
         } 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()) {
@@ -1253,21 +1250,19 @@ bool 
cmListCommand::HandleSortCommand(std::vector<std::string> const& args)
         } 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 28ae82e..3deaeb0 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1912,7 +1912,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
   // 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)) {
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx 
b/Source/cmLocalUnixMakefileGenerator3.cxx
index 713c985..c6b63ba 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -963,7 +963,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
         // 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;
@@ -1017,18 +1017,16 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
           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));
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx 
b/Source/cmMakefileExecutableTargetGenerator.cxx
index a7f2a97..19c667e 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(
@@ -243,7 +244,7 @@ void 
cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
     // 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 @@ void 
cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
     // 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..8d342f3 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(
@@ -373,7 +374,7 @@ void 
cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
 
     // 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 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
 
       // 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 008248c..7b26324 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -806,7 +806,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile(
 
     // 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/cmNinjaNormalTargetGenerator.cxx 
b/Source/cmNinjaNormalTargetGenerator.cxx
index cd84c03..865ae7d 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -228,7 +228,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool 
useResponseFile)
     // 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);
     }
@@ -367,7 +367,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool 
useResponseFile)
     // 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 8b0a6ba..c3459be 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -553,7 +553,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const 
std::string& lang)
     }
 
     for (std::string& i : ppCmds) {
-      i = launcher + i;
+      i = cmStrCat(launcher, i);
       rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
                                                    i, ppVars);
     }
@@ -770,7 +770,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const 
std::string& lang)
   }
 
   for (std::string& i : compileCmds) {
-    i = launcher + i;
+    i = cmStrCat(launcher, i);
     rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
                                                  vars);
   }
diff --git a/Source/cmOutputRequiredFilesCommand.cxx 
b/Source/cmOutputRequiredFilesCommand.cxx
index a66af5a..587e21c 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -215,10 +215,8 @@ protected:
           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;
             }
           }
@@ -227,10 +225,8 @@ protected:
             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;
               }
             }
@@ -240,10 +236,8 @@ protected:
             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;
               }
             }
@@ -253,10 +247,8 @@ protected:
             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;
               }
             }
@@ -340,9 +332,9 @@ protected:
           // 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;
@@ -421,9 +413,9 @@ protected:
 
     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);
@@ -486,9 +478,7 @@ bool cmOutputRequiredFilesCommand::InitialPass(
     // 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/cmRST.cxx b/Source/cmRST.cxx
index a329f7d..1f9aae8 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -342,7 +342,7 @@ void cmRST::OutputMarkupLines(bool inlineMarkup)
 {
   for (auto line : this->MarkupLines) {
     if (!line.empty()) {
-      line = " " + line;
+      line = cmStrCat(" ", line);
     }
     this->OutputLine(line, inlineMarkup);
   }
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index ffdd0ce..bb9aace 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -56,7 +56,7 @@ bool rootIsPrefix(const std::string& root,
 {
   for (std::string const& file : files) {
     if (!cmHasPrefix(file, root)) {
-      error = "ROOT: " + root + " is not a prefix of file: " + file;
+      error = cmStrCat("ROOT: ", root, " is not a prefix of file: ", file);
       return false;
     }
   }
@@ -94,7 +94,7 @@ bool addFilesToItsSourceGroups(const std::string& root,
 
     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/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 5f4e1fc..6aeba54 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -835,7 +835,7 @@ std::string cmSystemTools::FileExistsInParentDirectories(
   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;
     }
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 @@ std::string cmTargetIncludeDirectoriesCommand::Join(
   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/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::BinaryToString(const unsigned char* 
input) const
 
 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/cmake.cxx b/Source/cmake.cxx
index a81b7e4..3cc6776 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -808,8 +808,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
           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;
       }

-----------------------------------------------------------------------

Summary of changes:
 .clang-tidy                                    |   1 -
 Modules/FindPython.cmake                       |   6 +
 Modules/FindPython/Support.cmake               | 479 +++++++++++++++----------
 Modules/FindPython2.cmake                      |   6 +
 Modules/FindPython3.cmake                      |   6 +
 Source/CTest/cmCTestBuildHandler.cxx           |   6 -
 Source/CTest/cmCTestLaunch.cxx                 |   4 +-
 Source/CTest/cmCTestScriptHandler.cxx          |   7 +-
 Source/CTest/cmCTestSubmitHandler.cxx          |   8 +-
 Source/CTest/cmParseCoberturaCoverage.cxx      |   5 +-
 Source/cmBinUtilsLinuxELFLinker.cxx            |   5 +-
 Source/cmBinUtilsWindowsPELinker.cxx           |   3 +-
 Source/cmComputeLinkInformation.cxx            |   2 +-
 Source/cmCoreTryCompile.cxx                    |   5 +-
 Source/cmExportInstallFileGenerator.cxx        |   2 +-
 Source/cmExtraCodeBlocksGenerator.cxx          |   9 +-
 Source/cmExtraCodeLiteGenerator.cxx            |   7 +-
 Source/cmExtraSublimeTextGenerator.cxx         |   3 +-
 Source/cmFLTKWrapUICommand.cxx                 |  14 +-
 Source/cmFileAPI.cxx                           |   2 +-
 Source/cmFileCopier.cxx                        |   5 +-
 Source/cmGeneratorExpressionNode.cxx           |   2 +-
 Source/cmGhsMultiTargetGenerator.cxx           |   5 +-
 Source/cmGlobalGhsMultiGenerator.cxx           |  11 +-
 Source/cmGlobalNinjaGenerator.cxx              |  28 +-
 Source/cmGlobalXCodeGenerator.cxx              |   2 +-
 Source/cmInstallDirectoryGenerator.cxx         |   3 +-
 Source/cmInstallTargetGenerator.cxx            |   3 +-
 Source/cmJsonObjects.cxx                       |   6 +-
 Source/cmLinkLineComputer.cxx                  |  12 +-
 Source/cmListCommand.cxx                       |  51 ++-
 Source/cmLocalGenerator.cxx                    |   2 +-
 Source/cmLocalUnixMakefileGenerator3.cxx       |  12 +-
 Source/cmMakefileExecutableTargetGenerator.cxx |   5 +-
 Source/cmMakefileLibraryTargetGenerator.cxx    |   5 +-
 Source/cmMakefileTargetGenerator.cxx           |   2 +-
 Source/cmNinjaNormalTargetGenerator.cxx        |   4 +-
 Source/cmNinjaTargetGenerator.cxx              |   4 +-
 Source/cmOutputRequiredFilesCommand.cxx        |  36 +-
 Source/cmRST.cxx                               |   2 +-
 Source/cmSourceGroupCommand.cxx                |   4 +-
 Source/cmSystemTools.cxx                       |   2 +-
 Source/cmTargetIncludeDirectoriesCommand.cxx   |   5 +-
 Source/cmUuid.cxx                              |   6 +-
 Source/cmake.cxx                               |   4 +-
 45 files changed, 461 insertions(+), 340 deletions(-)


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
https://cmake.org/mailman/listinfo/cmake-commits

Reply via email to