Ошибка "неопределенная ссылка на символ" при использовании `ld` для ссылки - PullRequest
0 голосов
/ 10 февраля 2019

Я новичок в написании программ для Linux.У меня есть программа с одним модулем, которая использует shm_open, ftruncate, mmap, fork и wait.Я скомпилировал эту программу с gcc -c, а затем связал ее с ld -lrt (librt необходим для shm_open), и я получил странную ошибку компоновщика:

undefined reference to symbol 'waitpid@@GLIBC_2.2.5'

Страница руководства для wait говорит

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
   waitid():
       Since glibc 2.26: _XOPEN_SOURCE >= 500 ||
           _POSIX_C_SOURCE >= 200809L
       Glibc 2.25 and earlier:
           _XOPEN_SOURCE

, но включение #define _XOPEN_SOURCE в коде не поможет, и если я сделаю

gcc -c -D _XOPEN_SOURCE 

, компилятор скажет неявное объявление ftruncate.

Я использую Ubuntu под VMWare.GCC версии gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609.

Что может быть не так?

1 Ответ

0 голосов
/ 10 февраля 2019

Я скомпилировал эту программу с помощью gcc -c, а затем связал ее с ld -lrt

Пока вы не стали более опытными, вы не должны пытаться вызывать ld напрямую.Вместо этого, связывайте свои программы, а также компилируйте их, используя команду gcc (или cc).Для вашего случая использования должна работать командная строка:

gcc -o myprogram myprogram.o -lrt

.(Обратите внимание на размещение -lrt; в большинстве случаев -l опции должны идти после объектных файлов в командной строке, по утомительным историческим причинам.)

Под капотомКогда вы связываете программу с помощью команды gcc, она запускает для вас ld, но включает в себя целый набор дополнительных аргументов.Все это необходимо для создания обычных программ, и они достаточно сложны, чтобы обычные программисты не должны были о них беспокоиться.Одним из дополнительных аргументов является -lc, указывающее ld включить ядро ​​библиотеки времени выполнения C, которая предоставляет определение waitpid@@GLIBC_2.2.5, которое отсутствовало в вашей ссылке.(Не пытайтесь просто вставить -lc в командную строку ld самостоятельно. Собственно, попробуйте это. Вы обнаружите, что получаете только еще более загадочное сообщение об ошибке, вероятно, что-то вроде warning: cannot find entry symbol _start или undefined reference to __bswapsi2или кто даже знает.)

Вы можете увидеть, что это за дополнительные аргументы, если вам интересно, добавив -v к приведенному выше вызову gcc, но это большой беспорядок и единственный компиляторразработчикам нужно беспокоиться о большинстве из них.

Почему именно команда gcc, а не команда ld, знает все эти дополнительные аргументы, которые вам необходимы для правильной связи нормальной программы?Это в основном историческое, но идея в том, что ld минимален, поэтому, если вы делаете что-то необычное (например, связываете ядро ​​операционной системы), вам не нужно выключать что-либо обычное , отключая , вы простонужно начинать с нуля и наращивать.Но для обычных программ люди могут использовать (g)cc и не должны беспокоиться о дополнительных аргументах.

Кстати, материал, который вы нашли в руководстве по поводу _XOPEN_SOURCE, не о том, как сделать waitдоступно во время ссылки;речь идет о том, как сделать объявление из wait доступным в время компиляции .Кроме того, значение, которое вы определяете _XOPEN_SOURCE имеет значение.Определив его как -D_XOPEN_SOURCE вместо -D_XOPEN_SOURCE=500, вы получили жалобу на неявное объявление ftruncate.

...