首页 > 解决方案 > 如何使用 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) 为空?),在第二次运行示例后按预期创建

标签: makefiledirectory

解决方案


BetaMadScientist评论的启发,我想我有一个解决方案:

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

推荐阅读