Как использовать LDFLAGS в make файле
Я новичок в ОС Linux. Я пытаюсь скомпилировать файл .c
с помощью make файла. Математическая библиотека должна быть связана. Мой make файл выглядит так:
CC=gcc
CFLAGS=-Wall -lm
all:client
.PHONY: clean
clean:
rm *~ *.o client
Когда я запускаю make
, я получаю следующую ошибку:
"undefined reference to rint"
Поэтому он не может связать математическую библиотеку.
Но когда я компилирую явное использование
gcc client.c -lm -o client
он успешно компилируется.
Итак, как мне изменить свой make файл так, чтобы он работал. Я уже пробовал добавить LDFLAGS=-lm
. Но я получаю ту же ошибку.
Я также должен добавить, что при запуске make
он расширяется до
gcc -Wall -lm client.c -o client
(обратите внимание, что при явном запуске gcc
с -lm
в конце он работает).
Ответы
Ответ 1
Вашему компоновщику (ld) явно не нравится порядок, в котором make упорядочивает аргументы GCC, поэтому вам придется немного изменить ваш Makefile:
CC=gcc
CFLAGS=-Wall
LDFLAGS=-lm
.PHONY: all
all: client
.PHONY: clean
clean:
$(RM) *~ *.o client
OBJECTS=client.o
client: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS)
В строке, определяющей цель клиента, измените порядок $ (LDFLAGS) по мере необходимости.
Ответ 2
В более сложных сценариях сборки обычно прерывать компиляцию на этапы, сначала происходит сбор и сборка (вывод в объектные файлы), а также связывание объектных файлов с окончательным исполняемым файлом или библиотекой впоследствии - это не позволяет перекомпилировать все объектные файлы, когда их исходные файлы не изменились. Вот почему включение флага связи -lm
не работает, когда вы помещаете его в CFLAGS
(CFLAGS
используется на этапе компиляции).
Соглашение о подключении библиотек состоит в том, чтобы поместить их в LOADLIBES
или LDLIBS
(GNU make включает оба варианта, но ваш пробег может отличаться):
LDLIBS=-lm
Это позволит вам продолжать использовать встроенные правила, а не писать собственное правило привязки. Для других целей должен быть флаг для вывода встроенных правил (для GNU make, это -p
). Если ваша версия make не имеет встроенного правила для связывания (или если у него нет указателя на -l
), вам нужно написать свой собственный:
client.o: client.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o [email protected] $<
client: client.o
$(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o [email protected]
Ответ 3
Похоже, что порядок связующих флагов не был проблемой в более старых версиях gcc. Например, gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
поставляется с Centos-6.7 довольным вариантом компоновщика перед входным файлом; но gcc с ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413
не разрешает.
Это не только версия gcc, у меня есть что-то с дистрибутивами