Makefile用于具有自动目标创建的潜在大型项目

时间:2015-07-30 15:48:42

标签: c makefile gnu

我们说我有一个C项目。有几个文件:

/myproject/makefile
/myproject/src
/myproject/build
/myproject/src/baseHeader.h
/myproject/src/module1/module1.h
/myproject/src/module1/module1_a.c
/myproject/src/module1/module1_b.c
/myproject/src/main.c

我希望make在src中搜索不在第一个深度级别的所有* .h文件,即make应该在

中查找* .h文件
/myproject/src/module1/

因此不会使用

/myproject/src/baseHeader.h

然后对于每个找到的.h make应创建目标,其基本名称为.h,即

/myproject/src/module1/module1.h 

应该是

./build/module1.o: ./src/module1/module1_a.c ./src/module1/module1_b.c ./src/module1/module1.h $(OTHER_DEPS) | $(OPTIONAL_DEPS)
        $(CC) -c $< -o $@

它也应该为/ myproject / src / dir中的每个.c文件创建目标,而不是递归,在这个例子中只找到main.c而且target应该看起来像

./build/main.o: ./src/main.c $(OTHER_DEPS) | $(OPTIONAL_DEPS)

如何做到这一点? 有人可以给我提供示例链接吗?

我要求这样做是因为经过一天的尝试后我觉得忘记制作和使用bash脚本会更好......

1 个答案:

答案 0 :(得分:0)

这可以做到,但这不是微不足道的。一种方法是在.h目录及其子目录中递归地构建所有src文件的列表,然后从该列表中删除.h中的src个文件目录。

我们可以使用.h搜索$(wildcard src/**/*.h))文件的src目录和所有子目录,只搜索带有$(wildcard src / * .h)的.h文件的src目录。这些可以与filter-out函数结合使用,以生成仅包含.h子目录中的src/个文件的列表,如

MODULES := $(filter-out $(wildcard src/*.h),$(wildcard src/**/*.h))

这将生成一个类似

的列表
/myproject/src/module1/module1.h
/myproject/src/module2/module2.h
/myproject/src/module3/module3.h

我们可以用

删除目录结构
INCLUDES := $(notdir MODULES)

将产生

module1.h
module2.h
module3.h

我们可以使用

将这些转换为模块的目标文件
OBJDIR = build
OBJS := $(addprefix $(OBJDIR)/, $(patsubst %.h,%.o, $(INCLUDES)))

然后我们定义一个空的目标规则来创建所有这些

.PHONY: modules    
modules: $(OBJS)

创建对象的隐式规则

$(OBJDIR)/%.o: $(dir $(findstring %.h, $MODULES))*.c %.h $(OTHER_DEPS) | $(OPTIONAL_DEPS)
    $(CC) -c $? -o $@

编辑:不建议在先决条件列表中使用通配符,但这是我现在最好的解决方案。

要为.c中的每个src文件编译目标而不进行递归搜索,我们会采用类似的方法开始。

SRCS := $(wildcard src/*.c)

将找到顶级.c目录中的所有src个文件。我们可以使用

编译这些目标
$(SRCS:%.c=$(OBJDIR)/%.o): %.c $(OTHER_DEPS) | $(OPTIONAL_DEPS)