版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/helaisun/article/details/79618485
自动遍历子目录的通用Makefile
本文对文章 “一份通用makefile,自动遍历子目录源文件,自动生成依赖”进行了些许修改,并根据自己使用情况修改一份适合编译*.c文件的,自测试可以使用。
这份makefile可以将当前makefile所在文件夹以及所有子文件夹中的cpp文件打包成静态库/动态库/可执行文件.
自动生成所有依赖关系,修改任何文件都可以触发重新编译相应依赖的文件。 在Ubuntu 和 OSX 系统测试通过。
SHELL = /bin/bash
AllDirs := $(shell ls -R | grep '^\./.*:$$' | awk '{gsub(":","");print}') .
Sources := $(foreach n,$(AllDirs) , $(wildcard $(n)/*.cpp))
Objs := $(patsubst %.cpp,%.o, $(Sources))
Deps := $(patsubst %.cpp,%.d, $(Sources))
StaticLib := libyy.a
DynamicLib := libyy.so
Bin := obj
AllLibs : $(Bin)
CC = gcc
CXX = g++
RM = rm -f
#CXXFLAGS = -g -O2 -fPIC -Wall
CXXFLAGS = -g -Wall
CPPFLAGS = $(foreach n,$(AllDirs) , -I$(n))
LDFLAGS = -lstdc++
$(StaticLib) : $(Objs)
ar rcs $@ $^
$(DynamicLib) : $(Objs)
$(CXX) -shared -o $@ $^ $(LDFLAGS)
$(Bin) : $(Objs)
$(CXX) $(Objs) -o $@
%.d : %.cpp
$(CXX) -MT"$(<:.cpp=.o) $@" -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@
sinclude $(Deps)
clean:
$(RM) $(Objs) $(Deps) $(Bin)
.PHONY : clean
其中:
$< :代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件。
$^: 代表所有通过目录搜索得到的依赖文件的完整路径名(目录 + 一般文件名)列表。
$@:代表规则的目标
使用时,输入make clean即可把make生成的中间文件(.o .d)和目标文件(obj)清除掉。
上述的Makefile适合于*.cpp文件的编译,为了使用C文件的编译对上面的Makefile进行稍微的修改,如下:
SHELL = /bin/bash
AllDirs := $(shell ls -R | grep '^\./.*:$$' | awk '{gsub(":","");print}') .
Sources := $(foreach n,$(AllDirs) , $(wildcard $(n)/*.c))
Objs := $(patsubst %.c,%.o, $(Sources))
Deps := $(patsubst %.c,%.d, $(Sources))
StaticLib := libyy.a
DynamicLib := libyy.so
Bin := obj
AllLibs : $(Bin)
CC = gcc
CXX = g++
RM = rm -f
CXXFLAGS = -g -Wall
CPPFLAGS = $(foreach n,$(AllDirs) , -I$(n))
LDFLAGS = -lstdc++
$(StaticLib) : $(Objs)
ar rcs $@ $^
$(DynamicLib) : $(Objs)
$(CC) -shared -o $@ $^ $(LDFLAGS)
$(Bin) : $(Objs)
$(CC) $(Objs) -o $@
%.d : %.cpp
$(CC) -MT"$(<:.c=.o) $@" -MM $(CXXFLAGS) $(CPPFLAGS) $< > $@
sinclude $(Deps)
clean:
$(RM) $(Objs) $(Deps) $(Bin)
.PHONY : clean
在执行Makefile时,有时候会出现missing separator的错误,通常的原因是tab格式导致的。makefile里只有命令所在的行才能且只能以TAB开头,make变量的定义、赋值,make内定函数如$(error “strings”)都不能以TAB开头,不然make会将其作为命令来处理!“makefile: * missing separator. Stop”