本人QT生手,最近項目上卻有個需求,要將原本的Visual Studio的project轉成QT Creator的project。在進行了一番研究和動手實踐以及再研究再實踐之後,終於成功完成了這一轉換,特此記錄。
環境:
- Visual Studio 2013 (Ultimate)
- QT 5.5 Community
- 原本的VS工程是一個產生dll的工程
- 原本的VS工程其實是基於QT Template的工程
(安裝了QT的VS外掛程式,就可以在VS裡建立基於QT template的工程。但是這裡又有故事了。對於Visual Studio 2013,外掛程式(add-in)已經不再是推薦的方式,推薦的方式叫做package或extension。所以一旦你安裝了QT的外掛程式(往往是2012版的),再想卸載它就無比困難了,就連MSDN上也沒能寫一個很清晰的解決方案,而網上的解決方案多為修改註冊表,筆者沒有試過,不知道能否卸載乾淨。)
先介紹一下QT工程的特點。相比於VS,QT的工程檔案很簡單,就是一個.pro檔案,當然,有的時候還有.pri檔案和.pro.user檔案。.pro檔案的目的是為了實現cross platform,即跨平台。.pro檔案的內容都是配置資訊,比如指明標頭檔所在,庫檔案所在,庫檔案名稱,目標檔案名等等。.pri檔案也是一種.pro檔案,只是因為它是假定要被某.pro檔案include的,所以叫.pri而沒有叫.pro檔案。在我的執行個體當中,.pri檔案中主要是HEADERS和SOURCES,分別代表標頭檔和源檔案。最後,.pro.user檔案是一個xml檔案,它是自動產生的,主要記錄的是QT Creator裡項目的配置資訊,包括一些系統的環境變數等。
關於.pro檔案的內容以及如何編寫.pro檔案,網上有很多不錯的文章,這裡就不贅述了。貼幾篇文章的連結如下:
10分鐘學會qmake qmake教程 qmake概念 qmake進階概念 qmake命令參考 一篇轉了以上所有文章的文章 以上談.pro檔案的時候還談到了qmake,那麼它是什麼呢。為何說.pro檔案是為了跨平台而寫的呢。原來,qmake是Trolltech公司(於2008年被諾基亞收購)建立的用來為不同的平台和編譯器書寫Makefile的工具。手寫Makefile是比較困難並且容易出錯的,尤其是需要給不同的平台和編譯器組合寫幾個Makefile。使用qmake,開發人員建立一個簡單的“項目”檔案(即.pro檔案)並且運行qmake產生適當的Makefile。qmake會注意所有的編譯器和平台的依賴性,可以把開發人員解放出來只關心他們的代碼。Trolltech公司使用qmake作為Qt庫和Qt所提供的工具的主要連編工具。
那麼瞭解了qmake和.pro檔案的寫法之後,再來看看我的轉換曆程吧。
第一步,因為原Visual Studio工程就是基於QT Template的工程,所以我們可以用VS裡的QT外掛程式裡的"Create basic .pro file..."菜單選項來自動產生一個.pro檔案,實際上,不僅僅產生了.pro 檔案,還產生了.pri檔案。但是目前的.pro檔案還是不能用的,因為其中還有大量的配置需要修改,比如INCLUDEPATH和LIBS.
第二步,修改.pro檔案使其包含正確而必要的配置資訊。 總結筆者對.pro檔案的具體修改如下: 1. TEMPLATE = lib 2. 將DESTDIR = xxx改成: Release:DESTDIR = xxx/Release Debug:DESTDIR = xxx/Debug 3. CONFIG += debug_and_release 4. 完善INCLUDEPATH 5. 完善DEPENDPATH (這裡又有故事了:事後筆者發現,只要在LIBS裡寫了-L"<LIBPATH>",就沒必要寫DEPENDPATH了。) 6. 加上 Release:DEPENDPATH 和 Debug:DEPENDPATH 7. 類似的,完善LIBS,添加Release:LIBS和Debug:LIBS
第三步,雙擊改好的.pro檔案,QT Creator開啟此工程,選中合適的Kit,就可以build了。因為是64位機器,Kit選的是QT 5.5.1的msvc2013_64. 最後千萬要注意的是,在系統內容變數%PATH%裡,對於Visual Studio的編譯器cl.exe和連結器link.exe, 要選對路徑。比如,對於64位的機器,路徑 C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64 應該被加到%PATH%中,而不是 C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin 這一條在前一篇博文中已有詳細闡述。
以上步驟做完後,就可以順利地在QT Creator中進行build了。 最後還要提醒的一點是,如果更改了.pro檔案,想讓更改生效,必須手動刪除qmake產生的Makefile, Makefile.Debug和Makefile.Release檔案。
下面是一個.pro檔案的執行個體:
TEMPLATE = libTARGET = MyProjectRelease:DESTDIR = ../../../Output/x64/ReleaseDebug:DESTDIR = ../../../Output/x64/DebugQT += core qmlCONFIG += debug_and_releaseDEFINES += WIN64 QT_DLL QT_QML_LIB MyProject_LIBINCLUDEPATH += ./GeneratedFiles \ . \ ./GeneratedFiles/Release \ $$(VC_INCLUDE) \ $$(VC_INCLUDE)/../atlmfc/include \ $$(WINSDK_INCLUDE)/shared \ $$(WINSDK_INCLUDE)/umDEPENDPATH += . \ $$(WINSDK_LIB)/um/x64 \ $$(VC_LIB)/amd64 \ $$(QTDIR)/lib \ $$(QTDIR)/bin \Release:DEPENDPATH += ../../../3rd_library/opencv/libs/Release/x64 \ ../../../3rd_library/DirectShow/baseclasses/x64/ReleaseDebug:DEPENDPATH += ../../../3rd_library/opencv/libs/Debug/x64 \ ../../../3rd_library/DirectShow/baseclasses/x64/DebugMOC_DIR += ./GeneratedFiles/releaseOBJECTS_DIR += releaseUI_DIR += ./GeneratedFilesRCC_DIR += ./GeneratedFilesRelease:LIBS += -L"../../../3rd_library/DirectShow/baseclasses/x64/Release" \ -lstrmbase \ -L"../../../3rd_library/opencv/libs/Release/x64" \ -lqtmain \ -lQt5Qml \ -lQt5Core \ -lopencv_calib3d248 \ -lopencv_contrib248 \ -lopencv_core248 \ -lopencv_features2d248 \ -lopencv_flann248 \ -lopencv_gpu248 \ -lopencv_highgui248 \ -lopencv_imgproc248 \ -lopencv_legacy248 \ -lopencv_ml248 \ -lopencv_nonfree248 \ -lopencv_objdetect248 \ -lopencv_ocl248 \ -lopencv_photo248 \ -lopencv_stitching248 \ -lopencv_superres248 \ -lopencv_ts248 \ -lopencv_video248 \ -lopencv_videostab248Debug:LIBS += -L"../../../3rd_library/DirectShow/baseclasses/x64/Debug" \ -lstrmbasd \ -L"../../../3rd_library/opencv/libs/Debug/x64" \ -lqtmaind \ -lQt5Qmld \ -lQt5Cored \ -lopencv_calib3d248d \ -lopencv_contrib248d \ -lopencv_core248d \ -lopencv_features2d248d \ -lopencv_flann248d \ -lopencv_gpu248d \ -lopencv_highgui248d \ -lopencv_imgproc248d \ -lopencv_legacy248d \ -lopencv_ml248d \ -lopencv_nonfree248d \ -lopencv_objdetect248d \ -lopencv_ocl248d \ -lopencv_photo248d \ -lopencv_stitching248d \ -lopencv_superres248d \ -lopencv_ts248d \ -lopencv_video248d \ -lopencv_videostab248dLIBS += -L"$$(WINSDK_LIB)/um/x64" \ -L"$$(VC_LIB)/amd64" \ -L"$$(QTDIR)/lib" \ -L"$$(QTDIR)/bin" \ -lWtsapi32 \ -lPathcch \ -l3DScanningEngine \ -lUserenv \ -lwinmm \ -lMf \ -lMfplatinclude(MyProject.pri)
在實際build的過程中,筆者又發現QT是調用jom.exe去做的。這是個什麼呢。原來,在VS裡面,有一個工具叫做nmake,它和Linux上的make很像。但是這個nmake有一個缺點(筆者不確定現在還有沒有這個缺點,但在2009年的時候是有的),就是它無法利用多核的優勢並行編譯。於是,就有人寫了這麼一個叫做jom的工具,類似於是多線程版本的nmake. 最初的那篇介紹jom的文章在這裡: http://blog.qt.io/blog/2009/03/27/speeding-up-visual-c-qt-builds/