qmake language 关键字 true false host_build option return next break ever forever LITERAL_HASH

 使用qt版本 5.12.0

目录

简介

语法相关的关键字

qmake内置变量

qmake内置函数

杂谈


简介

qmake language中true和false与C/C++中true false是有区别的!qmake language中true和false都有两重意思,作为非判断语句的条件时,他们就是字符串;作为判断语句的条件时,true和false才会被qmake做关键字解释,true会被解析成C++中的bool类型的true,false会被解析成C++中bool类型的false。

语法相关的关键字


1、qmake的C++源码为qmake language定义的内置函数:qmake language 内置函数 自定义函数
2、ever、forever、else、for、return、next、break用于条件语句和循环语句:qmake language 
3、option、host_build,两者需要结合使用:option(host_build)。host_build其作用的地方在bool QMakeEvaluator::loadSpec()中,用于决定是生成QMAKE_SPEC(host主机)指定的架构的build还是QMAKE_XSPEC(target目标机)指定的架构的build。设置host_build为true,则生成QMAKE_SPEC指定的架构的build。
host_build是与true、 false关键字一样的关键字,也具有两重意思,区别在作为判断语句的条件时qmake根据配置情况会将host_build解析成C++的bool类型的truefalse,不是作为判断条件时会被当成字符串严格来说,qmake language中没有bool类型。只是qmake进行解析时将qmake language的关键字true固定解析成C++的bool的true,将qmake language的关键字false固定解析成C++中bool的false。而对于host_build,qmake会根据具体的配置将其解析成C++的true或false。
案例:

tt=true
true=ttt         #将字符串ttt赋予给名字为true的变量。
ttv=$$tt         #$$tt的值为字符串true,将字符串true传递给ttv。注意这里的操作不叫bool类型变量值传递。因为没有bool类型变量的概念。
ttv=host_build   #将字符串host_build赋予给变量ttv
ttv1=$$host_build#将名字为host_build的变量的值赋予给ttv1,因为没有定义host_build的变量,所以host_build的值为空。  


message($$tt)    #输出true  在qmake language中true应该只视为关键字,而不应该理解为常规意义的
message($$true)  #输出:Project MESSAGE: ttt
message($$ttv)   #输出host_build  host_build与true false是同等级的关键字,因为不是条件语句,在此host_build只是字符串
message($$ttv1)   #输出为空

host_build{message(here1)}  #输出here1  qmake解析判定条件时会计算判定条件,并将判定条件解析成C++的bool,host_build在被qmake解析时被解析成C++的bool类型。
else{message(here2)}

$$tt{message(here1)}    #$$tt就是关键字true,在此true作为条件语句,会被解析成C++的bool类型的true。输出here1
else{message(here2)}

$$ttv{message(here1)}   #$$ttv就是关键字host_build。在此true作为条件语句,会被解析成C++的bool类型。具体值qmake根据具体配置进行赋予。输出here1
else{message(here2)}

option、host_build的处理逻辑:

4、build_pass,一个特殊的CONFIG属性,qmake在build的阶段会主动加入CONFIG中

build_pass:message(here1)   #build_pass特殊变量,语句的意思表示冒号后面的代码块只执行一遍。

qmake内置变量

qmake内置变量,也就是qmake C++源码直接为qmake language初始化的变量qmake language写的配置文件中定义的变量。
1、特殊处理的内置变量:_LINE_(当前行号)、_FILE_(当前文件名)、LITERAL_HASH(字符#)、LITERAL_DOLLAR(字符$)、LITERAL_WHITESPACE(制表符tab键),相当于qmake language的预处理

var=aaaa
message($var)     #单个$在qmake中就被当做普通字符处理。两个$$符才会被当做取值符号处理。
message($$var)
message($$variablenotexist)
message($variablenotexist)
message(aa$${_LINE_}bb)
message(aa$${_FILE_}bb)
message(aa$${LITERAL_HASH}bb)
message(aa$${LITERAL_DOLLAR}bb)
message(aa$${LITERAL_WHITESPACE}bb)
#输出:
#Project MESSAGE: $var
#Project MESSAGE: aaaa
#Project MESSAGE: 
#Project MESSAGE: $variablenotexist
#Project MESSAGE: aa31bb
#Project MESSAGE: aaE:/workspace/QtWork/testEmpty/testEmpty.probb
#Project MESSAGE: aa#bb
#Project MESSAGE: aa$bb
#Project MESSAGE: aa	bb

qmake 对pro文件的预处理的C++源码: 

//E:\workspace\QtWork\qmake\library\qmakeparser.cpp
bool QMakeParser::resolveVariable(ushort *xprPtr, int tlen, int needSep, ushort **ptr,
                                  ushort **buf, QString *xprBuff,
                                  ushort **tokPtr, QString *tokBuff,
                                  const ushort *cur, const QStringRef &in)
{
    QString out;
    m_tmp.setRawData((const QChar *)xprPtr, tlen);
    if (m_tmp == statics.strLINE) {
        out.setNum(m_lineNo);
    } else if (m_tmp == statics.strFILE) {
        out = m_proFile->fileName();
        // The string is typically longer than the variable reference, so we need
        // to ensure that there is enough space in the output buffer - as unlikely
        // as an overflow is to actually happen in practice.
        int need = (in.length() - (cur - (const ushort *)in.constData()) + 2) * 5 + out.length();
        int tused = *tokPtr - (ushort *)tokBuff->constData();
        int xused;
        int total;
        bool ptrFinal = xprPtr >= (ushort *)tokBuff->constData()
                && xprPtr < (ushort *)tokBuff->constData() + tokBuff->capacity();
        if (ptrFinal) {
            xused = xprPtr - (ushort *)tokBuff->constData();
            total = xused + need;
        } else {
            xused = xprPtr - *buf;
            total = tused + xused + need;
        }
        if (tokBuff->capacity() < total) {
            tokBuff->reserve(total);
            *tokPtr = (ushort *)tokBuff->constData() + tused;
            xprBuff->reserve(total);
            *buf = (ushort *)xprBuff->constData();
            xprPtr = (ptrFinal ? (ushort *)tokBuff->constData() : *buf) + xused;
        }
    } else if (m_tmp == statics.strLITERAL_HASH) {
        out = QLatin1String("#");
    } else if (m_tmp == statics.strLITERAL_DOLLAR) {
        out = QLatin1String("$");
    } else if (m_tmp == statics.strLITERAL_WHITESPACE) {
        out = QLatin1String("\t");
    } else {
        return false;
    }
    xprPtr -= 2; // Was set up for variable reference
    xprPtr[-2] = TokLiteral | needSep;
    xprPtr[-1] = out.length();
    memcpy(xprPtr, out.constData(), out.length() * 2);
    *ptr = xprPtr + out.length();
    return true;
}

2、ARGS、ARGC、1、2、.... 用于函数参数:qmake language 内置函数 自定义函数  
3、qmake帮助手册中对通用内置变量介绍,这包括qmake源码端定义的变量和部分用qmake language写的配置文件中定义的变量:Qt 5.12->qmake Manual->Variables,手册中介绍的是部分的,但是不全。

qmake内置函数

1、defineTest、defineReplace用于定义函数:qmake language 内置函数 自定义函数 
2、bypassNesting,qmake内部为qmake language定义的特殊函数:bypassNesting() 
3、内部定义的test函数和replace函数 :qmake language 内置函数 自定义函数 
qmake帮助手册对内置函数介绍位置:
Qt 5.12->qmake Manual->Test Functions
Qt 5.12->qmake Manual->Replace Functions

杂谈

qmake源码列举的部分关键字,注意,这里不是关键字的定义,有的关键字并没有明确的给出定义,在解析的时候直接匹配解析了。 

//QrInstallDir\Qt5.12.0\5.12.0\Src\qtbase\qmake\library\qmakeevaluator.cpp
void QMakeEvaluator::initStatics()
{
    if (!statics.field_sep.isNull())
        return;

    statics.field_sep = QLatin1String(" ");
    statics.strtrue = QLatin1String("true");
    statics.strfalse = QLatin1String("false");
    statics.strCONFIG = ProKey("CONFIG");
    statics.strARGS = ProKey("ARGS");
    statics.strARGC = ProKey("ARGC");
    statics.strDot = QLatin1String(".");
    statics.strDotDot = QLatin1String("..");
    statics.strever = QLatin1String("ever");
    statics.strforever = QLatin1String("forever");
    statics.strhost_build = QLatin1String("host_build");  //host_build关键字。
    statics.strTEMPLATE = ProKey("TEMPLATE");
    statics.strQMAKE_PLATFORM = ProKey("QMAKE_PLATFORM");
    statics.strQMAKE_DIR_SEP = ProKey("QMAKE_DIR_SEP");
    statics.strQMAKESPEC = ProKey("QMAKESPEC");
#ifdef PROEVALUATOR_FULL
    statics.strREQUIRES = ProKey("REQUIRES");
#endif
.....
}


//QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\qmake\library\qmakeparser.cpp
void QMakeParser::initialize()
{
    if (!statics.strelse.isNull())
        return;

    statics.strelse = QLatin1String("else");
    statics.strfor = QLatin1String("for");
    statics.strdefineTest = QLatin1String("defineTest");
    statics.strdefineReplace = QLatin1String("defineReplace");
    statics.strbypassNesting = QLatin1String("bypassNesting");
    statics.stroption = QLatin1String("option");
    statics.strreturn = QLatin1String("return");
    statics.strnext = QLatin1String("next");
    statics.strbreak = QLatin1String("break");
    statics.strhost_build = QLatin1String("host_build");
    statics.strLINE = QLatin1String("_LINE_");
    statics.strFILE = QLatin1String("_FILE_");
    statics.strLITERAL_HASH = QLatin1String("LITERAL_HASH");
    statics.strLITERAL_DOLLAR = QLatin1String("LITERAL_DOLLAR");
    statics.strLITERAL_WHITESPACE = QLatin1String("LITERAL_WHITESPACE");
}

//QtInstallDir\Qt5.12.0\5.12.0\Src\qtbase\qmake\library\proitems.h
class QMAKE_EXPORT ProFile
{
.....
    bool isHostBuild() const { return m_hostBuild; }
    void setHostBuild(bool host_build) { m_hostBuild = host_build; }
.....
}

 qmake 源码中为qmake language定义内置变量的方式就是直接往qmake language的堆栈中压入变量,下面是qmake为qmake language定义内置变量TARGET、_PRO_FILE_、_PRO_FILE_PWD_、OUT_PWD的方式:

void QMakeEvaluator::setupProject()
{
    setTemplate();
    ProValueMap &vars = m_valuemapStack.top();
    int proFile = currentFileId();
    vars[ProKey("TARGET")] << ProString(QFileInfo(currentFileName()).baseName()).setSource(proFile);
    vars[ProKey("_PRO_FILE_")] << ProString(currentFileName()).setSource(proFile);
    vars[ProKey("_PRO_FILE_PWD_")] << ProString(currentDirectory()).setSource(proFile);
    vars[ProKey("OUT_PWD")] << ProString(m_outputDir).setSource(proFile);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值