如何在 BSD make 中处理调试和释放编译器标志

问题描述 投票:0回答:1

使用 BSD make,我希望对程序的调试和发布版本使用不同的编译器标志。要构建的程序的版本应通过

MODE
变量定义。我只想在必要时运行编译器,这意味着如果我构建调试版本然后构建发布版本,我想重新编译所有对象,即使它们在技术上根据 make 是最新的。

我的 makefile 的简化版本如下所示:

MODE ?= DEBUG # DEBUG or RELEASE

CFLAGS = -std=c99 -Werror -Wall -Wextra

.if $(MODE) == DEBUG
CFLAGS += -g -fsanitize=undefined,address
.endif

a.o: a.c a.h
    cc -c $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.c)

b.o: b.c a.h b.h
    cc -c $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.c)

c.o: c.c c.h
    cc -c $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.c)

program: a.o b.o c.o
    cc $(CFLAGS) -o $(.TARGET) $(.ALLSRC)

这个例子第一次构建得很好,但是如果我将

MODE
更改为
RELEASE
,make 会告诉我没有什么可构建的,因为一切都已经是最新的了。

我发现实现我正在寻找的结果的唯一方法是在构建过程结束时将

MODE
变量打印到纯文本文件中,检查与当前
MODE
值是否相等,并强制如果
MODE
已更改,则在所有“可重建”目标上重建。

MODE ?= DEBUG # DEBUG or RELEASE
LAST_MODE != cat mode

CFLAGS = -std=c99 -Werror -Wall -Wextra

.if $(MODE) == DEBUG
CFLAGS += -g -fsanitize=undefined,address
.endif

.if $(MODE) != $(LAST_MODE)
rebuildable: .PHONY

.END:
    printf "$(MODE)" > $(EXPORTS)/mode
.else
rebuildable: .USE
.endif

a.o: a.c a.h rebuildable
    cc -c $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.c)

b.o: b.c a.h b.h rebuildable
    cc -c $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.c)

c.o: c.c c.h rebuildable
    cc -c $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.c)

program: a.o b.o c.o rebuildable
    cc $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.o)

有没有更惯用、不那么老套的方法来做到这一点?

makefile bsd bsdmake
1个回答
1
投票

有没有更惯用、不那么老套的方法来做到这一点?

你必须有一些的方式来记住已经建立的模式目标。 不过,我建议,对这个问题的更自然的看法是,

Target-A-Debug
在逻辑上与
Target-A-Release
是不同的目标,即使它们最终是从相同的来源构建的。 因此你应该对它们有不同的规则。

这可能会产生类似这样的结果(但如果我错误了任何

bmake
特定的语法,请原谅我):

MODE ?= DEBUG # DEBUG or RELEASE

CFLAGS_RELEASE = -std=c99 -Werror -Wall -Wextra
CFLAGS_DEBUG = $(CFLAGS_RELEASE) -g -fsanitize=undefined,address

OBJS_BASE = a.o b.o c.o

.if $(MODE) == DEBUG
MODE_SUFFIX = -debug
.else
MODE_SUFFIX = -release
.endif

all: program$(MODE_SUFFIX) .PHONY
    cp $(.ALLSRC[1]) program

a-debug.o: a.c a.h
    cc -c $(CFLAGS_DEBUG) -o $(.TARGET) $(.ALLSRC:M*.c)

b-debug.o: b.c a.h b.h
    cc -c $(CFLAGS_DEBUG) -o $(.TARGET) $(.ALLSRC:M*.c)

c-debug.o: c.c c.h
    cc -c $(CFLAGS_DEBUG) -o $(.TARGET) $(.ALLSRC:M*.c)

program-debug: $(OBJS_BASE:S/.o$/-debug.o/)
    cc $(CFLAGS) -o $(.TARGET) $(.ALLSRC:M*.o)

a-release.o: a.c a.h
    cc -c $(CFLAGS_RELEASE) -o $(.TARGET) $(.ALLSRC:M*.c)

b-release.o: b.c a.h b.h
    cc -c $(CFLAGS_RELEASE) -o $(.TARGET) $(.ALLSRC:M*.c)

c-release.o: c.c c.h
    cc -c $(CFLAGS_RELEASE) -o $(.TARGET) $(.ALLSRC:M*.c)

program-release: $(OBJS_BASE:S/.o$/-release.o/)
    cc $(CFLAGS_RELEASE) -o $(.TARGET) $(.ALLSRC:M*.o)

我想可以应用一两个 bmake-ism 将这两个单独的规则列表合并为一个 - 这作为练习:-)

© www.soinside.com 2019 - 2024. All rights reserved.