编译链接专题第7篇-变量的高级主题(下)

admin 2024年3月13日17:07:28评论2 views字数 4585阅读15分17秒阅读模式

前言

很多非科班出身的工程师对项目的编译链接其实是很不熟悉的(包括作者自己),但是如果我们想自己做项目或者从01实现一个项目,或者想要优化程序,或者要修改memory layout,或者要实现AUTOSAR架构下内存保护,编译链接是必不可少的知识。本着打破沙锅学到底的目的,我们决定从01实现一个Windows操作系统下基于AUTOSAR架构的编译环境,同时为了锻炼我们的代码能力,从01实现一个常用的数据结构库,如果有比较优秀的开源AUTOSAR代码也计划加入进去。计划手写整个工程的makefile使用make工具能直接编译工程,同时编写CMakeLists文件,支持CMake生成makefile文件来编译整个工程。

对编译链工具不熟悉的,可以参考这篇文章:https://blog.51cto.com/xiacaojun/5648507

编译链接专题第7篇-变量的高级主题(下)

我们将使用的工具:

项目构建生成工具:CMake

编译链接专题第7篇-变量的高级主题(下)

编译链接专题第7篇-变量的高级主题(下)

项目构建工具:make

编译链接专题第7篇-变量的高级主题(下)

编译链接专题第7篇-变量的高级主题(下)

编译器:

Windosw: gcc/g++

编译链接专题第7篇-变量的高级主题(下)

编译链接专题第7篇-变量的高级主题(下)

编译链接专题第7篇-变量的高级主题(下)

TC3xx: Green Hills (GHS)

关于WindowCMake入门安装请参考这篇文章:Windows下CMake的小白级入门使用教程(hello world)

专题文章:

编译链接专题第1篇-make和makefile介绍

编译链接专题第2篇-初识makefile结构

编译链接专题第3篇-初识makefile中的伪目标

编译链接专题第4篇-变量和变量的不同赋值方式

编译链接专题第5篇-预定义变量的使用

编译链接专题第6篇-变量的高级主题(上)

本文目录

编译链接专题第7篇-变量的高级主题(下)

注:本文章引用了一些第三方工具和文档,若有侵权,请联系作者删除!

正文

1.环境变量(全局变量)

makefile中能够直接使用环境变量的值。

-- 如果makefile定义了同名变量,环境变量将被覆盖。

-- 运行make指定-e选项,优先使用环境变量。

环境变量的本质就是一系列的全局键值对。

为什么要在makefile中使用环境变量?

-- 优点:环境变量可以在所有makefile中使用。

-- 缺点:过多的依赖环境变量会导致移植性降低。

变量在不同makefile之间的传递方式

-- 直接在外部定义环境变量进行传递

-- 使用export定义变量进行传递(定义临时环境变量)

-- 定义make命令行变量进行传递(推荐)

makefile的本质是一种脚本程序,既然是脚本程序就要考虑它的移植性,如果makefile依赖一些环境变量的话,就不能保证这个makefile在另外一台机器上去执行得到的结果是一样的,所以环境变量要谨慎使用

1. 直接在外部定义环境变量能够实现变量在不同makefile之间的传递,但是考虑移植性的话,最好不要这么做

2. 使用export定义变量进行传递,就没有移植性的问题,因为变量是在当前makefile中定义的,并不是在操作系统里面定义的也不是makefile的外部定义的

3. 定义make命令行变量进行传递,如果当前的命令行变量需要使用另一个makefile完成一定的功能,那么我们在调用其他makefile的时候就可以定义一个命令行的变量,这样子另一个makefile里面就可以之间使用命令行变量了

实际项目里面更趋向与使用export定义变量进行传递

示例1

TEMPwindows操作系统中的一个环境变量。

编译链接专题第7篇-变量的高级主题(下)

#makefile lesson6 TEMP := temp pathtest :  @echo "TEMP =>$(TEMP)"

编译链接专题第7篇-变量的高级主题(下)

系统中有TEMP 这个环境变量,但是执行make命令没有大家环境变量中TEMP 的值,是因为自定义的变量覆盖环境变量了

如果非要使用系统中的环境变量的话,make -e

示例2

#makefile lesson7TEMP := temp pathvar := variabletest :  @echo "TEMP =>$(TEMP)"  @echo "make another file ..."  @$(MAKE) -f makefile_lesson7_2
#makefile lesson7_2test:  @echo "TEMP => $(TEMP)"  @ECHO "VAR => $(var)"

编译链接专题第7篇-变量的高级主题(下)

为什么在makefile_lesson7_2里面打印的TEMP 的值是makefile_lesson7里面定义的值了,不应该是实际TEMP的目录(环境变量)吗?--makefile_lesson7里面的 TEMP := temp path这一行代码的意思是:当前makefile执行的时候,将系统里面的TEMP这个环境变量的值改写成temp path,所以makefile_lesson7echo "TEMP =>$(TEMP)"打印出来的是temp path;由于系统中的TEMP的值在当前makefile中被改写了,这个改写就会传递到其他的地方,传递到其他的makefile里面,所以在makefile_lesson7_2里面打印的值是我们自定义的值了

var在makefile_lesson7_2里面是空值,因为var是在makefile_lesson7里面定义的,也就是var这个变量的作用域是在makefile_lesson7里面,不可能传递到其他makefile里面去,另外,var也不是系统的环境变量,所以makefile_lesson7里面定义的var变量旨在makefile_lesson7文件里面有效,所以根本不会传递到makefile_lesson7_2里面去的

如果想要传递的话,需要加上export临时创建一个环境变量,这样其他makefile里面就可以访问这个临时环境变量的值了!临时环境变量不会真正修改系统里面环的境变量的值

示例3:使用export传递临时环境变量

#makefile lesson7TEMP := temp pathexport var := variabletest :  @echo "TEMP =>$(TEMP)"  @echo "make another file ..."  @$(MAKE) -f makefile_lesson7_2
#makefile lesson7_2test:  @echo "TEMP => $(TEMP)"  @echo "VAR => $(var)"

编译链接专题第7篇-变量的高级主题(下)

示例4:通过命令行传递变量(NEWV := new_variable

#makefile lesson7TEMP := temp pathexport var := variableNEWV := new_variabletest :  @echo "TEMP =>$(TEMP)"  @echo "make another file ..."  @$(MAKE) -f makefile_lesson7_2  @$(MAKE) -f makefile_lesson7_2 NEWV:=$(NEWV)
#makefile lesson7_2test:  @echo "TEMP => $(TEMP)"  @echo "VAR => $(var)"  @echo "NEWV => $(NEWV)"

编译链接专题第7篇-变量的高级主题(下)

2.目标变量(局部变量)

目标变量的作用域只在指定目标及连带的规则中。

target : name <assignment> value

target: override name <assignment> value

var := variabletest : var := test-vartest:  @echo “test”  @echovar => $(var)”

var := variable定义的变量var的作用域是这个文件

test : var := test-var的意思是为test目标以及依赖定义一个名为var的变量,并且这个变量的值是test-var,开头的test是一个限定,限定当前定义的这个var变量的作用域是什么.

test:

    @echo "test:"

     @echo "var => $(var)"

打印出来的var的值是test-var,这和C和C++语言里面的概念是一致的,当前的局部变量会优先使用,即便局部变量和当前文件中的变量或者全局变量的名字相同

示例5

#makefile lesson7_3var := variabletest : var := test-vartest :  @echo "test"  @echo "var =>$(var)"

编译链接专题第7篇-变量的高级主题(下)

示例6

#makefile lesson7_3var := variabletest : var := test-vartest : another  @echo "test"  @echo "var =>$(var)"another:  @echo "another"  @echo "var =>$(var)"

编译链接专题第7篇-变量的高级主题(下)

连带的规则another及其规则当中打印的还是局部变量var的值

示例7:去掉连带规则

#makefile lesson7_3var := variabletest : var := test-vartest :  @echo "test"  @echo "var =>$(var)"another:  @echo "another"  @echo "var =>$(var)"

编译链接专题第7篇-变量的高级主题(下)

3.模式变量

模式变量是目标变量的扩展。

作用域只在符合模式的目标及其连带规则中。

target : name <assignment> value

target: override name <assignment> value

new := new_variable

%e :override new := test-new

rule:

    @echo rule

    @echo new=> $(new)

new := new_variable定义的变量new的作用域是当前文件。

%e : override new := test-new

%是一个通配符,这就意味着当前要定义一个名为new的局部变量,new的作用域就是所有以e字符解释的目标以及连带规则当中,override关键字的作用是局部变量new不希望被命令行变量所覆盖

rule:

    @echo "rule"

    @echo "new => $(new)"

打印的应该是test-new

示例8

new := new_variabletest : var := test-var%e : override new := test-newtest :  @echo "test"  @echo "var =>$(var)"  @echo "new =>$(new)"another:  @echo "test"  @echo "var =>$(var)"  @echo "new =>$(new)"

编译链接专题第7篇-变量的高级主题(下)

示例9

#makefile lesson7_3var := variablenew := new_variabletest : var := test-var%e : override new := test-newtest :  @echo "test"  @echo "var =>$(var)"  @echo "new =>$(new)"another:  @echo "test"  @echo "var =>$(var)"  @echo "new =>$(new)"rule:  @echo "rule"  @echo "var =>$(var)"  @echo "new =>$(new)"

编译链接专题第7篇-变量的高级主题(下)

编译链接专题第7篇-变量的高级主题(下)

4.小结

makefile中的三种变量:

- 全局变量makefile外部定义的环境变量。

- 文件变量makefile中定义的变量。

- 局部变量:指定目标的变量。

参考资料:

1.狄泰软件唐老师课程

2.专业嵌入式软件开发书籍

End

原文始发于微信公众号(汽车电子嵌入式):编译链接专题第7篇-变量的高级主题(下)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年3月13日17:07:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   编译链接专题第7篇-变量的高级主题(下)http://cn-sec.com/archives/2565630.html

发表评论

匿名网友 填写信息