zoukankan      html  css  js  c++  java
  • Makefile书写注意事项--个人择记(一)

     1 #sample Makefile
     2 edit : main.o kbd.o command.o display.o 
     3 insert.o search.o files.o utils.o
     4     cc -o edit main.o kbd.o command.o display.o 
     5         insert.o search.o files.o utils.o
     6 main.o : main.c defs.h
     7     cc -c main.c   
     8 kbd.o : kbd.c defs.h command.h
     9     cc -c kbd.c
    10 command.o : command.c defs.h command.h
    11     cc -c command.c
    12 display.o : display.c defs.h buffer.h
    13     cc -c display.c
    14 insert.o : insert.c defs.h buffer.h
    15     cc -c insert.c
    16 search.o : search.c defs.h buffer.h
    17     cc -c search.c
    18 files.o : files.c defs.h buffer.h command.h
    19     cc -c files.c
    20 utils.o : utils.c defs.h
    21     cc -c utils.c
    22 clean :
    23     rm edit main.o kbd.o command.o display.o 
    24     insert.o search.o files.o utils.o
    View Code

    示例Makefile如上

    1、将一个较长的行使用反斜线()来分解多行,这样可以使我们的Makefile书写清晰、容易阅读理解。但需要注意:反斜线之后不能有空格(这也是大家最容易犯的错误,错误比较隐蔽)。

    2、命令行定义了规则的动作(如何根据依赖文件来更新目标文件)。命令行必需以[Tab]字符开始,以和Makefile其他行区别。就是说所有的命令行必需以[Tab]字符开始,但并不是所有的以[Tab]键出现行都是命令行。但make程序会把出现在第一条规则之后的所有以[Tab]字符开始的行都作为命令行来处理。(记住:make程序本身并不关心命令是如何工作的,对目标文件的更新需要你在规则描述中提供正确的命令。 “make”程序所做的就是当目标程序需要更新时执行规则所定义的命令)

     3、目标”clean“不是一个文件,它仅仅代表执行一个动作标识。正常情况下,不需要执行这个规则所定义的动作,因此目标”clean“没有出现在其它任何规则的依赖列表中。因此在执行make时,它所指定的动作不会被执行。除非在执行make时明确指定它。而且目标”clean“没有任何依赖文件,它只有一个目的,就是通过这个目标名来执行它所定义的命令。Makefile中把那些没有任何依赖只有执行动作的目标称为”伪目标“(Phony targets)。需要执行"clean"目标所定义的命令,可在shell下输入make clean

    4、自动推导规则

    在使用make编译.c源文件时,编译.c源文件规则的命令可以不用明确给出。这是国 为make本身存在一个默认的规则,能够自动完成对.c文件的编译并生成对应的.o文件。它执行命令"cc -c"来编译.c源文件。在makefile中我们只需要要给出需要重建的目标文件名(一个.o文件),make会自动为这个.o文件寻找合适的依赖文件(对应.c文件。对应是指:文件名除后缀外,其余都相同的两个文件),而且使用正确的命令来重建这个目标文件。对于上国这的例子,此默认规则就使用命令"cc -c main.c -o main.o"来创建文件"main.o"。对一个目标文件是"N.o",依赖文件是"N.c"的规则,完全可以省略其规则的命令行,而由make 自身决定使用默认命令。此默认规则称为make的隐含规则。

      这样,在书写Makefile时,我们就可以省略掉描述.c文件和.o依赖关系的规则,而只需要给出那些特定的规则描述(.o目标所需要的.h文件)。因此上边的例子就可以以更加简单书写,我们同样使用变量”OBJ“。Makefile内容如下:

    OBJ=main.o kbd.o command.o display.o insert.o search.o files.o utils.o
    
    edit : $(OBJ)
        cc -o edit $(OBJ)
    main.o : def.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 command.h
    files.o : defs.h buffer.h command.h
    utils.o : defs.h
    
    .PHONY : clean
    clean :
        -rm edit ${OBJ}
    View Code

    清除工作目录过程文件

     

    规则除了完成源代码编译之外,也可以完成其他任务。例如:前边提到的为了实现清除当前目录中编译过程中产生的临时文件(edit和哪些.o文件)的规则:

    clean:
        rm edit $(OBJ)
    View Code

    在实际应用时,我们把这个规则写成如下稍微复杂一些的样子。以防止出现始料未及的情况

    .PHONY:clean
        clean:
            -rm edit $(OBJ)
    View Code

    这两个实现有两点不同:1.通过“.PHONY”特殊目标将“clean”目标声明为伪目标。避免当磁盘上存在一个名为“clean”文件时,目标“clean”所在规则的命令无法执行。2.在命令行之前使用“-”,意思是忽略命令“rm”的执行错误。

  • 相关阅读:
    Codechef MSTONES Milestones
    Gym101620C Cumulative Code
    bootstrap组件-导出数据
    安装pip工具
    权限管理系统---django版本
    tornado 路由、模板语言、session
    django 连接mysql
    django 表结构
    ajax和原生ajax、文件的上传
    django的cookie和session
  • 原文地址:https://www.cnblogs.com/tkid/p/4492210.html
Copyright © 2011-2022 走看看