Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Including nuget packages in VS2019 C++ cross platform program

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?

like image 987
Jason Avatar asked Oct 21 '19 14:10

Jason


1 Answers

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.

like image 85
Kevin Avatar answered Oct 14 '22 01:10

Kevin