自定义变量

= 是最基本的赋值,会把整个makefile展开之后再决定是多少

x=foo
y=$(x)bar #y是asdbar,不是foobar
x=asd

:= 是覆盖之前的值,和=不同,和赋值的位置有关

x=foo
y:=$(x)bar #y是foobar
x=asd

?= 是如果没有被赋值过就赋予等号后面的值,赋过了就不管了

+= 是添加等号后面的值

变量的使用

和shell一样,makefile通过$(FLAGS)来读取变量FLAGS的值,对于$本身,使用$$读取

变量替换

注意这两种替换的方式都得使用变量名,不能使用变量的内容,即不能写成诸如$($(VAR):o=a)的形式,其他返回内容的函数也不行,均会导致替换的失败

makefile中有两种变量替换,

  1. 形如$(var:a=b)或者${var:a=b},是把var中以a结尾的变量替换为b
OBJ=./obj/test.o
OBJ2=$(OBJ:o=a)
all:
@echo "OBJ:$(OBJ)"
@echo "OBJ2:$(OBJ2)"
#############################
$make all
OBJ:./obj/test.o
OBJ2:./obj/test.a
  1. 使用模式匹配的方式表示替换内容
OBJ=./obj/test.o
OBJ2=$(OBJ:%.o=%.a)
all:
@echo "OBJ:$(OBJ)"
@echo "OBJ2:$(OBJ2)"
############################
$make all
OBJ:./obj/test.o
OBJ2:./obj/test.a

自动化变量

? 所有比目标新的依赖的集合,以空格分隔,通常用他们的值,即$?

@ 规则中的目标文件集,如果有多个目标,那么就是匹配于目标中模式定义的集合,通常用他们的值,即$@

% 仅当目标是函数库文件中,表示规则中的目标成员名,如果不是,为空,通常用他们的值,即$%

< 依赖目标中的第一个目标的名字,通常用他们的值,即$<

^ 所有依赖目标的集合,以空格分隔,去除重复的依赖目标,通常用他们的值,即$^

+ 所有依赖目标的集合,不去除重复的依赖目标,通常用他们的值,即$+

* 表示目标模式中 %之前的部分,通常用他们的值,即$*

@D 表示@的目录部分(不以/结尾),通常用他们的值,即$(@D)

@F 表示@的文件部分,通常用他们的值,即$(@F)

。。。另外6个同理

环境变量

makefile会自动读取系统中的环境变量,并复制一份一模一样的,如果用户在makefile中定义的同名的变量,那么原来的环境变量就会被覆盖

VPATH

虚路径,如果没有指明VPATH变量,make只会在当前目录中去寻找依赖文件和目标文件,如果定义了VPATH,则make会在当前目录找不到的情况下,到所制定的目录中去找文件,这个变

VPATH=src:../headers

vpath

vpath是一个指令,可以用来搜索文件,通常有三种用法:

  1. VPATH <pattern> <directories>为符合模式<pattern>的文件指定搜索目录
  2. VPATH <pattern> 清除符合模式<pattern>的文件的搜索目录
  3. VPATH 清除所有已被设置好了的文件搜索目录

    这里,<pattern>需要包含 %字符,eg: vpath %.h ../headers

    如果多条vpath语句中出现了重复的<pattern>,则会按照先后顺序搜索

    print: *.c #依赖关系的通配符会被自动展开,表示print目标依赖于所有的.c 文件

    object=*.c #变量中的通配符不会被展开object就是 “
    .c”需要使用wildcard来展开

例子

#Makefile文件
CC:=gcc
CFLAGS:= -O2 -I ./include
TARGET:=linkstack
OBJS:=linkstack.o linkstack_main.o
HDRS:=linkstack.h
SRC:=$(OBJS:%.o=%.c) #注意,这里不能用$(OBJS)
VPATH=./src:./include/
#vpath %.h ./include/
$(TARGET):$(OBJS)
$(CC) $(CFLAGS) $^ -o $@
$(OBJS):$(SRC) $(HDRS)
$(CC) -c $^ $(CFLAGS)
.PHONY:clean
clean:
$(RM) $(OBJS) $(TARGET)

make执行前后的变化

$tree
.
├── include
│   └── linkstack.h
├── Makefile
└── src
├── linkstack.c
└── linkstack_main.c 2 directories, 4 files
$make
gcc -c ./src/linkstack.c ./src/linkstack_main.c -O2 -I ./include
gcc -O2 -I ./include linkstack.o linkstack_main.o -o linkstack
$tree
.
├── include
│   └── linkstack.h
├── linkstack
├── linkstack_main.o
├── linkstack.o
├── Makefile
└── src
├── linkstack.c
└── linkstack_main.c 2 directories, 7 files
$make clean
$tree
.
├── include
│   └── linkstack.h
├── Makefile
└── src
├── linkstack.c
└── linkstack_main.c 2 directories, 4 files

Makefile变量的更多相关文章

  1. makefile变量赋值

    在定义变量的值时,我们可以使用其它变量来构造变量的值,在Makefile中有两种方式来在用变量定义变量的值. 先看第一种方式,也就是简单的使用“=”号,在“=”左侧是变量,右侧是变量的值,右侧变量的值 ...

  2. makefile笔记5 - makefile变量

    在 Makefile 中的定义的变量,就像是 C/C++语言中的宏一样,他代表了一个文本字串,在 Makefile 中执行的时候其会自动原模原样地展开在所使用的地方.其与 C/C++所不同的是,你可以 ...

  3. makefile 变量展开

    Makefile中给变量赋值: =     是递归展开式变量 value1 = 5 value2 = $(value1) value1 = 6 最终$(value2)就变成了6 :=    是直接展开 ...

  4. 【 MAKEFILE 编程基础之三】详解 MAKEFILE 变量的定义规则使用!

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/gcc-makefile/770.html   ...

  5. 如何调试makefile变量

    六.七年前写过一篇<跟我一起写Makefile>,直到今天,还有一些朋友问我一些Makefile的问题,老实说,我有一段时间没有用Makefile了,生疏了.回顾,这几年来大家问题我的问题 ...

  6. makefile变量定义应用到c语言

    makefile是为组织程序工程的,其定义的宏怎样应用到c程序中呢? 我们知道Makefile中可定义变量或导出变量,make命令可定义变量:编译器(如gcc)可通过CFLAGS定义宏. 但如何才能使 ...

  7. 开始编写Makefile(二)Makefile变量的使用

    Makefile可以使用变量代替 命令行:make -f Makefile2 说明开始make一个名为Makefile2的文件 ###############定义变量################# ...

  8. Makefile学习(一)变量

    鉴于之前有一些了解,还有自己的学习习惯,我一上来就看Makefile的变量这一章.主要脉络是根据GNU make中文手册. 第六章:Makefile中的变量 6使用变量 定义:变量是一个名字,代表一个 ...

  9. Makefile中的变量和shell变量

    我们在写makefile时 多多少少会用到shell脚本, 对于变量的在shell中的使用有一些要注意的细节.让我们从一个简单的makefile来看看. 注意makefile中一定要有一个目标,且一定 ...

随机推荐

  1. 第 29 章 CSS3 弹性伸缩布局[下]

    学习要点: 1.新版本 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS3 提供的用来实现未来响应式弹性伸缩布局方案,这里做一个初步的了解. 一.新版本 新版本的 Flexbox 模型是 201 ...

  2. NOSQL学习笔记系列之MongoDB 一 基础

    主题:MongoDB 学习资料参考网址: 1.http://www.w3cschool.cc/mongodb/mongodb-tutorial.html 2.http://www.icoolxue.c ...

  3. JVM基本原理

    第一节 JVM内存模型 •堆栈简称栈,主要提供以下用途: –保存临时数据 –放置临时变量(局部.自动.堆栈) –保存调用现场 –方法返回值的传递 •堆主要提供以下用途: –存放对象(GC对象) –存放 ...

  4. Spark集群 + Akka + Kafka + Scala 开发(2) : 开发一个Spark应用

    前言 在Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境,我们已经部署好了一个Spark的开发环境. 本文的目标是写一个Spark应用,并可以在集群中测试. ...

  5. 通过RODBC包操作mysql数据库

    MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),MySQL数据库系统使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理.---百度百科 1. MySQL安装 官网下载 ...

  6. linux使用rpm重装jdk

    1.卸载jdk #rpm -qa | grep gcj 如果输出没有内容,说明没有jdk,如果输出有内容,要把搜索到的文件卸载掉,命令为: #rpm -e --nodeps [上步操作输出的文件] 然 ...

  7. sql2012还原sql2008备份文件语句

    --sql2012还原sql2008语句 --选择master数据库,新建查询 输入下面sql语句 --选择兼容模式(sql 2008)创建数据库db RESTORE DATABASE db FROM ...

  8. .Net中的并行编程-5.流水线模型实战

    自己在Excel整理了很多想写的话题,但苦于最近比较忙(其实这是借口).... 上篇文章<.Net中的并行编程-4.实现高性能异步队列>介绍了异步队列的实现,本篇文章介绍我实际工作者遇到了 ...

  9. js的querySelector跟querySelectorAll

    querySelector:document.querySelector('.className')------->可以选中.className的一个dom(注意只是一个) document.q ...

  10. 25佳漂亮的结婚邀请 & 婚礼请柬网站设计

    互联网给我们的生活带来了巨大的变化,越来越多的事情可以通过网络完成.下面向大家分享一组结婚邀请网站以及婚礼请柬网站的设计案例,如果你也正想制作这样的网站,相信这些优秀案例能够带给你很大的帮助. 您可能 ...