查看的文档:
https://blog.csdn.net/weixin_38391755/article/details/80380786
基础知识:
arm-linux工具:GCC是一套交叉编译工具链,支持分布编译,反汇编,可用于,输出预处理后的C++源程序,生成二进制目标文件,生成静态库,生成可执行程序,转换文件格式,
gcc:编译的前端程序,用于间源文件变异成目标文件,as汇编器(将汇编语言转换为ELF),ld连接器(链接定位文件中的代码区,数据区,BSS区,栈区,可重新定位目标模块链接成一个单一的,绝对定位的目标程序),ar库管理器,可将多个重定位目标模块归档为一个函数库文件,工程管理器MAKE,objcopy目标文件格式转换工具。
编译:将源文件.c生成.o文件,编译时检查语法是否争取 ,函数变量是否正确,告诉编译器头文件所在的位置每一个源文件对应一个中间目标文件,
链接:把大量的.o文件合成所执行的文件。链接函数和全局变量,由于编译生成的目标文件太多了,在链接时需要指出中间文件名,我们给中间文件设置个库文件,linux下面就是.a文件
make的工作过程,make会在当前目录下面找到makefile文件,找到第一个目标文件,如果目标不存在或者依赖的.o文件修改文件比目标新,那么它会指令命令生成目标文件,如果目标文件所依赖的.o文件存在,那么make会在当前文件中找到目标为.o文件的依赖性,如果找不到根据规则规则生成.o文件
一:makefile的规则
target ... : prerequisites ...
command
target 是一个伪目标文件,可以是object文件,也可以是执行文件,
prerequisites 生成目标所需的文件
command所执行的命令
prerequisites 中有文件比target要新时,command命令将被执行。
eg:
GFX_DIR := $(PWD)/uvc
GFX_SRC := $(wildcard $(GFX_DIR)/*.c)
MVS_SRC += $(GFX_SRC)
MVS_OBJ := $(MVS_SRC:%.c=%.o)
all: $(TARGET)
MPI_LIBS := $(REL_LIB)/libmpi.a
MPI_LIBS += $(REL_LIB)/libhdmi.a
$(TARGET):%:%.o $(COMM_OBJ) $(MVS_OBJ)
$(CC) $(CFLAGS) -lpthread -lm -o $@ $^ $(MPI_LIBS) $(AUDIO_LIBA) $(JPEGD_LIBA)
注意:前面加tab空格键
依赖关系说明目标文件由那些库文件生成。目标文件依赖于冒号后面的.o文件,每个.o文件依赖后面的.c和.h文件。
$^代表所有的可以依赖的文件
$@代表所有的目标文件
$<代表第一个依赖文件
链接依赖文件的是中间目标文件.o,这样我们会少些一个依赖关系,得到的.o文件不完整,从而导致变异失败,为了makefile的易维护我们使用常亮:MVS_OBJ ,定义的常亮表示所有的.o文件
二:makefile的通配符
一个大型的makefile总是以通配符来配置环境变量,并且,通配符就是一个定义的默认的公式。
1:wildcard用法:$(wildcard PATT)在makefile中,他被认为已近是存在的,使用空格分开的,匹配此模式的所有文件列表
$(wildcard *.c)来获取工程目录下的所有.c文件列表,objects := $(patsubst %.c,%.o,$(wildcard *.c))
此模式采用wildcard 获得工作目录下的.c文件,之后将列表中的所有目录下的.c替换为.o文件,这样我们就可以得到当前目录下生成的.o文件列表
用法一:GFX_DIR := $(PWD)/uvc
GFX_SRC := $(wildcard $(GFX_DIR)/*.c)
用法二:
objects := $(patsubst %.c,%.o,$(wildcard *.c))
foo : $(objects)
cc -o foo $(objects)
2:notdir:作用:把展开的文件去除掉路径信息。(将路径下的文件都去除掉)。
3:patsubst 替换通配符
简单历程
src=$(wildcard *.c ./sub/*.c)
dir=$(notdir $(src))
obj=$(patsubst %.c,%.o,$(dir) )
all:
@echo $(src)
@echo $(dir)
@echo $(obj)
最后将所有目录下的.c文件输出为.o文件,而不管路径信息。
4:替换规则使用:使用obj=$(dir:%.c=%.o)具有同样的效果。
MVS_OBJ := $(MVS_SRC:%.c=%.o)将目录下的以及子目录下的所有.c文件转换为.o文件
这里采用的是makefile里的替换引用规则,用你指定的变量替换为另一个变量。标准格式
$(var:a=b)或者${var:a=b}它的含义就是把变量var中的值结尾有b替换为a。
5:makefile的赋值
=:基本的赋值, :=覆盖之前的值 ?=如果没有被赋值就赋值等号后面的值 +=添加等号后面的值
6:命令选项列表
-c将输入如的源文件变异成目标文件, -s将c文件编译成汇编文件 -o file 将输出内容存于文件file中 -pipe 在编译的不同阶段采用管道通讯方式 -v 打印出编译过程中执行的命令 -s 说明文件输入类型 -ansi 支持所有的ANSI的C程序 -W关闭所有警告 -g文件中产生调试信息 -O0不优化(优化选项等级) -E 运行C的预处理器 -Wa option 将选项option传递给汇编器 -I 针对有效的头文件搜索路径
三:Makefile的一些基本参数:
LOCAL_CFLAGS+ =-DXXX,相当于源文件加一个宏定义 #define XXX
./sh中$@脚本中的所有参数,$#脚本中的参数的个数
eg:for arg in “$@” do done
/bin/bash 告诉系统其后路径所指的程序即是解释此脚本的shell程序。 后面跟参数,
makefile的环境设置:CFLAGS 指定头文件(.h的路劲)eg;CFLAGS =-I/usr/include,同样的安装一个包时,会在安装路劲下建立一个include目录,把安装包的iclude目录加入到该变量中。CXXFLAGS用于编译器的选项
LDFLAGS:gcc编译器会用到的一些优化参数,可以指定库文件的位置,用法:LDFLAGS=-L/usr/lib每一个安装包会在安装目录下建立一个lib目录,需要将包中的lib加入到LDFALGS中,
LIBS:告诉连接器需要连接那些库文件。