2016-05-06 25 views
10

Я два файла 37064544_p1.cpp & 37064544_p2.cpp с тем же содержанием, как показано ниже:Как разрешаются внешние символы?

int add(int x,int y) 
{ 
return x+y; 
} 

Я собирал их с помощью

g++ -c 37064544_p2.cpp -o 37064544_p2.o 
g++ -c 37064544_p2.cpp -o 37064544_p2.o 

и добавили их в архив с помощью

ar -rsc lib37064544pf.a 37064544_p1.o 37064544_p2.o 

И

$ nm -s lib37064544pf.a 

дает мне:

Archive index: 
_Z3addii in 37064544_p1.o 
_Z3addii in 37064544_p2.o 

37064544_p1.o: 
0000000000000000 T _Z3addii 

37064544_p2.o: 
0000000000000000 T _Z3addii 

и

$ ar -t lib37064544pf.a 

дает мне

37064544_p1.o 
37064544_p2.o 

У меня есть драйвер, который вызывает функцию _Z3addii которая компилируется с

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. -l37064544pf 

Результат

Sum : 11 

Вопросы

  1. Как символ _Z3addii решённые?

    • В соответствии с индексом архива?
    • Это порядок, в котором мы заполняем архив, используя ar?
  2. Как я могу изменить этот заказ?

  3. Как я могу предотвратить ar от дубликатов символов?

Компилятор: г ++ 4.6.3

+1

Хммм, я просто попробовал это по clang. Если вы скомпилируете с двумя файлами .o напрямую, вы получите дубликат символьной ошибки, но если вы поместите два файла .o в .a и скомпилируете их, тогда ошибки не будет. Я всегда думал, что .a - это просто удобный способ получить кучу файлов .o, но, похоже, это по-другому. – xaxxon

+1

Флаг 'r' для ar кажется, что это означает, что вещи, добавленные в архив позже, заменят более ранние, хотя вместо этого он запускает его с q, я все равно не могу получить дублируемую символьную ошибку. Ли линкер перестает смотреть на один файл, когда он встречает первую запись для символа, который он ищет, может быть? – xaxxon

+0

@xaxxon: 'Если вы скомпилируете с двумя файлами .o, вы получите дубликат символьной ошибки'. Да, но я не всегда в пользу этого ради удобства – sjsam

ответ

2

Как символ _Z3addii решен?

Реализация может делать все, что угодно, вы нарушаете one definition rule.

Реально он перестанет искать любой символ после первого совпадения, который, по-видимому, следует порядку, в который файлы были вставлены в архив.

Как я могу изменить этот заказ?

С ar вы можете использовать a (после) и b (до) модификаторы для размещения объектных файлов в архиве при вставке их, вы по-прежнему нарушает ODR, хотя.

Как предотвратить дублирование символов ar?

Вы не можете, насколько я знаю, ar относительно тупые и по уважительной причине, как некоторые языки позволяют для одинаковых символов, поэтому у вас нет каких-либо ошибок при связывании с архивом (нет требуется диагностика нарушений ODR).

Вы можете силой ld читать весь архив

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. \ 
-Wl,--whole-archive -l37064544pf -Wl,--no-whole-archive 

Или вы можете сделать частичную ссылку вместо традиционного архива, который даст вам ошибку, если есть какие-либо дубликаты

ld -r -o lib37064544pf.a 37064544_p1.o 37064544_p2.o 
+0

Thankyou Я согласен с тем, что нарушаю ODR, но это было специально для этого примера. Однако больший интерес был обнаружен при архивировании объектного кода. Спасибо за то, что он частично связан. Я также хотел бы добавить объекты в разные библиотеки и связать их в том порядке, в котором я хочу. – sjsam