2012-01-01 19 views
13

Zastanawiam się, co robi opcja -static na gcc. Ta opcja jest mi potrzebna podczas kompilowania określonej aplikacji, ale gdy to zrobię, pojawia się następujący błąd:-statyczna opcja dla gcc?

gcc -static -O3 -o prog prog.c 
/usr/bin/ld: cannot find -lc 
collect2: ld returned 1 exit status 

Co wymaga instalacji?

wersja GCC:

[[email protected] dir]$ gcc -v 
Using built-in specs. 
COLLECT_GCC=gcc 
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.6.1/lto-wrapper 
Target: x86_64-redhat-linux 
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux 
Thread model: posix 
gcc version 4.6.1 20110908 (Red Hat 4.6.1-9) (GCC) 

Odpowiedz

-23

Powinieneś zasadniczo unikać statycznego łączenia aplikacji (powinieneś wyjaśnić nam, dlaczego nie chcesz używać zwykłego dynamicznego łączenia). Sugeruję przynajmniej dynamiczne powiązanie bibliotek systemowych (w szczególności: libc) - jeśli absolutnie chcesz, możesz statycznie łączyć mniej popularnych bibliotek. Dlaczego chcesz statycznie połączyć swoją aplikację? Jest to generalnie błąd (ponieważ nie korzystasz z aktualizacji do dynamicznych bibliotek systemowych). W szczególności name service switch obiektów z libc chce dynamicznych bibliotek.

Twój system powinien mieć zainstalowany pakiet udostępniający statyczną bibliotekę libc. Na Debianie jest to pakiet libc-dev, ale nie wiem, co to jest na RedHacie.

Aby dowiedzieć się, co gcc ma, przekaż flagę -v jak

gcc -v -static -O3 -o prog prog.c 

Ale nie należy połączyć statycznie programów. W moich dystrybucjach Debiana istnieje ponad 700 programów w /usr/bin i tylko jeden jest statycznie połączony.

+0

Nie byłem pewien, co robi. Używam wcześniej istniejącej aplikacji iz jakiegoś powodu ma ona tę opcję w pliku makefile. W tym momencie myślę, że to już nie powinno mieć znaczenia. Dzięki. – sj755

+29

-1: Ukrywa odpowiedź w dużej mierze z powodu ograniczonych faktów pomocniczych. – mattnz

5

-static flag zmusza łącznik, aby przyjmować tylko statycznych bibliotek i nie wszystkie biblioteki współdzielone.

Jeśli chcesz używać -static, musisz upewnić się, że masz zainstalowaną statyczną wersję biblioteki C, co może być trudne do znalezienia (większość systemów nie ma już statycznej biblioteki C). Lub musisz anulować efekt -static. Jednak w tym przykładzie można by pokonać cel -static, ponieważ jedyną połączoną biblioteką jest (niejawnie) biblioteka C.

+1

Czy istnieje jakiś szczególny powód, dla którego nie powinno być możliwe po prostu połączenie linkera statycznie z bibliotekami, które są dostępne dla łącznika?Nawet jeśli odniesienia w kodzie są sformatowane w taki sposób, że muszą zostać rozwiązane w czasie wykonywania, myślę, że powinno być możliwe dołączenie odpowiednich procedur do pliku wykonywalnego i poprawienie referencji tak, aby wskazywały kod w pliku wykonywalnym . – supercat

+0

@supercat: W zwykłej bibliotece archiwum poszczególne pliki obiektów można oddzielnie zidentyfikować i można je łatwo wyodrębnić z biblioteki i połączyć w pliku wykonywalnym. Moje wrażenie (na pół poinformowane) polega na tym, że biblioteki współdzielone nie zawierają osobnych plików obiektów w ten sam sposób, więc dostajesz całą partię lub nic nie dostajesz. Śmiem twierdzić, że możliwe jest po prostu połączenie całej biblioteki współdzielonej z plikiem wykonywalnym, ale może to doprowadzić do powstania zbyt wielu nieużywanych kodów. Wiem, że niektóre duże firmy wolą używać linków statycznych do wszystkiego - mniejsze ryzyko nieoczekiwanej zmiany. –

+1

Nawet jeśli kod zostanie wyświetlony dynamicznie, sugeruję, aby zainstalowane aplikacje domyślnie otrzymywały własne kopie większości bibliotek. Jeśli biblioteki wymagają aktualizacji, można to zrobić, utrzymując system operacyjny dla każdego programu w "ustawieniach uaktualnienia" [np. jeśli program wykorzystujący FooLib 1.7 zauważy, że "FooLib 1.8" jest zainstalowany, może zezwolić użytkownikowi na uruchomienie go z wersją 1.7 lub 1.8 i zapisać wybór jako domyślny]. W ten sposób, jeśli program ma problemy związane z FooLib, użytkownik może je zaktualizować, ale rzeczy nie zmieniłyby się spontanicznie. – supercat

33

Opcja -static łączy statycznie program, innymi słowy nie wymaga uzależnienia od bibliotek dynamicznych w środowisku wykonawczym, aby można go było uruchomić.

Osiągnięcie łączenia statycznego wymaga istnienia archiwum (.a) wersji bibliotek w systemie. więc /usr/lib/libc.a /usr/lib/crt1.o etc ...

Na nowoczesnych systemach Linux (jak używasz czerwony kapelusz): kiedy binarny łączy je 1) albo stawia kod do pliku wykonywalnego poprzez pliki .o i .a lub 2) umieszcza odniesienia do plików bibliotek dynamicznych (.so), które są rozwiązywane przez /lib/ld-linux.so (lub/lib64/ld-linux = x86-64. tak), który jest zawsze w dobrze znanym miejscu.

W przypadku konkretnego systemu, jeśli program chce utworzyć statyczną wersję samego siebie, należy zainstalować statyczne wersje narzędzi devel. Potrzebujesz co najmniej pakietu statycznego glibc. Możesz również potrzebować pakietu libstdC++ - statycznego.