makefile 基础

原创 2013年12月02日 11:27:12
========================================
makefile 的 变量赋值
========================================
1、“=” 最后计算展开后赋值
      make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:
            x = foo
            y = $(x) bar
            x = xyz
      在上例中,y的值将会是 xyz bar ,而不是 foo bar 。

2、“:=” 立即赋值
      “:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。
            x := foo
            y := $(x) bar
            x := xyz
      在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。

?= 是如果没有被赋值过就赋予等号后面的值
    TEMP ?= var
    ifeq($(TEMP),undefined)
        TEMP = var
        endif


+= 是添加等号后面的值

第一阶段:读取所有的makefile文件(包括 include 项,命令行 -f 项)
   内建所有的变量、明确规则和隐含规则,
   并建立所有目标和依赖之间的依赖关系结构链表。

第二阶段:根据第一阶段已经建立的依赖关系结构链表决定哪些目标需要更新,并使用对应的规则来重建这些目标

========================================
makefile  条件语句
========================================

<conditional-directive>
<text-if-true>
else
<text-if-false>
endif

条件语句有ifeq, ifneq, ifdef, ifndef
句法书写举例:
ifeq(argv1,argv2)          # 字符串不用加单引号或双引号
ifdef(variable-name)        # 不能加$, 是变量名字
举例:
如果 strip 函数返回值为空
ifeq($(strip $(foo)),)
xxx
endif


给个例子:
[~/test]$ cat Makefile
foo=abc
ifdef foo
$(warning foo defined)
endif


========================================
makefile 调试
========================================
$(warning)函数
它可以放在makefile 中的任何地方:
开始的位置、工作目标或必要条件列表中以及命令脚本中。
这让你能够在最方便的地方查看变量的输出值

-n 或“--just-print”,那么其只是显示命令,但不会执行命令,
这个功能很有利于我们调试我们的Makefile,

-p 或(--print-data-base) 是另一个你常会用到的选项。显示make 所运行的命令, 然后输出它的内部数据库。
数据库里的数据将会依种类划分

    成以下几个组:
    variables、
    directories、
    implicit rules、
    pattern-specific variables、
    files(explicit rules)以及vpath search path。

-d 是另一个有用的选项。 大量的信息可能让人眼花。

========================================
makefile 控制命令回显。
========================================
“-s”或“--slient”则是全面禁止命令的显示。  
makefile 以tab开头表示命令,

当我们用“@”字符在命令行前,那么,这个命令将不被make显示出来. 为了向屏幕少输出信息。


========================================
makefile 依赖关系
========================================
----------------------------------------
有问题的最简单的Makefile
----------------------------------------
all:
    gcc  -o main main.o
main.o: main.c
    gcc -c -o main.o main.c
clean:
    rm *.o main

运行make, 提示如下错误:
gcc  -o main main.o
gcc: main.o: No such file or directory
gcc: no input files
make: *** [all] Error 1

我很奇怪,不是告诉它main.o 依赖main.c 吗,按定义的规则去生成。
而且我查看了make -d 的输出,发现其并没有继续检查main.o 的依赖关系。
后来我对比了正确的makefile 写法, 发现要把main.o 写在all 的右边才能作为依赖
才能使makefile继续检查它的生成关系。
如果你使用隐含规则,甚至不用写.c 生成.o 的规则。
----------------------------------------
下面是正确的写法:all 右边有依赖
----------------------------------------
all:main.o
    gcc  -o main main.o
clean:
    rm *.o main
运行make 的结果:
[root@hjj /home/samba/testapp]# make
cc    -c -o main.o main.c
gcc  -o main main.o

********************************************************************************

makefile 的 V=1 起了什么作用?
makefile 可以在命令行为宏变量赋值
ifeq ("$(origin V)", "command line")
KBUILD_VERBOSE = $(V)
endif

ifndef KBUILD_VERBOSE
KBUILD_VERBOSE = 0
endif
********************************************************************************




版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

Makefile debug的经验

1. 使用warning指令 warning 是个不错的命令,可以打印出消息,来判断makefile执行的流程     如 , 这是一个普通的编译kernel module的Makefile,但是我忘...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)