Installing a symlink with a relative path for RPM

$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
set(CPACK_PACKAGING_INSTALL_PREFIX "/")
execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/foo)
install(FILES ${CMAKE_BINARY_DIR}/foo DESTINATION usr/bin)
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../bin/foo ${CMAKE_BINARY_DIR}/bar)
install(FILES ${CMAKE_BINARY_DIR}/bar DESTINATION usr/lib)
include(CPack)

# $ mkdir build && cd build && cmake .. && make && cpack -G RPM && rpm2cpio *.rpm | cpio -dimv && ls -al usr/lib/bar
# ...
# ... usr/lib/bar -> /usr/bin/foo

# I expected a relative symlink, usr/lib/bar -> ../bin/foo
$ cmake --version
cmake3 version 3.14.6

CMake suite maintained and supported by Kitware (kitware.com/cmake).

Is it a valid relative symlink in the install destdir under _CPack_Packages as well or just in the RPM?

For RPM, the symlink is absolute under _CPack_Packages. What’s weird is that for TGZ the symlink is relative.

$ tree -a
...
── _CPack_Packages
│   └── Linux
│       ├── RPM
│       │   ├── BUILD
│       │   ├── BUILDROOT
│       │   ├── Project-0.1.1-Linux
│       │   │   └── usr
│       │   │       ├── bin
│       │   │       │   └── foo
│       │   │       └── lib
│       │   │           └── bar -> /usr/bin/foo
│       │   ├── rpmbuildproject.err
│       │   ├── rpmbuildproject.out
│       │   ├── RPMS
│       │   │   └── Project-0.1.1-Linux.rpm
│       │   ├── SOURCES
│       │   ├── SPECS
│       │   │   ├── project.spec
│       │   │   └── project.spec.in
│       │   ├── SRPMS
│       │   └── tmp
│       └── TGZ
│           ├── Project-0.1.1-Linux
│           │   └── usr
│           │       ├── bin
│           │       │   └── foo
│           │       └── lib
│           │           └── bar -> ../bin/foo
│           └── Project-0.1.1-Linux.tar.gz

Hmm. Tracing where that resolution is happening would be really nice. I wonder if rpmbuild is making it absolute somehow? cmake_install.cmake doesn’t differ between the two I think, so it’d have to be the other step which is converting it somewhere. Does CPACK_RPM_PACKAGE_RELOCATABLE make a difference?

I tried cpack with --trace-expand, it appears that CPackRPM.cmake is creating the absolute symlink:

/usr/share/cmake3/Modules/Internal/CPack/CPackRPM.cmake(537):  execute_process(COMMAND /usr/bin/cmake3 -E create_symlink /usr/bin/foo /home/anoyes/tmp/build/_CPack_Packages/Linux/RPM/Project-0.1.1-Linux//usr/lib/bar )

CPACK_RPM_PACKAGE_RELOCATABLE does not make a difference

That sounds like an issue to me. Though I don’t know who’s maintaining CPackRPM lately.