-статический вариант для gcc?

Мне интересно, что делает параметр -static в gcc. Мне нужна эта опция при компиляции определенного приложения, но когда я все же получаю следующую ошибку:

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

Что требует установки?

Версия GCC:

[user@localhost 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) 

person sj755    schedule 01.01.2012    source источник


Ответы (2)


Параметр -static связывает программу статически, другими словами, для ее выполнения не требуется зависимость от динамических библиотек во время выполнения.

Для достижения статического связывания требуется, чтобы в системе существовали архивные (.a) версии ваших библиотек. поэтому /usr/lib/libc.a /usr/lib/crt1.o и т. д.

В современных системах Linux (как вы используете красную шляпу): когда двоичный файл связывает вместе, он 1) либо помещает код в исполняемый файл через файлы .o и .a, либо 2) помещает ссылки на файлы динамических библиотек (.so) это разрешается /lib/ld-linux.so (или /lib64/ld-linux=x86-64.so), который всегда находится в хорошо известном месте.

Для вашей конкретной системы, если программа специально пытается создать статическую версию самой себя, вам необходимо установить статические версии ваших инструментов разработки. Вам понадобится как минимум пакет glibc-static. Вам также может понадобиться пакет libstdc ++ - static.

person Ahmed Masud    schedule 01.01.2012

Флаг -static заставляет компоновщик принимать только статические библиотеки, а не какие-либо разделяемые библиотеки.

Если вы хотите использовать -static, вы должны убедиться, что у вас установлена ​​статическая версия библиотеки C, которую может быть сложно найти (в большинстве систем больше нет статической библиотеки C). Или нужно отменить действие -static. Однако в примере это нарушит цель -static, поскольку единственная связанная библиотека (неявно) является библиотекой C.

person Jonathan Leffler    schedule 01.01.2012
comment
Есть ли какая-то конкретная причина, по которой компоновщик не может просто статически прикреплять код из любых библиотек, доступных компоновщику? Даже если ссылки в коде отформатированы таким образом, что они должны быть разрешены во время выполнения, я бы подумал, что должна быть возможность прикрепить соответствующие процедуры к исполняемому файлу и исправить ссылки, чтобы они указывали на код в исполняемом файле. . - person supercat; 29.08.2014
comment
@supercat: В обычной архивной библиотеке отдельные объектные файлы идентифицируются отдельно и могут быть легко извлечены из библиотеки и связаны с исполняемым файлом. Мое впечатление (частично информированное) состоит в том, что разделяемые библиотеки не содержат отдельных объектных файлов таким же образом, поэтому вы получаете их целиком или ничего. Осмелюсь сказать, что можно было бы просто связать всю разделяемую библиотеку с исполняемым файлом, но это также может привести к встраиванию большого количества неиспользуемого кода. Я знаю, что некоторые крупные компании предпочитают использовать статические ссылки для всего - меньше риска неожиданных изменений. - person Jonathan Leffler; 29.08.2014
comment
Даже если код в конечном итоге придется загружать динамически, я бы посоветовал каждому установленному приложению по умолчанию получать свои собственные копии большинства библиотек. Если библиотеки необходимо обновить, это можно решить, если ОС сохранит для каждой программы настройки обновления [например, если программа, использующая FooLib 1.7, замечает, что FooLib 1.8 установлена, она может позволить пользователю запустить ее с 1.7 или 1.8 и сохранить выбор по умолчанию]. Таким образом, если в программе есть проблемы, связанные с FooLib, пользователь может обновить ее, но спонтанно ничего не изменится. - person supercat; 29.08.2014
comment
Интересно, почему системы не реализовали такую ​​функциональность в своей инфраструктуре выполнения программ? Как кто-то отметил в другом комментарии, линкеры раздражали в 1980-х и все еще раздражают 30+ лет спустя. Есть ли причина, по которой они должны быть? - person supercat; 29.08.2014
comment
Если реализуете, может, и воспользуются. Преимущество общих библиотек заключается в том, что вы изменяете общую библиотеку, и все приложения, которые ее используют, автоматически получают исправления ошибок в новой версии. Преимущества статического связывания заключаются в том, что вам не нужно беспокоиться об управлении разделяемой библиотекой, и приложение не меняется, пока вы его не перестроите. Если вы выберете маршрут статического связывания, то в конечном итоге вы получите более интенсивное использование памяти (каждый исполняемый файл имеет свою собственную копию общего кода), но вы знаете, что программы не изменятся случайно. - person Jonathan Leffler; 29.08.2014