jjzjj

工具技能学习(一):前置技能-makfile、make、.mk

Hkcoco 2024-06-17 原文

工具技能学习(一):前置技能-makfile、make、.mk

在构建镜像的时候你肯定看到了很多的makefile文件,昨天我们也解读一些一些构建编译的makefile文件,但是有些兄弟没有这方面的经验,对于makefile文件的格式还是不是很熟悉。

其次make是我们编译时的关键命令,这也顺便来讲讲它和makefile的渊源。

最后如果你的内核是构建去做安卓方面的事情,这里面会有很多.mk文件,那么这个文件又是什么,下面一起来看看吧。

1、makfile、make、.mk是什么

makefile关系到了整个工程的编译规则。一个工程中的源文件不计其数,并且按类型、功能、模块分别放在若干个目录中,**makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,**甚至于进行更复杂的功能操作。

所以为什么有这个东西的目的显然–>因为一个大的工程数以万计的文件,你很难去正确快速的进行手动链接编译,因此使用makefile统一管理。(比如linux内核的source code)

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令

make命令执行时,需要一个makefile文件,以告诉make命令需要怎么样的去编译和链接程序。

makefile说明make make解释makefile

那.mk是什么?.mk是一种android编译环境下的一种特殊的“makefile”文件,mk文件最终还是要被android编译系统层层解析,转化为make命令能够读懂的格式,从而调用gcc编译器进行编译,暂时在我没有对其有更深的认识之前,我也把其当做一种特殊领域的makefile文件。只不过经过android编译系统的一大堆处理,android.mk的格式就变得非常简单,且与普通的makefile文件书写格式不一样了。

(一个成熟的开发框架必然有自己的打包系统,比如C或C++项目中的make文件、Java项目中的ant工具等,NDK也有自己的打包配置文件,这些文件以mk为后缀。Android.mk文件是NDK的编译脚本,用于把C或C++代码编译成so文件。)

(Android NDK的全称是Android Native Development Kit,顾名思义,就是原生代码调用,实际上就是允许Java程序通过JNI调用C或C++的动态链接库(so文件)。)

下面分为三个部分来讲讲具体的使用,如果你的嵌入式系统不是按安卓,可能其实你不需要看这个.mk,但是作为搞技术的,多学点没毛病的哦。

2、makefile文件

原文链接

想要书写一个完整的 Makefile文件,需要了解 Makefile 的相关的书写规则。我们已经知道了 Makefile 描述的是文件编译的相关规则,它的规则主要是两个部分组成,分别是依赖的关系和执行的命令,其结构如下所示:

targets : prerequisites
    command

或者是

targets : prerequisites; command
    command

相关说明如下:

  • targets:规则的目标,可以是 Object File(一般称它为中间文件),也可以是可执行文件,还可以是一个标

  • prerequisites:是我们的依赖文件,要生成 targets 需要的文件或者是目标。可以是多个,也可以是没有;

  • command:make 需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。

注意:我们的目标和依赖文件之间要使用冒号分隔开,命令的开始一定要使用Tab键。

通过下面的例子来具体使用一下 Makefile 的规则,Makefile文件中添代码如下:

test:test.c
    gcc -o test test.c

上述代码实现的功能就是编译 test.c 文件,通过这个实例可以详细的说明 Makefile 的具体的使用。其中 test 是的目标文件,也是我们的最终生成的可执行文件。依赖文件就是 test.c 源文件,重建目标文件需要执行的操作是gcc -o test test.c。这就是 Makefile 的基本的语法规则的使用。

使用 Makefile 的方式:首先需要编写好 Makefile 文件,然后在 shell 中执行 make 命令,程序就会自动执行,得到最终的目标文件。

通过上面的例子我们可以了解到,Makefile 的规则很简单,但这并不是 Makefile 的全部,这个仅仅是它的冰山一角。仅仅靠一个规则满足不了我们对于大的工程项目的编译。甚至几个文件的编译都会出现问题,所以要学习的东西还有很多。

简单的概括一下Makefile 中的内容,它主要包含有五个部分,分别是:
1) 显式规则
显式规则说明了,如何生成一个或多的的目标文件。这是由 Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

2) 隐晦规则
由于我们的 make 命名有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 Makefile,这是由 make 命令所支持的。

3) 变量的定义
在 Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点像C语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。

4) 文件指示
其包括了三个部分,一个是在一个 Makefile 中引用另一个 Makefile,就像C语言中的 include 一样;另一个是指根据某些情况指定 Makefile 中的有效部分,就像C语言中的预编译 #if 一样;还有就是定义一个多行的命令。

5) 注释
**Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用“#”字符,**这个就像 C/C++ 中的“//”一样。如果你要在你的 Makefile 中使用“#”字符,可以用反斜框进行转义,如:“#”。

内容真的还是蛮丰富的,很多前辈已经给出了很好的教程,就不再重复了

推荐学习资料:阮一峰老师的教你怎么写makefile

					      [跟我一起写 Makefile](https://blog.csdn.net/haoel/article/details/2886)

3、make命令

make只是一个根据指定的Shell命令进行构建的工具。它的规则很简单,你规定要构建哪个文件、它依赖哪些源文件,当那些文件有变动时,如何重新构建它。

1、可以简单的使用make或者在make命令后带上目标all

2、通过 -B 选项让所有目标总是重新建立

3、使用 -d 选项打印调试信息

4、使用 -C 选项改变目录

5、通过 -f 选项将其它文件看作 Makefile

原文链接

对于工具的学习我都是希望能看到简单的东西,大致有个认识,对于复杂可以在实际使用的时候去慢慢熟悉,当然每个人适合的不一样,just follow your heart.

4、.mk文件格式

(1)LOCAL_PATH:=$(call my-dir)

LOCAL_PATH是每个Android.mk文件都必须定义的,用于指定项目的根目录,编译器会在此目录树中查找代码源文件。另外,“call my-dir”语句返回的是当前目录路径。

(2)include$(CLEAR_VARS)

include语法用于包含外部库(C Library),CLEAR_VARS由编译系统提供,对应的GNU Makefile脚本会为我们清除LOCAL_PATH以外的所有以LOCAL_为前缀的变量,如LOCAL_MODULE、LOCAL_SRC_FILES、LOCAL_STATIC_LIBRARIES等。

这是必要的,因为所有的编译控制文件都在同一个GNU Make环境中。

(3)LOCAL_MODULE:=hello-jni

LOCAL_MODULE也是必须定义的,用于标识C工程中的各个模块,最终的链接库文件的名称也与此值有关,比如这里生成的so文件名就是libhello-jni.so。另外,LOCAL_MODULE值必须是唯一的,且不能含有空格。

(4)LOCAL_SRC_FILES:=hello-jni.c

LOCAL_SRC_FILES用于指定C工程的源代码文件,当然如果包含多个文件可以使用“\”符号进行换行。这里不需要包含头文件,系统会自动为我们准备好。另外,如果要使用不同的C++文件名,可以通过配置LOCAL_DEFAULT_CPP_EXTENSION参数来指定。

(5)include$(BUILD_SHARED_LIBRARY)

BUILD_SHARED_LIBRARY也由编译系统提供,对应的GNU Makefile脚本会为我们收集所有以LOCAL_为前缀的变量,这可以让C工程的类库和代码更加清晰,而我们也可以通过配置参数BUILD_STATIC_LIBRARY来生成静态库。比如,使用“include$(BUILD_STATIC_LIBRARY)”就将生成以.a为后缀的静态库。

当然,除了前面介绍的常用系统变量,如CLEAR_VARS、BUILD_SHARED_LIBRARY以及BUILD_STATIC_LIBRARY之外,Android.mk文件还支持以下变量。

  • TARGET_ARCH:用于指定CPU类型,常见的值有arm和x86。

  • TARGET_PLATFORM:用于指定Android平台的版本。

  • TARGET_ARCH_ABI:用于指定CPU+ABI的类型,比如armeabi就代表Armv5TE的指令集架构。虽然目前支持的类型只有两种,但是在未来的NDK版本中可能会出现更多的选择。

然后,再来看看除了常用的模块描述变量,如LOCAL_PATH、LOCAL_MODULE、LOCAL_SRC_FILES以及LOCAL_CPP_EXTENSION之外,Android.mk文件还支持的变量。

  • LOCAL_C_INCLUDES:可选项,表示C或C++头文件的搜索路径,一般是项目目录的相对路径。·

  • LOCAL_CFLAGS:可选的编译选项,在编译C代码时使用,在使用附加包或者宏定义的时候比较有用,比如LOCAL_CFLAGS:=-DHHH等价于头文件中的#define HHH。·

  • LOCAL_CXXFLAGS:同LOCAL_CFLAGS,只不过针对的是C++代码。·

  • LOCAL_CPPFLAGS:同LOCAL_CFLAGS,对C或者C++代码都适用。·

  • LOCAL_STATIC_LIBRARIES:表示模块编译时需要用到的静态库。·

  • LOCAL_SHARED_LIBRARIES:表示模块编译时需要用到的共享库(动态库)。·

  • LOCAL_LDLIBS:编译时需要使用的链接器选项,比如-lz就代表需要链接到libz.so库。

最后,再来学习一下Android.mk文件中可用的宏定义。·

  • my-dir:返回当前目录。·

  • all-subdir-makefiles:返回所有子目录的Android.mk文件的路径列表。·

  • this-makefile:返回当前Android.mk文件的路径。·

  • parent-makefile:返回调用数中父级的Android.mk文件路径。

  • APP_PROJECT_PATH:用于给出应用程序工程的根目录的一个绝对路径。·

  • APP_MODULES:用于列出应用所需的所有模块,如果没有定义,NDK将会对Android.mk中声明的默认模块进行编译。

  • APP_OPTIM:可选模式有release或debug两种,分别表示编译的应用是发布版还是调试版的。如果是发布版(release模式),编译器会生成更加优化的二进制文件,利于运行;而调试版(debug模式)则更利于调试。·

  • APP_CFLAGS:功能同Android.mk的LOCAL_CFLAGS。·

  • APP_CXXFLAGS:功能同Android.mk的LOCAL_CXXFLAGS。·

  • APP_CPPFLAGS:功能同Android.mk的LOCAL_CPPFLAGS。·

  • APP_BUILD_SCRIPT:指定编译脚本,默认情况下NDK编译器会在项目的jni目录下寻找名为Android.mk的文件。·

  • APP_ABI:选择指令集,可选项包括armeabi、armeabi-v7a以及x86。

以上就是对于这个部分的理解,大家对于工具的学习我建议是建立在需求之上的,不然来的也快,忘得也超级快的。

有关工具技能学习(一):前置技能-makfile、make、.mk的更多相关文章

  1. ruby-on-rails - rails : How to make a form post to another controller action - 2

    我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak

  2. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  3. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  6. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  7. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  8. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  9. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  10. ruby - 无法安装 gem - make 未被识别为内部或外部命令可运行程序或批处理文件 - 2

    我想在Windows7上安装带有ruby​​1.9.3的rspec-railsgem。我收到一些错误消息,提示无法安装某些json库。所以,我使用下面的说明来解决它。来源=The'json'nativegemrequiresinstalledbuildtools从[rubyinstaller.org][3]下载[Ruby1.9.3][2]从[rubyinstaller.org][3]下载DevKit文件对于Ruby1.9.3,使用[DevKit-tdm-32-4.5.2-20110712-1620-sfx.exe][4]将DevKit解压到路径C:\Ruby193\DevKit运行cd

随机推荐