Portage 専用の手冊。リポジトリ情報、目標設定、インストール済み版、world の選択を分けて再構築と depclean を考える。保守権限のある端末で実行し、profile 変更や全再構築を日常修復にしない。
情報を同期して変更予定を見る
環境記録・repository 同期・移行通知
emerge --info
調査用に全出力を保存し、共有前に固有情報を確認する。保守には対応する権限が必要。
emerge --sync
インストール済み package は更新しない。同期失敗を直してから更新計画を読む。
eselect news list
eselect news read 1
1 は実番号に置き換える。profile・Python・toolchain 移行の前提作業を先に行う。
依存解決を確認して同じ範囲を更新する
emerge -pvuDN @world --verbose-conflicts
-p は予覧、-v は詳細、-u は更新、-D は依存を深く調べ、-N は new USE を確認する。blocker・slot・降格・再 build 理由を読む。
emerge -avuDN @world
-a が -p の代わり。設定・repository が変わった場合は新計画を確認する。設定を merge し主要 service を検証してから depclean を考える。
目的に応じて package を調べる
equery list '*'
equery は app-portage/gentoolkit に含まれる。以下は独立した照会。
equery uses app-editors/neovim
equery depends app-editors/neovim
逆依存の確認で、neovim 自身の必要 package 一覧ではない。
equery files app-editors/neovim
equery は gentoolkit、eix/qlist は任意。追加・更新・降格・再構築・slot・blocker を確認し、news を読んでから emerge -avuDN @world を実行する。構築依存の保持方針も揃える。
USE・keyword・mask の役割を分ける
| 設定 | 目的 | 注意 |
| package.use | ビルド機能 | equery uses で対応フラグを確認 |
| package.accept_keywords | 選択パッケージの testing 等を許可 | パッケージ・版を限定し全体 ** を避ける |
| package.mask / package.unmask | 候補版の制限・指定 atom の解除 | unmask だけで keyword や依存競合は解決しない |
別々の file 内容例。既存の directory・単一 file 構成に合わせて統合し、一つの file に連結しない。先に下の照会で flag 対応を確認する。
/etc/portage/package.use/editor
app-editors/vim python
/etc/portage/package.accept_keywords/editor
app-editors/neovim ~amd64
~amd64 は対応 architecture の testing keyword。必要な時だけ使い、全機の既定値にしない。
package 単位の変更前後を確認する
equery uses app-editors/vim
python は Vim の例。現 ebuild の対応を確認してから上の file へ統合する。
emerge -pv app-editors/vim
想定と違えば詳細な package.use・profile・mask を確認し、全体 USE を安易に増やさない。
USE 再 build の方針を選ぶ
emerge -pvuD --changed-use @world
実状態の変化を中心に扱い、下の --newuse と選択する。
emerge -pvuDN @world
本機の方針に合う一方を選び、実行時は他の選択肢を保って -p を -a にする。
--newuse と --changed-use の予覧は同一ではない。newuse は未有効フラグの追加・削除でも再構築し得る。changed-use は実際の変更を重視する。一時 USE 指定は package.use に保存されず、autounmask-write の出力も確認が必要。
world にないから削除可能とは限らない
図を準備しています
world の選択が依存を保持する仕組みdeselect は uninstall ではない。depclean は保護集合からの依存到達性で候補を決め、別 package の必要 library は残す。
{"id":"ops-portage-reachability","title":"world の選択が依存を保持する仕組み","summary":"deselect は uninstall ではない。depclean は保護集合からの依存到達性で候補を決め、別 package の必要 library は残す。","height":600,"html":"<main><p class=\"quiet\" data-i18n=\"scope\"></p><div class=\"checks\"><label><input id=\"a\" type=\"checkbox\" checked><span data-i18n=\"a\"></span></label><label><input id=\"b\" type=\"checkbox\" checked><span data-i18n=\"b\"></span></label></div><div class=\"row code\">A → X\nB → X, Y</div><div class=\"pair\"><div class=\"row\" id=\"nodeA\"><strong>A</strong> · <span id=\"statusA\"></span></div><div class=\"row\" id=\"nodeB\"><strong>B</strong> · <span id=\"statusB\"></span></div><div class=\"row\" id=\"nodeX\"><strong>X</strong> · <span id=\"statusX\"></span></div><div class=\"row\" id=\"nodeY\"><strong>Y</strong> · <span id=\"statusY\"></span></div></div><div class=\"explain\"><div class=\"stable \"><p class=\"reserve\" aria-hidden=\"true\" data-i18n=\"hint\"></p><p id=\"message\" aria-live=\"polite\"></p></div></div></main>\n","css":"main {\n display: grid;\n gap: 18px;\n min-width: 0;\n}\np {\n overflow-wrap: anywhere;\n}\n.controls {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n align-items: center;\n}\n.presets {\n display: flex;\n flex-wrap: wrap;\n}\n.presets button {\n flex: 1 1 85px;\n font-size: 15px;\n}\n.cards {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 10px;\n}\n.card {\n border: 1px solid var(--rule);\n border-radius: 10px;\n padding: 14px;\n min-width: 0;\n background: var(--surface);\n}\n.card h3 {\n font-size: 15px;\n color: var(--muted);\n margin-bottom: 8px;\n}\n.card strong {\n font-size: 23px;\n font-weight: 500;\n overflow-wrap: anywhere;\n}\n.code {\n font-family: var(--viz-font-mono);\n font-size: 15px;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.stable {\n display: grid;\n min-width: 0;\n}\n.stable > * {\n grid-area: 1/1;\n margin: 0;\n}\n.stable > .reserve {\n visibility: hidden;\n pointer-events: none;\n}\n.explain {\n border-left: 3px solid var(--accent);\n padding: 12px 14px;\n background: var(--accent-soft);\n}\n.arrow {\n text-align: center;\n color: var(--accent);\n font-size: 25px;\n}\n.row {\n padding: 12px;\n border: 1px solid var(--rule);\n border-radius: 8px;\n min-width: 0;\n}\n.row.on {\n border-color: var(--accent);\n background: var(--accent-soft);\n}\n.row.off {\n color: var(--muted);\n}\n.bar {\n height: 18px;\n background: var(--surface);\n border: 1px solid var(--rule);\n border-radius: 5px;\n overflow: hidden;\n margin-top: 8px;\n}\n.bar > i {\n display: block;\n height: 100%;\n background: var(--accent);\n width: 0;\n transition: width 0.22s;\n}\n.checks {\n display: grid;\n gap: 8px;\n}\n.checks label {\n display: flex;\n gap: 10px;\n align-items: center;\n padding: 9px;\n border: 1px solid var(--rule);\n border-radius: 7px;\n font-size: 16px;\n}\n.checks input {\n width: 18px;\n height: 18px;\n accent-color: var(--accent);\n flex-shrink: 0;\n}\nlabel.range {\n display: block;\n font-size: 16px;\n}\nlabel.range output {\n float: right;\n font-variant-numeric: tabular-nums;\n}\n.pair {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n}\n.flow {\n display: grid;\n gap: 6px;\n}\n.quiet {\n font-size: 14px;\n color: var(--muted);\n}\n.badge {\n display: inline-block;\n padding: 2px 8px;\n border-radius: 5px;\n background: var(--accent-soft);\n color: var(--accent);\n}\nbutton {\n overflow-wrap: anywhere;\n}\n.large {\n font-size: 32px;\n color: var(--accent);\n font-weight: 500;\n}\n.layers {\n display: grid;\n gap: 12px;\n}\n.layer {\n border-left: 3px solid var(--rule);\n padding-left: 12px;\n}\n.layer.on {\n border-color: var(--accent);\n}\n@media (max-width: 520px) {\n .cards,\n .pair {\n grid-template-columns: 1fr;\n }\n .card {\n padding: 12px;\n }\n .card strong {\n font-size: 22px;\n }\n}\n.pair .row {\n min-height: 4.5em;\n}\n","js":"const $ = (s) => document.querySelector(s);\nconst $$ = (s) => [...document.querySelectorAll(s)];\nconst t = (k) => viz.t(k);\nconst put = (id, v) => ($(\"#\" + id).textContent = v);\nconst say = (k) => put(\"message\", t(k));\nconst state = (v) => ($(\"main\").dataset.state = JSON.stringify(v));\nconst press = (key, v) =>\n $$(\"[data-\" + key + \"]\").forEach((b) =>\n b.setAttribute(\"aria-pressed\", String(b.dataset[key] === v)),\n );\nfunction draw() {\n const a = $(\"#a\").checked,\n b = $(\"#b\").checked,\n retained = { A: a, B: b, X: a || b, Y: b };\n for (const [k, v] of Object.entries(retained)) {\n put(\"status\" + k, t(v ? \"keep\" : \"candidate\"));\n $(\"#node\" + k).classList.toggle(\"on\", v);\n }\n state({ a, b, retained });\n}\n$$(\"input\").forEach((e) => (e.onchange = draw));\nsay(\"hint\");\ndraw();\n","audio":false,"strings":{"a":"world で A を選択","b":"world で B を選択","candidate":"削除候補","hint":"A を外しても B は X が必要。図は予定を計算するだけで全 package は導入済みのまま。","keep":"保持","scope":"簡略 graph:A→X、B→X/Y。四つとも導入済み。world 到達性だけを示し実 Portage の @system・slot・USE 等は省略。"}}
明示選択を確認して不要な目標を外す
cat /var/lib/portage/world
ユーザーの選択一覧で、@world の全依存ではない。選択 set・system/profile も関係する。
emerge --pretend --depclean
emerge --ask --deselect app-editors/neovim
選択だけを変更し、アンインストールしない。誤った場合は emerge --ask --noreplace app-editors/neovim で再選択できる。
再解決してから削除する
emerge --pretend --depclean
service・一時 tool・build 依存を確認する。他から必要なら deselect しても残る。
emerge --ask --depclean
更新と依存問題を先に解決し、--unmerge で一覧を強制しない。
emerge --ask @preserved-rebuild
emerge の案内に従い、主要 program・service を確認する。全障害を直す万能操作ではない。
更新後に清理予定全体を確認する。deselect は明示選択の解除だけで、他の依存があれば残る。-1 は world に追加しない。unmerge は依存保護を回避し得る。preserved-rebuild は保存済み共有ライブラリの利用者を再構築する。
設定統合・リポジトリ・ビルド失敗
設定更新:差分を探して統合する
find /etc -name '._cfg*'
権限エラーの場合、更新対象なしとは判断できない。
dispatch-conf
diff と本機固有設定を確認し、影響する service を検証してから reload/restart する。
eselect repository list
対応 module が必要。有効化と同期済みは別。
emaint sync -a
emerge --sync と機械的に連続実行しない。単体なら -r NAME を使う。
eselect profile show
gcc-config -l
失敗復旧:最初の error と計画を残す
less /var/log/emerge.log
q で終了。詳細は PORTAGE_TMPDIR 配下の package temp/build.log にあり、掃除前に保存する。
emerge --resume --pretend
対象を確認して emerge --resume --ask。必須 package の失敗を skipfirst で隠さず、設定目標が変われば再解決する。
| 問題 | 保存する根拠 | 対応 |
| ビルド失敗 | emerge --info; build.log | 対象の temp/build.log と最初の実エラーを保存 |
| 保護された設定の更新 | ._cfg* | dispatch-conf / etc-update で審査。自動承認という意味ではない |
| profile・Python・GCC 移行 | eselect news; emerge --info | 移行手順に従う。コマンド切替だけでは依存移行にならない |
overlay の出所と上書き範囲を確認して有効化・同期する。MAKEOPTS と emerge の同時ジョブ数はメモリ負荷を重ねるため観測で決める。内核削除では起動確認済みの旧版を残す。カーネル手冊を参照。
Gentoo Portage · USE · emerge manual