• Makefile学习


    1、多个if判断

    DEMO := 2
    
    all:
    ifeq ($(DEMO), 1)
        @echo "DEMO 1"
    else ifeq ($(DEMO), 2)
        @echo "DEMO 2"
    else ifeq ($(DEMO), 3)
        @echo "DEMO 3"
    else
        @echo "DEMO Other"
    endif

    输出:

    DEMO 2
    DEMO2

    2、打印变量

    可以使用 ${} 或者$() 或者 $ ,其中 $ 用于单字符变量,对于多字符变量,只能用前面两个

    DEMO := 1
    X := 1

    all:
            @echo $${DEMO} = ${DEMO}
            @echo $$(DEMO) = $(DEMO)
            @echo $$X = $X

    输出:

    ${DEMO} = 1
    $(DEMO) = 1
    $X = 1

    3、=、:= 和 ?=

    x := 1
    y = 1
    x ?= 2
    
    all:
            @echo x=$(x)
            @echo y=$(y)
    
    y = 2
    y ?= 3

    输出:

    x=1
    y=2

    4、ifdef和ifndef使用

    X := 1
    Y :=
    Z := 2
    
    all:
    ifndef X
            @echo "X = $(X)"
    else ifdef Y
            @echo "Y = ${Y}"
    else ifdef Z
            @echo "Z = ${Z}"
    endif

    输出:

    Z = 2

    5、origin获得变量来源

    w1 := $(origin W)
    x1 := $(origin X)
    y1 := $(origin Y)
    Z := 1
    z1 := $(origin Z)
    c := $(origin CC)
    
    
    all:
            @echo "W: ${w1}"
            @echo "X: ${x1}"
            @echo "Y: ${y1}"
            @echo "Z: ${z1}"
            @echo "CC: ${c}"

    运行:

    $ X=1 make -f mk5 Y=2
    W: undefined
    X: environment
    Y: command line
    Z: file
    CC: default

    6、递归编译的三种方式

    目录结构:

    .
    ├── Makefile
    ├── sub1
    │   └── Makefile
    ├── sub2
    │   └── Makefile
    ├── sub3
    │   └── Makefile
    ├── sub4
    │   └── Makefile
    └── sub5
        └── Makefile

    子目录的Makefile内容只输出一句话:

    sub1/Makefile内容:
    all:
            @echo "	This is sub1"
    
    sub2/Makefile内容:
    all:
            @echo "	This is sub2"
    
    sub3/Makefile内容:
    all:
            @echo "	This is sub3"
    
    sub4/Makefile内容:
    all:
            @echo "	This is sub4"
    
    sub5/Makefile内容:
    all:
            @echo "	This is sub5"

    顶层Makefile内容如下:

    SUB_DIRS := $(sort $(wildcard sub*))
    
    all: subdir
            @echo "		**** method 2 ****"
            @echo "In top dir"
            @cd sub1 && make -s
            @cd sub2 && make -s
            @cd sub3 && make -s
            @cd sub4 && make -s
            @cd sub5 && make -s
    
            @echo "
    		**** method 3 ****"
            @echo "In top dir"
            @for dir in $(SUB_DIRS); do 
                    make -s -C $$dir; 
            done
    
    .PHONY: log $(SUB_DIRS)
    subdir:log $(SUB_DIRS)
    
    log:
            @echo "SUB_DIRS: 
    	$(SUB_DIRS)"
            @echo "
    		**** method 1 ****"
            @echo "In top dir"
    
    $(SUB_DIRS):
            @make -s -C $@

    输出:

    SUB_DIRS: 
            sub1 sub2 sub3 sub4 sub5
    
                    **** method 1 ****
    In top dir
            This is sub1
            This is sub2
            This is sub3
            This is sub4
            This is sub5
                    **** method 2 ****
    In top dir
            This is sub1
            This is sub2
            This is sub3
            This is sub4
            This is sub5
    
                    **** method 3 ****
    In top dir
            This is sub1
            This is sub2
            This is sub3
            This is sub4
            This is sub5

    7、make -n 或者 make --just-print

    可以用于调试Makefile的一些问题,此时make执行时只显示所要执行的命令,但不会真正的去执行这些命令

    8、make -s 或者 make --slient

    禁止所有执行命令的显示,就好像所有的命令行均使用"@"开始一样

    9、.PHONY

    使用这个修饰的目标,对应的命令会被无条件执行。而如果没有修饰的话,对于没有依赖文件的目标,只要目标文件不存在时才会执行定义的命令。

    实例:

    all:
            @echo "all is compiled"
    
    .PHONY:clean
    clean:
            @echo "clean is compiled"

    体会下面的输出:

    //此时当前目录只有一个Makefile文件
    $ ls
    Makefile
    
    //执行make后,all作为第一个目标,由于当前目录下不存在all这个文件,所以all的命令被执行
    $ make
    all is compiled
    $ make all
    all is compiled
    
    // clean由于是PHONY的,所以每次都执行
    $ make clean
    clean is compiled
    
    // 然后在当前目录下分别创建all和clean两个文件
    $ touch all
    $ touch clean
    $ ls
    all  clean  Makefile
    
    // 此时在编译all时,all的命令就不会执行了,因为当前目录已经存在all文件,并且all没有任何依赖文件
    $ make
    make: 'all' is up to date.
    $ make all
    make: 'all' is up to date.
    
    // clean由于是PHONY的,命令无条件执行
    $ make clean
    clean is compiled
    
    // 将all删除,发现all又可以执行了
    $ rm all 
    $ ls
    clean  Makefile
    $ make all
    all is compiled
    
    // clean由于是PHONY的,命令无条件执行
    $ make clean
    clean is compiled

    如果在对Makefile做个修改:

    all:clean
            @echo "all is compiled"
    
    .PHONY:clean
    clean:
            @echo "clean is compiled"

     即,将all的依赖文件设置为clean,那么此后,all也会被无条件执行了

    $ ls
    all  clean  Makefile
    $ make all
    clean is compiled
    all is compiled
    $ make
    clean is compiled
    all is compiled

    10、模式匹配

    • %

    当前目录下有如下几个文件:

    $ ls
    abc.A.abc  a.c  demo2.y  demo.sh  donglin.w  Makefile

    Makefile内容如下:

    all:demo demo2.x pengdonglin.w helloAworld
            @echo "all command"

    %:%.c
            @echo generate $@ through $<

    %:%.sh
            @echo generate $@ through $<

    %.x:%.y
            @echo generate $@ through $<

    hello%world:abc.%.abc
            @echo generate $@ through $<

    peng%:%
            @echo generate $@ through $<

    下面是运行结果:

    generate demo through demo.sh
    generate demo2.x through demo2.y
    generate pengdonglin.w through donglin.w
    generate helloAworld through abc.A.abc
    all command

     11、make -p 或 make --print-data-base

    可以查看在当前环境下make内置了那些规则

     12、 $(if $(KBUILD_VERBOSE:1=),@)  语法释疑

     https://blog.csdn.net/lcw_202/article/details/6656633

     等价于:

    $(if $(patsubst %1,%,$(KBUILD_VERBOSE)),@)

    也就是,如果KBUILD_VERBOSE为1,那么上面的表达式就是空,否则的话,就是@,这样后面的命令就会静默输出

     13、调用shell脚本

    Makefile中的shell用法

    makefile中的shell编程注意点

    Shell脚本——make命令和Makefile文件

    https://www.jb51.net/article/109797.htm

    shell 文件内调用makefile文件

    #!/bin/bash
    cd ctemplate-2.1
    ./configure
    sudo make -f install
    cd ../
    cd TemplateProcesser
    make

    说明:./configure文件是shell脚本文件,即shell内调用shell文件是很容易的;TemplateProcesser目录内有Makefile文件,调用方式,直接:make

    makefile文件内调用shell脚本文件:

    SHELL := /bin/bash
    test:
    @pwd
    cd ./TemplateProcesser && pwd
    sh ./build.sh
    @pwd

    说明:build.sh为shell脚本文件。

    调用perl文件
    /usr/bin/perl *.pl
    调用python文件
    /usr/bin/env *.py

     13、X:Y:Z

    X := 1.o 2.o 3.o
    Y := 4.o 5.o 6.o
    
    all:$(X) $(Y)
    
    X_c := $(patsubst %.o,%.c,$(X))
    Y_c := $(patsubst %.o,%.c,$(Y))
    
    $(X):%.o:%.c
            @echo "$@ <---- $<"
    
    $(Y):%.o:%.c
            @echo "$@ <==== $<"
    
    .PHONY:$(X_c) $(Y_c)

     输出:

    1.o <---- 1.c
    2.o <---- 2.c
    3.o <---- 3.c
    4.o <==== 4.c
    5.o <==== 5.c
    6.o <==== 6.c

    ===

  • 相关阅读:
    2015hust暑假集训 0715 F
    hust2015暑假集训 0715 c a coprime
    0714c
    hdu_1019Least Common Multiple(最小公倍数)
    hdu_1576A/B(扩展欧几里得求逆元)
    hdu_5104 Primes Problem()
    hdu_3483A Very Simple Problem(C(m,n)+快速幂矩阵)
    hdu_2604Queuing(快速幂矩阵)
    hdu_3003Pupu(快速幂)
    神奇的读入读出
  • 原文地址:https://www.cnblogs.com/pengdonglin137/p/9678067.html
Copyright © 2020-2023  润新知