mcpField
L
linkers-lto

linkers-lto

github.com/mohitmishra786开发269619 次安装18 周前更新
代码仓库

关于 linkers-lto

面向 Agent 的链接器与 LTO 技能,涵盖链接器选择、链接参数、链接顺序、符号可见性及常见错误排查。

主要功能

  1. 01选择 GNU ld、gold 或 lld
  2. 02配置常用链接参数和链接顺序
  3. 03设置 GCC 或 Clang 的 LTO
  4. 04通过节回收剔除未用代码
  5. 05控制符号可见性并生成映射文件

适用场景

  1. 01排查 undefined 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

目的

引导 Agent 选择链接器、使用常见链接器标志、处理链接顺序问题、设置 LTO,以及管理符号可见性。

触发条件

  • “我在链接时遇到了 undefined reference”
  • “如何为实际项目启用 LTO?”
  • “我应该使用哪个链接器:ld、gold 还是 lld?”
  • “如何使用 --gc-sections 减小二进制文件的大小?”
  • “如何编写或理解链接器脚本?”
  • “我遇到了重复符号或弱符号问题”

工作流

1. 选择链接器
链接器调用方式优点
GNU ld (BFD)Linux 上的默认选项通用、稳定
gold-fuse-ld=gold对 C++ 来说比 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'符号在两个 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 检查生成的二进制文件
  • 使用 skills/compilers/gcc 或 skills/compilers/clang 查看编译阶段的 LTO 标志
  • 使用 skills/binaries/binutils 了解 ar、strip、objcopy

评论

支持 Markdown