makefile - 如何使用 Makefile 在子文件夹中构建应用程序
问题描述
我正在尝试编写一个 Makefile 来构建存储在子文件夹中的应用程序。所以文件夹的结构如下:
examples/
Makefile
hello_world/
file1.c
main.c
**hello_world** <- expected build result
example1/
otherfile.c
main.c
**example1** <- expected build result
example2/
main.c
...
**example2** <- expected build result
我的 Makefile(简化版)如下所示:
EXAMPLES := hello_world example1 example2
SRC = $(wildcard */*.c)
OBJ = ${SRC:.c=.o}
OUT = $(foreach e, $(EXAMPLES), $(addprefix $(e)/,$(e)) )
CC := gcc
all: examples
$(OBJ): $(SRC)
@$(CC) -c $< -o $@
$(OUT): $(OBJ)
$(CC) $(filter $(dir $@)%,$^) -o $@ $(LDFLAGS)
clean:
@rm -f $(OUT) $(OBJ)
有没有办法让它工作?或者也许我应该在每个文件夹中分别有 Makefile?
此规则似乎解决了我的问题,将输出匹配到 .o,但过滤了为与过滤器函数链接而传递的文件
$(OUT): $(OBJ)
$(CC) $(filter $(dir $@)%,$^) -o $@ $(LDFLAGS)
替换旧规则:
$(OUT): $(OBJ)
$(CC) $^ -o $@
和
examples: $(OBJ)
$(foreach e, $(EXAMPLES), \
$(CC) $(wildcard $(e)/*.o) -o $(e)/$(e) $(LDFLAGS); \
)
现在几乎可以工作了,在清理之后,编译按预期工作,只有链接失败($(通配符 $(e)/*.o) 为空?),在第二次运行示例后按预期创建
解决方案
受Beta和MadScientist评论的启发,我想我有一个解决方案:
EXAMPLES := hello_world example1 example2
SRC = $(wildcard */*.c)
OBJ = ${SRC:.c=.o}
OUT = $(foreach e, $(EXAMPLES), $(addprefix $(e)/,$(e)) )
CC := gcc
all: $(OUT)
%.o: %.c
@$(CC) $(CFLAGS) -c $< -o $@
$(OUT): $(OBJ)
@$(CC) $(filter $(dir $@)%,$^) -o $@ $(LDFLAGS)
clean:
@rm -f $(OUT) $(OBJ)
.PHONY: all clean
推荐阅读
- slurm - Slurm:如何通过脚本使用jobName仅获取jobID
- javascript - 反应国家 -> 省/州 -> 城市选择器?
- swift - “表达式太复杂,无法在合理的时间内解决;考虑将表达式分解为不同的子表达式”
- ruby-on-rails - 延迟作业进程运行,队列中有一个项目,仍然没有运行(也没有失败)
- sql - 当源表上的记录发生更改时,如何创建将记录添加到不同表的触发器?
- vim - 命令托盘中的 Vim 正常模式
- flask - SqlAlchemy + Alembic - 如何修复模式差异
- mysql - MySQL如何解决一对一关系
- r - ggplot 中网格排列的 ggsave() 选项
- r - R:根据组与另一列的最大值相差的新列