• Makefile中的tab缩进


    Makefile中的Tab缩进

    这学期选了OOP课,写了条笔记。

    makefile中的缩进的问题,要从makefile的基本结构说起:

    target: prerequisite
    	recipe (shell commands)
    

    注意这个缩进是个tab,而且只能是tab,不能是空格。在makefile中,tab和空格是严格区分开的。每一句recipe(就是要执行的shell命令)的开头,都必须有一个tab。而makefile中的其他东西,例如target: prerequisiteifeq、变量赋值等等,前面一般不能有tab。也就是说,开头有没有tab是区分“makefile中的shell命令(recipe)”和“makefile中的其他语句”的标志。二者作用不同、语法不同,可以说是两套系统,大家一定要严格区分开。

    例1:变量

    例如,makefile中的变量和shell中的变量,是两种不同的东西。举个例子:

    VAR=foo
    all:
    	VAR=bar; echo $$VAR; echo $(VAR)
    # 这里分号的作用:在同一行写多条shell命令
    

    这个makefile运行后,输出的是:

    VAR=bar; echo $VAR; echo foo
    bar
    foo
    

    让我们逐条分辨一下这个makefile中每一个变量“VAR”的身份。

    语句 功能
    VAR=foo 定义一个makefile变量"VAR",赋值为"foo"
    VAR=bar 执行shell命令VAR=bar,即:定义一个shell变量"VAR",赋值为"bar"
    echo $$VAR 执行shell命令echo $VAR(makefile中打两个$是为了转义,
    相当于在shell中打了一个$),即:输出shell变量"VAR"的值
    echo $(VAR) 将$(VAR)替换成makefile变量"VAR"的值后,执行shell命令,
    即:执行shell命令echo foo

    请关注VAR=foo一句和VAR=bar一句的区别:正是前面有无tab的区别,导致前者是makefile变量操作,而后者是规则(rule)all: ...中的一条recipe。

    例2:ifeq

    另外需要注意的是,在ifeq之类的控制语句的语句体中,是不需要额外缩进的。ifeq的作用范围,由endif的位置决定;而决定是否缩进的,只有recipe和非recipe的区别。举个极端的例子:

    all:
    	echo $(VAR)
    
    FLAG=TRUE
    VAR=foo
    
    ifeq (TRUE, $(FLAG))
    	VAR=bar
    endif
    

    上面这个makefile中,如果倒数第二行想要操作makefile中的VAR变量的话,用tab缩进是不对的,应该直接顶格写,或者打若干空格也行(只要没有tab,效果就和没缩进一样)。

    但是,如果对上面这个“错误”的代码运行make,依然会输出和顶格写相同的结果:

    echo bar
    bar
    

    也就是说,尽管倒数第二行的开头有tab,VAR=bar仍然被识别成makefile变量操作,而不是shell命令——这是因为它的位置比较特殊,不属于任何规则,所以没被识别成shell命令。

    但是,一旦我们在ifeq前面插入一条规则:

    all:
    	echo $(VAR)
    
    FLAG=TRUE
    VAR=foo
    
    dummy:
    
    ifeq (TRUE, $(FLAG))
    	VAR=bar
    endif
    

    再运行make,输出就会变成:

    echo foo
    foo
    

    这是因为VAR=bar一句这次被识别成dummy: ...这条规则中的一条recipe了。为了验证,可以运行make dummy试试,果然输出了VAR=bar,这意味着VAR=bar一句确实被当做shell命令执行了。

    为了避免这样令人迷惑的事情,我们写makefile的时候,还是不要在非recipe语句的前面加tab了,直接写成:

    all:
    	echo $(VAR)
    
    FLAG=TRUE
    VAR=foo
    
    dummy:
    
    ifeq (TRUE, $(FLAG))
    VAR=bar
    endif
    

    就可以保证无论有无dummy:一行,输出结果都是:

    echo bar
    bar
    
    本文作者:胡小兔
    博客地址:http://rabbithu.cnblogs.com
  • 相关阅读:
    [编程题]多多的数字组合
    mac传输文件到服务器
    git 清除缓存、查看add内容
    go build
    vim编辑器
    Git: clone指定分支
    查看端口占用以及kill
    curl小记录
    Python3.9 malloc error: can’t allocate region
    设计模式-策略模式
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/makefile_tab.html
Copyright © 2020-2023  润新知