如何在makefile中使用LDFLAGS

我是Linux操作系统的新手。 我正在尝试使用makefile编译一个.c文件。 math库必须被链接。 我的makefile如下所示:

 CC=gcc CFLAGS=-Wall -lm all:client .PHONY: clean clean: rm *~ *.o client 

当我运行make ,出现以下错误:

 "undefined reference to rint" 

所以它不能链接math库。

但是,当我明确使用编译

 gcc client.c -lm -o client 

它成功编译。

那么我应该如何改变我的makefile文件呢。 我已经尝试添加LDFLAGS=-lm 。 但是我得到同样的错误。

我还应该补充说,当我运行make ,它会扩展到

 gcc -Wall -lm client.c -o client 

(注意,当我最后用-lm显式运行gcc时,它工作正常)。

你的链接器(ld)显然不喜欢make排列GCC参数的顺序,所以你必须改变你的Makefile文件:

 CC=gcc CFLAGS=-Wall LDFLAGS=-lm OBJECTS=client.o client: $(OBJECTS) $(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS) all:client .PHONY: clean clean: rm -f *~ *.o client 

在定义客户端目标的行中,根据需要更改$(LDFLAGS)的顺序。

在更复杂的构build场景中,通常将编译分为几个阶段,首先编译和汇编(输出到目标文件),然后将目标文件链接到最终的可执行文件或库中 – 这样可以防止在重新编译所有目标文件时他们的源文件没有改变。 这就是为什么包含链接标志-lm在将其放入CFLAGSCFLAGS用于编译阶段)时不起作用的原因。

图书馆链接的惯例是把它们放在LOADLIBESLDLIBS (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)在input文件之前带有Centos-6.7满足链接器选项; 但gcc与Ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413不允许。

它不是单独的海湾合作委员会版本,我已经得到了与发行版的东西