前言
很多非科班出身的工程师对项目的编译链接其实是很不熟悉的(包括作者自己),但是如果我们想自己做项目或者从0到1实现一个项目,或者想要优化程序,或者要修改memory layout,或者要实现AUTOSAR架构下内存保护,编译链接是必不可少的知识。本着打破沙锅学到底的目的,我们决定从0到1实现一个Windows操作系统下基于AUTOSAR架构的编译环境,同时为了锻炼我们的代码能力,从0到1实现一个常用的数据结构库,如果有比较优秀的开源AUTOSAR代码也计划加入进去。计划手写整个工程的makefile使用make工具能直接编译工程,同时编写CMakeLists文件,支持CMake生成makefile文件来编译整个工程。
对编译链工具不熟悉的,可以参考这篇文章:https://blog.51cto.com/xiacaojun/5648507
我们将使用的工具:
项目构建生成工具:CMake
项目构建工具:make
编译器:
Windosw: gcc/g++
TC3xx: Green Hills (GHS)
关于Window下CMake入门安装请参考这篇文章:Windows下CMake的小白级入门使用教程(hello world)
专题文章:
编译链接专题第1篇-make和makefile介绍
编译链接专题第2篇-初识makefile结构
本文目录
注:本文章引用了一些第三方工具和文档,若有侵权,请联系作者删除!
正文
问题:makefile中的目标究竟是什么?
从make程序的设计初衷谈起,make程序是被设计用来编译C语言源代码的,一个项目或者工程里面C语言文件太多了,我们需要一个程序来自动的管理自动的编译,于是make就被设计出来了。
在默认情况下:
-- make认为目标对应着一个文件。
-- make比较目标文件和依赖文件的新旧关系,决定是否执行命令。
-- make以文件处理作为第一优先级们,也就说在默认的情况下make认为一个目标对应一个文件。
下面的代码又什么意义?
clean:
del *.o hello.out
在这个上下文当中,我们不希望clean是一个文件,我们希望clean是一个标签,clean这个目标当作一个标签来使用,我们执行make clean的时候,就是希望执行这个标签之下的这些命令。
#makefile
hello.exe all : func.o main.o
gcc -o hello.exe func.o main.o
func.o : func.c
gcc -o func.o -c func.c
main.o : main.c
gcc -o main.o -c main.c
clean :
del *o hello.exe
注意:main.c和func.c参加专题第2篇文章《编译链接专题第2篇-初识makefile结构》
build目录下只有源文件(没有.o中间文件和.exe可执行文件)的时候,执行make,然后再执行make clean.
make: 生成.o和.exe文件
make clean: 删除.o和.exe文件
如果我们这样操作:build目录下只有源文件(没有.o中间文件和.exe可执行文件)的时候,执行make,然后创建一个clean的文件,然后再执行make clean
make: 生成.o和.exe文件
new-item clean: 创建一个名为clean的文件
make clean: 想要删除.o和.exe文件,make提示clean是最新的,所以clean之下的命令就不需要执行了。
这不是我们期望的结果,我们希望无论何时make clean都要删除.o和最终的.exe文件;make为啥有这种行为了?--因为在默认的情况下make认为自己是处理文件的,makefile里的每一个目标都应该对应着一个具体的文件,这个时候clean这个目标确实的对应了一个文件,所以说当make clean的时候,make程序发现clean文件时最新的,那就没有必要去执行del *.o hello.exe命令了。
那么该如何解决这个问题了?
makefile中的伪目标
-- 通过.PHONY关键字声明一个伪目标
-- 伪目标不对应任何实际的文件
-- 不管伪目标的依赖是否更新,命令总是执行
伪目标的语法:先声明,后使用
本质:伪目标是make中特殊目标.PHONY的依赖
.PHONY : clean
clean:
Del *.o hello.out
修改makefile如下:
hello.exe all : func.o main.o
gcc -o hello.exe func.o main.o
func.o : func.c
gcc -o func.o -c func.c
main.o : main.c
gcc -o main.o -c main.c
.PHONY : clean
clean :
del *o hello.exe
在clean文件存在的情况下,执行make命令后,能按我们想要的删除所有中间文件。
Make rebuild的时候执行的就是clean和all目标下的命令,也就是先删除上一次生成的中间文件,在重新编译。
技巧:绕开.PHONY关键字定义伪目标
原理:如果规则没有命令或者依赖,并且它的目标不是一个存在的文件名,在执行此规则时,目标总是会被认为是最新的。
clean : FORCES
del *.o hello.exe
FORCE:
FORCE总是被认为是最新的,则clean就会一定被执行,就算makefile目录下有clean文件存在,也不会影响clean目标下的命令执行.
.PHONY关键字是标准make里面才有的关键字,换句话说,.PHONY关键字在GNU make里面是存在的,如果使用GNU的make,要定义伪目标则可以使用.PHONY关键字。但是如果使用的make不是标准的make,不是GNU的make,它没有.PHONY关键字,就可以使用这个技巧。
hello.exe : func.o main.o
gcc -o hello.exe func.o main.o
func.o : func.c
gcc -o func.o -c func.c
main.o : main.c
gcc -o main.o -c main.c
clean : FORCE
del *.o hello.exe
FORCE :
-- 默认情况下,make认为目标对应着一个文件。
-- .PHONY用于声明一个伪目标,伪目标不对应时机的文件。
-- 伪目标的本质是make中特殊目标.PHONY的依赖。
-- 使用伪目标可以模拟”函数调用”。
我们通过编写Build.bat脚本来删除过程文件和目录。
@echo off
REM save current directory
PUSHD .
@if "%1" == "--clean" (
echo Delete all object files and directories.
rd build /s/q
) else (
@echo start build
mkdir build
cd build
cmake -G "MinGW Makefiles" ..
make
echo end build
pause
REM restore original current directory
POPD
)
参考资料:
1.狄泰软件唐老师课程
2.专业嵌入式软件开发书籍
End
「汽车电子嵌入式在CSDN上同步推出AUTOSAR精进之路专栏,本专栏每个模块完全按实际项目中开发及维护过程来详细介绍。模块核心概念介绍、实际需求描述、实际工程配置、特殊需求介绍及背后原理、实际工程使用经验总结。目的是让读者看完每一个章节后能理解原理后根据需求完成一个模块的配置或者解决一个问题。」
点击文章最后左下角的阅读原文可以获取更多信息
或者复制如下链接到浏览器获取更多信息
https://blog.csdn.net/qq_36056498/article/details/132125693
文末福利
2.为便于技术交流,创建了汽车电子嵌入式技术交流群,可尽情探讨AP,CP,DDS,SOME/IP等前沿热点话题,后台回复“加群”即可加入;
注:本文引用了一些第三方工具和文档,若有侵权,请联系作者删除!
推荐阅读
汽车电子嵌入式精彩文章汇总第一期:20210530-20230703
汽车电子嵌入式精彩文章汇总第2期
TC3xx芯片GTM模块-CMU,CCM,TBU详解
TC3xx芯片GTM模块-TOM详解
AUTOSAR架构下PWM模块配置实践
TC3xx芯片GTM模块-TIM详解
AUTOSAR架构下ICU模块配置实践
TC3xx芯片电源管理系统PMS详解
End
欢迎点赞,关注,转发,在看,您的每一次鼓励,都是我最大的动力!
汽车电子嵌入式
微信扫描二维码,关注我的公众号