真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯網站制作重慶分公司

qmakesourcecode解讀-創(chuàng)新互聯

qmake的主要功能執(zhí)行入口在main.cpp中的runQMake(int argc, char **argv)中。其主要框架如下:

創(chuàng)新互聯建站長期為超過千家客戶提供的網站建設服務,團隊從業(yè)經驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯網生態(tài)環(huán)境。為安仁企業(yè)提供專業(yè)的成都網站制作、網站設計,安仁網站改版等技術服務。擁有十年豐富建站經驗和眾多成功案例,為您定制開發(fā)。
runQMake(int argc, char **argv){
    QMakeVfs vfs;   //初始化qmake的文件系統(tǒng)。virtual file system。vfs會為每個文件賦予一個id,并提供根據id進行操作的函數。
    Option::vfs = &vfs;    
    QMakeGlobals globals;
    Option::globals = &globals;  globalst提供配置查詢環(huán)境參數和操作環(huán)境變量相關的一些函數。
    .......
    Option::init(argc, argv); //初始化參數
    .....
    QMakeProperty prop; //初始化property。構造函數中調用QMakeProperty 的reload函數。
    ....
    QMakeParser parser(&proFileCache, &vfs, &Option::evalHandler);//創(chuàng)建parser對象,parser的主要作用是將腳本代碼轉換成ProToken類型的數據,并存放到Profile對象中的m_proitems中。
    Option::parser = &parser;
    ......
    QMakeProject project;//創(chuàng)建qmake工程,構造函數參數會使用到option::parser,并賦予成員變量其m_parser,結構中的成員最終用于輔助生成makefile
    //QMakeProject::QMakeProject(): QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler){}  
    .......
    project.read(fn)  //加載和解析(詞法語法語義)配置文件(.prl、pri、.conf、.prf),解析工程pro文件
    ......
    MetaMakefileGenerator *mkfile = MetaMakefileGenerator::createMetaGenerator(&project,         QString(), false, &success); //創(chuàng)建makefile對象向,內部通過生成SubdirsMetaMakefileGenerator或BuildsMetaMakefileGenerator對象,初始化并返回。
    .....
    mkfile->write() //生成Makefile.Debug、Makefile.Release、Makefile三個文件。
}

QMakeProject是整體的架構,他繼承與QMakeEvaluator,用于描述一個qt工程,除了完成處理語法和語義分析的QMakeEvaluator的功能,還會做一些工程相關的處理(比如路徑、緩存文件)。一個QMakeProject對象含有一個用于處理詞法分析的QMakeParser對象成員。QMakeProject做完解析后,作為參數傳入MetaMakefileGenerator對象中,生成makefile文件。

解析從QMakeProject的read函數開始,內部會調用QMakeEvaluator::evaluateFile()。開始進行詞法和語法分析。

詞法分析

QMakeParser對象進行語法分析。QMakeParser主要作用是將qmake language語法的代碼進行標記化(tokenized),將原始代碼全部解析成ProToken類型的數據,解析內容放到Profile對象的m_proItems成員中。主要操作在QMakeParser::read中,read的調用堆棧如下:

//E:\workspace\QtWork\qmake\library\qmakeevaluator.cpp
evaluateFile是執(zhí)行腳本文件的入口函數
QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateFile(
        const QString &fileName, QMakeHandler::EvalFileType type, LoadFlags flags)
{
    QMakeParser::ParseFlags pflags = QMakeParser::ParseUseCache;
    if (!(flags & LoadSilent))
        pflags |= QMakeParser::ParseReportMissing;
    if (ProFile *pro = m_parser->parsedProFile(fileName, pflags)) {
        ProStringList &tiif = m_valuemapStack.first()[ProKey("QMAKE_VISIT_FILES")];
        ProString tifn(fileName);
        if (!tiif.contains(tifn))
            tiif<< tifn;
        m_locationStack.push(m_current);
        VisitReturn ok = visitProFile(pro, type, flags);
        m_current = m_locationStack.pop();
        pro->deref();
        if (ok == ReturnTrue && !(flags & LoadHidden)) {
            ProStringList &iif = m_valuemapStack.first()[ProKey("QMAKE_INTERNAL_INCLUDED_FILES")];
            ProString ifn(fileName);
            if (!iif.contains(ifn))
                iif<< ifn;
        }
        return ok;
    } else {
        debugMsgInternal(0, "failed evaluateing file %s,parse error", qPrintable(fileName));
        return ReturnFalse;
    }
}

--------------------------

parsedProFile作用是判斷文件是否已經被解析,未解析會調用readFile將文件內容讀取到內存中,存放到content變量中,然后調用parsedProBlock解析讀取到的代碼塊。
ProFile *parsedProFile(const QString &fileName, ParseFlags flags) 

parsedProBlock創(chuàng)建profile對象,對具體的代碼塊進行解析,然后返回profile對象
ProFile *parsedProBlock(const QStringRef &contents, int id, const QString &name, int line, SubGrammar grammar)
{
    ProFile *pro = new ProFile(id, name);
    read(pro, contents, line, grammar);
    return pro;
}

parsedProBlock對具體的代碼塊進行解析,可以是一整個文件的代碼,也可以是eval中傳入的小片代碼。
然后返回profile對象。詞法分析階段會進行字符轉義操作,和預處理操作。
void QMakeParser::read(ProFile *pro, const QStringRef &in, int line, SubGrammar grammar){.....}

字符轉義和部分特殊變量的預處理在這個階段進行。引號是否缺乏以及括號是否缺乏會在這個階段得出結果。

語法語義分析

對腳本文件的語法和語義分析用QMakeProject中的成員QMakeEvaluator對象進行處理,一個project對象只有一個QMakeEvaluator成員。在evaluateFile函數中,經過QMakeParser的解析出來的Profile傳遞給QMakeEaluator->visitprofile,開始對內容進行語法和語義分析。主要操作在visitProBlock中,調用堆棧如下。

E:\workspace\QtWork\qmake\library\qmakeevaluator.cpp
visitProfile的作用是在處理工程文件的時候預先加載背后的配置文件,以及處理不同時態(tài)(state)的命令行命令。
同時維護一個m_profileStack棧,用于存放parsed的ProFile。
QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(ProFile *pro, QMakeHandler::EvalFileType type, LoadFlags flags){}


這個visitProBlock調用下面的visitProBlock
QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(ProFile *pro, const ushort *tokPtr)
{
    m_current.pro = pro;
    m_current.line = 0;
    return visitProBlock(tokPtr);
}

這個visitProBlock是進行詞法和語法分析的主要邏輯。所有變量存入到m_valuemapStack中,這是一個棧和鏈表的功能兼有的數據結構類型的成員。
QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock(const ushort *tokPtr)
QMakeEvaluator的幾個重要數據成員
typedef QHashProValueMap;

class ProValueMapStack : public QLinkedList{}

struct ProFunctionDefs {
    QHashtestFunctions;
    QHashreplaceFunctions;
};

class QMakeEvaluator{
    QStackm_profileStack; // Includes only
    ProValueMapStack m_valuemapStack;
    ProFunctionDefs m_functionDefs;
    QStackm_locationStack;
}

QMakeEvaluator::m_valuemapStack:是存放變量的鍵值的數據成員,他的類型如下,兼有鏈表和棧功能操作的數據結構類型的變量,元素類型為ProValueMap類型。ProValueMap是QHash類型。QMakeEvaluator初始化時會往其中push一個ProValueMap對象,這個對象存放全局的變量和值鍵值對。
一個ProValueMap中存放的是一個作用域內的所有變量和值的鍵值對。有子作用域時,會創(chuàng)建一個新的ProValueMap存放該域內的變量名和值。qmake只有兩種作用于,一個是全局的,一個是函數內的。?(qmake language腳本語言的作用域與其他的語言的作用域有點差異,可以參考:qmake language)
QMakeEvaluator初始化時創(chuàng)建一個ProValueMap對象,用于存放全局變量和其值的鍵值對;每次調用自定義函數的時候會創(chuàng)建一個ProValueMap對象,存放該函數內的局部變量和鍵值對。如果函數內有調用的嵌套,會繼續(xù)為嵌套的函數創(chuàng)建ProValueMap對象,新創(chuàng)建的ProValueMap會push到m_valuemapStack中,函數調用結束后再從其中刪除(相應代碼邏輯在QMakeEvaluator::evaluateFunction中)。函數內訪問某個變量會先從該函數的ProValueMap中查找,未找到會到m_valuemapStack的下一層中尋找,直到找到變量或者遍歷完所有變量名。
ProKey 存放變量名,ProStringList存放變量的值(qmake language中只有字符串組的數據類型)。
下面是qmake中訪問一個變量的函數:

//E:\workspace\QtWork\qmake\library\qmakeevaluator.cpp
ProStringList QMakeEvaluator::values(const ProKey &variableName) const
{
    ProValueMapStack::ConstIterator vmi = m_valuemapStack.constEnd();
    for (bool first = true; ; first = false) {
        --vmi;
        ProValueMap::ConstIterator it = (*vmi).constFind(variableName);
        if (it != (*vmi).constEnd()) {
            if (it->constBegin() == statics.fakeValue.constBegin())
                break;
            return *it;
        }
        if (vmi == m_valuemapStack.constBegin())
            break;
        if (first && isFunctParam(variableName))
            break;
    }
    return ProStringList();
}

QMakeEvaluator::m_functionDefs :存放自定義的replace函數和test函數。
QStackm_locationStack:與m_valuemapStack同步使用,用于存放當前解析位置,方便進入子作用域退出后找到解析位置。
statics.functions:存放內置的test函數。
statics.expands:存放內置的replace函數。

m_functionDefs.testFunctions類型是QHash,是函數名與函數定義的鍵值對。ProFunctionDef中也有一個ProFile數據成員對象,用于存放函數定義的Tokens內容,在解析函數的時候會將這個Profile取出來進行解析。

腳本中調用內建函數cache()函數時qmake中的調用堆棧

腳本中調用cache函數的調用堆棧
腳本中調用自定義的replace函數的調用堆棧

qmake訪問replace函數和test函數邏輯。

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateExpandFunction( const ProKey &func, const ushort *&tokPtr, ProStringList *ret)  訪問replace函數
{
    auto isbuildinE = statics.expands.constFind(func);
    if(isbuildinE) evaluateBuiltinExpand(*adef, func, args, *ret);   //expandVariableReferences(tokPtr, 5, &args, true);

    QHash::ConstIterator it =m_functionDefs.replaceFunctions.constFind(func);
    if(it) evaluateFunction(*it, args, ret);  //prepareFunctionArgs(tokPtr, &args);
}

QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConditionalFunction(const ProKey &func, const ushort *&tokPtr)  訪問test函數
{
    auto isbuildinE = statics.functions.constFind(func);
    if(isbuildinT) evaluateBuiltinConditional(*adef, func, args);

    QHash::ConstIterator it =m_functionDefs.testFunctions.constFind(func);
    if(it)  evaluateBoolFunction(*it, args, func);
}
生成makefile

qmake 默認生成三個makefile相關的文件BuildsMetaMakefileGenerator::init()函數中會創(chuàng)建debug和release的MakefileGenerator對象,分別用于生成Makefile.Debug、Makefile.Release文件,BuildsMetaMakefileGenerator對象本身則生成Makefile文件。
具體可參考:如何通過pro文件向moc傳入參數--------qmake組裝makefile中的moc_*.cpp生成規(guī)則

qmake組裝moc_*.cpp生成規(guī)則調用堆棧

編譯使用到的宏開關

QT_CONFIG(process)
PROEVALUATOR_FULL?
QT_BOOTSTRAPPED?
QT_BUILD_QMAKE?
QT_NO_FOREACH?
PARSER_DEBUG

qmake 與 配置文件_丘上人的博客-博客

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧


分享標題:qmakesourcecode解讀-創(chuàng)新互聯
文章URL:http://weahome.cn/article/ceohdo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部