我们说我有一个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脚本会更好......
答案 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)