diff --git a/Help/cpack_gen/nuget.rst b/Help/cpack_gen/nuget.rst index d97f0c0c13..7192209012 100644 --- a/Help/cpack_gen/nuget.rst +++ b/Help/cpack_gen/nuget.rst @@ -41,6 +41,14 @@ List of CPack NuGet generator specific variables: :Mandatory: No :Default: ``OFF`` +.. variable:: CPACK_NUGET_SYMBOL_PACKAGE + + .. versionadded:: 4.1 + + Generate a Nuget symbol package (.snupkg). + + :Mandatory: No + :Default: ``OFF`` Required metadata variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Help/release/dev/cpack-nuget-symbol-package.rst b/Help/release/dev/cpack-nuget-symbol-package.rst new file mode 100644 index 0000000000..38eaf6c169 --- /dev/null +++ b/Help/release/dev/cpack-nuget-symbol-package.rst @@ -0,0 +1,6 @@ +cpack-nuget-symbol-package +-------------------------- + +* The :cpack_gen:`CPack NuGet Generator` gained option + :variable:`CPACK_NUGET_SYMBOL_PACKAGE` to generate NuGet + symbol packages containing PDB files. diff --git a/Modules/Internal/CPack/CPackNuGet.cmake b/Modules/Internal/CPack/CPackNuGet.cmake index 9b6cc91daf..5c3e451c46 100644 --- a/Modules/Internal/CPack/CPackNuGet.cmake +++ b/Modules/Internal/CPack/CPackNuGet.cmake @@ -468,6 +468,12 @@ if(CPACK_NUGET_PACKAGE_DEBUG) list(APPEND CPACK_NUGET_PACK_ADDITIONAL_OPTIONS "-Verbosity" "detailed") endif() +# Generate symbol package +if(CPACK_NUGET_SYMBOL_PACKAGE) + list(APPEND CPACK_NUGET_PACK_ADDITIONAL_OPTIONS "-Symbols") + list(APPEND CPACK_NUGET_PACK_ADDITIONAL_OPTIONS "-SymbolPackageFormat" "snupkg") +endif() + # Case one: ordinal all-in-one package if(CPACK_NUGET_ORDINAL_MONOLITIC) # This variable `CPACK_NUGET_ALL_IN_ONE` set by C++ code: @@ -552,9 +558,19 @@ else() endif() endif() -file(GLOB_RECURSE GEN_CPACK_OUTPUT_FILES "${CPACK_TEMPORARY_DIRECTORY}/*.nupkg") -if(NOT GEN_CPACK_OUTPUT_FILES) + +file(GLOB_RECURSE GEN_CPACK_NUGET_PACKAGE_FILES "${CPACK_TEMPORARY_DIRECTORY}/*.nupkg") +if(NOT GEN_CPACK_NUGET_PACKAGE_FILES) message(FATAL_ERROR "NuGet package was not generated at `${CPACK_TEMPORARY_DIRECTORY}`!") endif() +list(APPEND GEN_CPACK_OUTPUT_FILES "${GEN_CPACK_NUGET_PACKAGE_FILES}") + +if(CPACK_NUGET_SYMBOL_PACKAGE) + file(GLOB_RECURSE GEN_CPACK_NUGET_SYMBOL_PACKAGE_FILES "${CPACK_TEMPORARY_DIRECTORY}/*.snupkg") + if(NOT GEN_CPACK_NUGET_SYMBOL_PACKAGE_FILES) + message(FATAL_ERROR "NuGet symbol package was not generated at `${CPACK_TEMPORARY_DIRECTORY}`!") + endif() + list(APPEND GEN_CPACK_OUTPUT_FILES "${GEN_CPACK_NUGET_SYMBOL_PACKAGE_FILES}") +endif() _cpack_nuget_debug("Generated files: ${GEN_CPACK_OUTPUT_FILES}") diff --git a/Tests/RunCMake/CPack_NuGet/NuGetSymbol-cpack-NuGet-check.cmake b/Tests/RunCMake/CPack_NuGet/NuGetSymbol-cpack-NuGet-check.cmake new file mode 100644 index 0000000000..0edf206021 --- /dev/null +++ b/Tests/RunCMake/CPack_NuGet/NuGetSymbol-cpack-NuGet-check.cmake @@ -0,0 +1,31 @@ +file(GLOB generated_nuspec "${RunCMake_TEST_BINARY_DIR}/_CPack_Packages/*/NuGet/GeneratorTest-1.2.3-*/CPack.NuGet.nuspec") +if(NOT generated_nuspec) + set(RunCMake_TEST_FAILED "No nuspec file generated under ${RunCMake_TEST_BINARY_DIR}") +else() + # Read in the generated nuspec file content + file(STRINGS "${generated_nuspec}" actual_nuspec REGEX "^.*[^ ]+$") + # Read in the expected file content + file(STRINGS "${CMAKE_CURRENT_LIST_DIR}/expected.nuspec" expected_nuspec REGEX "^.*[^ ]+$") + + # Compare the file contents + string(COMPARE EQUAL "${actual_nuspec}" "${expected_nuspec}" nuspec_matches) + + if(NOT nuspec_matches) + set(RunCMake_TEST_FAILED "generated nuspec file incorrect") + set(failure_msg "") + # This would be nicer with a `diff` output, but it needs to be portable + string(APPEND failure_msg "\nExpected file:\n") + string(APPEND failure_msg "${expected_nuspec}") + string(APPEND failure_msg "Actual file:\n") + string(APPEND failure_msg "${actual_nuspec}") + set(RunCMake_TEST_FAILURE_MESSAGE "${failure_msg}") + endif() +endif() + +if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/GeneratorTest.1.2.3.nupkg") + set(RunCMake_TEST_FAILED "NuGet standard package not generated") +endif() + +if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/GeneratorTest.1.2.3.snupkg") + set(RunCMake_TEST_FAILED "NuGet symbol package not generated") +endif() diff --git a/Tests/RunCMake/CPack_NuGet/RunCMakeTest.cmake b/Tests/RunCMake/CPack_NuGet/RunCMakeTest.cmake index af8ad31a23..7daa457460 100644 --- a/Tests/RunCMake/CPack_NuGet/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPack_NuGet/RunCMakeTest.cmake @@ -5,3 +5,4 @@ set(env_PATH "$ENV{PATH}") set(RunCPack_GENERATORS NuGet) run_cpack(NuGetLib) +run_cpack(NuGetSymbol) diff --git a/Tests/RunCMake/RunCPack/NuGetSymbol/CMakeLists.txt b/Tests/RunCMake/RunCPack/NuGetSymbol/CMakeLists.txt new file mode 100644 index 0000000000..18ea2eac24 --- /dev/null +++ b/Tests/RunCMake/RunCPack/NuGetSymbol/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 4.0) # FIXME: Actually requires 4.1 +project(CPackNugetGenerator) + +install(FILES notactuallyalib.dll DESTINATION lib/net4) +install(FILES notactuallyalib.pdb DESTINATION lib/net4) +install(FILES alsonotalib.dll DESTINATION lib/net6.0) +install(FILES alsonotalib.pdb DESTINATION lib/net6.0) + +# Create NuGet package +set(CPACK_GENERATOR NuGet) +set(CPACK_PACKAGE_NAME GeneratorTest) +set(CPACK_PACKAGE_VERSION "1.2.3") +set(CPACK_PACKAGE_VENDOR "ACME Inc") +set(CPACK_NUGET_SYMBOL_PACKAGE ON) +set(CPACK_NUGET_PACKAGE_OWNERS "ACME Inc") +set(CPACK_PACKAGE_DESCRIPTION "A NuGet package for testing CMake's CPack NuGet generator") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A test NuGet package") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://www.example.com") +set(CPACK_NUGET_PACKAGE_REPOSITORY_URL "https://github.com/example/nugetlib.git") +set(CPACK_NUGET_PACKAGE_REPOSITORY_TYPE git) +set(CPACK_NUGET_PACKAGE_LICENSE_EXPRESSION "MIT") + +# Set up dependencies +set(CPACK_NUGET_PACKAGE_TFMS "net4;net6.0") +set(CPACK_NUGET_PACKAGE_DEPENDENCIES_net4 "Foo;Bar") +# NB: If a version number is omitted, the dependency will not be created +set(CPACK_NUGET_PACKAGE_DEPENDENCIES_net4_Foo_VERSION "1.23") +set(CPACK_NUGET_PACKAGE_DEPENDENCIES_net4_Bar_VERSION "4.3.2") +# NB: General dependencies (not framework-specific) go in this variable +set(CPACK_NUGET_PACKAGE_DEPENDENCIES "Baz") +set(CPACK_NUGET_PACKAGE_DEPENDENCIES_Baz_VERSION "9.8.6") +# NB: Since "net6.0" was listed but no dependencies have been specified, an empty group +# will be added to the nuspec file for this framework. This can be used to address `NU5128`_. + +include(CPack) diff --git a/Tests/RunCMake/RunCPack/NuGetSymbol/alsonotalib.dll b/Tests/RunCMake/RunCPack/NuGetSymbol/alsonotalib.dll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/RunCPack/NuGetSymbol/alsonotalib.pdb b/Tests/RunCMake/RunCPack/NuGetSymbol/alsonotalib.pdb new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/RunCPack/NuGetSymbol/notactuallyalib.dll b/Tests/RunCMake/RunCPack/NuGetSymbol/notactuallyalib.dll new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Tests/RunCMake/RunCPack/NuGetSymbol/notactuallyalib.pdb b/Tests/RunCMake/RunCPack/NuGetSymbol/notactuallyalib.pdb new file mode 100644 index 0000000000..e69de29bb2