嵌入式Linux系统编程学习之六make工程管理和Makefile


前言

  工程管理器指管理较多的文件,它是自动管理器,能根据文件时间自动发现更新过的文件而减少编译的工作量,同时通过读入Makefile文件来执行大量的编译工作。
Makefile格式:

target:dependency_files		//目标项:依赖项
<TAB>command				//必须以TAB开头,command编译命令

一、Makefile中特殊处理与伪目标

  .PHONY是Makefile文件的关键字,表示它后面列表中的目标均为伪目标;伪目标通常用在清理文件、强制重新编译等情况下。
示例:

#vi Makefile						#系统默认的文件名为Makefile
main.exe:main.o func.o				#表示想要生成main.exe文件,要依赖于main.o和func.o文件
	gcc -o main.exe main.o func.o	#如果main.o和func.o已经存在,就链接成main.exe
main.o:main.c						#表示main.o文件依赖于main.c文件
	gcc -c main.c					#编译main.c,默认生成main.o。可写为:gcc -c main.c -o mian.o
func.o:func.c						#表示func.o文件依赖于func.c文件
	gcc -c func.c					#如果func.c存在,则编译func.c,生成func.o
.PHONY:rebuild clean				#表示后面的是伪目标,通常用在清理文件、强制重新编译等情况下
rebuild:clean main.exe				#先执行清理,在执行main.exe
clean:
rm -rf main.o func.o main.exe		#最后删除.o和.exe的文件

在执行以下命令:

#make			//直接make,即从默认文件名(Makefile)的第一行开始执行
#make clean		//表示执行clean:开始的命令段
#make func.o	//表示执行func.o:开始的命令段
#make rebuild	//先执行清除,再重新编译链接

  若不用系统默认的文件名Makefile,而是用户随便起的一个名字,如:#vi Makefile11;则make后必须加上-f Makefile11。

二、变量、规则与函数

  通过make支持的变量定义、规则和内置函数,可以写出通用性较强的Makefile文件,使得同一个Makefile文件能够适应不同的项目。

1.变量

  变量用来代替一个文本字符串;
  定义变量的两种方法:

  • 变量名 = 变量值 递归变量展开(几个变量共享一个值) //不常用
  • 变量名: = 变量值 简单变量展开(类似于C++的赋值) //通常采用

  使用变量的一般方法:

  • $(变量名) = ??? 赋值
  • ??? = $(变量名) 引用

  变量分为用户自定义变量、预定义变量、自动变量、环境变量。
  自动变量是指在使用的时候,自动用特定的值替换。
  常用的变量:

变量说明
$@当前规则的目标文件
$<当前规则的第一个依赖文件
$^当前规则的所有依赖文件,以逗号分隔
$?规则中日期新于目标文件的所有相关文件列表,逗号分隔
$(@ D)目标文件的目录名部分
$(@ F)目标文件的文件名部分

  预定义变量:内部事先定义好的变量,值是固定的,且有些值为空。
  AR:库文件打包程序,默认为ar
  AS:汇编程序,默认为as
  CC:c编译器,默认为cc
  CPP:c预编译器,默认为$(CC) -E
  CXX:c++编译器,默认为g++
  RM:删除,默认为rm -f
  ARFLAGS:库选项,无默认
  ASFLAGS:汇编选项,无默认
  CFLAGS:c编译器选项,无默认
  CPPFLAGS:c预编译器选项,无默认
  CXXFLAGS:c++编译器选项

2.规则

  规则分为普通规则、隐含规则和模式规则。
  隐含规则:// *.o文件自动依赖*.c或*.cc文件,所以可以省略main.o:main.cpp等。
  模式规则:通过匹配模式找字符串,%匹配1或多个任意字符串。
  另外,还可以指定将"*.o"、"*.exe"、"*.a"、"*.so"等编译到指定目录中。
例:

DIR:=./Debug/
EXE:=main.exe
OBJS:=main.o
LIBFUNCSO:=libfunc.so
CFLAGS:=-fpic

$(DIR)$(EXE):$(DIR)$(OBJS) $(DIR)$(LIBFUNCSO)
	gcc -o $@ $< -L./ -lfunc
$(DIR)$(LIBFUNCSO):$(DIR)func.o
	gcc -shared -o $@ $^
$(DIR)main.o:main.c
	gcc -o $@ -c $^
$(DIR)func.o:func.c
	gcc $(CFLAGS) -c $^ -o $@
.PHONY:rebuild clean
rebuild:clean $(DIR)$(EXE)
clean:
	rm -rf $(DIR)*.o $(DIR)*.exe $(DIR)*.so 

注意:当OBJS里面有多项的时候,此时$(DIR)$(OBJS)只能影响到OBJS中的第一个,后面的全部无效,因此需要全部列出。

3.函数

  1. wildcard搜索当前目录下的文件名,展开成一列所有符合由其参数描述的文件名,文件间以空格间隔。SOURCES=$(wildcard *.cpp) 把当前目录下所有的’.cpp’文件存入变量SOURCES里。
  2. 字符串替换函数:$(patsubst 要查找的子串,替换后的目标子串,源字符串)。将源字符串(以空格分隔)中的所有要查找的子串替换成目标子串,如:
OBJS=$(patsubst %.cpp, %.o, $(SOURCES))
#把SOURCES中的'.cpp'替换为'.o',然后吧替换后的字符串存入变量OBJS
  1. $(addprefix 前缀, 源字符串) 函数把第二个参数列表的每一项前加上第一个参数值。
    一个较为通用的Makefile:
DIR:=./debug
EXE:=$(DIR)/Main.exe
CC:=g++
LIBS:=
SRCS:=$(wildcard *.cpp) $(wildcard *.c) $(wildcard *.cc)
OCPP:=$(patsubst %.cpp, $(DIR)/%.o, $(wildcard *.cpp))
OC:=$(patsubst %.c, $(DIR)/%.co, $(wildcard *.c))
OCC:=$(patsubst %.cc, $(DIR)/%.cco, $(wildcrd *.cc))
OBJS:=$(OC) $(OCC) $(OCPP)
RM:=rm -rf
CXXFLAGS:= -Wall -g
start:mkdebug $(EXE)
mkdebug:
@ if[! -d $(DIR)]; then mkidir $(DIR); fi;
$(EXE):$(OBJS)
$(CC) -o $@ $(OBJS) $(addprefix -l, $(LIBS))
$(DIR)/%.o:%.cpp
$(CC) -c $(CXXFLAGS) $< -o $@
$(DIR)/%.co:%.c
$(CC) -c $(CXXFLAGS) $< -o $@
$(DIR)/%.cco:%.cc
$(CC) -c $(CXXFLAGS) $< -o $@
.PHONY:clean rebuild
clean:
@ $(RM) $(DIR)/ *.exe $(DIR)/ *.o $(DIR)/ *.co $(DIR)/ *.cco
rebuild:clean start

总结

make的命令行选项:

命令格式含义
-C dir读入指定目录下的Makefile
-f dir读入当前目录下的file文件作为Makefile
-i忽略所有命令执行错误
-I dir指定被包含的Makefile所在目录
-n只打印要执行的命令,但不执行这些命令
-p显示make变量数据库和隐含规则
-s在执行命令时不显示命令
-w如果make在执行过程中改变目录,则打印当前目录名
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值