С ++ отличаются между связыванием с.o и с.a файлом: другое поведение, почему?

Я ожидал, что:

связь с файлом.o и связь с файлом.a, заархивированным из файла.o, не должны иметь различий.

Но на самом деле это не так. У меня есть 2 исходных файла, каждый из которых объявляет 1class+1 статический объект + 1 функцию и main.cpp, который вызвал одну из функций

$cat First.cpp
#include<stdio.h>
struct First{
  First(){printf("First\n");}
};
void f1(){printf("f1\n");}//Not called in main
static First f_obj;

$cat Second.cpp
#include<stdio.h>
struct Second{
  Second(){printf("Second\n");}
};
void f2(){printf("f2\n");}//Not called in main
static Second s_obj;

$cat main.cpp
void f2();
int main()
{
    f2();
    return 0;
}

$g++ -c First.cpp  -fPIC
$g++ -c Second.cpp -fPIC
$ar -rvs libmystatic.a  First.o Second.o
$g++ main.cpp -o MylinkSta -lmystatic -L.
$g++ main.cpp -o MyDirect First.o Second.o

$./MylinkSta
Second
f2

$./MyDirect
Second
First
f2

Так что вы можете видеть

(1) Результат выполнения MylinkSta не создает первый объект, но MyDirect делает.

(2) В то время как "Второй" объект всегда создается.

Я действительно не вижу никакой разницы между связыванием с двумя файлами '.o' и связыванием с файлом '.a', который заархивирован из этих двух файлов '.o'.

Почему они ведут себя по-разному? Я экспериментировал с gcc/clang на rhel/ubuntu, все показывают один и тот же результат. Интересно, есть ли какой-либо стандарт C++ ABI, который говорит, когда должен быть действительно вызван созданный статический / глобальный объект, с помощью любого варианта связывания?

Откуда эта разница?

1 ответ

Решение

Это связано с семантикой статических библиотек. Линкер будет включать файлы из статической библиотеки только в том случае, если он содержит символ, на который ссылается некоторый объектный файл, который предшествует ему в командной строке (например, main.cpp ссылается на f2 из Second, поэтому он включен). Вы можете изменить это поведение, окружив свою библиотеку

-Wl,--whole-archive -lmystatic -Wl,--no-whole-archive

но это не стандартно

Другие вопросы по тегам