zoukankan      html  css  js  c++  java
  • 跟我学Makefile(一)

      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工作时执行步骤如下:

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

     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”。

  • 相关阅读:
    数据分析优化之惩罚性线性回归算法
    数据分析之贝叶斯算法案例
    SSM-CRUD练习
    使用 Code First 迁移以设定数据库种子
    .Net Web Api相关学习内容
    ASP.NET MVC5的学习知识点
    Entity Framework的学习(ASP.NET MVC5的学习中的一部分)
    EFCore框架的学习
    jsp中的<%%>用法
    nginx出现404和403错误
  • 原文地址:https://www.cnblogs.com/Caden-liu8888/p/5607294.html
Copyright © 2011-2022 走看看