https://mp.weixin.qq.com/s?__biz=MzAxNTAyOTczMw==&mid=2649329385&idx=1&sn=4651ff2ee20dfb87e87ff2ba19add68f&chksm=83976a63b4e0e3758ae5f76a430842b0584195b1d691767c74b7d8e181fc86bb47ea82b52fa6&scene=21#wechat_redirect
    在makefile中有两种变量:
    · 1)简单变量(即时变量):
    A := xxx // A的值即刻确定,在定义时即确定
    对于即时变量使用“:=”表示,它的值在定义的时候已被确定。

    · 2)延时变量
    B = xxx // B的值被使用到时才确定
    对于延时变量使用“=”表示。它只有在使用到的时候才确定,在定义/等于时并没有确定下来。

    想使用变量的时候使用“$”来引用,如果不想看到命令时,可以在命令的前面加上”@”符号,则不会显示命令本身。
    当我们执行make命令的时候,make这个指令本身,会把整个Makefile读进去,进行全部分析,然后解析里面的变量。常用的变量的定义如下:
    := // 即时变量
    = // 延时变量
    ?= // 延时变量, 如果是第一次定义才起效, 如果在前面该变量已定义则忽略这句
    += // 附加, 它是即时变量还是延时变量取决于前面的定义
    ?=: // 如果这个变量在前面已经被定义,这句话就不会起效果。

    实例:
    A := $(C)
    B = $(C)
    C = abc

    #D = 100ask
    D ?= weidongshan

    all:
    @echo A = $(A)
    @echo B = $(B)
    @echo D = $(D)

    C += 123
    执行:
    make

    结果:
    A =
    B = abc 123
    D = weidongshan
    分析:
    1)
    A := $(C):A为即时变量,在定义时即确定,由于刚开始C的值为空,所以A的值也为空。
    2) B = (C):B为延时变量,只有使用到时它的值才确定,当执行make时,会解析Makefile里面的所用变量,所以先解析C=abc, 然后解析C+=123,此时C=abc123,
    当执行:@echoB=(C):B为延时变量,只有使用到时它的值才确定,当执行make时,会解析Makefile里面的所用变量,所以先解析C=abc, 然后解析C+=123,此时,C=abc123,当执行:@echoB=(B) B的值为 abc 123。

    3)
    D ?= weidongshan:D变量在前面没有定义,所以D的值为weidongshan,如果在前面添加D = 100ask,最后D的值为100ask。
    我们还可以通过命令行存入变量的值
    例如执行:
    make D=123456
    里面的D ?= weidongshan这句话便不再起作用。
    结果:
    A =
    B = abc 123
    D = 123456
    GNU Make 使用手册(中译版).pdf