GNU Make gcc,选项顺序
GNU Make gcc, order of options
我正在尝试弄清楚 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)
其中returns编译器选项的顺序略有不同,然后在找不到静态库后出现一堆错误:
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
看起来我把库的顺序搞混了,老实说,我只是不太确定这里发生了什么。正如我上面提到的,该项目正在建设中,但我想通过 make 更清楚地了解这个问题。非常感谢任何帮助!
您有两个问题导致了您的问题。
第一个是 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
这会给您带来您看到的错误,因为您在目标文件之前的 link 行上有库,而 GCC 与大多数 link 用户一样是单通道 link呃
要解决此问题,您应该做以下两件事之一(或同时做两件事):
按照惯例,LDFLAGS
make 变量用于 linker flags,如 -Wl...
,LDLIBS
make 变量用于库,如 -lm
。所以按照惯例,你会写:
LDFLAGS = -Wl,-rpath=$$HOME/.local/lib
LDLIBS = -lportsf -lm
And/or,如果你想使用你的规则而不是内置规则,你应该将目标更改为 sf2float
(或者,在任何地方使用 $(BINARY)
变量).
我正在尝试弄清楚 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)
其中returns编译器选项的顺序略有不同,然后在找不到静态库后出现一堆错误:
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
看起来我把库的顺序搞混了,老实说,我只是不太确定这里发生了什么。正如我上面提到的,该项目正在建设中,但我想通过 make 更清楚地了解这个问题。非常感谢任何帮助!
您有两个问题导致了您的问题。
第一个是 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
这会给您带来您看到的错误,因为您在目标文件之前的 link 行上有库,而 GCC 与大多数 link 用户一样是单通道 link呃
要解决此问题,您应该做以下两件事之一(或同时做两件事):
按照惯例,LDFLAGS
make 变量用于 linker flags,如 -Wl...
,LDLIBS
make 变量用于库,如 -lm
。所以按照惯例,你会写:
LDFLAGS = -Wl,-rpath=$$HOME/.local/lib
LDLIBS = -lportsf -lm
And/or,如果你想使用你的规则而不是内置规则,你应该将目标更改为 sf2float
(或者,在任何地方使用 $(BINARY)
变量).