На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела *nix / gcc / Eclipse / Qt / wxWidgets / GTK+
  • При создании темы ОБЯЗАТЕЛЬНО указывайте версию тулкита / библиотеки / компилятора.
  • Перед тем как задать вопрос, сформулируйте его правильно, чтобы вас могли понять.
  • Нарушение Правил может повлечь наказание со стороны модераторов.


Полезные ссылки:
user posted image Boost по-русски
user posted image Qt по-русски
Модераторы: archimed7592
  
> Логика линковщика , Не могу понять
    Написал Привет мир на "С"

    ExpandedWrap disabled
      #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
      LIBC это C Runtime - она по умолчанию всегда подключается.
        Я понял что по умолчанию всегда включаеться. Но почему именно эта версия.
        Если я хочу другую подставить.. как это сделать?
          Цитата Aleman @
          Если я хочу другую подставить.. как это сделать?

          Я сейчас точно не помню, посмотри параметры линкера.
          Должна быть опция --nodefaultlib или что-то в таком духе - т.е. линковать без библиотек по умолчанию.
          А в командной строке укажеш ту которую хочеш подключить.
          Только если ты функции из LIBC используеш (а ты скорее всего используеш) - то какую-нибудь версию всё равно подключать прийдётся.
          Если сам не найдёш - выложи тут список опций линкера, я на память не помню...
            Хорошо. Спасибо. Пороем.
            Всетаки это вшито в линкер при сборке чтоли <_<
              У gcc есть скрипт компиляции (specs file). В частности, в нем указано, какие либы по умолчанию вкомпиливать, и т.д.
              Посмотреть дефолтовый specs file можно, вызвав gcc -dumpspecs. Где хранится specs file, я не помню.
              Важно понимать, как устроен gcc: есть главная программ gcc (она называется driver, т.е., ведущий). Эта программа использует specs и опции командной строки, чтобы определить, какие шаги сборки и каким образом выполнить (препроцессинг, компиляция, линковка). Т.е., в простейшем случае (для сборки helloworld) gcc сначала запускает препроцессор, потом компилятор (cc1 или cc1plus), потом линковщик. С каким параметрами их запускать, определяется исходя из скрипта и опций командной строки.
                Цитата mo3r @
                есть главная программ gcc (она называется driver, т.е., ведущий)

                Меня всегда смущал такой ньюанс :).
                ExpandedWrap disabled
                  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++
                  $
                  Цитата
                  Меня всегда смущал такой ньюанс :).

                  А если так, то соберется:
                  ExpandedWrap disabled
                    gcc main.cpp -lstdc++

                  Как я понимаю, gcc и g++ используют различные профили компилятора, которые подключают разные библиотеки.
                    ExpandedWrap disabled
                      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
                      Цитата
                      *lib:
                      %{pthread:-lpthread} %{shared:-lc} %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}

                      -lc и есть libc. А уж libc.so.6 выбирается, наверное, из символических ссылок.
                        Посмотрю сегодня...
                          посмотрел...

                          Цитата mo3r @
                          -lc и есть libc. А уж libc.so.6 выбирается, наверное, из символических ссылок.

                          сама libc.so лежит в /usr/lib
                          самое интересное она не являеться ни ссылкой ни библеотекой.. в ней обычный текст:

                          ExpandedWrap disabled
                            /* 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 подставляет.
                            что скажете?
                              Я не уверен насчет этого, но, возможно, кроме редактирования этого скрипта надо еще делать ldconfig для обновления кэша линковщика.

                              Добавлено
                              Цитата mo3r @
                              надо еще делать ldconfig для обновления кэша линковщика.

                              Только поаккуратней с этим — если неправильно что-то сделать, то может случиться так, что ни одна программа, использующая libc, не запустится.

                              Мне кажется, более продуктивным будет заменить specs. Например, gcc --specs=<specs file>.

                              В любом случае, надо будет читать документацию.
                                спасибо.. пороем... ;)
                                  \usr\lib\lib.so.6 - есть по сути дела текстовый файл, в простейшем случае содержащий
                                  Цитата

                                  GROUP ( /lib/libc.so.6 )

                                  то бишь, подставляемый на сим-линк - на главную libс-такойто-то-там-версии-so.6 хотя возможно подключить в виде статики "libc-x-x-x-.a" (получив тем самым большую автономность и независимость приложения, как впрочем и большой размер файла).

                                  Добавлено
                                  Короче - Логика линковщика (для линукс!) такова - что он при компиляции может использовать как сим линк (либо импорт будет завязан на конкретную версию!) на бинарные ELF-файлы , так и статический *.a (ARCH - архив, с его предкомпилеными, обьектными файлами).
                                    Цитата N0P @
                                    \usr\lib\lib.so.6 - есть по сути дела текстовый файл, в простейшем случае содержащий


                                    \usr\lib\libc.so такто текстовый файл а \lib\libс.so.6 библа

                                    Агде искать этот specs файл?

                                    Кстати пробовал просто скомпилить с параметром -c. потом попробовал слинковать ld'шкой.. с ошибкой но както получилось сделать исполняемый но не рабочий файл, заглянув в него всеравно увидел libc.so.6 значит это у линковщика по умолчанию идет?
                                      Вообще, у компилятора и линковщика со стандартной библиотекой довольно тесные связи. Просто так заменить libc не получится. Лучше почитай документацию uclibc или newlib — там может быть описано, как собрать gcc с не libc.
                                        Может все легко делаеться.. может я просто не так обьяснил...

                                        Я хотел бы увидеть при ldd myprograms вот так:

                                        ExpandedWrap disabled
                                          libc.so => /lib/libc.so (0x00002af766e5a000)
                                          /lib64/ld-linux-x86-64.so.2 (0x00002af766c3c000)


                                        или это впринципе вс таже задача и есть...
                                          вообщем это снова я.. и тема эта до сих пор не понятна для меня.
                                          Сегодня я приведу другой , более видный пример.

                                          Вообщем создл я программку, которая использует функции из библиотеки xlib.
                                          Соответствено и скомпилировал я её так:
                                          ExpandedWrap disabled
                                            сс test.c -o test.out -lX11


                                          как вы видите я передал ему параметр -lX11 чтоб он скомпоновал (не сам естественно) эту библиотеку.

                                          все нормально скомпелировалось, создался исполняемый.
                                          Давайте посмотрим на него вот так:
                                          ExpandedWrap disabled
                                             ldd test.out

                                          и вот что мы увидим:
                                          ExpandedWrap disabled
                                             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 и СС...

                                          Помогите пожалуйста эту загадку решить..
                                          Сообщение отредактировано: Aleman -
                                            Цитата Aleman @
                                            Как я понял -lX11 это не одна библиотека?

                                            Одна библиотека. Но у libX11.so.6 есть зависимости.
                                            ExpandedWrap disabled
                                              $ 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

                                            Добавлено
                                            Еще для примера:
                                            ExpandedWrap disabled
                                              $ 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
                                              Цитата mo3r @
                                              Одна библиотека. Но у libX11.so.6 есть зависимости.

                                              Точно!

                                              Цитата mo3r @
                                              Наверное, прописано в ELF-заголовках в /usr/lib/libX11.so.6

                                              Да так оно и есть...

                                              но вернемся к самому началу этапа. Я ему сказал -lX11 он в заголовок моей проги загнал libX11.so.6. вот это меня больше тревожит.
                                              где эти соответствия у него написаны, что -lX11 = libX11.so.6
                                                Может все дело в том, что libX11.so - ссылка на конкретную библиотеку?
                                                  Цитата gruy @
                                                  Может все дело в том, что libX11.so - ссылка на конкретную библиотеку?


                                                  Ему без разницы.. он бы и ссылку запихал.
                                                    .6 — это версия ABI (вроде бы)
                                                      Что такое ABI?
                                                        http://en.wikipedia.org/wiki/Application_binary_interface
                                                          За аби просвятился, если это так:

                                                          Цитата mo3r @
                                                          .6 — это версия ABI (вроде бы)


                                                          Где в Линуксе её прячут? Эту версию? Просто для эксперемента посмотрю.
                                                            Цитата Aleman @
                                                            Где в Линуксе её прячут? Эту версию? Просто для эксперемента посмотрю.

                                                            На этом мои знания заканчиваются :) Мне кажется, самое простое объяснение — линковщик прописывает то, на что указывает ссылка в момент линковки.
                                                              Цитата mo3r @

                                                              На этом мои знания заканчиваются

                                                              плохо :(
                                                                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...
                                                                  Спасибо. Будем смотреть
                                                                    Цитата grustnoe @
                                                                    soname задается при сборке самой библиотеки.
                                                                    Пример: gcc -shared -Wl,-soname,libmystuff.so.1 -o libmystuff.so.1.0.1 a.o b.o -lc

                                                                    Но в даном случае сборка идет моей программы.
                                                                    И компоновщик сует готовое имя этой библы
                                                                      которое прописано в ней самой.
                                                                      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                                                      0 пользователей:


                                                                      Рейтинг@Mail.ru
                                                                      [ Script execution time: 0,0713 ]   [ 15 queries used ]   [ Generated: 19.05.24, 13:22 GMT ]