I've been tasked with starting to lay out a C++ cross platform program with CMake. One of our main dependencies involves in-house nuget packages. With our Windows C++ projects, I'd just right click the project and choose Manage Nuget Packages. In the cross platform, there's no such option, and I am struggling to find any relevant information on how I'd go about including those dependencies. Can anyone link me to any good sources of info, or demo?
EDIT: As of CMake 3.15, CMake supports referencing Nuget packages with VS_PACKAGE_REFERENCES
. Now, this is a much cleaner solution than the work-around proposed below. To add a Nuget package reference to a CMake target, use the package name and package version separated by an underscore _
; here is an example for BouncyCastle
version 1.8.5:
set_property(TARGET MyApplication
PROPERTY VS_PACKAGE_REFERENCES "BouncyCastle_1.8.5"
)
Note, this solution only works for C# or hybrid C#/C++ projects. As mentioned here, Microsoft doesn't support PackageReference
for pure C++ projects.
Prior to CMake 3.15, CMake has no built-in commands for Nuget support, so you will have to use the nuget
command line utilities to include Nuget dependencies using CMake.
You can use CMake's find_program()
to locate the nuget
command line utility (once installed), coupled with add_custom_command()
or execute_process()
to execute nuget
commands from CMake. The answers to this question discuss in more detail, but it could essentially look something like this:
# Find Nuget (install the latest CLI here: https://www.nuget.org/downloads).
find_program(NUGET nuget)
if(NOT NUGET)
message(FATAL "CMake could not find the nuget command line tool. Please install it!")
else()
# Copy the Nuget config file from source location to the CMake build directory.
configure_file(packages.config.in packages.config COPYONLY)
# Run Nuget using the .config file to install any missing dependencies to the build directory.
execute_process(COMMAND
${NUGET} restore packages.config -SolutionDirectory ${CMAKE_BINARY_DIR}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
endif()
This assumes you have an existing packages.config
file listing the nuget dependencies for your project.
To tie dependencies to a specific target, you (unfortunately) have to use the full path to where nuget
placed the assembly/library.
For .NET nuget packages this would look like this:
# Provide the path to the Nuget-installed references.
set_property(TARGET MyTarget PROPERTY
VS_DOTNET_REFERENCE_MyReferenceLib
${CMAKE_BINARY_DIR}/packages/path/to/nuget/lib/MyReferenceLib.dll
)
For C++-flavored nuget packages, it could look like this:
add_library(MyLibrary PUBLIC
MySource.cpp
MyClass1.cpp
...
)
# Provide the path to the Nuget-installed libraries.
target_link_libraries(MyLibrary PUBLIC
${CMAKE_BINARY_DIR}/packages/path/to/nuget/lib/MyCppLib.dll
)
As an aside, CMake does support the creation of Nuget packages with CPack. Here is the documentation for the CPack Nuget generator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With