zoukankan      html  css  js  c++  java
  • 【Makefile】5-Makefile变量的基础


    前言

    • 本笔记主要记录Makefile一些概念要点。

    概念

    Chapter 5:变量的基础

    • 变量可以使用在 目标依赖目标命令 或是 Makefile的其它部分中

    • 变量的名字可以包含 字符、数字和下划线(可以以数字开头)

      • 但是不应该包含有 : # = 空格 回车 等特殊字符。
      • 变量名具有大小写敏感特性。(推荐大小写搭配使用)
    • 变量赋值时,会自动删除等号 = 两边的空格,但是,变量值后面的空格会保留,直至遇到 结束符或注释符 **

    5.1 变量的基础 *

    • 使用变量时需要在变量前面添加 $ 符号,表示去该变量的值。
      • 推荐在取值时给变量添加上 (){}
      • 如果需要使用真实的 $ ,就用 $$ 即可。
    • 取变量值其实就是相当于 C/C++ 中的宏展开一样,其实还是字符串替换。
    • 注:推荐看例子。*
      • 赋值时要注意后面的空格和注释符 #
        • 注释符 # 可以表示终止一个变量的定义。
        • 例子:
          • /foo/bar 后面还跟了几个 空格,如果使用到 $(dir)/file ,那 路径就错误了。
    dir := /foo/bar      # directory to put the frobs indir := /foo/bar # directory to put the frobs in
    

    空格的定义 **

    • 先定义一个空变量 empty
    • 然后用 $ 符号取出 + 空格 + 注释符 #
      • 因为 注释符 # 可以结束一个变量的赋值。
      • 不用注释符 # 也可以,只是怕空格的数量不对才用 注释符 # 表示一下而已。
    empty:=
    a = $(empty) #
    

    一些赋值

     变量定义语法:

    形式 说明
    A = xxx 延时变量
    B ?= xxx 延时变量,只有第一次定义时赋值才成功,若曾被定义过,则此赋值无效。
    C := xxx 立即变量
    D += yyy 如果D在前面是延时变量,那么现在它还是延时变量
    如果D在前面是立即变量,那么它现在还是立即变量

    一些特殊的符号

    符号 说明
    $@ 表示规则中的目标文件集
    $% 当目标为函数库的时候,则表示规则中的目标成员名。反之为空。如一个目标为"foo.a(bar.o)",那么,"$%"就是"bar.o",以空格分隔开。
    $< 依赖文件集合中的第一个文件,如果依赖文件以"%"形式出现,则表示符合模式的一系列文件集合
    $? 所有比目标新的依赖集合,以空格分隔开。
    $^ 所有依赖文件集合,以空格分隔开。如果依赖有相同,则取其一。
    $+ 和 "$^"类同,但是不会把相同的删除掉。
    $* 这个变量表示目标模式中 "%"及其之前的部分,如果目标是 test/a.test.c,目标模式为 a.%.c, 那么 "$* " 就是 test/a.test。

    5.2 变量中的变量 *

    • = 号右侧可以是值,也可以是变量*
    • 如果 = 右侧是 变量,那么该 变量 可以定义在文件的任何一处(就是 延时变量 =)。(但是不推荐使用该方法

    • 为了避免上面第二点的操作,一般使用 即时变量 := 来赋值,例子:
      • y 的值是 foo bar
    x := foo
    y := $(x) bar
    x := later
    
    * y 的值是 **bar**
    
    y := $(x) bar
    x := food
    

    5.3 变量高级用法

    • 变量值替换
    • 把变量的值再变成变量

    变量值替换

    • 替换变量中的共有的部分
      • 格式
        • $(var:a=b)
        • ${var:a=b}
      • 意思是把变量 var 中的所有以 a 字串结尾的 a 替换成 b 字串。
        • 这里 结尾 的意思是 空格结束符
      • 例子
    foo := a.o b.o c.o
    bar := $(foo:.o=.c)
    # 或
    foo := a.o b.o c.o
    bar := $(foo:%.o=%.c)
    

    把变量的值再当成变量

    • 直接上例子:
    ifdef do_sort
    func := sort
    else
    func := strip
    endif
    bar := a d b g q c
    foo := $($(func) $(bar))
    
    • 用在操作符左边:
    dir = foo
    $(dir)_sources := $(wildcard $(dir)/*.c)
    define $(dir)_print
    lpr $($(dir)_sources)
    endef
    

    5.5 override 指示符

    • 通常在执行 make 时,如果通过命令行定义了一个变量,那么它将替代在 Makefile 中出现的同名变量的定义。
    • 如果不希望命令行指定的变量值替代在 Makefile 中的变量定义,那么我们需要在 Makefile 中使用指示符 override 来对这个变量进行声明,如:
    override <variable>; = <value>;
    # 或
    override <variable>; := <value>;
    # 或
    override <variable>; += <more text>;
    # 或
    override define foo
    bar
    endef
    

    5.6 多行变量

    • 相当于 C 中的函数
    • 关键字 define。(使用该该关键字可以有 换行
    • 例子
    define two-lines
    echo foo
    echo $(bar)
    endef
    

    5.7 环境变量

    • make 运行时的系统环境变量可以在 make 开始运行时被载入到 Makefile 文件中,但是如果 Makefile中已定义了这个变量,或是这个变量由 make 命令行带入,那么系统的环境变量的值将被覆盖。(如果make 指定了“-e”参数,那么,系统环境变量将覆盖 Makefi le 中定义的变量)

    5.8 目标变量

    • 为某个目标设置局部变量,这种变量被称为Target-specifi c Variable
    • 范围只在这条规则以及连带规则中
    • 语法
      • ; 可以是前面讲过的各种赋值表达式,如 = := += 或是 ?=
    <target ...> : <variable-assignment>;
    <target ...> : overide <variable-assignment>
    
    • 例子
      • 在这个示例中,不管全局的 $(CFLAGS) 的值是什么,在 prog 目标,以及其所引发的所有规则中(prog.o foo.o bar.o 的规则),$(CFLAGS) 的值都是 -g
    prog : CFLAGS = -g
    prog : prog.o foo.o bar.o
        $(CC) $(CFLAGS) prog.o foo.o bar.o
    prog.o : prog.c
        $(CC) $(CFLAGS) prog.c
    foo.o : foo.c
        $(CC) $(CFLAGS) foo.c
    bar.o : bar.c
        $(CC) $(CFLAGS) bar.c
    

    5.9 模式变量

    • 就是把上面 目标变量 中的具体目标改为一种模式(一条语句(表达一种模式))。
    • 语法
    <pattern ...>; : <variable-assignment>;
    <pattern ...>; : override <variable-assignment>;
    
    • 例子:就是把 prog 改为 %.o%.o 就是一种模式,所有 .o 结尾的都符合该模式。
    %.o : CFLAGS = -O
    

    参考

    • 《GUN Makefile》
    • 《跟我一起写Makefile》
  • 相关阅读:
    下拉列表
    集合(List、Set、Map)
    IDEA实用教程(一)
    IDEA实用教程(四)—— 创建JavaSE工程
    IDEA实用教程(二)
    IDEA实用教程(三)
    IDEA实用教程(五)——配置IDEA的JVM内存值
    详解 JAVA 适配模式和 接口适配器
    ubuntu查看硬件信息
    IT职场人生:员工的公司观
  • 原文地址:https://www.cnblogs.com/lizhuming/p/14050056.html
Copyright © 2011-2022 走看看