Makefile文件,本来一个工程就只需要写一次,所以表示也没有经常的去特别注重语法;
就记录一下我最常用的Makefile文件模板,以后直接套用就好,并加以完善;
CC := arm-none-linux-gnueabi-g++
INC_DIR = -I./include -I./include/freetype2 -I./include/libpng -DTEST_DATA=1
SRC_DIR = ./src
OBJ_DIR = ./object
BIN_DIR = ./
SRC = $(wildcard ${SRC_DIR}/*.cpp)
OBJ = $(patsubst %.cpp,${OBJ_DIR}/%.o,$(notdir ${SRC}))
LIB_DIR = ./lib /usr/local/lib ./includefile/ ./includefile/student ./includefile/student/name
XLINKER = -Xlinker "-(" -ljson_arm -lpng16 \
-lfreetype -Xlinker "-)" -lpthread -lrt
EXE = helloworld.out
BIN_TARGET = ${BIN_DIR}/${EXE}
CFLAGS = -Wall -c -fPIC -O2 ${INC_DIR}
${BIN_TARGET}:${OBJ}
$(CC) -o $@ $(OBJ) ${addprefix -L,${LIB_DIR}} ${XLINKER}
@echo
@echo 编译完成
@echo
${OBJ_DIR}/%.o:${SRC_DIR}/%.cpp
@echo 编译文件 $<
$(CC) ${CFLAGS} $< -o $@
.PHONY:clean
clean:
find ${OBJ_DIR} -name *.o -exec rm -rf {} \;
rm ${BIN_TARGET}
各定义的变量:
1 CC 指定编译器为 arm-none-linux-gnueabi-g++
2 INC_DIR 指定我头文件搜索的路径
3 SRC_DIR 我的cpp源码
4 OBJ_DIR 存放编译后生成的对象文件(.o文件)到该目录
5 BIN_DIR 生成的执行文件
6 LIB_DIR 静态库存放的路径
7 定义一个宏定义变量 TEST_DATA=1
用到的语法:
1 -Xlinker 编译时忽略库的次序重复查找依赖库
2 添加线程库-lpthread 和 -实时库 lrt
3 -Wall 允许输出警告信息
4 -fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code)
5 -O2 代码优化选项 -O2 提供更加高级的代码优化,会占用更长的编译时间( 分别有0,1,2,3四个等级)
6 addprefix -I 给文件增加前缀,例程中就是为了给${LIB_DIR}增加前缀为lib库文件;
7 \$< 第一个依赖文件
8 \$@ 所有依赖关系中的文件
9 PHONY 伪命令,当目录下有clean文件夹中,伪目标仍然正常工作;
10 *.o 通配所有的.o文件
编译时输出当前正在编译那些文件,如果文件更新时间戳跟着更新;
这时候希望能够看到当前是否正确的读取到时间戳并对更新过的源文件进行重新编译:
{OBJ_DIR}/%.o:${SRC_DIR}/%.cpp
@echo 正在编译 $<
这里就是在编译时加入echo输出当前正在编译的文件:
编译时就会输出
$ make -s
正在编译 src/Main.cpp
正在编译 src/Test.cpp
正在编译 src/Read.cpp
这里编译时可以不加入-s,-s就是slient的意思,也是很形象的嘛!就是为了不要echo出完整的编译语句;
为了完整地清晰地看到正在编译CPP文件,就不应该输出warning信息,所以暂时屏蔽warning干扰;
当然在平时编译项目时请打开警告输出开关,培养顺手改掉warning的好习惯;
# 不加入-Wall,则是不允许输出警告信息
#CFLAGS = -Wall -c -fPIC -O2 ${addprefix -I,${INC_DIR}}
CFLAGS = -c -fPIC -O2 ${addprefix -I,${INC_DIR}}
关于编译阶段使用宏定义:
#定义宏变量 TEST_DATA=1
INC_DIR = -I./include -I./include/freetype2 -I./include/libpng -DTEST_DATA=1
为了解决一般性中小型项目,约如此Makefile;
关于基础版的Makefile如下:
edit : main.o kbd.o command.o\
display.o /
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o /
insert.o search.o files.o utils.o
这简单例程来自网络。
其中 $make edit 时,则是编译cc -o edit main.o kbd.o command.o…
依赖关系已经写在edit:的同一行中
编译edit时会自动检查依赖文件是否为最新编译出来的文件
否则就是调用影响的执行脚本进行编译出.o文件。
可以看出下面的.o文件作为目标也有对应的依赖c/cpp文件,所以就会
先编译c/cpp文件为.o文件再编译执行文件edit;