2011-07-09 11 views
25

Mam wspólną bibliotekę używaną przez inną aplikację, która jest poza moją kontrolą i która wymaga obiektów * .so. Moja biblioteka korzysta z sqlite3, który musi być statycznie połączony z nim (absolutnie potrzebuję samodzielnego pliku binarnego).C++ Statycznie połączona biblioteka współdzielona

Kiedy próbuję skompilować i połączyć moją bibliotekę:

-fpic -flto -pthread -m64 
-flto -static -shared 

I skończyć z powodu następującego błędu:

/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC 
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value 
collect2: ld returned 1 exit status 

Co Przekompiluj z flagą -fPIC związane? Mój kod lub CRT?

Próbowałem już skompilować mój obiekt za pomocą opcji -fPIC z tym samym wynikiem.

Dzięki.

EDIT:

Problem nie wydaje się być związane z SQLite3.

napisałem prostą bibliotekę jedna linia-do-niczego, co kompiluje i łącza takie jak ten:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -shared -o bar.so bar.o 

ale nie w ten sposób:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -static -shared -o bar.so bar.o 

Problem wydaje się być związane z CRT (crtbeginT.o). Czy mam rekompilować GCC - z pic-picem lub czymkolwiek?

+0

To trochę zagmatwane. Czy próbujesz po prostu połączyć bibliotekę ze statyczną biblioteką sqlite, czy też próbujesz zrobić coś innego? – nos

+0

PIC = kod niezależny od pozycji, wymagany dla bibliotek współdzielonych (na większości architektur, jak sądzę) – sehe

+0

@nos Próbuję połączyć moją bibliotekę współdzieloną z sqlite3.a – Petr

Odpowiedz

35

Nie należy użyć flagi -static podczas tworzenia biblioteki współdzielonej, to do tworzenia statycznie połączone pliki wykonywalne.

Jeśli masz tylko statyczną wersję biblioteki, możesz po prostu połączyć ją przy użyciu . Ale jeśli istnieje zarówno wersja dynamiczna (.so), jak i wersja statyczna, linker woli dynamiczny.

Aby polecić linkerowi wybranie statycznego, należy podać linkerowi flagę -Bstatic i przywrócić dynamiczne łączenie innych rzeczy (takich jak libc i dynamiczne środowisko uruchomieniowe) za pomocą -Bdynamic. Oznacza to, że używasz flag:

-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic 

Alternatywnie, możesz po prostu podać pełną ścieżkę pliku .a, np. /usr/lib/libsqlite3.a zamiast dowolnych flag kompilatora/łącznika.

Z GNU ld można również użyć -l:libsqlite3.a zamiast . Spowoduje to wymuszenie użycia pliku biblioteki libsqlite3.a zamiast libsqlite3.so, który linker preferuje domyślnie.

Pamiętaj, aby upewnić się, że plik .a został skompilowany z flagą -fpic, w przeciwnym razie zwykle nie można go osadzić w bibliotece współdzielonej.

+0

Mam tutaj ten sam problem i nie wiem, jak skompilować bibliotekę współdzieloną, która NIE PODŁĄCZA dynamicznie do personelu zależnego od dystrybucji, takiego jak libc/libstdC++ - "-Bstatic" udostępnia dynamicznie połączoną bibliotekę współdzieloną. Cudownie, używając MinGW na Windowsie mogę poprawnie powiązać plik .dll z '-static' (w zależności tylko od bibliotek Windows, ale nie od mingw). Czy istnieje sposób na połączenie statyczne ??? – Nick

+0

Nie. Współużytkowane biblioteki unix działają bardzo różnie od bibliotek Windows. – nos

+0

Sztuczka -l: libsqlite3.a działa także w eclipse cdt. Wpisz: libsqlite3.a w Właściwości-> C/C++ Build-> Ustawienia-> GCC C Linker-> Biblioteki i kompilacja będą statycznie łączyć się z biblioteką. – zztops

7

Każdy kod, który w jakiś sposób trafi do biblioteki dynamicznej, powinien zostać przeniesiony. Oznacza to, że wszystko, co jest powiązane z twoim .so, nieważne statycznie lub dynamicznie, powinno być skompilowane z -fPIC. W szczególności biblioteka statyczna sqlite powinna być również skompilowana z -fPIC.

Szczegóły co PIC pomocą tutaj: http://en.wikipedia.org/wiki/Position-independent_code

+0

Przekompilowałem program sqlite3 - z-pic, ale wynik jest nadal taki sam ... – Petr

+0

Publikuj pełne polecenia linków, które wykonujesz, abyśmy mogli dalej analizować) – vines

+0

Zobacz oryginalny wpis. – Petr

0

Miałem ten sam problem. Podobno -statyczny nie jest taki sam jak -Bstatic. Przełączyłem się na -Bstatic i wszystko działało.