如何根据构建选项创建 makefile

发布于 2024-09-28 11:49:48 字数 193 浏览 4 评论 0原文

很久以前,我记得使用过一些 Solaris make,它们有一个巧妙的选项,可以自动检测编译器选项何时更改,并适当地重建所有规则。例如,假设我从:

g++ -O3

切换到

g++ -g

那么所有文件都应该重新编译。我正在使用 gnu make,但还没有找到任何这样的功能,并且想知道是否有人有办法让它工作。

A long time ago, I remember using some Solaris make, and they had an ingenious option that would automatically detect when the compiler options had changed, and rebuild all rules appropriately. For example, suppose I switch from:

g++ -O3

to

g++ -g

Then all files should be recompiled. I'm using gnu make, and haven't found any feature like this, and was wondering whether anyone has a way of making it work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

赠我空喜 2024-10-05 11:49:48

使用gmake实现此目的的一个简单方法是将gcc选项写入文件中。然后,在Makefile中,将这些选项读取到一个变量中,在gcc命令行中使用这个变量,并将所有目标文件的依赖添加到这个选项文件中(可以在模式规则中完成)。

A simple way to achieve this with gmake is to write the gcc options into a file. Then, in the Makefile, read these options to a variable, use this variable in the gcc command line, plus add the dependency for all object files to this option file (can be done in the pattern rule).

和影子一齐双人舞 2024-10-05 11:49:48

这是执行此操作的基本方法(尽管我确信这是一个可怕的想法,请参见下文):

-include CFLAGS.save

CFLAGS := -O2 -g

all: foo

CFLAGS.save:
    echo 'CFLAGS_SAVE := $(CFLAGS)' > $@
ifeq ($(CFLAGS),$(CFLAGS_SAVE))
%.o: %.c CFLAGS.save
    gcc $(CFLAGS_SAVE) -c -o $@ 
lt;
else
.PHONY: CFLAGS.save
%.o: %.c CFLAGS.save
    $(MAKE) $@
endif

foo: foo.o
    gcc -o $@ $^

发生的情况如下:在完成任何编译之前,当前的 CFLAGS 是写出到CFLAGS.save。如果 CFLAGS 不等于 CFLAGS_SAVE,则用户一定已更改它们。如果是这样,我们声明 CFLAGS.save 是假的,因此 make 将重建它。另请注意,如果 CFLAGS 已更改,我们将更新它,但内存中仍保留旧值。因此,我们必须为每个源文件递归调用make。对于一个大项目来说并不酷。

另一个问题是,如果您忽略在命令行上指定 CFLAGS,它将返回并使用默认值重建所有内容。您可以通过测试 CFLAGS$(origin) 来解决这个问题,但说实话,不行。我的职业道德不允许我这么做。

make 的目的是简单。发行商已经很难理解打包者对构建工具的滥用(遗憾的是,大多数针对 automake 的指责都是由于这一点)。请对 Cthulloid 构建系统说不。

此外,make clean all CFLAGS='-Whatever -foo' 也同样有效。

Here's a basic way to do this (although I'm convinced it's a terrible idea, see below):

-include CFLAGS.save

CFLAGS := -O2 -g

all: foo

CFLAGS.save:
    echo 'CFLAGS_SAVE := $(CFLAGS)' > $@
ifeq ($(CFLAGS),$(CFLAGS_SAVE))
%.o: %.c CFLAGS.save
    gcc $(CFLAGS_SAVE) -c -o $@ 
lt;
else
.PHONY: CFLAGS.save
%.o: %.c CFLAGS.save
    $(MAKE) $@
endif

foo: foo.o
    gcc -o $@ $^

Here's what happens: Before any compilation is done, the current CFLAGS are written out to CFLAGS.save. If CFLAGS isn't equal to CFLAGS_SAVE, then the user must've changed them. If so, we declare CFLAGS.save to be phony so make will rebuild it. Note also that if CFLAGS has changed, we'll update it but we'll still have the old value in memory. Therefore, we have to recursively invoke make for every source file. Not cool on a big project.

The other problem is that if you neglect to specify CFLAGS on the command line, it will go back and rebuild everything with the default. You could work around this by testing the $(origin) of CFLAGS, but seriously, no. My professional ethics won't allow me to stand for this.

make is meant to be simple. Distributors already have enough trouble understanding packagers' abuses of build tools (sadly, most of the blame levelled at automake is due to this). Please, just say no to Cthulhoid build systems.

Besides, make clean all CFLAGS='-Whatever -foo' will work just as well.

蹲墙角沉默 2024-10-05 11:49:48

只需让你的目标依赖于 makefile 本身:

all: a.out

a.out: boo.c Makefile
        cc -O3 -g boo.c

Just make your target depend on the makefile itself:

all: a.out

a.out: boo.c Makefile
        cc -O3 -g boo.c
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文