1.首先,把源文件编译生成中间代码文件,Windows下.obj文件,unix下.o文件,即Object File。这个动作叫编译(compile)

  把大量的Object File合并执行文件,叫做链接(link)

  2.在编译时,编译器只检测程序语法、函数、变量是否被申明。如果函数为被申明,编译器会给出一个警告,但可以生成object File。

  而在链接程序时,连接器会在所有的object File中寻找函数的实现,如果找不到,就会报链接错误码(link ERROR)

Makefile的规则:

  target:prerequisite    //target:目标文件,prerequisite :就是要生成那个target所需的文件或是目标

    command            //command也就是make所需执行的命令。注意:这一行一定是一个Tap键作为开头。

例:

  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

3.  .PHONY:clean        //表示“.PHONY”表示,clean是个伪目标文件

  clean:                      //clean不是一个文件,只是一个动作名字,像C语言中的lable一样,其冒号后什么都没有,make不会自动去找文件的依赖性,要执行其后面的命令,就要在make命令后明显得指出这个lable的名字。即:“make clean”

      rm edit $(objects)

4.每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。这是一个“修养”

  一般的风格都是:
      clean:
        rm edit $(objects)
  更为稳健的做法是:
      .PHONY : clean
      clean :
        -rm edit $(objects)  //。而在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事

  不成文的规矩是——“clean从来都是放在文件的最后”。

5.Makefile中只有行注释,其注释是用“#”字符,如果你再Makefile中使用“#”字符,可以使用反斜框进行转义,如“\#”

make的工作方式

GNU的make工作时执行步骤如下:

.读入所有的makefile。
.读入被include的其它makefile。
.初始化文件中的变量。
.推导隐晦规则,并分析所有规则。
.为所有的目标文件创建依赖关系链。
.根据依赖关系,决定哪些目标要重新生成。
.执行生成命令。

1-5 步为第一个阶段, 6-7 为第二个阶段。第一个阶段中,如果定义的变量被使用了,那么,make 会把其展开在使用的位置。但 make 并不会完全马上展开, make 使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。

规则说明:

targets : prerequisites
command
...
或是这样:
targets : prerequisites ; command
command
...

command 是命令行,如果其不与“target:prerequisites”在一行,那么,必须以[Tab]开头,如果和 prerequisites 在一行,那么可以用分号做为分隔。

如果你的 Makefile 需要一口气生成若干个可执行文件,但你只想简单地敲一个 make 完事,并且,所有的目标文件都写在一个 Makefile 中,那么你可以使用“伪目标”这个特性:

all : prog1 prog2 prog3
.PHONY : all prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o prog2 : prog2.o
cc -o prog2 prog2.o prog3 : prog3.o sort.o utils.o
cc -o prog3 prog3.o sort.o utils.o

编译器支持“-M”选项,表示自动找寻文件中包含的头文件。

如:gcc -M main.c

make执行时,带入make参数“-n”或“--just-print”,那么其只是显示命令,但不会执行命令,这个功能很有利于我们调试makefile。看看我们书写的命令执行顺序。

make参数“-s”或“--slient”,则全面禁止命令的显示。。。

需要注意的是,如果你要让上一条命令的结果应用在下一条命令时,你应该使用分号分隔这两条命令。 比如你的第一条命令是 cd 命令,你希望第二条命令得在 cd 之后的基础
上运行,那么你就不能把这两条命令写在两行上。

示例一:
exec:
cd /home/hchen
pwd
示例二:
exec:
cd /home/hchen; pwd

当我们执行“make exec”时,第一个例子中的 cd 没有作用,pwd 会打印出当前的 Makefile目录,而第二个例子中, cd 就起作用了, pwd 会打印出“/home/hchen”。

跟我学Makefile(一)的更多相关文章

  1. 跟我学Makefile(三)

    紧接着跟我学Makefile(二)继续学习:变量高级用法 (1)变量值的替换 :替换变量中的共有的部分,其格式是“$(var:a=b)”或是“${var:a=b}”,把变量“var”中所有以“a”字串 ...

  2. 一起学makefile

    Unix.Linux必学知识哈哈,网上看到一哥们写得挺好挺详细的,直接复制地址就分享哈哈哈. 跟我一起写 Makefile(一) 概述 跟我一起写 Makefile(二) make是如何工作的 跟我一 ...

  3. 跟我学Makefile(七)

    定义模式规则 使用模式规则来定义一个隐含规则.一个模式规则就好像一个一般的规则,只是在规则中,目标的定义需要有“%”字符.“%”的意思是表示一个或多个任意字符.在依赖目标中同样可以使用“%”,只是依赖 ...

  4. 跟我一起学Makefile

    概述 什么是makefile?或许很多Winodws程序员都不知道这个东西,因为那些Windows IDE都为你做了这个工作,但我觉得要做一个好的和professional的程序员,makefile还 ...

  5. 跟我学Makefile(六)

    shell 函数 :和反引号“`”是相同的功能 . shell 函数把执行操作系统命令后的输出作为函数返回. contents := $(shell cat foo) files := $(shell ...

  6. 跟我学Makefile(五)

    文件名操作函数 每个函数的参数字符串都会被当做一个或是一系列的文件名来对待. $(dir <names...>) 名称:取目录函数——dir. 功能:从文件名序列<names> ...

  7. 跟我学Makefile(二)

    命令出错: 每当命令运行完后, make 会检测每个命令的返回码,如果命令返回成功,那么 make 会执行下一条命令. 如果一个规则中的某个命令出错了(命令退出码非零),那么 make 就会终止执行当 ...

  8. 一起学Makefile(六)

    命令的回显: 通常,make在执行命令之前都会把执行的命令进行输出,例如: 关闭命令回显有以下几种方式: 每个需要关闭回显的命令行之前加上”@”符号: 执行make时机上参数-s 或 –slient进 ...

  9. 一起学Makefile(五)

    多目标规则 多目标规则,可以简单的理解为是一种将多条具有1)相同依赖和2)相同生成命令的规则,合并成一条规则的语法,其基本格式为: targets...: prerequisites... comma ...

随机推荐

  1. Java编译后产生class文件的命名规则

    今天刚好有同学问了下Java编译后产生的.class文件名的问题,虽然一直都在使用Java做开发,但是之前对编译后产生的.class文件名的规范也基本没做了解过,也真的是忏愧啊!今天无论如何都要总结下 ...

  2. python中的字典 和 集合

    python中字典是一种key-value的数据类型 字典的特性: 1.无序的 2.key必须的唯一的,so,字典天生去重 语法: 增加 修改 删除 查找 多级字典嵌套及操作 字典的其他用法 #set ...

  3. javascript -- 阻止默认事件 阻止事件冒泡

    1. event.preventDefault();  -- 阻止元素的默认事件.注:a元素的点击跳转的默认事件 , button,radio等表单元素的默认事件 , div 元素没有默认事件 例: ...

  4. List<T>转DataTable

    /// <summary> /// 将集合类转换成DataTable /// </summary> /// <param name="list"> ...

  5. 自己开发iOS版按键精灵--TTouch

    利用闲余时间,把之前的按键录制和播放整理了一些,开发了一个iOS版按键录制.播放的越狱APP,类似按键精灵.触动精灵等按键类的基本功能.脚本采用lua语法格式,可直接执行lua脚本,通过lua和obj ...

  6. 【C++缺省函数】 空类默认产生的6个类成员函数

    1.缺省构造函数. 2.缺省拷贝构造函数. 3. 缺省析构函数. 4.缺省赋值运算符. 5.缺省取址运算符. 6. 缺省取址运算符 const. <span style="font-s ...

  7. 编程之美 set 18 拈两堆石子游戏(3)

    题目 假设有两堆石头, 有两个玩家按照如下规则轮流取石头 每个人每次可以从两堆石头中取出数量相等的石头, 或者仅从一堆石头中取出任意数量的石头 最后把剩下的石头依次拿光的人取胜 首先取石头的人能否赢得 ...

  8. iOS开发之 -- 判断是否第一次登陆APP

    判断是否第一次登陆app,具体方法如下: if (![[NSUserDefaults standardUserDefaults]boolForKey:@"firstLaunch"] ...

  9. Git详解之二 Git细节拾遗

    git知识点详解 文件状态 现在我们手上已经有了一个真实项目的 Git 仓库,并从这个仓库中取出了所有文件的工作拷贝.接下来,对这些文件作些修改,在完成了一个阶段的目标之后,提交本次更新到仓库. 请记 ...

  10. hdu1071(定积分求面积)

    太弱了,写了一下午,高中基础太差的孩子伤不起... 记住抛物线是关于x轴对称的. 而且抛物线的方程可以是: y=k(x-h)+c  //其中(h,c)为顶点坐标 The area Time Limit ...