使用 Visual C++ 2010 建置 Qt 4.6.3

| | 2 Comments| 14:37
Categories:

首先,Heresy 這邊所使用的 Qt 是官方網站下載(http://qt.nokia.com/downloads)的 LGPL、Qt SDK for Windows 的 4.6.3 Open Source 版本(雖然官方說他是基於 MinGW、不支援 VS 編譯器,但是因為 Framework only 的版本只有 for VS2008 的,所以也只好硬上了…),下載連結是:http://qt.nokia.com/downloads/sdk-windows-cpp,所下載的檔案名稱是「qt-sdk-win-opensource-2010.04.exe」。

在下載完、安裝結束後,Qt 預設會被安裝在 C:\Qt 的目錄下。而接下來的步驟,都是要使用 Visual Studio 2010 的命令提示字元(Command Prompt)來進行的。

開啟了 Visual Studio 的命令提示字元後,先切換到 Qt 所在的目錄(Heresy 這邊是 C:\Qt\2010.04\qt,以下的目錄也都是相對這個目錄),然後就可以開始進行下列的工作了∼

第一步,先設定 Qt 的參數

configure -opensource -fast -platform win32-msvc2008

也可以透過「configure -help」來看所有的參數說明,並根據自己的需求做調整。platform 的選項的話,可以參考 \mkspecs 下的資料夾列表。如果想要清除掉現有的設定的話,可以執行「nmake confclean」。

而第二步驟,就是要透過 VC 的 nmake 來進行編譯了∼不過在進行前,要先針對 Qt 的程式做一些修改,不然沒辦法編譯完成(主要是 webkit、script、scripttools 這三個模組)。要修改的內容包括:

  1. 修改 StructureTransitionTable.h 這個檔案,這個檔案在下面兩個位置都有,都需要修改:

    \src\3rdparty\javascriptcore\JavaScriptCore\runtime\
    \src\3rdparty\webkit\javascriptcore\runtime\

    在檔案裡面可以找到下面的程式碼片段:

    if (!specificValue){
      TransitionTable::iterator find = table()->find(key);
      if (find == table()->end())
        table()->add(key, Transition(structure, 0));
      else
        find->second.first = structure;
    } else {
      // If we're adding a transition to a specific value, then there cannot be
      // an existing transition
      ASSERT(!table()->contains(key));
      table()->add(key, Transition(0, structure));
    }

    將裡面 Transition 的初始化參數由 0 改為 nullptr 就可以了∼(Heresy 這邊是146 行與 153 行)也就是變成下面的樣子:

    if (!specificValue){
      TransitionTable::iterator find = table()->find(key);
      if (find == table()->end())
        table()->add(key, Transition(structure, nullptr));
      else
        find->second.first = structure;
    } else {
      // If we're adding a transition to a specific value, then there cannot be
      // an existing transition
      ASSERT(!table()->contains(key));
      table()->add(key, Transition(nullptr, structure));
    }
  2. 在 build webkit 和 script 的時候,可能會發生 link error 的問題,此時請刪除名為 mocinclude.tmp 的檔案,包括了:

    \src\3rdparty\webkit\WebCore\tmp\moc\release_shared\mocinclude.tmp
    \src\3rdparty\webkit\WebCore\tmp\moc\debug_shared\mocinclude.tmp
    \src\script\tmp\moc\release_shared\mocinclude.tmp
    \src\script\tmp\moc\debug_shared\mocinclude.tmp

    理論上在建置 Qt 的過程,會重新產生這兩個檔案,之後應該就不會有 link error 的問題了。
    (參考:《Building QT with Visual Studio》)

修改完成後,就直接在 Visual Studio 的命令提示字元,下「nmake」的指令,就可以開始透過 Visual C 的編譯器來建置 Qt 了∼不過這段時間可能會非常久(Heresy 這邊要花上好幾個小時啊…),建議可以找些別的事情來做,等他建置完成。

而由於 Qt 預設應該是只會使用一顆邏輯處理器來進行編譯,所以如果電腦是使用多核心的 CPU、或是使用多 CPU 的話,可以透過修改 \mkspecs\win32-msvc2008\qmake.conf 這個檔案,來開啟使用多核心編譯的功能。修改方法是找到該檔案的「QMAKE_CFLAGS」,幫他加上「-MP」。

QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t-
QMAKE_CFLAGS            = -nologo -Zm200 -Zc:wchar_t- -MP

上面的第一行(qmake.conf 這個檔案裡的第 19 行)就是原來內容,只要在後面多加一個「-MP」,變成第二行就可以了。理論上,在多核心的電腦上,這樣編譯所需的時間是會縮短不少的∼

而編譯完後,所有需要的 .lib、.dll 檔,都可以在 \lib 的目錄下找到,而其他需要的執行檔(例如:moc、uic、qmake),也都可以在 \bin 這個目錄找到;理論上到這邊都沒問題的話,應該就算是完成整個 Qt 的建置了∼


不過上面講的修改、設定都是針對 Win32、也就是 32 位元的環境,那如果要編譯出 64 位元的版本呢?除了 Visual Studio 的命令提示字元要換成 64 位元的版本(Visual Studio x64 Win64 Command Prompt)外,也還要再針對 Qt 內預先建立好的設定參數做一些調整。這邊 Heresy 是參考 mixxx wiki 裡的《build_windows_dependencies》一文。

不過另外要注意的是:Visual C 2010 目前在 64bit release 時的最佳化有問題,會造成 Qt 無法正確執行!詳細的情形可以參考 Qt 官方的錯誤回報系統(Qt apps fail to start when I build Qt 4.7 with win32-msvc2010 on Windows 7 x64),以及 Microsoft Connect 的《Incorrect alignment with x64 optimizer and MOVAPS》。

理論上目前微軟目前已經有在處理了,近期內應該會有針對這個問題的 hotfix,不過現階段,應該是沒有辦法再開啟最佳化(/O2、/Ox)的情況下,編譯出可以用的 x64 release 版的 Qt…而目前的對應方法,就是犧牲效率、不要針對 x64 release 版開啟最佳化了。

要修改的檔案有兩個:

  1. 打開檔案 \mkspecs\win32-msvc2008\qmake.conf
    1. 找到 QMAKE_LFLAGS,加上「/MACHINE:X64」
    2. 找到 QMAKE_CFLAGS_RELEASE,把本來的「-O2」改成「-O1」

    在 Heresy 這,修改後就變成:

      22: QMAKE_CFLAGS_RELEASE    = -O1 -MD
        : ...
      54: QMAKE_LFLAGS = /NOLOGO /MACHINE:X64
  2. 打開檔案 \qmake\makefile.win32,找到 LFLAGS,加上「/MACHINE:X64」修改過後,會變成
     43: LFLAGS      = /MACHINE:X64

不過這裡主要要改的重點應該是 linking 階段的 flag(LFLAGS):「/MACHINE:X64」。而編譯的 CFlags 的「/favor:AMD64」實際上是強制針對 AMD64 的平台做最佳化(不過現在一般的家用處理器、就算是 Intel 的,所支援的 64 位元也都是 AMD64 就是了),所以應該不見得要做這樣的設定(參考《/favor (Optimize for x64)》@MSDN)。

理論上,在做了這些修改後,再重新執行上面的步驟、進行 configure 和 nmake 就可以建置出 64 位元版的 Qt 了∼不過另外要注意的是,Qt 的檔案輸出路徑是沒有變動的,所以如果想要讓 32 位元和 64 位元的 Qt 並存的話,是需要在編譯完成後,自行把編譯後的備份、保存下來的。不過 Heresy 個人會建議,如果硬碟夠的話,還是直接 keep 兩份 Qt 的檔案會比較直接…


雖然目前 Qt 4.6.3 還沒有支援 Visual C 2010,不過目前還在 Beta 中的 Qt 4.7 應該是有正式支援了(雖然 VC10 x64 release 的問題應該還是一樣);所以如果不想自己修改的話,就試試看改用 Qt 4.7 吧∼

最後一提,Heresy 個人是覺得 Qt 整個弄得滿亂的…姑且不論他的肥大(安裝完後就 1.28GB 了)和編譯時間的冗長,還是有不少讓人覺得討厭的地方。

雖然按照步驟進行的話,應該是可以正確編譯出來的。但是 Heresy 在建置的過程,卻常常遇到一些不可解的狀況。像是 Heresy 就碰過好幾次沒辦法進行 nmake clean 的動作,也導致一些編譯過程出現問題。 Heresy 自己就重灌了好幾次 Qt,才弄出最後可以運作的版本。

而另外很糟糕的一點是,Qt 雖然有獨立出一個 \include 資料夾來放 header 檔,但是在裡面的檔案卻又常常回頭去 include \src 底下的檔案…這也使得要把 Qt 的 header 檔抽出來的難度增加許多…

2 thoughts on “使用 Visual C++ 2010 建置 Qt 4.6.3”

  1. @heresy

    再聽了您的建議,我重新找了4.7.3的版本
    在改完上述的東西後,卻在 building qmake failed
    不知道這部分該怎麼解決@@?

  2. @Ricky

    Heresy 這邊主要是針對 4.6.3 來做設定的,不確定針對 4.7 是否不需要做這麼多修改。
    建議直接去 build 原來的 source 看看。

    或者,也可以考慮直接使用 4.8 官方針對 MSVC 2010 build 好的版本(沒有 x64 就是了)

發佈回覆給「heresy」的留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *