Skip to content

Add opt-in CPack support for RPM and DEB packaging - #3904

Open
jameshickman wants to merge 4 commits into
aws:mainfrom
jameshickman:cpack-packaging
Open

Add opt-in CPack support for RPM and DEB packaging#3904
jameshickman wants to merge 4 commits into
aws:mainfrom
jameshickman:cpack-packaging

Conversation

@jameshickman

@jameshickman jameshickman commented Aug 27, 2026

Copy link
Copy Markdown

Issue #, if available: #843 (also relevant to #1888)

Description of changes:

Adds opt-in CPack support for building RPM and DEB packages of the SDK, split into per-service-group components rather than one monolithic package.

Everything is behind a new ENABLE_CPACK_PACKAGING option that defaults to OFF.

I verified what "off" actually means rather than assuming it: I configured the core build twice — once with the four modified files reverted to their upstream contents, and once with them as they are on this branch and the option OFF — then diffed every generated cmake_install.cmake. They are identical except for one deliberate difference, described below. No include(CPack), no changed install components, no new targets.

The one difference with the option OFF: the bulk cmake/ directory install gains five EXCLUDE patterns. Those patterns only ever match files this PR adds (CPackConfig.cmake, CPackComponents.cmake, ServiceGroupMapping.cmake, rpm-scripts/, deb-scripts/). They are unconditional on purpose — without them, a packaging-disabled build would start shipping this branch's build-only scaffolding into consumers' lib/cmake/AWSSDK. Keeping them always-on is what makes the installed tree byte-for-byte identical to today's.

What it produces

With -DENABLE_CPACK_PACKAGING=ON, cpack -G RPM / -G DEB generate separate runtime and -devel packages per service group (e.g. aws-sdk-cpp-core, aws-sdk-cpp-core-devel, aws-sdk-cpp-crt, aws-sdk-cpp-crt-devel), with:

  • version-pinned cross-package dependencies (-devel → matching runtime, crt-develcore-devel)
  • runtime shared-library deps resolved via AUTOREQ / SHLIBDEPS instead of hardcoded distro package names (avoids the libcurl vs curl, libssl3 vs libssl1.1 split across distros)
  • the -devel dependency target switched between the runtime and -static package based on BUILD_SHARED_LIBS, so static-only builds don't depend on a runtime package that was never produced

New files

  • cmake/CPackConfig.cmake, cmake/CPackComponents.cmake — CPack setup and per-component naming/dependency config
  • cmake/ServiceGroupMapping.cmake — maps the ~400 generated service clients into installable groups
  • cmake/rpm-scripts/, cmake/deb-scripts/ — post-install/post-remove ldconfig scriptlets
  • scripts/build-packages.sh — convenience wrapper
  • docs/PACKAGING.md — build/install/consume documentation

Modified files

  • CMakeLists.txt — the ENABLE_CPACK_PACKAGING option and three gated hooks
  • cmake/setup_cmake_find_module.cmake — tag config-module installs with the core-devel component, and exclude build-only files from the bulk cmake/ install so they aren't shipped to consumers
  • cmake/utilities.cmake, src/aws-cpp-sdk-core/CMakeLists.txt — component routing on existing install rules

No generated client code is touched, and no changes were made under code-generation/.

Scope / limitations

  • Linux only (RPM + DEB). No effect on Windows, macOS, iOS, or Android builds.
  • Wired into the LEGACY_BUILD path (the current default). The -DLEGACY_BUILD=OFF modern-CMake path is not covered — happy to extend it if you'd prefer that first.

Check all that applies:

  • Did a review by yourself.
  • Added proper tests to cover this PR. (If tests are not applicable, explain.)
    • No automated tests added. This is a packaging/build-system change with no runtime code, and the repo has no existing harness for asserting on generated .rpm/.deb artifacts. Verified manually on Linux: (a) the configure-time A/B diff of generated install rules described above, confirming the option genuinely gates the feature; (b) with the option ON, cpack -G RPM emits the expected per-component package set, with rpm -qp --requires / dpkg-deb --info showing correct inter-package Requires/Depends and autodetected shared-library deps. Glad to add a CI job that builds packages and asserts on the output if you'd like that as part of this PR.
  • Checked if this PR is a breaking (APIs have been changed) change. — Not breaking; no public API or ABI change, and the feature is off by default.
  • Checked if this PR will not introduce cross-platform inconsistent behavior. — Gated to opt-in Linux packaging; other platforms are unaffected.
  • Checked if this PR would require a ReadMe/Wiki update. — Added docs/PACKAGING.md.

Check which platforms you have built SDK on to verify the correctness of this PR.

  • Linux
  • Windows
  • Android
  • MacOS
  • IOS
  • Other Platforms

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

telendry and others added 4 commits August 27, 2026 10:27
`cpack -G RPM` previously produced packages named aws-sdk-cpp-Devel /
-Development / -Runtime / -Unspecified with no inter-package Requires --
none of the per-component naming or dependency config in the macros took
effect. Verified end-to-end: cpack now generates aws-sdk-cpp-{core,
core-devel, crt, crt-devel} with correct Requires (system devel libs,
cross-package version-pinned deps, AUTOREQ for shared libs).

CPackComponents.cmake:
- Uppercase component name on the LHS of CPACK_RPM/DEBIAN_<COMPONENT>_*
  sets (CPack uppercases before lookup, so lowercase names were ignored)
- Drop \${CPACK_PACKAGE_VERSION} backslash escape so CMake substitutes
  the version at configure time (CPack does not re-expand ${...} -- RPM
  uses %{...} for macros, not ${...})
- Force macro-arg dereference via "${GROUP_NAME}" in if() -- a bare
  GROUP_NAME inside macro() is a variable lookup, not a substitution,
  so the non-core branch was running for core too and overwriting the
  standalone CORE-DEVEL_PACKAGE_REQUIRES
- Switch devel-package dep target between runtime and -static based on
  BUILD_SHARED_LIBS so static-only builds don't depend on a runtime
  package that was never produced
- Drop hardcoded distro-specific runtime package names (libcurl vs curl,
  libssl3 vs libssl1.1); rely on AUTOREQ/SHLIBDEPS for runtime deps
- include(CPackComponent) so cpack_add_component_group works -- this
  file runs before include(CPack) loads the helper
- Route aws-crt-cpp's Runtime/Development install components to
  aws-sdk-cpp-crt[-devel] rpm/deb names and add the crt-devel cross-dep
  on core-devel

CPackConfig.cmake:
- CPACK_COMPONENTS_GROUPING IGNORE (was ONE_PER_GROUP, which collapsed
  runtime+devel into a single package and bypassed all per-component
  name/Requires variables)

CMakeLists.txt:
- Move include(ServiceGroupMapping.cmake) before add_sdks() so
  get_service_group_component is defined when each service's
  setup_install/do_packaging runs -- otherwise every install fell
  through to "Unspecified"
- Default CMAKE_INSTALL_DEFAULT_COMPONENT_NAME to "Development" around
  add_subdirectory(crt/aws-crt-cpp) so the CRT submodules that install
  without an explicit COMPONENT (aws-c-http, aws-c-compression headers)
  merge into the crt-devel package instead of producing a stray rpm

setup_cmake_find_module.cmake:
- Tag installs with COMPONENT core-devel (was landing in Unspecified)
- Exclude build-only files (CPackConfig.cmake, CPackComponents.cmake,
  ServiceGroupMapping.cmake, rpm-scripts/, deb-scripts/) from the bulk
  cmake/ directory install so they don't ship to consumers

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four install() calls picked up a COMPONENT argument unconditionally, so
they changed behavior even with ENABLE_CPACK_PACKAGING=OFF: the three
find_package(AWSSDK) config installs moved from CPack's implicit
"Unspecified" bucket to "core-devel", and the exported targets file moved
from "Unspecified" to "Devel". A plain `make install` was unaffected, but
component-scoped installs (cmake --install --component ...) were not.

Wrap those in a variable that expands to nothing when the option is off,
so the option genuinely gates the whole feature.

The EXCLUDE patterns on the bulk cmake/ directory install are left
unconditional on purpose: they only match files this branch adds, so
keeping them always-on leaves the installed tree identical to before
rather than shipping build-only scaffolding to consumers.

Verified by configuring core with the four modified files reverted to
upstream and again with ENABLE_CPACK_PACKAGING=OFF: the generated
cmake_install.cmake files are identical apart from those EXCLUDEs. With
the option ON, core-devel and core-runtime components are still assigned.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YCSRkLxHYetVoe421e5fha
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant