博主要建立一个工程目录,但愿将全部的.c文件都编译成.o并存放到out/目录下。以下:shell
. ├── d1 │ ├── aa.c │ └── dd.c ├── main.c ├── Makefile └── out
通过一夜的尝试,最终使用了foreach函数实现了这个目标:数组
TARGET=test ALL_SOURCES=$(shell find -name "*.c") SOURCE_TO_OBJECT = ./out/$(subst .c,.o,$(notdir $(1))) ALL_OBJECTS=$(foreach src,$(ALL_SOURCES),$(call SOURCE_TO_OBJECT,$(src))) define CREATE_OBJECT_TARGET $(call SOURCE_TO_OBJECT,$(1)) : $(1) gcc -c -o $$@ $$^ endef all: $(TARGET) clean: -rm $(ALL_OBJECTS) -rm $(TARGET) $(TARGET):$(ALL_OBJECTS) gcc -o $@ $^ $(foreach src,$(ALL_SOURCES),$(eval $(call CREATE_OBJECT_TARGET,$(src))))
大概思路是这样的:
首先,ALL_SOURCES=$(shell find -name "*.c")
,我将当前目录下的全部.c文件找到并赋值给ALL_SOURCE变量。
而后,ALL_OBJECTS=$(foreach src,$(ALL_SOURCES),$(call SOURCE_TO_OBJECT,$(src)))
,对每一个一ALL_SOURCE
中的源文件进行处理,将每一个文件名去除路径,并将后缀.c替换成.o,再加上./out前缀就成了目标文件名。注意:函数调用中不能随意地加空格!!
SOURCE_TO_OBJECT
是一个将源文件名转换成目标文件名的函数。上面用$(call ...)
对它进行调用。函数
而后,我想为每一个目标文件创建依赖关系,以下:code
./obj/main.o : main.c gcc -c -o $@ $^ ./obj/aa.o : d1/aa.c gcc -c -o $@ $^ ./obj/bb.o : d1/bb.c gcc -c -o $@ $^
文件个数少还好说,若是工程大了,上百个文件维护起来很吃力。因而想到要用 $(foreach ...)
函数来实现。建立这么一个函数,用于生成目标与文件依赖关系:ip
define CREATE_OBJECT_TARGET $(call SOURCE_TO_OBJECT,$(1)) : $(1) gcc -c -o $$@ $$^ endef
转入的一个参数$(1)是源文件全路径。
注意:其中的 gcc -c -o $$@ $$^
,是双 $ 符号。字符串
再用以下的$(foreach ...)函数达到对每个源文件都创建一个目标的目的:
$(foreach src,$(ALL_SOURCES),$(eval $(call CREATE_OBJECT_TARGET,$(src))))
编译
其中用到的命令有:test
其它经常使用的函数还有:变量
若是你们还有别的什么更好的方法,欢迎留言。gcc