Skip to content

Move C++ projects to use PackageReference  #8171

Closed

Description

Apparently PackageReference will work in C++ projects now. We should try it and see if there are any gaps, and if acceptable then remove the packages.config stuff as it complicates things.


Alexander Sklar (@asklar) As it turns out, PackageReference support in C++ projects works today. You will need to do the following:

  1. Add <ProjectCapability Include="PackageReferences" /> to an item group in your vcxproj file or a targets file included by it.
  2. Add a Directory.Build.props file or above the project’s directory, and add an Import element to it with the following value: $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.props. (You can technically add this anywhere that MSBuild will see it, but I find that putting it in Directory.Build.props ensures that it is both included at the correct place, and is also easily shared between all the projects in your solution.)
  3. Add a Directory.Build.targets file in the same location, and add an Import element to it with this value: $(MSBuildProjectExtensionsPath)$(MSBuildProjectFile).*.targets.
  4. Unload and reload your C++ project(s).

After that, not only will NuGet packages auto-restore like with csproj, but the NuGet Package Manager UI will also add and remove PackageReference elements from the project instead of creating a packages.config file. (If this doesn’t seem to work, you may need to use the VS 16.11 beta; that’s what I’m using, and it works great for me.) Note that vcxproj will require you to run File > Save All before changes made in the NuGet UI will persist to the project file, as with any other changes to a vcxproj made using the GUI. Hope this helps!

Originally posted by William Kent (@wjk) in dotnet/project-system#2491 (comment)

References

Activity

  1. ghost added
    Needs: Triage 🔍New issue that needs to be reviewed by the issue management team (label applied by bot)
    on Jul 6, 2021
  2. JunielKatarn commented on Jul 6, 2021

    @JunielKatarn
    Contributor

    I think Danny van Velzen (@dannyvv) tried this before, only native projects still rely on traditional NuGet locations (meaning, packages will still be stored in the packages relative folder).

    This is definitely useful, however, as it reduces the possibility of version mismatches.

  3. wjk commented on Jul 6, 2021

    @wjk

    Julio César Rocha (@JunielKatarn) Not necessarily. I have used vcxproj PackageReference with both the global (per-user) NuGet package cache, and a local package cache set via the nuget.config file, and have never ran into any such problems. Keep in mind that either way, the packages will all be unpacked as siblings of the same directory (either the per-user cache, or the path set in the nuget.config file), just as with packages.config. IMHO, if a NuGet package requires a specific restore layout to function properly, that is a bug in that package that should be corrected. (All paths in props/targets files in NuGet packages should be relative to $(MSBuildThisFileDirectory).) What packages do you expect will give problems?

  4. JunielKatarn commented on Jul 6, 2021

    @JunielKatarn
    Contributor

    William Kent (@wjk) none specifically. Maybe I was misinformed?
    If a Native C++ project can load the packages from the NuGet package cache instead of requiring an explicit location (usually relative to the VCXPROJ file), that would be a huge gain for us, because we wouldn't need to copy the packages for each local git clone.

    Did I understand this correctly?

  5. wjk commented on Jul 6, 2021

    @wjk

    That’s correct! 🚀

  6. JunielKatarn commented on Jul 6, 2021

    @JunielKatarn
    Contributor

    That’s correct! 🚀

    🤯
    I guess I'll be submitting this enhancement for this project... TODAY, then.

    One last question. Does this PackageReference mechanism work with plain NuGet.exe, or does it require some VS magic?

  7. wjk commented on Jul 6, 2021

    @wjk

    As it turns out, PackageReferences uses neither! Just run MSBuild.exe /t:Restore to download all needed packages, just as you would do with csproj (or run MSBuild.exe /restore to do so and then build the project).

  8. JunielKatarn commented on Jul 6, 2021

    @JunielKatarn
    Contributor

    Pretty much, pure modern MSBuild APIs, then.
    Awesome.

  9. asklar commented on Jul 6, 2021

    @asklar
    MemberAuthor

    Yeah I'm excited about the opportunity for simplification this brings!
    If it requires a specific min version of VS, then that'd be important to know.

    Today our C++ projects (both the framework as well as 3rd party libraries) have hardcoded dependencies to find nuget packages under the solution folder, so being able to remove all that would be great.

  10. wjk commented on Jul 7, 2021

    @wjk

    Alexander Sklar (@asklar) Support for C++ PackageReference in the VS GUI requires at least 16.9 per dotnet/project-system#6629, which was the last PR needed to implement this feature. Support for restoring C++ PackageReferences via the command line goes back much, much further.

  11. mingkuang-Chuyu commented on Jul 16, 2021

    @mingkuang-Chuyu

    Haha, you only discovered this secret now. How long have I been using it.

    Here is a more comprehensive configuration that allows vcxproj to support PackageReference.

    Directory.Build.props

    <?xml version="1.0" encoding="utf-8"?>
    <!--
    为Cpp工程强制开启 PackageReferences 支持
    
    Visual Studio 2017使用以后只能让MSBuild以及nuget.exe支持包还原。
    
    Visual Studio 2019 16.8或者更高版本可以直接让Visual Studio NuGet插件支持包管理。
    
    使用方法:将此文件复制到 sln 或者 vcxproj同级目录。
    
    
    作者:mingkuang
    最后修订:2021-06-21
    
    -->
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <ItemGroup Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
        <!--强制引入PackageReferences-->
        <ProjectCapability Include="PackageReferences" />
      </ItemGroup>
      <PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.vcxproj'">
        <!--指定自己的体系为native-->
        <NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == ''">native,Version=v0.0</NuGetTargetMoniker>
        <!--如果不指定这一行,那么arm64平台会找不到RID而失败-->
        <RuntimeIdentifiers Condition="'$(RuntimeIdentifiers)' == ''">win;win-x86;win-x64;win-arm;win-arm64</RuntimeIdentifiers>
      </PropertyGroup>
      
      <!--从兼容性考虑,继续向上搜索 Directory.Build.props-->
      <PropertyGroup>
        <DirectoryBuildPropsPath>$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))</DirectoryBuildPropsPath>
      </PropertyGroup>
      <Import Project="$(DirectoryBuildPropsPath)" Condition="'$(DirectoryBuildPropsPath)' != ''"/>
    </Project>
  12. davidhunter22 commented on Aug 9, 2021

    @davidhunter22
  13. asklar commented on Aug 9, 2021

    @asklar
    MemberAuthor

    David Hunter (@davidhunter22) React Native for Windows does not support C++/CLI. If you have questions about msbuild or VS support, please file them through VS feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions