Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.135.201.209] |
|
Сообщ.
#1
,
|
|
|
Написал Привет мир на "С"
#include <stdio.h> int main(void) { printf ("Hello World\n"); return 0; } Скомпилировал "gcc hw.c" Смотрим на использумые библиотеки "ldd a.out" Увидел: libc.so.6 => /lib/libc.so.6 (0x00002b09231ff000) /lib64/ld-linux-x86-64.so.2 (0x00002b0922dd1000) Вот и озадачиваюсь вопросом. Кто говорит линковщику, где это у него настроено, что именно libc библиотеку нужно эту брать libc.so.6 |
Сообщ.
#2
,
|
|
|
LIBC это C Runtime - она по умолчанию всегда подключается.
|
Сообщ.
#3
,
|
|
|
Я понял что по умолчанию всегда включаеться. Но почему именно эта версия.
Если я хочу другую подставить.. как это сделать? |
Сообщ.
#4
,
|
|
|
Цитата Aleman @ Если я хочу другую подставить.. как это сделать? Я сейчас точно не помню, посмотри параметры линкера. Должна быть опция --nodefaultlib или что-то в таком духе - т.е. линковать без библиотек по умолчанию. А в командной строке укажеш ту которую хочеш подключить. Только если ты функции из LIBC используеш (а ты скорее всего используеш) - то какую-нибудь версию всё равно подключать прийдётся. Если сам не найдёш - выложи тут список опций линкера, я на память не помню... |
Сообщ.
#5
,
|
|
|
Хорошо. Спасибо. Пороем.
Всетаки это вшито в линкер при сборке чтоли |
Сообщ.
#6
,
|
|
|
У gcc есть скрипт компиляции (specs file). В частности, в нем указано, какие либы по умолчанию вкомпиливать, и т.д.
Посмотреть дефолтовый specs file можно, вызвав gcc -dumpspecs. Где хранится specs file, я не помню. Важно понимать, как устроен gcc: есть главная программ gcc (она называется driver, т.е., ведущий). Эта программа использует specs и опции командной строки, чтобы определить, какие шаги сборки и каким образом выполнить (препроцессинг, компиляция, линковка). Т.е., в простейшем случае (для сборки helloworld) gcc сначала запускает препроцессор, потом компилятор (cc1 или cc1plus), потом линковщик. С каким параметрами их запускать, определяется исходя из скрипта и опций командной строки. |
Сообщ.
#7
,
|
|
|
Цитата mo3r @ есть главная программ gcc (она называется driver, т.е., ведущий) Меня всегда смущал такой ньюанс . archimed7592@PC ~/testlabs/g++ $ cat main.cpp #include <ostream> #include <iostream> int main() { std::cout << "Hello world!" << std::endl; return 0; } archimed7592@PC ~/testlabs/g++ $ g++ ./main.cpp archimed7592@PC ~/testlabs/g++ $ gcc ./main.cpp C:/Temp/ccIlbaaa.o(.text+0xd):main.cpp: undefined reference to `std::string::size() const' C:/Temp/ccIlbaaa.o(.text+0x60):main.cpp: undefined reference to `std::string::operator[](unsigned int) const' C:/Temp/ccIlbaaa.o(.text+0x9f):main.cpp: undefined reference to `std::string::operator[](unsigned int) const' C:/Temp/ccIlbaaa.o(.text+0xce):main.cpp: undefined reference to `std::string::operator[](unsigned int) const' C:/Temp/ccIlbaaa.o(.text+0x135):main.cpp: undefined reference to `std::cout' C:/Temp/ccIlbaaa.o(.text+0x13a):main.cpp: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' C:/Temp/ccIlbaaa.o(.text+0x142):main.cpp: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)' C:/Temp/ccIlbaaa.o(.text+0x14a):main.cpp: undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))' C:/Temp/ccIlbaaa.o(.text+0x173):main.cpp: undefined reference to `std::ios_base::Init::Init()' C:/Temp/ccIlbaaa.o(.text+0x18e):main.cpp: undefined reference to `std::ios_base::Init::~Init()' collect2: ld returned 1 exit status archimed7592@PC ~/testlabs/g++ $ |
Сообщ.
#8
,
|
|
|
Цитата Меня всегда смущал такой ньюанс . А если так, то соберется: gcc main.cpp -lstdc++ Как я понимаю, gcc и g++ используют различные профили компилятора, которые подключают разные библиотеки. |
Сообщ.
#9
,
|
|
|
aleman@aleman-desktop:~$ gcc -dumpspecs *asm: --traditional-format %{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} %{m32:--32} %{m64:--64} *asm_debug: %{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}} *asm_final: *asm_options: %a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O} *invoke_as: %{!S:-o %|.s | as %(asm_options) %|.s %A } *cpp: %{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT} *cpp_options: %(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps:-fpch-preprocess} *cpp_debug_options: %{d*} *cpp_unique_options: %{C|CC:%{!E:%eGCC does not support -C or -CC without -E}} %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I %{MD:-MD %{!o:%b.d}%{o*:%.d%*}} %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}} %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i %{fmudflap:-D_MUDFLAP -include mf-runtime.h} %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h} %{E|M|MM:%W{o*}} *trad_capable_cpp: cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp} *cc1: %(cc1_cpu) %{profile:-p} *cc1_options: %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}} %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*} %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}} %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs} %{v:-version} %{pg:-p} %{p} %{f*} %{undef} %{Qn:-fno-ident} %{--help:--help} %{--target-help:--target-help} %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}} %{fsyntax-only:-o %j} %{-param*} %(ssp_default) %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants} %{coverage:-fprofile-arcs -ftest-coverage} *cc1plus: *link_gcc_c_sequence: %{static:--start-group} %G %L %{static:--end-group}%{!static:%G} *link_ssp: %{fstack-protector:} *ssp_default: %{!fno-stack-protector:-fstack-protector} *endfile: %{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s *link: %{!static:--eh-frame-hdr} %{!m32:-m elf_x86_64} %{m32:-m elf_i386} --hash-style=both %{shared:-shared} %{!shared: %{!static: %{rdynamic:-export-dynamic} %{m32:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} %{static:-static}} *lib: %{pthread:-lpthread} %{shared:-lc} %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}} *mfwrap: %{static: %{fmudflap|fmudflapth: --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc --wrap=mmap --wrap=munmap --wrap=alloca} %{fmudflapth: --wrap=pthread_create}} %{fmudflap|fmudflapth: --wrap=main} *mflib: %{fmudflap|fmudflapth: -export-dynamic} *libgcc: %{static|static-libgcc:-lgcc -lgcc_eh}%{!static:%{!static-libgcc:%{!shared-libgcc:-lgcc --as-needed -lgcc_s --no-as-needed}%{shared-libgcc:-lgcc_s%{!shared: -lgcc}}}} *startfile: %{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s} *switches_need_spaces: *cross_compile: 0 *version: 4.1.3 *multilib: . !m64 !m32;64:../lib m64 !m32;32:../lib32 !m64 m32; *multilib_defaults: m64 *multilib_extra: *multilib_matches: m64 m64;m32 m32; *multilib_exclusions: *multilib_options: m64/m32 *linker: collect2 *link_libgcc: %D *md_exec_prefix: *md_startfile_prefix: *md_startfile_prefix_1: *startfile_prefix_spec: *sysroot_spec: --sysroot=%R *sysroot_suffix_spec: *sysroot_hdrs_suffix_spec: *cc1_cpu: %{!mtune*: %{m386:mtune=i386 %n`-m386' is deprecated. Use `-march=i386' or `-mtune=i386' instead. } %{m486:-mtune=i486 %n`-m486' is deprecated. Use `-march=i486' or `-mtune=i486' instead. } %{mpentium:-mtune=pentium %n`-mpentium' is deprecated. Use `-march=pentium' or `-mtune=pentium' instead. } %{mpentiumpro:-mtune=pentiumpro %n`-mpentiumpro' is deprecated. Use `-march=pentiumpro' or `-mtune=pentiumpro' instead. } %{mcpu=*:-mtune=%* %n`-mcpu=' is deprecated. Use `-mtune=' or '-march=' instead. }} %<mcpu=* %{mintel-syntax:-masm=intel %n`-mintel-syntax' is deprecated. Use `-masm=intel' instead. } %{mno-intel-syntax:-masm=att %n`-mno-intel-syntax' is deprecated. Use `-masm=att' instead. } *link_command: %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S: %(linker) %l %{pie:-pie} %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %(mfwrap) %(link_libgcc) %o %(mflib) %{fprofile-arcs|fprofile-generate|coverage:-lgcov} %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}} Чет невижу тут libc.so.6 |
Сообщ.
#10
,
|
|
|
Цитата *lib: %{pthread:-lpthread} %{shared:-lc} %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}} -lc и есть libc. А уж libc.so.6 выбирается, наверное, из символических ссылок. |
Сообщ.
#11
,
|
|
|
Посмотрю сегодня...
|
Сообщ.
#12
,
|
|
|
посмотрел...
Цитата mo3r @ -lc и есть libc. А уж libc.so.6 выбирается, наверное, из символических ссылок. сама libc.so лежит в /usr/lib самое интересное она не являеться ни ссылкой ни библеотекой.. в ней обычный текст: /* GNU ld script Use the shared library, but some functions are only in the static library, so try that secondarily. */ OUTPUT_FORMAT(elf64-x86-64) GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-x86-64.so.2 ) ) Менял libc.so.6 на другую.. всеравно libc.so.6 подставляет. |
Сообщ.
#13
,
|
|
|
что скажете?
|
Сообщ.
#14
,
|
|
|
Я не уверен насчет этого, но, возможно, кроме редактирования этого скрипта надо еще делать ldconfig для обновления кэша линковщика.
Добавлено Цитата mo3r @ надо еще делать ldconfig для обновления кэша линковщика. Только поаккуратней с этим — если неправильно что-то сделать, то может случиться так, что ни одна программа, использующая libc, не запустится. Мне кажется, более продуктивным будет заменить specs. Например, gcc --specs=<specs file>. В любом случае, надо будет читать документацию. |
Сообщ.
#15
,
|
|
|
спасибо.. пороем...
|
Сообщ.
#16
,
|
|
|
\usr\lib\lib.so.6 - есть по сути дела текстовый файл, в простейшем случае содержащий
Цитата GROUP ( /lib/libc.so.6 ) то бишь, подставляемый на сим-линк - на главную libс-такойто-то-там-версии-so.6 хотя возможно подключить в виде статики "libc-x-x-x-.a" (получив тем самым большую автономность и независимость приложения, как впрочем и большой размер файла). Добавлено Короче - Логика линковщика (для линукс!) такова - что он при компиляции может использовать как сим линк (либо импорт будет завязан на конкретную версию!) на бинарные ELF-файлы , так и статический *.a (ARCH - архив, с его предкомпилеными, обьектными файлами). |
Сообщ.
#17
,
|
|
|
Цитата N0P @ \usr\lib\lib.so.6 - есть по сути дела текстовый файл, в простейшем случае содержащий \usr\lib\libc.so такто текстовый файл а \lib\libс.so.6 библа Агде искать этот specs файл? Кстати пробовал просто скомпилить с параметром -c. потом попробовал слинковать ld'шкой.. с ошибкой но както получилось сделать исполняемый но не рабочий файл, заглянув в него всеравно увидел libc.so.6 значит это у линковщика по умолчанию идет? |
Сообщ.
#18
,
|
|
|
Вообще, у компилятора и линковщика со стандартной библиотекой довольно тесные связи. Просто так заменить libc не получится. Лучше почитай документацию uclibc или newlib — там может быть описано, как собрать gcc с не libc.
|
Сообщ.
#19
,
|
|
|
Может все легко делаеться.. может я просто не так обьяснил...
Я хотел бы увидеть при ldd myprograms вот так: libc.so => /lib/libc.so (0x00002af766e5a000) /lib64/ld-linux-x86-64.so.2 (0x00002af766c3c000) или это впринципе вс таже задача и есть... |
Сообщ.
#20
,
|
|
|
вообщем это снова я.. и тема эта до сих пор не понятна для меня.
Сегодня я приведу другой , более видный пример. Вообщем создл я программку, которая использует функции из библиотеки xlib. Соответствено и скомпилировал я её так: сс test.c -o test.out -lX11 как вы видите я передал ему параметр -lX11 чтоб он скомпоновал (не сам естественно) эту библиотеку. все нормально скомпелировалось, создался исполняемый. Давайте посмотрим на него вот так: ldd test.out и вот что мы увидим: libX11.so.6 => /usr/lib/libX11.so.6 (0x00002b7c54441000) libc.so.6 => /lib/libc.so.6 (0x00002b7c54752000) libXau.so.6 => /usr/lib/libXau.so.6 (0x00002b7c54aad000) libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00002b7c54caf000) libdl.so.2 => /lib/libdl.so.2 (0x00002b7c54eb5000) /lib64/ld-linux-x86-64.so.2 (0x00002b7c54223000) Как я понял -lX11 это не одна библиотека? Где это прописано у GCC и СС... Помогите пожалуйста эту загадку решить.. |
Сообщ.
#21
,
|
|
|
Цитата Aleman @ Как я понял -lX11 это не одна библиотека? Одна библиотека. Но у libX11.so.6 есть зависимости. $ ldd /usr/lib/libX11.so.6 linux-vdso.so.1 => (0x00007fffec3fd000) libXau.so.6 => /usr/lib/libXau.so.6 (0x00002b85beb5f000) libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00002b85bec62000) libdl.so.2 => /lib/libdl.so.2 (0x00002b85bed68000) libc.so.6 => /lib/libc.so.6 (0x00002b85bee6c000) /lib64/ld-linux-x86-64.so.2 (0x0000555555554000) Цитата Aleman @ Где это прописано Наверное, прописано в ELF-заголовках в /usr/lib/libX11.so.6 Добавлено Еще для примера: $ less /usr/lib/libX11.so.6 ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x20850 Start of program headers: 64 (bytes into file) Start of section headers: 1087728 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 7 Size of section headers: 64 (bytes) Number of section headers: 26 Section header string table index: 25 Dynamic section at offset 0x104b50 contains 25 entries: Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libXau.so.6] 0x0000000000000001 (NEEDED) Shared library: [libXdmcp.so.6] 0x0000000000000001 (NEEDED) Shared library: [libdl.so.2] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000000e (SONAME) Library soname: [libX11.so.6] 0x000000000000000c (INIT) 0x1df30 0x000000000000000d (FINI) 0xa9028 0x0000000000000004 (HASH) 0x1c8 0x000000006ffffef5 (GNU_HASH) 0x2760 … |
Сообщ.
#22
,
|
|
|
Цитата mo3r @ Одна библиотека. Но у libX11.so.6 есть зависимости. Точно! Цитата mo3r @ Наверное, прописано в ELF-заголовках в /usr/lib/libX11.so.6 Да так оно и есть... но вернемся к самому началу этапа. Я ему сказал -lX11 он в заголовок моей проги загнал libX11.so.6. вот это меня больше тревожит. где эти соответствия у него написаны, что -lX11 = libX11.so.6 |
Сообщ.
#23
,
|
|
|
Может все дело в том, что libX11.so - ссылка на конкретную библиотеку?
|
Сообщ.
#24
,
|
|
|
Цитата gruy @ Может все дело в том, что libX11.so - ссылка на конкретную библиотеку? Ему без разницы.. он бы и ссылку запихал. |
Сообщ.
#25
,
|
|
|
.6 — это версия ABI (вроде бы)
|
Сообщ.
#26
,
|
|
|
Что такое ABI?
|
Сообщ.
#27
,
|
|
|
http://en.wikipedia.org/wiki/Application_binary_interface
|
Сообщ.
#28
,
|
|
|
За аби просвятился, если это так:
Цитата mo3r @ .6 — это версия ABI (вроде бы) Где в Линуксе её прячут? Эту версию? Просто для эксперемента посмотрю. |
Сообщ.
#29
,
|
|
|
Цитата Aleman @ Где в Линуксе её прячут? Эту версию? Просто для эксперемента посмотрю. На этом мои знания заканчиваются Мне кажется, самое простое объяснение — линковщик прописывает то, на что указывает ссылка в момент линковки. |
Сообщ.
#30
,
|
|
|
Цитата mo3r @ На этом мои знания заканчиваются плохо |
Сообщ.
#31
,
|
|
|
6 - это часть soname, для каждой либы она прописана в самой либе.
soname задается при сборке самой библиотеки. Пример: gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc Просветительская ссылка: http://www.tldp.org/HOWTO/text/Program-Library-HOWTO ldd в новых дистрах показывает зависимости не только самого бинарника, но и библиотек, от которых он зависит. В линуксе постарее он бы показал только libX11.so.6 без libXau.so.6, libXdmcp.so.6... |
Сообщ.
#32
,
|
|
|
Спасибо. Будем смотреть
|
Сообщ.
#33
,
|
|
|
Цитата grustnoe @ soname задается при сборке самой библиотеки. Пример: gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc Но в даном случае сборка идет моей программы. И компоновщик сует готовое имя этой библы |
Сообщ.
#34
,
|
|
|
которое прописано в ней самой.
|