А я прописываю в .bashrc alias gcc='gcc -lm' (на время этих экспериментов ещё не успел - забыл), потому как мои программки - это математические вычисления. До этого дистрибутива всегда работало.
Из man ld:
ld -o <output> /lib/crt0.o hello.o -lc
This tells ld to produce a file called output as the result of linking
the file "/lib/crt0.o" with "hello.o" and the library "libc.a", which
will come from the standard search directories. (See the discussion of
the -l option below.)
Some of the command-line options to ld may be specified at any point in
the command line. However, options which refer to files, such as -l or
-T, cause the file to be read at the point at which the option appears
in the command line, relative to the object files and other file
options.
То есть, если следовать этому мануалу, то самое законное место для -l - это сразу после файла, к которому эта библиотека должна быть привязана. Но это для линкера, а не для компилятора.
У меня gcc ставит линкеру -lm сразу после нужного файла только в том случае, если я её пишу её сразу после test.o. Тогда работает. Если перед, или после, но между ними ещё какя-то опция - gcc передаёт линкеру -lm
перед файлом. И тогда не работает.
Это справедливо, если я отправляю объектные файлы. Если же исходные тексты - то тут опять не всё однозначно:
Код: Выделить всё
>gcc test.c -lm -O
/home/oleg/tmp/ccG7HVJk.o: In function `main':
test.c:(.text+0x29): undefined reference to `sin'
collect2: выполнение ld завершилось с кодом возврата 1
>gcc -O test.c -lm
>./a.out
hello
0.130923
Но: (извиняюсь за длину - смотрите первую и последнюю строчки)
Код: Выделить всё
>gcc -O test.c -lm -v
Используются внутренние спецификации.
Целевая архитектура: i586-alt-linux
Параметры конфигурации: ../configure --host=i586-alt-linux --build=i586-alt-linux --target=i586-alt -linux --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib --libexecdir=/usr/libexec --localstat edir=/var/lib --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info --disable -dependency-tracking --without-included-gettext --program-suffix=-4.1 --with-slibdir=/lib --enable-shared --enable-__cxa_atexit --enable-threads=posix --enable-checking=release --with-system-zlib --without-included-gettext --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,treelang,java,ada --enable-java-awt=gtk --disable-plugin --with-native-libdir=/usr/lib/gcj-4.1 --enable-libgcj-multifile --with-cpu=i586 --with-arch=i586 --with-tune=pentium4
Модель многопотоковости: posix
gcc версия 4.1.1 20070105 (ALT Linux, build 4.1.1-alt11)
/usr/libexec/gcc/i586-alt-linux/4.1.1/cc1 -D_FORTIFY_SOURCE=2 -quiet -v test.c -fstack-protector -quiet -dumpbase test.c -march=i586 -auxbase test -O -version -o /home/oleg/tmp/ccj8OGxv.s
несуществующий каталог "/usr/lib/gcc/i586-alt-linux/4.1.1/../../../../i586-alt-linux/include" проигнорирован
порядок поиска для #include "...":
порядок поиска для #include <...>:
/usr/local/include
/usr/lib/gcc/i586-alt-linux/4.1.1/include
/usr/include
конец списка поиска
GNU C версия 4.1.1 20070105 (ALT Linux, build 4.1.1-alt11) (i586-alt-linux)
скомпилировано GNU C версия 4.1.1 20070105 (ALT Linux, build 4.1.1-alt11).
эвристики GGC: --param ggc-min-expand=64 --param ggc-min-heapsize=64547
Compiler executable checksum: 47b67d78d2d55d8e46d637540ceaca3e
as -V -Qy -o /home/oleg/tmp/cc8F7hxV.o /home/oleg/tmp/ccj8OGxv.s
GNU assembler version 2.17.50.0.6 (i586-alt-linux) using BFD version 2.17.50.0.6 20061020
/usr/libexec/gcc/i586-alt-linux/4.1.1/collect2 --as-needed --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crt1.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crti.o /usr/lib/gcc/i586-alt-linux/4.1.1/crtbegin.o -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1 -L/usr/lib/gcc/i586-alt-linux/4.1.1/../../.. -lm /home/oleg/tmp/cc8F7hxV.o -lgcc --as-needed -lgcc_s -lc -lgcc --as-needed -lgcc_s /usr/lib/gcc/i586-alt-linux/4.1.1/crtend.o /usr/lib/gcc/i586-alt-linux/4.1.1/../../../crtn.o
/home/oleg/tmp/cc8F7hxV.o: In function `main':
test.c:(.text+0x29): undefined reference to `sin'
collect2: выполнение ld завершилось с кодом возврата 1
В многостадийном процессе превращения текстов в программы компилятор тасует опции как хочет.
Нормальным это, конечно не назовёшь.
И опять-таки по поводу опции --as-needed для линкера (я так думаю, что она придумана для повышения быстродействия). -lm можно ставить в любом месте списка опций - я ставил и на первом и на последнем месте. Всё линкуется, если на -lm не воздействует --as-needed. Действие этой опции прекращается за --no-as-needed или за объектным файлом, к которому данная библиотека должна быть привязана.
В общем, чтобы найти конкретного виновника этого безобразия нужно учинять следственную комиссию.
Эксперименты мне уже поднадоели, пойду-ка я подумаю, как мне от этого безобразия избавиться.