Search code examples
c++visual-studio-2017nuget

How do I regenerate the packages directory for a Visual Studio C++ project?


I recently created a C++ Visual Studio 2017 unit test project (vcxproj) based on Google Test. I used File/New/Project/Installed/Visual C++/Test/Google Test.

This created a package.config file:

<?xml version="1.0" encoding="utf-8"?>
  <packages>
    <package id="Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn" version="1.8.0" targetFramework="native" />
  </packages>

It also created a packages directory in my solution and places the googletest package in it. This directory contains binary libraries (no source code) so I did not add the packages directory to revision control. My assumption was that Visual Studio would re-download the package if it was missing (using nuget or something).

However when I clone the repository and start fresh, the unit test project refuses to open ("load failed") because the packages directory mentioned in one of its import statements is absent:

<Import Project="..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets" />

I looked at this article, which seems to contain some tips: https://learn.microsoft.com/en-gb/nuget/consume-packages/package-restore

They recommend to enable "Automatically check for missing packages during build". My checkbox was already checked, so I am guessing it can't build until the project is loaded.

What is the right way to proceed here? Should I check in packages or is there some other way to fetch the packages automatically (like VS did when it created my project)?

UPDATE: I was able to recover the packages directory manually using nuget restore -SolutionDir xyz on the command line, but is there a way to trigger this automatically before the project is opened?


Solution

  • What is the right way to proceed here?

    You should add condition to the Import target:

      <ImportGroup Label="ExtensionTargets">
        <Import Project="..\packages\xxx\xx.targets" Condition="Exists('..\packages\xxx\xx.targets')" />
      </ImportGroup>
    

    When we create the Google Test project, it imports .targets file to the project file .vcxproj by default. You can unload your project and edit it, you will following import statements:

      <ImportGroup Label="ExtensionTargets">
        <Import Project="..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets" Condition="Exists('..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.0\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" />
      </ImportGroup>
    

    Not sure why the Condition="Exists('..\packages\xx.targets')" was lost in your import statement, to resolve this issue, please add the condition to the Import target.

    Hope this helps.