zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    多测师讲解html _伪类选择器17_高级讲师肖sir
    多测师讲解html _后代选择器16_高级讲师肖sir
    多测师讲解html _组合选择器_高级讲师肖sir
    多测师讲解html _标签选择器14_高级讲师肖sir
    前端 HTML form表单标签 input标签 type属性 重置按钮 reset
    前端 HTML form表单标签 textarea标签 多行文本
    前端 HTML form表单标签 input标签 type属性 file 上传文件
    前端 HTML form表单标签 input标签 type属性 radio 单选框
    前端 HTML form表单标签 input标签 type属性 checkbox 多选框
    前端 HTML form表单目录
  • 原文地址:https://www.cnblogs.com/RabbitHu/p/makefile_tab.html
Copyright © 2011-2022 走看看