【发布时间】:2019-12-23 03:13:04
【问题描述】:
我有一个生成两个 elf 文件的 Makefile 设置。 elf 文件有两个输入,一个是通用的,一个是唯一的。我正在尝试让公共输入 (main.c) 只编译一次。
我有以下模仿我的设置的示例:
Makefile
proj
- main.c
- print.c
- Makefile
根 Makefile:
.PHONY: all
all: proj/build/0/0.elf proj/build/1/1.elf
proj/build/0/0.elf:
$(MAKE) -C proj VARIANT=0 all
proj/build/1/1.elf:
$(MAKE) -C proj VARIANT=1 all
项目/制作文件:
COMMON_SRCS = main.c
VARIANT_SRCS = print.c
BUILD_DIR_COMMON = build/common
BUILD_DIR_VARIANT= build/$(VARIANT)
OBJECTS += $(addprefix $(BUILD_DIR_COMMON)/,$(COMMON_SRCS:.c=.o))
OBJECTS += $(addprefix $(BUILD_DIR_VARIANT)/,$(VARIANT_SRCS:.c=.o))
.PHONY: all
all: $(BUILD_DIR_VARIANT)/$(VARIANT).elf
$(BUILD_DIR_COMMON)/%.o: %.c
@mkdir -p $(BUILD_DIR_COMMON)
$(CC) -c $< -o $@
$(BUILD_DIR_VARIANT)/%.o: %.c
@mkdir -p $(BUILD_DIR_VARIANT)
$(CC) -DVARIANT=$(VARIANT) -c $< -o $@
$(BUILD_DIR_VARIANT)/$(VARIANT).elf: $(OBJECTS)
$(CC) $(OBJECTS) -o $@
.c 文件并不重要,只要知道 print.c 使用 VARIANT 定义即可。
当我在根目录中运行make 时,我得到以下输出:
make -C proj VARIANT=0 all
make -C proj VARIANT=1 all
make[1]: Entering directory '/home/phil/dev/make_test/proj'
make[1]: Entering directory '/home/phil/dev/make_test/proj'
cc -c main.c -o build/common/main.o
cc -c main.c -o build/common/main.o
cc -DVARIANT=0 -c print.c -o build/0/print.o
cc build/common/main.o build/0/print.o -o build/0/0.elf
cc -DVARIANT=1 -c print.c -o build/1/print.o
cc build/common/main.o build/1/print.o -o build/1/1.elf
make[1]: Leaving directory '/home/phil/dev/make_test/proj'
make[1]: Leaving directory '/home/phil/dev/make_test/proj'
从输出中可以看出,main.c 被编译了两次。我正在寻找一些选项,使其只编译一次而不会完全改变我的项目结构
【问题讨论】:
-
有趣,只有运行
make -j2才能重现此行为。在这种情况下,这是一个简单的竞争条件,可以通过消除make递归(许多人认为这是邪恶的)来避免。
标签: makefile