C++项目的Makefile编写
make makefile 的参数

make makefile 的参数make是一个常用的构建工具,用于自动化编译和构建软件项目。
makefile是make工具的配置文件,用于描述项目的构建规则和依赖关系。
本文将介绍makefile的参数,包括常用的参数及其用法。
一、常用参数及其用法1. -f 文件名:指定makefile的文件名,默认为"makefile"或"Makefile"。
通过该参数,可以使用其他名称的makefile文件。
2. -C 目录:指定make命令的工作目录。
在执行make命令时,会切换到指定的目录,并在该目录下查找makefile文件进行构建。
3. -n:显示执行make命令时的操作,但不实际执行。
通过该参数,可以预览make命令的执行过程,检查构建规则是否正确。
4. -p:显示make命令的内置变量和规则。
通过该参数,可以查看make命令的内部工作机制,了解makefile文件的编写规则和使用方法。
5. -B:强制重新构建目标文件。
通过该参数,可以忽略文件的时间戳,强制重新执行构建规则,生成新的目标文件。
6. -j 并发数:指定make命令的并发执行数。
通过该参数,可以提高构建速度,同时执行多个任务。
7. -s:静默模式,不显示执行的命令。
通过该参数,可以减少输出信息,使构建过程更加清晰。
二、makefile的构建规则makefile由一系列构建规则组成,每个规则定义了目标文件、依赖文件和构建命令。
make命令根据构建规则,自动判断需要更新的文件,并执行相应的构建命令。
构建规则的基本格式如下:目标文件: 依赖文件构建命令其中,目标文件是要生成的文件,依赖文件是目标文件依赖的文件,构建命令是生成目标文件的命令。
构建规则中的目标文件和依赖文件可以是文件名,也可以是变量。
通过使用变量,可以提高makefile的可维护性和灵活性。
构建命令可以是任意的Shell命令,包括编译、链接、拷贝等操作。
c语言makefile编写实例

c语言makefile编写实例Makefile是用来管理程序编译的工具,可以方便地管理程序的编译过程。
使用Makefile可以大大简化程序的编译过程,提高程序的可维护性。
Makefile的语法比较简单,主要由目标、依赖和命令三部分组成。
下面我们以一个简单的C程序为例,来介绍如何使用Makefile进行编译。
假设我们有一个名为hello.c的程序,代码如下:```c#include <stdio.h>int main(){printf("Hello, world!\n");return 0;}```我们需要使用gcc编译器将其编译成可执行文件。
下面是一个简单的Makefile:```makefilehello: hello.cgcc -o hello hello.c```这个Makefile很简单,它定义了一个名为hello的目标,该目标依赖于hello.c文件,并使用gcc命令将其编译成可执行文件。
如果我们在终端中输入make命令,Makefile会自动执行编译过程:```$ makegcc -o hello hello.c```Makefile还可以定义多个目标,每个目标可以有多个依赖和多个命令。
下面是一个稍微复杂一些的Makefile:```makefileCC=gccCFLAGS=-Wall -gall: hello goodbyehello: hello.o$(CC) $(CFLAGS) -o hello hello.ogoodbye: goodbye.o$(CC) $(CFLAGS) -o goodbye goodbye.ohello.o: hello.c$(CC) $(CFLAGS) -c hello.cgoodbye.o: goodbye.c$(CC) $(CFLAGS) -c goodbye.cclean:rm -f *.o hello goodbye```这个Makefile定义了两个目标:all和clean。
交叉编译makefile编写

交叉编译makefile编写交叉编译Makefile编写在软件开发中,我们通常会遇到需要在不同平台上编译程序的情况。
当我们需要在一台主机上编译运行另一种架构的程序时,就需要进行交叉编译。
而Makefile作为一种构建工具,可以帮助我们自动化编译过程,提高开发效率。
本文将介绍如何编写适用于交叉编译的Makefile,以实现在不同平台上的程序构建。
一、了解交叉编译概念交叉编译是指在一台主机上编译生成另一种架构的可执行文件。
通常情况下,我们在本机上编写并编译程序,然后在本机上运行。
但是,当我们需要在不同的平台上运行程序时,由于不同平台的指令集、库文件等差异,我们就需要使用交叉编译来生成适用于目标平台的可执行文件。
二、Makefile的基本结构Makefile是一种用于描述程序构建过程的文件,它包含了一系列规则(rules),每个规则由一个或多个目标(target)和依赖项(dependencies)组成。
当某个目标的依赖项发生变化时,Make工具会根据规则自动更新目标文件。
一个基本的Makefile结构如下所示:```target: dependenciescommand```其中,target表示目标文件,dependencies表示目标文件的依赖项,command表示生成目标文件的命令。
三、交叉编译的Makefile编写在编写交叉编译的Makefile之前,我们需要了解目标平台的相关信息,如架构、编译器、库文件等。
以ARM架构为例,我们可以使用arm-linux-gnueabi-gcc作为交叉编译器。
我们需要定义一些变量,用于指定交叉编译工具链和相关参数:```CC = arm-linux-gnueabi-gccCFLAGS = -Wall -O2```其中,CC表示编译器,CFLAGS表示编译参数。
接下来,我们可以定义目标文件和依赖项:```TARGET = myprogramSRCS = main.c foo.c bar.cOBJS = $(SRCS:.c=.o)```其中,TARGET表示目标文件,SRCS表示源文件列表,OBJS表示目标文件列表。
makefile编写规则

makefile编写规则⼀、makefile 规则:⼀般开头都是 Tab ,不能空格, include 前⾯不能是 Tab; 1、如果没编译过,将所有的(.c)⽂件编译并且链接; 2、如果有其中的(.c)⽂件改变,编译并链接改变的⽂件; 3、如果(.h)⽂件被修改,编译引⽤相应的(.c)⽂件, 链接; 4、在随意修改时间的情况下,会导致编译过程中⽣成的(.o 中间⽂件)与可执⾏⽂件时间不⼀致,此时会编译相应的⽂件,并链接,最终编译成可执⾏⽂件;⼆、第⼀版 makefile: 例如有2个 .h ⽂件(utils.h, player.h, actor.h)和 3个 .c ⽂件( main.c, player.c, actor.c)需要编译链接:/*****main.c*********/#include "utils.h"#include "player.h"void main() {// do something}/*******player.c**********/#include "utils.h"#include "actor.h"bool create_player() {// do something}/****actor.c************/#include "utils.h"bool create_actor() {// do something}/********* makefile *****************/test : main.o actor.occ -o test main.o actor.omain.o : main.c utils.h player.h actor.hcc -c main.cpalyer.o: player.c player.h actor.h utils.hcc -c player.cactor.o: actor.h utils.hcc -c actor.cclean:rm test ain.o player.o actor.o 优点:可毒性很强,思路清晰明了; 缺点:⿇烦,重复的依赖过多,当需要编译⼤量⽂件时容易出错;第⼆版:利⽤ makefile 的变量;/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉main.o : main.c utils.h player.h actor.hcc -c main.cpalyer.o: player.c player.h actor.h utils.hcc -c player.cactor.o: actor.h utils.hcc -c actor.c .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ) // 前⾯的(-)表⽰,执⾏过程中不 care 出错;第三版:利⽤ GUN make 的⾃动推导规则 当 make 看到(.o )⽂件,他会⾃动把(.c)⽂件加上依赖关系,包括执⾏的语句(cc -c xx.c);/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉main.o : utils.h player.h actor.hpalyer.o: player.h actor.h utils.hactor.o: actor.h utils.h .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ)第四版:对第三版的整理(有⼀些重复的 .h) 公共的⼀起依赖,单独的单独依赖/********* makefile *****************/OBJ = main.o actor.o // 跟第⼀版⽐较,唯⼀的区别在这test : $(OBJ) // 这⼉cc -o test $(OBJ) // 这⼉$(OBJ) : utils.h actor.omain.o player.o .PHONY : clean // 伪⽬标,避免:如果当前⽬录下存在 clean rm 指令不执⾏clean:-rm test $(OBJ)优点:简洁缺点:不好理解以上的makefike⽂件的基本写法;或许你也发现了,如果有⼏百个源⽂件咋整呢,光是⽬录就要晕死,下⾯就是针对这种情况来说⼀下⼤型⼯程 makefile 的编写设计⼆、⼤型项⽬makefile编写: Makefile 同样也有像 c / c++ 类似的include功能; 例如我们有⼀堆 a.mk , b.mk以及 foo.make和⼀个变量 $(bar),其包含了 e.mk,f.mk, 那么 include foo.make *.mk $(bar) ------- 等价-------》 include foo.make a.mk b.mk e.mk f.mk。
c语言 makefile例题

一、概述在计算机编程领域,C语言是一种广泛应用的高级编程语言,而Makefile作为一种构建工具,在C语言项目中也扮演着重要的角色。
本文将介绍C语言和Makefile的基本概念,并通过例题的方式,展示C语言项目如何使用Makefile进行编译和构建。
二、C语言基本概念1. C语言的起源与发展C语言由贝尔实验室的Dennis Ritchie在20世纪70年代初开发,它基于B语言,并对B语言进行了扩展和改进。
C语言的出现极大地推动了系统软件开发的进程,成为了Unix操作系统的编程语言,也为后来的C++和Java等语言的发展奠定了基础。
2. C语言的特点C语言是一种中级编程语言,它结合了高级语言和汇编语言的特点。
C 语言具有良好的可移植性、高效性和灵活性,可以直接访问计算机硬件,也支持结构化编程和面向对象编程。
3. C语言的基本语法C语言的基本语法包括变量、运算符、流程控制语句和函数等。
C语言程序的执行从main函数开始,通过调用其他函数实现具体的功能。
三、Makefile基本概念1. Makefile的作用Makefile是一种构建工具,它用于管理C语言项目的编译和构建过程。
通过Makefile,我们可以定义编译规则、目标文件和依赖关系,实现对C语言程序的自动化构建。
2. Makefile的语法Makefile由一系列规则和命令组成。
每个规则包括目标、依赖和命令三部分,用于描述源文件、目标文件和编译命令之间的关系。
3. Makefile的基本命令在Makefile中,常用的命令包括赋值、目标定义、依赖规则和命令等。
通过这些命令,我们可以定义C语言项目的编译规则和构建方案。
四、例题分析考虑一个简单的C语言项目,包括两个源文件main.c和util.c,以及一个头文件util.h。
我们需要编写Makefile来管理项目的编译和构建过程。
1. 创建Makefile文件我们首先创建一个名为Makefile的文件,用于定义C语言项目的编译规则和构建方案。
makefile引用标准c函数

一、概述在软件开发过程中,为了提高代码的可维护性和可移植性,通常会使用Makefile来管理代码的编译和信息过程。
而在C语言的开发中,经常会用到标准C库中的各种函数。
本文将讨论如何在Makefile中引用标准C函数,以及一些注意事项和最佳实践。
二、Makefile中的规则Makefile是用来描述软件项目中文件之间的依赖关系的文件。
它包含了一系列规则,每个规则包含了一个目标文件、依赖文件和生成目标文件的命令。
当执行make命令时,Makefile会根据规则自动执行对应的命令,从而生成目标文件。
三、引用标准C函数1. 在Makefile中引用标准C函数需要首先确保C标准库的头文件被正确包含。
在C语言中,通过#include指令可以将标准C库的头文件包含到源文件中。
2. 在Makefile中,我们可以使用变量来定义编译器、编译选项和信息选项。
我们可以定义CC变量来指定C语言的编译器,CFLAGS变量来指定编译选项,LDFLAGS变量来指定信息选项。
3. 当我们需要在Makefile中引用标准C函数时,我们只需要在对应的规则中使用变量来指定编译选项和信息选项。
如果我们需要使用标准C函数printf,我们只需要在对应的规则中将需要用到的标准库信息到目标文件中。
四、注意事项和最佳实践1. 在Makefile中引用标准C函数时,我们需要确保编译时能找到对应的标准C库文件。
通常情况下,标准C库文件会在系统的标准库目录下,我们需要将这些目录添加到信息选项中。
2. 在Makefile中引用标准C函数时,我们需要确保编译器能找到对应的标准C库头文件,通常情况下,标准C库头文件会在系统的标准头文件目录下,我们需要将这些目录添加到编译选项中。
3. 在Makefile中引用标准C函数时,我们需要确保编译器能正确识别和处理对应的标准C函数的参数和返回值类型。
通常情况下,标准C函数的参数和返回值类型会在对应的头文件中定义,我们需要确保这些定义被正确包含到源文件中。
clion makefile编译

clion makefile编译使用CLion进行Makefile编译是一种方便且高效的方式,它可以帮助开发者轻松管理和构建复杂的项目。
CLion是一款功能强大的集成开发环境,专为C和C++开发而设计,它提供了许多有用的功能,包括代码编辑、调试和版本控制等。
我们需要在CLion中创建一个新的项目。
选择“File”->“New Project”菜单,然后选择“C Executable”或“C++ Executable”项目类型。
接下来,我们需要设置项目的名称和位置,并选择所需的编译器。
一旦项目创建完成,我们可以在CLion的项目窗口中看到项目的结构。
在项目窗口中,我们可以添加源文件、头文件和其他资源文件。
只需右键单击项目文件夹,选择“New”菜单,然后选择“C/C++ Source File”或“Header File”选项。
完成了源文件和头文件的添加后,我们可以开始编写Makefile。
Makefile是一个文本文件,用于指定如何构建项目。
它包含了一系列规则,每个规则指定了一个目标文件以及生成该目标文件所需的源文件和依赖文件。
下面是一个简单的Makefile示例:```CC = gccCFLAGS = -Wall -gSRC = main.c foo.c bar.cOBJ = $(SRC:.c=.o)TARGET = myprogram$(TARGET): $(OBJ)$(CC) $(CFLAGS) -o $@ $^%.o: %.c$(CC) $(CFLAGS) -c $< -o $@.PHONY: cleanclean:rm -f $(OBJ) $(TARGET)```在这个示例中,我们首先定义了编译器和编译选项的变量。
然后,我们定义了源文件、目标文件和最终生成的可执行文件的变量。
接下来,我们定义了一个规则来生成目标文件。
这个规则使用通配符来匹配所有的源文件,并使用编译器将它们编译成目标文件。
makefile中make指令传入的参数

makefile中make指令传入的参数(实用版)目录1.Makefile 简介2.Make 指令的作用3.Make 指令传入的参数4.示例与实践正文1.Makefile 简介Makefile 是一种构建脚本,用于自动化构建和编译软件项目。
它通常包含一系列的规则和指令,可以自动地执行编译、链接和安装等任务。
Makefile 最早用于 Unix 系统,现在已广泛应用于各种操作系统和编程语言。
2.Make 指令的作用在 Makefile 中,Make 指令是最核心的命令。
它可以自动地执行一系列的编译、链接和安装等任务,以构建软件项目。
Make 指令的工作原理是基于依赖关系,它可以自动地发现源文件和目标文件之间的依赖关系,并按照一定的顺序执行相应的操作。
3.Make 指令传入的参数Make 指令传入的参数主要有以下几种:(1)目标:指定要构建的目标文件,通常是可执行文件或库文件。
(2)源文件:指定构成目标文件的源文件,可以是 C、C++等源代码文件。
(3)编译器:指定用于编译源文件的编译器,例如 gcc、g++等。
(4)链接器:指定用于链接目标文件和库文件的链接器,例如 ld、ld.so 等。
(5)其他选项:还可以指定其他选项,例如优化级别、输出文件名等。
4.示例与实践下面是一个简单的 Makefile 示例,用于编译一个 C 语言程序:```CC = gccCFLAGS = -Wall -o2SOURCES = main.cOBJECTS = main.oTARGET = mainall: $(TARGET)$(TARGET): $(OBJECTS)t$(CC) $(CFLAGS) $^ -o $@$(OBJECTS): $(SOURCES)t$(CC) $(CFLAGS) -c $< -o $@```在这个示例中,我们指定了编译器(CC)、优化选项(CFLAGS)、源文件(SOURCES)、目标文件(TARGET)和依赖关系(all: $(TARGET))。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一个C++项目的Makefile编写-Tony与Alex的对话系列- -Tony : Hey Alex, How are you doing?Alex : 不怎么样。
(显得很消沉的样子)Tony : Oh , Really ? What is the matter?Alex : 事情是这样的。
最近有一个Unix下的C++项目要求我独自完成,以前都是跟着别人做,现在让自己独立完成,还真是不知道该怎么办,就连一个最简单的项目的Makefile都搞不定。
昨晚看了一晚上资料也没有什么头绪。
唉!!Tony : 别急,我曾经有一段时间研究过一些关于Makefile的东西,也许能帮得上忙,来,我们一起来设计这个项目的Makefile。
Alex : So it is a deal。
(一言为定)Tony : 我们现在就开始吧,给我拿把椅子过来。
(Tony坐在Alex电脑的旁边)Tony : 把你的项目情况大概给我讲讲吧。
Alex : No Problem ! 这是一个“半成品”项目,也就是说我将提供一个开发框架供应用开发人员使用,一个类似MFC的东西。
Tony : 继续。
Alex : 我现在头脑中的项目目录结构是这样的:APL (Alex's Programming Library)-Make.properties-Makefile(1)-include //存放头文件-Module1_1.h-Module1_2.h-Module2_1.h-Module2_2.h-src //存放源文件-Makefile(2)-module1-Module1_1.cpp-Module1_2.cpp-Makefile(3)-module2-Module2_1.cpp-Module2_2.cpp-Makefile(3)-...-lib //存放该Project依赖的库文件,型如libxxx.a-dist //存放该Project编译连接后的库文件libapl.a-examples //存放使用该“半成品”搭建的例子应用的源程序Makefile(4)-src //存放应用源代码-include-bin //存放应用可执行程序-appdemo2-Makefile(5)-src //存放应用源代码-include-bin //存放应用可执行程序-...Tony : I got it!Alex : 下面我们该如何做呢?Tony : 我们来分析一下各个Makefile的作用。
你来分析一下各个级别目录下的Makefile的作用是什么呢?Alex : (思考了一会儿)我想应该是这样的吧。
Makefile(3)负责将其module下的.cpp源文件编译为同名.o文件,同时其phony target "clean"负责删除该目录下的所有.o文件;Makefile(2)负责调用src目录下所有module的Makefile文件。
Makefile(1)负责先调用src中的Makefile生成静态库文件,然后调用examples中的Makefile构建基于该框架的应用。
至于Make.properties,定义通用的目录信息变量、编译器参数变量和通用的依赖关系。
Tony : 说得很好。
我们一点一点来,先从src中每个module下的Makefile着手,就如你所说在每个module下的Makefile负责将该module下的.cpp文件编译为同名的.o文件。
Alex : 好的,我来写吧,这个我还是能搞定的。
看下面:module1下的Makefile如下:## Makefile for module1#all : Module1_1.o Module1_2.oModule1_1.o : Module1_1.cppg++ -c $^ -I ../../includeModule1_2.o : Module1_2.cppg++ -c $^ -I ../../includeclean :rm -f *.omodule2下的Makefile如下:## Makefile for module2#all : Module2_1.o Module2_2.og++ -c $^ -I ../../includeModule2_2.o : Module2_2.cppg++ -c $^ -I ../../includeclean :rm -f *.omake一下,顺利产生相应的.o文件。
/*=============================================================Note: 关于$^、$<和$@的用法说明:$@ -- “$@”表示目标的集合,就像一个数组,“$@”依次取出目标,并执于命令。
$^ -- 所有的依赖目标的集合。
以空格分隔。
如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
$< -- 依赖目标中的第一个目标名字举例: Module1_1.o Module1_2.o : Module1_1.cpp Module1_2.cpp则$@ -- Module1_1.o Module1_2.o$^ -- Module1_1.cpp Module1_2.cpp$< -- Module1_1.cpp==============================================================*/Tony : Well done! 不过发现什么问题了么?Alex : 什么问题?Tony : 存在重复的东西。
在重构中我们知道如果两个子类中都定义相同的接口函数,我们会将其pull up到基类中。
同样我们可以重构我们的Makefile,把一些重复的东西拿到外层去。
Alex : (似乎略微明白了一些)我想有三处重复:a)查找头文件的路径是重复的; b)g++这个字符串可以用一个变量定义代替c)编译器的编译参数可以也定义到一个变量中。
我知道Make工具支持include一个文件,我们就建立一个公用的文件来存放一些通用的东西吧。
Tony : 没错,Just do it.Alex : 就按我原先的想法,把这些公共的部分放到Make.properties中吧。
## Properties for demo's Makefile#MAKEFILE = MakefileBASEDIR = $(HOME)/proj/demo##################### Directory layout #####################SRCDIR = $(BASEDIR)/srcINCLUDEDIR = $(BASEDIR)/includeLIBDIR = $(BASEDIRE)/lib##################### Compiler options ## F_ -- FLAG #####################CC = g++# Compiler search optionsF_INCLUDE = -I$(INCLUDEDIR)F_LIB = -L $(LIBDIR)CFLAGS =CPPFLAGS = $(CFLAGS) $(F_INCLUDE)然后修改一下,各个module中的Makefile文件,以module1为例,修改后如下:## Makefile for module1#include ../../Make.propertiesall : Module1_1.o Module1_2.oModule1_1.o : Module1_1.cpp$(CC) -c $^ $(CPPFLAGS)Module1_2.o : Module1_2.cpp$(CC) -c $^ $(CPPFLAGS)clean :rm -f *.oTony : 其实这两个Makefile中还有一个隐含的重复的地方Alex : 你是指依赖规则么?Tony : 嗯,这个依赖规则在src中的各个module中都会用得到的。
Alex : 没错,我也是这么想的,我现在就把这个规则抽取出来,然后你来评审一下。
我想利用make 工具的传统的“后缀规则”来定义通用依赖规则,我在Make.properties加入下面的变量定义:##################### Common depends #####################DEPS = .cpp.o然后还是以module1为例,修改module1的Makefile后如下:## Makefile for module1#include ../../Make.properties$(CC) -c $^ $(CPPFLAGS)clean :rm -f *.oTony : 基本满足需求。
我们可以进行上一个层次的Makefile的设计了。
我们来设计Makefile(2)。
Alex,你来回顾一下Makefile(2)的作用。
/*=============================================================Note: 关于后缀规则的说明后缀规则中所定义的后缀应该是make 所认识的,如果一个后缀是make 所认识的,那么这个规则就是单后缀规则,而如果两个连在一起的后缀都被make 所认识,那就是双后缀规则。
例如:".c"和".o"都是make 所知道。
因而,如果你定义了一个规则是".c.o"那么其就是双后缀规则,意义就是".c"是源文件的后缀,".o"是目标文件的后缀, ".c.o"意为利用.c 文件构造同名.o文件。
==============================================================*/Alex : No Problem! 正如前面说过的Makefile(2)负责调用src目录下所有module子目录下的Makefile 文件,并负责将各个module下的.o文件打包为libdemo.a文件放到dist目录中。
所以存在简单的依赖关系就是libdemo.a依赖各个module子目录下的.o文件,而前面的Makefile(3)已经帮我们解决了.o 文件的生成问题了,即我们只需要逐个在各module子目录下make即可。
我的Makefile(2)文件设计如下:## Makefile for src directory#include ../Make.propertiesTARGET = libdemo.a##################### Subdirs define #####################MODULE1_PA TH = module1MODULE2_PA TH = module2SUBDIRS = $(MODULE1_PA TH) $(MODULE2_PA TH)##################### Objects define #####################MODULE1_OBJS = $(MODULE1_PA TH)/Module1_1.o $(MODULE1_PA TH)/Module1_2.oMODULE2_OBJS = $(MODULE2_PA TH)/Module2_1.o $(MODULE2_PA TH)/Module2_2.oDEMO_OBJS = $(MODULE1_OBJS) $(MODULE2_OBJS)all : subdirs $(TARGET)@for i in $(SUBDIRS); do \echo "===>$$i"; \(cd $$i &&$(MAKE) -f $(MAKEFILE)) || exit 1; \echo "<===$$i"; \done$(TARGET) : $(DEMO_OBJS)ar -r $@ $^clean:@for i in $(SUBDIRS); do \echo "===>$$i"; \(cd $$i &&$(MAKE) clean -f $(MAKEFILE)) || exit 1; \echo "<===$$i"; \donerm -f $(DISTDIR)/$(TARGET)Tony : Alex你的进步真的是很大,分析问题的能力提高的很快,方法也不错。