mcpField
L
linkers-lto

linkers-lto

github.com/mohitmishra786開発269619 回インストール18 週間前に更新
リポジトリ

linkers-lto について

リンカーと LTO を扱うエージェント向けのスキルです。リンカーの選択、フラグ、リンク順序、シンボル可視性、リンク時のエラー対処を説明します。

主な機能

  1. 01GNU ld、gold、lld の選択
  2. 02リンカーフラグとライブラリ順序の設定
  3. 03GCC または Clang での LTO 設定
  4. 04未使用セクションの削除
  5. 05シンボル可視性とマップファイルの管理

活用シーン

  1. 01undefined reference エラーの診断
  2. 02プロジェクトでの LTO 有効化
  3. 03バイナリサイズの削減
  4. 04重複シンボルや循環依存の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill linkers-lto

インストール後、Claude Code で/linkers-ltoを入力して読み込まれたか確認します。

同梱ファイルreferences/flags.md

詳細

リンカーと LTO

目的

リンカーの選択、よく使われるリンカーフラグ、リンク順序の問題、LTO の設定、シンボル可視性の管理について、エージェントを案内します。

トリガー

  • 「リンク時に undefined reference が発生します」
  • 「実際のプロジェクトで LTO を有効にする方法を教えてください」
  • 「ld、gold、lld のどのリンカーを使うべきですか?」
  • 「--gc-sections でバイナリサイズを小さくする方法を教えてください」
  • 「リンカースクリプトの書き方や読み方を教えてください」
  • 「重複シンボルまたは弱シンボルの問題が発生しています」

ワークフロー

1. リンカーの選択
リンカー呼び出し方長所
GNU ld (BFD)Linux でのデフォルト汎用的で安定しています
gold-fuse-ld=goldC++ では ld より高速です。LTO プラグインをサポートします
lld (LLVM)-fuse-ld=lld最速で並列処理に対応し、Clang LTO に必要です
# Use lld with GCC or Clang
gcc -fuse-ld=lld -o prog ...
clang -fuse-ld=lld -o prog ...

# Check which linker is used
gcc -v -o prog main.c 2>&1 | grep 'Invoking'
2. 基本的なリンカーフラグ
# Pass linker flags via compiler driver:
# -Wl,flag1,flag2   (comma-separated, no spaces)
# -Wl,flag1 -Wl,flag2  (separate -Wl options)

gcc main.c -o prog \
  -Wl,-rpath,/opt/mylibs/lib \     # runtime library search path
  -Wl,--as-needed \                 # only link libraries that are actually used
  -Wl,--gc-sections \               # remove unused sections (requires -ffunction-sections -fdata-sections)
  -Wl,-z,relro \                    # mark relocations read-only after startup
  -Wl,-z,now \                      # resolve all symbols at startup (full RELRO)
  -L/opt/mylibs/lib -lfoo
3. リンク順序が重要です(GNU ld)

GNU ld はアーカイブを左から右へ処理します。ライブラリは、それを必要とするオブジェクトの後に指定する必要があります。

# Wrong: libfoo provides symbols needed by main.o
gcc main.o -lfoo libdep.a -o prog   # can fail if libdep.a needs libfoo

# Correct: dependencies after dependents
gcc main.o -lfoo -ldep -o prog

# If there are circular deps between archives:
gcc main.o -Wl,--start-group -lfoo -lbar -Wl,--end-group -o prog
# --start-group/--end-group: repeat search until no new symbols resolved
4. GCC での LTO
# Compile
gcc -O2 -flto -ffunction-sections -fdata-sections -c foo.c -o foo.o
gcc -O2 -flto -ffunction-sections -fdata-sections -c bar.c -o bar.o

# Link (must pass -flto again)
gcc -O2 -flto -Wl,--gc-sections foo.o bar.o -o prog

# Archives: must use gcc-ar / gcc-ranlib, not plain ar
gcc-ar rcs libfoo.a foo.o
gcc-ranlib libfoo.a

並列 LTO:

gcc -O2 -flto=auto foo.o bar.o -o prog   # uses jobserver
gcc -O2 -flto=4   foo.o bar.o -o prog    # 4 parallel jobs
5. Clang / lld での LTO
# Full LTO
clang -O2 -flto -fuse-ld=lld foo.c bar.c -o prog

# ThinLTO (faster, nearly same quality)
clang -O2 -flto=thin -fuse-ld=lld foo.c bar.c -o prog

# LTO with cmake: set globally
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)   # enables -flto

ThinLTO は作業内容をキャッシュします。変更されていないモジュールを再利用する以降のビルドは高速になります。 キャッシュの場所:-Wl,--thinlto-cache-dir=/tmp/thinlto-cache で指定します。

6. デッドコードの除去
# Compile with per-function/per-data sections
gcc -O2 -ffunction-sections -fdata-sections -c foo.c -o foo.o

# Link with garbage collection
gcc -Wl,--gc-sections foo.o -o prog

# Verify what was removed
gcc -Wl,--gc-sections -Wl,--print-gc-sections foo.o -o prog 2>&1 | head -20

macOS では、リンカーがデフォルトでデッドコードを除去します(-dead_strip)。

7. シンボル可視性

可視性を制御すると、DSO サイズを削減でき、LTO もより効果的になります。

# Hide all symbols by default, export explicitly
gcc -fvisibility=hidden -O2 -shared -fPIC foo.c -o libfoo.so

# In source, mark exports:
__attribute__((visibility("default"))) int my_public_function(void);

または、バージョンスクリプトを使用します。

# foo.ver
{
  global: my_public_function; my_other_public;
  local: *;
};
gcc -Wl,--version-script=foo.ver -shared -fPIC -o libfoo.so foo.o
8. よくあるリンカーエラー
エラー原因対処方法
undefined reference to 'foo'ライブラリが指定されていないか、順序が間違っています-lfoo を追加し、それを必要とするオブジェクトの後に移動します
multiple definition of 'foo'シンボルが 2 つの TU で定義されています重複を削除するか、static または extern を使用します
cannot find -lfooライブラリが検索パスにありません-L/path/to/lib を追加するか、開発用パッケージをインストールします
relocation truncated再配置でアドレスがオーバーフローしています-mcmodel=large を使用するか、イメージの構成を変更します
version 'GLIBC_2.33' not foundバイナリがより新しい glibc を必要としています静的リンクするか、より古いホスト上で再ビルドします
circular referenceアーカイブが相互に依存しています--start-group/--end-group を使用します
9. リンカーマップファイル
# Generate a map file (shows symbol → section → file)
gcc -Wl,-Map=prog.map -o prog foo.o bar.o
less prog.map

バイナリサイズとシンボルの配置をデバッグする際に役立ちます。

リンカーと LTO のフラグについて詳しくは、references/flags.md を参照してください。

関連スキル

  • 生成されたバイナリの検査には skills/binaries/elf-inspection を使用します
  • コンパイルフェーズの LTO フラグには skills/compilers/gcc または skills/compilers/clang を使用します
  • ar、strip、objcopy には skills/binaries/binutils を使用します

コメント