美文网首页
Makefile书写命令相关内容

Makefile书写命令相关内容

作者: chenwr2018 | 来源:发表于2019-03-05 20:13 被阅读0次

    一、命令显示

    1.@关闭命令的回显
    2.make带入参数“-n”或“--just-print”,只是显示命令,但不会执行命令,这个功能方便调试 Makefile。
    3.make 参数“-s”或“--slient”全面禁止命令的显示。

    二、命令执行

    make 逐条执行其后的命令。
    如果打算上一条命令结果应用到下一条命令,需要把要执行的命令写在同一行使用分号;隔开。

    test:
        cd ./path1
        pwd
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    cd ./path1
    pwd
    /home/workspace/my_workspace/study/makefile
    
    test:
        cd ./path1;pwd
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    cd ./path1;pwd
    /home/workspace/my_workspace/study/makefile/path1
    

    三、命令出错

    makefile使用mkdir创建目录时,不存在时makefile正常运行,但是目录存在则无法mkdir时出现报错,这个并不应该影响到后面命令的执行。

    test:
        @mkdir path1
        @echo continue
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    mkdir: cannot create directory ‘path1’: File exists
    make: *** [test] Error 1
    

    命令执行错误直接终止。
    解决办法
    (1)Makefile命令行前加一个减号-
    (2)全局的办法,给 make 加上“-i”或是“--ignore-errors”参数。

    test:
        -@mkdir path1
        @echo continue
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    mkdir: cannot create directory ‘path1’: File exists
    make: [test] Error 1 (ignored)
    continue
    
    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test --ignore-errors
    mkdir: cannot create directory ‘path1’: File exists
    make: [test] Error 1 (ignored)
    continue
    

    如果一个规则是以“.IGNORE”作为目标的,那么这个规则中的所有命令将会忽略错误。

    .IGNORE: test
    test:
        @mkdir path1
        @cat no_exist_file
        @echo continue
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    mkdir: cannot create directory ‘path1’: File exists
    make: [test] Error 1 (ignored)
    cat: no_exist_file: No such file or directory
    make: [test] Error 1 (ignored)
    continue
    

    四、嵌套执行make

    根据功能和模块将相关的文件放置在不同的文件夹中,每个文件夹中单独创建一个Makefile来进行管理维护。最外层有个总控Makefile,可以实现全编译。

    定义$(MAKE)宏变量的意思是,定义成一个变量便于make参数传递,利于维护。

    subdir = ./path1
    test:
        cd $(subdir) && $(MAKE)
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    cd ./path1 && make
    make[1]: Entering directory `/home/workspace/my_workspace/study/makefile/path1'
    gcc -c hello.c
    make[1]: Leaving directory `/home/workspace/my_workspace/study/makefile/path1'
    

    总控Makefile中的参数要传递给子目录下的Makefile。
    只需在总控Makefile的变量前添加export即可,相反如果特定变量不想传递下去则使用unexport。
    总控Makefile

    export subdir = ./path1
    test:
        cd $(subdir) && $(MAKE)
    

    子目录path1中的Makefile

    hello.o: hello.c
        gcc -c hello.c
        echo $(subdir)
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    cd ./path1 && make
    make[1]: Entering directory `/home/workspace/my_workspace/study/makefile/path1'
    gcc -c hello.c
    echo ./path1
    ./path1
    make[1]: Leaving directory `/home/workspace/my_workspace/study/makefile/path1'
    

    如果很多变量要传递,只需要添加export关键字,后面不需要跟变量名。

    export 
    subdir = ./path1
    other = 666
    test:
        cd $(subdir) && $(MAKE) && rm *.o
    

    运行结果:

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make test
    cd ./path1 && make && rm *.o
    make[1]: Entering directory `/home/workspace/my_workspace/study/makefile/path1'
    gcc -c hello.c
    ./path1
    666
    make[1]: Leaving directory `/home/workspace/my_workspace/study/makefile/path1'
    

    注意:
    SHELL、MAKEFLAGE这两个变量比较特殊,不管是否export它们都会传递到子目录Makefile中。MAKEFLAGE还是系统级别的环境变量。

    总控Makefile定义的变量传递到下级Makefile中,如果下级Makefile有定义同名的变量。下级Makefile变量值不会被覆盖。如果想要覆盖,执行makefile的时传递参数-e
    -e, --environment-overrides
    Environment variables override makefiles.
    覆盖makefile环境变量。

    make的参数还蛮多的

    root@chenwr-pc:/home/workspace/my_workspace/study/makefile# make --help
    Usage: make [options] [target] ...
    Options:
      -b, -m                      Ignored for compatibility.
                                  (忽略的兼容性)
      -B, --always-make           Unconditionally make all targets.
                                  (无条件完成所有目标)
      -C DIRECTORY, --directory=DIRECTORY
                                  Change to DIRECTORY before doing anything.
                                  (在做任何事情之前切换到目录)
      -d                          Print lots of debugging information.
                                  (打印大量调试信息)
      --debug[=FLAGS]             Print various types of debugging information.
                                  (打印各种类型的调试信息)
      -e, --environment-overrides
                                  Environment variables override makefiles.
                                  (环境变量覆盖makefile)
      -f FILE, --file=FILE, --makefile=FILE
                                  Read FILE as a makefile.
                                  (将文件读取为makefile)
      -h, --help                  Print this message and exit.
                                  (打印该信息并退出)
      -i, --ignore-errors         Ignore errors from commands.
                                  (忽略来自命令的错误)
      -I DIRECTORY, --include-dir=DIRECTORY
                                  Search DIRECTORY for included makefiles.
                                  (搜索包含makefile的目录)
      -j [N], --jobs[=N]          Allow N jobs at once; infinite jobs with no arg.
                                  (一次允许N个作业;没有参数的无限作业)
      -k, --keep-going            Keep going when some targets can't be made.
                                  (当一些目标无法达成时,继续执行)
      -l [N], --load-average[=N], --max-load[=N]
                                  Don't start multiple jobs unless load is below N.
                                  (除非负载小于N,否则不要启动多个作业)
      -L, --check-symlink-times   Use the latest mtime between symlinks and target.
                                  (使用符号链接和目标之间的最新时间)
      -n, --just-print, --dry-run, --recon
                                  Don't actually run any commands; just print them.
                                  (不要实际运行任何命令;只是打印)
      -o FILE, --old-file=FILE, --assume-old=FILE
                                  Consider FILE to be very old and don't remake it.
                                  (考虑文件是非常旧的,不要重新创建)
      -p, --print-data-base       Print make's internal database.
                                  (打印make的内部数据库)
      -q, --question              Run no commands; exit status says if up to date.
                                  (运行任何命令;退出状态表示是否最新)
      -r, --no-builtin-rules      Disable the built-in implicit rules.
                                  (禁用内置的隐式规则)
      -R, --no-builtin-variables  Disable the built-in variable settings.
                                  (禁用内置变量设置)
      -s, --silent, --quiet       Don't echo commands.
                                  (不要echo命令)
      -S, --no-keep-going, --stop
                                  Turns off -k.
      -t, --touch                 Touch targets instead of remaking them.
                                  (触摸目标,而不是重做)
      -v, --version               Print the version number of make and exit.
                                  (打印make和exit的版本号)
      -w, --print-directory       Print the current directory.
                                  (打印当前目录)
      --no-print-directory        Turn off -w, even if it was turned on implicitly.
                                  (关闭-w,即使它是隐式打开的)
      -W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE
                                  Consider FILE to be infinitely new.
                                  (认为文件是无限新的)
      --warn-undefined-variables  Warn when an undefined variable is referenced.
                                  (引用未定义的变量时发出警告)
    
    This program built for x86_64-pc-linux-gnu
    Report bugs to <bug-make@gnu.org>
    

    make 的参数“-k”或“--keep-going”,参数意思是,如果某规则中的命令出错了,那么就终目该规则的执行,但继续执行其它规则。

    但是 make 命令中的有几个参数并不往下传递,它们是“-C”,“-f”,“-h”“-o”和“-W”。
    当你使用“-C”参数来指定 make 下层 Makefile 时,“-w”会被自动打开的。如果参数中有“-s”(“--slient”)或是“--no-print-directory”,那么,“-w”总是失效的。

    五、定义命令包

    makefile中的命令包写法类似C语言中的define

    define my_action
    touch smile
    endef
    
    test:
        $(my_action)
    

    定义一个my_action 它的功能是创建个smile文件。调用方式也跟引用变量的方式是一样的。make 在执行命令包时,命令包中的每个命令会被依次独立执行。

    相关文章

      网友评论

          本文标题:Makefile书写命令相关内容

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