立即赋值和延迟赋值

  1. := 立即赋值 按照先后顺序执行,立即赋值
  2. = 延迟赋值,赋值的结果会等到整个路径执行完成以后确定。换句话说,后面会覆盖前面的。
  • 测试用例 ```makefile a = foo b1 := $(a) bar b2 = $(a) bar a = xyz

all: @echo b1=$(b1) @echo b2=$(b2)

  1. - 执行结果
  2. ```bash
  3. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make all
  4. b1=foo bar
  5. b2=xyz bar

以上就可以看出差别了,日常推荐使用 := 进行赋值

变量赋值和目标执行

我们先查看下面的例子,

  1. a ?= aaa
  2. b := $(a)
  3. c = $(a)
  4. a_origin = $(origin a)
  5. b_origin = $(origin b)
  6. c_origin = $(origin c)
  7. all:
  8. @echo all:$(a)
  9. @echo all:$(b)
  10. @echo all:$(c)
  11. @echo all:$(a_origin)
  12. @echo all:$(b_origin)
  13. @echo all:$(c_origin)
  14. a = bbb
  15. b := $(a)
  16. c = $(a)
  17. test1:
  18. @echo test1:$(a)
  19. @echo test1:$(b)
  20. @echo test1:$(c)
  21. @echo test1:$(a_origin)
  22. @echo test1:$(b_origin)
  23. @echo test1:$(c_origin)
  24. a = ccc
  25. b := $(a)
  26. c = $(a)
  27. test2:
  28. @echo test2:$(a)
  29. @echo test2:$(b)
  30. @echo test2:$(c)
  31. @echo test2:$(a_origin)
  32. @echo test2:$(b_origin)
  33. @echo test2:$(c_origin)
  34. a = ddd
  • 执行默认的target
    1. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make all
    2. all:ddd
    3. all:ccc
    4. all:ddd
    5. all:file
    6. all:file
    7. all:file
    8. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make test1
    9. test1:ddd
    10. test1:ccc
    11. test1:ddd
    12. test1:file
    13. test1:file
    14. test1:file
    15. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make test2
    16. test2:ddd
    17. test2:ccc
    18. test2:ddd
    19. test2:file
    20. test2:file
    21. test2:file
    发现执行得结果都是一样得,所以,结论是,Makefile 中所有变量赋值的语句在所有 target 之前完成,跟变量赋值与 target 的相对位置无关。
    另外,我们可以看到 b 没有跟上 c 的节奏,拿到 ccc 就不再跟 c 一样去拿最后设置的 ddd 了,体现了 “:=” 的 “立即赋值”,而 c 一直等到了 Makefile 最后的 a。另外,三个变量最后的值都是文件内部赋值,所以 origin 是 file。

    通过命令行赋值

    1. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make test2 a=123
    2. test2:123
    3. test2:123
    4. test2:123
    5. test2:command line
    6. test2:file
    7. test2:file
    8. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make test2 b=123
    9. test2:ddd
    10. test2:123
    11. test2:ddd
    12. test2:file
    13. test2:command line
    14. test2:file
    由次可以断定通过命令行传入得参数优先级高。

    通过环境变量赋值

  1. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ export a=123456
  2. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ ecport a = 12345^C
  3. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make -e all
  4. all:123456
  5. all:123456
  6. all:123456
  7. all:environment override
  8. all:file
  9. all:file
  10. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ unset a
  11. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ b=343 make -e all
  12. all:ddd
  13. all:343
  14. all:ddd
  15. all:file
  16. all:environment override
  17. all:file

使用-e用环境变量得覆盖变量,不过很少有见到使用得。

调试与跟踪

  • 调试跟踪

    1. # 调试
    2. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make --debug all
    3. # 跟踪
    4. zhou@zhou:~/100ask-imx6-ull/Linux-project/Linux_Device_Driver/temp$ make --trace all
  • 日志

  1. $(info ...)
  2. $(warning ...)
  3. # 下面这一个会停止运行Makefile
  4. $(error ...)
  • Environment dumping
    1. # 将所有的变量保存到文件里面
    2. make -p xxx > xxx.data.dump

参考资料

泰晓科技-gitee库
泰晓科技