makefile - 具有两个目标和单独的构建文件夹的 Makefile
问题描述
我正在尝试使用具有两个相似目标和两个单独构建文件夹的 Makefile。目标之间的唯一区别是添加了CFLAG
定义。
这是我所拥有的一个片段,但是我无法让构建文件夹根据目标评估不同的东西。我用foo
andbar
来表示不同的目标。
...
foo_BUILD_DIR := build_foo/
bar_BUILD_DIR := build_bar/
C_SRCS := main.c
CFLAGS := -std=c99 -Os -Wall
foo_CFLAGS := $(CFLAGS) -DBLE=1
C_OBJS := $(addprefix $(BUILD_DIR),$(subst .c,.o,$(C_SRCS)))
$(BUILD_DIR)%.o: %.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) $^ -o $@
foo:$(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $@
bar:$(OBJS)
$(CC) $(OBJS) $(LDFLAGS) -o $@
解决方案
您需要在这里解决三个问题。
首先是在构建目录中构建目标文件。首先我们编写一个模式规则来构建 foo 对象:
foo_BUILD_DIR := build_foo. # Don't put the trailing slash in the dir name, it's a pain.
CFLAGS := -std=c99 -Os -Wall
foo_CFLAGS := $(CFLAGS) -DBLE=1
$(foo_BUILD_DIR)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(foo_CFLAGS) $^ -o $@
一旦完美运行,我们为 bar 对象编写另一个规则:
$(bar_BUILD_DIR)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) $^ -o $@
第二个问题是整理我们到目前为止所写的内容。该foo_CFLAGS
变量现在是使这两个配方不同的唯一因素,因此让我们通过特定于目标的变量赋值来摆脱它:
$(foo_BUILD_DIR)/%.o: CFLAGS += -DBLE=1
$(foo_BUILD_DIR)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) $^ -o $@
现在我们可以将规则组合成一个具有两个目标的模式规则:
$(foo_BUILD_DIR)/%.o: CFLAGS += -DBLE=1
$(foo_BUILD_DIR)/%.o $(bar_BUILD_DIR)/%.o: %.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) $^ -o $@
第三个问题是获取foo
和bar
规则来要求正确的对象。显然这条规则:
foo:$(OBJS)
...
不行,我们需要一些特定的东西foo
:
foo: $(addprefix $(foo_BUILD_DIR)/, $(OBJS))
...
这行得通,但它要求我们编写一个foo
指定的规则$(foo_BUILD_DIR)
,一个指定的bar
规则,$(bar_BUILD_DIR)
等等。有没有更懒的方法?我们所需要的只是获取目标(例如foo
)并将其放入先决条件列表中。如您所知,自动变量 $@
包含目标,但它在先决条件列表中不可用,因为先决条件列表在为该变量分配值之前已展开 -除非我们使用Secondary Expansion。这是一种先进的技术,但它允许我们在后期进行第二次扩展(使用额外的转义变量$
以保护它们免受第一次扩展的影响):
.SECONDEXPANSION:
foo: $(addprefix $$($$@_BUILD_DIR)/, $(OBJS))
...
一旦它起作用了,我们可以添加另一个目标,或者我们想要的任意多个:
foo bar: $(addprefix $$($$@_BUILD_DIR)/, $(OBJS))
...
可能还有一两个改进,但这已经足够开始了。
推荐阅读
- c# - 创建继承接口的对象
- database - 如何将非规范化表(M:M)分解为数据模型(来自同一个表)?
- java - 在 Quarkus 中更改构建时间配置
- python - 如何访问 AirFlow 中 Dag 的列表(Python)中的列表中的属性?
- asp.net - 将重写映射拆分到多个文件的可能性
- python - 如何使用 Stack Exchange API 获取给定评论 id 的问题标签?
- pandas - 如何使用熊猫加载文本文件?
- tensorflow - 为什么使用tensorflow做物体检测时Average Precision和Average Recall = -1?
- swift - SwiftUI 不正确的帧大小
- android - 有什么想法可以提高此自定义视图的渲染性能吗?