#1、wildcard : 扩展通配符
#2、notdir : 去除路径
#3、patsubst :替换通配符
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
$? 表示比目标还要新的依赖文件列表
* :: 表示任意一个或多个字符
? :: 表示任意一个字符
[...] :: ex. [abcd] 表示a,b,c,d中任意一个字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一个数字
~ :: 表示用户的home目录
如一个目录下有如下文件:
按照 Makefile 规则规规矩矩的写:
在MakeFile中定义变量有两种方式,一种是递归展开式,一种是简单扩展方式。
首先拿简单扩展方式举例子。
MakeFile的格式为:
target:dependency_files
command
target是目标体,dependency_files是依赖的文件,command是运行的命令。
实例如下:
makefile:
helloworld : main.o print.o #helloword 就是我们要生成的目标
# main.o print.o是生成此目标的先决条件
gcc -o helloworld main.o print.o #shell命令,最前面的一定是一个tab键
mian.o : mian.c print.h
gcc -c main.c
print.o : print.c print.h
gcc -c print.c
clean :
rm helloworld main.o print.o
OK,一个简单的makefile制作完毕,现成我们输入 make,自动调用Gcc编译了,
输入 make clean就会删除 hellowworld mian.o print.o
简化一点
再看一下,为没一个*.o文件都写一句gcc -c main.c是不是显得多余了,
能不能把它干掉?而且 main.c 和print.c都需要print.h,为每一个都写上是
不是多余了,能不能再改进?
能,当然能了:
makefile:
objects = main.o print.o #应该叫变量的声明更合适,作用相当于C语言的宏
helloworld : $(objects)//声明了变量以后使用就要$()了
gcc -o helloworld$(objects)
$(objects) : print.h # 都依赖print.h
mian.o : mian.c #干掉了gcc -c main.c 让Gun make自动推导了。
print.o : print.c
clean :
rm helloworld $(objects)
除此之外,复杂的MakeFile涉及到不同目录下的文件进行编译,这时,也可以通过定义“宏”,来进行。
编译当前位置下所有的文件的实例:
如图代码如下:
CC=gcc
INCLUDEDIR= -I. -I ./include
TARGET=main
EXTFLAGS=
LIBDIR=
CFLAGS= -lpthread
CSRC = $(wildcard *.c */*.c)
COBJ = $(patsubst %c,%o,$(CSRC))
$(TARGET):$(COBJ)
$(CC) $(COBJ) $(INCLUDEDIR) $(LIBDIR) $(CFLAGS) -o $(TARGET)
$(COBJ) : %o : %c
$(CC) $(INCLUDEDIR) $(EXTFLAGS) -c $< -o $@
.PHONY : clean
clean :
rm -rf $(TARGET) $(COBJ)
枪弹柜的Makefile实例:
代码如下:
# Makefile for zlib
# Copyright (C) 2012-2013 dessmann zyx.
# To install the dm_smarthome to /home/share/
# make install
WORK_DIR = /home/zqs/workdir
TARGET = dm_smarthome
MINIGUI_DIR = $(WORK_DIR)/minigui/share
MNT_DIR =/home/zqs/workdir/nfsroot
#MNT_DIR1 =/usr/CX92755/storage/
COM_PATH =$(WORK_DIR)/crosstool-ng/toolchain/gcc4.4.3-glibc2.9/arm-cortex_a8-linux-gnueabi
CC=$(COM_PATH)/bin/arm-cortex_a8-linux-gnueabi-gcc-4.4.3
CXX=$(COM_PATH)/bin/arm-cortex_a8-linux-gnueabi-g++
CPP=$(COM_PATH)/bin/arm-cortex_a8-linux-gnueabi-cpp
AR=$(COM_PATH)/bin/arm-cortex_a8-linux-gnueabi-ar
AS=$(COM_PATH)/bin/arm-cortex_a8-linux-gnueabi-as
LD=$(COM_PATH)/bin/arm-cortex_a8-linux-gnueabi-ld
RANLIB=$(COM_PATH)/bin/arm-cortex_a8-linux-gnueabi-ld
CFLAGS=-lpthread -lminigui_ths -lz -lpng12 -lasound -lmad -lid3tag -lts -lcurl -lexslt -lfreetype -ljpeg -lmdolphin -lsqlite3 -lcairo -lpixman-1 -lfontconfig\
-lmgncs -lmgplus -lxslt -lxml2 -lmgutils -lcares -lstdc++ -std=c99 \
$(WORK_DIR)/libs/dcapps-0.0.1/libcmem.a \
$(WORK_DIR)/libs/dcapps-0.0.1/libcxon2venc.a \
$(WORK_DIR)/libs/dcapps-0.0.1/cxon2dec-6.0.0.a \
$(WORK_DIR)/libs/dcapps-0.0.1/lib_dc_gfx.a \
$(WORK_DIR)/libs/dcapps-0.0.1/libdcapi.a
EXTFLAGS = -g -D DEBUG
INCLUDEDIR=-I$(COM_PATH)/arm-cortex_a8-linux-gnueabi/sysroot/usr/include -I$(MINIGUI_DIR)/minigui/include \
-I$(MINIGUI_DIR)/mdolphin \
-I$(WORK_DIR)/inc/dcapps-0.0.1 -I$(WORK_DIR)/inc/staging_usr_inc -I./include -I./include/recorder -I ./include/common -I ./include/cabinetmisc
LIBDIR=-L $(COM_PATH)/lib -L./lib -L$(WORK_DIR)/libs/staging_usr_lib -L$(MINIGUI_DIR)/minigui/lib
CSRC = $(wildcard *.c */*.c */*/*.c */*/*/*.c */*/*/*/*.c */*/*/*/*/*.c)
COBJ = $(patsubst %c,%o,$(CSRC))
CPP_SRC = $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp */*/*/*/*.cpp */*/*/*/*/*.cpp)
CPP_OBJ = $(patsubst %cpp,%o,$(CPP_SRC))
$(TARGET):$(COBJ) $(CPP_OBJ)
$(CC) $(COBJ) $(CPP_OBJ) $(LIBDIR) $(CFLAGS) -o $(TARGET)
cp $(TARGET) $(MNT_DIR)
# cp $(TARGET) $(MNT_DIR1)
$(CPP_OBJ):%.o:%.cpp
$(CC) $(INCLUDEDIR) -c $< -o $@
$(COBJ) : %o : %c
$(CC) $(EXTFLAGS) $(INCLUDEDIR) -c $< -o $@
clean :
rm -rf $(TARGET) $(COBJ) $(CPP_OBJ)