makefile学习笔记(多目录嵌套调用、变量使用)

http://blog.csdn.net/leexiang_han/article/details/9274229

 

学习了几天的makefile的嵌套调用编写也有一些心得,先声明,我也是初学者写文章只是为了更好的交流,也希望避免其他刚入Linux编程大门的童鞋少走弯路。以下都是经过我多次测试并跑成功的,如有偏差还请见谅与指正。

我有两个练习例子:

①先来说说第一个例子:生成一个可执行文件edit

top dir(根目录)下有源文件main.c、makefile(主)、文件夹sub1、文件夹sub2;子目录sub1里有源文件sub1.c和makefile(次1);子目录sub2里有源文件sub2.c和makefile(次2)。

main.c里有主函数,需要调用sub1.c里的排序函数(按升序排)和sub2.c里的排序函数(按降序排)。要求通过根目录下的makefile嵌套调用子目录下的makefile来编译,最后链接生成可执行文件edit。

好了,我就不贴三个源文件的C代码了,大家自己写用来测试,我就直接贴makefile的编写了。

首先是子目录sub1下的makefile:

sub1.o : sub1.c

              gcc-c sub1.c

接下来是子目录sub2下的makefile:

sub2.o : sub2.c

       gcc -csub2.c

都很简单对吧,就一条正常的编译命令,最后是根目录下的makefile:

VPATH=./sub1 ./sub2

obj=main.o sub1.o sub2.o

 

edit : $(obj)

       gcc -oedit main.o ./sub1/sub1.o ./sub2/sub2.o

 

main.o : main.c

       gcc -cmain.c

sub1.o : sub1.c

       $(MAKE) -C./sub1

sub2.o : sub2.c

       $(MAKE) -C./sub2

 

.PHONY : clean

clean :

       rm editmain.o -fr

       rm./sub1/*.o -fr

       rm./sub2/*.o -fr

 

②下面就说说我的第二个练习例子:生成两个可执行文件edit1、edit2

top dir(根目录)下有源文件lib.c、makefile(主)、文件夹main1、文件夹main2;子目录main1里有源文件main1.c和makefile(次1);子目录main2里有源文件main2.c和makefile(次2)。

main1.c和main2.c里都有主函数,需要调用lib.c里的求和函数,只是所传递的参数值不同。要求通过根目录下的makefile嵌套调用子目录下的makefile来编译,最后链接生成可执行文件edit1和edit2,最后执行edit1和edit2应该能得到两个不同的值(也就是lib.c所求得的和)。

首先是子目录main1的makefile:

main1.o : main1.c

       gcc -cmain1.c

 

接下来是子目录main2的makefile:

main2.o : main2.c

       gcc -cmain2.c

 

最后是根目录下的makefile:

VPATH = ./main1 ./main2

obj1 = main1.o lib.o

obj2 = main2.o lib.o

 

all : edit1 edit2

 

edit1 : $(obj1)

       gcc -o./main1/edit1 ./main1/main1.o lib.o

main1.o : main1.c

       $(MAKE) -C./main1

lib.o : lib.c

       gcc -clib.c

 

edit2 : $(obj2)

       gcc -o ./main2/edit2./main2/main2.o lib.o

main2.o : main2.c

       $(MAKE) -C./main2

 

.PHONY : clean

clean :

       rm *.o -fr

       rm./main1/*.o ./main1/edit1 -fr

       rm./main2/*.o ./main2/edit2 –fr

 

难道你认为这次学习就结束了吗??当然不!上面这些makefile的确能满足嵌套调用的基本需求,但是你不觉得./sub1/sub1.c,./sub2/sub.2这些路径的表达很烦琐吗?万一这是个大的工程项目,突然要往某个子目录下增加一个源文件,那么修改这些makefile还不弄死你啊,可怕的不是累而是容易遗漏某一处而导致错误,所以对于立志成为一个好的makefile的编写员的人这些还远远不够!下面就让我们来对以上的makefile进行一次改头换面吧!领略一下变量的风采!

①    第一个例子的根目录下的makefile修改如下,其余两个makefile不变:

cur-dir:=$(shell pwd)

s1=$(cur-dir)/sub1

s2=$(cur-dir)/sub2

 

obj=main.o sub1.o sub2.o

 

edit : $(obj)

       gcc -oedit main.o $(s1)/sub1.o $(s2)/sub2.o

 

main.o : main.c

       gcc -cmain.c

sub1.o : $(s1)/sub1.c

       $(MAKE) -C$(s1)

sub2.o : $(s2)/sub2.c

       $(MAKE) -C$(s2)

 

.PHONY : clean

clean :

       rm editmain.o -fr

       rm $(s1)/*.o-fr

       rm$(s2)/*.o -fr

 

②    第二个例子的根目录下的makefile修改如下,其余两个makefile不变:

cur-dir:=$(shell pwd)

s1=$(cur-dir)/main1

s2=$(cur-dir)/main2

 

obj1 = main1.o lib.o

obj2 = main2.o lib.o

 

all : edit1 edit2

 

edit1 : $(obj1)

       gcc -o$(s1)/edit1 $(s1)/main1.o lib.o

main1.o : $(s1)/main1.c

       $(MAKE) -C$(s1)

lib.o : lib.c

       gcc -clib.c

 

edit2 : $(obj2)

       gcc -o$(s2)/edit2 $(s2)/main2.o lib.o

main2.o : $(s2)/main2.c

       $(MAKE) -C$(s2)

 

.PHONY : clean

clean :

       rm *.o -fr

       rm$(s1)/*.o $(s1)/edit1 -fr

       rm$(s2)/*.o $(s2)/edit2 -fr

时间: 2024-09-24 06:17:42

makefile学习笔记(多目录嵌套调用、变量使用)的相关文章

<转>Windows平台下Makefile学习笔记(二)

  本文转自:http://blog.csdn.net/clever101/article/details/8286066         上次我们学习了怎么用Makefile编译一个控制台工程.这次我们学习一下如何使用Makefile来编译一个win 32的GUI程序.win 32的GUI程序其编译过程大部分和控制台程序一样,不同的是多了一步RC编译器将资源文件编译成res文件,然后在最后一步链接中需要把这个res文件链接到exe文件中.         好,现在让我们在实践中学习吧.新建一个

thinkphp学习笔记1—目录结构和命名规则

最近开始学习thinkphp,在下不才,很多的问题看不明白所以想拿出来,恕我大胆发在首页上,希望看到的人能为我答疑解惑,这样大家有个互动,学起来快点,别无他意,所谓活到老,学到老,希望各位不要见笑啊.   我的做法很简单,先从手册开始,手册是开发thinkphp作者辛勤劳动的成果,但是有些地方是在是不懂,如果有幸各位也遇到类似的问题希望能回复.        1.框架目录   在章节1.6 目录结构,内容如下:   新版的目录结构在原来的基础上进行了调整,更加清晰.   目录/文件 说明 Thi

javascript学习笔记整理(概述、变量、数据类型简介)_基础知识

A.概述1.输出工具: document.write()---可以是html alert()---字符串 prompt(text,defaultText) text---可选.要在对话框中显示的纯文本(而不是 HTML 格式的文本). defaultText---可选.默认的输入文本. 2.js的放置 a.可以再HTML的任何位置放置 b.但他是一个整体,相互影响 c.在超链接和重定向的位置 <a href="javascript:alert();"></a>

linux学习笔记 linux目录架构_unix linux

linux目录架构   / 根目录   /bin 常用的命令 binary file 的目錄   /boot 存放系统启动时必须读取的档案,包括核心 (kernel) 在内   /boot/grub/menu.lst GRUB设置   /boot/vmlinuz 内核   /boot/initrd 核心解壓縮所需 RAM Disk   /dev 系统周边设备   /etc 系统相关设定文件   /etc/DIR_COLORS 设定颜色   /etc/HOSTNAME 设定用户的节点名   /et

PHP学习笔记(二):变量详解_php实例

一.PHP 变量简介 1.语法 复制代码 代码如下: //PHP是弱类型语言,变量类型由存储的值决定 //强类型语言:int a = 1 $变量名 = 值 2.命名规则 1).不能数字开头 2).不能使用PHP运算符(+-x/%&) 3).可以使用PHP关键字 4).区分大小写(php只有变量.常量区分大小写) 5).驼峰命名法:aaBbCc(第一个单词首字母小写) 3.可变变量 变量名可动态设置,例如:$$var 4.引用赋值 复制代码 代码如下: $a=1; $b=&$a; //将$a

JavaScript权威设计--JavaScript函数(简要学习笔记十)

1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"likeZqz()".有些些函数是用作内部用的或者为私有函数通常以一条下划线为前缀,就像"_zqzName()".   2.以表达式方式定义的函数 如: var zqz=function (){ return "zhaoqize"; } 在使用的时候必须把它赋值给一

javascript学习笔记_浅谈基础语法,类型,变量_基础知识

基础语法.类型.变量 非数字值的判断方法:(因为Infinity和NaN他们不等于任何值,包括自身) 1.用x != x ,当x为NaN时才返回true; 2.用isNaN(x) ,当x为NaN或非数字值时,返回true; 3.用isFinity(x),在x不是NaN.Infinity.-Infinity时返回true; 虽然(字符串.数字.布尔值)不是对象,他们的属性是只读的,但也可以像操作对象一样来引用他们的属性和方法,原理: javascript构造一个(String.Number.Boo

C#学习笔记整理_变量等基础语法(必看篇)_C#教程

C#学习笔记1: 变量的作用域冲突时,调用实例变量:this.a,调用类变量:类名.a 常量总是静态的,必须初始化,一般用全大写格式,声明关键字为const,如const int NUNBE = 10; C#的基本预定义类型内置于.NET Framework结构中(System),object是基类: 整型:System.SByte.System.Int16.System.Int32.System.Int64 有符号的8位.16位.32位.64位分别表示为sbyte.short.int.long

iOS开发:学习笔记—变量、属性、方法、实现

  1.代码说明: Person.h 开发:学习笔记-变量.属性.方法.实现-"> Person.h #import @interface Person : NSObject { int age,sex;//变量的定义 int height,width; } @property int age,sex;//属性的定义 @property char height; //-(void) setAge; -(int) setAge1 :(int)a; -(int) setWH :(int)w :