如何在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
在将其放入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)
在input文件之前带有Centos-6.7满足链接器选项; 但gcc与Ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413
不允许。
它不是单独的海湾合作委员会版本,我已经得到了与发行版的东西