CPack empty archive with absolute install DESTINATION path

CMake install(TARGETS) allows an absolute path, but then CPack produces an empty archive. Is this intended behavior? Example CMakeLists.txt:

cmake_minimum_required(VERSION 3.30)
project(EmptyArchive)
add_executable(main main.cpp)
include(GNUInstallDirs)

install(TARGETS main
  RUNTIME
    # Contrived example showing that absolute path produces
    #    an empty CPack archive.
    DESTINATION /tmp/demo/${CMAKE_INSTALL_BINDIR}
    COMPONENT justExe
)

set(CPACK_GENERATOR TGZ)
set(CPACK_PACKAGE_NAME ${CMAKE_PROJECT_NAME})
set(CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
set(CPACK_VERBATIM_VARIABLES TRUE)

if (PROJECT_IS_TOP_LEVEL)
  include(CPack)
endif()

cpack_add_component(justExe
  DISPLAY_NAME  Boilerplate
  DESCRIPTION   "Demo empty archive"
  REQUIRED
  INSTALL_TYPES Full
)

I was surprised by this behavior, so I decided to share here per Craig’s suggestion. I fixed this problem as follows:

  1. Add set(CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION TRUE), rerun, fail. Oh, maybe because this variable exists, absolute install paths are discouraged?
  2. Add set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}), giving a parent install directory that I (as a non-admin user) have permission to write to.
  3. Change install to DESTINATION ${CMAKE_INSTALL_BINDIR} (relative path).
  4. This now produces the expected non-empty package, containing a single executable.

Is CMake install(TARGETS) wrong to allow absolute destination paths, or is CPack wrong for producing an empty archive under this condition, or is there some third option I’m missing? Thank you in advance for any insight!

The trouble is that some CPack generator allows absolute install path handling as a default behavior (CPackRPM, CPackDeb) whereas other (Archive (TGZ, ZIP , etc…)) do not.
In fact, it does not seems to make any sense to put an absolute path in an archive (including a TGZ), however RPM and DEB are meant to include absolute install path (e.g. for file going to /etc/…).

This “default behavior” is governed by https://cmake.org/cmake/help/latest/variable/CPACK_SET_DESTDIR.html#variable:CPACK_SET_DESTDIR
https://cmake.org/cmake/help/book/mastering-cmake/chapter/Packaging%20With%20CPack.html#cpack-and-destdir

So you can try to
set(CPACK_SET_DESTDIR "ON")
and you get you absolute install path into your TGZ.

CPackRPM and CPack DEB do set CPACK_SET_DESTDIR to ON internally (you don’t need to to do it)

Note: This will also not work with your example absolute install path configuration:

cmake --install build --prefix /tmp/test

see too cpack installation create empty archive · Issue #873 · DaveGamble/cJSON (github.com)

Thanks very much for your explanations. While I gave a contrived install DESTINATION above, the one that actually brought me to this problem is more believable as a CPack newcomer’s choice, I think: DESTINATION ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} seemed like a reasonable initial choice to me, but it produced the empty TGZ archive because of its absolute path.

I wasn’t striving to force an absolute install DESTINATION path. I naively picked an absolute path without knowing it, and then was surprised by the empty archive my choice produced.