summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-variables.7.rst1
-rw-r--r--Help/manual/cmake.1.rst11
-rw-r--r--Help/release/dev/vs-package-restore.rst10
-rw-r--r--Help/variable/CMAKE_VS_NUGET_PACKAGE_RESTORE.rst22
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx3
-rw-r--r--Source/cmBuildOptions.h25
-rw-r--r--Source/cmGeneratorTarget.cxx20
-rw-r--r--Source/cmGeneratorTarget.h3
-rw-r--r--Source/cmGlobalGenerator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx69
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx40
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h1
-rw-r--r--Source/cmakemain.cxx23
-rw-r--r--Tests/RunCMake/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt1
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/Package/CMakeLists.txt17
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/Package/Library.cs9
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/Program.cs14
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/.nupkg.metadata5
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkgbin0 -> 5664 bytes
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha5121
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec11
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/VsNugetPackageRestore.cmake9
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/nuget.config.in7
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-result.txt1
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-off-stderr.txt1
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-result.txt1
-rw-r--r--Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt1
32 files changed, 319 insertions, 8 deletions
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 51b092f..8c43c22 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 04e2eda..1d638b9 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=<on|off|only>``
+ .. 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 0000000..697778f
--- /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=<on|off|only>``
+ 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 0000000..7160726
--- /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 9b5e319..e09b4dd 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 ed26703..58baeef 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 421e136..45e3b64 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -8102,6 +8102,26 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(BT<std::string> const& name,
return cmLinkItem(resolved.Target, false, bt);
}
+bool cmGeneratorTarget::HasPackageReferences() const
+{
+ return this->IsInBuildSystem() &&
+ !this->GetProperty("VS_PACKAGE_REFERENCES")->empty();
+}
+
+std::vector<std::string> cmGeneratorTarget::GetPackageReferences() const
+{
+ std::vector<std::string> 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 71212c4..a58dc93 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -424,6 +424,9 @@ public:
cmLinkItem ResolveLinkItem(BT<std::string> const& name,
cmLocalGenerator const* lg) const;
+ bool HasPackageReferences() const;
+ std::vector<std::string> 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 8559aba..156ecce 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 5634def..6b060a6 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<std::string> 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 aea999d..4977a84 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 685d34d..fb8351d 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<std::string> packageReferences;
- if (cmValue vsPackageReferences =
- this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) {
- cmExpandList(*vsPackageReferences, packageReferences);
- }
+ std::vector<std::string> 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<std::string> 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 8d2b77d..ba44a6f 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 0f128ce..22fdcf8 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 <cfg> = For multi-configuration tools, choose <cfg>.\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 f0457a8..1c73834 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 0000000..d00491f
--- /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 0000000..4811bea
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/build-invalid-package-resolve-arg-stderr.txt
@@ -0,0 +1 @@
+^Usage: cmake --build <dir> +\[options\] \[-- \[native-options\]\]
diff --git a/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt b/Tests/RunCMake/VsNugetPackageRestore/CMakeLists.txt
new file mode 100644
index 0000000..d8200fc
--- /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 0000000..56920d9
--- /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 0000000..d9ae85a
--- /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 0000000..681461f
--- /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 0000000..6a87d0a
--- /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 0000000..5569a29
--- /dev/null
+++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg
Binary files differ
diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha512 b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha512
new file mode 100644
index 0000000..5526b76
--- /dev/null
+++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.1.0.0.nupkg.sha512
@@ -0,0 +1 @@
+2sG1Ws4da8r6qj7rUAZ1GaOjkELonH0X+vR9yfDwgg+QxG0cpRIfGqEXKAkGT+UCwU24ogJcm8IA9dXv5zmLXg==
diff --git a/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec
new file mode 100644
index 0000000..9a943a8
--- /dev/null
+++ b/Tests/RunCMake/VsNugetPackageRestore/Repository/NuGetTestProject/1.0.0/nugettestproject.nuspec
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+ <metadata>
+ <id>NuGetTestProject</id>
+ <version>1.0.0</version>
+ <authors>CMake.org</authors>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <description>Package to test automatic NuGet package restore.</description>
+ <summary>NuGetTestProject built using CMake</summary>
+ </metadata>
+</package>
diff --git a/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake b/Tests/RunCMake/VsNugetPackageRestore/RunCMakeTest.cmake
new file mode 100644
index 0000000..625167c
--- /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 0000000..a0227df
--- /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 0000000..2e54c8f
--- /dev/null
+++ b/Tests/RunCMake/VsNugetPackageRestore/nuget.config.in
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <packageSources>
+ <clear />
+ <add key="local" value="@CMAKE_CURRENT_SOURCE_DIR@/Repository/" />
+ </packageSources>
+</configuration>
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 0000000..d00491f
--- /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 0000000..10f3293
--- /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 0000000..d00491f
--- /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 0000000..4811bea
--- /dev/null
+++ b/Tests/RunCMake/VsNugetPackageRestore/vs-nuget-package-restore-wrong-stderr.txt
@@ -0,0 +1 @@
+^Usage: cmake --build <dir> +\[options\] \[-- \[native-options\]\]