Линкер (компоновщик) выполняет связывание объектных файлов и библиотек в единую исполняемую программу или библиотеку. Его работа включает:
// main.cpp
extern void foo(); // Объявление
int main() { foo(); }
// lib.cpp
void foo() {} // Определение
Линкер сопоставляет объявления (declarations) с определениями (definitions).
Объектные файлы содержат различные секции:
.text
- исполняемый код.data
- инициализированные данные.bss
- неинициализированные данные.rodata
- read-only данныеЛинкер объединяет однотипные секции из разных файлов.
Корректирует относительные и абсолютные адреса в объединенном коде.
g++ main.cpp lib.cpp -o program
g++ main.cpp -lsharedlib -o program
g++ -c file.cpp # Создает file.o
ld file1.o file2.o # Линкует объектные файлы
ar rcs libmylib.a file1.o file2.o # Создает архив
g++ main.cpp -L. -lmylib # Использует библиотеку
g++ -shared -o libmylib.so file1.o file2.o
g++ main.cpp -L. -lmylib
Сбор всех объектных файлов
Линкер получает на вход .o файлы и библиотеки
Сканирование на неразрешенные символы
Поиск внешних ссылок (undefined references)
Поиск определений в библиотеках
Проверка статических и динамических библиотек
Разрешение конфликтов
Обработка дубликатов, weak/strong символов
Оптимизация
Удаление неиспользуемого кода (dead code elimination)
Генерация выходного файла
Создание исполняемого файла или библиотеки
Причины:
// file1.cpp
int global = 42;
// file2.cpp
int global = 100; // Ошибка линковки
Решение:
extern
или static
// A.h
struct A { B* b; };
// B.h
struct B { A* a; };
Решение:
Указание путей поиска:
g++ -L/path/to/libs -lmylib
Контроль видимости символов:
g++ -fvisibility=hidden
Оптимизации:
g++ -Wl,--gc-sections # Удаление неиспользуемых секций
Отладочная информация:
g++ -g # Включение debug символов
Modules:
Link-time optimization (LTO):
g++ -flto # Межмодульная оптимизация
Резюмируем: линкер выполняет критически важную работу по объединению разрозненных объектных файлов и библиотек в согласованную исполняемую программу, разрешая символы, объединяя секции и релоцируя адреса. Понимание процесса линковки необходимо для диагностики распространенных проблем и создания оптимальных бинарных файлов.