diff options
54 files changed, 505 insertions, 347 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac4eb2e..fbf1947 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -205,6 +205,16 @@ t:debian12-hip-radeon: variables: CMAKE_CI_NO_MR: "true" +t:fedora38-hip-radeon: + extends: + - .fedora38_hip_radeon + - .cmake_test_linux_release + - .linux_x86_64_tags_radeon + - .run_dependent + - .needs_centos6_x86_64 + variables: + CMAKE_CI_NO_MR: "true" + t:fedora38-ninja-clang: extends: - .fedora38_ninja_clang diff --git a/.gitlab/ci/configure_fedora38_hip_radeon.cmake b/.gitlab/ci/configure_fedora38_hip_radeon.cmake new file mode 100644 index 0000000..58036b0 --- /dev/null +++ b/.gitlab/ci/configure_fedora38_hip_radeon.cmake @@ -0,0 +1,3 @@ +set(CMake_TEST_HIP "ON" CACHE BOOL "") + +include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake") diff --git a/.gitlab/ci/docker/fedora38/deps_packages.lst b/.gitlab/ci/docker/fedora38/deps_packages.lst index c7c1385..da050d9 100644 --- a/.gitlab/ci/docker/fedora38/deps_packages.lst +++ b/.gitlab/ci/docker/fedora38/deps_packages.lst @@ -44,6 +44,13 @@ file jq which +# Install HIP language toolchain. +hsakmt-devel +lld +rocm-comgr-devel +rocm-hip-devel +rocm-runtime-devel + # Packages needed to test CTest. breezy subversion diff --git a/.gitlab/ci/env_fedora38_hip_radeon.sh b/.gitlab/ci/env_fedora38_hip_radeon.sh new file mode 100644 index 0000000..812ef5a --- /dev/null +++ b/.gitlab/ci/env_fedora38_hip_radeon.sh @@ -0,0 +1 @@ +export HIPCXX=/usr/bin/clang++-16 diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml index dd6299e..3b2a494 100644 --- a/.gitlab/os-linux.yml +++ b/.gitlab/os-linux.yml @@ -69,7 +69,7 @@ ### Fedora .fedora38: - image: "kitware/cmake:ci-fedora38-x86_64-2023-05-22" + image: "kitware/cmake:ci-fedora38-x86_64-2023-08-07" variables: GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes" @@ -366,6 +366,13 @@ CMAKE_CONFIGURATION: debian12_hip_radeon CTEST_LABELS: "HIP" +.fedora38_hip_radeon: + extends: .fedora38 + + variables: + CMAKE_CONFIGURATION: fedora38_hip_radeon + CTEST_LABELS: "HIP" + ### C++ modules .gcc_cxx_modules_x86_64: @@ -645,3 +652,5 @@ -DCMake_SPHINX_CMAKE_ORG_OUTDATED=$CMAKE_CI_SPHINX_OUTDATED -DCMake_VERSION_NO_GIT=$CMAKE_CI_VERSION_NO_GIT - ninja + # FIXME(#25175): non-main index entries are scored too high. + - sed -i '/search for explicit entries in index directives/,/^$/d' html/_static/searchtools.js diff --git a/Help/release/3.27.rst b/Help/release/3.27.rst index e98a49a..457b48c 100644 --- a/Help/release/3.27.rst +++ b/Help/release/3.27.rst @@ -33,7 +33,7 @@ Generators linker will cause a relink if they change (typically modified timestamps). See the :variable:`CMAKE_LINK_DEPENDS_USE_LINKER` variable. -* The :ref:`Visual Studio Generators` for VS 2015 and above learned to +* The :ref:`Visual Studio Generators` for VS 14 (2015) and above learned to select the Windows SDK version explicitly using a ``version=`` field in the :variable:`CMAKE_GENERATOR_PLATFORM` variable. See :ref:`Visual Studio Platform Selection`. @@ -257,6 +257,9 @@ Other Changes * :ref:`Visual Studio Generators`, for VS 15.8 (2017) and newer, now build custom commands in parallel. See policy :policy:`CMP0147`. +* :ref:`Visual Studio Generators` for VS 14 (2015) and above now prefer + to select the latest Windows SDK version. See policy :policy:`CMP0149`. + Updates ======= @@ -268,3 +271,16 @@ Changes made since CMake 3.27.0 include the following. * This version made no changes to documented features or interfaces. Some implementation updates were made to support ecosystem changes and/or fix regressions. + +3.27.2 +------ + +* :ref:`Visual Studio Generators` for VS 14 (2015) and above now prefer to + select the latest Windows SDK, as documented by policy :policy:`CMP0149`, + when targeting any version of Windows. In CMake 3.27.[0-1] the + preference was limited to targeting Windows 10 and above. + +* :ref:`Visual Studio Generators` for VS 14 (2015) and above now support + using ``version=8.1`` in the :variable:`CMAKE_GENERATOR_PLATFORM` variable + to select the Windows 8.1 SDK. In CMake 3.27.[0-1] the ``version=`` field + was limited to selecting Windows 10 SDKs. diff --git a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst index 416ff60..22bf655 100644 --- a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst +++ b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst @@ -50,7 +50,7 @@ Supported pairs are: .. versionadded:: 3.27 Specify the Windows SDK version to use. This is supported by VS 2015 and - above when targeting Windows 10.0+ or Windows Store. CMake will set the + above when targeting Windows or Windows Store. CMake will set the :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable to the selected SDK version. @@ -66,6 +66,10 @@ Supported pairs are: the value of :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM`, if that variable is set. + ``8.1`` + Specify the 8.1 SDK version. This is always supported by VS 2015. + On VS 2017 and above the 8.1 SDK must be installed. + If the ``version`` field is not specified, CMake selects a version as described in the :variable:`CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION` variable documentation. diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index 75d33e8..5fec06f 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -102,6 +102,10 @@ function(compiler_id_detection outvar lang) set(ordered_compilers NVIDIA Clang) endif() + if("x${lang}" STREQUAL "xHIP") + set(ordered_compilers Clang) + endif() + if(CID_ID_DEFINE) foreach(Id ${ordered_compilers}) string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "# define ${CID_PREFIX}COMPILER_IS_${Id} 0\n") diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake index c839d1c..13d8d8e 100644 --- a/Modules/Compiler/NVIDIA-CUDA.cmake +++ b/Modules/Compiler/NVIDIA-CUDA.cmake @@ -1,4 +1,5 @@ -include(Compiler/CMakeCommonCompilerMacros) +include(Compiler/NVIDIA) +__compiler_nvidia_cxx_standards(CUDA) set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True) set(CMAKE_CUDA_VERBOSE_FLAG "-v") @@ -98,65 +99,6 @@ if(UNIX AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX")) list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl") endif() -if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC") - # MSVC requires c++14 as the minimum level - set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "") - set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "") - - # MSVC requires c++14 as the minimum level - set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "") - set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "") - - if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0) - if(CMAKE_CUDA_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.10.25017) - set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14") - set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14") - else() - set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "") - set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "") - endif() - endif() - - if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0) - if(CMAKE_CUDA_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505) - set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "-std=c++17") - set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17") - endif() - endif() - - if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0) - if(CMAKE_CUDA_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505) - set(CMAKE_CUDA20_STANDARD_COMPILE_OPTION "-std=c++20") - set(CMAKE_CUDA20_EXTENSION_COMPILE_OPTION "-std=c++20") - endif() - endif() - -else() - set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "") - set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "") - - set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11") - set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11") - - if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0) - set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "-std=c++03") - set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "-std=c++03") - set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14") - set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14") - endif() - - if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 11.0) - set(CMAKE_CUDA17_STANDARD_COMPILE_OPTION "-std=c++17") - set(CMAKE_CUDA17_EXTENSION_COMPILE_OPTION "-std=c++17") - endif() - - if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 12.0) - set(CMAKE_CUDA20_STANDARD_COMPILE_OPTION "-std=c++20") - set(CMAKE_CUDA20_EXTENSION_COMPILE_OPTION "-std=c++20") - endif() - -endif() - if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0") set(CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG "--options-file ") set(CMAKE_CUDA_RESPONSE_FILE_FLAG "--options-file ") @@ -171,5 +113,3 @@ else() set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0) set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0) endif() - -__compiler_check_default_language_standard(CUDA 6.0 03) diff --git a/Modules/Compiler/NVIDIA.cmake b/Modules/Compiler/NVIDIA.cmake new file mode 100644 index 0000000..686c03d --- /dev/null +++ b/Modules/Compiler/NVIDIA.cmake @@ -0,0 +1,69 @@ + +# This module is shared by multiple languages; use include blocker. +if(__COMPILER_NVIDIA) + return() +endif() +set(__COMPILER_NVIDIA 1) + +include(Compiler/CMakeCommonCompilerMacros) + +macro(__compiler_nvidia_cxx_standards lang) + if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC") + # MSVC requires c++14 as the minimum level + set(CMAKE_${lang}03_STANDARD_COMPILE_OPTION "") + set(CMAKE_${lang}03_EXTENSION_COMPILE_OPTION "") + + # MSVC requires c++14 as the minimum level + set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "") + set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "") + + if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 9.0) + if(CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.10.25017) + set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++14") + set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=c++14") + else() + set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "") + set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "") + endif() + endif() + + if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 11.0) + if(CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505) + set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++17") + set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=c++17") + endif() + endif() + + if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0) + if(CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.11.25505) + set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std=c++20") + set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std=c++20") + endif() + endif() + else() + set(CMAKE_${lang}03_STANDARD_COMPILE_OPTION "") + set(CMAKE_${lang}03_EXTENSION_COMPILE_OPTION "") + + set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++11") + set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=c++11") + + if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 9.0) + set(CMAKE_${lang}03_STANDARD_COMPILE_OPTION "-std=c++03") + set(CMAKE_${lang}03_EXTENSION_COMPILE_OPTION "-std=c++03") + set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++14") + set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=c++14") + endif() + + if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 11.0) + set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++17") + set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=c++17") + endif() + + if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 12.0) + set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std=c++20") + set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std=c++20") + endif() + endif() + + __compiler_check_default_language_standard(${lang} 6.0 03) +endmacro() diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 61a8bfa..70fb53c 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,7 +1,7 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 27) -set(CMake_VERSION_PATCH 20230809) +set(CMake_VERSION_PATCH 20230814) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index 82dc019..ef6712a 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -5,6 +5,7 @@ #include <windows.h> #include "cmCPackGenerator.h" +#include "cmCryptoHash.h" #include "cmUuid.h" cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger, @@ -134,7 +135,8 @@ std::string cmWIXSourceWriter::CreateGuidFromComponentId( { std::string guid = "*"; if (this->ComponentGuidType == CMAKE_GENERATED_GUID) { - std::string md5 = cmSystemTools::ComputeStringMD5(componentId); + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + std::string md5 = hasher.HashString(componentId); cmUuid uuid; std::vector<unsigned char> ns; guid = uuid.FromMd5(ns, md5); diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 34c56c9..8d16428 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -290,8 +290,8 @@ std::string DebGenerator::generateMD5File() const continue; } - std::string output = - cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5); + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + std::string output = hasher.HashFile(file); if (output.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem computing the md5 of " << file << std::endl); diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 7d4b0a8..1934d8c 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -285,8 +285,8 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( if (cmIsOn(this->GetOption("InternalTest"))) { upload_as += "ffffffffffffffffffffffffffffffff"; } else { - upload_as += - cmSystemTools::ComputeFileHash(local_file, cmCryptoHash::AlgoMD5); + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + upload_as += hasher.HashFile(local_file); } if (!cmSystemTools::FileExists(local_file)) { @@ -549,8 +549,8 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, } } - std::string md5sum = - cmSystemTools::ComputeFileHash(file, cmCryptoHash::AlgoMD5); + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + std::string md5sum = hasher.HashFile(file); // 1. request the buildid and check to see if the file // has already been uploaded // TODO I added support for subproject. You would need to add diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index a58f2b7..273296d 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -14,6 +14,7 @@ #include "cmArgumentParser.h" #include "cmArgumentParserTypes.h" +#include "cmCryptoHash.h" #include "cmExecutionStatus.h" #include "cmExperimental.h" #include "cmExportBuildAndroidMKGenerator.h" @@ -310,7 +311,8 @@ static bool HandlePackage(std::vector<std::string> const& args, // named by a hash of its own content. This is deterministic and is // unique with high probability. const std::string& outDir = mf.GetCurrentBinaryDirectory(); - std::string hash = cmSystemTools::ComputeStringMD5(outDir); + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + std::string hash = hasher.HashString(outDir); StorePackageRegistry(mf, package, outDir.c_str(), hash.c_str()); return true; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 8f1818d..eb4ba90 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -1224,6 +1224,11 @@ bool cmGeneratorTarget::IsNormal() const return this->Target->IsNormal(); } +bool cmGeneratorTarget::IsRuntimeBinary() const +{ + return this->Target->IsRuntimeBinary(); +} + bool cmGeneratorTarget::IsSynthetic() const { return this->Target->IsSynthetic(); diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 3de9b17..a32e742 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -51,6 +51,7 @@ public: bool IsInBuildSystem() const; bool IsNormal() const; + bool IsRuntimeBinary() const; bool IsSynthetic() const; bool IsImported() const; bool IsImportedGloballyVisible() const; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 8a8d2e0..9af6e9b 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -30,6 +30,7 @@ #include "cmAlgorithms.h" #include "cmCPackPropertiesGenerator.h" #include "cmComputeTargetDepends.h" +#include "cmCryptoHash.h" #include "cmCustomCommand.h" #include "cmCustomCommandLines.h" #include "cmDuration.h" @@ -64,7 +65,6 @@ # include <cm3p/json/value.h> # include <cm3p/json/writer.h> -# include "cmCryptoHash.h" # include "cmQtAutoGenGlobalInitializer.h" #endif @@ -3222,7 +3222,6 @@ std::set<std::string> const& cmGlobalGenerator::GetDirectoryContent( void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs, std::string const& content) { -#if !defined(CMAKE_BOOTSTRAP) // Ignore if there are no outputs. if (outputs.empty()) { return; @@ -3242,20 +3241,14 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs, // Associate the hash with this output. this->RuleHashes[fname] = hash; -#else - (void)outputs; - (void)content; -#endif } void cmGlobalGenerator::CheckRuleHashes() { -#if !defined(CMAKE_BOOTSTRAP) std::string home = this->GetCMakeInstance()->GetHomeOutputDirectory(); std::string pfile = cmStrCat(home, "/CMakeFiles/CMakeRuleHashes.txt"); this->CheckRuleHashes(pfile, home); this->WriteRuleHashes(pfile); -#endif } void cmGlobalGenerator::CheckRuleHashes(std::string const& pfile, diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 7a852f8..0bdc3f9 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -18,6 +18,7 @@ #include "cmsys/Glob.hxx" #include "cmsys/RegularExpression.hxx" +#include "cmCryptoHash.h" #include "cmDocumentationEntry.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" @@ -548,7 +549,7 @@ bool cmGlobalVisualStudio10Generator::InitializePlatformWindows(cmMakefile*) } bool cmGlobalVisualStudio10Generator::VerifyNoGeneratorPlatformVersion( - cmMakefile*, cm::optional<std::string>) const + cmMakefile*) const { return true; } @@ -1202,9 +1203,10 @@ std::string cmGlobalVisualStudio10Generator::GenerateRuleFile( { // The VS 10 generator needs to create the .rule files on disk. // Hide them away under the CMakeFiles directory. + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); std::string ruleDir = cmStrCat( this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeFiles/", - cmSystemTools::ComputeStringMD5(cmSystemTools::GetFilenamePath(output))); + hasher.HashString(cmSystemTools::GetFilenamePath(output))); std::string ruleFile = cmStrCat(ruleDir, '/', cmSystemTools::GetFilenameName(output), ".rule"); return ruleFile; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 38942cb..40bdd71 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -187,8 +187,7 @@ protected: bool InitializePlatform(cmMakefile* mf) override; virtual bool InitializePlatformWindows(cmMakefile* mf); - virtual bool VerifyNoGeneratorPlatformVersion( - cmMakefile* mf, cm::optional<std::string> reason = cm::nullopt) const; + virtual bool VerifyNoGeneratorPlatformVersion(cmMakefile* mf) const; virtual bool ProcessGeneratorToolsetField(std::string const& key, std::string const& value); diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx index 9f1926d..68b4d1a 100644 --- a/Source/cmGlobalVisualStudio14Generator.cxx +++ b/Source/cmGlobalVisualStudio14Generator.cxx @@ -141,14 +141,103 @@ bool cmGlobalVisualStudio14Generator::MatchesGeneratorName( bool cmGlobalVisualStudio14Generator::InitializePlatformWindows(cmMakefile* mf) { - if (cmHasLiteralPrefix(this->SystemVersion, "10.0")) { + // If a Windows SDK version is explicitly requested, search for it. + if (this->GeneratorPlatformVersion) { + std::string const& version = *this->GeneratorPlatformVersion; + + // VS 2019 and above support specifying plain "10.0". + if (version == "10.0"_s) { + if (this->Version >= VSVersion::VS16) { + this->SetWindowsTargetPlatformVersion("10.0", mf); + return true; + } + /* clang-format off */ + mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "given platform specification containing a\n" + " version=10.0\n" + "field. The value 10.0 is only supported by VS 2019 and above.\n" + )); + /* clang-format on */ + return false; + } + + if (cmHasLiteralPrefix(version, "10.0.")) { + return this->SelectWindows10SDK(mf); + } + + if (version == "8.1"_s) { + if (this->IsWin81SDKInstalled()) { + this->SetWindowsTargetPlatformVersion("8.1", mf); + return true; + } + /* clang-format off */ + mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "given platform specification containing a\n" + " version=8.1\n" + "field, but the Windows 8.1 SDK is not installed.\n" + )); + /* clang-format on */ + return false; + } + + if (version.empty()) { + /* clang-format off */ + mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "given platform specification with empty\n" + " version=\n" + "field.\n" + )); + /* clang-format on */ + return false; + } + + /* clang-format off */ + mf->IssueMessage(MessageType::FATAL_ERROR, cmStrCat( + "Generator\n" + " ", this->GetName(), "\n" + "given platform specification containing a\n" + " version=", version, "\n" + "field with unsupported value.\n" + )); + /* clang-format on */ + return false; + } + + // If we are targeting Windows 10+, we select a Windows 10 SDK. + // If no Windows 8.1 SDK is installed, which is possible with VS 2017 and + // higher, then we must choose a Windows 10 SDK anyway. + if (cmHasLiteralPrefix(this->SystemVersion, "10.0") || + !this->IsWin81SDKInstalled()) { return this->SelectWindows10SDK(mf); } - return this->VerifyNoGeneratorPlatformVersion(mf); + + // Under CMP0149 NEW behavior, we search for a Windows 10 SDK even + // when targeting older Windows versions, but it is not required. + if (mf->GetPolicyStatus(cmPolicies::CMP0149) == cmPolicies::NEW) { + std::string const version = this->GetWindows10SDKVersion(mf); + if (!version.empty()) { + this->SetWindowsTargetPlatformVersion(version, mf); + return true; + } + } + + // We are not targeting Windows 10+, so fall back to the Windows 8.1 SDK. + // For VS 2019 and above we must explicitly specify it. + if (this->Version >= cmGlobalVisualStudioGenerator::VSVersion::VS16 && + !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) { + this->SetWindowsTargetPlatformVersion("8.1", mf); + } + return true; } bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion( - cmMakefile* mf, cm::optional<std::string> reason) const + cmMakefile* mf) const { if (!this->GeneratorPlatformVersion) { return true; @@ -164,9 +253,6 @@ bool cmGlobalVisualStudio14Generator::VerifyNoGeneratorPlatformVersion( " " << this->SystemName << ' ' << this->SystemVersion << '\n' ; /* clang-format on */ - if (reason) { - e << *reason << '.'; - } mf->IssueMessage(MessageType::FATAL_ERROR, e.str()); return false; } @@ -210,16 +296,6 @@ bool cmGlobalVisualStudio14Generator::ProcessGeneratorPlatformField( bool cmGlobalVisualStudio14Generator::SelectWindows10SDK(cmMakefile* mf) { - if (this->GeneratorPlatformVersion && - this->GeneratorPlatformVersion->empty()) { - mf->IssueMessage( - MessageType::FATAL_ERROR, - cmStrCat("Generator\n ", this->GetName(), - "\ngiven platform specification with empty\n version=\n" - "field.")); - return false; - } - // Find the default version of the Windows 10 SDK. std::string const version = this->GetWindows10SDKVersion(mf); @@ -251,7 +327,8 @@ void cmGlobalVisualStudio14Generator::SetWindowsTargetPlatformVersion( std::string const& version, cmMakefile* mf) { this->WindowsTargetPlatformVersion = version; - if (!cmSystemTools::VersionCompareEqual(this->WindowsTargetPlatformVersion, + if (!this->WindowsTargetPlatformVersion.empty() && + !cmSystemTools::VersionCompareEqual(this->WindowsTargetPlatformVersion, this->SystemVersion)) { mf->DisplayStatus(cmStrCat("Selecting Windows SDK version ", this->WindowsTargetPlatformVersion, @@ -299,6 +376,11 @@ bool cmGlobalVisualStudio14Generator::IsWindowsStoreToolsetInstalled() const cmSystemTools::KeyWOW64_32); } +bool cmGlobalVisualStudio14Generator::IsWin81SDKInstalled() const +{ + return true; +} + std::string cmGlobalVisualStudio14Generator::GetWindows10SDKMaxVersion( cmMakefile* mf) const { @@ -360,16 +442,6 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion( cmMakefile* mf) { #if defined(_WIN32) && !defined(__CYGWIN__) - // Accept specific version requests as-is. - if (this->GeneratorPlatformVersion) { - std::string const& ver = *this->GeneratorPlatformVersion; - - // VS 2019 and above support specifying plain "10.0". - if (this->Version >= VSVersion::VS16 && ver == "10.0"_s) { - return ver; - } - } - std::vector<std::string> win10Roots; { diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h index f59a323..e903578 100644 --- a/Source/cmGlobalVisualStudio14Generator.h +++ b/Source/cmGlobalVisualStudio14Generator.h @@ -40,10 +40,10 @@ protected: // of the toolset is installed bool IsWindowsStoreToolsetInstalled() const; + virtual bool IsWin81SDKInstalled() const; + bool InitializePlatformWindows(cmMakefile* mf) override; - bool VerifyNoGeneratorPlatformVersion( - cmMakefile* mf, - cm::optional<std::string> reason = cm::nullopt) const override; + bool VerifyNoGeneratorPlatformVersion(cmMakefile* mf) const override; bool ProcessGeneratorPlatformField(std::string const& key, std::string const& value) override; diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx index 52e6d42..d816d7b 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx +++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx @@ -892,26 +892,6 @@ cmGlobalVisualStudioVersionedGenerator::FindAuxToolset( return AuxToolset::PropsMissing; } -bool cmGlobalVisualStudioVersionedGenerator::InitializePlatformWindows( - 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::VSVersion::VS16 && - !cmSystemTools::VersionCompareGreater(this->SystemVersion, "8.1")) { - this->SetWindowsTargetPlatformVersion("8.1", mf); - return this->VerifyNoGeneratorPlatformVersion( - mf, "with the Windows 8.1 SDK installed"); - } - return cmGlobalVisualStudio14Generator::InitializePlatformWindows(mf); - } - // Otherwise we must choose a Win 10 SDK even if we are not targeting - // Windows 10. - return this->SelectWindows10SDK(mf); -} - bool cmGlobalVisualStudioVersionedGenerator::SelectWindowsStoreToolset( std::string& toolset) const { diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h index 8712459..8f0345f 100644 --- a/Source/cmGlobalVisualStudioVersionedGenerator.h +++ b/Source/cmGlobalVisualStudioVersionedGenerator.h @@ -72,10 +72,8 @@ protected: // of the toolset is installed bool IsWindowsStoreToolsetInstalled() const; - bool InitializePlatformWindows(cmMakefile* mf) override; - // Check for a Win 8 SDK known to the registry or VS installer tool. - bool IsWin81SDKInstalled() const; + bool IsWin81SDKInstalled() const override; std::string GetWindows10SDKMaxVersionDefault(cmMakefile*) const override; diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx index e0a6958..2b0e03c 100644 --- a/Source/cmIncludeGuardCommand.cxx +++ b/Source/cmIncludeGuardCommand.cxx @@ -2,11 +2,12 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmIncludeGuardCommand.h" +#include "cmCryptoHash.h" #include "cmExecutionStatus.h" #include "cmMakefile.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" -#include "cmSystemTools.h" +#include "cmStringAlgorithms.h" #include "cmValue.h" #include "cmake.h" @@ -21,14 +22,8 @@ enum IncludeGuardScope std::string GetIncludeGuardVariableName(std::string const& filePath) { - std::string result = "__INCGUARD_"; -#ifndef CMAKE_BOOTSTRAP - result += cmSystemTools::ComputeStringMD5(filePath); -#else - result += cmSystemTools::MakeCidentifier(filePath); -#endif - result += "__"; - return result; + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + return cmStrCat("__INCGUARD_", hasher.HashString(filePath), "__"); } bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar) diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx index 32196d3..71d5471 100644 --- a/Source/cmInstallExportGenerator.cxx +++ b/Source/cmInstallExportGenerator.cxx @@ -8,6 +8,7 @@ #include <cm/memory> +#include "cmCryptoHash.h" #ifndef CMAKE_BOOTSTRAP # include "cmExportInstallAndroidMKGenerator.h" #endif @@ -64,11 +65,10 @@ std::string cmInstallExportGenerator::TempDirCalculate() const return path; } -#ifndef CMAKE_BOOTSTRAP + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); path += '/'; // Replace the destination path with a hash to keep it short. - path += cmSystemTools::ComputeStringMD5(this->Destination); -#endif + path += hasher.HashString(this->Destination); return path; } diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 499dd24..ffab712 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -25,6 +25,7 @@ #include "cmAlgorithms.h" #include "cmComputeLinkInformation.h" +#include "cmCryptoHash.h" #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" #include "cmCustomCommandLines.h" @@ -59,11 +60,6 @@ #include "cmVersion.h" #include "cmake.h" -#if !defined(CMAKE_BOOTSTRAP) -# define CM_LG_ENCODE_OBJECT_NAMES -# include "cmCryptoHash.h" -#endif - #if defined(__HAIKU__) # include <FindDirectory.h> # include <StorageDefs.h> @@ -3026,13 +3022,11 @@ void cmLocalGenerator::WriteUnitySourceInclude( } else { pathToHash = "ABS_" + sf_full_path; } + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); unity_file << "/* " << pathToHash << " */\n" << "#undef " << *uniqueIdName << "\n" << "#define " << *uniqueIdName << " unity_" -#ifndef CMAKE_BOOTSTRAP - << cmSystemTools::ComputeStringMD5(pathToHash) << "\n" -#endif - ; + << hasher.HashString(pathToHash) << "\n"; } if (beforeInclude) { @@ -3700,9 +3694,9 @@ void cmLocalGenerator::GenerateTargetInstallRules( } } -#if defined(CM_LG_ENCODE_OBJECT_NAMES) -static bool cmLocalGeneratorShortenObjectName(std::string& objName, - std::string::size_type max_len) +namespace { +bool cmLocalGeneratorShortenObjectName(std::string& objName, + std::string::size_type max_len) { // Check if the path can be shortened using an md5 sum replacement for // a portion of the path. @@ -3746,7 +3740,7 @@ bool cmLocalGeneratorCheckObjectName(std::string& objName, // already too deep. return false; } -#endif +} std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName( const std::string& sin, std::string const& dir_max) @@ -3796,7 +3790,6 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName( } while (!done); } -#if defined(CM_LG_ENCODE_OBJECT_NAMES) if (!cmLocalGeneratorCheckObjectName(ssin, dir_max.size(), this->ObjectPathMax)) { // Warn if this is the first time the path has been seen. @@ -3817,9 +3810,6 @@ std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName( this->IssueMessage(MessageType::WARNING, m.str()); } } -#else - (void)dir_max; -#endif // Insert the newly mapped object file name. std::map<std::string, std::string>::value_type e(sin, ssin); diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 3d2e5f6..eddc033 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -701,12 +701,6 @@ private: std::string const& filename_base); }; -#if !defined(CMAKE_BOOTSTRAP) -bool cmLocalGeneratorCheckObjectName(std::string& objName, - std::string::size_type dir_len, - std::string::size_type max_total_len); -#endif - namespace detail { void AddCustomCommandToTarget(cmLocalGenerator& lg, cmCommandOrigin origin, cmTarget* target, cmCustomCommandType type, diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index e41a0c3..089498b 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -1469,9 +1469,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( gt, linkBuild.OrderOnlyDeps, config, fileConfig, DependOnTargetArtifact); // Add order-only dependencies on versioning symlinks of shared libs we link. - if (!this->GeneratorTarget->IsDLLPlatform()) { - if (cmComputeLinkInformation* cli = - this->GeneratorTarget->GetLinkInformation(config)) { + // If our target is not producing a runtime binary, it doesn't need the + // symlinks (anything that links to the target might, but that consumer will + // get its own order-only dependency). + if (!gt->IsDLLPlatform() && gt->IsRuntimeBinary()) { + if (cmComputeLinkInformation* cli = gt->GetLinkInformation(config)) { for (auto const& item : cli->GetItems()) { if (item.Target && item.Target->GetType() == cmStateEnums::SHARED_LIBRARY && diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index bf3fcd9..2bdc928 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -47,13 +47,6 @@ # endif #endif -#if !defined(CMAKE_BOOTSTRAP) -# if defined(_WIN32) -# include <cm/memory> -# endif -# include "cmCryptoHash.h" -#endif - #if defined(CMake_USE_MACH_PARSER) # include "cmMachO.h" #endif @@ -1308,89 +1301,6 @@ void cmSystemTools::MoveFileIfDifferent(const std::string& source, RemoveFile(source); } -#ifndef CMAKE_BOOTSTRAP -std::string cmSystemTools::ComputeFileHash(const std::string& source, - cmCryptoHash::Algo algo) -{ - cmCryptoHash hash(algo); - return hash.HashFile(source); -} - -std::string cmSystemTools::ComputeStringMD5(const std::string& input) -{ - cmCryptoHash md5(cmCryptoHash::AlgoMD5); - return md5.HashString(input); -} - -# ifdef _WIN32 -std::string cmSystemTools::ComputeCertificateThumbprint( - const std::string& source) -{ - std::string thumbprint; - - CRYPT_INTEGER_BLOB cryptBlob; - HCERTSTORE certStore = nullptr; - PCCERT_CONTEXT certContext = nullptr; - - HANDLE certFile = CreateFileW( - cmsys::Encoding::ToWide(source.c_str()).c_str(), GENERIC_READ, - FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); - - if (certFile != INVALID_HANDLE_VALUE && certFile != nullptr) { - DWORD fileSize = GetFileSize(certFile, nullptr); - if (fileSize != INVALID_FILE_SIZE) { - auto certData = cm::make_unique<BYTE[]>(fileSize); - if (certData != nullptr) { - DWORD dwRead = 0; - if (ReadFile(certFile, certData.get(), fileSize, &dwRead, nullptr)) { - cryptBlob.cbData = fileSize; - cryptBlob.pbData = certData.get(); - - // Verify that this is a valid cert - if (PFXIsPFXBlob(&cryptBlob)) { - // Open the certificate as a store - certStore = - PFXImportCertStore(&cryptBlob, nullptr, CRYPT_EXPORTABLE); - if (certStore != nullptr) { - // There should only be 1 cert. - certContext = - CertEnumCertificatesInStore(certStore, certContext); - if (certContext != nullptr) { - // The hash is 20 bytes - BYTE hashData[20]; - DWORD hashLength = 20; - - // Buffer to print the hash. Each byte takes 2 chars + - // terminating character - char hashPrint[41]; - char* pHashPrint = hashPrint; - // Get the hash property from the certificate - if (CertGetCertificateContextProperty( - certContext, CERT_HASH_PROP_ID, hashData, &hashLength)) { - for (DWORD i = 0; i < hashLength; i++) { - // Convert each byte to hexadecimal - snprintf(pHashPrint, 3, "%02X", hashData[i]); - pHashPrint += 2; - } - *pHashPrint = '\0'; - thumbprint = hashPrint; - } - CertFreeCertificateContext(certContext); - } - CertCloseStore(certStore, 0); - } - } - } - } - } - CloseHandle(certFile); - } - - return thumbprint; -} -# endif -#endif - void cmSystemTools::Glob(const std::string& directory, const std::string& regexp, std::vector<std::string>& files) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 27d788e..9563fd6 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -22,7 +22,6 @@ #include "cmsys/Status.hxx" // IWYU pragma: export #include "cmsys/SystemTools.hxx" // IWYU pragma: export -#include "cmCryptoHash.h" #include "cmDuration.h" #include "cmProcessOutput.h" @@ -214,20 +213,6 @@ public: static void MoveFileIfDifferent(const std::string& source, const std::string& destination); -#ifndef CMAKE_BOOTSTRAP - //! Compute the hash of a file - static std::string ComputeFileHash(const std::string& source, - cmCryptoHash::Algo algo); - - /** Compute the md5sum of a string. */ - static std::string ComputeStringMD5(const std::string& input); - -# ifdef _WIN32 - //! Get the SHA thumbprint for a certificate file - static std::string ComputeCertificateThumbprint(const std::string& source); -# endif -#endif - /** * Run a single executable command * diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 593a019..7cc5d2e 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2652,6 +2652,24 @@ bool cmTarget::IsPerConfig() const return this->impl->PerConfig; } +bool cmTarget::IsRuntimeBinary() const +{ + switch (this->GetType()) { + case cmStateEnums::EXECUTABLE: + case cmStateEnums::SHARED_LIBRARY: + case cmStateEnums::MODULE_LIBRARY: + return true; + case cmStateEnums::OBJECT_LIBRARY: + case cmStateEnums::STATIC_LIBRARY: + case cmStateEnums::UTILITY: + case cmStateEnums::INTERFACE_LIBRARY: + case cmStateEnums::GLOBAL_TARGET: + case cmStateEnums::UNKNOWN_LIBRARY: + break; + } + return false; +} + bool cmTarget::CanCompileSources() const { if (this->IsImported()) { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 7c10295..dae997f 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -212,6 +212,7 @@ public: bool IsImported() const; bool IsImportedGloballyVisible() const; bool IsPerConfig() const; + bool IsRuntimeBinary() const; bool CanCompileSources() const; bool GetMappedConfig(std::string const& desired_config, cmValue& loc, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 700631c..48f3197 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -17,11 +17,14 @@ #include <cmext/string_view> #include "windows.h" +// include wincrypt.h after windows.h +#include <wincrypt.h> #include "cmsys/FStream.hxx" #include "cmsys/RegularExpression.hxx" #include "cmComputeLinkInformation.h" +#include "cmCryptoHash.h" #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" #include "cmFileSet.h" @@ -1821,8 +1824,9 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule( } script += lg->FinishConstructScript(this->ProjectType); if (this->ProjectType == VsProjectType::csproj) { - std::string name = cmStrCat("CustomCommand_", c, '_', - cmSystemTools::ComputeStringMD5(sourcePath)); + cmCryptoHash hasher(cmCryptoHash::AlgoMD5); + std::string name = + cmStrCat("CustomCommand_", c, '_', hasher.HashString(sourcePath)); this->WriteCustomRuleCSharp(e0, c, name, script, additional_inputs.str(), outputs.str(), comment, ccg); } else { @@ -4865,6 +4869,73 @@ void cmVisualStudio10TargetGenerator::WriteSingleSDKReference( .Attribute("Include", cmStrCat(extension, ", Version=", version)); } +namespace { +std::string ComputeCertificateThumbprint(const std::string& source) +{ + std::string thumbprint; + + CRYPT_INTEGER_BLOB cryptBlob; + HCERTSTORE certStore = nullptr; + PCCERT_CONTEXT certContext = nullptr; + + HANDLE certFile = CreateFileW( + cmsys::Encoding::ToWide(source.c_str()).c_str(), GENERIC_READ, + FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + + if (certFile != INVALID_HANDLE_VALUE && certFile != nullptr) { + DWORD fileSize = GetFileSize(certFile, nullptr); + if (fileSize != INVALID_FILE_SIZE) { + auto certData = cm::make_unique<BYTE[]>(fileSize); + if (certData != nullptr) { + DWORD dwRead = 0; + if (ReadFile(certFile, certData.get(), fileSize, &dwRead, nullptr)) { + cryptBlob.cbData = fileSize; + cryptBlob.pbData = certData.get(); + + // Verify that this is a valid cert + if (PFXIsPFXBlob(&cryptBlob)) { + // Open the certificate as a store + certStore = + PFXImportCertStore(&cryptBlob, nullptr, CRYPT_EXPORTABLE); + if (certStore != nullptr) { + // There should only be 1 cert. + certContext = + CertEnumCertificatesInStore(certStore, certContext); + if (certContext != nullptr) { + // The hash is 20 bytes + BYTE hashData[20]; + DWORD hashLength = 20; + + // Buffer to print the hash. Each byte takes 2 chars + + // terminating character + char hashPrint[41]; + char* pHashPrint = hashPrint; + // Get the hash property from the certificate + if (CertGetCertificateContextProperty( + certContext, CERT_HASH_PROP_ID, hashData, &hashLength)) { + for (DWORD i = 0; i < hashLength; i++) { + // Convert each byte to hexadecimal + snprintf(pHashPrint, 3, "%02X", hashData[i]); + pHashPrint += 2; + } + *pHashPrint = '\0'; + thumbprint = hashPrint; + } + CertFreeCertificateContext(certContext); + } + CertCloseStore(certStore, 0); + } + } + } + } + } + CloseHandle(certFile); + } + + return thumbprint; +} +} + void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile( Elem& e0) { @@ -4911,14 +4982,14 @@ void cmVisualStudio10TargetGenerator::WriteWinRTPackageCertificateKeyFile( } e1.Element("PackageCertificateKeyFile", pfxFile); - std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile); + std::string thumb = ComputeCertificateThumbprint(pfxFile); if (!thumb.empty()) { e1.Element("PackageCertificateThumbprint", thumb); } } else if (!pfxFile.empty()) { Elem e1(e0, "PropertyGroup"); e1.Element("PackageCertificateKeyFile", pfxFile); - std::string thumb = cmSystemTools::ComputeCertificateThumbprint(pfxFile); + std::string thumb = ComputeCertificateThumbprint(pfxFile); if (!thumb.empty()) { e1.Element("PackageCertificateThumbprint", thumb); } diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index ce2479b..b18f5cf 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -13,6 +13,7 @@ #include "cmCommandLineArgument.h" #include "cmConsoleBuf.h" +#include "cmCryptoHash.h" #include "cmDuration.h" #include "cmGlobalGenerator.h" #include "cmList.h" @@ -1692,11 +1693,8 @@ int cmcmd::HashSumFile(std::vector<std::string> const& args, std::cerr << "Error: " << filename << " is a directory" << std::endl; retval++; } else { - std::string value -#ifndef CMAKE_BOOTSTRAP - = cmSystemTools::ComputeFileHash(filename, algo) -#endif - ; + cmCryptoHash hasher(algo); + std::string value = hasher.HashFile(filename); if (value.empty()) { // To mimic "md5sum/shasum" behavior in a shell: std::cerr << filename << ": No such file or directory" << std::endl; diff --git a/Tests/RunCMake/BuildDepends/FortranInclude.cmake b/Tests/RunCMake/BuildDepends/FortranInclude.cmake index fa9f399..ad5fd0a 100644 --- a/Tests/RunCMake/BuildDepends/FortranInclude.cmake +++ b/Tests/RunCMake/BuildDepends/FortranInclude.cmake @@ -1,5 +1,10 @@ enable_language(Fortran) +if("${CMAKE_Fortran_COMPILER_ID};${CMAKE_Fortran_SIMULATE_ID}" MATCHES "^Intel(LLVM)?;MSVC$") + string(APPEND CMAKE_Fortran_FLAGS_DEBUG " -Z7") + string(APPEND CMAKE_Fortran_FLAGS_RELWITHDEBINFO " -Z7") +endif() + set(check_pairs "") add_executable(preprocess FortranIncludePreprocess.F) diff --git a/Tests/RunCMake/CXXModules/examples/generated-stderr.txt b/Tests/RunCMake/CXXModules/examples/generated-stderr.txt index 1dd9876..06160ce 100644 --- a/Tests/RunCMake/CXXModules/examples/generated-stderr.txt +++ b/Tests/RunCMake/CXXModules/examples/generated-stderr.txt @@ -1,4 +1,4 @@ -CMake Warning \(dev\) at CMakeLists.txt:12 \(target_sources\): +CMake Warning \(dev\) at CMakeLists.txt:16 \(target_sources\): CMake's C\+\+ module support is experimental. It is meant only for experimentation and feedback to CMake developers. This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt index 73f7ff7..9a8da3d 100644 --- a/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt +++ b/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt @@ -3,10 +3,14 @@ project(cxx_modules_generated CXX) include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake") -configure_file( - "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in" - "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx" - COPYONLY) +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx" + DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in" + COMMAND "${CMAKE_COMMAND}" + -E copy_if_different + "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in" + "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx" + COMMENT "Copying 'importable.cxx'") add_executable(generated) target_sources(generated diff --git a/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake b/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake index 891e138..6847a23 100644 --- a/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake +++ b/Tests/RunCMake/DependencyGraph/RunCMakeTest.cmake @@ -59,3 +59,5 @@ run_optimize_test(OptimizeStatic StaticTop) if(CMAKE_Fortran_COMPILER) run_optimize_test(OptimizeFortran FortranTop) endif() + +run_cmake_build(RuntimeTargets mylib SharedTop) diff --git a/Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake b/Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake new file mode 100644 index 0000000..21531cd --- /dev/null +++ b/Tests/RunCMake/DependencyGraph/RuntimeTargets.cmake @@ -0,0 +1,18 @@ +enable_language(C) + +set(CMAKE_OPTIMIZE_DEPENDENCIES TRUE) +add_library(mylib STATIC mylib.c) +add_library(neverbuild SHARED neverbuild.c) + +# Building mylib should not require building neverbuild +target_link_libraries(mylib PRIVATE neverbuild) +set_target_properties(neverbuild PROPERTIES EXCLUDE_FROM_ALL YES) + +# Building SharedTop should require SharedBottom to be built +add_library(SharedTop SHARED top.c) +add_library(StaticMiddle STATIC middle.c) +add_library(SharedBottom SHARED bottom.c) +target_link_libraries(SharedTop PRIVATE StaticMiddle) +target_link_libraries(StaticMiddle PRIVATE SharedBottom) +set_target_properties(StaticMiddle SharedBottom PROPERTIES EXCLUDE_FROM_ALL YES) +set_target_properties(StaticMiddle PROPERTIES POSITION_INDEPENDENT_CODE YES) diff --git a/Tests/RunCMake/DependencyGraph/bottom.c b/Tests/RunCMake/DependencyGraph/bottom.c new file mode 100644 index 0000000..c8ea481 --- /dev/null +++ b/Tests/RunCMake/DependencyGraph/bottom.c @@ -0,0 +1,7 @@ +#ifdef _WIN32 +__declspec(dllexport) +#endif + int bottom(void) +{ + return 23; +} diff --git a/Tests/RunCMake/DependencyGraph/middle.c b/Tests/RunCMake/DependencyGraph/middle.c new file mode 100644 index 0000000..3b1b84c --- /dev/null +++ b/Tests/RunCMake/DependencyGraph/middle.c @@ -0,0 +1,9 @@ +#ifdef _WIN32 +__declspec(dllimport) +#endif + int bottom(void); + +int middle(void) +{ + return bottom() + 19; +} diff --git a/Tests/RunCMake/DependencyGraph/neverbuild.c b/Tests/RunCMake/DependencyGraph/neverbuild.c new file mode 100644 index 0000000..e490510 --- /dev/null +++ b/Tests/RunCMake/DependencyGraph/neverbuild.c @@ -0,0 +1 @@ +#error I should not be built diff --git a/Tests/RunCMake/DependencyGraph/top.c b/Tests/RunCMake/DependencyGraph/top.c new file mode 100644 index 0000000..eceb0a5 --- /dev/null +++ b/Tests/RunCMake/DependencyGraph/top.c @@ -0,0 +1,9 @@ +int middle(void); + +#ifdef _WIN32 +__declspec(dllexport) +#endif + int top(void) +{ + return middle() + 2; +} diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionMissing-stderr.txt b/Tests/RunCMake/GeneratorPlatform/BadVersionMissing-stderr.txt index d82eb0b..41e94f3 100644 --- a/Tests/RunCMake/GeneratorPlatform/BadVersionMissing-stderr.txt +++ b/Tests/RunCMake/GeneratorPlatform/BadVersionMissing-stderr.txt @@ -6,6 +6,6 @@ given platform specification with - version=1\.2\.3\.4 + version=10\.0\.0\.0 field, but no Windows SDK with that version was found\.$ diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionPlatform-stderr.txt b/Tests/RunCMake/GeneratorPlatform/BadVersionPlatform-stderr.txt deleted file mode 100644 index d3c62e3..0000000 --- a/Tests/RunCMake/GeneratorPlatform/BadVersionPlatform-stderr.txt +++ /dev/null @@ -1,19 +0,0 @@ -^CMake Error at CMakeLists.txt:[0-9]+ \(project\): - Generator - - Visual Studio [^ -]+ - - given platform specification (containing a - - version=8\.1 - - field\. The version field is not supported when targeting - - Windows 8\.1( - - with the Windows 8\.1 SDK installed\.)?|with - - version=8\.1 - - field, but no Windows SDK with that version was found\.)$ diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionPlatform-result.txt b/Tests/RunCMake/GeneratorPlatform/BadVersionPre2019-result.txt index d00491f..d00491f 100644 --- a/Tests/RunCMake/GeneratorPlatform/BadVersionPlatform-result.txt +++ b/Tests/RunCMake/GeneratorPlatform/BadVersionPre2019-result.txt diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionPre2019-stderr.txt b/Tests/RunCMake/GeneratorPlatform/BadVersionPre2019-stderr.txt new file mode 100644 index 0000000..649b89d --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/BadVersionPre2019-stderr.txt @@ -0,0 +1,11 @@ +^CMake Error at CMakeLists.txt:[0-9]+ \(project\): + Generator + + Visual Studio [^ +]+ + + given platform specification containing a + + version=10\.0 + + field\. The value 10\.0 is only supported by VS 2019 and above\.$ diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionPlatform.cmake b/Tests/RunCMake/GeneratorPlatform/BadVersionPre2019.cmake index 2fc38e5..2fc38e5 100644 --- a/Tests/RunCMake/GeneratorPlatform/BadVersionPlatform.cmake +++ b/Tests/RunCMake/GeneratorPlatform/BadVersionPre2019.cmake diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported-result.txt b/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported-stderr.txt b/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported-stderr.txt new file mode 100644 index 0000000..c165267 --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported-stderr.txt @@ -0,0 +1,11 @@ +^CMake Error at CMakeLists.txt:[0-9]+ \(project\): + Generator + + Visual Studio [^ +]+ + + given platform specification containing a + + version=1\.2\.3\.4 + + field with unsupported value\.$ diff --git a/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported.cmake b/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported.cmake new file mode 100644 index 0000000..2fc38e5 --- /dev/null +++ b/Tests/RunCMake/GeneratorPlatform/BadVersionUnsupported.cmake @@ -0,0 +1 @@ +message(FATAL_ERROR "This should not be reached!") diff --git a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake index 233eb0a..d8965f7 100644 --- a/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorPlatform/RunCMakeTest.cmake @@ -36,12 +36,16 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$") run_cmake(BadFieldUnknown) set(RunCMake_GENERATOR_PLATFORM "version=") run_cmake(BadVersionEmpty) - set(RunCMake_GENERATOR_PLATFORM "version=1.2.3.4") + set(RunCMake_GENERATOR_PLATFORM "version=10.0.0.0") run_cmake(BadVersionMissing) - set(RunCMake_GENERATOR_PLATFORM "version=8.1") - run_cmake_with_options(BadVersionPlatform -DCMAKE_SYSTEM_VERSION=8.1) + set(RunCMake_GENERATOR_PLATFORM "version=1.2.3.4") + run_cmake(BadVersionUnsupported) - if(NOT RunCMake_GENERATOR MATCHES "^Visual Studio (1[45]) ") + if(RunCMake_GENERATOR MATCHES "^Visual Studio (1[45]) ") + set(RunCMake_GENERATOR_PLATFORM "version=10.0") + run_cmake(BadVersionPre2019) + unset(RunCMake_GENERATOR_PLATFORM) + else() set(expect_version "10.0") set(RunCMake_GENERATOR_PLATFORM "version=${expect_version}") set(RunCMake_TEST_VARIANT_DESCRIPTION "-${expect_version}") @@ -61,6 +65,16 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$") file(GLOB kits RELATIVE "${kitsInclude}" "${kitsInclude}/*/um/windows.h") list(TRANSFORM kits REPLACE "/.*" "") endif() + cmake_host_system_information(RESULT kitsRoot81 + QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/Microsoft/Windows Kits/Installed Roots" + VALUE "KitsRoot81" + VIEW 64_32 + ERROR_VARIABLE kitsRoot81Error + ) + if(NOT kitsRoot81Error AND EXISTS "${kitsRoot81}/include/um/windows.h") + list(PREPEND kits "8.1") + endif() + if(kits) message(STATUS "Available Kits: ${kits}") if(RunCMake_GENERATOR MATCHES "^Visual Studio 14 ") @@ -83,29 +97,28 @@ if("${RunCMake_GENERATOR}" MATCHES "^Visual Studio (1[4567])( 20[0-9][0-9])?$") message(FATAL_ERROR "Could not find any Windows SDKs to drive test cases.") endif() - if(kits) - foreach(expect_version IN LISTS kits) - set(RunCMake_GENERATOR_PLATFORM "version=${expect_version}") - set(RunCMake_TEST_VARIANT_DESCRIPTION "-${expect_version}") - run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=10.0) - unset(RunCMake_GENERATOR_PLATFORM) - endforeach() - foreach(expect_version IN LISTS kits) - set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMP0149-OLD-${expect_version}") - run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=${expect_version} -DCMAKE_POLICY_DEFAULT_CMP0149=OLD) - endforeach() - if(kits MATCHES "(^|;)([0-9.]+)$") - set(expect_version "${CMAKE_MATCH_2}") - foreach(test_version IN LISTS kits) - set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMP0149-NEW-${test_version}") - run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=${test_version} -DCMAKE_POLICY_DEFAULT_CMP0149=NEW) - endforeach() - endif() - foreach(expect_version IN LISTS kits) - set(RunCMake_TEST_VARIANT_DESCRIPTION "-WindowsSDKVersion-${expect_version}") - set(ENV{WindowsSDKVersion} "${expect_version}\\") - run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_POLICY_DEFAULT_CMP0149=NEW) - unset(ENV{WindowsSDKVersion}) + foreach(expect_version IN LISTS kits) + set(RunCMake_GENERATOR_PLATFORM "version=${expect_version}") + set(RunCMake_TEST_VARIANT_DESCRIPTION "-${expect_version}") + run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=10.0) + unset(RunCMake_GENERATOR_PLATFORM) + endforeach() + foreach(expect_version IN LISTS kits) + set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMP0149-OLD-${expect_version}") + run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=${expect_version} -DCMAKE_POLICY_DEFAULT_CMP0149=OLD) + endforeach() + if(kits MATCHES "(^|;)([0-9.]+)$") + set(expect_version "${CMAKE_MATCH_2}") + foreach(test_version IN LISTS kits) + set(RunCMake_TEST_VARIANT_DESCRIPTION "-CMP0149-NEW-${test_version}") + run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=${test_version} -DCMAKE_POLICY_DEFAULT_CMP0149=NEW) endforeach() endif() + list(REMOVE_ITEM kits 8.1) + foreach(expect_version IN LISTS kits) + set(RunCMake_TEST_VARIANT_DESCRIPTION "-WindowsSDKVersion-${expect_version}") + set(ENV{WindowsSDKVersion} "${expect_version}\\") + run_cmake_with_options(VersionExists -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_POLICY_DEFAULT_CMP0149=NEW) + unset(ENV{WindowsSDKVersion}) + endforeach() endif() diff --git a/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake b/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake index 6c3c8e5..62fb278 100644 --- a/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake +++ b/Tests/RunCMake/GeneratorPlatform/VersionExists-check.cmake @@ -1,9 +1,13 @@ if(actual_stdout MATCHES "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION='([^']+)'") set(actual_version "${CMAKE_MATCH_1}") - if(NOT "${actual_version}" STREQUAL "${expect_version}") - set(RunCMake_TEST_FAILED "Actual SDK version '${actual_version}' did not match expected '${expect_version}'") - return() - endif() +elseif(actual_stdout MATCHES "CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION=''" AND RunCMake_GENERATOR MATCHES "Visual Studio 1[45] ") + set(actual_version "8.1") else() set(RunCMake_TEST_FAILED "No CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION found in output.") + return() +endif() + +if(NOT "${actual_version}" STREQUAL "${expect_version}") + set(RunCMake_TEST_FAILED "Actual SDK version '${actual_version}' did not match expected '${expect_version}'") + return() endif() |