Makefile笔记

Makefile 笔记

一、简单的 Makefile 例子

  1. 文档目录结构
    • 文档目录结构是用户目录HOME下有src incl bin lib
      src:源码
      incl:头文件
      bin:执行码
      lib:静态/动态库
      这是大家最常见的Linux编程目录结构,以下代码编译都是依据这个结构。
      
  2. Makefile 代码
    hello:hello.c
        gcc -I${HOME}/incl -c hello.c   // 预处理+编译+汇编命令 不汇编
        gcc -o hello hello.o    
        rm -f hell.o
        mv hello ${HOME}/bin
    
    • 简单的Makefile确实可以当shell脚本执行,但是只学会简单的Makefile并看不懂大神的Makefile啊

二、Makefile 结构说明

  • Makefile里主要包含了五个东西:变量定义、显式规则、隐晦规则、文件指示和注释。
  1. 变量定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
  2. 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。 刚才写的疑似shell脚本的Makefile全部都是显示规则。
  3. 隐晦规则。由于我们的 make 有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 Makefile,这是由make所支持的。
    4.文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样。
  4. 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。

三、略复杂的 Makefile 例子

  1. Makefile 代码
    # 隐含规则:这个隐晦规则其实就是告诉大家,后缀为cpp的文件怎么编译成.o,后缀为c的文件怎么编译成.o。
    INCL=-I${HOME}/incl             # 变量定义
    
    .SUFFIXES: .cpp .c
    .cpp.o:
        g++ ${INCl} -c $<           # ${INCl} 进行了变量使用
    
    .c.o:
        gcc ${INCL} -c %<           # %< 是预定义变量
    
    # C++编译
    hellocpp:hellocpp.o
        echo "开始编译"
        g++ -o hellocpp hellocpp.o
        rm -f hellocoo.o 
        mv hellocpp ${HOME}/bin
        echo "编译结束"
    
    # C编译
    hello:hello.o
        echo "开始编译"
        gcc -o hello hello.o
        rm -f hello.o
        mv hello ${HOME}/bin
        echo "编译结束"
    
  2. 预定义变量
    $*    不包含扩展名的目标文件名称。
    $+    所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
    $<    第一个依赖文件的名称。
    $?    所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。
    $@     目标的完整名称。
    $^    所有的依赖文件,以空格分开,不包含重复的依赖文件。
    $%      如果目标是归档成员,则该变量表示目标的归档成员名称。
    
  3. 进一步理解预定义变量
    • Makefile文件
      all: first second third
          @echo "\$$@ => $@"
          @echo "$$^ => $^"       # "$"对于makefile有特殊含义输出时需要加上一个"$"进行转义
          @echo "$$< => $<"       # "$@"对于Bash Shell有特殊含义输出时需要加上"\"进行转义
      
    • 执行后
      $@ => all
      $^ => first second third
      $< => first
      

四、整理下三中 Makefile 例子

  1. 最后形成的 Makefile 例子
    #最后形成的Makefile
    INCL=-I${HOME}/incl
    BIN=$(HOME)/bin
    OBJ1=hellocpp.o
    OBJ2=hello.o
    
    .SUFFIXES: .cpp .c
    .cpp.o:
        g++ ${INCL} -c $<
    
    .c.o:
        gcc ${INCL} -c $<
    
    all: hellocpp hello
    
    #C++编译
    hellocpp:${OBJ1}
        @echo "============开始编译============"
        g++ -o $@ $?
        @rm -f ${OBJ1}
        @mv $@ ${BIN}
        @echo "============编译结束============"
        @echo ""
    
    #C编译
    hello:${OBJ2}
        @echo "============开始编译============"
        gcc -o $@ $?
        @rm -f ${OBJ2}
        @mv $@ ${BIN}
        @echo "============编译结束============"
        @echo ""
    
  2. 命令前加@,表示当前命令不显示

你可能感兴趣的:(Makefile笔记)