From 6a1010349355354e27015a004f5620b77993b91c Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Fri, 21 Jan 2022 17:41:44 +0100 Subject: [PATCH 1/4] Help: Update preset schema description for version 3 entries. --- Help/manual/presets/schema.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json index 327291d0bc..3844611363 100644 --- a/Help/manual/presets/schema.json +++ b/Help/manual/presets/schema.json @@ -429,7 +429,7 @@ }, "buildPresetsItemsV3": { "type": "array", - "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 3 and higher.", "items": { "type": "object", "properties": { @@ -560,7 +560,7 @@ }, "buildPresetsV3": { "type": "array", - "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 2 and higher.", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 3 and higher.", "allOf": [ { "$ref": "#/definitions/buildPresetsItemsV3" }, { "$ref": "#/definitions/buildPresetsItemsV2" } @@ -624,7 +624,7 @@ }, "testPresetsItemsV3": { "type": "array", - "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", + "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 3 and higher.", "items": { "type": "object", "properties": { @@ -949,7 +949,7 @@ }, "testPresetsV3": { "type": "array", - "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 2 and higher.", + "description": "An optional array of test preset objects. Used to specify arguments to ctest. Available in version 3 and higher.", "allOf": [ { "$ref": "#/definitions/testPresetsItemsV2" }, { "$ref": "#/definitions/testPresetsItemsV3" } From 193b8fca52b5665387dbc7f3199981d9e6cd4b79 Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Fri, 21 Jan 2022 17:43:17 +0100 Subject: [PATCH 2/4] cmBuildOptions: Split build arguments into separate object. --- Source/CMakeLists.txt | 1 + Source/CTest/cmCTestBuildAndTestHandler.cxx | 5 ++++- Source/cmBuildOptions.h | 21 ++++++++++++++++++++ Source/cmGlobalBorlandMakefileGenerator.cxx | 7 ++++--- Source/cmGlobalBorlandMakefileGenerator.h | 3 ++- Source/cmGlobalGenerator.cxx | 22 ++++++++++++--------- Source/cmGlobalGenerator.h | 8 +++++--- Source/cmGlobalGhsMultiGenerator.cxx | 3 ++- Source/cmGlobalGhsMultiGenerator.h | 4 +++- Source/cmGlobalJOMMakefileGenerator.cxx | 7 ++++--- Source/cmGlobalJOMMakefileGenerator.h | 3 ++- Source/cmGlobalNMakeMakefileGenerator.cxx | 7 ++++--- Source/cmGlobalNMakeMakefileGenerator.h | 3 ++- Source/cmGlobalNinjaGenerator.cxx | 2 +- Source/cmGlobalNinjaGenerator.h | 4 +++- Source/cmGlobalUnixMakefileGenerator3.cxx | 4 ++-- Source/cmGlobalUnixMakefileGenerator3.h | 4 +++- Source/cmGlobalVisualStudio10Generator.cxx | 10 ++++++---- Source/cmGlobalVisualStudio10Generator.h | 3 ++- Source/cmGlobalVisualStudio7Generator.cxx | 2 +- Source/cmGlobalVisualStudio7Generator.h | 3 ++- Source/cmGlobalWatcomWMakeGenerator.cxx | 7 ++++--- Source/cmGlobalWatcomWMakeGenerator.h | 4 +++- Source/cmGlobalXCodeGenerator.cxx | 2 +- Source/cmGlobalXCodeGenerator.h | 3 ++- Source/cmake.cxx | 11 ++++++----- Source/cmake.h | 5 +++-- Source/cmakemain.cxx | 4 +++- 28 files changed, 109 insertions(+), 53 deletions(-) create mode 100644 Source/cmBuildOptions.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index b31b8dcaa6..ddcdd7e90e 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -155,6 +155,7 @@ set(SRCS cmBinUtilsWindowsPELinker.h cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.cxx cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h + cmBuildOptions.h cmCacheManager.cxx cmCacheManager.h cmCLocaleEnvironmentScope.h diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index adfc8ef774..9b5e31972f 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -9,6 +9,7 @@ #include "cmsys/Process.h" +#include "cmBuildOptions.h" #include "cmCTest.h" #include "cmCTestTestHandler.h" #include "cmGlobalGenerator.h" @@ -263,10 +264,12 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) if (!config) { config = "Debug"; } + + cmBuildOptions buildOptions(!this->BuildNoClean, false); int retVal = cm.GetGlobalGenerator()->Build( cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir, this->BuildProject, { tar }, output, this->BuildMakeProgram, config, - !this->BuildNoClean, false, false, remainingTime); + buildOptions, false, remainingTime); out << output; // if the build failed then return if (retVal) { diff --git a/Source/cmBuildOptions.h b/Source/cmBuildOptions.h new file mode 100644 index 0000000000..ed26703d58 --- /dev/null +++ b/Source/cmBuildOptions.h @@ -0,0 +1,21 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#pragma once + +#include "cmConfigure.h" // IWYU pragma: keep + +struct cmBuildOptions +{ +public: + cmBuildOptions() noexcept = default; + explicit cmBuildOptions(bool clean, bool fast) noexcept + : Clean(clean) + , Fast(fast) + { + } + explicit cmBuildOptions(const cmBuildOptions&) noexcept = default; + cmBuildOptions& operator=(const cmBuildOptions&) noexcept = default; + + bool Clean = false; + bool Fast = false; +}; diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 5503619144..776ee406c5 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -71,12 +71,13 @@ std::vector cmGlobalBorlandMakefileGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int /*jobs*/, bool verbose, + const std::string& config, int /*jobs*/, bool verbose, + const cmBuildOptions& buildOptions, std::vector const& makeOptions) { return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, - cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); + makeProgram, projectName, projectDir, targetNames, config, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, makeOptions); } void cmGlobalBorlandMakefileGenerator::PrintBuildCommandAdvice( diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h index 646dfffa89..a280b8123e 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.h +++ b/Source/cmGlobalBorlandMakefileGenerator.h @@ -59,7 +59,8 @@ protected: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 6433681632..8559abab3c 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1994,16 +1994,19 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, } std::string config = mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); + cmBuildOptions defaultBuildOptions(false, fast); + return this->Build(jobs, srcdir, bindir, projectName, newTarget, output, "", - config, false, fast, false, this->TryCompileTimeout); + config, defaultBuildOptions, false, + this->TryCompileTimeout); } std::vector cmGlobalGenerator::GenerateBuildCommand( const std::string& /*unused*/, const std::string& /*unused*/, const std::string& /*unused*/, std::vector const& /*unused*/, - const std::string& /*unused*/, bool /*unused*/, int /*unused*/, - bool /*unused*/, std::vector const& /*unused*/) + const std::string& /*unused*/, int /*unused*/, bool /*unused*/, + const cmBuildOptions& /*unused*/, std::vector const& /*unused*/) { GeneratedMakeCommand makeCommand; makeCommand.Add("cmGlobalGenerator::GenerateBuildCommand not implemented"); @@ -2021,7 +2024,7 @@ int cmGlobalGenerator::Build( int jobs, const std::string& /*unused*/, const std::string& bindir, const std::string& projectName, const std::vector& targets, std::string& output, const std::string& makeCommandCSTR, - const std::string& config, bool clean, bool fast, bool verbose, + const std::string& config, const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout, cmSystemTools::OutputOption outputflag, std::vector const& nativeOptions) { @@ -2053,9 +2056,9 @@ int cmGlobalGenerator::Build( std::string outputBuffer; std::string* outputPtr = &outputBuffer; - std::vector makeCommand = - this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, targets, - realConfig, fast, jobs, verbose, nativeOptions); + std::vector makeCommand = this->GenerateBuildCommand( + makeCommandCSTR, projectName, bindir, targets, realConfig, jobs, verbose, + buildOptions, nativeOptions); // Workaround to convince some commands to produce output. if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH && @@ -2064,10 +2067,11 @@ int cmGlobalGenerator::Build( } // should we do a clean first? - if (clean) { + if (buildOptions.Clean) { std::vector cleanCommand = this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, - { "clean" }, realConfig, fast, jobs, verbose); + { "clean" }, realConfig, jobs, verbose, + buildOptions); output += "\nRun Clean Command:"; output += cleanCommand.front().Printable(); output += "\n"; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 2406798af4..a43d4a63b0 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -20,6 +20,7 @@ #include "cm_codecvt.hxx" +#include "cmBuildOptions.h" #include "cmCustomCommandLines.h" #include "cmDuration.h" #include "cmExportSet.h" @@ -229,8 +230,8 @@ public: int jobs, const std::string& srcdir, const std::string& bindir, const std::string& projectName, std::vector const& targetNames, std::string& output, - const std::string& makeProgram, const std::string& config, bool clean, - bool fast, bool verbose, cmDuration timeout, + const std::string& makeProgram, const std::string& config, + const cmBuildOptions& buildOptions, bool verbose, cmDuration timeout, cmSystemTools::OutputOption outputflag = cmSystemTools::OUTPUT_NONE, std::vector const& nativeOptions = std::vector()); @@ -248,7 +249,8 @@ public: virtual std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()); virtual void PrintBuildCommandAdvice(std::ostream& os, int jobs) const; diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index bf537b738a..5e51dd2f7d 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -510,7 +510,8 @@ std::vector cmGlobalGhsMultiGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& /*config*/, bool /*fast*/, int jobs, bool /*verbose*/, + const std::string& /*config*/, int jobs, bool /*verbose*/, + const cmBuildOptions& /*buildOptions*/, std::vector const& makeOptions) { GeneratedMakeCommand makeCommand = {}; diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 9076e0e319..26ea3c70e6 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -9,6 +9,7 @@ #include #include +#include "cmBuildOptions.h" #include "cmGlobalGenerator.h" #include "cmGlobalGeneratorFactory.h" #include "cmTargetDepend.h" @@ -87,7 +88,8 @@ protected: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx index 1b406a6969..1a625cc686 100644 --- a/Source/cmGlobalJOMMakefileGenerator.cxx +++ b/Source/cmGlobalJOMMakefileGenerator.cxx @@ -63,7 +63,8 @@ std::vector cmGlobalJOMMakefileGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions, std::vector const& makeOptions) { std::vector jomMakeOptions; @@ -81,6 +82,6 @@ cmGlobalJOMMakefileGenerator::GenerateBuildCommand( } return cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, jobs, - verbose, jomMakeOptions); + makeProgram, projectName, projectDir, targetNames, config, jobs, verbose, + buildOptions, jomMakeOptions); } diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h index 822974589b..332d1cf055 100644 --- a/Source/cmGlobalJOMMakefileGenerator.h +++ b/Source/cmGlobalJOMMakefileGenerator.h @@ -52,7 +52,8 @@ protected: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx index 9f3d30eeb2..55748cfa60 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.cxx +++ b/Source/cmGlobalNMakeMakefileGenerator.cxx @@ -106,7 +106,8 @@ std::vector cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int /*jobs*/, bool verbose, + const std::string& config, int /*jobs*/, bool verbose, + const cmBuildOptions& buildOptions, std::vector const& makeOptions) { std::vector nmakeMakeOptions; @@ -117,8 +118,8 @@ cmGlobalNMakeMakefileGenerator::GenerateBuildCommand( cm::append(nmakeMakeOptions, makeOptions); return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, - cmake::NO_BUILD_PARALLEL_LEVEL, verbose, nmakeMakeOptions); + makeProgram, projectName, projectDir, targetNames, config, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, nmakeMakeOptions); } void cmGlobalNMakeMakefileGenerator::PrintBuildCommandAdvice(std::ostream& os, diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h index ca5b8d61b4..b3574ebf58 100644 --- a/Source/cmGlobalNMakeMakefileGenerator.h +++ b/Source/cmGlobalNMakeMakefileGenerator.h @@ -58,7 +58,8 @@ protected: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 19c4ee3a21..5b85179ccb 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -955,7 +955,7 @@ cmGlobalNinjaGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, std::vector const& targetNames, const std::string& config, - bool /*fast*/, int jobs, bool verbose, + int jobs, bool verbose, const cmBuildOptions& /*buildOptions*/, std::vector const& makeOptions) { GeneratedMakeCommand makeCommand; diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 84fc06c1cd..c619b2eb27 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -18,6 +18,7 @@ #include "cm_codecvt.hxx" +#include "cmBuildOptions.h" #include "cmGeneratedFileStream.h" #include "cmGlobalCommonGenerator.h" #include "cmGlobalGeneratorFactory.h" @@ -199,7 +200,8 @@ public: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 0556540913..ab9ca5055e 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -518,7 +518,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( const std::string& makeProgram, const std::string& /*projectName*/, const std::string& /*projectDir*/, std::vector const& targetNames, const std::string& /*config*/, - bool fast, int jobs, bool verbose, + int jobs, bool verbose, const cmBuildOptions& buildOptions, std::vector const& makeOptions) { GeneratedMakeCommand makeCommand; @@ -548,7 +548,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( makeCommand.Add(makeOptions.begin(), makeOptions.end()); for (auto tname : targetNames) { if (!tname.empty()) { - if (fast) { + if (buildOptions.Fast) { tname += "/fast"; } cmSystemTools::ConvertToOutputSlashes(tname); diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 94ee47633b..5157826c56 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -12,6 +12,7 @@ #include #include +#include "cmBuildOptions.h" #include "cmGeneratorTarget.h" #include "cmGlobalCommonGenerator.h" #include "cmGlobalGeneratorFactory.h" @@ -163,7 +164,8 @@ public: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index d7bc05d64a..5634defc90 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -1099,7 +1099,8 @@ std::vector cmGlobalVisualStudio10Generator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions, std::vector const& makeOptions) { std::vector makeCommands; @@ -1145,8 +1146,8 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( if (useDevEnv) { // Use devenv to build solutions containing Intel Fortran projects. return cmGlobalVisualStudio7Generator::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, jobs, - verbose, makeOptions); + makeProgram, projectName, projectDir, targetNames, config, jobs, verbose, + buildOptions, makeOptions); } std::vector realTargetNames = targetNames; @@ -1178,8 +1179,9 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( cmSystemTools::ConvertToUnixSlashes(targetProject); } } - makeCommand.Add(std::move(targetProject)); + makeCommand.Add(targetProject); } + std::string configArg = "/p:Configuration="; if (!config.empty()) { configArg += config; diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index c8fd14975a..aea999db39 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -43,7 +43,8 @@ public: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index c72b10957d..91012dda49 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -212,7 +212,7 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, std::vector const& targetNames, const std::string& config, - bool /*fast*/, int /*jobs*/, bool /*verbose*/, + int /*jobs*/, bool /*verbose*/, const cmBuildOptions& /*buildOptions*/, std::vector const& makeOptions) { // Select the caller- or user-preferred make program, else devenv. diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index d1fb8040c7..33f1063092 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -69,7 +69,8 @@ public: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx index 3e2d92df73..fb2a8b6a6e 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.cxx +++ b/Source/cmGlobalWatcomWMakeGenerator.cxx @@ -65,12 +65,13 @@ std::vector cmGlobalWatcomWMakeGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int /*jobs*/, bool verbose, + const std::string& config, int /*jobs*/, bool verbose, + const cmBuildOptions& buildOptions, std::vector const& makeOptions) { return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand( - makeProgram, projectName, projectDir, targetNames, config, fast, - cmake::NO_BUILD_PARALLEL_LEVEL, verbose, makeOptions); + makeProgram, projectName, projectDir, targetNames, config, + cmake::NO_BUILD_PARALLEL_LEVEL, verbose, buildOptions, makeOptions); } void cmGlobalWatcomWMakeGenerator::PrintBuildCommandAdvice(std::ostream& os, diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h index da39d3f5db..eb939341d7 100644 --- a/Source/cmGlobalWatcomWMakeGenerator.h +++ b/Source/cmGlobalWatcomWMakeGenerator.h @@ -9,6 +9,7 @@ #include #include +#include "cmBuildOptions.h" #include "cmGlobalGeneratorFactory.h" #include "cmGlobalUnixMakefileGenerator3.h" @@ -57,7 +58,8 @@ protected: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index bc2a6f77d1..203addd247 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -478,7 +478,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& /*projectDir*/, std::vector const& targetNames, const std::string& config, - bool /*fast*/, int jobs, bool /*verbose*/, + int jobs, bool /*verbose*/, const cmBuildOptions& /*buildOptions*/, std::vector const& makeOptions) { GeneratedMakeCommand makeCommand; diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h index 5917db3135..ff6ffe8898 100644 --- a/Source/cmGlobalXCodeGenerator.h +++ b/Source/cmGlobalXCodeGenerator.h @@ -80,7 +80,8 @@ public: std::vector GenerateBuildCommand( const std::string& makeProgram, const std::string& projectName, const std::string& projectDir, std::vector const& targetNames, - const std::string& config, bool fast, int jobs, bool verbose, + const std::string& config, int jobs, bool verbose, + const cmBuildOptions& buildOptions = cmBuildOptions(), std::vector const& makeOptions = std::vector()) override; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index c708eb2059..2361ce2e14 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -28,6 +28,7 @@ #include "cm_sys_stat.h" +#include "cmBuildOptions.h" #include "cmCMakePath.h" #include "cmCMakePresetsGraph.h" #include "cmCommandLineArgument.h" @@ -3219,8 +3220,8 @@ std::vector cmake::GetDebugConfigs() int cmake::Build(int jobs, std::string dir, std::vector targets, std::string config, std::vector nativeOptions, - bool clean, bool verbose, const std::string& presetName, - bool listPresets) + cmBuildOptions& buildOptions, bool verbose, + const std::string& presetName, bool listPresets) { this->SetHomeDirectory(""); this->SetHomeOutputDirectory(""); @@ -3326,8 +3327,8 @@ int cmake::Build(int jobs, std::string dir, std::vector targets, config = expandedPreset->Configuration; } - if (!clean && expandedPreset->CleanFirst) { - clean = *expandedPreset->CleanFirst; + if (!buildOptions.Clean && expandedPreset->CleanFirst) { + buildOptions.Clean = *expandedPreset->CleanFirst; } if (!verbose && expandedPreset->Verbose) { @@ -3466,7 +3467,7 @@ int cmake::Build(int jobs, std::string dir, std::vector targets, this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs); return this->GlobalGenerator->Build( - jobs, "", dir, projName, targets, output, "", config, clean, false, + jobs, "", dir, projName, targets, output, "", config, buildOptions, verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions); } diff --git a/Source/cmake.h b/Source/cmake.h index b13cc963e8..bfa10acd3a 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -45,6 +45,7 @@ class cmMakefileProfilingData; #endif class cmMessenger; class cmVariableWatch; +struct cmBuildOptions; struct cmDocumentationEntry; /** \brief Represents a cmake invocation. @@ -587,8 +588,8 @@ public: //! run the --build option int Build(int jobs, std::string dir, std::vector targets, std::string config, std::vector nativeOptions, - bool clean, bool verbose, const std::string& presetName, - bool listPresets); + cmBuildOptions& buildOptions, bool verbose, + const std::string& presetName, bool listPresets); //! run the --open option bool Open(const std::string& dir, bool dryRun); diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 00aafdc2cf..0f128ce8f5 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -19,6 +20,7 @@ #include +#include "cmBuildOptions.h" #include "cmCommandLineArgument.h" #include "cmConsoleBuf.h" #include "cmDocumentationEntry.h" // IWYU pragma: keep @@ -657,7 +659,7 @@ int do_build(int ac, char const* const* av) }); return cm.Build(jobs, std::move(dir), std::move(targets), std::move(config), - std::move(nativeOptions), cleanFirst, verbose, presetName, + std::move(nativeOptions), buildOptions, verbose, presetName, listPresets); #endif } From b2f8f0bb87b3b49a39d1db4333bffc5405166245 Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Sat, 22 Jan 2022 10:29:46 +0100 Subject: [PATCH 3/4] cmGlobalVisualStudio10Generator: Auto restore NuGet packages. --- Help/manual/cmake-variables.7.rst | 1 + Help/manual/cmake.1.rst | 11 +++ Help/release/dev/vs-package-restore.rst | 10 +++ .../CMAKE_VS_NUGET_PACKAGE_RESTORE.rst | 22 ++++++ Source/CTest/cmCTestBuildAndTestHandler.cxx | 3 +- Source/cmBuildOptions.h | 25 ++++++- Source/cmGeneratorTarget.cxx | 20 +++++ Source/cmGeneratorTarget.h | 3 + Source/cmGlobalGenerator.cxx | 2 +- Source/cmGlobalVisualStudio10Generator.cxx | 69 ++++++++++++++++++ Source/cmGlobalVisualStudio10Generator.h | 2 + Source/cmVisualStudio10TargetGenerator.cxx | 40 ++++++++-- Source/cmVisualStudio10TargetGenerator.h | 1 + Source/cmakemain.cxx | 23 ++++++ Tests/RunCMake/CMakeLists.txt | 1 + ...ild-invalid-package-resolve-arg-result.txt | 1 + ...ild-invalid-package-resolve-arg-stderr.txt | 1 + .../VsNugetPackageRestore/CMakeLists.txt | 3 + .../Package/CMakeLists.txt | 17 +++++ .../VsNugetPackageRestore/Package/Library.cs | 9 +++ .../RunCMake/VsNugetPackageRestore/Program.cs | 14 ++++ .../NuGetTestProject/1.0.0/.nupkg.metadata | 5 ++ .../1.0.0/nugettestproject.1.0.0.nupkg | Bin 0 -> 5664 bytes .../1.0.0/nugettestproject.1.0.0.nupkg.sha512 | 1 + .../1.0.0/nugettestproject.nuspec | 11 +++ .../VsNugetPackageRestore/RunCMakeTest.cmake | 12 +++ .../VsNugetPackageRestore.cmake | 9 +++ .../VsNugetPackageRestore/nuget.config.in | 7 ++ .../vs-nuget-package-restore-off-result.txt | 1 + .../vs-nuget-package-restore-off-stderr.txt | 1 + .../vs-nuget-package-restore-wrong-result.txt | 1 + .../vs-nuget-package-restore-wrong-stderr.txt | 1 + 32 files changed, 319 insertions(+), 8 deletions(-) create mode 100644 Help/release/dev/vs-package-restore.rst create mode 100644 Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst create mode 100644 Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt create mode 100644 Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt create mode 100644 Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt create mode 100644 Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt create mode 100644 Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs create mode 100644 Tests/RunCMake/VsNugetPackageRestore/Program.cs create mode 100644 Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata create mode 100644 Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg create mode 100644 Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha512 create mode 100644 Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec create mode 100644 Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake create mode 100644 Tests/RunCMake/VsNugetPackageRestore/nuget.config.in create mode 100644 Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt create mode 100644 Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt create mode 100644 Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt create mode 100644 Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 51b092f5df..8c43c22531 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -119,6 +119,7 @@ Variables that Provide Information /variable/CMAKE_VS_DEVENV_COMMAND /variable/CMAKE_VS_MSBUILD_COMMAND /variable/CMAKE_VS_NsightTegra_VERSION + /variable/CMAKE_VS_NUGET_PACKAGE_RESTORE /variable/CMAKE_VS_PLATFORM_NAME /variable/CMAKE_VS_PLATFORM_NAME_DEFAULT /variable/CMAKE_VS_PLATFORM_TOOLSET diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 04e2eda447..1d638b942b 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -463,6 +463,17 @@ following options: Build target ``clean`` first, then build. (To clean only, use ``--target clean``.) +``--resolve-package-references=`` + .. versionadded:: 3.23 + + Resolve remote package references (e.g. NuGet packages) before build. + When set to ``on`` (default), packages will be restored before building a + target. When set to ``only``, the packages will be restored, but no build + will be performed. When set to ``off``, no packages will be restored. + + If the target does not define any package references, this option does + nothing. + ``--use-stderr`` Ignored. Behavior is default in CMake >= 3.0. diff --git a/Help/release/dev/vs-package-restore.rst b/Help/release/dev/vs-package-restore.rst new file mode 100644 index 0000000000..697778ffe4 --- /dev/null +++ b/Help/release/dev/vs-package-restore.rst @@ -0,0 +1,10 @@ +vs-package-restore +------------------ + +* Targets with :prop_tgt:`VS_PACKAGE_REFERENCES` will now automatically attempt + to restore the package references from NuGet. The cache variable + :variable:`CMAKE_VS_NUGET_PACKAGE_RESTORE` was added to toggle automatic + package restore off. + +* :manual:`cmake(1)` gained the ``--resolve-package-references=`` + command-line option to control automatic package restoration. diff --git a/Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst b/Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst new file mode 100644 index 0000000000..716072630a --- /dev/null +++ b/Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst @@ -0,0 +1,22 @@ +CMAKE_VS_NUGET_PACKAGE_RESTORE +------------------------------ + +.. versionadded:: 3.23 + +When using a Visual Studio generator, this cache variable controls +if msbuild should automatically attempt to restore NuGet packages +prior to a build. NuGet packages can be defined using the +:prop_tgt:`VS_PACKAGE_REFERENCES` property on a target. If no +package references are defined, this setting will do nothing. + +The command line option ``--resolve-package-references`` can be used +alternatively to control the resolve behavior globally. This option +will take precedence over the cache variable. + +Targets that use the :prop_tgt:`DOTNET_SDK` are required to run a +restore before building. Disabling this option may cause the build +to fail in such projects. + +This setting is stored as a cache entry. Default value is ``ON``. + +See also the :prop_tgt:`VS_PACKAGE_REFERENCES` property. diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx index 9b5e31972f..e09b4dd40a 100644 --- a/Source/CTest/cmCTestBuildAndTestHandler.cxx +++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx @@ -265,7 +265,8 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring) config = "Debug"; } - cmBuildOptions buildOptions(!this->BuildNoClean, false); + cmBuildOptions buildOptions(!this->BuildNoClean, false, + PackageResolveMode::Disable); int retVal = cm.GetGlobalGenerator()->Build( cmake::NO_BUILD_PARALLEL_LEVEL, this->SourceDir, this->BinaryDir, this->BuildProject, { tar }, output, this->BuildMakeProgram, config, diff --git a/Source/cmBuildOptions.h b/Source/cmBuildOptions.h index ed26703d58..58baeef759 100644 --- a/Source/cmBuildOptions.h +++ b/Source/cmBuildOptions.h @@ -4,13 +4,35 @@ #include "cmConfigure.h" // IWYU pragma: keep +/** \brief Defines how to resolve packages **/ +enum class PackageResolveMode +{ + /** \brief Defines behavior based on cache variable (e.g. + CMAKE_VS_NUGET_PACKAGE_RESTORE). This is the default. **/ + FromCacheVariable, + + /** \brief Ignore behavior defined by cache variable and forces packages to + be resolved prior to build. **/ + Force, + + /** \brief Ignore behavior defined by cache variable and forces packages to + be resolved, but skip the actual build. **/ + OnlyResolve, + + /** \brief Ignore behavior defined by cache variable and dont resolve any + packages **/ + Disable +}; + struct cmBuildOptions { public: cmBuildOptions() noexcept = default; - explicit cmBuildOptions(bool clean, bool fast) noexcept + explicit cmBuildOptions(bool clean, bool fast, + PackageResolveMode resolveMode) noexcept : Clean(clean) , Fast(fast) + , ResolveMode(resolveMode) { } explicit cmBuildOptions(const cmBuildOptions&) noexcept = default; @@ -18,4 +40,5 @@ public: bool Clean = false; bool Fast = false; + PackageResolveMode ResolveMode = PackageResolveMode::FromCacheVariable; }; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 421e13671a..45e3b64d1b 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -8102,6 +8102,26 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(BT const& name, return cmLinkItem(resolved.Target, false, bt); } +bool cmGeneratorTarget::HasPackageReferences() const +{ + return this->IsInBuildSystem() && + !this->GetProperty("VS_PACKAGE_REFERENCES")->empty(); +} + +std::vector cmGeneratorTarget::GetPackageReferences() const +{ + std::vector packageReferences; + + if (this->IsInBuildSystem()) { + if (cmValue vsPackageReferences = + this->GetProperty("VS_PACKAGE_REFERENCES")) { + cmExpandList(*vsPackageReferences, packageReferences); + } + } + + return packageReferences; +} + std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const { if (OutputInfo const* info = this->GetOutputInfo(config)) { diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index 71212c4faf..a58dc93712 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -424,6 +424,9 @@ public: cmLinkItem ResolveLinkItem(BT const& name, cmLocalGenerator const* lg) const; + bool HasPackageReferences() const; + std::vector GetPackageReferences() const; + // Compute the set of languages compiled by the target. This is // computed every time it is called because the languages can change // when source file properties are changed and we do not have enough diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 8559abab3c..156ecce8a5 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1994,7 +1994,7 @@ int cmGlobalGenerator::TryCompile(int jobs, const std::string& srcdir, } std::string config = mf->GetSafeDefinition("CMAKE_TRY_COMPILE_CONFIGURATION"); - cmBuildOptions defaultBuildOptions(false, fast); + cmBuildOptions defaultBuildOptions(false, fast, PackageResolveMode::Disable); return this->Build(jobs, srcdir, bindir, projectName, newTarget, output, "", config, defaultBuildOptions, false, diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 5634defc90..6b060a6722 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -1180,6 +1180,63 @@ cmGlobalVisualStudio10Generator::GenerateBuildCommand( } } makeCommand.Add(targetProject); + + // Check if we do need a restore at all (i.e. if there are package + // references and restore has not been disabled by a command line option. + PackageResolveMode restoreMode = buildOptions.ResolveMode; + bool requiresRestore = true; + + if (restoreMode == PackageResolveMode::Disable) { + requiresRestore = false; + } else if (cmValue cached = + this->CMakeInstance->GetState()->GetCacheEntryValue( + tname + "_REQUIRES_VS_PACKAGE_RESTORE")) { + requiresRestore = cached.IsOn(); + } else { + // There are no package references defined. + requiresRestore = false; + } + + // If a restore is required, evaluate the restore mode. + if (requiresRestore) { + if (restoreMode == PackageResolveMode::OnlyResolve) { + // Only invoke the restore target on the project. + makeCommand.Add("/t:Restore"); + } else { + // Invoke restore target, unless it has been explicitly disabled. + bool restorePackages = true; + + if (this->Version < VS15) { + // Package restore is only supported starting from Visual Studio + // 2017. Package restore must be executed manually using NuGet + // shell for older versions. + this->CMakeInstance->IssueMessage( + MessageType::WARNING, + "Restoring package references is only supported for Visual " + "Studio 2017 and later. You have to manually restore the " + "packages using NuGet before building the project."); + restorePackages = false; + } else if (restoreMode == PackageResolveMode::FromCacheVariable) { + // Decide if a restore is performed, based on a cache variable. + if (cmValue cached = + this->CMakeInstance->GetState()->GetCacheEntryValue( + "CMAKE_VS_NUGET_PACKAGE_RESTORE")) + restorePackages = cached.IsOn(); + } + + if (restorePackages) { + if (this->IsMsBuildRestoreSupported()) { + makeCommand.Add("/restore"); + } else { + GeneratedMakeCommand restoreCommand; + restoreCommand.Add(makeProgramSelected); + restoreCommand.Add(targetProject); + restoreCommand.Add("/t:Restore"); + makeCommands.emplace_back(restoreCommand); + } + } + } + } } std::string configArg = "/p:Configuration="; @@ -1561,6 +1618,18 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::GetNasmFlagTable() const return LoadFlagTable(std::string(), this->DefaultNasmFlagTableName, "NASM"); } +bool cmGlobalVisualStudio10Generator::IsMsBuildRestoreSupported() const +{ + if (this->Version >= VS16) { + return true; + } + + static std::string const vsVer15_7_5 = "15.7.27703.2042"; + cm::optional vsVer = this->GetVSInstanceVersion(); + return (vsVer && + cmSystemTools::VersionCompareGreaterEq(*vsVer, vsVer15_7_5)); +} + std::string cmGlobalVisualStudio10Generator::GetClFlagTableName() const { std::string const& toolset = this->GetPlatformToolsetString(); diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index aea999db39..4977a845d0 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -173,6 +173,8 @@ public: cmIDEFlagTable const* GetMasmFlagTable() const; cmIDEFlagTable const* GetNasmFlagTable() const; + bool IsMsBuildRestoreSupported() const; + protected: cmGlobalVisualStudio10Generator(cmake* cm, const std::string& name, std::string const& platformInGeneratorName); diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 685d34dec3..fb8351d470 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -431,6 +431,9 @@ void cmVisualStudio10TargetGenerator::Generate() // The groups are stored in a separate file for VS 10 this->WriteGroups(); + + // Update cache with project-specific entries. + this->UpdateCache(); } void cmVisualStudio10TargetGenerator::WriteClassicMsBuildProjectFile( @@ -1000,11 +1003,9 @@ bool cmVisualStudio10TargetGenerator::HasCustomCommands() const void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0) { - std::vector packageReferences; - if (cmValue vsPackageReferences = - this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) { - cmExpandList(*vsPackageReferences, packageReferences); - } + std::vector packageReferences = + this->GeneratorTarget->GetPackageReferences(); + if (!packageReferences.empty()) { Elem e1(e0, "ItemGroup"); for (std::string const& ri : packageReferences) { @@ -5366,3 +5367,32 @@ void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1) e1.Element("StdOutEncoding", "UTF-8"); } } + +void cmVisualStudio10TargetGenerator::UpdateCache() +{ + std::vector packageReferences; + + if (this->GeneratorTarget->HasPackageReferences()) { + // Store a cache entry that later determines, if a package restore is + // required. + this->GeneratorTarget->Makefile->AddCacheDefinition( + this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE", "ON", + "Value Computed by CMake", cmStateEnums::STATIC); + } else { + // If there are any dependencies that require package restore, inherit the + // cache variable. + cmGlobalGenerator::TargetDependSet const& unordered = + this->GlobalGenerator->GetTargetDirectDepends(this->GeneratorTarget); + using OrderedTargetDependSet = + cmGlobalVisualStudioGenerator::OrderedTargetDependSet; + OrderedTargetDependSet depends(unordered, CMAKE_CHECK_BUILD_SYSTEM_TARGET); + + for (cmGeneratorTarget const* dt : depends) { + if (dt->HasPackageReferences()) { + this->GeneratorTarget->Makefile->AddCacheDefinition( + this->GeneratorTarget->GetName() + "_REQUIRES_VS_PACKAGE_RESTORE", + "ON", "Value Computed by CMake", cmStateEnums::STATIC); + } + } + } +} diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 8d2b77d292..ba44a6f523 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -198,6 +198,7 @@ private: std::string GetCSharpSourceLink(cmSourceFile const* source); void WriteStdOutEncodingUtf8(Elem& e1); + void UpdateCache(); private: friend class cmVS10GeneratorOptions; diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 0f128ce8f5..22fdcf88f0 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -447,6 +447,7 @@ int do_build(int ac, char const* const* av) bool cleanFirst = false; bool foundClean = false; bool foundNonClean = false; + PackageResolveMode resolveMode = PackageResolveMode::FromCacheVariable; bool verbose = cmSystemTools::HasEnv("VERBOSE"); std::string presetName; bool listPresets = false; @@ -480,6 +481,22 @@ int do_build(int ac, char const* const* av) } return false; }; + auto resolvePackagesLambda = [&](std::string const& value) -> bool { + std::string v = value; + std::transform(v.begin(), v.end(), v.begin(), ::tolower); + + if (v == "on") { + resolveMode = PackageResolveMode::Force; + } else if (v == "only") { + resolveMode = PackageResolveMode::OnlyResolve; + } else if (v == "off") { + resolveMode = PackageResolveMode::Disable; + } else { + return false; + } + + return true; + }; auto verboseLambda = [&](std::string const&) -> bool { verbose = true; return true; @@ -516,6 +533,8 @@ int do_build(int ac, char const* const* av) cleanFirst = true; return true; } }, + CommandArgument{ "--resolve-package-references", + CommandArgument::Values::One, resolvePackagesLambda }, CommandArgument{ "-v", CommandArgument::Values::Zero, verboseLambda }, CommandArgument{ "--verbose", CommandArgument::Values::Zero, verboseLambda }, @@ -641,6 +660,8 @@ int do_build(int ac, char const* const* av) " --config = For multi-configuration tools, choose .\n" " --clean-first = Build target 'clean' first, then build.\n" " (To clean only, use --target 'clean'.)\n" + " --resolve-package-references={on|only|off}\n" + " = Restore/resolve package references during build.\n" " --verbose, -v = Enable verbose output - if supported - including\n" " the build commands to be executed. \n" " -- = Pass remaining options to the native tool.\n" @@ -658,6 +679,8 @@ int do_build(int ac, char const* const* av) cmakemainProgressCallback(msg, prog, &cm); }); + cmBuildOptions buildOptions(cleanFirst, false, resolveMode); + return cm.Build(jobs, std::move(dir), std::move(targets), std::move(config), std::move(nativeOptions), buildOptions, verbose, presetName, listPresets); diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index f0457a8a10..1c73834d68 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -618,6 +618,7 @@ endif() if(CMAKE_GENERATOR MATCHES "^Visual Studio (1[6-9]|[2-9][0-9])") add_RunCMake_test(VsDotnetSdk) + add_RunCMake_test(VsNugetPackageRestore) endif() if(XCODE_VERSION) diff --git a/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt new file mode 100644 index 0000000000..4811bea2f7 --- /dev/null +++ b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt @@ -0,0 +1 @@ +^Usage: cmake --build +\[options\] \[-- \[native-options\]\] diff --git a/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt b/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt new file mode 100644 index 0000000000..d8200fca0a --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.22) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt b/Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt new file mode 100644 index 0000000000..56920d920a --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.12) + +project(NuGetTestProject VERSION 1.0.0 LANGUAGES CSharp) + +add_library(NuGetPackage SHARED "Library.cs") +set_target_properties(NuGetPackage PROPERTIES + VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.7.2" + VS_DOTNET_REFERENCES "System") +install(TARGETS NuGetPackage) + +set(CPACK_GENERATOR "NuGet") +set(CPACK_PACKAGE_NAME "NuGetTestProject") +set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}") +set(CPACK_PACKAGE_DESCRIPTION "Package to test automatic NuGet package restore.") +set(CPACK_PACKAGE_VENDOR "CMake.org") + +include(CPack) diff --git a/Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs b/Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs new file mode 100644 index 0000000000..d9ae85a6d2 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs @@ -0,0 +1,9 @@ +using System; + +namespace CMake +{ + public class NuGetTest + { + public static int GetNumber() => 42; + } +} diff --git a/Tests/RunCMake/VsNugetPackageRestore/Program.cs b/Tests/RunCMake/VsNugetPackageRestore/Program.cs new file mode 100644 index 0000000000..681461f365 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Program.cs @@ -0,0 +1,14 @@ +using System; +using CMake; + +namespace Test +{ + public class Program + { + public static void Main(string[] args) + { + Console.WriteLine(NuGetTest.GetNumber()); + Console.ReadKey(); + } + } +} diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata new file mode 100644 index 0000000000..6a87d0a8b8 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata @@ -0,0 +1,5 @@ +{ + "version": 2, + "contentHash": "2sG1Ws4da8r6qj7rUAZ1GaOjkELonH0X+vR9yfDwgg+QxG0cpRIfGqEXKAkGT+UCwU24ogJcm8IA9dXv5zmLXg==", + "source": null +} diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..5569a2966eef9a680782f3743b3efa46580efc8e GIT binary patch literal 5664 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 + + + NuGetTestProject + 1.0.0 + CMake.org + false + Package to test automatic NuGet package restore. + NuGetTestProject built using CMake + + diff --git a/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake b/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake new file mode 100644 index 0000000000..625167c063 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake @@ -0,0 +1,12 @@ +cmake_policy(SET CMP0053 NEW) +include(RunCMake) + +set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/VsNugetPackageRestore) +run_cmake(VsNugetPackageRestore) + +set(RunCMake_TEST_NO_CLEAN 1) +run_cmake_command(vs-nuget-package-restore-off ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=off) +run_cmake_command(vs-nuget-package-restore-only ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=only) +run_cmake_command(vs-nuget-package-restore-on ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=on) +run_cmake_command(vs-nuget-package-restore-wrong ${CMAKE_COMMAND} --build ${RunCMake_TEST_BINARY_DIR} --resolve-package-references=wrong) +set(RunCMake_TEST_NO_CLEAN 0) diff --git a/Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake b/Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake new file mode 100644 index 0000000000..a0227df0f8 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake @@ -0,0 +1,9 @@ +enable_language(CSharp) + +add_executable(TestProgram "Program.cs") +configure_file("nuget.config.in" "nuget.config") +set_target_properties(TestProgram PROPERTIES + VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.7.2" + VS_DOTNET_REFERENCES "System" + VS_PACKAGE_REFERENCES "NuGetTestProject_1.0.0" +) diff --git a/Tests/RunCMake/VsNugetPackageRestore/nuget.config.in b/Tests/RunCMake/VsNugetPackageRestore/nuget.config.in new file mode 100644 index 0000000000..2e54c8fc5d --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/nuget.config.in @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt new file mode 100644 index 0000000000..10f32932ee --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt @@ -0,0 +1 @@ +^$ diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt new file mode 100644 index 0000000000..4811bea2f7 --- /dev/null +++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt @@ -0,0 +1 @@ +^Usage: cmake --build +\[options\] \[-- \[native-options\]\] From 9aa7831f05e924830848822aecdb43aa7261bc11 Mon Sep 17 00:00:00 2001 From: Carsten Rudolph <18394207+crud89@users.noreply.github.com> Date: Sat, 22 Jan 2022 10:12:25 +0100 Subject: [PATCH 4/4] Presets: add resolve packages setting to build presets. --- Help/manual/cmake-presets.7.rst | 36 +++++++++++++ Help/manual/cmake.1.rst | 13 +++++ Help/manual/presets/schema.json | 53 ++++++++++++++++++- Help/release/dev/vs-package-restore.rst | 3 ++ Source/cmCMakePresetsGraph.cxx | 3 ++ Source/cmCMakePresetsGraph.h | 3 ++ ...mCMakePresetsGraphReadJSONBuildPresets.cxx | 35 +++++++++++- Source/cmGlobalVisualStudio10Generator.cxx | 4 ++ Source/cmake.cxx | 4 ++ Tests/RunCMake/CMakePresetsBuild/Good.json.in | 8 ++- .../CMakePresetsBuild/RunCMakeTest.cmake | 2 +- 11 files changed, 160 insertions(+), 4 deletions(-) diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index 474e1aa6c9..b43c9152cd 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -475,6 +475,42 @@ that may contain the following fields: An optional bool. If true, equivalent to passing ``--clean-first`` on the command line. +``resolvePackageReferences`` + + An optional string that specifies the package resolve mode. This is + allowed in preset files specifying version ``4`` or above. + + This field overwrites the ``--resolve-package-references`` command line + parameter. If there are no targets that define package references, this + option does nothing. Valid values are: + + ``on`` + + Causes package references to be resolved before attempting a build. + + ``off`` + + Package references will not be resolved. Note that this may cause + errors in some build environments, such as .NET SDK style projects. + + ``only`` + + Only resolve package references, but do not perform a build. + + .. note:: + + If this setting is not specified in a preset, CMake will instead + use the setting specified by the ``--resolve-package-references`` + command line parameter. If the command line parameter is not + provided either, an environment-specific cache variable will be + evaluated to decide, if package restoration should be performed. + + When using the Visual Studio generator, package references are + defined using the :prop_tgt:`VS_PACKAGE_REFERENCES` property. + Package references are restored using NuGet. It can be disabled + by setting the ``CMAKE_VS_NUGET_PACKAGE_RESTORE`` variable to + ``OFF``. This can also be done from within a configure preset. + ``verbose`` An optional bool. If true, equivalent to passing ``--verbose`` on the diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst index 1d638b942b..1463f0a23f 100644 --- a/Help/manual/cmake.1.rst +++ b/Help/manual/cmake.1.rst @@ -474,6 +474,19 @@ following options: If the target does not define any package references, this option does nothing. + This setting can be specified in a build preset (using + ``resolvePackageReferences``). In this case, the command line option will + be ignored. + + If the no command line parameter or preset option is not provided, an + environment-specific cache variable will be evaluated to decide, if package + restoration should be performed. + + When using the Visual Studio generator, package references are defined + using the :prop_tgt:`VS_PACKAGE_REFERENCES` property. Package references + are restored using NuGet. It can be disabled by setting the + ``CMAKE_VS_NUGET_PACKAGE_RESTORE`` variable to ``OFF``. + ``--use-stderr`` Ignored. Behavior is default in CMake >= 3.0. diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json index 3844611363..12f8b5ec17 100644 --- a/Help/manual/presets/schema.json +++ b/Help/manual/presets/schema.json @@ -52,7 +52,7 @@ "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"}, "vendor": { "$ref": "#/definitions/vendor" }, "configurePresets": { "$ref": "#/definitions/configurePresetsV3"}, - "buildPresets": { "$ref": "#/definitions/buildPresetsV3"}, + "buildPresets": { "$ref": "#/definitions/buildPresetsV4"}, "testPresets": { "$ref": "#/definitions/testPresetsV3"}, "include": { "$ref": "#/definitions/include"} }, @@ -427,6 +427,22 @@ "additionalProperties": false } }, + "buildPresetsItemsV4": { + "type": "array", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 4 and higher.", + "items": { + "type": "object", + "properties": { + "resolvePackageReferences": { + "type": "string", + "description": "An optional string specifying the package resolve behavior. Valid values are \"on\" (packages are resolved prior to the build), \"off\" (packages are not resolved prior to the build), and \"only\" (packages are resolved, but no build will be performed).", + "enum": [ + "on", "off", "only" + ] + } + } + } + }, "buildPresetsItemsV3": { "type": "array", "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 3 and higher.", @@ -558,6 +574,41 @@ ] } }, + "buildPresetsV4": { + "type": "array", + "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 4 and higher.", + "allOf": [ + { "$ref": "#/definitions/buildPresetsItemsV4" }, + { "$ref": "#/definitions/buildPresetsItemsV3" }, + { "$ref": "#/definitions/buildPresetsItemsV2" } + ], + "items": { + "type": "object", + "properties": { + "name": {}, + "hidden": {}, + "inherits": {}, + "configurePreset": {}, + "vendor": {}, + "displayName": {}, + "description": {}, + "inheritConfigureEnvironment": {}, + "environment": {}, + "jobs": {}, + "targets": {}, + "configuration": {}, + "cleanFirst": {}, + "resolvePackageReferences": {}, + "verbose": {}, + "nativeToolOptions": {}, + "condition": {} + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, "buildPresetsV3": { "type": "array", "description": "An optional array of build preset objects. Used to specify arguments to cmake --build. Available in version 3 and higher.", diff --git a/Help/release/dev/vs-package-restore.rst b/Help/release/dev/vs-package-restore.rst index 697778ffe4..e8b5f0c653 100644 --- a/Help/release/dev/vs-package-restore.rst +++ b/Help/release/dev/vs-package-restore.rst @@ -8,3 +8,6 @@ vs-package-restore * :manual:`cmake(1)` gained the ``--resolve-package-references=`` command-line option to control automatic package restoration. + +* :manual:`cmake-presets(7)` gained support for specifying the + ``resolvePackageReferences`` command line option in a build preset. diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx index 58dca36821..f8e71c9390 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -724,6 +724,9 @@ cmCMakePresetsGraph::BuildPreset::VisitPresetInherit( InheritOptionalValue(preset.CleanFirst, parent.CleanFirst); InheritOptionalValue(preset.Verbose, parent.Verbose); InheritVector(preset.NativeToolOptions, parent.NativeToolOptions); + if (!preset.ResolvePackageReferences) { + preset.ResolvePackageReferences = parent.ResolvePackageReferences; + } return ReadFileResult::READ_OK; } diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h index 02c506f93b..5159b60b3b 100644 --- a/Source/cmCMakePresetsGraph.h +++ b/Source/cmCMakePresetsGraph.h @@ -14,6 +14,8 @@ #include +enum class PackageResolveMode; + class cmCMakePresetsGraph { public: @@ -182,6 +184,7 @@ public: cm::optional CleanFirst; cm::optional Verbose; std::vector NativeToolOptions; + cm::optional ResolvePackageReferences; ReadFileResult VisitPresetInherit(const Preset& parent) override; ReadFileResult VisitPresetAfterInherit(int /* version */) override; diff --git a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx index ef605d15fe..eefe2fe28a 100644 --- a/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx +++ b/Source/cmCMakePresetsGraphReadJSONBuildPresets.cxx @@ -12,6 +12,7 @@ #include +#include "cmBuildOptions.h" #include "cmCMakePresetsGraph.h" #include "cmCMakePresetsGraphInternal.h" #include "cmJSONHelpers.h" @@ -20,6 +21,37 @@ namespace { using ReadFileResult = cmCMakePresetsGraph::ReadFileResult; using BuildPreset = cmCMakePresetsGraph::BuildPreset; +ReadFileResult PackageResolveModeHelper(cm::optional& out, + const Json::Value* value) +{ + if (!value) { + out = cm::nullopt; + return ReadFileResult::READ_OK; + } + + if (!value->isString()) { + return ReadFileResult::INVALID_PRESET; + } + + if (value->asString() == "on") { + out = PackageResolveMode::Force; + } else if (value->asString() == "off") { + out = PackageResolveMode::Disable; + } else if (value->asString() == "only") { + out = PackageResolveMode::OnlyResolve; + } else { + return ReadFileResult::INVALID_PRESET; + } + + return ReadFileResult::READ_OK; +} + +std::function const + ResolvePackageReferencesHelper = + [](BuildPreset& out, const Json::Value* value) -> ReadFileResult { + return PackageResolveModeHelper(out.ResolvePackageReferences, value); +}; + auto const BuildPresetHelper = cmJSONObjectHelper( ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false) @@ -59,7 +91,8 @@ auto const BuildPresetHelper = .Bind("nativeToolOptions"_s, &BuildPreset::NativeToolOptions, cmCMakePresetsGraphInternal::PresetVectorStringHelper, false) .Bind("condition"_s, &BuildPreset::ConditionEvaluator, - cmCMakePresetsGraphInternal::PresetConditionHelper, false); + cmCMakePresetsGraphInternal::PresetConditionHelper, false) + .Bind("resolvePackageReferences"_s, ResolvePackageReferencesHelper, false); } namespace cmCMakePresetsGraphInternal { diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 6b060a6722..e9824fbcf4 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -724,6 +724,10 @@ void cmGlobalVisualStudio10Generator::Generate() /* clang-format on */ lg->IssueMessage(MessageType::WARNING, e.str()); } + if (cmValue cached = this->CMakeInstance->GetState()->GetCacheEntryValue( + "CMAKE_VS_NUGET_PACKAGE_RESTORE")) { + this->CMakeInstance->MarkCliAsUsed("CMAKE_VS_NUGET_PACKAGE_RESTORE"); + } } void cmGlobalVisualStudio10Generator::EnableLanguage( diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 2361ce2e14..8393cd36bb 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -3331,6 +3331,10 @@ int cmake::Build(int jobs, std::string dir, std::vector targets, buildOptions.Clean = *expandedPreset->CleanFirst; } + if (expandedPreset->ResolvePackageReferences) { + buildOptions.ResolveMode = *expandedPreset->ResolvePackageReferences; + } + if (!verbose && expandedPreset->Verbose) { verbose = *expandedPreset->Verbose; } diff --git a/Tests/RunCMake/CMakePresetsBuild/Good.json.in b/Tests/RunCMake/CMakePresetsBuild/Good.json.in index c7f318ceda..568907c754 100644 --- a/Tests/RunCMake/CMakePresetsBuild/Good.json.in +++ b/Tests/RunCMake/CMakePresetsBuild/Good.json.in @@ -1,5 +1,5 @@ { - "version": 2, + "version": 4, "configurePresets": [ { "name": "default", @@ -78,6 +78,12 @@ "name": "singleTarget", "inherits": "build-default", "targets": "good" + }, + { + "name": "initResolve", + "inherits": "build-default", + "targets": "good", + "resolvePackageReferences": "off" } ] } diff --git a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake index b37c7709a5..2fe0407a2b 100644 --- a/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresetsBuild/RunCMakeTest.cmake @@ -70,7 +70,7 @@ else() set(Good_json_jobs [["jobs": 0,]]) endif() -run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvironment;macros;vendorObject;singleTarget") +run_cmake_build_presets(Good "default;other" "build-other;withEnvironment;noEnvironment;macros;vendorObject;singleTarget;initResolve") run_cmake_build_presets(InvalidConfigurePreset "default" "badConfigurePreset") run_cmake_build_presets(Condition "default" "enabled;disabled")