本文主要是介绍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类型的true或false,不是作为判断条件时会被当成字符串。严格来说,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 referencexprPtr[-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_FULLstatics.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);
}
这篇关于qmake language 关键字 true false host_build option return next break ever forever LITERAL_HASH的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!