9

Вопрос по linux, c – GCC libm не работает

У меня есть программа c, которая вызывает sin, cos и acos. Когда я компилирую, я получаю следующие ошибки:

/tmp/ccDfW98S.o: In function `zip_search':
main.c:(.text+0xf30): undefined reference to `sin'
main.c:(.text+0xf45): undefined reference to `sin'
main.c:(.text+0xf66): undefined reference to `cos'
main.c:(.text+0xf7b): undefined reference to `cos'
main.c:(.text+0xf9c): undefined reference to `cos'
main.c:(.text+0xfc6): undefined reference to `acos'
collect2: ld returned 1 exit status

Я знаю, что это обычно, когда вы не используете флаг -lm gcc. Я использую этот флаг. Я звоню в GCC следующим образом:

gcc -o zipcode-server -lm main.c

Когда я компилирую на одном из моих компьютеров, это работает нормально. Единственное различие, о котором я могу думать, состоит в том, что это не работает на x86_64, а на компьютере, на котором он работает - i686. Оба Ubuntu. Файл libm.a присутствует на компьютере, на котором он не работает, и я не получаю никаких сообщений о том, что его нельзя найти. Что может быть причиной этого?

  • Error: User Rate Limit Exceeded

    от Stewart
  • Не могли бы вы опубликовать соответствующую часть вашего кода, чтобы мы могли помочь вам с вашей проблемой?

    от krzysz00
  • Просто для удовольствия попробуйте:gcc -o zipcode-server main.c -lm

    от Andrew Tomazos
  • 21

    Вы должны положить

    -lm послеmain.c

    В общем, если у вас есть несколько библиотек, они должны быть написаны в порядке их использования. Например, если библиотекаA использует библиотекуB, у тебя должно быть-lA -lB.

    В вашем случае объектный файл, который является результатом компиляцииmain.c использует библиотекуm и поэтому-lm должен прийти после этого.

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

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

    Поскольку библиотеки всегда могут быть объявлены компоновщику в правильном порядке их зависимостей1Для линкера нет причин выбирать неэффективный путь.

    1 Libraries normally have a one-way relationship, in the sense that one uses the other. Circular dependencies between libraries is rare, if at all existing, but it could still be used with this model by repeating certain libraries to be reinspected.