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