5

我阅读了很多关于的教程CFLAGS,还查看了官方文档。他们说的所有地方CFLAGS都是隐式的,但仍然在他们的示例 makefile 中将其显式传递给编译器:

CFLAGS=-O2
gcc $(CFLAGS) -c foo.c -o foo.o

那么,在这种情况下,“隐式”一词是什么意思?如果我CFLAGS=-O2在我的 makefile 中声明然后只是说gcc -c foo.c -o foo.o, 是否-O2会处于活动状态(那么,它真的是隐含的吗)?如果是这样,为什么所有教程(包括官方文档)仍然在他们的示例中明确传递它?

4

4 回答 4

9

他们到处都说 CFLAGS 是隐式的,但仍然在他们的示例 makefile 中将其显式传递给编译器。

gcc 不使用CFLAGS环境变量。请参阅影响 GCC 的环境变量

CFLAGS是具有 C 编译器标志的 Makefile 变量的常规名称,它被隐式 make 规则使用。有关详细信息,请参阅隐式规则使用的变量。

如果您使用自己的 make 规则而不是内置规则,则根本不需要使用CFLAGS。尽管这样做是一个有用的约定,因为人们熟悉传统的 make 变量名称。

于 2015-04-27T15:26:34.827 回答
1

您可以轻松地对其进行测试:

$ cat cflags.mak 
CFLAGS = -wrong

foo.o: foo.c

$ make -f cflags.mak 
cc -wrong   -c -o foo.o foo.c
cc: unrecognized option '-wrong'

所以你可以看到它使用了 CFLAGS 的值,即使它没有在规则中明确指定;因此它是隐含的。

但是,如果您确实为编译 .c 文件指定了自己的规则,如果您想使用它,则必须包含它:

$ cat cflags.mak 
CFLAGS = -wrong

foo.o: foo.c
    gcc -c $<
$ make -f cflags.mak 
gcc -c foo.c

在这里,我为不包含 CFLAGS 的 .c 文件提供了我自己的规则,因此没有使用 CFLAGS。

所以底线是如果你依赖内置的 make 规则来编译 .c 文件,CFLAGS 将被隐式包含。但是,如果您覆盖该规则,如果您仍希望使用它,则必须明确包含它。

于 2015-04-27T15:32:37.550 回答
1

这意味着有使用 CFLAGS 的隐式 make 规则,您可以使用。所以你可以写一个单行makefile:

CFLAGS=-O2

如果你以后这样做:

make filename

(省略扩展名)它将使用引用 CFLAGS 的隐式规则将源文件 .c 转换为可执行文件,因此您无需为简单构建编写显式构建语句。

例如,如果您准备了一个源名称 file.c,它将使用隐式规则构建它,例如:

$GCC $CFLAGS file.c -o file $LDFLAGS

请参阅:GNU 制作文档

于 2015-04-27T15:32:37.627 回答
1

我相信 CFLAGS 是由 makefile 通过默认编译规则隐式传递给编译器命令行的......但是 CFLAGS 可以用自定义标志覆盖,以便每个编译命令都可以使用它。

于 2015-04-27T15:28:57.460 回答