【发布时间】:2019-02-12 00:24:11
【问题描述】:
我正在尝试设置一个构建系统,该系统支持在单独的文件夹中构建库和可执行文件,而不必求助于递归构建。 我当前的目录树如下:
Project
├── Foo
│ └── src
│ └── foo.c
├── Bar
| └── Source
| └── bar.c
├── App
| └── src
| └── main.c
└── Makefile
注意 Bar 文件夹中的“Source”而不是“src”。
我希望能够生成以下构建目录:
Build
├── Foo
│ ├── foo.o
│ └── foo.a
├── Bar
│ ├── bar.o
│ └── bar.a
└── App
├── main.o
└── app.exe
我还没有找到一种方法来生成通配符配方以在正确的构建目录中生成对象/libs/bins而不重复自己:
BUILD_DIR := Path/To/Build
CC ?= gcc
.PHONY: all
all: Foo Bar
# Foo
FOO_DIR = Foo
FOO_SRCS = foo.c
FOO_OBJS = $(addprefix $(BUILD_DIR)/$(FOO_DIR)/,$(FOO_SRCS:.c=.o))
.PHONY: Foo
Foo: $(FOO_OBJS)
## This line has to be repeated for Bar as well
$(BUILD_DIR)/$(FOO_DIR)/%.o: $(FOO_DIR)/src/%.c | $(BUILD_DIR)/$(FOO_DIR)
$(CC) -c $< -o $@
# Bar
BAR_DIR = Bar
BAR_SRCS = bar.c
BAR_OBJS = $(addprefix $(BUILD_DIR)/$(BAR_DIR)/,$(BAR_SRCS:.c=.o))
.PHONY: Bar
Bar: $(BAR_OBJS)
## Here, I am repeating the same line as in Foo
$(BUILD_DIR)/$(BAR_DIR)/%.o: $(BAR_DIR)/Source/%.c | $(BUILD_DIR)/$(BAR_DIR)
$(CC) -c $< -o $@
# Utils
$(BUILD_DIR)/%:
mkdir -p $@
【问题讨论】:
-
有什么不使用递归make的具体原因吗?它将允许您在单独的
make实例中隔离不同的构建配置,即减少污染的危险、不正确的构建工件和奇怪的构建问题。 -
也就是说,您可能想学习this answer 如何从变量中动态生成源文件和目标文件之间的依赖关系,并使用静态模式规则来避免代码重复。
-
请看this Q/A
-
@StefanBecker 我不能使用递归make,因为“Bar”库不在源代码树中(我在问题中省略了这个)。这也是它的源使用不同目录名称的原因。
-
@Rogozhin 一种解决方案是在您当前的树中为“Bar”添加一个 makefile,其中包含来自“Bar”源树的 Makefile(片段)。