Skip to content

support: honor DESTDIR in install(CODE) steps - #1238

Open
takano32 wants to merge 1 commit into
avast:masterfrom
takano32:fix/support-install-destdir
Open

support: honor DESTDIR in install(CODE) steps#1238
takano32 wants to merge 1 commit into
avast:masterfrom
takano32:fix/support-install-destdir

Conversation

@takano32

Copy link
Copy Markdown
Contributor

Fixes #1177.

Problem

CMake automatically prepends $ENV{DESTDIR} to the destinations of install(TARGETS/FILES/DIRECTORY/PROGRAMS) rules, but not to paths baked into install(CODE) scripts. The support installation steps in support/CMakeLists.txt pass configure-time absolute paths (derived from CMAKE_INSTALL_PREFIX) directly, so a staged installation

DESTDIR=$(mktemp -d) make -C build install

fails with PermissionError: [Errno 13] Permission denied: '/usr/local/share/retdec' from install-share.py when run as a regular user (the exact failure in #1177) — or, worse, when run as root it executes retdec-yarac from, writes into, and REMOVE_RECURSEs directories under the live installation prefix. This breaks the standard packaging workflow (Debian, RPM, AUR, staged installs in general).

Fix

Prefix every absolute path inside the four install(CODE) strings with an install-time-evaluated \$ENV{DESTDIR} — the same idiom CMake uses in its own generated install rules. Notes:

  • When DESTDIR is not set, $ENV{DESTDIR} expands to an empty string, so a plain make install is byte-for-byte unchanged.
  • Running the staged retdec-yarac works because the project sets an $ORIGIN-relative RPATH.
  • The install(DIRECTORY ordinals ...) rule is intentionally untouched: CMake already applies DESTDIR there, and prefixing it again would double the path (the pitfall that broke the 2019 attempt CMake: unbreak make DESTDIR=/foo install #579 on the pre-rewrite build system).
  • The configure-time FILE(REMOVE_RECURSE) cache cleanup is left alone because DESTDIR is unknowable at configure time.

Testing

Ran DESTDIR=<stage> make -C build install end-to-end as a non-root user:

  • completed with exit 0 (previously: PermissionError + CMake Error at support/cmake_install.cmake),
  • support package downloaded and extracted into <stage>/usr/local/share/retdec/support/,
  • the staged retdec-yarac was executed, YARA rules compiled into the stage, version-yarac.txt written into the stage,
  • nothing was created or modified under the live /usr/local.

Also verified the generated support/cmake_install.cmake now carries $ENV{DESTDIR} on every previously-bare path.

🤖 Generated with Claude Code

https://claude.ai/code/session_014nNMVbAuffaPPQuYdLZgD1

CMake automatically prepends $ENV{DESTDIR} to the destinations of
install(TARGETS/FILES/DIRECTORY/PROGRAMS) rules, but not to paths
baked into install(CODE) scripts. The support installation steps
passed configure-time absolute paths (derived from
CMAKE_INSTALL_PREFIX) directly, so a staged installation

    DESTDIR=/tmp/stage make -C build install

either failed with PermissionError from install-share.py when run as
a regular user, or - worse - executed retdec-yarac from, wrote into,
and REMOVE_RECURSE'd directories under the live installation prefix
when run as root.

Prefix all absolute paths inside the install(CODE) strings with an
install-time-evaluated $ENV{DESTDIR}. When DESTDIR is not set the
variable expands to an empty string, so a plain 'make install' is
unchanged. The install(DIRECTORY ordinals ...) rule needs no change
because CMake already applies DESTDIR to it, and the configure-time
FILE(REMOVE_RECURSE) cache cleanup is left alone because DESTDIR is
unknowable at configure time.

Fixes avast#1177

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014nNMVbAuffaPPQuYdLZgD1
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.

support/cmake_install.cmake ignores DESTDIR

1 participant