介绍
在 Qt6 中,CMake 成为 Qt 的默认构建系统,取代了 qmake。不幸的是,过渡并不顺利。在第一个 Qt6 版本中,缺少 Android 支持。iOS 需要原生 Xcode 项目,即使在 Qt 6.3 上,WebAssembly 仍处于技术预览阶段。
当针对 iOS、Android 和 WebAssembly 时,CMake 的缓慢采用迫使许多开发人员实施他们自己的自定义 CMake 工具链,以便在其项目所需的所有目标平台上构建基于 Qt 的应用程序。
这也是我的情况。我是Cute server的开发者,它扩展了 Qt 的信号和槽机制,使它们能够在网络上使用。使用 Cute,客户端通过创建远程对象并与它们的信号和插槽进行交互,就像它们是本地的一样,而不是依赖于传统的请求/响应模型。Cute 项目为 Linux、macOS、Windows、iOS、Android 和 WebAssembly 提供基于 Linux 的服务器和客户端 SDK,因此需要为不同的平台构建多个资产。
为了在所有需要的平台上创建 Cute 服务器项目的资产,我开发了一个 CMake 文件来为桌面构建和一个 CMake 工具链,它允许交叉编译 iOS、Android 和 WebAssembly。
我想要一些独立于 IDE 的东西。我还想要一个可以在 IDE 中或直接在命令行中使用的通用 CMake 解决方案。
CMake 资产在GitHub上可用,其中一个在屏幕上打印问候消息的简单 Qt Quick 应用程序使用 Cute 的 CMake 资产来定位许多平台。
在这里,我们将展示如何在命令行上构建桌面、iOS、Android 和 WebAssembly 的示例应用程序。尽管使用基于英特尔的 mac 来构建应用程序,但 Linux 和 Windows 也是有效的构建主机。
要将 macOS 用作构建主机,您应该从在线安装程序安装 Xcode 和 Qt。下面的命令显示了如何为所有支持的平台构建项目。
桌面
可以使用 Qt5 为桌面构建应用程序,如下所示:
# configure project
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release \
-DQT_SDK_DIR=/Users/glauco/Programming/Qt/SDK/5.15.2/clang_64 \
/Users/glauco/Programming/MyProjects/HelloWorld
# build
make -j8
# run app
open App/MyApp.app
使用Qt6只是改变QT_SDK_DIR
CMake变量的问题,如下图:
# configure project
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release \
-DQT_SDK_DIR=/Users/glauco/Programming/Qt/SDK/6.2.3/macos \
/Users/glauco/Programming/MyProjects/HelloWorld
# build
make -j8
# run app
open App/MyApp.app
iOS
下面的命令使用 Qt5 为 iOS 模拟器构建应用程序(注意交叉编译需要 CMake 工具链):
# configure project
cmake -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DAPPLE_IOS_TARGET=True \
-DAPPLE_IOS_SIMULATOR=True \
-DMIN_IOS_SDK_TARGET=12 \
-DQT_SDK_DIR=/Users/glauco/Programming/Qt/SDK/5.15.2/ios \
-DCMAKE_TOOLCHAIN_FILE=CMake/Cute.toolchain.cmake \
/Users/glauco/Programming/MyProjects/HelloWorld
# build
make -j8
# App/MyApp.app can be run on simulator
下面,我们使用 Qt6 为 iOS 设备构建应用程序(QT_HOST_PATH
必需):
# configure project
cmake -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DAPPLE_IOS_TARGET=True \
-DAPPLE_IOS_DEVICE=True \
-DMIN_IOS_SDK_TARGET=13 \
-DQT_HOST_PATH=/Users/glauco/Programming/Qt/SDK/6.2.3/macos \
-DQT_SDK_DIR=/Users/glauco/Programming/Qt/SDK/6.2.3/ios \
-DCMAKE_TOOLCHAIN_FILE=CMake/Cute.toolchain.cmake \
/Users/glauco/Programming/MyProjects/HelloWorld
# build
make -j8
# App/MyApp.app can be run on devices
可以使用 CMake 变量中指定的代码签名身份对应用程序进行签名APPLE_CODE_SIGN_IDENTITY
。
安卓
Android 构建使用了 Android 构建工具 31.0.0 和 NDK 22.1.7171670。您可以通过 Android Studio 安装它们。如果没有安装java,可以定义JAVA_HOME
环境变量使用Android Studio提供的java运行环境。
Android 需要为多种架构构建。CMake 通过外部项目支持多种架构。因此,工具链定义了许多目标来为所有架构创建资产。目标MyApp-all
为所有架构构建,并使用该androiddeployqt
工具创建 Bundle/APK。下面显示的命令使用 Qt5 创建 Android 应用程序:
# configure project
cmake -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_TARGET=True \
-DANDROID_TARGET_SDK_VERSION=28 \
-DANDROID_SDK=/Users/glauco/Library/Android/sdk \
-DANDROID_BUILD_TOOLS_REVISION=31.0.0 \
-DANDROID_NDK=/Users/glauco/Library/Android/sdk/ndk/22.1.7171670 \
-DANDROID_ABIS='arm64-v8a;armeabi-v7a;x86;x86_64' \
-DKS_URL=/Users/glauco/Programming/AndroidKeystore/android.keystore \
-DKS_KEY_ALIAS=AndroidDeveloperKeystore \
-DKS_PASS_FILE=/Users/glauco/Programming/AndroidKeystore/keystore.pass \
-DQT_SDK_DIR=/Users/glauco/Programming/Qt/SDK/5.15.2 \
-DCMAKE_TOOLCHAIN_FILE=CMake/Cute.toolchain.cmake \
/Users/glauco/Programming/MyProjects/HelloWorld
# build
make MyApp-all -j8
# App/MyApp/android-build/build/outputs has apk and bundle folders
# containing debug apk for testing and bundle with release build
以下命令使用 Qt6 构建 Android 应用程序(QT_HOST_PATH
必需):
# configure project
cmake -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_TARGET=True \
-DANDROID_TARGET_SDK_VERSION=31 \
-DANDROID_SDK=/Users/glauco/Library/Android/sdk \
-DANDROID_BUILD_TOOLS_REVISION=31.0.0 \
-DANDROID_NDK=/Users/glauco/Library/Android/sdk/ndk/22.1.7171670 \
-DANDROID_ABIS='arm64-v8a;armeabi-v7a;x86;x86_64' \
-DKS_URL=/Users/glauco/Programming/AndroidKeystore/android.keystore \
-DKS_KEY_ALIAS=AndroidDeveloperKeystore \
-DKS_PASS_FILE=/Users/glauco/Programming/AndroidKeystore/keystore.pass \
-DQT_HOST_PATH=/Users/glauco/Programming/Qt/SDK/6.3.0/macos \
-DQT_SDK_DIR=/Users/glauco/Programming/Qt/SDK/6.3.0 \
-DCMAKE_TOOLCHAIN_FILE=CMake/Cute.toolchain.cmake \
/Users/glauco/Programming/MyProjects/HelloWorld
# build
make MyApp-all -j8
# App/MyApp/android-build/build/outputs has apk and bundle folders
# containing debug apk for testing and bundle with release build
WebAssembly
Qt for WebAssembly 需要 Emscripten。以下命令在主机上设置 Emscripten:
# we are at /Users/glauco/Programming/Wasm
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 3.1.6
./emsdk activate 3.1.6
echo 'source "/Users/glauco/Programming/Wasm/emsdk/emsdk_env.sh"' >> ~/.zprofile
下面的命令使用 Qt 6.3 为 WebAssembly 构建应用程序:
# configure project
cmake -G "Unix Makefiles" \
-DCMAKE_BUILD_TYPE=Release \
-DWASM_TARGET=True \
-DWASM_SDK=/Users/glauco/Programming/Wasm/emsdk/upstream \
-DQT_SDK_DIR=/Users/glauco/Programming/Qt/SDK/6.3.0/wasm_32 \
-DQT_HOST_PATH=/Users/glauco/Programming/Qt/SDK/6.3.0/macos \
-DCMAKE_TOOLCHAIN_FILE=CMake/Cute.toolchain.cmake \
/Users/glauco/Programming/MyProjects/HelloWorld
# build project
make -j8
# load page on browser
emrun --browser firefox App/MyApp.html
结论
程序员用代码解决问题。查看 CMake 的最佳方式是作为一种用于对项目的构建过程进行编码的编程语言。
通过将 CMake 视为一种编程语言,您可以在偶然发现构建问题时编写解决方案,而不是暂停并期待有人修复它。有了这个观点,一切皆有可能。
网友评论