Makefile

wildcard 


1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符


例子:
建立一个测试目录,在测试目录下建立一个名为sub的子目录
$ mkdir test
$ cd test
$ mkdir sub


在test下,建立a.c和b.c2个文件,在sub目录下,建立sa.c和sb.c2 个文件


建立一个简单的Makefile
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )


all:
@echo $(src)
@echo $(dir)
@echo $(obj)
@echo "end"


执行结果分析:
第一行输出:
a.c b.c ./sub/sa.c ./sub/sb.c


wildcard把 指定目录 ./ 和 ./sub/ 下的所有后缀是c的文件全部展开。


第二行输出:
a.c b.c sa.c sb.c
notdir把展开的文件去除掉路径信息


第三行输出:
a.o b.o sa.o sb.o


在$(patsubst %.c,%.o,$(dir) )中,patsubst把$(dir)中的变量符合后缀是.c的全部替换成.o,
任何输出。
或者可以使用
obj=$(dir:%.c=%.o)
效果也是一样的。


这里用到makefile里的替换引用规则,即用您指定的变量替换另一个变量。
它的标准格式是
$(var:a=b) 或 ${var:a=b}
它的含义是把变量var中的每一个值结尾用b替换掉a


今天在研究makefile时在网上看到一篇文章,介绍了使用函数wildcard得到指定目录下所有的C语言源程序文件名的方法,这下好了,不用手工一个一个指定需要编译的.c文件了,方法如下:


SRC = $(wildcard *.c)


等于指定编译当前目录下所有.c文件,如果还有子目录,比如子目录为inc,则再增加一个wildcard函数,象这样:


SRC = $(wildcard *.c) $(wildcard inc/*.c)


也可以指定汇编源程序:
ASRC = $(wildcard *.S)


这样一来,makefile模板可修改的基本就是AVR名称和时钟频率了,其它的一般不用动



SUFFIXES

.SUFFIXES:
.SUFFIXES:  .g  .o                                  ----------->关心的文件的后缀类型

.g.o:                                        ---------> 凡是.g结尾的文件,均编译成对应名字的.o的目标文件,相当于 xx.o: xx.g

gcc -c $^ 

这个规则表示所有的 .o文件都是依赖与相应的.c文件的


Makefile示例:

CFILES 	= $(wildcard *.c)
#$(CFILES:*.c=*.o)(有星号)  和 $(CFILES: .c=.o)(有空格)  均错误
OBJS    = $(CFILES:.c=.o)

PICFLAG	:= $(shell if [ `uname -o` != 'Cygwin' ]; then echo '-fPIC'; fi)

INCS	= $(PICFLAG) -I<path1> -I<path2> ...
#INCS = $(PICFLAG) -I/you/libhome -I../me

LIBS	= -L<mypath1> -l<libname1> -L<mypath2> -l<libname2> ...
#LIBS	= -L/you/libhome -ldoit -L../me -ljust    doit maybe libdoit.a or libdoit.so

CFLAGS	= $(FLAG) -Wall -Werror $(INCS)
MYNAME	= xxname
SUFFIX	:= $(shell if [ `uname -o` == 'Cygwin' ]; then echo dll; else echo so; fi)
TARGET	= $(MYNAME).$(SUFFIX)

CC		= gcc
 
.PHONY: all clean cleanall dll dynamic static debug

$(TARGET): $(OBJS)
	$(CC) -shared $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)

debug:
	$(CC) -g -Wall -shared $(INCS) -o $(TARGET) $(SRCFILES) $(LIBS)
	
static: $(OBJS)
	ar cr $(MNAME).a $(OBJS)

clean:
	rm -rf *.o  $(TARGET) $(MYNAME).a $(MYNAME).so $(MYNAME).dll *.output *.stackdump


.PHONY目标并非实际的文件名,只是在显式请求时执行命令的名字,后面接的命令总会执行

举例说明:


.PHONY all aa bb

all: aa bb

<command>

.PHONY all aa bb 表明all是伪目标,aa、bb也均为显式伪目标, 当下面没有对aa、bb做定义时,那么all: aa bb冒号后的aa bb无任何操作(不会将其当文件检测),

就继续执行<command>


.PHONY all

all: aa bb

<command>

.PHONY all表明all是伪目标,aa、bb不是显式伪目标,aa: aa bb 会优先把aa bb当做一个目标查看:检查makefile内有无aa和bb做目标的规则,有则执行找到的规则,没有则将aa和bb当做文件查看


############################################################################# # Makefile for building: sample 2011-09-26 # # Project: # Template: # Command: # ------基本上简单用法的makefile------- #1. 第一个目标为最终目标 #2. 命令以 Tab开头,可以有多个命令 #3. 分行号\ 后面不可以跟空格 #4、加@可以去掉命令显示 #5. 变量为 abc = efd 访问为 $(abc) echo $abc # # # #缺点,单文件夹 #每次都会重新生成 # #foo.o : foo.c defs.h # foo模块 #cc -c -g foo.c # #多目录 一种方法,在主目录里面include "",然后其里面OBJS += .o,这样其实就是 或用foreach ############################################################################# #target EXECUTABLE := test CC := gcc CXX := g++ STRIP := strip AR := ar cqs LINK := g++ RM := rm -f CFLAGS := -g -Wall CXXFLAGS := $(CFLAGS) CXXFLAGS += -MD LIBS := -lm LIBPATH := -L/usr/local/lib INCPATH := ####### Output directory OBJSPATH := ../Obj/ EXECUTABLEPATH := ../Execute/ #######source Files SOURCE := $(wildcard *.c) $(wildcard *.cpp) OBJS := $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(SOURCE))) DEPS := $(patsubst %.o,%.d,$(OBJS)) #######rule .SUFFIXES: .cpp .c .o .so .a .d $(OBJSPATH)%.o:%.c $(CC) $(CFLAGS) -c $< -o $@ $(OBJSPATH)%.o:%.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ $(OBJSPATH)%.d:%.cpp $(CXX) -MM $ $@ ######main .PHONY : all deps objs clean rebuild all: $(EXECUTABLE) $(CXX) $(CXXFLAGS) $(INCLUDEPATH) $(LIBS) $(LIBPATH) $(addprefix $(OBJSPATH),$(OBJS)) \ -o $(EXECUTABLEPATH)$(EXECUTABLE) deps: $(addprefix $(OBJSPATH),$(DEPS)) objs: $(addprefix $(OBJSPATH),$(OBJS)) clean: @$(RM) $(OBJSPATH)*.o @$(RM) $(OBJSPATH)*.d @$(RM) $(EXECUTABLEPATH)$(EXECUTABLE) rebuild: clean all -include $(addprefix $(OBJSPATH),$(DEPS)) ##.d里面是详细的.o rule 自己会括展开的,然后没有文件就自己去重建 $(EXECUTABLE) : objs
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值