Связывание с gcc и -lm не определяет ceil () в Ubuntu - PullRequest
13 голосов
/ 25 ноября 2011

Я сейчас использую gcc для компиляции, и мне нужно использовать <math.h>. Проблема в том, что он не распознает библиотеку. Я тоже пробовал -lm и ничего. Функция, которую я пытался использовать, была ceil(), и я получаю следующую ошибку:

: undefined reference to `ceil'
collect2: ld returned 1 exit status

Я использую последнюю версию Ubuntu, и там есть math.h. Я пытался использовать -lm на другом компьютере, и он отлично работал.

Кто-нибудь знает, как решить эту проблему?


Я включил <math.h>. Также я использовал команду:

gcc -lm -o fb file.c

Ответы [ 3 ]

20 голосов
/ 25 ноября 2011

Возьмите этот код и поместите его в файл ceil.c:

#include <math.h>
#include <stdio.h>
int main(void)
{
    printf("%f\n", ceil(1.2));
    return 0;
}

Скомпилируйте его с помощью:

$ gcc -o ceil ceil.c
$ gcc -o ceil ceil.c -lm

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

Примечания:

  1. Aсовременный компилятор вполне может оптимизировать код для передачи 2.0 непосредственно в printf(), не вызывая ceil() вообще во время выполнения, поэтому не нужно вообще использовать библиотеку математики.

  2. Полезное правило: перечисление объектных файлов и исходных файлов в командной строке перед библиотеками.Этот ответ показывает, что используется: -lm идет после исходного файла ceil.c.Если вы строите с make и т. Д., То вы обычно используете ceil.o в командной строке (вместе с другими объектными файлами);обычно вы должны перечислить все объектные файлы перед любой из библиотек.

Иногда бывают исключения из практического правила, но они редки и будут документированы для конкретных случаев, когдаисключение ожидается / требуется.При отсутствии явных документов об обратном примените правило большого пальца.

9 голосов
/ 25 ноября 2011

Не хватает репутации, чтобы комментировать ответ @Jonathan Leffler. Хотелось бы упомянуть, что книга Питера ван дер Линдена Программирование на Эксперте C хорошо посвящена этому вопросу в главе 5 Думая о связывании .

На архивы (статические библиотеки) действуют иначе, чем на общие объекты (динамические библиотеки). В динамических библиотеках все символы библиотеки попадают в виртуальное адресное пространство выходного файла, и все символы доступны для всех других файлов в ссылке. Напротив, статическое связывание просматривает архив только для неопределенных символов, которые в настоящее время известны загрузчику на момент обработки архива.

Если вы укажете математическую библиотеку (которая обычно является статической) перед вашими объектными файлами, то компоновщик не добавит никаких символов.

3 голосов
/ 17 декабря 2014

Попробуйте скомпилировать так:

gcc -Wall -g file.c -lm -o file

У меня была такая же проблема, и она была решена с помощью этой команды. Кроме того, если вы установили Ubuntu в тот же день, когда у вас возникла проблема, это может быть проблемой обновления.

...