嵌入式Linux系统编程学习之六make工程管理和Makefile
文章目录
- 前言
- 一、Makefile中特殊处理与伪目标
- 二、变量、规则与函数
- 1.变量
- 2.规则
- 3.函数
- 总结
前言
工程管理器指管理较多的文件,它是自动管理器,能根据文件时间自动发现更新过的文件而减少编译的工作量,同时通过读入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.ogcc -shared -o $@ $^
$(DIR)main.o:main.cgcc -o $@ -c $^
$(DIR)func.o:func.cgcc $(CFLAGS) -c $^ -o $@
.PHONY:rebuild clean
rebuild:clean $(DIR)$(EXE)
clean:rm -rf $(DIR)*.o $(DIR)*.exe $(DIR)*.so
注意:当OBJS里面有多项的时候,此时$(DIR)$(OBJS)只能影响到OBJS中的第一个,后面的全部无效,因此需要全部列出。
3.函数
- wildcard搜索当前目录下的文件名,展开成一列所有符合由其参数描述的文件名,文件间以空格间隔。SOURCES=$(wildcard *.cpp) 把当前目录下所有的’.cpp’文件存入变量SOURCES里。
- 字符串替换函数:$(patsubst 要查找的子串,替换后的目标子串,源字符串)。将源字符串(以空格分隔)中的所有要查找的子串替换成目标子串,如:
OBJS=$(patsubst %.cpp, %.o, $(SOURCES))
#把SOURCES中的'.cpp'替换为'.o',然后吧替换后的字符串存入变量OBJS
- $(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在执行过程中改变目录,则打印当前目录名 |
嵌入式Linux系统编程学习之六make工程管理和Makefile相关推荐
- 嵌入式Linux系统编程学习之二常用命令
嵌入式Linux系统编程学习之二常用命令 文章目录 嵌入式Linux系统编程学习之二常用命令 前言 一.常用命令 1.su(用户切换) 2.useradd(添加用户) 3.passwd(修改密码) 4 ...
- 嵌入式Linux系统编程学习之一目录结构
嵌入式Linux系统编程学习之一目录结构 文章目录 嵌入式Linux系统编程学习之一目录结构 前言 一.Linux目录结构 前言 Linux目录结构 一.Linux目录结构 /bin:存放Linux的 ...
- 嵌入式Linux系统编程学习之九基于文件描述符的文件操作
文章目录 前言 一.文件描述符 二.打开.创建和关闭文件 三.读写文件 四.改变文件大小 五.文件定位 六.原子操作 七.进一步理解文件描述符 八.文件描述符的复制 九.文件的锁定 十.获取文件信息 ...
- 嵌入式Linux系统编程学习之八基于文件指针的文件操作
文章目录 前言 一.文件的创建.打开与关闭 二.读写文件 三.文件定位 四.标准输入/输出流 五.目录操作 前言 对文件进行操作有打开文件.关闭文件.读写文件. 文件指针:每打开一个文件,就返 ...
- 嵌入式Linux系统编程学习之三vi编辑器
文章目录 前言 一.插入文本 二.删除与修改 三.光标的移动 四.查找与替换 五.块操作 六.结束编辑 前言 在Linux下编程,使用编辑器vi(vim).gedit或Emacs,编译链接器gcc,调 ...
- 嵌入式Linux系统编程学习之三十三网络相关概念
文章目录 一.网络相关名词的概念 1.套接口 2.端口号 3.IP 地址 二.Socket 概念 三.Socket 类型 四.Socket 的信息数据结构 五.数据存储优先顺序的转换 六.地址转格式转 ...
- 嵌入式Linux系统编程学习之十二守护进程
文章目录 前言 一.守护进程的特性 二.daemon 进程的编程规则 1.创建子进程,父进程退出 2.在子进程中创建新会话 前言 daemon 运行在后台,也称作"后台服务进程" ...
- 嵌入式Linux系统编程学习之十一Linux进程的创建与控制
文章目录 一.fork函数 二.进程的终止 三.wait 和 waitpid 函数 四.exec 函数族 五.system 函数 六.popen 函数 总结 一.fork函数 fork 函数原型: # ...
- 嵌入式Linux系统编程学习之三十一线程的属性
文章目录 前言 一.线程属性初始化 二.设置绑定属性 三.设置分离属性 四.获取线程优先级 五.设置优先级 前言 pthread_create 的第 2 个参数 attr 是一个结构体指针,结构体 ...
最新文章
- java查看对象锁级别_对象级别锁 vs 类级别锁(Java)
- “python不是内部命令或外部命令,也不是可执行程序解决方案”的解决方案
- 修改FileZilla生成证书的有效期
- Spark详解(二):Spark完全分布式环境搭建
- sqlplus中上下键无效的解决办法
- 机器视觉和Tesseract
- oracle 更新flwid,Oracle分析函数RANK(),ROW_NUMBER(),LAG()等的使用方法
- socket协议和http协议性能对比
- 视频解码芯片SAA7111A的初始化
- pythoninit作用_简介Python中的__init__的作用
- 如果奇迹有颜色,那么一定是暴力or模拟比较6
- 分析华为鸿蒙操作系统的特点,申万宏源-通信行业系列深度研究和分析报告之华为鸿蒙操作系统全景解构.pdf...
- 如何通过几何画板学这些定理
- mysql windows局域网访问_window下 局域网内使用mysql,mysql 开启远程访问权限
- pythonista模板_Python——Code Like a Pythonista: Idiomatic Python
- 安装图形化界面consol/centos-xfce-vnc
- java正则完美匹配注释_匹配Email邮箱的正则表达式(完美经典)
- 图像修复必读的10篇论文
- 【转载】整车CAN网络介绍
- springBoot+thymeleaf框架实现cms内容管理和商城系统
热门文章
- pytorch学习——构建多元线性回归的网络结构
- 关闭保护火狐浏览器的保护与多余的加载项
- 回声检测仿真信号matlab,杭州oracle培训入门
- ubuntu命令 图片 壁纸_太简单了!1分钟把Win 10 高颜值的开屏锁屏壁纸存储到电脑!...
- scrapy-实现下一页请求, scrapy.Request
- 解开Future的神秘面纱之任务执行
- HTML5商城开发四 多图或多商品的水平滚动展示
- 右键菜单管理---右键管家
- jquery学习之1.12-给节点添加样式
- 30 个用于杂志网站的 WordPress 主题