learning_notes

学习笔记

View project on GitHub

概念

  1. Makefile的规则

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

    target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。

    prerequisites就是,要生成那个target所需要的文件或是目标。

    command也就是make需要执行的命令。(任意的Shell命令)

  2. Makefile如何工作(只输入make)

    1. 再当前目录下查找 Makefile或makefile
    2. 查找第一个target
    3. 检查依赖文件是否更新或存在,是否需要重新编译或执行,一层一层的查找,类似堆栈
    4. 执行target的命令
  3. 变量的定义,方便重复引用

变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。如果你要使用真实的“$”字符,那么你需要用“$$”来表示

object = main.o kbd.o #定义变量
edit : $(object)  #使用变量
   gcc -o edit $(object)
  1. .PHONY(伪目标文件)

    伪目标的特性是,总是被执行的,依赖文件总是比它旧

伪目标一般没有依赖的文件。但是,我们也可以为伪目标指定所依赖的文件

   all : prog1 prog2 prog3

   .PHONY : all

 

   prog1 : prog1.o utils.o

           cc -o prog1 prog1.o utils.o
           
  1. 清空目标文件的规则
        .PHONY : clean
        clean :
                -rm edit $(objects)
        //不成文的规矩是——“clean从来都是放在文件的最后”。
  1. 引用其他的makefile
include foo.make *.mk $(bar)
  1. 特殊符号

    1. ‘~’:$HOME
    2. ‘*’:通配符
    3. ’':转义
  2. 文件搜索

VPATH

VPATH = src:../headers #全大写的,固定目录
#上面的的定义指定两个目录,“src”和“../headers”,make会按照这个顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)

  1. vpath < pattern> < directories> 为符合模式< pattern>的文件指定搜索目录
  2. vpath < pattern> 清除符合模式< pattern>的文件的搜索目录。
  3. vpath 清除所有已被设置好了的文件搜索目录。

vpath

   vpath %.c foo:bar

   vpath %   blish
   
#vapth使用方法中的< pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符
#而上面的语句则表示“.c”结尾的文件,先在“foo”目录,然后是“bar”目录,最后才是“blish”目录。
  1. 显示命令
    @echo 正在编译...
  1. 命令执行
exec:
   cd /home;pwd  #将cd的结果作为pwd的输入
   #【tab键后,命令前加-,表示命令出错也表示成功】
   
make exec #执行伪目标文件
  1. 嵌套执行make
subsystem:
    cd subdir && $(MAKE)
    
#如果需要传递变量
    export var = value
  1. 函数
$(subst ee,EE,feet on the street) #字符串处理函数,将ee替换为EE

  1. $@ $^ $< 的作用
    • $@ –代表目标文件(target)
    • $^ –代表所有的依赖文件(components)
    • $< –代表第一个依赖文件(components中最左边的那个)
      main.out:main.o line1.o line2.o
      g++ -o $@ $^
      main.o:main.c line1.h line2.h
      g++ -c $<
      line1.o:line1.c line1.h
      g++ -c $<
      line2.o:line2.c line2.h
      g++ -c $<