【问题标题】:How to use LDFLAGS in makefile如何在 makefile 中使用 LDFLAGS
【发布时间】:2012-10-26 07:43:39
【问题描述】:

我是 Linux 操作系统的新手。我正在尝试使用 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 时,它可以工作)。

【问题讨论】:

    标签: makefile ldflags


    【解决方案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)
    

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

    【讨论】:

    • LDLIBS 用于库,LDFLAGS 应用于标志/搜索路径 (-L)
    • 我还认为 -lm 应该在 LDFLAGS 中,但事实证明(请参阅 laindir 的回答和gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html),它应该在 LOADLIBES 中,然后一切正常(即没有定义明确的规则)!
    • 您在规则中的何处使用源代码?它已定义,但未使用。很难理解这一点。
    • @MrPickles:你说得对,SOURCE 实际上没有使用,可以删除。
    • @EmilVatai 根据gnu.org/software/make/manual/make.html#index-LDLIBS LOADLIBES 已弃用,应改用 LDLIBS。
    【解决方案2】:

    在更复杂的构建场景中,通常将编译分成多个阶段,首先进行编译和组装(输出到目标文件),然后将目标文件链接到最终的可执行文件或库中——这样可以避免重新编译所有源文件未更改时的目标文件。这就是为什么将链接标志-lm 放入CFLAGS 时不起作用的原因(CFLAGS 用于编译阶段)。

    要链接的库的约定是将它们放在LOADLIBESLDLIBS 中(GNU make 包括这两者,但你的里程可能会有所不同):

    LDLIBS=-lm
    

    这应该允许您继续使用内置规则,而不必编写自己的链接规则。对于其他品牌,应该有一个输出内置规则的标志(对于 GNU 品牌,这是-p)。如果您的 make 版本没有内置的链接规则(或者如果它没有 -l 指令的占位符),您需要编写自己的:

    client.o: client.c
        $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o $@ $<
    
    client: client.o
        $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@
    

    【讨论】:

      【解决方案3】:

      似乎链接标志的顺序在旧版本的 gcc 中不是问题。例如gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16) 带有 Centos-6.7,在输入文件之前对链接器选项感到满意;但是 ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413 的 gcc 不允许。

      它不仅仅是 gcc 版本,我与发行版有一些关系

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-03-17
        • 2015-03-18
        • 2011-08-29
        • 1970-01-01
        • 1970-01-01
        • 2014-09-04
        • 2018-10-27
        相关资源
        最近更新 更多