VS: Auto restore NuGet packages.
NuGet package dependencies can be defined per target using the VS_PACKAGE_REFERENCES
property. Currently, this only works if the user manually restores the packages prior to the build. This merge request causes msbuild to be invoked with the appropriate parameters to automatically restore all packages prior to each build.
A workaround for the original problem was to invoke cmake --build
by passing the -r
or -t:Restore
switch as native option:
cmake --build . -- -r
The same effect could be achieved by using the nativeToolOptions
in a preset or the buildCommandArgs
in a CMaketSettings.json file. Restoring packages by default removes the requirement of explicitly specifying those arguments.
The implementation checks if the CMAKE_VS_NUGET_PACKAGE_RESTORE
is present in the cache when generating the build command. If it is not present, restoration defaults to true
(CMAKE_VS_NUGET_PACKAGE_RESTORE=ON
). For targets that define NuGet dependencies, this will cause them to be restored (if required). For all targets without package references, this will have no effect (hence I decided to make this the default behavior).
MSBuild 15.5 introduced the new switch -restore
that can be used as an alternative to -t:Restore
. This switch causes msbuild to lookup for packages all over the project and restores them. The implementation of this MR checks the Visual Studio version. If it is VS16
or above, it uses /restore
instead of /t:Restore
. Conceptually this should not make any difference, however, since this switch renders the restore target basically obsolete, it might be a long-term replacement for it, so using it for current iterations of msbuild appears reasonable for me.
This fixes issue #20646 (closed). Note, however, that the approach is slightly different than suggested in the issue. The original idea was to use the CMAKE_VS_NUGET_PACKAGE_RESTORE
variable to call msbuild to restore the NuGet packages after configuration. With this merge request, the restoration happens prior to a build. This is favored over the original approach, since the NuGet package cache could have been altered between configuration and build time (for example by uninstalling the package in question).
There is still one important limitation when using NuGet packages this way: they are not copied over during at INSTALL
time. This is due to them not being actual target dependencies. If this MR gets accepted, I would like to address this is a separate issue, since I am not sure if I am able to fix this on my own.
Feedback is much appreciated. :-)
Fixes: #20646 (closed)
Closes: #23008 (closed)