1. 程式人生 > >[QT]VS中Qt自動生成moc_XXX.cpp檔案的一些問題

[QT]VS中Qt自動生成moc_XXX.cpp檔案的一些問題

原創文章,歡迎轉載。轉載請註明:轉載自 祥的部落格

1.問題來源

Qt會自己先把用到Qt自己的東西編譯一遍,變成標準C++編譯器可以識別的東西。

moc 全稱是 Meta-Object Compiler,也就是“元物件編譯器”。Qt 程式在交由標準編譯器編譯之前,先要使用 moc 分析 C++ 原始檔。如果它發現在一個頭檔案中包含了巨集 Q_OBJECT,則會生成另外一個 C++ 原始檔。這個原始檔中包含了 Q_OBJECT 巨集的實現程式碼。這個新的檔名字將會是原檔名前面加上 moc_ 構成。這個新的檔案同樣將進入編譯系統,最終被連結到二進位制程式碼中去。因此我們可以知道,這個新的檔案不是“替換”掉舊的檔案,而是與原檔案一起參與編譯。另外,我們還可以看出一點,moc 的執行是在前處理器之前。因為前處理器執行之後,Q_OBJECT 巨集就不存在了。

我一直用Release|Win32模式進行開發,基本都用qDebug()進行除錯,一般不會在Debug模式下進行除錯,有一次手殘(or NC),把Generated/Debug 下的moc_XXX.cpp全刪除了(是在VS的工程專案中刪除的,在資料夾中刪除了,無所謂,每次編譯的時候,會自動moc,這個過程是你XXX.cpp檔案的設定)。

不知道是多久之前,乾的蠢事,Release模式下,各種OK,突然要用Debug模式了,發現編譯不過,然後引發各種問題,下面將解決的過程進行還原(降低了挑戰難度,表情:笑著哭)

2.錯誤LNK2001 以及解決

當我刪除Generated/Debug 中的 moc_bridge.cpp

時,在Release模式下,編譯執行都沒什麼影響,但是在切換到Debug後,連結生成exe就會報錯,熟悉的error LNK2001,就是說刪除的moc_bridge.cpp 才會把bridge.cpp裡面的函式生成為.obj檔案,所以不能刪除。

IMG20180701024146.png

1>bridge.obj : error LNK2001: 無法解析的外部符號 “public: virtual struct QMetaObject const * __thiscall bridge::metaObject(void)const ” ([email protected]@@[email protected]

@XZ)
1>bridge.obj : error LNK2001: 無法解析的外部符號 “public: virtual void * __thiscall bridge::qt_metacast(char const *)” ([email protected]@@[email protected])
1>bridge.obj : error LNK2001: 無法解析的外部符號 “public: virtual int __thiscall bridge::qt_metacall(enum QMetaObject::Call,int,void * *)” ([email protected]@@[email protected]@@[email protected])

IMG20180701023953

那麼我直接將刪除的moc_bridge.cpp檔案新增進Generated/Debug 中,這樣Debug模式下,程式就可以正常的編譯運行了。

IMG20180701024199

3.警告LNK4042 以及解決

但是!在Release模式下編譯連結,會出現一個Warning

1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(942,5): warning MSB8027: Two or more files with the name of moc_bridge.cpp will produce outputs to the same location. This can lead to an incorrect build result. The files involved are GeneratedFiles\Debug\moc_bridge.cpp, GeneratedFiles\Release\moc_bridge.cpp.
1> moc_bridge.cpp
1>Release\moc_bridge.obj : warning LNK4042: 物件被多次指定;已忽略多餘的指定

這裡寫圖片描述

這是因為,參與編譯連結的有兩個moc_bridge.cpp,一個是Generated/Debug 中的,一個是Generated/Release 中的。但是,這裡面有這麼多個相同的moc_XXX.cpp,為什麼要針對我刪除的這個?

IMG20180701025724

經過我嘔心瀝血的對比查詢,發現就是一個設定的問題,需要修改QtWebTest.vcxproj這個檔案。

IMG20180701030048

Notepad++開啟(開啟前關閉專案,可以使用各種文字編輯器,本人習慣用Notepad++,神器),找到GeneratedFiles\Debug\moc_bridge.cpp對應的部分。

  <ItemGroup>

      ... ...

    <ClCompile Include="GeneratedFiles\Debug\moc_bridge.cpp" />
    <ClCompile Include="GeneratedFiles\Debug\moc_checkConfigPath.cpp">
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="GeneratedFiles\Debug\moc_ComThread.cpp">
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
    </ClCompile>

      ... ...



    <ClCompile Include="GeneratedFiles\Release\moc_bridge.cpp">
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="GeneratedFiles\Release\moc_checkConfigPath.cpp">
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
    </ClCompile>
    <ClCompile Include="GeneratedFiles\Release\moc_ComThread.cpp">
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
    </ClCompile>


      ... ...   



  </ItemGroup>

對比可以看出,相較於GeneratedFiles\Debug\moc_checkConfigPath.cppGeneratedFiles\Debug\moc_ComThread.cpp,我們主要在乎的物件GeneratedFiles\Debug\moc_bridge.cpp缺少了,一個子節點標籤

<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
true
</ExcludedFromBuild>

這句話是啥意思?翻譯成人話就是:
當專案處在Release|Win32模式下,這個GeneratedFiles\Debug\moc_bridge.cpp不進行Build(生成解決方案),這樣就可以理解了,下面的GeneratedFiles\Release\moc_bridge.cpp等檔案,也是設定了在Debug|Win32Debug|x64下,排除Build

改過之後,No warning。大功告成,Enjoy!

4.反思

排除這個warning的過程其實是很痛苦的,現在看著思路很清晰,但真實情況是各種碰壁,我當初是吧整個GeneratedFiles\Debug 都刪除了,根本沒有對比的物件(表情:笑著哭),我是對比一些好的工程,進行分析,除了分析XXXX.vcxproj檔案外,還主要分析了檔案XXXX.vcxproj.filters。各種碰壁,不過好在機智的解決了問題,這就是不精通Qt編譯原理,以及被IDE整合開發環境慣壞了的 傳統教訓!!!

讚賞碼New

相關推薦

[QT]VSQt自動生成moc_XXX.cpp檔案一些問題

原創文章,歡迎轉載。轉載請註明:轉載自 祥的部落格 1.問題來源 Qt會自己先把用到Qt自己的東西編譯一遍,變成標準C++編譯器可以識別的東西。 moc 全稱是 Meta-Object Compiler,也就是“元物件編譯器

vsQT專案的路徑配置

1.新建一個QT專案,然後選中專案名稱,之後點選選單欄的 專案-屬性。 2.然後點選VC++目錄-包含目錄,再.點選右邊的下三角按鈕,接著點選 “編輯”。 3.設定包含目錄。點選上面最左邊的“新建一行”的圖示,接著點選 右邊的“瀏覽”按鈕將QT的包含目錄新增進來。 再

解決QT+VS無法打開ui_*.h文件

結構 tools 項目 ima com lan sign 技術分享 等待 在VS中添加插件Qt VS Tools,就可以在VS中寫QT項目了,但是VS中寫QT項目和在QT Creater中並不完全一樣,VS中的項目文件結構是: 但是如圖中的ui_SignalAndSlot

vsqt結合opengl搭建

1、QT分為MSVC和MINGW版本,是支援的兩種不同的編譯器 MSVC是指微軟的VC編譯器,做Windows應用首選,VS中只能整合這個編譯器的QT。 MingGW是指是Minimalist GNU on Windows的縮寫。它是一個可自由使用和自由釋出的Windows

QT+VS使用qDebbug()打印調試信息無法顯示

依次 cmd 調試 png mage 顯示 nbsp 窗口 信息 首先右鍵點擊項目名稱,找到最後一項屬性 然後依次設置為如圖所示即可 再次編譯後,會彈出CMD窗口,出現qDebug的調試信息。 QT+VS中使用qDebbug()打印調試信息無法顯示

opencv+QT+vs 顯示圖片總結

opencv支援QT,QT也有vs外掛,所以學習一下用QT顯示圖片的方法,實現的是圖片的讀取顯示與反轉顯示。 各種配置完成之後,在vs中新建一個qt專案,專案名字不要有中文,一路確定、下一步,直到完成。 在專案下面會自動生成一些檔案。.ui為qt設計檔案,雙

VSQT的智慧提示設定

把下面內容貼到vax的custome include 裡面$(QTDIR)/include$(QTDIR)/include/Qt$(QTDIR)/include/QtCore$(QTDIR)/include/QtGui$(QTDIR)/include/QtHelp$(QTDI

vsQt程式碼感應問題

If you are using Visual Studio withQt, you can ensure a more productive experience by adding the Qt directories to your Visual Studio l

eclipse如何自動生成構造函數

技術 tor get src sin image super java 構造函數 eclipse中如何自動生成構造函數 eclipse是一個非常好的IDE,我在寫java程序的時候使用eclipse感覺開發效率很高。而且有很多的快捷和簡便方式供大家使用,並且能直接生成cla

VS定義後期生成事件,希望生成的目標檔案拷貝到指定目錄當中

1、語句 del $(SolutionDir)Release\Result\GetCRCResult.execopy $(SolutionDir)Release\GetCRCResult.exe $(SolutionDir)Release\Result\ 其中Result是指定的資料夾,這裡我把它放在Re

vim括號自動生成

https://blog.oldj.net/2011/06/17/vim-parenthesis/ set smartindent set tabstop=4 set shiftwidth=4 set expandtab "括號自動補全,用了兩種形式請區分清除 inoremap ' '

Eclipsemybatis自動生成程式碼

工具下載 Eclipse中help–>install new software 如下圖所示 Location:內容 完成安裝之後,選擇新建–Ctrl + N之後,生成generateConfig.xml檔案 GenerateConfig.xm

EclipseMybatis自動生成外掛使用

       對於使用Mybatis的開發者來說, 使用mybatis generator來生成mapper 以及配置檔案, 可以大大簡化工作, mybatis generator有多種工作方式, eclipse外掛是一種比較友好的方式. 第一, 首先,到http://ma

QT CreaterQt Multimedia模組的使用

Qt 5中Qt Multimedia模組代替Qt 4 Phone模組的使用音訊檔案播放:main.cpp:#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[

去除 struts2 標籤自動生成的佈局樣式table/tr/td+ 全選 反選

<table> <thead> <tr> <th width="100"><s:checkbox id="doAllSe

VSToken的生成

第一次寫部落格,寫得不好請見諒~ 首先搭好相應的框架,在Repository層中寫對應的登陸邏輯 在Domain層對Repository進行呼叫,完成框架的搭建後 我們就要開始生成Token啦 首先我們先配置一下路由在web API 中的----App_Start----Startup.A

在Eclipse設定自動生成javadoc註釋

轉自:http://jingyan.baidu.com/article/a501d80c09dab1ec620f5e4b.html http://www.cnblogs.com/fsjohnhuang/p/3988883.html windows-->preferen

android工程自動生成Android Dependencies的解決方式

今天遇到的奇怪問題是網上下載的demo匯入第三方包執行後Android: NoClassDefFoundError的錯誤,原因是第三方的jar包並沒有打包進apk裡,執行是肯定要出錯的。網 上百度了N久,都是說先移除之前的Libraries,再將lib更名為libs的做法。今天是遇到邪門了,照做還是執行報錯。

Visual Studio-VS新增WSDL生成代理類工具

VS中新增WSDL生成代理類工具 1.點選 vs選單欄->工具 ,選擇 外部工具, 2.在彈出的視窗中點選 新增,然後在“標題”行中輸入”WSDL生成代理類”,”命令”行中輸入”C:\Program Files\Microsoft.NET\SDK\

使用T4模板從根據資料庫自動生成類類檔案

一個數據庫可能有多個表,需要生成多個類檔案,首先建立一個xx.ttinclude檔案.此檔案主要能夠生成單獨的類檔案。同時再定義一個類DBHelper來獲取資料庫裡所有表的資訊和資料。 <#@ assembly name="System.Core"#><#@ assembly nam