Ubuntu 18.04 MinGW環境でQt – GUI Windows Applicationをクロスコンパイル

WindowsとLinux環境のGUIアプリケーションを作りたいので、今回cross-platformを対応しているQTフレームワークをUbuntu環境でコンパイルと開発して、Windows環境に実行するクロスコンパイル方法を試します。

# 環境
- AsRock DeskMini GTX1060(Z370)
- Core i9-9900 (3.10GHz 8core 16thread)
- メモリー32GB
- Ubuntu 18.04.5 LTS
- Qt 5.13.2
- mingw-w64 7.3.0
- cmake 3.10.2
- Qt Creator 4.9.2

# MinGW
Linux環境で Windows コンパイラーのmingw-w64をインストールします。

```
sudo apt-get install binutils-mingw-w64-x86-64
sudo apt-get install mingw-w64-common
sudo apt-get install mingw-w64-x86-64-dev
sudo apt-get install mingw-w64-tools
sudo apt-get install gcc-mingw-w64-base
sudo apt-get install gcc-mingw-w64-x86-64
sudo apt-get install g++-mingw-w64-x86-64
```

Win64 + pthread版(posix)を使用

```
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
```

# Qt Source
トップのリポジトリの取得

```
PKG=qt5 VER=5.13.2 TAG=v$VER
QTDIR=~/Qt
mkdir -p "$QTDIR/$VER/mingw_64"
mkdir -p "$QTDIR/$VER/src"
cd "$QTDIR/$VER/src"

git clone --depth 1 git://code.qt.io/qt/qt5.git $PKG
cd $PKG
git fetch --depth 1 origin tag $TAG
git checkout -f $TAG
```

サブモジュールの取得
Qt5は大量のサブモジュールから構成されている。
サブモジュールの全履歴をダウンロードに時間がかかるので、
今回はQt Widgetsでの開発に必要なqtbaseのサブモジュールのみをダウンロードします。

```
for module in qtbase; do
  git submodule update --init --depth 1 --progress $module
done

git clean -dfX
git submodule foreach --recursive git clean -dfX
```

# Configuring Qt
Windows環境向けのQtをクロスコンパイル設定します。

```
./configure \
-xplatform win32-g++ \
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
--prefix="$QTDIR/$VER/mingw_64" \
-opensource \
-confirm-license \
-developer-build \
-no-compile-examples \
-nomake examples \
-opengl desktop \
-L/usr/x86_64-w64-mingw32/lib \
QMAKE_LIBS+="-lws2_32"
```

# Make Qt
コンパイルの時間が長いので、CPUスレード数で並列コンパイルします。
PCメモリー不足よりコンパイルが異常終了した場合、並列コンパイルの数を減らしてコンパイルしてくだいさい。
「16スレード環境でコンパイルした場合：　メモリー8G、10分程度かかる」

```
J=$(grep -cs '^processor' /proc/cpuinfo || echo 2)
echo $J
make -j $J
```

# Installation Qt

```
J=$(grep -cs '^processor' /proc/cpuinfo || echo 2)
echo $J
make -j $J install
```

# Qt Creator

## MinGWコンパイラの設定
Qt CreatorでMinGWコンパイラを追加します。
[ツール][オプション][Kits][コンパイラ][追加][MinGW]よりMinGWのC、C++のコンパイラを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/523abeb3-9bd0-17a7-b99c-f61d4fe90348.png)

## Qtバージョンの設定
[ツール][オプション][Kits][Qtバージョン][追加]よりビルド＆インストールした"QTDIR/VER/mingw_64/bin/qmake"を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/97b3e393-3d2c-c512-c6b2-037cb45e2664.png)

## Development Kitの設定
[ツール][オプション][Kits][キット][追加]より追加します。
コンパイラ：追加したMinGWコンパイラを選択
Qtバージョン：追加したMinGW Qtバージョンを選択
追加したMinGW Qtキットを既定にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/f3092078-cb8d-9cfc-59a3-43da503ae8b3.png)

# Qt Applicationの作成
## アプリケーションを新規
[ファイル][プロジェクトの新規作成]より作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/a40ed15a-239d-c4fc-a204-464fbb300abc.png)

アプリケーションの名前と保存場所を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/b59ddc16-da4c-f9dd-22bc-0669490ad543.png)

追加したMinGW Qtキットを選択、ビルド場所を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/424e32ff-51ec-ed39-5930-3169ea0e6abe.png)

クラス情報のDefault設定を使用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/fe2c31d5-c2a0-a39f-11a7-bd8da42f54b7.png)

設定を完了

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/a675bd66-a493-6481-b66e-cef7042fd82b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/29bd8be5-c1ea-0744-d558-9b471ebe3f78.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/b739b6d4-486c-a6c7-03d3-55176dab56f9.png)

## GUI画面を編集

GUIにボタンを追加
Forms/mainwindow.ui をダブルクリックよりForm編集画面を開く
[Buttons][Push Button]をFormにドラッグ & ドロップ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/63daa33c-24fe-f1fd-2dbd-ca6428178cba.png)

# Qt Applicationのビルド
[ビルド][プロジェクトをリビルド]よりQt Applicationをビルドします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/0a7c0da8-40ef-b30a-be8b-9e7c7d79aeb3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/5f3e02d1-7c01-88fb-ced3-4c2497b9128e.png)

# Qt ApplicationをWindows環境にデプロイ

ビルドしたqt_gui_app.exeとMinGWのDLL、QtのDLLをWindowsにコピーします。

コピー元：
/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libgcc_s_seh-1.dll
/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/libstdc++-6.dll
/usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll
コピー先：exeと同じフォルダー

コピー元：QTDIR/VER/mingw_64/bin
Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll
コピー先：exeと同じフォルダー

コピー元：QTDIR/VER/mingw_64/plugins/platforms
qwindows.dll
コピー先：exeフォルダーのplatformsサブフォルダー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/2c38c05d-738d-336f-52b8-01980447c4f4.png)



# Qt ApplicationをWindows環境で実行

*.exeをダブルクリックより実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/48ea0c50-2527-c3e7-80ca-6aca796e48bf.png)