diff options
34 files changed, 332 insertions, 59 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 465dc2c..18844d1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -363,6 +363,13 @@ test:intel2021.1.2-makefiles: CMAKE_CI_BUILD_NAME: intel2021.1.2_makefiles CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.1.2-el8 +test:intel2021.2.0-makefiles: + extends: + - .cmake_test_linux_intelclassic_makefiles + variables: + CMAKE_CI_BUILD_NAME: intel2021.2.0_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.2.0-el8 + test:oneapi2021.1.1-makefiles: extends: - .cmake_test_linux_inteloneapi_makefiles @@ -377,6 +384,13 @@ test:oneapi2021.1.2-makefiles: CMAKE_CI_BUILD_NAME: oneapi2021.1.2_makefiles CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.1.2-el8 +test:oneapi2021.2.0-makefiles: + extends: + - .cmake_test_linux_inteloneapi_makefiles + variables: + CMAKE_CI_BUILD_NAME: oneapi2021.2.0_makefiles + CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2021.2.0-el8 + build:linux-x86_64-package: extends: - .linux_package diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst index 8de6deb..d9f54ca 100644 --- a/Help/command/foreach.rst +++ b/Help/command/foreach.rst @@ -14,9 +14,12 @@ semicolon or whitespace. All commands between ``foreach`` and the matching ``endforeach`` are recorded without being invoked. Once the ``endforeach`` is evaluated, the recorded list of commands is invoked once for each item in ``<items>``. -At the beginning of each iteration the variable ``loop_var`` will be set +At the beginning of each iteration the variable ``<loop_var>`` will be set to the value of the current item. +The scope of ``<loop_var>`` is restricted to the loop scope. See policy +:policy:`CMP0124` for details. + The commands :command:`break` and :command:`continue` provide means to escape from the normal control flow. diff --git a/Help/guide/ide-integration/index.rst b/Help/guide/ide-integration/index.rst index addf932..779883b 100644 --- a/Help/guide/ide-integration/index.rst +++ b/Help/guide/ide-integration/index.rst @@ -69,9 +69,9 @@ While reading, parsing, and evaluating the contents of ``CMakePresets.json`` is straightforward, it is not trivial. In addition to the documentation, IDE vendors may also wish to refer to the CMake source code and test cases for a better understanding of how to implement the format. -:download:`This file </manual/presets/schema.json>` provides a machine-readable -JSON schema for the ``CMakePresets.json`` format that IDE vendors may find -useful for validation and providing editing assistance. +:download:`This file <../../manual/presets/schema.json>` provides a +machine-readable JSON schema for the ``CMakePresets.json`` format that IDE +vendors may find useful for validation and providing editing assistance. Configuring =========== diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index b41ce59..08449a7 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.21 .. toctree:: :maxdepth: 1 + CMP0124: foreach() loop variables are only available in the loop scope. </policy/CMP0124> CMP0123: ARMClang cpu/arch compile and link flags must be set explicitly. </policy/CMP0123> CMP0122: UseSWIG use standard library name conventions for csharp language. </policy/CMP0122> CMP0121: The list command detects invalid indicies. </policy/CMP0121> diff --git a/Help/policy/CMP0124.rst b/Help/policy/CMP0124.rst new file mode 100644 index 0000000..88d03e3 --- /dev/null +++ b/Help/policy/CMP0124.rst @@ -0,0 +1,20 @@ +CMP0124 +------- + +.. versionadded:: 3.21 + +The loop variables created by :command:`foreach` command have now their scope +restricted to the loop scope. + +Starting with CMake 3.21, the :command:`foreach` command ensures that the loop +variables have their scope restricted to the loop scope. + +The ``OLD`` behavior for this policy let the loop variables to exist, with an +empty value, in the outer scope of loop scope. + +This policy was introduced in CMake version 3.21. Use the +:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly. +Unlike many policies, CMake version |release| does *not* warn when the policy +is not set and simply uses ``OLD`` behavior. + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/foreach-variable-scope.rst b/Help/release/dev/foreach-variable-scope.rst new file mode 100644 index 0000000..29a57bb --- /dev/null +++ b/Help/release/dev/foreach-variable-scope.rst @@ -0,0 +1,5 @@ +foreach-variable-scope +---------------------- + +* The :command:`foreach` command restrict loop variables to the loop scope. + See policy :policy:`CMP0124` for details. diff --git a/Modules/CMakeCompilerIdDetection.cmake b/Modules/CMakeCompilerIdDetection.cmake index c79d423..850fc14 100644 --- a/Modules/CMakeCompilerIdDetection.cmake +++ b/Modules/CMakeCompilerIdDetection.cmake @@ -18,7 +18,7 @@ function(compiler_id_detection outvar lang) file(GLOB lang_files "${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake") set(nonlang CXX) - if (lang STREQUAL CXX) + if ("x${lang}" STREQUAL "xCXX") set(nonlang C) endif() diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake index f767847..ee7fedb 100644 --- a/Modules/CMakeDetermineCompileFeatures.cmake +++ b/Modules/CMakeDetermineCompileFeatures.cmake @@ -4,7 +4,7 @@ function(cmake_determine_compile_features lang) - if(lang STREQUAL C AND COMMAND cmake_record_c_compile_features) + if("x${lang}" STREQUAL "xC" AND COMMAND cmake_record_c_compile_features) message(CHECK_START "Detecting ${lang} compile features") set(CMAKE_C90_COMPILE_FEATURES) @@ -54,7 +54,7 @@ function(cmake_determine_compile_features lang) message(CHECK_PASS "done") - elseif(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features) + elseif("x${lang}" STREQUAL "xCXX" AND COMMAND cmake_record_cxx_compile_features) message(CHECK_START "Detecting ${lang} compile features") set(CMAKE_CXX98_COMPILE_FEATURES) @@ -110,7 +110,7 @@ function(cmake_determine_compile_features lang) message(CHECK_PASS "done") - elseif(lang STREQUAL CUDA AND COMMAND cmake_record_cuda_compile_features) + elseif("x${lang}" STREQUAL "xCUDA" AND COMMAND cmake_record_cuda_compile_features) message(CHECK_START "Detecting ${lang} compile features") set(CMAKE_CUDA03_COMPILE_FEATURES) diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake index f3a8b74..024ff14 100644 --- a/Modules/FindBLAS.cmake +++ b/Modules/FindBLAS.cmake @@ -333,12 +333,21 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE) set(BLAS_mkl_INTFACE "gf") set(BLAS_mkl_THREADING "gnu") - set(BLAS_mkl_OMP "gomp") else() set(BLAS_mkl_INTFACE "intel") set(BLAS_mkl_THREADING "intel") - set(BLAS_mkl_OMP "iomp5") endif() + + foreach(lang IN ITEMS C CXX Fortran) + if(CMAKE_${lang}_COMPILER_LOADED) + find_package(OpenMP COMPONENTS ${lang}) + if(${OpenMP_${lang}_FOUND}) + set(BLAS_mkl_OMP ${OpenMP_${lang}_LIBRARIES}) + break() + endif() + endif() + endforeach() + set(BLAS_mkl_LM "-lm") set(BLAS_mkl_LDL "-ldl") endif() @@ -403,7 +412,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version @@ -412,7 +421,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS @@ -468,7 +477,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All") # old version @@ -477,7 +486,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") # mkl >= 10.3 list(APPEND BLAS_SEARCH_LIBS - "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}") + "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP}") endif() if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All") list(APPEND BLAS_SEARCH_LIBS @@ -540,7 +549,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All") ${BLAS_mkl_SEARCH_SYMBOL} "" "${SEARCH_LIBS}" - "${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}" + "${BLAS_mkl_OMP};${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}" "${BLAS_mkl_MKLROOT}" "${BLAS_mkl_LIB_PATH_SUFFIXES}" ) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index e0b5dc2..d740db0 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 20) -set(CMake_VERSION_PATCH 20210502) +set(CMake_VERSION_PATCH 20210504) #set(CMake_VERSION_RC 0) set(CMake_VERSION_IS_DIRTY 0) diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx index bcacb15..4845a6d 100644 --- a/Source/cmForEachCommand.cxx +++ b/Source/cmForEachCommand.cxx @@ -17,6 +17,7 @@ #include <utility> #include <cm/memory> +#include <cm/optional> #include <cm/string_view> #include <cmext/string_view> @@ -25,7 +26,7 @@ #include "cmListFileCache.h" #include "cmMakefile.h" #include "cmMessageType.h" -#include "cmProperty.h" +#include "cmPolicies.h" #include "cmRange.h" #include "cmStringAlgorithms.h" #include "cmSystemTools.h" @@ -113,9 +114,11 @@ bool cmForEachFunctionBlocker::ReplayItems( // At end of for each execute recorded commands // store the old value - std::string oldDef; - if (cmProp d = mf.GetDefinition(this->Args.front())) { - oldDef = *d; + cm::optional<std::string> oldDef; + if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) { + oldDef = mf.GetSafeDefinition(this->Args.front()); + } else if (mf.IsNormalDefinitionSet(this->Args.front())) { + oldDef = *mf.GetDefinition(this->Args.front()); } auto restore = false; @@ -131,9 +134,14 @@ bool cmForEachFunctionBlocker::ReplayItems( } if (restore) { - // restore the variable to its prior value - mf.AddDefinition(this->Args.front(), oldDef); + if (oldDef) { + // restore the variable to its prior value + mf.AddDefinition(this->Args.front(), *oldDef); + } else { + mf.RemoveDefinition(this->Args.front()); + } } + return true; } @@ -185,10 +193,15 @@ bool cmForEachFunctionBlocker::ReplayZipLists( assert("Sanity check" && iterationVars.size() == values.size()); // Store old values for iteration variables - std::map<std::string, std::string> oldDefs; + std::map<std::string, cm::optional<std::string>> oldDefs; for (auto i = 0u; i < values.size(); ++i) { - if (cmProp d = mf.GetDefinition(iterationVars[i])) { - oldDefs.emplace(iterationVars[i], *d); + const auto& varName = iterationVars[i]; + if (mf.GetPolicyStatus(cmPolicies::CMP0124) != cmPolicies::NEW) { + oldDefs.emplace(varName, mf.GetSafeDefinition(varName)); + } else if (mf.IsNormalDefinitionSet(varName)) { + oldDefs.emplace(varName, *mf.GetDefinition(varName)); + } else { + oldDefs.emplace(varName, cm::nullopt); } } @@ -226,7 +239,11 @@ bool cmForEachFunctionBlocker::ReplayZipLists( // Restore the variables to its prior value if (restore) { for (auto const& p : oldDefs) { - mf.AddDefinition(p.first, p.second); + if (p.second) { + mf.AddDefinition(p.first, *p.second); + } else { + mf.RemoveDefinition(p.first); + } } } return true; diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index c2a6410..588f70b 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -410,7 +410,8 @@ void cmLocalNinjaGenerator::AppendCustomCommandDeps( } std::string cmLocalNinjaGenerator::WriteCommandScript( - std::vector<std::string> const& cmdLines, std::string const& customStep, + std::vector<std::string> const& cmdLines, std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep, cmGeneratorTarget const* target) const { std::string scriptPath; @@ -419,9 +420,13 @@ std::string cmLocalNinjaGenerator::WriteCommandScript( } else { scriptPath = cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles"); } + scriptPath += this->GetGlobalNinjaGenerator()->ConfigDirectory(outputConfig); cmSystemTools::MakeDirectory(scriptPath); scriptPath += '/'; scriptPath += customStep; + if (this->GlobalGenerator->IsMultiConfig()) { + scriptPath += cmStrCat('-', commandConfig); + } #ifdef _WIN32 scriptPath += ".bat"; #else @@ -464,7 +469,8 @@ std::string cmLocalNinjaGenerator::WriteCommandScript( } std::string cmLocalNinjaGenerator::BuildCommandLine( - std::vector<std::string> const& cmdLines, std::string const& customStep, + std::vector<std::string> const& cmdLines, std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep, cmGeneratorTarget const* target) const { // If we have no commands but we need to build a command anyway, use noop. @@ -483,8 +489,8 @@ std::string cmLocalNinjaGenerator::BuildCommandLine( cmdLinesTotal += cmd.length() + 6; } if (cmdLinesTotal > cmSystemTools::CalculateCommandLineLengthLimit() / 2) { - std::string const scriptPath = - this->WriteCommandScript(cmdLines, customStep, target); + std::string const scriptPath = this->WriteCommandScript( + cmdLines, outputConfig, commandConfig, customStep, target); std::string cmd #ifndef _WIN32 = "/bin/sh " @@ -697,7 +703,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } gg->WriteCustomCommandBuild( - this->BuildCommandLine(cmdLines, customStep), + this->BuildCommandLine(cmdLines, ccg.GetOutputConfig(), fileConfig, + customStep), this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], depfile, cc->GetJobPool(), cc->GetUsesTerminal(), /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, fileConfig, diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index 8b6824f..a73fa27 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -61,7 +61,8 @@ public: } std::string BuildCommandLine( - std::vector<std::string> const& cmdLines, + std::vector<std::string> const& cmdLines, std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep = std::string(), cmGeneratorTarget const* target = nullptr) const; @@ -119,6 +120,8 @@ private: std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg); std::string WriteCommandScript(std::vector<std::string> const& cmdLines, + std::string const& outputConfig, + std::string const& commandConfig, std::string const& customStep, cmGeneratorTarget const* target) const; diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 40a67a3..dba8560 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -2507,6 +2507,20 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const return def != nullptr; } +bool cmMakefile::IsNormalDefinitionSet(const std::string& name) const +{ + cmProp def = this->StateSnapshot.GetDefinition(name); +#ifndef CMAKE_BOOTSTRAP + if (cmVariableWatch* vv = this->GetVariableWatch()) { + if (!def) { + vv->VariableAccessed( + name, cmVariableWatch::UNKNOWN_VARIABLE_DEFINED_ACCESS, nullptr, this); + } + } +#endif + return def != nullptr; +} + cmProp cmMakefile::GetDefinition(const std::string& name) const { cmProp def = this->StateSnapshot.GetDefinition(name); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 71d765c..3c07808 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -486,6 +486,7 @@ public: const std::string& GetSafeDefinition(const std::string&) const; const std::string& GetRequiredDefinition(const std::string& name) const; bool IsDefinitionSet(const std::string&) const; + bool IsNormalDefinitionSet(const std::string&) const; bool GetDefExpandList(const std::string& name, std::vector<std::string>& out, bool emptyArgs = false) const; /** diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 1d511f2..1b514b8 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -287,7 +287,8 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule( // If there is no ranlib the command will be ":". Skip it. cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands()); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(linkCmds, config, config); // Write the linker rule with response file if needed. rule.Comment = @@ -310,7 +311,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( cmNinjaRule rule(this->LanguageLinkerCudaDeviceRule(config)); rule.Command = this->GetLocalGenerator()->BuildCommandLine( { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_DEVICE_LINKER"), - " -arch=$ARCH $REGISTER -o=$out $in") }); + " -arch=$ARCH $REGISTER -o=$out $in") }, + config, config); rule.Comment = "Rule for CUDA device linking."; rule.Description = "Linking CUDA $out"; this->GetGlobalGenerator()->AddRule(rule); @@ -336,7 +338,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( compileCmd, vars); rule.Name = this->LanguageLinkerCudaDeviceCompileRule(config); - rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd }); + rule.Command = this->GetLocalGenerator()->BuildCommandLine({ compileCmd }, + config, config); rule.Comment = "Rule for compiling CUDA device stubs."; rule.Description = "Compiling CUDA device stub $out"; this->GetGlobalGenerator()->AddRule(rule); @@ -345,7 +348,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules( rule.Command = this->GetLocalGenerator()->BuildCommandLine( { cmStrCat(mf->GetRequiredDefinition("CMAKE_CUDA_FATBINARY"), " -64 -cmdline=--compile-only -compress-all -link " - "--embedded-fatbin=$out $PROFILES") }); + "--embedded-fatbin=$out $PROFILES") }, + config, config); rule.Comment = "Rule for CUDA fatbinaries."; rule.Description = "Creating fatbinary $out"; this->GetGlobalGenerator()->AddRule(rule); @@ -475,7 +479,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, linkCmds.insert(linkCmds.begin(), "$PRE_LINK"); linkCmds.emplace_back("$POST_BUILD"); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(linkCmds, config, config); // Write the linker rule with response file if needed. rule.Comment = @@ -500,7 +505,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, std::vector<std::string> cmd; cmd.push_back(cmakeCommand + " -E cmake_symlink_executable $in $out"); cmd.emplace_back("$POST_BUILD"); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(cmd, config, config); } rule.Description = "Creating executable symlink $out"; rule.Comment = "Rule for creating executable symlink."; @@ -512,7 +518,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile, cmd.push_back(cmakeCommand + " -E cmake_symlink_library $in $SONAME $out"); cmd.emplace_back("$POST_BUILD"); - rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(cmd, config, config); } rule.Description = "Creating library symlink $out"; rule.Comment = "Rule for creating library symlink."; @@ -1312,10 +1319,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement( preLinkCmdLines.push_back("cd " + homeOutDir); } - vars["PRE_LINK"] = localGen.BuildCommandLine(preLinkCmdLines, "pre-link", - this->GeneratorTarget); - std::string postBuildCmdLine = localGen.BuildCommandLine( - postBuildCmdLines, "post-build", this->GeneratorTarget); + vars["PRE_LINK"] = localGen.BuildCommandLine( + preLinkCmdLines, config, fileConfig, "pre-link", this->GeneratorTarget); + std::string postBuildCmdLine = + localGen.BuildCommandLine(postBuildCmdLines, config, fileConfig, + "post-build", this->GeneratorTarget); cmNinjaVars symlinkVars; bool const symlinkNeeded = diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 2e0ffdb..f7777fc 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -539,7 +539,8 @@ cmNinjaRule GetScanRule( cmRulePlaceholderExpander::RuleVariables const& vars, const std::string& responseFlag, const std::string& flags, cmRulePlaceholderExpander* const rulePlaceholderExpander, - cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds) + cmLocalNinjaGenerator* generator, std::vector<std::string> scanCmds, + const std::string& outputConfig) { cmNinjaRule rule(ruleName); // Scanning always uses a depfile for preprocessor dependencies. @@ -580,7 +581,8 @@ cmNinjaRule GetScanRule( for (std::string& scanCmd : scanCmds) { rulePlaceholderExpander->ExpandRuleVariables(generator, scanCmd, scanVars); } - rule.Command = generator->BuildCommandLine(scanCmds); + rule.Command = + generator->BuildCommandLine(scanCmds, outputConfig, outputConfig); return rule; } @@ -672,7 +674,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, auto scanRule = GetScanRule( scanRuleName, vars, responseFlag, flags, rulePlaceholderExpander.get(), - this->GetLocalGenerator(), std::move(scanCommands)); + this->GetLocalGenerator(), std::move(scanCommands), config); scanRule.Comment = cmStrCat("Rule for generating ", lang, " dependencies."); @@ -702,7 +704,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, auto scanRule = GetScanRule( scanRuleName, vars, "", flags, rulePlaceholderExpander.get(), - this->GetLocalGenerator(), std::move(scanCommands)); + this->GetLocalGenerator(), std::move(scanCommands), config); // Write the rule for generating dependencies for the given language. scanRule.Comment = cmStrCat("Rule for generating ", lang, @@ -734,7 +736,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, ddModmapArg, " --dd=$out @", rule.RspFile); ddCmds.emplace_back(std::move(ccmd)); } - rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(ddCmds, config, config); } rule.Comment = cmStrCat("Rule to generate ninja dyndep files for ", lang, '.'); @@ -930,7 +933,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang, vars); } - rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds); + rule.Command = + this->GetLocalGenerator()->BuildCommandLine(compileCmds, config, config); // Write the rule for compiling file of the given language. rule.Comment = cmStrCat("Rule for compiling ", lang, " files."); @@ -1248,7 +1252,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( this->ExportObjectCompileCommand( language, sourceFileName, objectDir, objectFileName, objectFileDir, - vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]); + vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"], config); objBuild.Outputs.push_back(objectFileName); if (firstForConfig) { @@ -1619,7 +1623,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( std::string const& language, std::string const& sourceFileName, std::string const& objectDir, std::string const& objectFileName, std::string const& objectFileDir, std::string const& flags, - std::string const& defines, std::string const& includes) + std::string const& defines, std::string const& includes, + std::string const& outputConfig) { if (!this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS")) { return; @@ -1681,8 +1686,8 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( compileObjectVars); } - std::string cmdLine = - this->GetLocalGenerator()->BuildCommandLine(compileCmds); + std::string cmdLine = this->GetLocalGenerator()->BuildCommandLine( + compileCmds, outputConfig, outputConfig); this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName); } diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 79dc622..3a28cef 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -162,7 +162,8 @@ protected: std::string const& language, std::string const& sourceFileName, std::string const& objectDir, std::string const& objectFileName, std::string const& objectFileDir, std::string const& flags, - std::string const& defines, std::string const& includes); + std::string const& defines, std::string const& includes, + std::string const& outputConfig); void AdditionalCleanFiles(const std::string& config); diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 92c5b52..7a04c47 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -139,8 +139,8 @@ void cmNinjaUtilityTargetGenerator::WriteUtilBuildStatements( gg->WriteBuild(this->GetCommonFileStream(), phonyBuild); } } else { - std::string command = - lg->BuildCommandLine(commands, "utility", this->GeneratorTarget); + std::string command = lg->BuildCommandLine( + commands, config, fileConfig, "utility", this->GeneratorTarget); std::string desc; cmProp echoStr = genTarget->GetProperty("EchoString"); if (echoStr) { diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 0a5bb4b..0ff12d5 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -369,7 +369,10 @@ class cmMakefile; 21, 0, cmPolicies::WARN) \ SELECT(POLICY, CMP0123, \ "ARMClang cpu/arch compile and link flags must be set explicitly.", \ - 3, 21, 0, cmPolicies::WARN) + 3, 21, 0, cmPolicies::WARN) \ + SELECT(POLICY, CMP0124, \ + "foreach() loop variables are only available in the loop scope.", 3, \ + 21, 0, cmPolicies::WARN) #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1) #define CM_FOR_EACH_POLICY_ID(POLICY) \ diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 0255d60..cc1586d 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -5037,7 +5037,9 @@ std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink( { // For out of source files, we first check if a matching source group // for this file exists, otherwise we check if the path relative to current - // source- or binary-dir is used within the link and return that + // source- or binary-dir is used within the link and return that. + // In case of .cs files we can't do that automatically for files in the + // binary directory, because this leads to compilation errors. std::string link; std::string sourceGroupedFile; std::string const& fullFileName = source->GetFullPath(); @@ -5059,7 +5061,8 @@ std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink( link = sourceGroupedFile; } else if (cmHasPrefix(fullFileName, srcDir)) { link = fullFileName.substr(srcDir.length() + 1); - } else if (cmHasPrefix(fullFileName, binDir)) { + } else if (!cmHasSuffix(fullFileName, ".cs") && + cmHasPrefix(fullFileName, binDir)) { link = fullFileName.substr(binDir.length() + 1); } else if (cmProp l = source->GetProperty("VS_CSHARP_Link")) { link = *l; diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c index e1e7721..5ae846a 100644 --- a/Source/kwsys/ProcessUNIX.c +++ b/Source/kwsys/ProcessUNIX.c @@ -122,6 +122,10 @@ static inline void kwsysProcess_usleep(unsigned int msec) /* The maximum amount to read from a pipe at a time. */ #define KWSYSPE_PIPE_BUFFER_SIZE 1024 +#if defined(__NVCOMPILER) +# pragma diag_suppress 550 /* variable set but never used (in FD_ZERO) */ +#endif + /* Keep track of times using a signed representation. Switch to the native (possibly unsigned) representation only when calling native functions. */ diff --git a/Tests/RunCMake/NinjaMultiConfig/LongCommandLine-release-config-build-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine-release-config-build-stdout.txt new file mode 100644 index 0000000..628b6bc --- /dev/null +++ b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine-release-config-build-stdout.txt @@ -0,0 +1,2 @@ + +Post-build Debug Release \.*$ diff --git a/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake index 00aa896..de528be 100644 --- a/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/LongCommandLine.cmake @@ -14,3 +14,10 @@ add_custom_target( ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gen.txt" ) + +add_executable(exe main.c) + +add_custom_command( + TARGET exe POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "Post-build $<CONFIG> $<COMMAND_CONFIG:$<CONFIG>> ${very_long}" + ) diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake index aa42739..e7acbc2 100644 --- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake @@ -198,8 +198,11 @@ run_cmake_build(PostBuild release Release Exe) run_cmake_build(PostBuild debug-in-release-graph Release Exe:Debug) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/LongCommandLine-build) +set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") run_cmake_configure(LongCommandLine) +unset(RunCMake_TEST_OPTIONS) run_cmake_build(LongCommandLine release Release custom) +run_cmake_build(LongCommandLine release-config Release exe:Debug) set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build) set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all") diff --git a/Tests/RunCMake/ToolchainFile/LangVars-toolchain.cmake b/Tests/RunCMake/ToolchainFile/LangVars-toolchain.cmake new file mode 100644 index 0000000..be07dc3 --- /dev/null +++ b/Tests/RunCMake/ToolchainFile/LangVars-toolchain.cmake @@ -0,0 +1,2 @@ +set(C 1) +set(CXX 1) diff --git a/Tests/RunCMake/ToolchainFile/LangVars.cmake b/Tests/RunCMake/ToolchainFile/LangVars.cmake new file mode 100644 index 0000000..169e639 --- /dev/null +++ b/Tests/RunCMake/ToolchainFile/LangVars.cmake @@ -0,0 +1,7 @@ +foreach(test_language C CXX) + enable_language(${test_language}) + if(DEFINED CMAKE_${test_language}_STANDARD_DEFAULT + AND NOT CMAKE_${test_language}_COMPILE_FEATURES) + message(FATAL_ERROR "Compile features not found for ${test_language}") + endif() +endforeach() diff --git a/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake b/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake index 659523c..304c105 100644 --- a/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake +++ b/Tests/RunCMake/ToolchainFile/RunCMakeTest.cmake @@ -9,6 +9,7 @@ run_cmake_toolchain(CallEnableLanguage) run_cmake_toolchain(CallProject) run_cmake_toolchain(CheckLanguage) run_cmake_toolchain(FlagsInit) +run_cmake_toolchain(LangVars) run_cmake_toolchain(LinkFlagsInit) function(run_IncludeDirectories) diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/cmake/AssemblyInfo.cs.in b/Tests/RunCMake/VS10Project/CSharpSourceGroup/cmake/AssemblyInfo.cs.in new file mode 100644 index 0000000..63e5a5c --- /dev/null +++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/cmake/AssemblyInfo.cs.in @@ -0,0 +1,18 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows; + +//General Information about an assembly is controlled through the following +//set of attributes. Change these attribute values to modify the information +//associated with an assembly. + +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake index 80d76e4..9c9409c 100644 --- a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake @@ -13,6 +13,7 @@ set(SOURCE_GROUPS_TO_FIND "CSharpSourceGroup\\\\nested\\\\baz\\.cs" "CSharpSourceGroup\\\\images\\\\empty\\.bmp" "VsCsharpSourceGroup\\.png" + "AssemblyInfo\\.cs" ) foreach(GROUP_NAME IN LISTS SOURCE_GROUPS_TO_FIND) diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake index 510d712..b67868f 100644 --- a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake +++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake @@ -20,3 +20,11 @@ add_library(VsCsharpSourceGroup SHARED ${SRC_FILES} ${IMAGE_FILES} ${RESOURCE_FI source_group("CSharpSourceGroup" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs) source_group("CSharpSourceGroup/nested" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs) source_group("Images" FILES ${IMAGE_FILES}) + +# Test covering CMake Issue 22104. +# Basically there should not be any link tags for files in the binary directory. +include(CSharpUtilities) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/cmake/AssemblyInfo.cs.in" "Properties/AssemblyInfo.cs") + +target_sources(VsCsharpSourceGroup PRIVATE "Properties/AssemblyInfo.cs") +csharp_set_designer_cs_properties("Properties/AssemblyInfo.cs") diff --git a/Tests/RunCMake/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake index d3f7c23..15ca477 100644 --- a/Tests/RunCMake/foreach/RunCMakeTest.cmake +++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake @@ -20,3 +20,5 @@ run_cmake(foreach-RANGE-non-int-test-3-2) run_cmake(foreach-RANGE-non-int-test-3-3) run_cmake(foreach-RANGE-invalid-test) run_cmake(foreach-RANGE-out-of-range-test) +run_cmake(foreach-var-scope-CMP0124-OLD) +run_cmake(foreach-var-scope-CMP0124-NEW) diff --git a/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-NEW.cmake b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-NEW.cmake new file mode 100644 index 0000000..7e2eee0 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-NEW.cmake @@ -0,0 +1,51 @@ + +cmake_policy(SET CMP0124 NEW) + +foreach(VAR a b c) +endforeach() +if (DEFINED VAR) + message(SEND_ERROR "Variable 'VAR' unexpectedly defined.") +endif() + +set(LIST1 a b c) +set(LIST2 x y z) +foreach(VAR1_1 VAR1_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (DEFINED VAR1_1 OR DEFINED VAR1_2) + message(SEND_ERROR "Variables 'VAR1_1' or 'VAR1_2' unexpectedly defined.") +endif() + + +set (VAR2 OLD) +foreach(VAR2 a b c) +endforeach() +if (NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR2' not defined or wrong value.") +endif() + +set (VAR2_2 OLD) +foreach(VAR2_1 VAR2_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (DEFINED VAR2_1 OR NOT DEFINED VAR2_2) + message(SEND_ERROR "Variable 'VAR2_1' unexpectedly defined or variable 'VAR2_2' not defined.") +endif() + + +set (VAR3 OLD CACHE STRING "") +foreach(VAR3 a b c) +endforeach() +# check that only cache variable is defined +set(OLD_VALUE "${VAR3}") +unset(VAR3 CACHE) +if (DEFINED VAR3 OR NOT OLD_VALUE STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR3' wrongly defined or wrong value.") +endif() + +set (VAR3_2 OLD CACHE STRING "") +foreach(VAR3_1 VAR3_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +set(OLD_VALUE "${VAR3_2}") +unset(VAR3_2 CACHE) +if (DEFINED VAR3_1 OR DEFINED VAR3_2 OR NOT OLD_VALUE STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR3_1' unexpectedly defined or variable 'VAR2_2' wrongly defined or wrong value.") +endif() diff --git a/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD.cmake b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD.cmake new file mode 100644 index 0000000..f955982 --- /dev/null +++ b/Tests/RunCMake/foreach/foreach-var-scope-CMP0124-OLD.cmake @@ -0,0 +1,53 @@ + +cmake_policy(SET CMP0124 OLD) + +foreach(VAR a b c) +endforeach() +if (NOT DEFINED VAR OR NOT VAR STREQUAL "") + message(SEND_ERROR "Variable 'VAR' not defined or wrong value.") +endif() + +set(LIST1 a b c) +set(LIST2 x y z) +foreach(VAR1_1 VAR1_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (NOT DEFINED VAR1_1 OR NOT VAR1_1 STREQUAL "" + OR NOT DEFINED VAR1_2 OR NOT VAR1_2 STREQUAL "") + message(SEND_ERROR "Variables 'VAR1_1' or 'VAR1_2' not defined or wrong value.") +endif() + + +set (VAR2 OLD) +foreach(VAR2 a b c) +endforeach() +if (NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR2' not defined or wrong value.") +endif() + +set (VAR2_2 OLD) +foreach(VAR2_1 VAR2_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +if (NOT DEFINED VAR2_1 OR NOT VAR2_1 STREQUAL "" + OR NOT DEFINED VAR2_2 OR NOT VAR2_2 STREQUAL "OLD") + message(SEND_ERROR "Variables 'VAR2_1' or 'VAR2_2' not defined or wrong value.") +endif() + + +set (VAR3 OLD CACHE STRING "") +foreach(VAR3 a b c) +endforeach() +# a normal variable is defined, holding cache variable value +unset(VAR3 CACHE) +if (NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "OLD") + message(SEND_ERROR "Variable 'VAR3' not defined or wrong value.") +endif() + +set (VAR3_2 OLD CACHE STRING "") +foreach(VAR3_1 VAR3_2 IN ZIP_LISTS LIST1 LIST2) +endforeach() +# a normal variable is defined, holding cache variable value +unset(VAR3_2 CACHE) +if (NOT DEFINED VAR3_1 OR NOT VAR3_1 STREQUAL "" + OR NOT DEFINED VAR3_2 OR NOT VAR3_2 STREQUAL "OLD") + message(SEND_ERROR "Variables 'VAR3_1' or 'VAR3_2' not defined or wrong value.") +endif() |