notdir,wildcard和patsubst是makefile中几个有用的函数,以前没留意过makefile中函数的用法,今天稍微看看~
1、makefile里的函数
makefile里的函数使用,和取变量的值类似,是以一个‘$’开始,然后是一个括号里面是函数名和需要的参数列表,多个变量用逗号隔开,像这样
return = $(functionname arg1,arg2,arg3…)。
可能这里的’$’更像是从某个地址取值类似的操作。
2、 wildcard
使用:SRC = $(wildcard *.cpp )
搜索当前目录下所有以.cpp结尾的文件,然后存入变量 SRC 里。
3、notdir
使用:SRC = $(notdir wildcard)
去除所有的目录信息,SRC里的文件名列表将只有文件名。
4、patsubst
使用:OBJ = $(patsubst%.c,%.o,$(SRC))
patsubst是patten substitude的缩写,匹配替代的意思。它需要3个参数——第一个是一个需要匹配的式样,第二个表示用什么来替换它,第三个是一个需要被处理的由空格分隔的字列。
这行将处理所有在 SRC字列中的字(一列文件名),如果它的结尾是 ‘.c’ ,就用 ‘.o’ 把 ‘.c’取代。注意这里的 % 符号将匹配一个或多个字符,而它每次所匹配的字串叫做一个‘柄’(stem) 。 在第二个参数里,
%被解读成用第一参数所匹配的那个柄。
举个栗子:
#obj dir
SRC := $(wildcard *.cpp $(TINYXMLDIR)/*.cpp $(PUBDIR)/*.cpp $(COMMDIR)/*.cpp)
OBJ := $(patsubst %.cpp, $(OUTDIR)/%.o, $(notdir ${SRC}))
传说中的万能makefile
###########################################################
# Generic makefile
#
# by George Foot
# email: george.foot@merton.ox.ac.uk
#
# Copyright (c) 1997 George Foot
# All rights reserved.
# 保留所有版权
#
# No warranty, no liability;
# you use this at your own risk.
# 沒保险,不负责
# 你要用这个,你自己担风险
#
# You are free to modify and
# distribute this without giving
# credit to the original author.
# 你可以随便更改和发送这个文件
# 而不需要給原作者什么荣誉。
# (你好意思?)
#
######################################
### Customising
#
# Adjust the following if necessary; EXECUTABLE is the target
# executable's filename, and LIBS is a list of libraries to link in
# (e.g. alleg, stdcx, iostr, etc). You can override these on make's
# command line of course, if you prefer to do it that way.
#
# 如果需要,调整下面的东西。 EXECUTABLE 是目标的可执行文件名, LIBS
# 是一个需要连接的程序包列表(例如 alleg, stdcx, iostr 等等)。当然你
# 可以在 make 的命令行覆盖它们,你愿意就沒问题。
#
EXECUTABLE := mushroom.exe
LIBS := alleg
# Now alter any implicit rules' variables if you like, e.g.:
#
# 现在來改变任何你想改动的隐含规则中的变量,例如
CFLAGS := -g -Wall -O3 -m486
CXXFLAGS := $(CFLAGS)
# The next bit checks to see whether rm is in your djgpp bin
# directory; if not it uses del instead, but this can cause (harmless)
# `File not found' error messages. If you are not using DOS at all,
# set the variable to something which will unquestioningly remove
# files.
#
# 下面先检查你的 djgpp 命令目录下有沒有 rm 命令,如果沒有,我们使用
# del 命令來代替,但有可能给我们 'File not found' 这个错误信息,这沒什么大碍 。如果你不是用 DOS ,把它设定成一个删除文件而不废话的命令。
# (其实这一步在 UNIX 类的系统上是多余的,只是方便 DOS 用户。 UNIX
# 用户可以删除这5行命令。)
ifneq ($(wildcard $(DJDIR)/bin/rm.exe),)
RM-F := rm -f
else
RM-F := del
endif
# You shouldn't need to change anything below this point.
#
# 从这里开始, 你应该不需要改动任何东西。(我是不太相信,太 NB 了!)
SOURCE := $(wildcard *.c) $(wildcard *.cc)
OBJS := $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(SOURCE)))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.c,$(MISSING_DEPS)) \
$(patsubst %.d,%.cc,$(MISSING_DEPS)))
CPPFLAGS += -MD
.PHONY : everything deps objs clean veryclean rebuild
everything : $(EXECUTABLE)
deps : $(DEPS)
objs : $(OBJS)
clean :
@$(RM-F) *.o
@$(RM-F) *.d
veryclean: clean
@$(RM-F) $(EXECUTABLE)
rebuild: veryclean everything
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
@$(RM-F) $(patsubst %.d,%.o,$@)
endif
-include $(DEPS)
$(EXECUTABLE) : $(OBJS)
gcc -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))
###