Skip to content

VS: Auto restore NuGet packages.

Carsten Rudolph requested to merge crud89/cmake:vs-package-restore into master

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)

Edited by Brad King

Merge request reports