Gentoo USE Flags: Choosing Between Global and Per-Package Configuration
A decision guide for Gentoo administrators on when to set USE flags globally in make.conf versus per-package in package.use/, with a comparison table, trade-off analysis, and a validated example enabling VA-API for Firefox only.
21 Aug 2025, 10:32 UTC

The Decision: Scope Your USE Flag Changes
Every Gentoo administrator eventually faces the same question: should a USE flag change go in /etc/portage/make.conf (global) or /etc/portage/package.use/ (per-package)? The answer determines whether you trigger a full system rebuild or a targeted update, and whether you accidentally break unrelated packages.
Takeaway: Default to per-package configuration in package.use/ unless a flag genuinely applies system-wide. Reserve global make.conf changes for architectural decisions (e.g., -systemd, wayland) that you intend to enforce everywhere.
Comparing Configuration Scopes
| Aspect | Global (make.conf) | Per-Package (package.use/) |
|---|---|---|
| Rebuild scope | Entire @world set on next emerge -uDN @world | Only the listed package(s) and their reverse dependencies |
| Consistency | Enforces uniform feature set across all builds | Allows exceptions; packages can diverge from global defaults |
| Maintenance burden | Low initial effort, high risk of unintended side effects | Higher initial effort, explicit and auditable |
| Typical use cases | Init system choice, GUI toolkit defaults, CPU instruction sets | Optional features (bluetooth, cups), backend selection (ffmpeg vs gstreamer), debug symbols |
| Rollback complexity | Requires full rebuild to revert cleanly | Revert single file, rebuild one package |
Trade-offs in Practice
Global Flags: The "Set and Forget" Trap
Adding USE="-bluetooth" to make.conf seems harmless—until you install bluez or a desktop environment that pulls in Bluetooth stack libraries. Portage will respect the global disable, potentially compiling packages without Bluetooth support they expect at runtime. The resulting segmentation faults or missing features often surface weeks later.
Conversely, enabling USE="debug" globally inflates every binary with debug symbols, consuming disk space and increasing build times for packages you never debug.
Per-Package Flags: Explicit Intent
A package.use/ entry like media-video/ffmpeg v4l2 documents why that package needs Video4Linux support. Future maintainers (including yourself) can read the file and understand the requirement without grepping build logs.
The cost: you must identify each package that needs the flag. Tools like equery and emerge --pretend make this manageable.
Concrete Implementation: Enabling Hardware Video Decoding for Firefox Only
Scenario: You want Firefox to use VA-API for hardware video decode, but you don't want to pull VA-API dependencies into every package that optionally supports it.
Step 1: Inspect Current State
# Run as root or with sudo
emerge -pv www-client/firefox
Output shows vaapi in the USE list but disabled (prefixed with -). Note the dependent packages that would change if you enable it globally.
Step 2: Create Per-Package Rule
# Create directory if it doesn't exist
mkdir -p /etc/portage/package.use
# Add rule for firefox only
echo 'www-client/firefox vaapi' > /etc/portage/package.use/firefox-vaapi
Step 3: Validate Dependency Impact
emerge -pv www-client/firefox
Verify that only firefox and its direct dependencies (e.g., media-libs/libva) are marked for rebuild. No unrelated packages should appear.
Step 4: Apply and Verify
emerge -av www-client/firefox
# After build completes, confirm the feature is active
equery uses www-client/firefox | grep vaapi
Expected output: [+] vaapi indicating the flag is enabled for the installed package.
Validation Checklist Before Any Global Change
- Preview the world rebuild:
emerge -puDN @world— count affected packages. If >50, reconsider. - Check reverse dependencies:
equery dshows what would break if you disable a flag globally. - Test in a container or VM: Apply the change in a throwaway environment first.
- Document the rationale: Add a comment in
make.confwith date, author, and reason (e.g.,# 2026-10-10: disable systemd per team decision).
Common Patterns Worth Global Setting
USE="-systemd"orUSE="systemd"— init system is a whole-system architectural choice.USE="-wayland"/USE="wayland"— display protocol affects most GUI packages.CPU_FLAGS_X86="avx2 fma"— hardware capability flags belong inmake.conf(orpackage.accept_keywordsfor per-package overrides).FEATURES="splitdebug"— debug symbol handling is a build-infrastructure decision.
Limitations and Gotchas
- USE flag dependencies: Some flags imply others (e.g.,
pulseaudiomay pullalsa). Checkequery uses --verboseto see the full expansion. - Profile defaults: Your selected profile (
eselect profile list) sets baseline USE flags. Globalmake.confoverrides these; per-packagepackage.useaugments them. - Masked or unstable flags: Flags prefixed with
~in ebuilds are experimental. Avoid enabling them globally. - Binary packages (binpkgs): If you use
FEATURES="getbinpkg", USE flag changes may not take effect until the binary package is rebuilt locally.
Practical Verification Commands
| Goal | Command | Run As |
|---|---|---|
| Show effective USE for a package | equery uses | user |
| Show USE flags defined in ebuild | equery uses --verbose | user |
| Preview rebuild with new flags | emerge -pv | root |
| List all package.use files | ls -la /etc/portage/package.use/ | root |
| Find packages with a specific flag | equery hasuse vaapi | user |
Rollback Procedure (Per-Package Only)
If a per-package change causes issues:
- Remove or comment the line in
/etc/portage/package.use/. - Run
emerge -avto rebuild without the flag. - No system-wide rebuild required.
Global changes require emerge -uDN @world to revert cleanly—plan for 30 minutes to several hours depending on package count.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.