MacArm 為 Qt 配置 WebAssembly 環境

需求

我正在配置 Qt wasm環境, 但是 emsdk 不支持 apple m1 issue 769
上一篇博文 我配置好 wasm 後發現 還是無法配合 qt 使用.

環境:
MacOS Bigsur M1, Qt 5.15.2

單單配置好wasm, 當前的配置還是不能工作, 比如說, 我現在用 clang 編譯一個 Qt 的 Example:

clang 可以跑起來

可以看到, 項目本身沒問題, 能跑起來;

我接著用剛剛配置的 em++ 編譯一遍:

得到一堆報錯

分析上面的報錯, 有一大堆 permission denied 或者 file not found. 結合 Docker 容器的特性, 我們就知道錯誤的根源了. 上面的配置, emcc 的路徑只和當前的路徑對應, 而在 qt 編譯過程中會引用很多不在當前目錄下的文件, 容器找不到, 就只能報錯.

那麼怎麼解決呢? 我們當然可以手動給他映射上去, 但是每一次都這麼幹, 碰到複雜的項目煩也要煩死. 而且如果像第一種沒有 WebAssembly Kit 的情況, qt 自己也不支持, 那麼要做的東西要海了去了. 所以說, 總是要有其他方法的.

這個方法還是 Docker.

解決方案

Qt 官網文檔: using-docker-test-qt-webassembly
maukalinow/qtwasm_builder : Docker Hub

以上文檔的意思是叫我們自己 Build 一個 Docker 鏡像. 但是顯然已經有人做過了, 本著不要重複發明輪子的定律, 我們可以直接將網友做好的鏡像 Pull 過來: (自行根據 Qt 版本選擇)

docker pull maukalinow/qtwasm_builder:5.15_latest

接著, 我們編譯一下剛才的項目測試一下:

docker run --rm -v ~/Desktop/anaclock/bin:/project/build -v ~/Desktop/anaclock:/project/source maukalinow/qtwasm_builder:5.15_latest
cd /Users/justin/Desktop/anaclock/bin
python3 -m http.server

接下來打開 這個地址: http://localhost:8000/analogclock.html

可以看到, 我們的 qt 應用已經在瀏覽器上面原生運行了.

結果非常成功

為 Qt 安裝 emsdk 到現在為止已經成功.

優化

加快項目生成速度

編譯的 Log

觀察以上編譯記錄我們可以發現, 絕大部分的時間都浪費在 generating system library 上了, 而這些庫無疑都是可以復用的. 所以接下來的事情, 就比較簡單了. 在命令後面加一條, 把緩存文件夾映射到宿主機上, 不就成了嗎?

docker run --rm -v ~/Desktop/anaclock/bin:/project/build -v ~/Desktop/anaclock:/project/source -v ~/.emsdk_cache:/root/dev/emsdk/upstream/emscripten/cache maukalinow/qtwasm_builder:5.15_latest

連著運行這個命令兩遍, 可以看出, 第二遍明顯就比第一遍快了 N 多倍.

第二遍編譯的 Log

簡化輸入命令

正如之前提到, 這麼長的命令並不利於記憶, 我們可以寫一個腳本讓他變短很多.

所以我就寫了一個腳本, 你可以在下面的鏈接下載到.

之後只要在目錄下輸入 qtwasm , 構建就自動完成了

Qt 添加 Mysql 驅動

需求

Qt 自帶的 SQLITE 驅動, 只支持本地的數據庫 . 而能支持在線數據庫的 QMYSQL 需要自己編譯.
本文的環境使用的是 MacOS Bigsur, Qt版本 5.14.2. ( Qt 不能為從 Brew 安裝的版本! )

解決方案

前往 官網 下載 SQLServer, 安裝到本地.
我們不需要他開機啟動, 安裝他只是為了獲得他提供的 Lib, 所以進設置關掉開機啟動.

乘著下載的時間, 我們設置一下 PATH

export QTDIR=/opt/Qt/5.14.2/clang_64
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export PATH=$QTDIR/bin:$PATH
export PATH="/usr/local/mysql/bin:$PATH"

可以試一試運行 mysql, 如果能跑起來, qt 就應該可以監測到.

下載、安裝完成後, 定位到 Qt 安裝的目錄:

cd /opt/Qt/5.14.2/src/qtbase/src/plugins/sqldrivers

(我安裝在/Opt目錄裡面, 你的可能在其他地方.)

然後運行如下指令:

$ qmake -- MYSQL_PREFIX=/usr/local/mysql

Info: creating stash file /opt/Qt/5.14.2/Src/qtbase/src/plugins/sqldrivers/.qmake.stash

Running configuration tests...
Checking for DB2 (IBM)... no
Checking for InterBase... no
Checking for MySQL... yes
Checking for OCI (Oracle)... no
Checking for ODBC... no
Checking for PostgreSQL... no
Checking for SQLite (version 2)... no
Checking for TDS (Sybase)... no
Done running configuration tests.

Configure summary:

Qt Sql Drivers:
  DB2 (IBM) .............................. no
  InterBase .............................. no
  MySql .................................. yes
  OCI (Oracle) ........................... no
  ODBC ................................... no
  PostgreSQL ............................. no
  SQLite2 ................................ no
  SQLite ................................. yes
    Using system provided SQLite ......... no
  TDS (Sybase) ........................... no

Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into '/opt/Qt/5.14.2/clang_64'.

Prior to reconfiguration, make sure you remove any leftovers from
the previous build.

如果你像我一樣看到 Mysql 對應的是yes, 那麼就可以進入下一步了.

make sub-mysql

如果沒有報錯的話, 可以接著運行:

make install

現在 再次編譯程序, 應該已經可以正常工作了.

如果需要打印當前 Qt 支持的驅動, 可以參考以下程序:

#include "mainwindow.h"
#include <QApplication>
#include <QtSql>

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);
	qDebug() << "Available drivers:";
	QStringList drivers = QSqlDatabase::drivers();
	foreach(QString driver, drivers)
		qDebug() << "\t" << driver;
	return a.exec();
}
安裝完畢後以上程序輸出

踩坑

  • 如果你需要在其他系統上正常運作程序, 你可能需要將 lib 文件拷貝過去, lib 文件位於 /opt/Qt/5.14.2/src/qtbase/src/plugins/sqldrivers/plugins/sqldrivers
  • 如果你用 qt5 的話, 強烈建議使用最新版. 比較舊的如 5.9 編譯時會報錯.
  • 如果你在沒有配置完成的情況下運行了一次 qmake , 然後後面怎樣 make 都提示 no, 應該是沒有把第一次 make 出來的東西清理乾淨, 首先

    make distclean #刪除 make 製造出來的所有文件

    然後參考 Qt 的 repo 把目錄裡多出來的東西清理一下 (注意你的版本要保持一致).
  • 如果不小心誤刪了文件其實也是沒有關係的, clone 一下 qt 的 repo 然後把對應版本的代碼考到你的 qt 安裝目錄重新安裝就可以了.

Qt IDE 從文件夾導入源代碼

需求

– 現有一個下載好的 Qt 項目
– 項目裡有很多子文件夾, 沒有 Pro 文件
– 想要導入這個項目, 生成 Pro 文件

解決方案

在源代碼根目錄下運行以下指令,生成 .pro 文件

qmake -project

打開 Qt Creator,點擊導入項目,這個時候應該會出現 Configure Project 的界面 (如果沒有,自己點擊左側的 Project 按鈕配置)

點擊 “Import build from…”, 選擇包含源代碼根目錄的文件夾(包含.pro文件的文件夾的上級目錄),點擊 Import

點擊 “Configure Project”, 等待…

項目導入完成.