如何在makefile中使用LDFLAGS

时间:2012-11-06 11:03:11

标签: makefile ldflags

我是Linux OS新手。我正在尝试使用makefile编译.c文件。必须链接数学库。我的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 个答案:

答案 0 :(得分:61)

您的链接器(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)的顺序。

答案 1 :(得分:50)

在更复杂的构建场景中,通常将编译分解为阶段,首先进行编译和汇编(输出到目标文件),然后将目标文件链接到最终的可执行文件或库中 - 这可以防止必须重新编译所有目标文件的源文件未更改。这就是为什么当你将-lm放入CFLAGS时,包含链接标志CFLAGS不起作用的原因(编译阶段使用LOADLIBES)。

要链接的库的惯例是将它们放在LDLIBSLDLIBS=-lm 中(GNU make包含两者,但您的里程可能会有所不同):

-p

这应该允许您继续使用内置规则,而不必编写自己的链接规则。对于其他品牌,应该有一个标志来输出内置规则(对于GNU make,这是-l)。如果您的make版本没有用于链接的内置规则(或者如果它没有client.o: client.c $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $< client: client.o $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@ 指令的占位符),那么您需要编写自己的:

{{1}}

答案 2 :(得分:1)

似乎链接标志的顺序在旧版本的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版本,我对发行版有所了解