Open crud89 opened 3 years ago
Update on this! Currently NuGet support for CMake is missing some essential features. I will update on them here, as soon as they are contributed. In order to get a fully working out-of-the-box NuGet experiences, here's what I want to continue to contribute to CMake
-r
build argument in the settings/preset. It would also add support for MSBuild 15.0 - 15.5, where no restore-and-build functionality is available. I've already created a merge request.~packages.config
-style dependency management. This would add support to define NuGet dependencies in C++/CLI projects.install
.The nuget-example
branch of this repository is used to test those changes. If there are any updates, I will post them here.
Builtin package restore
This is now in CMake starting from version 3.23
Builtin package restore
This is now in CMake starting from version 3.23
I know! As mentioned above, I am the author of the MR that implements this feature. 🙂 I will update the comment now to make clear that this works. I've also started working in restoring using packages.config
, however resolving .NET versions turned out harder than anticipated.
Ah whoops! I've missed that part, sorry. Thank you for working on this, it seems like one of the most obscure cmake corners.
I'm mostly interested in the third point, since as of now the support for install is practically non-existant. I was setting out to write a Python script for that (I use this kind of set up in project), but I wouldn't mind helping make that part of cmake
I agree! I think currently your best bet is to simply set the CMAKE_RUNTIME_OUTPUT_DIRECTORY
to a common build directory and don't use install
. However, this prevents you to cpack
the app, unfortunately. Alternatively, you could take a look at vcpkg - they have a X_VCPKG_APPLOCAL_DEPS_INSTALL
variable, which does exactly that. It is implemented here. Basically it invokes this script, which itself invokes either objdump
, dumpbin
or llvm-objdump
to scan for all dependencies on the artifact to install. It then copies everything over to the install directory. You would additionally have to do some filtering to not copy over system dependencies.
If you do not want to re-write this on your own, I guess you could also try to add vcpkg as a submodule and simply use its toolchain file, then set this variable to ON
. What it does though is to overwrite several cmake-functions, such as install
to hook custom logic in.
If you only need PackageReference
dependencies in non-C++/CLI projects, you could also parse the project.assets.json file from the builds intermediate directory. In fact that's what I had in mind for implementing this, but this only works for PackageReference
-dependencies, not for packages.json, unfortunately. 😕
Adding NuGet packages to C++/CLI projects is surprisingly hard. Whilst purely managed assemblies can simply be referenced by a C++/CLI project, the
TargetFramework
property not beeing properly set for C++/CLI projects, results in errors when NuGet tries to restore the package:You might also experience other errors, such as
NU1201
orNU1202
.Whilst in theory it is possible for C++/CLI projects to use NuGet packages that target the same .NET Framework version, it is currently not properly implemented by Microsoft. The naïve approach of defining a
VS_PACKAGE_REFERENCE
, as you would do for a C# project, will result in NuGet not beeing able to resolve the target framework for the project and you will receive the errors mentioned earlier. There are two possible workarounds for this issue, both of which require an intermediate C# project that has aVS_PACKAGE_REFERENCE
set, so that MSBuild is able to restore the package. In this template this could be the CommonLib project.VS_DOTNET_REFERENCE_*
) to the package assembly. However, this approach is not ideal, since you have to know where the current NuGet package cache resides, which might cause forward compatibility problems.The second option could be made much more feasible by exploiting the fact, that the proper assemblies are automatically copied over to the output directory during the build. If those assemblies could be added to the CMake export config for the project, than a simple
TARGET_LINK_LIBRARIES
would be enough to properly reference them within the C++/CLI project or other dependent projects.However, my CMake expertise is actually limited and I spent way to many hours trying to fix this issue. So if you feel you could contribute to a solution to this problem, feel free to join the discussion in this issue or open an PR! 🙂
Related resources:
%USERPROFILE%
now.