Handbook:Parts/Portage/Advanced
Readers should not try to follow instructions directly from the Handbook:Parts namespace (which is THIS page!). The sections displayed below are used as a skeleton for transcluding information into the computer architecture specific handbooks and are therefore lacking critical information.
Please visit the Handbook list to read instructions for a relevant computer architecture.
Introduction to Portage's advanced features
For most readers, the information received thus far is sufficient for all their Linux operations. But Portage is capable of much more; many of its features are for advanced customization purposes or are only applicable in specific corner cases.
Of course, with lots of flexibility comes a huge list of potential cases. It will not be possible to document them all here. Instead, the goal is to focus on some generic issues which can then be augmented to fit a particular niche. More tweaks and tips such as these can be found across the Gentoo wiki.
Most, if not all, of these additional features can be easily found by digging through the manual pages that are provided with Portage:
user $
man portage
user $
man make.conf
Finally, know that these are advanced features which, if not configured correctly, can make debugging and troubleshooting much more difficult. Be sure any of these sorts of customization is explicitly mentioned when opening a bug report.
Per-package environment variables
Using /etc/portage/env
By default, package builds will use the environment variables defined in /etc/portage/make.conf, such as CFLAGS, MAKEOPTS and others. In some cases, it is beneficial to provide different variables for specific packages. To do so, Portage supports the use of the /etc/portage/env directory and /etc/portage/package.env file.
The /etc/portage/package.env file contains a list of packages for which deviating environment variables are needed as well as a specific identifier that indicates to Portage which identifier file to apply. The identifier name is free format. Portage will look for a file with the exactly same case-sensitive name as the identifier. See the following example for more detail.
Example: Using debugging for specific packages
As an example, to enable debugging for the media-video/mplayer package.
Set the debugging variables in a file called /etc/portage/env/debug-cflags. The filename is arbitrarily chosen, but of course the name reflects the purpose of the file, which should make it obvious if reviewing later why the file exists. The /etc/portage/env directory will need created if it does not yet exist:
root #
mkdir /etc/portage/env
# Add -ggdb to CFLAGS for debugging
CFLAGS="-O2 -ggdb -pipe"
FEATURES="${FEATURES} nostrip"
Next, the media-video/mplayer package is 'tagged' to use the new debug identifier in the package.env file:
media-video/mplayer debug-cflags
Hooking into the emerge process
Using /etc/portage/bashrc and affiliated files
When Portage works with ebuilds, it uses a bash environment in which it calls the various build functions (like src_prepare
, src_configure
, pkg_postinst
, etc.). Portage allows system administrators to set up a specific bash environment.
The advantage of using a specific bash environment is that it allows for hooks into the emerge process during each step it performs. This can be done for every emerge (through /etc/portage/bashrc) or by using per-package environments (through /etc/portage/env as discussed earlier).
Portage calls so-called phase hook functions if they are defined in /etc/portage/bashrc. These functions follow the naming convention pre_phase_name
and post_phase_name
. For example, Portage will call the post_pkg_postinst
hook just after calling the pkg_postinst
phase function.
To hook in the process, the bash environment can listen to the variables that are always available during ebuild development (such as CATEGORY, P, PF, ...). Based on the values of these variables additional steps and/or functions can be executed.
Example: Updating the file database
In this example, the /etc/portage/bashrc file will be used to call some file database applications in order to ensure their databases are up to date with the system. The applications used in the example are aide (an intrusion detection tool) and updatedb (to use with mlocate), but these are meant as examples. Do not consider this as a guide for AIDE.
To use /etc/portage/bashrc for this case, we need to “hook” in the postinst
(after installation of files) and postrm
(after removal of files) phases, because that is when the files on the file system have been changed.
my_database_update() {
echo ":: Calling aide --update to update its database"
aide --update
echo ":: Calling updatedb to update its database"
updatedb
}
post_pkg_postinst() { my_database_update; }
post_pkg_postrm() { my_database_update; }
Executing tasks after ebuild repository syncs
Using /etc/portage/postsync.d location
In addition to hooking into the ebuild phases, Portage offers another option for hook functionality: postsync.d. These types of hooks are run after updating, also referred to as syncing, the Gentoo ebuild repository. In order to run tasks after updating the Gentoo repository, put scripts inside the /etc/portage/postsync.d directory. Be sure any files inside the directory have been marked as executable or they will not run.
Example: Running eix-update
If eix-sync was not used to update sync the repository, then it is still possible to update the eix database after running emerge --sync (or emerge-webrsync) by putting a symlink to /usr/bin/eix called eix-update in /etc/portage/postsync.d.
root #
ln -s /usr/bin/eix /etc/portage/postsync.d/eix-update
If a different name is chosen, then it needs to be a script that calls /usr/bin/eix-update instead. The eix binary looks at how it has been called to determine which function to execute. If a symlink were created that pointed to eix yet was not called eix-update, it would not run correctly.
Overriding profile settings
Using /etc/portage/profile
By default, Gentoo uses the settings contained in the profile pointed to by /etc/portage/make.profile, which is a symbolic link to the target profile directory. These profiles define both specific settings as well as inherit settings from other profiles (through their parent files).
By using /etc/portage/profile, system administrators can override profile settings such as packages (what packages are considered to be part of the system set), forced USE flags, and more.
Example: Adding nfs-utils to the system set
When using an NFS-based file systems for critical file systems, it might be necessary to mark net-fs/nfs-utils as a system package, which will cause Portage to heavily warn administrators in the event they would attempt to unmerge it.
To accomplish this, the package must be added to the /etc/portage/profile/packages file, prepended with a *
(asterisk symbol):
*net-fs/nfs-utils
Applying non-standard patches
Patching source code using user patches in /etc/portage/patches/
User patches provide a way to apply patches to package source code when sources are extracted before installation. This can be useful for applying upstream patches to unresolved bugs, or simply for local customizations.
Patches need to be dropped into /etc/portage/patches/. They will automatically be applied during package installation.
Patches can be dropped into any of the following directories:
- /etc/portage/patches/${CATEGORY}/${P}/ e.g. /etc/portage/patches/dev-lang/python-3.3.5-r1/
- /etc/portage/patches/${CATEGORY}/${PN}/ e.g. /etc/portage/patches/dev-lang/python-3.4.2/
- /etc/portage/patches/${CATEGORY}/${P}-${PR}/ e.g. /etc/portage/patches/dev-lang/python-3.3.5-r0/
Example: Applying patches to Firefox
The www-client/firefox package is one of the many that already call eapply_user
(possibly implicitly) from within the ebuild, so there is no need to override anything specific.
If for some reason (for instance because a developer provided a patch and asked to check if it fixes the bug reported) patching Firefox is wanted, all that is needed is to put the patch in /etc/portage/patches/www-client/firefox/ (it might be best to use the full name and version so that the patch does not interfere with later versions) and rebuild Firefox.