User:Kentnl/Thinking In Prefix

From Gentoo Wiki
Jump to:navigation Jump to:search

I'm just gonna start encoding how I understand the various prefix control structures in the hope somebody finds it useful, and maybe some salient documentation can emerge from it.


In my understanding, EPREFIX is a string that is to be considered to be possibly injected into the final binaries, but also used to derive a "final resting place" relative to "the root of your target environment", and is used for various install paths.

In that, if EPREFIX was "/alternative", and the code was compiled with:


That a binary shipped with the package would be intended to get stored in "/alternative/usr/bin/myname", and in the final environment of execution, running said binary, that binary could also <stat /alternative/usr/bin/myname> and expect to find itself.

This is not a chroot situation, and doing a chroot into 'alternative' would give you a broken chroot, as calling <stat /alternative/usr/bin/myname> would get translated by the kernel to <stat /alternative/alternative/usr/bin/myname>, which wouldn't exist.

In a pure chroot situation, it would be ROOT that changes, and this should be invisible during src_compile and friends.

Portage would set EPREFIX="", the code would compile (mostly) under the assumption its getting installed to "/", while *actually* getting installed to a path in /var/tmp/portage/...../image/, which would then get transplanted to your chroot path "/alternative-chroot". That way, inside the chroot, all the paths are predicted to be sensible.

Subsequently, unless you're doing things outside the various src_* phases, that need to modify paths in the final destination, you probably don't need to even think about ROOT or EROOT, as these are paths portage has mostly dealt with for you.

Various builtin functions also assume you want EPREFIX used, so if a function like etouch existed, etouch /file would implicitly mean touch "${EPREFIX}/file



  1. Must be available on the final target at runtime
  2. May not be necessarily usable on the build environment (CBUILD) if cross-compilation is occurring.




Currently, tests are run directly on the CBUILD host, and there's no way not to. Subsequently, if the tests can't be run under cross-compile, the right approach is not to run tests at all. (eg: with some RESTRICT magic or a gate in src_test)

This means that as a result, the test dependencies must be available in BDEPEND.

For perl, this means that the "standard" value of BDEPEND should be:

       test? ( $TEST_REQUIRES )

As upstream declares that all runtime requirements must be satisfied prior to invoking make/Build, and all runtime/configure/build requirements listed in META.* must be satisfied prior to invoking perl Makefile.PL or perl Build.PL ( And various failures can occur if you don't satisfy this, and (potentially copious) warnings are expected to occur if you don't satisfy this, and their formatting is prone to users thinking things are broken and filing bugs, even if no real problem exists )

In theory we could do:

       test? ( $RDEPEND $TEST_REQUIRES )

Which would pull in RDEPEND on the build host only when running tests, which would give portage more opportunities to potentially elide installing RDEPEND values unless strictly necessary (ie: conceptually, most perl packages can be built and installed without any dependencies at all, but configure is where things can get funky because upstream likes do do thing special on a regular basis, including changing behaviour based on what is presently installed ), but there's lots of risks with increased fragility, and to the best of my knowledge, portage can't presently make use of these opportunities anyway.