Ответ 1
Проблема исходит от компоновщика ld
, а не gcc (следовательно, сообщение о статусе выхода). В общем случае ld требует, чтобы объекты и библиотеки указывались в порядке user
supplier
, где user
- объект, который использует библиотечную функцию, и supplier
- объект, который его предоставляет.
Когда ваш test.c
скомпилирован для объекта, компилятор заявляет, что fmod является ссылкой undefined
$ gcc -c test.c
$ nm test.o
U fmod
0000000000000000 T main
(nm перечисляет все функции, на которые ссылается объектный файл)
Компоновщик изменяет ссылки undefined на определенные, просматривая ссылки, чтобы увидеть, поставляются ли они в других файлах.
$ gcc -lm test.o
$ nm a.out
0000000000600e30 d _DYNAMIC
0000000000600fe8 d _GLOBAL_OFFSET_TABLE_
00000000004006a8 R _IO_stdin_used
w _Jv_RegisterClasses
0000000000600e10 d __CTOR_END__
...
0000000000601018 D __dso_handle
w __gmon_start__
...
U [email protected]@GLIBC_2.2.5
0000000000601020 A _edata
0000000000601030 A _end
0000000000400698 T _fini
0000000000400448 T _init
0000000000400490 T _start
00000000004004bc t call_gmon_start
0000000000601020 b completed.7382
0000000000601010 W data_start
0000000000601028 b dtor_idx.7384
U [email protected]@GLIBC_2.2.5
0000000000400550 t frame_dummy
0000000000400574 T main
Большинство из них относятся к функциям libc, которые запускаются до и после main, чтобы настроить среду. Вы можете видеть, что fmod теперь указывает на glibc, где он будет разрешен совместно используемой библиотечной системой.
Моя система настроена на использование разделяемых библиотек по умолчанию. Если я вместо этого статическую ссылку, я получаю зависимость заказа, которую вы видите
$ gcc -static -lm test.o
test.o: In function `main':
test.c:(.text+0x40): undefined reference to `fmod'
collect2: ld returned 1 exit status
Помещая -lm
позже в команде компоновщика, после test.o
, он позволяет ему успешно связываться.
Проверка символов fmod теперь должна быть разрешена на фактический адрес, и действительно это
$ gcc -static test.o -lm
$ nm a.out | grep fmod
0000000000400480 T __fmod
0000000000402b80 T __ieee754_fmod
0000000000400480 W fmod