Windows 7でQt5.4.0をビルドする。その２(Qt 64bitビルド)

## 1. はじめに
　私は、今まで主にファームウェア(時々Windows)の世界の住人で、最近FOSSの世界に飛び込みました。そして、dllが苦手です。単純なので静的リンクしたい人なのです。

　そんな私が最近Qtを始めたのですが、公開されているQtのバイナリーは動的リンクでした。そこで、FOSSに慣れるついでに静的リンクのQt開発環境を用意しようと、[ここ](http://qt-project.org/wiki/Building_Qt_5_from_Git "[Qt Project] Building Qt 5 from Git")の手順をベースにしてQtをビルドしました。
　結果、うまいことできましたので、記憶が新しいうちにビルド手順をまとめてみました。

　長くなりすぎたので２つに分けてます。
　[前のエントリー](./2da05e9df4db9ba0d8ec "Windows 7でQt5.4.0を64ビット・スタティック・ビルドする　その１(Qt5.4.0の準備)")でQt5.4.0を準備してHallo Worldするところまで書きました。
　このエントリーでQt5.4.0をビルドするところを書きます。

## 3. Qt5.4.0 64bitのビルド

### 3.1 必要なソフトウェアをインストールする

|ソフトウェア|ダウンロードするファイル|インストール方法|
|:-----------|:------------|:-----------|
|[MinGW-w64 4.9.1 rev2](http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.1/threads-posix/seh/ "MinGW-w64 - for 32 and 64 bit Windows")|[x86_64-4.9.1-release-posix-seh-rt_v3-rev2.7z](http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.1/threads-posix/seh/x86_64-4.9.1-release-posix-seh-rt_v3-rev2.7z/download "Click to download")|N:\Qt\Toolsへ[解凍](http://sourceforge.jp/projects/sevenzip/ "7-Zip")後、mingw64フォルダをmingw491_64へリネーム|
|[QtBinPatcher 2.1.1 64bit](http://tver-soft.org/component/phocadownload/category/13-qtbinpatcher211 "QtBinPatcher 2.1.1")|[qtbinpatcher-2.1.1-win-x64.zip](http://tver-soft.org/component/phocadownload/category/13-qtbinpatcher211?download=67:qtbinpatcher-211-win-x64 "Click to download")|N:\Qt\Tools\QtBinPatcherへ解凍|
|[DirectX 9 SDK](http://www.microsoft.com/en-us/download/details.aspx?id=6812 "[Microsoft Download Center] DirectX Software Development Kit")|[DXSDK_Jun10.exe](http://www.microsoft.com/en-us/download/confirmation.aspx?id=6812 "Click to download")|DXSDK_Jun10.exeを起動。"Help Improve the DirectX SDK"はお好みで。他はデフォルトのまま。|
|[ActivePerl 5.20.1(64bit)](http://www.activestate.com/activeperl/downloads "[ActiveState] Download Perl Binaries: ActivePerl Community Edition")|[ActivePerl-5.20.1.2000-MSWin32-x64-298557.msi](http://www.activestate.com/activeperl/downloads/thank-you?dl=http://downloads.activestate.com/ActivePerl/releases/5.20.1.2000/ActivePerl-5.20.1.2000-MSWin32-x64-298557.msi "Click to download")|ActivePerl-5.20.1.2000-MSWin32-x64-298557.msiをインストール。オプションはデフォルトのまま。|
|[Python 2.7.8](https://www.python.org/downloads/ "[python] Download the latest version for Windows")|[python-2.7.8.msi](https://www.python.org/ftp/python/2.7.8/python-2.7.8.msi "Click to download")|python-2.7.8.msiをインストール。"Add phthon.exe to Path"を選択する。他はデフォルトのまま。|

　全てインストール後、環境変数を反映するためPCを再起動します。

### 3.2 Qtのソースをダウンロードする
　[ここ](http://qt5.jp/qt5-mirrors.html "[Qt 5 の未来は明るいブログ] Qt 5 のミラーリポジトリを使用する")を参考にして、[日本Qtユーザー会](http://qt-users.jp/index.html "[日本 Qt ユーザー会] HOME")にある[Qt5のリポジトリ](http://git.qt-users.jp/?p=qt/qt5.git;a=tree "[日本Qtユーザー会] git://git.qt-users.jp / qt/qt5.git / tree")([本家](https://github.com/qtproject/qt5 "[GitHub] qtproject/qt5")のミラー)をローカルへクローンし、Qt5.4.0をチェックアウトしました。
　コマンド・プロンプトを起動してN:へ移動し、下記の手順で行います。

1. [cd \Qt5](./acb465f388aa75f5d6a5/#32-qtのソースをダウンロードする "Qtをビルド環境を作るフォルダ(N:\Qt5)へ移動します。")
1. [git clone git://git.qt-users.jp/qt/qt5.git qt5](./acb465f388aa75f5d6a5/#32-qtのソースをダウンロードする "Qt5リポジトリをN:\Qt5\qt5へクローンします。")
1. [cd qt5](./acb465f388aa75f5d6a5/#32-qtのソースをダウンロードする "リポジトリ(N:\Qt5\qt5)へ移動します。")
1. [git checkout 5.4.0](./acb465f388aa75f5d6a5/#32-qtのソースをダウンロードする "Qt5.4.0をチェックアウトします。")
1. [perl init-repository --mirror git://git.qt-users.jp/](./acb465f388aa75f5d6a5/#32-qtのソースをダウンロードする "必要なサブモジュールをチェックアウトします。")

### 3.3 Qt5.4.0の動的リンク版をビルドする
　下記コマンドにより、ビルドを構成(step 4.)し、ビルド(step 5.)します。フォルダ構成は[1.3](./2da05e9df4db9ba0d8ec/#13-主要フォルダ構成)を想定しています。

1. [set PATH=N:\Qt\Tools\mingw491_64\bin;%PATH%](./acb465f388aa75f5d6a5/#33-qt540の動的リンク版をビルドする "コンパイラのパスを設定します。")
1. [set PATH=N:\Qt\Tools\QtCreator\bin;%PATH%](./acb465f388aa75f5d6a5/#33-qt540の動的リンク版をビルドする "jom.exeのパスを設定します。")
1. [cd \Qt5\Qt540x64g491shared](./acb465f388aa75f5d6a5/#33-qt540の動的リンク版をビルドする "動的リンク版のビルド・フォルダへ移動します。")
1. [..\qt5\configure -developer-build -opensource -nomake examples -nomake tests](./acb465f388aa75f5d6a5/#33-qt540の動的リンク版をビルドする "ビルド制御用ファイル群を構成します。数分かかります。")  
この時、"Do you accept the terms of the license?"と聞かれるので、"y"と答えます。
1. [jom](./acb465f388aa75f5d6a5/#33-qt540の動的リンク版をビルドする "jom.exeを使ってビルドします。かなり長い時間かかります。")

```text:Note
step 5.ではmingw32-makeでも可能ですが、jomを使った方が高速にビルドできます。(赤い彗星より速いですぞ。)　Core™ i7-3820 3.60 GHzのパソコンで、mingw32-makeは約4時間かかりましたがjomなら約1時間でした。
jom.exeは、2.1のようにインストールするとN:\Qt\Tools\QtCreator\binに入ってます。
```
### 3.4 ビルドしたQt開発環境をインストールする
　下記コマンドで、Qt開発環境として必要なファイルをN:\QtInstall\Qt5\qt-5.4.0-x64-mingw482r4-seh-sharedへ集めることができます。

1. [set PATH=N:\Qt\Tools\mingw491_64\bin;%PATH%](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "コンパイラのパスを設定します。")
1. [set PATH=N:\Qt\Tools\QtCreator\bin;%PATH%](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "jom.exeのパスを設定します。")  
1. [set PATH=N:\Qt\Tools\QtBinPatcher;%PATH%](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "qtbinpatcher.exeのパスを設定します。")
1. [set INSTALL_ROOT=\QtInstall](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "インストール先フォルダのルートを指定します。")
1. [cd \Qt5\Qt540x64g491shared](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "動的リンク版のビルド・フォルダへ移動します。")
1. [jom install](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "必要なオブジェクトをQtInstall以下へ集めます。数分かかります。")
1. [cd \QtInstall\Qt5\Qt540x64g491shared\qtbase](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "インストールされたQt開発環境のフォルダへ移動します。")
1. [qtbinpatcher](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "Qt開発環境の各ファイル内の絶対パスをインストール先に合わせて修正します。")

```text:Note
この手順はオプションです。ビルド・フォルダのQtを直接使うこともできます。
インストールを行うことでビルド環境から切り離されたQt開発環境を作れるので、ソースをスイッチしたりビルド・フォルダを削除したりしてもQtアプリを開発できることがメリットです。
```

### 3.5 QtCreatorとプロジェクトに設定し、Hello World
* `[ツール(T)]`→`[オプション(O)...]`をクリックし`[ビルドと実行]`を選択し、`[Qt バージョン]`、`[コンパイラ]`、`[デバッガ]`の各タブを選択して`[追加ボタン]`を押し、下表のように設定します。(名前は適当で良いです。)

|タブ|名前|設定|
|:---|:---|:---|
|コンパイラ|MinGW 4.9.1 64bit|N:\Qt\Tools\mingw491_64\bin\g++.exe|
|デバッガ|MinGW 4.9.1 64bit|N:\Qt\Tools\mingw491_64\bin\gdb.exe|
|Qt バージョン|Qt540x64g491shared|N:\Qt5Install\Qt5\Qt540x64g491shared\qtbase\bin\qmake.exe|
(もし、ビルド・フォルダのQtを直接使う場合は、Qt バージョンにN:\Qt5\Qt540x64g491shared\qtbase\bin\qmake.exeを指定して下さい。)

* `[キット]`のタブを選択して`[追加ボタン]`を押し、下表のように設定します。

|欄|設定|
|:---|:---|
|コンパイラ|MinGW 4.9.1 64bit|
|デバッガ|MinGW 4.9.1 64bit|
|Qt バージョン|Qt540x64g491shared|

　以下はキットを設定した時の画面です。

![13.キット設定.png](https://qiita-image-store.s3.amazonaws.com/0/59362/0cb46c7f-5961-5fa4-0aed-ae7255a67585.png)

* 64bit 動的リンクしたいプロジェクトにこのキットを追加して使います。  
下は昨日のHello Worldプロジェクトへキットを追加しようとしている画面です。

![14.プロジェクト設定.png](https://qiita-image-store.s3.amazonaws.com/0/59362/7caf490d-4c64-6715-f776-c716168eb4aa.png)

* 最後に緑の三角ボタンを押してビルドし起動します。  
Hello Worldが表示されれば勝ちです。Congratulations!!

### 3.6 Qt5.4.0の静的リンク版をビルドする
　ちょっと工夫しないとgccのライブラリが動的リンクになります。
　ここでは、gccのライブラリも含めて静的リンクする手順を説明します。

```text:Note
ここで説明する方法はmkspecsにフォルダを追加します。
この程度のことでmkspecsを増やすのはよくないようにも感じます。
Qtを静的リンクさせる時は常にgccのライブラリも静的リンクさせたかったのでこのようにしてみました。より適切な方法をご存知の方がいたら、是非教えて下さい。
```

　まず、win32-g++staticをqt5へ追加します。
　N:\Qt5\qt5\qtbase\mkspecs\win32-g++をまるごと、N:\Qt5\qt5\qtbase\mkspecs\win32-g++staticへコピーし、qmake.confファイルのQMAKE_LFLAGSを設定している行を次のように修正します。(gccのライブラリを静的リンクする指定です。)

```text:qmake.conf
QMAKE_LFLAGS = -static -static-libgcc -static-libstdc++
```

　次に、ビルドを構成し、ビルドします。
　手順は[3.3](./acb465f388aa75f5d6a5/#33-qt540の動的リンク版をビルドする "3.3 Qt5.4.0の動的リンク版をビルドする")とほぼ同じです。ビルド・フォルダとconfigureのパラメータに-staticが追加されている点が異なります。(step 3.とstep 4.が次のように変わります。step 5.jomの実行をお忘れなく。)
　　
3. [cd \Qt5\Qt540x64g491static](./acb465f388aa75f5d6a5/#36-qt540の静的リンク版をビルドする "静的リンク版のビルド・フォルダへ移動します。")
4. [..\qt5\configure -static -developer-build -opensource -nomake examples -nomake tests](./acb465f388aa75f5d6a5/#36-qt540の静的リンク版をビルドする "ビルド制御用ファイル群を構成します。数分かかります。")

### 3.7 ビルドしたQt開発環境をインストールする
　手順は[3.4](./acb465f388aa75f5d6a5/#34-ビルドしたqt開発環境をインストールする "3.4 ビルドしたQt開発環境をインストールする")とほぼ同じです。ビルド・フォルダに静的リンク版を指定します。(step 5.とstep 7.が次のように変わります。他の手順の実行もお忘れなく。)
　
5. [cd \Qt5\Qt540x64g491static](./acb465f388aa75f5d6a5/#372-ビルドしたqt開発環境をインストールする "静的リンク版のビルド・フォルダへ移動します。")
7. [cd \QtInstall\Qt5\Qt540x64g491static\qtbase](./acb465f388aa75f5d6a5/#372-ビルドしたqt開発環境をインストールする "インストールされたQt開発環境のフォルダへ移動します。")
 
```text:Note
3.4と同じくこの手順もオプションです。
ただし、gccのライブラリを静的リンクしたい場合は、手順が少し変わります。
win32-g++staticをN:\Qt5\qt5\qtbase\mkspecs\win32-g++staticではなく、N:\Qt5\Qt540x64g491static\qtbase\mkspecs\win32-g++staticへ作ります。
また、N:\Qt5\qt5\qtbase\mkspecs\commonをまるごとN:\Qt5\Qt540x64g491static\qtbase\mkspecs\commonへコピーします。
これでgccライブラリを静的リンクできました。
```
### 3.8 QtCreatorとプロジェクトに設定し、Hello World

* [3.5](./acb465f388aa75f5d6a5/#35-qtcreatorとプロジェクトに設定しhello-world "3.5 QtCreatorとプロジェクトに設定し、Hello World")と同様の手順で下記設定を行います。

|タブ|名前|設定|
|:---|:---|:---|
|Qt バージョン|Qt540x64g491static|N:\Qt5Install\Qt5\Qt540x64g491static\qtbase\bin\qmake.exe|
　この時、「qmlsceneがインストールされていません。」という警告が表示されます。
　Qtのソースを確認すると、N:\Qt5\qt5\qtdeclarative\tools\tools.proで静的リンクの時はqmlsceneをビルドしないように設定されています。Qtは静的リンクの時qmlsceneを意図的にビルドしていないようですので、このままにしておきます。

![17.qmlscene無し.png](https://qiita-image-store.s3.amazonaws.com/0/59362/d1a4010e-641a-46f4-0a56-3ac08027e4ac.png)

* [3.5](./acb465f388aa75f5d6a5/#35-qtcreatorとプロジェクトに設定しhello-world "3.5 QtCreatorとプロジェクトに設定し、Hello World")と同様の手順でキット設定を行います。

|欄|設定|
|:---|:---|
|コンパイラ|MinGW 4.9.1 64bit|
|デバッガ|MinGW 4.9.1 64bit|
|Qt バージョン|Qt540x64g491static|
|Qt mkspec|win32-g++static|
　ここではキットに警告マークがつきます。キット名をポイントすると「コンパイラ・・・はQt バージョン・・・と互換性のあるコードを生成しない可能性があります。」との警告が表示されます。ABIの一部が異なっているようです。コンパイラはmsys、Qt バーションはunknownになってます。静的リンクなのでmsysは関係ない筈(違ったらごめん)なので、このままにしておきます。

![16.キット設定2.png](https://qiita-image-store.s3.amazonaws.com/0/59362/8db03323-22ea-a4a7-b42d-6cf32c847522.png)

　なお、Qt mkspec欄を空欄にしておけば、gccライブラリは動的リンクされます。

* 64bit 静的リンクしたいプロジェクトにこのキットを追加します。  
* 今度はトンカチマークを押してビルドします。  
* そして、ビルド・フォルダのreleaseかdebugの下にできているHelloWorld.exeを起動します。  
Hello Worldが表示されれば成功です。おめでとう！！

![15.静的リンクHelloWorld.png](https://qiita-image-store.s3.amazonaws.com/0/59362/5b24f37d-2186-b02e-021a-07c4b7eba71a.png)
　動的リンクでは約37MBytesだったのが、約25MBytesに減っています。＼(^o^)／

## 4. おまけ(バッチ・ファイル)
　GitHubの[ここ](https://github.com/Chironian/BuildQt "[GitHub] Tools for building Qt5")にバッチ・ファイル群のリボジトリを登録しました。(リモート・リポジトリを使ってみたかったのですよ。)
　内容はここまで説明してきた通りです。(ログ保存や多少のエラー対策を追加してます)

　チェックアウトしたQt5フォルダごとN:\Qt5フォルダへ上書きコピーしてインストールします。

* N:\Qt5\Qt540x64g491shared等のビルド・フォルダにあるバッチ・ファイル  
ビルド用のバッチ・ファイルです。
[z_config.bat, z_build.bat](./acb465f388aa75f5d6a5#33-qt540の動的リンク版をビルドする "Qt5.4.0の動的リンク版をビルドする"), [z_install.bat](./acb465f388aa75f5d6a5#34-ビルドしたqt開発環境をインストールする "ビルドしたQt開発環境をインストールする")の３つがあります。それぞれ名前の通りの処理を行います。(zは超合金の証です。ｷﾘｯ)
* toolsにあるバッチ・ファイル  
    * Clean.bat : ワーキングコピーの掃除後、tools\win32-g++staticを[3.6](./acb465f388aa75f5d6a5#36-qt540の静的リンク版をビルドする "3.6 Qt5.4.0の静的リンク版をビルドする")の場所へコピーします。
    * AllBuild.bat : 上記の動的リンクと静的リンクのQtの構成とビルドとインストールを連続実行します。なお、最初にClean.batを呼んでいますので、ご注意下さい。  
また、tools内の他のバッチ・ファイルは直接呼び出さないで下さい。  

```text:Note
なお、ドライブはN:でなくても全て同じドライブに入れておけば動作する筈です。\Qtと\QtInstallのフォルダ名を変更する時はバッチ・ファイルの修正が必要になります。\Qt5フォルダ名は恐らく変更しても大丈夫です。
```


## 5. インストール手順について
　ここで書いたインストール手順ですが、[Qt Projectの公式手順](http://qt-project.org/doc/qt-5/windows-building.html#step-4-build-the-qt-library "Qt for Windows - Building from Source")を見つける前にあれこれやっていて、見つけた方法です。(エヘッ)

　jom installでファイルは集まるのですが、QtCreatorへの登録がうまく行かず、探している内に[ここ](http://stackoverflow.com/questions/4699311/how-to-install-qt-on-windows-after-building "How to install Qt on Windows after building?")の情報でqmake.exeに絶対パスが入っていてqmake -queryで見れることが判りました。早速、ダウンロードしたQtのqmake.exeでやってみると、確かにインストールしたパスが入っています！　ということは、インストール中になんらかの方法で書き換えている筈なのです。
　どんなツールなのか見つけるために、後述のqt-5.3.2-x64-mingw491r1-seh.exeをインストール中にタスクマネージャを睨んで見つけたのが、qtbinpatcherです。後は、グーグル先生に教えてもらって[ここ](http://www.tver-soft.org/programs/qtbinpatcher "QtBinPatcher")を見つけました。

　jom install自体はインストール・ファイルを集める公式手順ですし、QtBinPatcherはQt-x64で使われているツールですので、このインストール手順で間違いはないと思いますが、問題が潜んでいる可能性は有ります。ご用心あれ。

## 6. あとがき
　実は、当初は安定版のQt5.3.2をターゲットにして、qt-5.3.2-x64-mingw491r1-seh.exeをインストールしたのですが、それでビルドしたQtQuickアプリは起動直後にクラッシュします。
　QtQuickやQMLなどでグーグル先生にしつこくシツコク聞いてみたのですが解決のヒントが見つかりませんでした。32bit版では起きないし、qt-5.3.1-x64-mingw482r4-seh.exeでもおきないことが分かったのですが、相変わらずヒントが見つからないのです。
　諦めて、先にQtをビルドできるようにしてから、Qtのソース・コードにデバッグ文を入れて追いかけたところ、下記現象が発生していました。

* qtbaseのsrc\3rdparty\angleの奥深くにあるShaderLnag.cppのShCompile()関数から、Compiler.cppのTCompiler::compile()を呼び出している。
* Compiler.cppのTCompiler::compile()は最後まで実行されるのだが、呼出元に戻らない。エーッ！  
どうもスタックが壊れている様子です。ソンナバカナ！

　ANGLEが関係していることが分かったので[angleproject](https://code.google.com/p/angleproject/)へ行って、あれこれ検索して[ここ](https://code.google.com/p/angleproject/issues/detail?id=651 "Crash in TSymbolTableLevel::~TSymbolTableLevel with GCC 4.9")が見つかりました。このパッチをQtのソースに施すと、Qt 5.3.2でもQtQuickが落ちなくなりました！！

　おっ、もしかするといきなり貢献できるかもっ？　はりきってQt Bug Trackerへバグレポートしようとガイドラインに沿って準備している過程で[ここ](https://bugreports.qt-project.org/browse/QTBUG-41472 "ANGLE compiled with gcc 4.9 crashes.")を見つけました。Qt5.4.0で既に修正されていました。(チッ)

　でも、この活動を通じてFOSSにちょっと慣れたさっ！

## 7. 謝辞
　Qt Projectの方々、および、各ビルドツールを提供されている方々、こんなに素晴らしいものを自由に使わせて頂け、最高の感謝を。ありがとう！そして、ありがとう！

　また、日本Qtユーザー会の皆さん、[Qt のあれこれ (仮)]の朝木卓見さん、[理ろぐ]の理音 伊織さん、[Qt 5 の未来は明るいブログ]のTasuku Suzukiさん、および、Qt情報を日本語で公開されている方々、誠にありがとうございます。お陰様で安心して進めることができました。(やっぱ日本語の方がよく解るとですよ～。)

　そして、最後までお付き合い頂いたあなたに。ありがとうございました。m(__)m

---
　明日はmogurisoさんのQt for Tizenのビルド＋αです。Tizenってなんだろう？　ワクワクですっ。