一、温故知新

1、可执行程序的生成过程

2、gcc的常用操作

gcc/g++ 命令的基本格式为
gcc -[选项] [文件名]
例如:
gcc -c -I /home/inc/ test.c -o test.o
gcc -I /home/inc/ -O2 -g3 main.c test.o -o main

二、make操作

make 的基本格式为:
make -[选项] [文件名]
例如:
make -v
make -n
make -C /home/erc/ -f Makefile02 -s

三、编写Makefile文件时常用操作

下面会着重介绍编写Makefile文件时经常用到的操作,对于makef的执行规则等更细致全面的知识可以参考Makefile教程(绝对经典,所有问题看这一篇足够了)

注意:在Makefile文件中 空格和缩进是完全不同的,不可以相互转换。

1、框架格式

目标1:依赖
命令
目标2:依赖
命令
目标3:依赖
命令

2、举例

假如说我现在有这么一个程序需要编译:

所需的 .h 头文件在 /home/inc/ 目录下
所需的 .c 源文件在 /home/src/ 目录下
#include "myadd.h"
#include "mysub.h" 主函数在当前目录下的 main.c 里

int main()

{

return 0;

}

那么Makefile文件应该这么编写

main:/home/inc/myadd.o /home/inc/mysub.o ./main.o
gcc -I /home/inc/ /home/inc/myadd.o /home/inc/mysub.o ./main.o -o main /home/inc/myadd.o:/home/src/myadd.c

gcc -c -I /home/inc/ /home/src/myadd.c -o /home/src/myadd.o /home/inc/mysub.o:/home/src/mysub.c

gcc -c -I /home/inc/ /home/src/mysub.c -o /home/src/mysub.o ./main.o:./main.c

gcc -c -I /home/inc/ ./main.c -o ./main.o clean:

rm -rf /home/inc/mysub.o /home/inc/myadd.o ./main.o main

3、优化

以下是优化后的代码

NAME=main

SRC=\((</span>wildcard ./*.c<span class="token variable">)</span></span> <span class="token variable"><span class="token variable">\)(wildcard /home/src/*.c)

OBJ=\((</span>patsubst %.c, %.o, <span class="token punctuation">\)(SRC))

INC=-I"/home/inc/"

\((</span>NAME<span class="token variable">)</span></span><span class="token builtin class-name">:</span><span class="token variable"><span class="token variable">\)(OBJ)

@ \((</span>CC<span class="token variable">)</span></span> <span class="token parameter variable">-g</span> <span class="token variable"><span class="token variable">\)(INC) \((</span>OBJ<span class="token variable">)</span></span> <span class="token parameter variable">-o</span> <span class="token variable"><span class="token variable">\)(NAME) %.o:%.c

@ \((</span>CC<span class="token variable">)</span></span> <span class="token parameter variable">-c</span> <span class="token variable"><span class="token variable">\)(INC) \(^ <span class="token parameter variable">-o</span> <span class="token variable">\)@ .PHONY:clean clean:

@ rm -f \((</span>OBJ<span class="token variable">)</span></span> <span class="token variable"><span class="token variable">\)(NAME)

1). 伪目标 .PHONY

声明目标成伪目标之后,make会无条件执行该目标,
且不会判断目标是否存在或者是否需要更新。

例如:常常把 clean声明为伪目标

	.PHONY:clean
clean:
<span class="token function">rm</span> <span class="token parameter variable">-rf</span> <span class="token variable"><span class="token variable">$(</span>OBJ<span class="token variable">)</span></span> <span class="token variable"><span class="token variable">$(</span>NAME<span class="token variable">)</span></span>

2). $ 和 @ 符号的作用

@ :运行命令时,隐藏命令
例如:@ rm -f $(OBJ) $(NAME) 会删除这些文件,但终端上不会有rm -r 输出

$ :使用变量,(定义变量的时候不需要加$)
例如 echo $(NAME)

3). 变量

注意:

不管是自定义变量或者是系统变量,使用方法都一样

使用方法即: $(变量名称)

变量的工作原理和 C语言中的 define类似,是会直接替换的,
所以一定要处理好空格。

变量种类

自定义变量:
定义: NAME=main
使用: echo $(NAME)

系统常量:
优点:与设备无关,全平台通用,使 makefile 可以跨平台。
常见系统常量:

Makefile 中常见系统变量:
(加 星号 的是使用频率较高的)

4). 匹配模式

目标前缀名和依赖前缀名相同时,可以使用匹配模式缩减代码长度
例如:
myadd.o : myadd.c 可以被替换为
%.o : %.c

$(wildcard /home/src/*.c)
获取某目录下的所有.c文件名称

$(patsubst %.c, %.o, $(SRC))
获取某些 .c 文件对应的 .o 文件

使用方法

获取当前目录下的所有 .c 文件的全名,获取 /home/src/目录下的所有 .c 文件的全名
并把文件名储存到 SRC 变量里
SRC=$(wildcard ./*.c) $(wildcard /home/src/*.c) 获取SRC变量里的 .c 文件对应的 .o 文件的全名

并把文件名储存到 OBJ 变量里

OBJ=\((</span>patsubst %.c, %.o, <span class="token punctuation">\)(SRC))

此时再回头看优化代码,OvO,原来是这样。

4、Makefile中的条件判断 ifeq ifdef

使用:

ifeq 判断两个变量是否相等
括号里是要判断的两个变量

A=aa
TMP:=
ifeq ($(A),aa)
TMP1:=aa
else
TMP1:=no-aa
endif

ifdef 判断某变量是否定义且赋值(如果没有赋值也是false)

B=
TMP2:=
ifdef (B)
TMP2:=def-B
else
TMP2:=ndef-B
endif

注意事项:

注意书写格式,ifeq 或者 ifdef 和括号之间有一个空格!!!

Makefile中不存在 elif 但可以嵌套调用 ifeq 或 ifdef 来实现elif的功能

5、Makefile中的循环 foreach

语法

命令 $(foreach v, 集合, 对v进行重命名或拼接等)

例子

TARGET=t1 t2 t3 t4

all:

mkdir \((</span>foreach v, <span class="token punctuation">\)(TARGET), $v_dir)

说明:

遍历TARGET变量,然后在每个变量名后面拼接_dir组成新的名称,

然后以新的名称创建目录

演示结果:

6、Makefile中的赋值 = 和 :=

= 是最终赋值,
:= 是临时赋值,
实际上 := 类似 C++中的变量引用,
对于 = 和 := 具体的区别,大家可以自己动手实操感受下。

总结

纸上谈来终觉浅,绝知此事要躬行!

[转帖]gcc与makefile常用操作(绝对常用,也绝对够用)的更多相关文章

  1. centos LAMP第四部分mysql操作 忘记root密码 skip-innodb 配置慢查询日志 mysql常用操作 mysql常用操作 mysql备份与恢复 第二十二节课

    centos  LAMP第四部分mysql操作  忘记root密码  skip-innodb 配置慢查询日志 mysql常用操作  mysql常用操作 mysql备份与恢复   第二十二节课 mysq ...

  2. JavaScript常用操作,常用类

    算术运算符 重点关注 算数,赋值,逻辑运算符,三目运算符 <!DOCTYPE html> <html> <head> <meta charset=" ...

  3. Vim常用操作(1)-常用指令

    1.清空文件内容 Normal模式下,先输入"gg",将光标定位到文件首,然后输入"dG",文件就被清空了.当然也可以直接输入"ggdG".

  4. 大白话说GIT常用操作,常用指令git操作大全

    列一下在开发中用的比较多的git指令 git clone https://github.com/chineseLiao/Small-career // 克隆远程仓库到本地 git add . // 把 ...

  5. FastJson的常用操作

    FastJson的常用操作 2017-06-05 常用操作包括以下内容: 对象与(JsonObject或JsonArray)与String的互换 String转换为(JsonObject或JsonAr ...

  6. Hbase到Solr同步常用操作

    Hbase到Solr同步常用操作 1. 整体流程 2. 常用操作 Hbase常用操作 Solr常用操作 hbase-index常用操作 3. 其他资料 Lily HBase Indexer使用整理 h ...

  7. Linux - nginx基础及常用操作

    目录 Linux - nginx基础及常用操作 Tengine淘宝nginx安装流程 nginx的主配置文件nginx.conf 基于域名的多虚拟主机实战 nginx的访问日志功能 网站的404页面优 ...

  8. gcc与makefile编译 BY 四喜三顺

    gcc编译控制过程:(假设源代码为a.c)(1)源文件到预处理文件:    gcc -E -o a.cxx a.c    a.cxx显示调用哪些头文件(2)生成汇编代码:              g ...

  9. Linux常用操作练习

    Linux常用操作练习 练习一:安装CentOS 1.设置为1G内存(才有图形界面).10G硬盘 2.分给交换分区2G(4G一下2G,8G-32G分4G-8G) 练习二:安装CentOS迷你版 1.安 ...

  10. GreenPlum-数据存储目录迁移及常用操作

    一.环境介绍 Greenplum5 3节点集群,Centos7.2虚拟机, 二.需求 因为/home目录磁盘空间已满,需要将Greenplum的数据存储目录转移到新的分区/opt目录下,虚拟机磁盘管理 ...

随机推荐

  1. PNG文件解读(1):PNG/APNG格式的前世今生

    PNG格式的前世今生 png是一种无损压缩的位图片形格式,其设计目的是试图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性.PNG使用从LZ77派生的无损数据压缩算法--LZW专 ...

  2. ClickHouse 在 UBA 系统中的字典编码优化实践

    ClickHouse UBA 版本是字节跳动内部在开源版本基础上为火山引擎增长分析专门深度定制优化的版本.本文介绍在字典编码方向上的优化实践,作者系字节跳动数据平台研发工程师 Jet He,长期致力于 ...

  3. 收钱吧与火山引擎VeDI合作一年后 有了哪些新变化?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群     收钱吧正在和火山引擎数智平台(VeDI)跑出一条业务提效新通路.   相关数据显示,收钱吧的日服务人次就近 ...

  4. Solon2 接口开发: 熟悉 Gateway

    Gateway 是 Solon 框架的特殊控制器(也是Handler 的一个实现类).它通过注册收集之后,在局部范围内提供:二级路由.拦截.过滤.融断.异常处理等功能,并统一到网关处理. 另一个作用: ...

  5. 使用 Diffusers 通过 DreamBooth 来训练 Stable Diffusion.md

    邀请参与我们的 DreamBooth 微调编程马拉松活动! DreamBooth 是一种使用专门的微调形式来训练 Stable Diffusion 的新概念技术.一些人用他仅仅使用很少的他们的照片训练 ...

  6. MVCC多版本并发控制和幻读问题的解决

    首先我们先介绍一下锁的分类,再进入今天的正题. 一.锁分类: 1.从性能上分:乐观锁.悲观锁.乐观锁(用版本号对比或CAS机制)适用于读比较多的场景,悲观锁适用于写比较多的场景.如果在写比较多的场景使 ...

  7. 0x69 图论-二分图的覆盖与独立集

    A:Machine Schedule 输入 5 5 10 0 1 1 1 1 2 2 1 3 3 1 4 4 2 1 5 2 2 6 2 3 7 2 4 8 3 3 9 4 3 0 输出 3 在二分图 ...

  8. [NOI2015]荷马史诗 - Huffman树

    题目描述 追逐影子的人,自己就是影子. --荷马 llison 最近迷上了文学.她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的<荷马史诗>.但是由<奥德赛&g ...

  9. 2013年 第四届蓝桥杯C/C++ B组(省赛)

    第一题:高斯日记 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们知道,那个整数就是日期,它表示那一天是高斯出生 ...

  10. L3-001. 凑零钱-PAT团体程序设计天梯赛GPLT(01背包,动态规划)

    韩梅梅喜欢满宇宙到处逛街.现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债.韩梅梅手边有 104 枚来自各个星球的硬币,需要请你帮她盘算一下 ...