《GNU_makefile》第五章——为规则书写命令

Posted yangxinrui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《GNU_makefile》第五章——为规则书写命令相关的知识,希望对你有一定的参考价值。

1.

  使用make的命令行参数-n或--just-print,make会只显示要执行的命令,不执行,这样方便调试makefile。

2.执行命令

  每写一行命令,make会fork出一个shell进程来执行该命令,如果要让shell连续执行多条语句,使用 ; 链接命令。

  SHELL环境变量指定make使用的shell程序.

3.并发执行

  使用命令行选项-j指定make最多fork多少个shell进程去执行命令。

4.命令执行的错误

  命令执行错误返回非0,make放弃对后续命令的执行。

  使用 -,让make忽略命令执行错误。

  如: -rm *.o

5.

6.递归执行命令

subsystem:
    cd subdir && $(MAKE)
其等价于规则:
subsystem:
    $(MAKE) -C subdir

  make只将 命令定义变量(如 CFLAGS),环境变量(export xxx)传递给子make。

  export 的一个变量或函数的引用,会被立即展开。

Y = Z
export X=$(Y)

  不带任何参数的 export 指示符,会将所有变量传递给子make,但不但任何参数的unexport没有任何意义。

  在多级make中,变量 MAKELEVEL 代表了调用深度,最上层为0,依次加1

Main 目录下的 Makefile 清单如下:
#maindir Makefile
………
………
.PHONY :test
test:
    @echo “main makelevel = $(MAKELEVEL)”
    @$(MAKE) –C subdir dislevel
#subdir Makefile
………..
………..
.PHONY : test
test :
    @echo “subdir makelevel = $(MAKELEVEL)”
在 maindir 目录下执行“ make test”。将显式如下信息:
main makelevel = 0
make[1]: Entering directory `/…../ subdir subdir makelevel = 1
make[1]: Leaving directory `/…../ subdir 
这个变量主要用在条件测试指令中。例如:我们可以通过测试此变量的值来决定是
否执行递归方式的 make 调用或者其他方式的 make 调用。我们希望一个子目录必须被
上层 make 调用才可以执行此目录下的 Makefile,而不允许直接在此目录下执行 make。
我们可以这样实现:
.......
ifeq ($(MAKELEVEL),0)
all : msg
else
all : other
endif
……
…...
msg:
@echo ”Can not make in this directory!”

  命令行参数之所以可以传递给子make,是因为命令行参数借助环境变量MAKEFLAGS传递。

        “-C”、“ -f”、“ -o”和“ -W”。 这些命令行选项是不会被赋值给变量“ MAKEFLAGS”的 

  -j虽然会被传递,但子make和主控make会进行通信,保证整个进程数不超过-j设置的值。

  当不希望MAKEFLAGS传递给子make,可以将其置空

subsystem:
    cd subdir && $(MAKE) MAKEFLAGS=

 

7.定义命令包

  命令包和C语言中的宏一样。

  如

define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef

  命令包的使用,命令包在运行阶段被展开,和宏一样,是完全替换

foo.c : foo.y
    $(run-yacc)

--》
foo.c : foo.y
    yacc $(firstword $^)
    mv y.tab.c $@

  在$(run-yacc)前一个tab,导致命令包每个命令前都加一个tab

 

以上是关于《GNU_makefile》第五章——为规则书写命令的主要内容,如果未能解决你的问题,请参考以下文章

JAVA-初步认识-第五章-数组-常见操作-排序位置

第五章学习小结

第五章 复杂查询 5-1 视图

第五章 jQuery基础及选择器

构建之法第第五章读后感

java第五章:面向对象(oop)