我们在Linux环境下开发程序,少不了要自己编写Makefile,一个稍微大一些的工程下面都会包含很多.c的源文 件。
如果我们用gcc去一个一个编译每一个源文件的话,效率会低很多,但是如果我们可以写一个Makefile,那么只需要执行一个make就OK了,这 样大大提高了开发效率。
但是Makefile的语法规则众多,而且缺乏参考资料,对于初学者来说,写起来还是有一定的难度,往往令很多人望而生畏。
下面我 们介绍一个比较通用而且简洁的Makefile,大家只要对它稍作修改就可以用在你们自己的工程里了。
现在假设我们有一个工程叫my_project,工程源码目录下面有app1.c,app2.c,app3.c以及main.c这五个源文件。我们现在需要编译出app1.o,app2.o,app3.o以及main.o,然后再把这些.o文件链接成为一个ELF格式的可执行程序叫做my_app。我们先看一个最简单的Makefile如何编写:
my_app : main.o, app1.o, app2.o, app3.o, app4.o
gcc –o my_app main.o app1.o, app2.o, app3.o, app4.o
main.o : main.c
gcc –c main.c
app1.o : app1.c
gcc –c app1.c
app2.o : app2.c
gcc –c app2.c
app3.o : app3.c
gcc –c app3.c
clean :
rm main.o app1.o, app2.o, app3.o, app4.o
这是一个傻瓜式的Makefile,不灵活,而且不具备可复制性,想象一个如果我们的工程下面有50个源文件,那岂不是要一个一个写出来。
我们的目标是写一个Makefile,只要稍作修改就可以在各个工程之间通用。
下面这个Makefile就可以满足这个要求:
- SRCS = $(wildcard *.c)
- OBJS = $(SRCS:.c = .o)
- CC = gcc
- INCLUDES = -I/×××
- LIBS = -L/×××
- CCFLAGS = -g -Wall -O0
- my_app : $(OBJS)
- $(CC) $^ -o $@ $(INCLUDES) $(LIBS)
- %.o : %.c
- $(CC) -c $< $(CCFLAGS)
- clean:
- rm *.o
- .PHONY:clean
大家看这个Makefile和前一个比起来是不是简洁很多,当然理解起来不如上一个那么直观。
实际上编写 Makefile就是为了提高我们的工作效率,而不是增加我们的工作量。
因此Makefile为我们提供了很多强大的功能,比如定义变量,使用通配符等 等。只要合理利用,就可以达到事半功倍的效果。
下面我们一条一条分析这个Makefile:
SRCS = $(wildcard *.c)
这条语句定义了一个变量SRCS,它的值就是当前面目录下面所有的以.c结尾的源文件。
OBJS = $(SRCS:.c = .o)
这里变量OBJS的值就是将SRCS里面所有.c文件编译出的.o目标文件
CC = gcc
变量CC代表我们要使用的编译器
INCLUDES = -I/×××
LIBS = -L/×××
这里指定除了编译器默认的头文件和库文件的路径之外需要额外引用的头文件路径以及库的路径(×××表示路径)。
CCFLAGS = -g -Wall -O0
CCFLAGS变量存放的是编译选项
my_app : $(OBJS)
$(CC) $^ -o $@ $(INCLUDES) $(LIBS)
my_app依赖于所有的.o文件,$^代表$(OBJS),$@代表my_app
%.o : %.c
$(CC) -c $< $(CCFLAGS)
将所有的.c源代码编译成.o目标文件,这样写是不是很省事?
clean:
rm *.o
在执行make clean之后删除所有编译过程中生成的.o文件。
.PHONY:clean
每次执行make clean时都要执行rm *.o命令
这个Makefile就具备灵活的通用性,我们只要对它稍作修改就可以用在自己的工程里面。当然Makefile还有很多强大的功能,需要我们进一步学习。
分享到:
相关推荐
### U-Boot中Makefile详解 #### 一、引言 U-Boot(Universal Boot Loader)是一个开源项目,用于各种嵌入式系统平台上的启动加载程序。它支持多种处理器架构,如ARM、PowerPC等,并且能够适应各种硬件平台的需求。...
### Linux/Unix环境下的Make和Makefile详解 #### 一、Make工具简介 在Linux或Unix环境下,Make是一个极其重要的工具,广泛应用于项目开发和软件安装过程中。它可以帮助开发者高效地管理和编译复杂的项目,尤其是当...
总结来说,这个通用 CC++ Makefile 提供了一个便捷的方式来管理 C/C++ 项目的编译过程,通过自定义变量和规则适应不同的项目结构,降低了手动构建的复杂度,提高了开发者的生产力。尽管不能保证在所有环境下都能直接...
"LINUX2.6内核makefile详解" Linux 2.6 内核 Makefile 详解是 Linux 内核开发中非常重要的一部分。Makefile 是一个脚本文件,用于描述如何编译和构建 Linux 内核。该文件是 Linux 内核开发的核心组件之一,对开发...
### Linux 2.6 内核 Makefile 详解 #### 概述 Linux 内核的构建过程由一系列复杂的 Makefile 控制,其中最为核心的是 Kbuild 体系。这一体系在 2.6 版本的内核中进行了大幅改进,以适应更复杂的功能需求和更为灵活...
### 通用Makefile详解 #### 一、引言 在软件开发过程中,特别是涉及大量C语言编程时,Makefile作为一种自动化构建工具,极大地提升了开发效率。一个精心设计的Makefile可以减少编译时间,简化构建过程,并使得项目...
### Makefile详解知识点 #### 一、Makefile概念与作用 **Makefile**是一种用于管理项目构建过程的脚本文件,主要用于自动化编译任务。它通过定义一系列规则来指定源文件之间的依赖关系以及如何编译这些文件。...
《Makefile详解》 在软件开发中,自动化构建是提高效率的关键步骤,而Makefile则是这一过程中的核心工具。本文将深入探讨Makefile的基本概念、语法特性以及在实际项目中的应用,帮助初学者快速入门。 一、Makefile...
`makefile`是一个文本文件,其中包含了构建项目的规则和指令。它是`make`工作的蓝图,定义了目标文件、依赖文件以及用于生成目标的命令。一个基本的`makefile`通常包括目标、依赖项和动作三个部分。例如: ```...
### Linux/Unix环境下的make与makefile详解 #### 一、引言 在现代软件开发过程中,自动化构建工具扮演着至关重要的角色。特别是在Linux和Unix环境下,`make` 工具成为了开发人员不可或缺的好帮手。它能够有效地帮助...
以下是一个简单的 Makefile 示例,展示了如何为一个包含 8 个 C 源文件和 3 个头文件的项目编写 Makefile。 ```makefile # 定义编译器和编译选项 CC = gcc CFLAGS = -Wall -g # 定义目标文件和依赖文件 OBJS = ...
### Makefile详解介绍 #### 一、Makefile概览及重要性 Makefile是一种用于自动化构建过程的脚本文件,在Linux/Unix系统中尤为重要。它不仅简化了项目的编译流程,还能有效地管理复杂的工程项目,提高开发效率。...
`make`是一个自动化构建工具,它根据`makefile`中的规则来编译、链接源代码,生成可执行程序。在复杂的项目中,当源文件众多且相互依赖时,手动管理编译过程会变得极其繁琐。`make`通过自动化这一过程,节省了大量的...
然而,编写一个高质量、通用性强的 Makefile 并非易事。幸运的是,借助于 automake 和 autoconf 这样的工具,我们可以更加高效地生成符合自由软件惯例的 Makefile 文件。 #### 二、Makefile 基础知识 在深入了解 ...
### makefile详解 #### 什么是makefile? makefile是一种用于自动化构建软件项目的重要脚本,尤其是在Unix和类Unix系统中广泛使用。对于Windows程序员来说,可能由于集成开发环境(IDE)如Visual Studio或Eclipse...
本文将深入分析一个通用Makefile模板的结构与功能,并探讨其在实际项目中的应用方法。 #### 二、Makefile模板详解 该模板的核心特点在于其高度的灵活性与易用性。用户只需简单地设置一些关键参数,如编译器选项、...