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”, 等待…

項目導入完成.

C語言多線程編程實戰

我沒有專門學習過多線程,非常可能有更簡單的方法,我說了一大堆廢話只是繞了遠路。不過這次嘗試中應該還是有很多自己的感悟的,所以如果你是大神,覺得很滑稽,這個家夥寫得都是什麽垃圾啊,笑一笑就好啦 : ) 如果你是和我一樣的小白,歡迎共勉共同進步。

想要實現一個Text UI (我對命令行情有獨鐘,因為我做不出圖形界面) ,要控制光標同時繪制多個區域以及時響應。那麽這個就很明顯用到多線程了,奈何我對多線程一竅不通,於是…

  • 這是我理想中的窗體:
  • 實際畫出來的效果是這樣的:

這一坨坨條形碼,讓我頓時感到世界對自己充滿了惡意…

閱讀全文 C語言多線程編程實戰

自製 Goose 愚人節小病毒

愚人節前我亂翻小衆軟件,突然發現了這個東西,於是就有了靈感:
點擊前往: Desktop-Goose 小衆軟件

這是什麽

程序全屏運行示意圖

這是一個可以瘋狂啓動上述 呆鵝 的小程序,只有按照指令敲入句子才可以將其關掉。
簡而言之,這是一個 啓動器,用來啓動和關閉 Goose 程序,僅此而已。

技術細節

整個程序是我用蹩脚的 C++ 編寫的,使用了 辣鷄 DevC++ ,因此你可以猜到這個東西跑起來是什麽樣子。
代碼比較凌亂。而且因爲我是趕出來的,直接一個文件解決問題,相信我你絕對不會想要去讀這個代碼的 🙂

Debug 模式下可以看到 Daemon

一些值得 Mark的 小技巧有:

  • 適當使用了 Windows Api, 實現了自由控制 文字顔色 和窗口 全屏
  • 用命令控制開啓和 一次性 關閉所有進程
  • 不同的 啓動參數 可以改變程序的行爲
  • 可以通過改變 預編譯 命令 來決定程序的惡心程度
  • 簡單的多綫程實現
  • 開啓了一個 守護進程 來檢查並阻止關閉程序(守護進程也無法關閉)
  • 檢測到嘗試關閉程序會有 懲罰
  • 長時間沒有輸入也有懲罰(多綫程實現)
  • 隱藏了一個 “上帝指令” 允許優雅的關閉程序

下載程序

在下載前,你需要知道:

  • 壓縮包裏只有 文本文件和圖片資源,你需要自己編譯 main.cpp
  • Goose程序需要分別下載,下載完之後放到程序的同級目錄

Goose: 跳轉至官網
程序源碼: 點擊下載

程序沒有任何的傳播性(不會自我複製),隱藏性(不會僞裝),破壞性(不會讀寫其他文件),且不會自動運行(若想達到這一點你可以讓程序自己複製到啓動),因此嚴格來説這個東西并不能被稱作病毒。請在編譯前仔細閲讀代碼,確定沒有問題后運行,一切後果 雨我無瓜.

病毒一般具有 传播性、隐蔽性、感染性、潜伏性、可激发性、表现性或破坏性, 一般具有兩種即以上就可以被稱作電腦病毒。具體請參考 維基百科 – 計算機病毒的特徵