2

I struggle to create a NuGet package from a native C++ library. For now, I have the following setup:

include(GNUInstallDirs)
file(RELATIVE_PATH relDir
    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}
    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_INSTALL_RPATH $ORIGIN $ORIGIN/${relDir})
set(CMAKE_INSTALL_DOCDIR ${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME})

# ...other CMake config...

install(TARGETS MyLib
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mylib
)

set(CPACK_PACKAGE_NAME MyLib)
set(CPACK_PACKAGE_VENDOR Me)
# ...standard CPack variables...

if(WIN32)
    set(CPACK_NUGET_PACKAGE_TAGS "Native" "native")
    set(CPACK_GENERATOR ZIP;NuGet)
else()
    set(CPACK_GENERATOR TGZ)
endif()

include(CPack)

Then, I run cmake --build . --target package to package my lib, and CMake correctly generates a .nupkg file containing the .lib and .h files I want. But then, when I try to use the generated package in a C++/WinRT project, I cannot #include the packaged headers.

So I have the following questions :

  • according to this SO answer and MS documentation, the packaged files should follow a certain hierarchy. Do I need to change CMake install() paths?
  • according to this SO answer, the reason I cannot find my headers is because I don't have any .targets file. Do I need to create one myself or is there a way to tell CPack to generate it?
2
  • Did you ever find answers to your questions?
    – Kevin
    Commented Jun 16, 2021 at 0:40
  • 1
    Unfortunately not, I think this CPack generator doesn't work correctly (at least when I tried). I did manage to create a packet manually using configuration I found here, here and here
    – loics2
    Commented Jun 16, 2021 at 6:51

1 Answer 1

0

Not sure if the problem still exists, but for me it works with the CPack nuget generator.

In my library I'm doing the following for installation. I mark the inculde headers as public

target_include_directories(${LIBRARY_NAME}
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>
        $<INSTALL_INTERFACE:include/>)

set_target_properties(${LIBRARY_NAME}
    PROPERTIES PUBLIC_HEADER 
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/>)

For installation

install(
    TARGETS ${LIBRARY_NAME}
    ARCHIVE  DESTINATION "lib"
    LIBRARY  DESTINATION "bin"
    RUNTIME  DESTINATION "bin"
    PUBLIC_HEADER DESTINATION "include")

The headers can be included in an other C++/CLI project after installing the nuget package.

2
  • Did the above cmake rules create .targets for you inside nuget specs file? It didn't work for me, so checking.
    – LKB
    Commented Dec 9, 2022 at 5:05
  • The nuget spec file contains the ID of the main project, but no sub targets. I use nuget to install a native library in a MSVC CLI project. I also added MSBuild scrips to integrate the library in the MSVC CLI project for propper linking. The build scripts are also part of the nuget package and auto generated with cmake based on some rules
    – Dirk Adler
    Commented Mar 17, 2023 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.