文档章节

学会使用makefile:3

e
 eversliver
发布于 2016/08/07 15:17
字数 1007
阅读 3
收藏 0

前面写的makefile的相关只是都没有使用到变量,依照变量,makefile可以使用的非常多变。

foo = $(bar)
bar = Huh?
all:
    @echo $(foo)

上面这个例子执行 make 将会打出 Huh?当 make 读到 foo = $(bar) 时,确定 foo 的值是 $(bar) ,但并不立即展开 $(bar) ,然后读到 bar = Huh? ,确定 bar 的值是 Huh?

通过上面这个特点,我们可以讲变量的值推迟到后面去定义:

main.o: main.c
        $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
CC = gcc
CFLAGS = -O -g
CPPFLAGS = -Iinclude

像上面这样,编译选项就可以展开生成为:gcc -O -g -Iinclude -c main.c

通常把 CFLAGS 定义成一些编译选项,例如 -O 、 -g 等,而把 CPPFLAGS 定义成一些预处理选项,例如 -D 、 -I 等。

如果希望makefile在遇到赋值的时候立刻展开,可以使用:=来代替= ,下面这个例子

root@wc:~/Codes/Learn# cat makefile 
x := foo
y := $(x) bar!
all:
	@echo "$(y)"
root@wc:~/Codes/Learn# make all
foo bar!
root@wc:~/Codes/Learn#

如果x 和 y的位置交换,那么赋值的时候x会被展开成为一个空值

还有一种有用的赋值运算符是?=:例如 foo ?= $(bar) 的意思是:如果 foo 没有定义过,那么 ?= 相当于 = ,定义 foo 的值是 $(bar) ,但不立即展开;如果先前已经定义了 foo ,则什么也不做,不会给 foo 重新赋值。

另一种是+=,其可以给变量追加值,+=依旧保持着=或者:=的特性,主要看这个变量原先是怎么定义的。如果变量还没有定义过就直接用 += 赋值,那么 += 相当于 = 。

 

类似$@这样的特殊变量还有:

$@ ,表示规则中的目标。
$< ,表示规则中的第一个条件。
$? ,表示规则中所有比目标新的条件,组成一个列表,以空格分隔。
$^ ,表示规则中的所有条件,组成一个列表,以空格分隔。

按照上面,下面的两条语句实际上就是等价的了:

main: main.o stack.o maze.o
    gcc main.o stack.o maze.o -o main
main: main.o stack.o maze.o
    gcc $^ -o $@

这样即使以后又往条件里添加了新的目标文件,编译命令也不需要修改,减少了出错的可能。

$? 变量也很有用,有时候希望只对更新过的条件进行操作,例如有一个库文件 libsome.a 依赖于几个目标文件:

libsome.a: foo.o bar.o lose.o win.o
    ar r libsome.a $?
    ranlib libsome.a

这样,只有更新过的目标文件才需要重新打包到 libsome.a 中,没更新过的目标文件原本已经在 libsome.a 中了,不必重新打包。

第一节中可以看到默认规则中有很多变量,类似CC,CFLAGS,CC默认值为cc,而CFLAGS的默认值为空,类似的变量还有很多:

AR  静态库打包命令的名字,缺省值是 ar 。
ARFLAGS     静态库打包命令的选项,缺省值是 rv 。
AS     汇编器的名字,缺省值是 as 。
ASFLAGS     汇编器的选项,没有定义。
CC     C编译器的名字,缺省值是 cc 。
CFLAGS     C编译器的选项,没有定义。
CXX     C++编译器的名字,缺省值是 g++ 。
CXXFLAGS     C++编译器的选项,没有定义。
CPP     C预处理器的名字,缺省值是 $(CC) -E 。
CPPFLAGS     C预处理器的选项,没有定义。
LD     链接器的名字,缺省值是 ld 。
LDFLAGS     链接器的选项,没有定义。
TARGET_ARCH  和目标平台相关的命令行选项,没有定义。
OUTPUT_OPTION  输出的命令行选项,缺省值是 -o $@ 。
LINK.o  把 .o 文件链接在一起的命令行,缺省值是 $(CC) $(LDFLAGS) $(TARGET_ARCH) 。
LINK.c   把 .c 文件链接在一起的命令行,缺省值是 $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)$(TARGET_ARCH) 。 
LINK.cc   把 .cc 文件(C++源文件)链接在一起的命令行,缺省值是 $(CXX) $(CXXFLAGS)$(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) 。
COMPILE.c   编译 .c 文件的命令行,缺省值是 $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 。
COMPILE.cc  编译 .cc 文件的命令行,缺省值是 $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c 。
RM  删除命令的名字,缺省值是 rm -f 。

 

 

 

© 著作权归作者所有

e
粉丝 0
博文 57
码字总数 10582
作品 0
成都
私信 提问
Make 命令教程

代码变成可执行文件,叫做编译(compile);先编译这个,还是先编译那个(即编译的安排),叫做构建(build)。 Make是最常用的构建工具,诞生于1977年,主要用于C语言的项目。但是实际上 ,...

阮一峰
2015/02/20
0
0
嵌入式linux裸板开发--点亮LED

----------上一篇文章写的是linux下通过gcc完成程序源文件的编译执行的过程。以及makefile文件的编写,最后在终端平台输出myhello word!有了这个基础,这次学习的就是通过linux编译生成的代...

ludy51
2017/12/09
0
0
最全LinuxC语言系统开发资源视频资源

1小时快速攻破链表数据结构----(视频可下载)http://www.wyzc.com/forum/56796.html 深入理解auto register static关键字 http://www.wyzc.com/forum/56132.html 如何使用日期时间函数 http...

马洪伟
2014/12/26
0
0
linux驱动编写(usb host驱动入门)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 usb协议是一个复杂的协议,目前涉及到的版本就有usb1.0, usb2.0, usb3.0。大家如果打开kernel usb ho...

feixiaoxing
2018/04/06
0
0
Android Studio目录介绍

OK,我们这么看,第一,把这么多文件先分成这么三块 1. 编译系统(Gradle) 2. 配置文件 3. 应用模块 是Google推荐使用的一套基于的编译系统脚本(当然,你也可以使用ant),具体的介绍和文档...

fanhao812
2016/03/04
58
0

没有更多内容

加载失败,请刷新页面

加载更多

C# 视频多人脸识别的实现过程

整个项目是用虹软技术完成开发 上一篇内容的调整,提交到git了,https://github.com/catzhou2002/ArcFaceDemo 基本思路如下: 一、识别线程 1.获取当前图片 2.识别当前图片的人脸位置,并将结...

是哇兴哥棒棒哒
3分钟前
0
0
Spring Cloud Eureka 你还在让它裸奔吗??

前些天栈长在微信公众号Java技术栈分享了 Spring Cloud Eureka 最新版 实现注册中心的实战教程:Spring Cloud Eureka 注册中心集群搭建,Greenwich 最新版!,成功进入 Eureka 控制台页面。 ...

Java技术栈
19分钟前
1
0
linux gyp ERR! stack Error: EACCES: permission denied, mkdir ‘xxx’

在使用linux npm install的出现这个错误了,百度了下,没有权限加个参数即可 npm install --unsafe-perm

朝如青丝暮成雪
20分钟前
0
0
使用kubeadm 搭建K8s集群

1. 参考官网 https://kubernetes.io/docs/setup/independent/install-kubeadm/

whhbb
48分钟前
2
0
Dubbo 3.0 !提升不止一点点!

Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网、网易考拉等互联网公司,也不乏中国人寿、青岛海尔等大型传统企业。 自去年 12 月开始,Dubbo 3.0 便已正...

编程SHA
49分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部