第三章 Makefile 快速入门

   注意:makefile 仅仅是一个编译期的一个过程,随时可以修改,应尽量简单化,避免太复杂的逻辑,修改不便。 从工程中来看makefile 尽量在短时间内完成需要的时候可以修改。不用占据很长世间。 在这里我强烈建议手写makefile ,避免使用automaker autoconfig 之类的工具生成makefile 即使编译出错手写的也容易检查。本文只列出常用makefile 特性,对于其它不常用的建议参考gun make手册。

(1) makefile 的三条规则

  1>   如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。 

  2>   如果这个工程的某几个C 文件被修改,那么我们只编译被修改的C 文件,并链接目标程序。 

  3>   如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C 文件,并链接目标程序。

(2) makefile 的基本格式

  TARGET... : PREREQUISITES...

    COMMAND

  TARGET 代表目标文件 ,可以是可执行文件 ,中间文件*.o  或者伪目标

  PREREQUISITES 生成目标文件所依赖的文件

  COMMAND  编译命令

  注意:每一个命令行必须以[Tab]字符开始,[Tab] 字符告诉make此行是一个命令行。

复制代码
main : main.o add.o
    gcc main.o add.o -O main
    
add.o : add.c add.h
    gcc -c test.c
    
main.o : main.c add.h
    gcc -c main.c
    
clean:
    rm *.o        
复制代码

(3) make 工作方式

  1>   make会在当前目录下找名字叫“Makefile” 或“makefile”的文件。

  2>   如果找到,它会找文件中的第一个目标文件(target ),在上面的例子中,他会找到“main”这个文件,并把这个文件作为最终的目标文件。

  3>   如果main文件不存在,或是 main所依赖的后面的 .o  文件的文件修改时间要比 main这个文件新,那么,他就会执行后面所定义的命令来生成main。

  4>   如果main所依赖的.o 文件也存在,那么 make会在当前文件中找目标为.o 文件的依赖性,如果找到则再根据那一个规则生成.o 文件。

  5>   当然,你的 C 文件和H 文件是存在的啦,于是make会生成 .o  文件,然后再用 .o  文件生命make的终极任务,也就是执行文件edit 了

 (4)  通配符使用

  *  ? [...]  ~  注意 以~开始的文件名代表当前用户的宿主目录 可以通过 echo ~ 查看

(5) 目录搜寻

  1> 一般搜寻 VPATH 变量  VPATH = src:../headers   注意目录以:隔开

    2> 选择性搜寻

    vpath PATTERN DIRECTORIES 为所有符合模式“PATTERN”的文件指定搜索目录“DIRECTORIES ”。多个目录使用空格或者冒号(:)分开。

    vpath PATTERN 清除之前为符合模式“PATTERN”的文件设置的搜索路径。

    vpath 清除所有已被设置的文件搜索路径

     eg: vpath %.h ../headers

  3> 库文件和搜寻目录

    依赖规则中书写-lNAME

    eg: foo : foo.c -lcurses ;cc $^ -o $@   

  目录搜寻过程 当前路径->VPATH顺序路径   对于库文件继续搜索 "/lib" ->"/usr/lib"    库文件先按搜索路径搜索动态库,在搜索静态库。

(6)伪目标

  规则所定义的命令不是去创建目标文件,而是通过make命令行明确指定它来执一些特定的命令。

  eg:  clean:

        rm *.o temp

      .PHONY : clean

(7) make 的递归执行

   subsystem:

      cd subdir && $(MAKE)   或者    $(MAKE) -C subdir

(8) 变量

  1>   自定义变量  VAR=main.o add.o     使用变量 $(VAR)   建议变量用大些字母表示

      VAR =  main.o    递归展开式

      VAR := main.o    直接展开式

      VAR ?= main.o  没有定义则赋值

      VAR += main.o   追加赋值  

  2>  自动化变量

    $@ 表示规则的目标文件名

    $< 规则依赖所有的文件名   

(9)make 隐含规则与隐含变量

  1> 命令变量

    AR 函数库打包程序,可创建静态库.a 文档。默认是“ar ”

    AS 汇编程序。默认是“as”。

    CC C编译程序。默认是“cc”。

    CXX  C++ 编译程序。默认是“g++ ”

    RM 删除命令。默认是“rm -f”。

  2> 参数变量

    ARFLAGS 执行“AR”命令的命令行参数。默认值是“rv ”

    ASFLAGS 执行汇编语器“AS”的命令行参数

    CFLAGS 执行“CC”编译器的命令行参数(编译.c 源文件的选项)

    CXXFLAGS 执行“g++ ”编译器的命令行参数(编译.cc 源文件的选项)。

  3> 模式规则

     %.o : %.c ; COMMAND...

    eg : %.o : %.c

          $(CC) -c $(CFLAGS) $( CPPFLAGS) $< -o $@

  (10) makefile举例

    这里不再单独举例书写makefile ,放到后面的代码编写之中,对应相应的工程做makefile 更为实际。 

posted @ 2013-07-11 14:08  皁仩腄覺  阅读(285)  评论(0编辑  收藏  举报