diff options
-rw-r--r-- | Help/command/file.rst | 46 | ||||
-rw-r--r-- | Help/command/get_filename_component.rst | 7 | ||||
-rw-r--r-- | Help/release/3.14.rst | 2 | ||||
-rw-r--r-- | Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst | 7 | ||||
-rw-r--r-- | Modules/CMakeDetermineASMCompiler.cmake | 2 | ||||
-rw-r--r-- | Modules/CMakeDetermineCompilerABI.cmake | 6 | ||||
-rw-r--r-- | Modules/CMakeDetermineCompilerId.cmake | 2 | ||||
-rw-r--r-- | Modules/CMakeDetermineVSServicePack.cmake | 2 | ||||
-rw-r--r-- | Modules/ExternalProject.cmake | 3 | ||||
-rw-r--r-- | Modules/FindBoost.cmake | 8 | ||||
-rw-r--r-- | Modules/Platform/UnixPaths.cmake | 14 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio14Generator.cxx | 13 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudio14Generator.h | 3 | ||||
-rw-r--r-- | Source/cmGlobalVisualStudioVersionedGenerator.cxx | 6 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 77 | ||||
-rw-r--r-- | Source/cmQtAutoGenGlobalInitializer.cxx | 64 | ||||
-rw-r--r-- | Source/cmQtAutoGenGlobalInitializer.h | 6 | ||||
-rw-r--r-- | Source/cmQtAutoGenInitializer.cxx | 53 | ||||
-rw-r--r-- | Source/cmQtAutoGenInitializer.h | 4 |
19 files changed, 208 insertions, 117 deletions
diff --git a/Help/command/file.rst b/Help/command/file.rst index db4d6fc..465e567 100644 --- a/Help/command/file.rst +++ b/Help/command/file.rst @@ -26,8 +26,8 @@ Synopsis file(`MAKE_DIRECTORY`_ [<dir>...]) file({`COPY`_ | `INSTALL`_} <file>... DESTINATION <dir> [...]) file(`SIZE`_ <filename> <out-var>) - file(`READ_SYMLINK`_ <filename> <out-var>) - file(`CREATE_LINK`_ <file> <new-file> [...]) + file(`READ_SYMLINK`_ <linkname> <out-var>) + file(`CREATE_LINK`_ <original> <linkname> [...]) `Path Conversion`_ file(`RELATIVE_PATH`_ <out-var> <directory> <file>) @@ -350,22 +350,22 @@ pointing to a file and is readable. .. code-block:: cmake - file(READ_SYMLINK <filename> <variable>) + file(READ_SYMLINK <linkname> <variable>) -Read the symlink at ``<filename>`` and put the result in ``<variable>``. -Requires that ``<filename>`` is a valid path pointing to a symlink. If -``<filename>`` does not exist, or is not a symlink, an error is thrown. +This subcommand queries the symlink ``<linkname>`` and stores the path it +points to in the result ``<variable>``. If ``<linkname>`` does not exist or +is not a symlink, CMake issues a fatal error. Note that this command returns the raw symlink path and does not resolve -relative symlinks. If you want to resolve the relative symlink yourself, you -could do something like this: +a relative path. The following is an example of how to ensure that an +absolute path is obtained: .. code-block:: cmake - set(filename "/path/to/foo.sym") - file(READ_SYMLINK "${filename}" result) + set(linkname "/path/to/foo.sym") + file(READ_SYMLINK "${linkname}" result) if(NOT IS_ABSOLUTE "${result}") - get_filename_component(dir "${filename}" DIRECTORY) + get_filename_component(dir "${linkname}" DIRECTORY) set(result "${dir}/${result}") endif() @@ -373,23 +373,23 @@ could do something like this: .. code-block:: cmake - file(CREATE_LINK <file> <new-file> + file(CREATE_LINK <original> <linkname> [RESULT <result>] [COPY_ON_ERROR] [SYMBOLIC]) -Create a link to ``<file>`` at ``<new-file>``. +Create a link ``<linkname>`` that points to ``<original>``. +It will be a hard link by default, but providing the ``SYMBOLIC`` option +results in a symbolic link instead. Hard links require that ``original`` +exists and is a file, not a directory. If ``<linkname>`` already exists, +it will be overwritten. -It is a hard link by default. This can be changed to symbolic links by -using ``SYMBOLIC``. The original file needs to exist for hard links. - -The ``<result>`` variable, if specified, gets the status of the operation. -It is set to ``0`` in case of success. Otherwise, it contains the error -generated. In case of failures, if ``RESULT`` is not specified, a fatal error -is emitted. +The ``<result>`` variable, if specified, receives the status of the operation. +It is set to ``0`` upon success or an error message otherwise. If ``RESULT`` +is not specified and the operation fails, a fatal error is emitted. Specifying ``COPY_ON_ERROR`` enables copying the file as a fallback if -creating the link fails. - -Overwrites the ``<new-file>`` if it exists. +creating the link fails. It can be useful for handling situations such as +``<original>`` and ``<linkname>`` being on different drives or mount points, +which would make them unable to support a hard link. Path Conversion ^^^^^^^^^^^^^^^ diff --git a/Help/command/get_filename_component.rst b/Help/command/get_filename_component.rst index f55499a..9bbf877 100644 --- a/Help/command/get_filename_component.rst +++ b/Help/command/get_filename_component.rst @@ -15,14 +15,13 @@ Sets ``<var>`` to a component of ``<FileName>``, where ``<mode>`` is one of: NAME = File name without directory EXT = File name longest extension (.b.c from d/a.b.c) NAME_WE = File name without directory or longest extension - LAST_EXT = File name last extention (.c from d/a.b.c) + LAST_EXT = File name last extension (.c from d/a.b.c) NAME_WLE = File name without directory or last extension PATH = Legacy alias for DIRECTORY (use for CMake <= 2.8.11) Paths are returned with forward slashes and have no trailing slashes. -The longest file extension is always considered. If the optional -``CACHE`` argument is specified, the result variable is added to the -cache. +If the optional ``CACHE`` argument is specified, the result variable is +added to the cache. .. code-block:: cmake diff --git a/Help/release/3.14.rst b/Help/release/3.14.rst index 13d209f..a04005c 100644 --- a/Help/release/3.14.rst +++ b/Help/release/3.14.rst @@ -172,7 +172,7 @@ Modules * The :module:`ExternalProject` module :command:`ExternalProject_Add` command gained ``LOG_PATCH`` to optionally log the patch step. -* The :module:`ExternalProject` module's ``ExternalProject_Add`` command +* The :module:`ExternalProject` module :command:`ExternalProject_Add` command learned to apply ``SOURCE_SUBDIR`` when ``BUILD_IN_SOURCE`` is also used. The ``BUILD_COMMAND`` is run in the given ``SOURCE_SUBDIR`` of the ``SOURCE_DIR``. diff --git a/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst b/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst index cc80851..e361fd9 100644 --- a/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst +++ b/Help/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES.rst @@ -6,4 +6,9 @@ Directories implicitly searched by the compiler for header files. CMake does not explicitly specify these directories on compiler command lines for language ``<LANG>``. This prevents system include directories from being treated as user include directories on some -compilers. +compilers, which is important for ``C``, ``CXX``, and ``CUDA`` to +avoid overriding standard library headers. + +This value is not used for ``Fortran`` because it has no standard +library headers and some compilers do not search their implicit +include directories for module ``.mod`` files. diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake index dbc41c8..ac27f87 100644 --- a/Modules/CMakeDetermineASMCompiler.cmake +++ b/Modules/CMakeDetermineASMCompiler.cmake @@ -83,7 +83,7 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID) set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_XL "XL C") list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS MSVC ) - set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "/?") + set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_FLAGS_MSVC "-?") set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_REGEX_MSVC "Microsoft") list(APPEND CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDORS TI ) diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index fd1d5fb..e0d2449 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -96,6 +96,12 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Parsed ${lang} implicit include dir info from above output: rv=${rv}\n${log}\n\n") if("${rv}" STREQUAL "done") + # Entries that we have been told to explicitly pass as standard include + # directories will not be implicitly added by the compiler. + if(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES) + list(REMOVE_ITEM implicit_incdirs ${CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES}) + endif() + # We parsed implicit include directories, so override the default initializer. set(_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT "${implicit_incdirs}") endif() diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 83ce392..8ba4246 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -824,7 +824,7 @@ function(CMAKE_DIAGNOSE_UNSUPPORTED_CLANG lang envvar) endif() # Test whether an MSVC-like command-line option works. - execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" /? + execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -? RESULT_VARIABLE _clang_result OUTPUT_VARIABLE _clang_stdout ERROR_VARIABLE _clang_stderr) diff --git a/Modules/CMakeDetermineVSServicePack.cmake b/Modules/CMakeDetermineVSServicePack.cmake index 9edc309..a3c4d9c 100644 --- a/Modules/CMakeDetermineVSServicePack.cmake +++ b/Modules/CMakeDetermineVSServicePack.cmake @@ -79,7 +79,7 @@ endfunction() function(_DetermineVSServicePack_FastCheckVersionWithCompiler _SUCCESS_VAR _VERSION_VAR) if(EXISTS ${CMAKE_CXX_COMPILER}) execute_process( - COMMAND ${CMAKE_CXX_COMPILER} /? + COMMAND ${CMAKE_CXX_COMPILER} -? ERROR_VARIABLE _output OUTPUT_QUIET ) diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index c5d6b45..e097894 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -550,7 +550,8 @@ External Project Definition When enabled, the output of the test step is logged to files. ``LOG_MERGED_STDOUTERR <bool>`` - When enabled, the output the step is not split by stdout and stderr. + When enabled, stdout and stderr will be merged for any step whose + output is being logged to files. ``LOG_OUTPUT_ON_FAILURE <bool>`` This option only has an effect if at least one of the other ``LOG_<step>`` diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake index 8c112d4..7882c4b 100644 --- a/Modules/FindBoost.cmake +++ b/Modules/FindBoost.cmake @@ -1807,10 +1807,12 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) foreach(compiler IN LISTS _boost_COMPILER) list(APPEND _boost_RELEASE_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} ) endforeach() list(APPEND _boost_RELEASE_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} ) @@ -1819,10 +1821,12 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) foreach(compiler IN LISTS _boost_COMPILER) list(APPEND _boost_RELEASE_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) endforeach() list(APPEND _boost_RELEASE_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) endif() endforeach() @@ -1860,10 +1864,12 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) foreach(compiler IN LISTS _boost_COMPILER) list(APPEND _boost_DEBUG_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} ) endforeach() list(APPEND _boost_DEBUG_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} ) @@ -1872,10 +1878,12 @@ foreach(COMPONENT ${Boost_FIND_COMPONENTS}) foreach(compiler IN LISTS _boost_COMPILER) list(APPEND _boost_DEBUG_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) endforeach() list(APPEND _boost_DEBUG_NAMES ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) endif() endforeach() diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake index 46c24bb..97f744d 100644 --- a/Modules/Platform/UnixPaths.cmake +++ b/Modules/Platform/UnixPaths.cmake @@ -63,21 +63,29 @@ list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES /lib /lib32 /lib64 /usr/lib /usr/lib32 /usr/lib64 ) +if(CMAKE_SYSROOT_COMPILE) + set(_cmake_sysroot_compile "${CMAKE_SYSROOT_COMPILE}") +else() + set(_cmake_sysroot_compile "${CMAKE_SYSROOT}") +endif() + # Default per-language values. These may be later replaced after # parsing the implicit directory information from compiler output. set(_CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES} - /usr/include + "${_cmake_sysroot_compile}/usr/include" ) set(_CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES} - /usr/include + "${_cmake_sysroot_compile}/usr/include" ) set(_CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES} - /usr/include + "${_cmake_sysroot_compile}/usr/include" ) +unset(_cmake_sysroot_compile) + # Enable use of lib32 and lib64 search path variants by default. set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE) set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index a0a9558..2025867 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -158,14 +158,22 @@ bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf, bool required) { // Find the default version of the Windows 10 SDK. - this->WindowsTargetPlatformVersion = this->GetWindows10SDKVersion(); - if (required && this->WindowsTargetPlatformVersion.empty()) { + std::string const version = this->GetWindows10SDKVersion(); + if (required && version.empty()) { std::ostringstream e; e << "Could not find an appropriate version of the Windows 10 SDK" << " installed on this machine"; mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); return false; } + this->SetWindowsTargetPlatformVersion(version, mf); + return true; +} + +void cmGlobalVisualStudio14Generator::SetWindowsTargetPlatformVersion( + std::string const& version, cmMakefile* mf) +{ + this->WindowsTargetPlatformVersion = version; if (!cmSystemTools::VersionCompareEqual(this->WindowsTargetPlatformVersion, this->SystemVersion)) { std::ostringstream e; @@ -175,7 +183,6 @@ bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf, } mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION", this->WindowsTargetPlatformVersion.c_str()); - return true; } bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset( diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h index 32008b0..6e12d3e 100644 --- a/Source/cmGlobalVisualStudio14Generator.h +++ b/Source/cmGlobalVisualStudio14Generator.h @@ -40,6 +40,9 @@ protected: virtual bool SelectWindows10SDK(cmMakefile* mf, bool required); + void SetWindowsTargetPlatformVersion(std::string const& version, + cmMakefile* mf); + // Used to verify that the Desktop toolset for the current generator is // installed on the machine. bool IsWindowsDesktopToolsetInstalled() const override; diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index 913fc4a..2f9eb3f 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -401,6 +401,12 @@ bool cmGlobalVisualStudioVersionedGenerator::InitializeWindows(cmMakefile* mf) // If the Win 8.1 SDK is installed then we can select a SDK matching // the target Windows version. if (this->IsWin81SDKInstalled()) { + // VS 2019 does not default to 8.1 so specify it explicitly when needed. + if (this->Version >= cmGlobalVisualStudioGenerator::VS16 && + !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) { + this->SetWindowsTargetPlatformVersion("8.1", mf); + return true; + } return cmGlobalVisualStudio14Generator::InitializeWindows(mf); } // Otherwise we must choose a Win 10 SDK even if we are not targeting diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 8090e00..7e56818 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -920,6 +920,20 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( return result; } + // Standard include directories to be added unconditionally at the end. + // 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); + cmSystemTools::ExpandListArgument(value, userStandardDirs); + for (std::string& usd : userStandardDirs) { + cmSystemTools::ConvertToUnixSlashes(usd); + } + } + // Implicit include directories std::vector<std::string> implicitDirs; std::set<std::string> implicitSet; @@ -928,24 +942,27 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( return (implicitSet.find(dir) == implicitSet.end()); }; { - std::string rootPath; - if (const char* sysrootCompile = - this->Makefile->GetDefinition("CMAKE_SYSROOT_COMPILE")) { - rootPath = sysrootCompile; - } else { - rootPath = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT"); - } - cmSystemTools::ConvertToUnixSlashes(rootPath); - // Raw list of implicit include directories - std::vector<std::string> impDirVec; + // Start with "standard" directories that we unconditionally add below. + std::vector<std::string> impDirVec = userStandardDirs; // Load implicit include directories for this language. - std::string key = "CMAKE_"; - key += lang; - key += "_IMPLICIT_INCLUDE_DIRECTORIES"; - if (const char* value = this->Makefile->GetDefinition(key)) { - cmSystemTools::ExpandListArgument(value, impDirVec); + // We ignore this for Fortran because: + // * There are no standard library headers to avoid overriding. + // * 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)) { + size_t const impDirVecOldSize = impDirVec.size(); + cmSystemTools::ExpandListArgument(value, impDirVec); + // FIXME: Use cmRange with 'advance()' when it supports non-const. + for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) { + cmSystemTools::ConvertToUnixSlashes(impDirVec[i]); + } + } } // The Platform/UnixPaths module used to hard-code /usr/include for C, CXX, @@ -965,13 +982,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( } for (std::string const& i : impDirVec) { - std::string imd = i; - cmSystemTools::ConvertToUnixSlashes(imd); - if (!rootPath.empty() && !cmHasPrefix(imd, rootPath)) { - imd = rootPath + imd; - } - if (implicitSet.insert(imd).second) { - implicitDirs.emplace_back(std::move(imd)); + if (implicitSet.insert(i).second) { + implicitDirs.emplace_back(i); } } } @@ -1010,23 +1022,10 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit( MoveSystemIncludesToEnd(result, config, lang, target); // Append standard include directories for this language. - { - std::vector<std::string> userStandardDirs; - { - std::string key = "CMAKE_"; - key += lang; - key += "_STANDARD_INCLUDE_DIRECTORIES"; - std::string const value = this->Makefile->GetSafeDefinition(key); - cmSystemTools::ExpandListArgument(value, userStandardDirs); - } - userDirs.reserve(userDirs.size() + userStandardDirs.size()); - for (std::string& usd : userStandardDirs) { - cmSystemTools::ConvertToUnixSlashes(usd); - if (notImplicit(usd)) { - emitDir(usd); - } - userDirs.emplace_back(std::move(usd)); - } + userDirs.reserve(userDirs.size() + userStandardDirs.size()); + for (std::string& usd : userStandardDirs) { + emitDir(usd); + userDirs.emplace_back(std::move(usd)); } // Append compiler implicit include directories diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx index 95a297c..3ad91ee 100644 --- a/Source/cmQtAutoGenGlobalInitializer.cxx +++ b/Source/cmQtAutoGenGlobalInitializer.cxx @@ -6,10 +6,12 @@ #include "cmAlgorithms.h" #include "cmCustomCommandLines.h" +#include "cmDuration.h" #include "cmGeneratorTarget.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" +#include "cmProcessOutput.h" #include "cmState.h" #include "cmStateTypes.h" #include "cmSystemTools.h" @@ -183,6 +185,68 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc( } } +bool cmQtAutoGenGlobalInitializer::GetExecutableTestOutput( + std::string const& generator, std::string const& executable, + std::string& error, std::string* output) +{ + // Check if we have cached output + { + auto it = this->ExecutableTestOutputs_.find(executable); + if (it != this->ExecutableTestOutputs_.end()) { + // Return output on demand + if (output != nullptr) { + *output = it->second; + } + return true; + } + } + + // Check if the executable exists + if (!cmSystemTools::FileExists(executable, true)) { + error = "The \""; + error += generator; + error += "\" executable "; + error += cmQtAutoGen::Quoted(executable); + error += " does not exist."; + return false; + } + + // Test the executable + std::string stdOut; + { + std::string stdErr; + std::vector<std::string> command; + command.push_back(executable); + command.emplace_back("-h"); + int retVal = 0; + const bool runResult = cmSystemTools::RunSingleCommand( + command, &stdOut, &stdErr, &retVal, nullptr, cmSystemTools::OUTPUT_NONE, + cmDuration::zero(), cmProcessOutput::Auto); + if (!runResult) { + error = "Test run of \""; + error += generator; + error += "\" executable "; + error += cmQtAutoGen::Quoted(executable) + " failed.\n"; + error += cmQtAutoGen::QuotedCommand(command); + error += "\n"; + error += stdOut; + error += "\n"; + error += stdErr; + return false; + } + } + + // Return executable output on demand + if (output != nullptr) { + *output = stdOut; + } + + // Register executable and output + this->ExecutableTestOutputs_.emplace(executable, std::move(stdOut)); + + return true; +} + bool cmQtAutoGenGlobalInitializer::generate() { return (InitializeCustomTargets() && SetupCustomTargets()); diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h index 9e6bac0..74184a0 100644 --- a/Source/cmQtAutoGenGlobalInitializer.h +++ b/Source/cmQtAutoGenGlobalInitializer.h @@ -8,6 +8,7 @@ #include <map> #include <memory> // IWYU pragma: keep #include <string> +#include <unordered_map> #include <vector> class cmLocalGenerator; @@ -38,10 +39,15 @@ private: void AddToGlobalAutoRcc(cmLocalGenerator* localGen, std::string const& targetName); + bool GetExecutableTestOutput(std::string const& generator, + std::string const& executable, + std::string& error, std::string* output); + private: std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_; std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_; std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_; + std::unordered_map<std::string, std::string> ExecutableTestOutputs_; }; #endif diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx index a96d574..614a88b 100644 --- a/Source/cmQtAutoGenInitializer.cxx +++ b/Source/cmQtAutoGenInitializer.cxx @@ -1439,18 +1439,18 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target) return res; } -std::pair<bool, std::string> GetQtExecutable( - const cmQtAutoGen::IntegerVersion& qtVersion, cmGeneratorTarget* target, +std::pair<bool, std::string> cmQtAutoGenInitializer::GetQtExecutable( const std::string& executable, bool ignoreMissingTarget, std::string* output) { const std::string upperExecutable = cmSystemTools::UpperCase(executable); - std::string result = - target->Target->GetSafeProperty("AUTO" + upperExecutable + "_EXECUTABLE"); + std::string result = this->Target->Target->GetSafeProperty( + "AUTO" + upperExecutable + "_EXECUTABLE"); if (!result.empty()) { - cmListFileBacktrace lfbt = target->Target->GetMakefile()->GetBacktrace(); + cmListFileBacktrace lfbt = + this->Target->Target->GetMakefile()->GetBacktrace(); cmGeneratorExpression ge(lfbt); std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(result); - result = cge->Evaluate(target->GetLocalGenerator(), ""); + result = cge->Evaluate(this->Target->GetLocalGenerator(), ""); return std::make_pair(true, result); } @@ -1460,12 +1460,12 @@ std::pair<bool, std::string> GetQtExecutable( // Find executable { const std::string targetName = - GetQtExecutableTargetName(qtVersion, executable); + GetQtExecutableTargetName(this->QtVersion, executable); if (targetName.empty()) { err = "The AUTO" + upperExecutable + " feature "; err += "supports only Qt 4, Qt 5 and Qt 6."; } else { - cmLocalGenerator* localGen = target->GetLocalGenerator(); + cmLocalGenerator* localGen = this->Target->GetLocalGenerator(); cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse(targetName); if (tgt != nullptr) { if (tgt->IsImported()) { @@ -1485,36 +1485,14 @@ std::pair<bool, std::string> GetQtExecutable( // Test executable if (err.empty()) { - if (cmSystemTools::FileExists(result, true)) { - std::vector<std::string> command; - command.push_back(result); - command.emplace_back("-h"); - std::string stdOut; - std::string stdErr; - int retVal = 0; - const bool runResult = cmSystemTools::RunSingleCommand( - command, &stdOut, &stdErr, &retVal, nullptr, - cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto); - if (!runResult) { - err = "Test of \"" + executable + "\" binary "; - err += cmQtAutoGen::Quoted(result) + " failed: "; - err += cmQtAutoGen::QuotedCommand(command); - } else { - if (output != nullptr) { - *output = stdOut; - } - } - } else { - err = "The \"" + executable + "\" binary "; - err += cmQtAutoGen::Quoted(result); - err += " does not exist"; - } + this->GlobalInitializer->GetExecutableTestOutput(executable, result, err, + output); } // Print error if (!err.empty()) { std::string msg = "AutoGen ("; - msg += target->GetName(); + msg += this->Target->GetName(); msg += "): "; msg += err; cmSystemTools::Error(msg); @@ -1526,16 +1504,14 @@ std::pair<bool, std::string> GetQtExecutable( bool cmQtAutoGenInitializer::GetMocExecutable() { - const auto result = - GetQtExecutable(this->QtVersion, this->Target, "moc", false, nullptr); + const auto result = this->GetQtExecutable("moc", false, nullptr); this->Moc.Executable = result.second; return result.first; } bool cmQtAutoGenInitializer::GetUicExecutable() { - const auto result = - GetQtExecutable(this->QtVersion, this->Target, "uic", true, nullptr); + const auto result = this->GetQtExecutable("uic", true, nullptr); this->Uic.Executable = result.second; return result.first; } @@ -1543,8 +1519,7 @@ bool cmQtAutoGenInitializer::GetUicExecutable() bool cmQtAutoGenInitializer::GetRccExecutable() { std::string stdOut; - const auto result = - GetQtExecutable(this->QtVersion, this->Target, "rcc", false, &stdOut); + const auto result = this->GetQtExecutable("rcc", false, &stdOut); this->Rcc.Executable = result.second; if (!result.first) { return false; diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h index 10f0bf3..781dd15 100644 --- a/Source/cmQtAutoGenInitializer.h +++ b/Source/cmQtAutoGenInitializer.h @@ -110,6 +110,10 @@ private: std::vector<std::string>& files, std::string& errorMessage); + std::pair<bool, std::string> GetQtExecutable(const std::string& executable, + bool ignoreMissingTarget, + std::string* output); + private: cmQtAutoGenGlobalInitializer* GlobalInitializer; cmGeneratorTarget* Target; |