Mam dwa pliki 37064544_p1.cpp
& 37064544_p2.cpp
o tej samej treści, jak pokazano poniżej:W jaki sposób są rozwiązywane symbole zewnętrzne?
int add(int x,int y)
{
return x+y;
}
Skompilowałem je za pomocą
g++ -c 37064544_p2.cpp -o 37064544_p2.o
g++ -c 37064544_p2.cpp -o 37064544_p2.o
i dodaje je do archiwum z wykorzystaniem
ar -rsc lib37064544pf.a 37064544_p1.o 37064544_p2.o
I
$ nm -s lib37064544pf.a
daje mi:
Archive index:
_Z3addii in 37064544_p1.o
_Z3addii in 37064544_p2.o
37064544_p1.o:
0000000000000000 T _Z3addii
37064544_p2.o:
0000000000000000 T _Z3addii
i
$ ar -t lib37064544pf.a
daje mi
37064544_p1.o
37064544_p2.o
mam kierowca, który wywołuje funkcję _Z3addii
który jest skompilowany z
g++ -static 37064544driver.cpp -o 37064544driver.elf -L. -l37064544pf
Wynik jest
Sum : 11
Pytania
Jak jest symbol
_Z3addii
rozwiązany?- Czy jest według indeksu archiwum?
- Czy jest to zgodne z kolejnością, w jakiej zapełniamy archiwum za pomocą
ar
?
Jak mogę zmienić tę kolejność?
- Jak mogę zapobiec dodawaniu powtarzających się symboli przez
ar
?
Compiler: g ++ 4.6.3
Hmmmm, właśnie próbowałem tego na klang. Jeśli skompilujesz z dwoma plikami .o bezpośrednio, otrzymasz duplikat błędu symbolu, ale jeśli umieścisz dwa pliki .o w pliku .a i skompilujesz je z tym, to nie ma błędu. Zawsze uważałem, że .a był po prostu wygodnym sposobem na zbieranie plików .o, ale wygląda na to, że jest pod pewnymi względami inny. – xaxxon
Znacznik 'r' do ar wydaje się, że oznacza to, że rzeczy dodane do archiwum później zastąpią wcześniejsze, chociaż zamiast tego uruchomię je za pomocą q, nadal nie mogę uzyskać duplikatu błędu symbolu. Czy linker przestaje przeglądać pojedynczy plik, gdy napotyka pierwszy wpis dla symbolu, którego szuka? – xaxxon
@xaxxon: 'Jeśli skompilujesz z dwoma plikami .o bezpośrednio, otrzymasz duplikat błędu symbolu,'. Tak, ale nie zawsze jestem za tym dla wygody – sjsam