본문으로 건너뛰기
cccskills
무료GitHub에 공개

linkers-lto

Use when choosing a linker, fixing link order or undefined symbol errors, enabling LTO or ThinLTO, or cutting dead code with --gc-sections. Not for inspecting the linked binary: use elf-inspection.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(3)

  • SKILL.md6.2 KB
  • agents/openai.yaml204 B
  • references/flags.md5.3 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Linkers and LTO

The linker turns object files into one binary and decides what survives from each translation unit. Most link failures are order problems; most size wins are LTO plus dead-code removal.

Contract

FieldBound contract
TriggerThe task fixes undefined reference or multiple definition errors, selects a linker, enables LTO or ThinLTO, removes dead code, controls symbol visibility, or reads a linker map.
AuthorityReversible local: writes only build flags, linker scripts, and build outputs; rollback is version control and a rebuild. No remote mutation.
Side effectLocal writes to the outputs the build produces and to build configuration the user names.
DoneThe link succeeds with the intended flags, or the size and visibility changes are proven by the map, --print-gc-sections, or nm -D output.

Inputs

  • The failing link command or build configuration: required.
  • Toolchain in use: required. GCC and Clang differ in LTO setup and archive tools.
  • Whether LTO must be incremental: required before choosing ThinLTO over full LTO.

Procedure

  1. Select the linker through the compiler driver. ld is the universal default, gold is the retired-in-name C++ linker kept for legacy builds, lld is the fast choice and the practical requirement for Clang LTO on large projects. Verify which linker actually ran from the driver's verbose output. Done when: the build uses the intended linker.
gcc  -fuse-ld=lld -o prog main.c
clang -fuse-ld=lld -o prog main.c
gcc -v main.c -o prog 2>&1 | grep 'collect2\|ld\.new\|lld'
  1. Pass flags correctly. The driver forwards linker flags after -Wl, with commas instead of spaces. Done when: readelf -d or the map shows the flag took effect.
gcc main.o -o prog \
  -Wl,-rpath,/opt/mylibs/lib \
  -Wl,--as-needed \
  -Wl,--gc-sections \
  -Wl,-z,relro -Wl,-z,now \
  -L/opt/mylibs/lib -lfoo
  1. Fix link order. GNU ld resolves archives left to right; a library must follow the objects that use it. Circular archive dependencies need a group. Done when: the link succeeds without suppression flags.
gcc main.o -lfoo -ldep -o prog                    # dependents first
gcc main.o -Wl,--start-group -lfoo -lbar -Wl,--end-group -o prog
  1. Enable LTO with GCC. Every compile and the final link carry -flto with the same optimization level. LTO archives must be built with gcc-ar and gcc-ranlib, because plain ar cannot build the LTO symbol index. Done when: the link succeeds and size or performance improves against the non-LTO build.
gcc -O2 -flto -ffunction-sections -fdata-sections -c foo.c -o foo.o
gcc -O2 -flto -Wl,--gc-sections foo.o bar.o -o prog
gcc-ar rcs libfoo.a foo.o
gcc-ranlib libfoo.a
gcc -O2 -flto=auto foo.o bar.o -o prog   # parallel, uses the make jobserver
  1. Enable ThinLTO with Clang. ThinLTO parallelizes across machines and caches results, so incremental links stay fast. Done when: the link succeeds and the ThinLTO cache directory fills.
clang -O2 -flto=thin -fuse-ld=lld foo.c bar.c -o prog

In CMake, set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) selects the right LTO mode per compiler.

  1. Remove dead code. --gc-sections discards unreferenced sections, which only exist if compilation used -ffunction-sections -fdata-sections. Done when: --print-gc-sections reports the removals and the binary still runs.
gcc -O2 -ffunction-sections -fdata-sections -c foo.c -o foo.o
gcc -Wl,--gc-sections -Wl,--print-gc-sections foo.o -o prog
  1. Control visibility for LTO quality and DSO size. Hide everything, export the API. Done when: nm -D --defined-only libfoo.so lists only the public API.
gcc -fvisibility=hidden -O2 -shared -fPIC foo.c -o libfoo.so
# foo.ver
{
  global: my_public_function; my_other_public;
  local: *;
};
gcc -Wl,--version-script=foo.ver -shared -fPIC -o libfoo.so foo.o
  1. Read the map file when size or placement puzzles. Every symbol's origin and address is in the map. Done when: the surprising symbol is traced to its object and input section.
gcc -Wl,-Map=prog.map -o prog foo.o bar.o
  1. Diagnose by error class. Done when: each error maps to its row and the fix is applied.
ErrorCauseFix
undefined reference to 'foo'Missing or misordered libraryAdd -lfoo after the objects that need it
multiple definition of 'foo'Symbol defined in two objectsKeep one definition, or declare the other extern
cannot find -lfooLibrary outside -L pathsAdd -L or install the development package
relocation truncated to fitAddress outside the relocation's reachUse -mcmodel=large, or restructure the image layout
version 'GLIBC_2.xx' not foundBuilt on a newer glibcBuild on the older host or link statically
LTO bytecode mismatchMixed LTO and non-LTO objectsRecompile every object with the same -flto
file format not recognizedForeign architecture objectUse the matching cross toolchain for all objects

Failure and recovery

Failure classBehavior
LTO build fails on one objectThat object was compiled without -flto. Recompile it with the same flags as the rest.
--gc-sections removed a needed sectionSomething referenced it only from assembly or a linker script. Add KEEP(*(...)) in the script, or the reference.
ThinLTO cache grows without boundPoint -Wl,--thinlto-cache-dir at a managed path and clear it on a schedule.
A group link got slow--start-group rescans archives until fixed point. Resolve the cycle explicitly instead of leaving the group in place.
LTO changed behaviorInlining across units can expose latent UB. Reproduce without LTO, then fix the source.

Output

The linked binary plus the evidence for each decision: linker chosen, map excerpts, --print-gc-sections output, or nm -D export lists. The full flag tables, lld extras, MSVC /GL /LTCG, and a linker script skeleton are in references/flags.md.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when explaining System V AMD64, ARM AAPCS, RISC-V psABI, stack frames, variadic calls, or FFI register rules. Not for the Rust FFI binding layer: use rust-ffi.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

Use when configuring ADC sampling time, DMA-driven ADC, calibration, or DAC channel setup on bare-metal MCUs. Not for the DMA stream itself: use dma-baremetal.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

af-xdp

무료

Use when creating AF_XDP sockets, configuring UMEM and XSK rings, writing an XDP redirect program, or choosing copy versus zero-copy mode. Not for full kernel bypass: use dpdk.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

Use when a completed session needs an agent-environment retrospective. Not for an engineering retrospective from telemetry: use engineering-retrospective.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

Use when a redacted, trimmed agent transcript must be appended to a GitHub PR or issue body, with human approval and preview. Not for automated or model-initiated insertion.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

agents-md

무료

Use when a repo needs agent setup, AGENTS.md added or made lean, CLAUDE.md audited, or agent instructions scored or pruned. Not for remote, credential, publish, deploy, or irreversible changes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OutlineDriven/odin-claude-plugin372026년 9월 29일 업데이트

OutlineDriven의 스킬 모두 보기

이 스킬의 문제 신고