【问题标题】:GNU Make gcc, order of optionsGNU Make gcc,选项顺序
【发布时间】:2021-05-27 06:53:18
【问题描述】:

我试图弄清楚 make 是如何处理 gcc 命令上的选项的:

我正在重建 Richard Dobson 的一个程序以将声音文件转换为浮点数, 它需要链接一个位于$HOME/.local/lib的静态库

如果我运行,项目构建没有问题 gcc -Wl,-rpath=$HOME/.local/lib -lm -o sf2float sf2float.c -lportsf

在堆栈交换的其他地方有一些非常有用的帖子,还有https://nullprogram.com/blog/2017/06/19/

我真的很想知道如何在 makefile 中运行这个命令。

我尝试了以下 makefile 的几种不同变体:

SHELL=bash

CC = gcc
CFLAGS = -Wall
LDFLAGS = -Wl,-rpath=$$HOME/.local/lib -lm -lportsf

OBJECTS = sf2float.o
BINARY = sf2float

all: sf2float

example: $(OBJECTS)
    $(CC) $(CFLAGS) $(OBJECTS) -o $(BINARY) $(LDFLAGS)

clean:
    rm -f $(BINARY) $(OBJECTS)

这会返回编译器选项顺序略有不同的变化,然后在找不到静态库后会出现一堆错误:

gcc -Wl,-rpath=$HOME/.local/lib -lm -lportsf  sf2float.o   -o sf2float
/usr/bin/ld: sf2float.o: in function `main':
sf2float.c:(.text+0x64): undefined reference to `psf_init'
/usr/bin/ld: sf2float.c:(.text+0x9d): undefined reference to `psf_sndOpen'
/usr/bin/ld: sf2float.c:(.text+0xfd): undefined reference to `psf_getFormatExt'
/usr/bin/ld: sf2float.c:(.text+0x15b): undefined reference to `psf_sndCreate'
/usr/bin/ld: sf2float.c:(.text+0x210): undefined reference to `psf_sndReadFloatFrames'
/usr/bin/ld: sf2float.c:(.text+0x23b): undefined reference to `psf_sndWriteFloatFrames'
/usr/bin/ld: sf2float.c:(.text+0x268): undefined reference to `psf_sndReadFloatFrames'
/usr/bin/ld: sf2float.c:(.text+0x2c7): undefined reference to `psf_sndReadPeaks'
/usr/bin/ld: sf2float.c:(.text+0x38f): undefined reference to `psf_sndClose'
/usr/bin/ld: sf2float.c:(.text+0x39f): undefined reference to `psf_sndClose'
/usr/bin/ld: sf2float.c:(.text+0x3ca): undefined reference to `psf_finish'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: sf2float] Error 1

看起来我的库的顺序有点混乱,老实说,我只是不完全确定这里发生了什么。正如我上面提到的那样,该项目正在建设中,但我想更清楚地理解这个问题。非常感谢任何帮助!

【问题讨论】:

  • -o $(BINARY) 移动到Example 目标的末尾。你在$(LDFLAGS) 之前就已经得到了它,这显然不是有效的。
  • 这条评论不对。 -o 的顺序无关紧要。
  • 这里的礼仪是始终勾选最佳答案...这让您询问一些声誉积分并给回答者一些积分,另外它告诉那些在家观看的人这是真正的答案。 .. 欢迎来到 SO

标签: c gcc audio makefile static-libraries


【解决方案1】:

您有两个问题导致您的问题。

第一个问题是 make 问题:您要求 make 构建 sf2float,因为您将 all: sf2float 作为您的第一个目标。

但是,你还没有告诉 make 如何构建 sf2float。您告诉它如何构建一个名为 example 的目标,但您从未将其列为任何事情的先决条件:

example: $(OBJECTS)

所以,make 根本没有使用你的规则。幸运的是 (?) make 有内置规则,知道如何从同名的目标文件创建二进制文件。该内置规则(基本上)如下所示:

% : %.o
        $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

这会给你你看到的命令行:

gcc -Wl,-rpath=$HOME/.local/lib -lm -lportsf  sf2float.o   -o sf2float

这会给您看到的错误,因为您在目标文件之前的链接行中有库,并且 GCC 像大多数链接器一样是单通道链接器。

要解决此问题,您应该做以下两件事之一(或两者兼而有之):

按照惯例,LDFLAGS make 变量用于链接器标志,如-Wl...LDLIBS make 变量用于库,如-lm。所以要遵循惯例,你会写:

LDFLAGS = -Wl,-rpath=$$HOME/.local/lib
LDLIBS = -lportsf -lm

并且/或者,如果您想使用您的规则而不是内置规则,您应该将目标更改为 sf2float(或者,在任何地方使用 $(BINARY) 变量)。

【讨论】:

  • 嘿,谢谢一百万 - 这真的澄清了事情。今天早上我还去快速浏览了 gcc 手册的选项部分,所以它帮助我更清楚地思考我在做什么。我注意到的第一件事是未能将 sf2float 指定为您正确指出的目标。第二件事显然是混乱的 LDFLAGS 任务。非常感谢您的回答,真的很清楚!
  • 如果您的问题得到了回答,请这样标记,以便其他人知道。
  • 啊哈,谢谢 - 最初看不到复选标记!
猜你喜欢
  • 2010-12-06
  • 2021-12-24
  • 1970-01-01
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 2015-01-17
相关资源
最近更新 更多