1.makefile的作用是什么?

本文详细介绍了Makefile的概念及其在软件工程中的应用。Makefile用于自动化编译过程,通过定义编译规则,实现源文件的高效管理和编译。文章还探讨了Makefile的工作原理,包括依赖性的解析和命令的执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MakeFile文件是什么?它里面包含什么内容、具有什么作用、怎么使用?下面就来具体说说。

     什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和 professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解 HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完 成大型工程的能力。
     因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系 列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell 脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是 一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

一、什么是Makefile?

   makefile文件保存了编译器和连接器的参数选项,还表述了所有源文件之间的关系(源代码文件需要的特定的包含文件,可执行文件要求包含的目标文件模块及库等).创建程序(make程序)首先读取makefile文件,然后再激活编译器,汇编器,资源编译器和连接器以便产生最后的输出,最后输出并生成的通常是可执行文件.创建程序利用内置的推理规则来激活编译器,以便通过对特定CPP文件的编译来产生特定的OBJ文件. 
附上原文: 
Experienced  programmers  are  familiar  with  makefiles.  A  makefile  stores compiler  and  linker  options  and  expresses  all  the  interrelationships  among source  files.  (A  source  code  file  needs  specific  include  files,  an executable  file  requires  certain  object  modules  and  libraries,  and  so  forth.)  A  make  program  reads  the  makefile  and  then  invokes  the  compiler, assembler,  resource  compiler,  and  linker  to  produce  the  final  output,  which is  generally  an  executable  file.  The  make  program  uses  built-in  inference rules  that  tell  it,  for  example,  to  invoke  the  compiler  to  generate  an OBJ  file  from  a  specified  CPP  file.

二、Make是如何工作的?

在默认的方式下,也就是我们只输入make命令。那么,

1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。

3、如果edit文件不存在,或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。

4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)

5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生成make的终极任务,也就是执行文件edit了。

   这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

   通过上述分析,我们知道,像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

   于是在我们编程中,如果这个工程已被编译过了,当我们修改了其中一个源文件,比如file.c,那么根据我们的依赖性,我们的目标file.o会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o的文件也是最新的啦,于是file.o的文件修改时间要比edit要新,所以 edit也会被重新链接了(详见edit目标文件后定义的命令)。

   而如果我们改变了“command.h”,那么,kdb.o、command.o和files.o都会被重编译,并且,edit会被重链接。

三、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中的命令,必须要以[Tab]键开始。

<think>我们正在讨论Android.mk文件。根据用户的问题,用户想了解Android.mk文件的主要作用及用途。根据引用[1]和[引用2],Android.mk文件是AndroidNDK编译系统的一部分,用于描述C/C++源代码文件如何编译成共享库或可执行文件。引用[1]提到:Android.mk文件首先必须定义LOCAL_PATH变量,用于在开发树中查找源文件。引用[2]明确指出:Android.mk编译文件用来向AndroidNDK描述C/C++源代码文件。引用[3]和[4]则提供了一些具体用法,例如编译一个apk时如何设置变量,以及LOCAL_SRC_FILES变量必须包含要编译的源代码文件。因此,我们可以总结Android.mk文件的主要作用如下:1.定义模块:每个Android.mk文件描述一个模块(如一个静态库、共享库或独立可执行文件)。2.设置编译变量:如LOCAL_PATH(模块所在路径)、LOCAL_MODULE(模块名)、LOCAL_SRC_FILES(源文件列表)等。3.指定编译行为:通过包含预定义的宏(如BUILD_SHARED_LIBRARY)来指示NDK构建系统如何构建模块。下面我们按照用户的要求,用清晰的结构回答,并生成相关问题。</think>### Android.mk 文件的主要作用及用途 Android.mk 是 Android NDK(Native Development Kit)编译系统的核心配置文件,主要用于管理 C/C++ 原生代码的编译过程。其主要作用包括: 1. **定义模块编译规则** 通过声明变量(如 `LOCAL_MODULE`, `LOCAL_SRC_FILES`)描述模块属性。例如: ```makefile LOCAL_PATH := $(call my-dir) # 定义当前目录路径[^1][^3] LOCAL_MODULE := native-lib # 模块名称 LOCAL_SRC_FILES := native-lib.cpp # 指定源文件[^4] include $(BUILD_SHARED_LIBRARY) # 声明构建共享库 ``` 2. **管理多模块依赖** 支持同时编译多个静态库/共享库,并通过 `LOCAL_STATIC_LIBRARIES` 声明依赖关系。例如: ```makefile LOCAL_STATIC_LIBRARIES := lib1 lib2 # 依赖其他静态库 ``` 3. **控制编译行为** 可定制编译选项(如优化级别、ABI 过滤等): ```makefile LOCAL_CFLAGS += -O2 # 添加编译标志 LOCAL_ARM_MODE := arm # 指定ARM模式 ``` 4. **资源与权限集成** 在编译 APK 时集成 Java 代码和资源: ```makefile LOCAL_PACKAGE_NAME := MyApp # APK名称 LOCAL_SRC_FILES := $(call all-subdir-java-files) # 包含所有Java文件[^3] ``` ### 典型应用场景 - **NDK 开发**:构建 JNI 接口的底层 C/C++ 库供 Java 调用。 - **跨平台移植**:复用现有 C/C++ 代码到 Android 平台。 - **性能优化**:编译高性能算法库(如图像处理)。 - **系统定制**:为 AOSP(Android 开源项目)添加原生模块。 > **关键特性**: > - 自动处理头文件依赖,无需手动列出[^4]。 > - 通过 `include $(CLEAR_VARS)` 隔离模块配置[^3]。 > - 支持条件编译(如针对不同 ABI 架构)。 --- ### 相关问题 1. **如何在 Android.mk 中配置多平台 ABI(如 armeabi-v7a, arm64-v8a)?** 2. **Android.mk 与 CMake 有何区别?应如何选择?** 3. **Android.mk 中 `LOCAL_EXPORT_C_INCLUDES` 的作用是什么?** 4. **如何解决 Android.mk 编译时的 "undefined reference" 错误?** [^1]: Android.mk文件语法规范及使用模板。一个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。 [^2]: Android.mk编译文件是用来向Android NDK描述你的C,C++源代码文件的,这篇文档描述了它的语法。 [^3]: LOCAL_PATH := $(call my-dir) 用于返回当前路径,include $(CLEAR_VARS) 用于清除局部变量。 [^4]: LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的C或C++源代码文件。编译系统会自动处理头文件依赖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值