Linkers Lto

mohitmishra786/low-level-dev-skills/skills/binaries/linkers-lto

作者 mohitmishra786bdc58472fa9f無授權條款253 個星標收錄於 2026年10月9日更新於 2026年10月9日儲存庫3 個月前更新

Linker and Link-Time Optimisation (LTO) skill. Use when configuring GNU ld, gold, or lld linker flags, diagnosing link-order issues or undefined symbols at link time, enabling LTO safely in real projects, or understanding inter-module optimisation trade-offs. Activates on queries about linker flags, -flto, thin LTO, LTCG, --gc-sections, link order errors, weak symbols, or linker scripts.

AI 產生的概覽

指導連結器選擇、連結器旗標、連結順序問題、LTO 設定以及符號可見性,適用於 GNU ld、gold 和 lld。

功能
此技能提供在 GNU ld、gold 和 lld 之間選擇的說明,以及常用連結器旗標的套用方式,例如 -Wl,--as-needed、--gc-sections 和 RELRO 選項。它說明封存檔的連結順序規則,包括 --start-group/--end-group,並涵蓋 GCC 與 Clang 的 LTO 啟用方式,包括 ThinLTO 和 CMake 程序間最佳化。它也涉及死碼剝除、透過 -fvisibility=hidden 和版本指令碼控制符號可見性、常見連結錯誤以及對應檔產生。隨附的參考檔案列出連結器和 LTO 旗標。
適用情境
在為 GNU ld、gold 或 lld 設定連結器旗標時使用,或在診斷連結期問題(例如未定義參考、重複或弱符號、封存檔循環相依)時使用。它也適合在實際專案中安全啟用 LTO、使用 --gc-sections 縮小二進位檔大小,以及理解連結器指令碼或模組間最佳化取捨。
執行需求
不附指令碼,僅為說明性內容。依範例操作需要帶連結器(GNU ld、gold 或 lld)的 C/C++ 工具鏈、GCC 或 Clang,以及 ar、gcc-ar、gcc-ranlib 等 binutils 工具。不需要憑證或網路存取。

Linkers and LTO

Purpose

Guide agents through linker selection, common linker flags, link-order issues, LTO setup, and symbol-visibility management.

Triggers

  • "I'm getting undefined reference at link time"
  • "How do I enable LTO for a real project?"
  • "Which linker should I use: ld, gold, or lld?"
  • "How do I reduce binary size with --gc-sections?"
  • "How do I write or understand a linker script?"
  • "I have duplicate symbol or weak symbol issues"

Workflow

1. Linker selection

LinkerInvocationStrengths
GNU ld (BFD)default on LinuxUniversal, stable
gold-fuse-ld=goldFaster than ld for C++; supports LTO plugins
lld (LLVM)-fuse-ld=lldFastest, parallel, required for Clang LTO
bash
# Use lld with GCC or Clanggcc -fuse-ld=lld -o prog ...clang -fuse-ld=lld -o prog ...
# Check which linker is usedgcc -v -o prog main.c 2>&1 | grep 'Invoking'

2. Essential linker flags

bash
# 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. Link order matters (GNU ld)

GNU ld processes archives left-to-right. A library must come after the objects that need it.

bash
# Wrong: libfoo provides symbols needed by main.ogcc main.o -lfoo libdep.a -o prog   # can fail if libdep.a needs libfoo
# Correct: dependencies after dependentsgcc 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. LTO with GCC

bash
# Compilegcc -O2 -flto -ffunction-sections -fdata-sections -c foo.c -o foo.ogcc -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 argcc-ar rcs libfoo.a foo.ogcc-ranlib libfoo.a

Parallel LTO:

bash
gcc -O2 -flto=auto foo.o bar.o -o prog   # uses jobservergcc -O2 -flto=4   foo.o bar.o -o prog    # 4 parallel jobs

5. LTO with Clang / lld

bash
# Full LTOclang -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 globallyset(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)   # enables -flto

ThinLTO caches work: subsequent builds that reuse unchanged modules are faster. Cache location: specify with -Wl,--thinlto-cache-dir=/tmp/thinlto-cache.

6. Dead-code stripping

bash
# Compile with per-function/per-data sectionsgcc -O2 -ffunction-sections -fdata-sections -c foo.c -o foo.o
# Link with garbage collectiongcc -Wl,--gc-sections foo.o -o prog
# Verify what was removedgcc -Wl,--gc-sections -Wl,--print-gc-sections foo.o -o prog 2>&1 | head -20

On macOS, the linker strips dead code by default (-dead_strip).

7. Symbol visibility

Controlling visibility reduces DSO size and enables better LTO:

bash
# Hide all symbols by default, export explicitlygcc -fvisibility=hidden -O2 -shared -fPIC foo.c -o libfoo.so
# In source, mark exports:__attribute__((visibility("default"))) int my_public_function(void);

Or use a version script:

text
# foo.ver{  global: my_public_function; my_other_public;  local: *;};
bash
gcc -Wl,--version-script=foo.ver -shared -fPIC -o libfoo.so foo.o

8. Common linker errors

ErrorCauseFix
undefined reference to 'foo'Missing library or wrong orderAdd -lfoo; move after the object that needs it
multiple definition of 'foo'Symbol defined in two TUsRemove duplicate; use static or extern
cannot find -lfooLibrary not in search pathAdd -L/path/to/lib; install dev package
relocation truncatedAddress overflow in relocationUse -mcmodel=large; restructure image
version 'GLIBC_2.33' not foundBinary needs newer glibcLink statically or rebuild on older host
circular referenceArchives mutually dependUse --start-group/--end-group

9. Linker map file

bash
# Generate a map file (shows symbol → section → file)gcc -Wl,-Map=prog.map -o prog foo.o bar.oless prog.map

Useful for debugging binary size and symbol placement.

For a comprehensive linker and LTO flags reference, see references/flags.md [blocked].

Related skills

  • Use skills/binaries/elf-inspection for examining the resulting binary
  • Use skills/compilers/gcc or skills/compilers/clang for compile-phase LTO flags
  • Use skills/binaries/binutils for ar, strip, objcopy

來源與署名

來源:mohitmishra786/low-level-dev-skills位於skills/binaries/linkers-lto提交bdc5847

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架