美文网首页
linux中的Makefile

linux中的Makefile

作者: 秋的懵懂 | 来源:发表于2018-03-26 02:27 被阅读0次

    时间:2018-02-26 作者:魏文应


    Makefile 的变量

    下面是定义makefile:

    objects = main.o kbd.o command.o display.o \
    insert.o search.o files.o utils.o
    

    然后引用变量:

    $(objects)
    

    makefile中的变量只是简单引用替换,和C语言的宏很像,比如:

    # 定义了一个变量
    srcdir = ../../../src
    
    # 引用变量
    cd $(srcdir)
    
    # 这里就是简单替换,等价于
    cd ../../../src
    

    不要在变量定义同一行中使用 # 号来注释:

    # 如何表示一个值为空格的变量呢?
    # 定义了一个空变量nullstring,space的值就以nullstring变量为起点,以 # 结束
    nullstring :=
    space := $(nullstring) #
    
    # 下面的定义,dir的值是 **/usr/bin 加上 $(srcdir)和#之间的那4个空格**,显然不是我们想要的
    srcdir := /usr/bin
    dir := $(srcdir)    # 
    

    Makefile 中的 := 符号

    符号 := 说明,不能引用后面定义的变量:

    # 引用前面定义
    # 那么展开y就等价于 y := foo bar
    x := foo
    y := $(x) bar
    
    # 不引用后面的
    # 那么展开y就等价于 y := bar
    y := $(x) bar
    x := foo
    

    Makefile 中的 ?= 符号

    表示如果之前FOO没有定义过,就给它赋值为bar,如果已经定义过,就不重新赋值了,保持原来的。

    FOO ?= bar
    

    Makefile 的自动推导

    GNU make 功能比较强大,它会做一些推导。假设有一个 main.c 源代码文件,内容如下:

    # include <stdio.h>
    
    void main(void)
    {
      print("hello world!!!")
    }
    
    

    那么编译这个 main.c 文件时,要生成 main.o,这main.o文件要依赖 main.c和stdio.h 这两个文件来生成,正常我们这么写:

    main.o : main.c stdio.h 
    

    有了自动推导功能以后,make 工具可以自动认为 main.o 文件有一个默认的依赖,那就是main.c文件,所以等价的写法如下:

    main.o : stdio.h
    

    Makefile 中的伪目标

    makefile中的伪目标其实是标签,比如:

    prepare:
      @echo \#############
    
    .PHONY clean
    clean:
      rm -rf output/
    
    

    上面 prepare 就是伪目标,比如我们执行 make prepare 命令,那么就只执行prepare的内容,而下一个伪目标clean的内容不会得到执行。.PHONY 明确地告诉make工具,这是个伪目标(标签)。如果没有 .PHONY 关键字,make 工具会自动判断。

    Makefile 中的 rm 指令前加 ‘-’

    比如,有时我们会看到这样的

    -rm -rf main.o hello.o
    

    我们在linux的bash命令中,一般是这样执行 rm -rf main.o hello.o 来删除main.o 和hello.o这两个文件的。rm 前加上 “-” ,是告诉make工具,这个指令可能有问题(比如main.o这个文件不存在),但不要管它,继续执行后面的操作。

    Makefile 中的注释

    makefile使用 # 号来注释,注释里你写什么都行(你开心就好):

    # 在这里写注释
    .PHONY clean
    clean:
      -rm -rf output
    

    如果你要引用 ‘#’ 这字符,就使用 转义符加#号:\#

    Makefile 中的命令

    makefile中的命令要以 Tab 键开始(其实很多脚本对缩进是敏感的):

    .PHONY clean
    clean:
      -rm -rf output
    

    你看,这里 -rm -rf output 这个命令前要加 Tab 键进行缩进。

    Makefile 的文件名

    创建一个makefile,它的文件名一般用 MakefilemakefileGNUmakefile 来命名,我们一般用 Makefile 这个名词。当我们用make工具编译链接源代码时,这样 make 这个指令就默认使用当前目录下的这个Makefile脚本了:

    # 执行
    make
    # 相当于
    make Makefile

    如果你不这么命名,如命名为wifi-makefile,你就需要显式地指定了:

    make -f wifi-makefile

    Makefile 的模式规则

    模式规则就是你定义一个规则,比如:

    # 当前目录下的所有.c文件编译生成.o文件
    %.o : %.c
      # CC是编译器,CFLAGS是C语言编译器参数,
      # CPPFLAGS是C预处理器参数,$< 在这里就是挨个的.o文件,
      # $@ 在这里就是挨个的.c文件,下面就是生成规则
      $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
    

    Makefile 的自动化变量

    符号 描述
    $@ 所有目标的挨个值
    $< 所有依赖的挨个值
    $(@F) 取 $@ 中的文件部分,比如$@的值是src/main.c,$(@F) 的值就等于 main.c

    GCC的编译选项

    相关文章

      网友评论

          本文标题:linux中的Makefile

          本文链接:https://www.haomeiwen.com/subject/rvquxftx.html