makefile使用说明

基本格式

targets:
[tab键]command
target:目标文件
command:是 make 需要执行的命令,

基本规则

  • make 会在当前目录下找到一个名字叫 Makefile 或 makefile 的文件
  • 如果找到,它会找文件中第一个目标文件(target),并把这个文件作为最终的目标文件
  • 如果 target 文件不存在,或是 target 文件依赖的 .o 文件(prerequities)的文件修改时间要比 target 这个文件新,就会执行后面所定义的命令 command 来生成 target 这个文件

变量

变量定义

cpp := src/main.cpp 
obj := objs/main.o

变量引用

cpp := src/main.cpp 
obj := objs/main.o

$(obj) : ${cpp}
	@g++ -c $(cpp) -o $(obj)

compile : $(obj)

预定义变量

cpp := src/main.cpp 
obj := objs/main.o

$(obj) : ${cpp}
	@g++ -c $< -o $@
	@echo $^

compile : $(obj)
.PHONY : compile

makefile常用符号

= 赋值符
:= 立即赋值运算符 定义后不更改
?= 默认赋值运算符 已经定义则不进行任何操作
+= 累加
\ 续航符
* 匹配任意字符串
% 匹配任意字符串并作为变量使用

makefile常用函数

$(fn, arguments) or ${fn, arguments}
  • fn: 函数名
  • arguments: 函数参数,参数间以逗号 , 分隔,而函数名和参数之间以“空格”分隔
$(shell <command> <arguments>)
名称:shell 命令函数 —— shell
功能:调用 shell 命令 command
返回:函数返回 shell 命令 command 的执行结果

示例
# shell 指令, 获取计算机架构
HOST_ARCH := $(shell uname -m)
$(subst <from>,<to>,<text>)
名称:字符串替换函数——subst
功能:把字串 <text> 中的 <from> 字符串替换成 <to>
返回:函数返回被替换过后的字符串

示例
cpp_srcs := $(shell find src -name "*.cpp")
cpp_objs := $(subst src/,objs/,$(cpp_objs)) 
$(patsubst <pattern>,<replacement>,<text>)
名称:模式字符串替换函数 —— patsubst
功能:通配符 %,表示任意长度的字串,从 text 中取出 patttern, 替换成 replacement
返回:函数返回被替换过后的字符串

示例
cpp_srcs := $(shell find src -name "*.cpp") #shell指令,src文件夹下找到.cpp文件
cpp_objs := $(patsubst %.cpp,%.o,$(cpp_srcs)) #cpp_srcs变量下cpp文件替换成 .o文件

makefile条件分支

  • ifeq/else/endif (ifneq/else/endif ifdef/else/endif相同用法 )
ifeq ($(XXX),XXX)
else ifeq ($(XXX),XXX)
else ifeq ($(XXX),XXX)
endif

compile

# 使用shell命令在src目录下查找所有的.cpp文件,并将结果赋值给cpp_srcs变量。
cpp_srcs := $(shell find src -name *.cpp)

# 将cpp_srcs中的每个.cpp文件名替换成对应的.o文件名,并将结果赋值给cpp_files变量
cpp_files := $(patsubst src/%.cpp,src/%.i,$(cpp_srcs))

# 这段代码是一个规则,意思是将src目录下的每个.cpp文件进行预处理,
# 使用g++编译器进行预处理,生成对应的.o文件。
src/%.o : src/%.cpp
	@g++ -E $^ -o $@
	
# 定义一个名为preprocess的目标,依赖于pp_files中的所有文件。
# 当执行make preprocess时,会先生成cpp_files中的所有文件,然后再执行后续的操作。
preprocess : $(cpp_files)

clean :
	@rm -f src/*.i

debug :
	@echo $(pp_files)

.PHONY : debug preprocess clean
  • 编译选项
    -m64: 指定编译为 64 位应用程序
    -std=: 指定编译标准,例如:-std=c++11、-std=c++14
    -g: 包含调试信息
    -w: 不显示警告
    -O: 优化等级,通常使用:-O3
    -I: 加在头文件路径前
    fPIC: (Position-Independent Code), 产生的没有绝对地址,全部使用相对地址,代码可以被加载到内存的任意位置,且可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的
  • 链接选项
    -l: 加在库名前面
    -L: 加在库路径前面
    -Wl,<选项>: 将逗号分隔的 <选项> 传递给链接器
    -rpath=: “运行” 的时候,去找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找

链接库

静态链接
g++ [main.o] -o [可执行文件] -l[库名] -L[库路径]

动态链接
g++ [main.o] -o [可执行文件] -l[库名] -L[库路径] -Wl,-rpath=[库路径]

makefile中的特殊字符含义

$@  表示目标文件
$^  表示所有的依赖文件
$<  表示第一个依赖文件
$?  表示比目标还要新的依赖文件列表
# 简单的makefile模板
OBJ := test

CFLAGS := -Wall -g -L../lib -lXXX

APP_SRC := ../src/main.c

INC :=  -I../include/

CC := arm-linux-gcc

$(OBJ) : $(APP_SRC)
	${CC} $(APP_SRC) -o $@ $(CFLAGS) ${INC} 

.PHONY : clean
clean:
	rm -f $(OBJ)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值