依睛(IT blog) 我回来了,PHP<-->C/C++ LINUX

笨鸟

导航

<2025年4月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

留言簿(26)

随笔分类(315)

文章分类(5)

收藏夹

随笔档案(330)

文章档案(11)

相册

阅读排行榜

评论排行榜

统计

积分与排名

友情连接

最新评论

Linux Makefile学习 (一)

这个很不错,在面临工作的要求而学习, 刚入门,还有那么多东西没学,

一.概述
  源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。
 
  1)在编译时,编译器只检测程序语法,和函数,变量是否被声明。如果函数未被声明,编译器会给出一个警
告,但可以生成Object File.
 
  2)在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那就会报链接错误码
(Linker Error)
.c-->.o--------->可执行文件
.c-->.o-->.lib-->可执行文件
 
二.Makefile的规则
1.target:一个目标文件,可以是Object File,也可以是执行文件;还可以是标签(Label),对于标签这种特性
,在后续的"伪目标"章节中会有叙述。
  prerequisites:要生成那个target所需要的文件或目标.target这一个或多个的目标文件依赖于prerequistes中的文件
  command: 就是make需要执行的命令(任意的Shell命令),如果prerequisites中如果有一个以上的文件
比target文件要新的话,command所定义的命令就会被执行
  target...:prerequisites...
            command
            ...
            ...
 
 
三.一个例子:
/******************************************************************************/
    edit : main.o kbd.o command.o display.o \
           insert.o search.o files.o utils.o
            cc -o edit main.o kbd.o command.o display.o \
                       insert.o search.o files.o utils.o
    main.o : main.c defs.h
            cc -c main.c
    kbd.o : kbd.c defs.h command.h
            cc -c kbd.c
    command.o : command.c defs.h command.h
            cc -c command.c
    display.o : display.c defs.h buffer.h
            cc -c display.c
    insert.o : insert.c defs.h buffer.h
            cc -c insert.c
    search.o : search.c defs.h buffer.h
            cc -c search.c
    files.o : files.c defs.h buffer.h command.h
            cc -c files.c
    utils.o : utils.c defs.h
            cc -c utils.c
    clean :
            rm edit main.o kbd.o command.o display.o \
               insert.o search.o files.o utils.o
/******************************************************************************/
1)反斜杠(\)是换行符的意思,这样比较便于Makefile的易读
 
2)定义好了依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头
 
3)clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,
make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令;要执行其后的命令,就要在make命
令后明显得指出这个lable的名字。
注意:make并不管命令是怎么工作的,它只管执行所定义的命令;make会比较targets文件和prerequisites文
件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,
make就会执行后续定义的命令。
 
 
四.make是如何工作的
  1.make会在当前目录下找名字"Makefile"或"makefile"的文件
  2.再找文件中的第一个目标文件(target),上面例子中的"edit"这个文件,这个就是最终目标文件
  3.如果edit文件不存在,或是edit所依赖的后面的.o文件的文件修改时间要比edit这个文件新,那么就会执
行后面所定义的命令来生成edit这个文件。
  4.如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据
那一个规则生成.o文件。(这有点像一个堆栈的过程)
 
 
五.Makefile中使用变量
 
1.没有使用变量前的情况:
edit : main.o kbd.o command.o display.o
            cc -o edit main.o kbd.o command.o display.o
我们可以看到[.o]文件的字符串被重复了两次,如果我们在工程中加入一个新的[.o]文件,那么我们需要至少
在两个地方加(还有一个地方在clean中);如果makefile变得复杂,我们就有可能会忘掉一个需要加入的地方,
而导致编译失败。
 
2.使用变量的情况:
 objects = main.o kbd.o command.o display.o
  我们声明一个变量,叫objects,OBJECTS,objs,OBJS,obj,或是OBJ,反正不管什么都好,只要能表示obj
文件就行了。
  于是,我们就可以很方便地在我们的makefile中以"$(objects)"的方式来使用这个变量了,于是我们改良版
makefile就变成下面这个样子:
/******************************************************************************/
    objects = main.o kbd.o command.o display.o \
              insert.o search.o files.o utils.o
    edit : $(objects)
            cc -o edit $(objects)
    main.o : main.c defs.h
            cc -c main.c
    kbd.o : kbd.c defs.h command.h
            cc -c kbd.c
    command.o : command.c defs.h command.h
            cc -c command.c
    display.o : display.c defs.h buffer.h
            cc -c display.c
    insert.o : insert.c defs.h buffer.h
            cc -c insert.c
    search.o : search.c defs.h buffer.h
            cc -c search.c
    files.o : files.c defs.h buffer.h command.h
            cc -c files.c
    utils.o : utils.c defs.h
            cc -c utils.c
    clean :
            rm edit $(objects)
/******************************************************************************/
如果有新的.o文件加入,我们只需简单地修改一下objects变量就可以了
                
六.让make自动推导
    GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]
文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。
    只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,
那么whatever.c,就会是whatever.o的依赖文件;并且cc -c whatever.c也会被推导出来:
/******************************************************************************/
    objects = main.o kbd.o command.o display.o \
              insert.o search.o files.o utils.o
    edit : $(objects)
            cc -o edit $(objects)
    main.o : defs.h
    kbd.o : defs.h command.h
    command.o : defs.h command.h
    display.o : defs.h buffer.h
    insert.o : defs.h buffer.h
    search.o : defs.h buffer.h
    files.o : defs.h buffer.h command.h
    utils.o : defs.h
    .PHONY : clean
    clean :
            rm edit $(objects)
/******************************************************************************/
这种方法叫做make的"隐晦规则"。上面文件内容中,".PHONY"表示,clean是个伪目标文件
 
 
七.另类风格的makefile
   我们的make可以自动推导命令,[.o]和[.h]的依赖关系有点麻烦,太多重复的[.h],我们可以利用make将其
收拢起来;但这种风格,虽然使得makefile变得很简单,但文件依赖关系就显得有点凌乱了。弊端有:
   1.文件的依赖关系看不清楚
   2.如果文件一多,要加入几个新的.o文件,那就理不清楚了
/******************************************************************************/
    objects = main.o kbd.o command.o display.o \
                   insert.o search.o files.o utils.o
    edit : $(objects)
            cc -o edit $(objects)
    $(objects) : defs.h
    kbd.o command.o files.o : command.h
    display.o insert.o search.o files.o : buffer.h
    .PHONY : clean
    clean :
            rm edit $(objects)
/******************************************************************************/
 
 
八.清空目标文件的规则
一般风格是:
        clean:
            rm edit $(objects)
更为稳健的做法是:
        .PHONY : clean
        clean :
                -rm edit $(objects)
前面说过,.PHONY意思表示clean是一个"伪目标",而在rm命令前面加了一个小减号的意思就是,也许某些文件
出现问题,但不要管,继续做后面的事。当然,clean的规则不要放在文件的开头,不然,这就会变成make的默
认目标;不成文的规矩是------"clean从来都是放在文件的最后"。


posted on 2007-06-30 12:37 向左向右走 阅读(567) 评论(0)  编辑 收藏 引用 所属分类: Linux 学习库

只有注册用户登录后才能发表评论。