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 从公开仓库中收录这些内容。

举报或申请下架