Подтвердить что ты не робот

Как использовать 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 в конце он работает).

4b9b3361

Ответ 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, у меня есть что-то с дистрибутивами