Build Qt5/Qt6 universal version for mac记录
人生苦短,少折腾是一种智慧
一. 相关背景
环境:
M1
macOS :14,12
Xcode:15,13
背景知识:
- Xcode工具链:
安装地址:https://developer.apple.com/develop/
包含编译器:clang
链接器:ld
调试器:LLDB
其他工具:otool、nm、ar、lipo、strip等
- LLVM 工具链(编译器框架):
安装地址:https://github.com/llvm/llvm-project/releases
LLVM 核心工具 :llvm-as llvm-dis llvm-link llvm-opt
Clang 工具: clang clang++ clang-format clang-tidy
LLDB 调试器 :lldb
其他工具: mlir-tblgen polly cfe
Xcode工具链依赖于Xcode IDE,集成良好,但是版本绑定;
LLVM工具链独立可随意升级。
安装LLVM主要是为了编译QDoc,不编译QDoc时不需要装。
If you want to build Qt WebEngine or Qt PDF, you will need the following additional dependencies:
Python html5lib
Bison, Flex
Gperf
Node.js version 8 or later (version 12 recommended)
Qt官方文档说明,如果要编译Qt WebEngine or Qt PDF,要安装上述几个依赖,切记不要用 brew 安装。brew install 的版本不是universal版本。比如node.js 需要去官网安装,官网支持universal,而不是brew安装。
编译universal版本切记一个要点,依赖的工具,依赖的库也要universal
检查完所有的编译依赖版本后,检查下系统路径有没有什么干扰,比如brew安装过的包llvm,clang 是不是配置过,这会导致编译Qt时不会用Xcode的clang版本。如下图注释掉。
vim ~/.bash_profile
or
vim ~/.zshrc
二. 编译Qt universal 版本
思路:
- 一套 x86-64 平台的二进制包
- 一套 arm64 平台的二进制包
- lipo 工具将这两套二进制打包成一包
- 上述步骤的1,2 通用做法是选择在对应的架构平台下编译,然后统一使用lipo(安装Xcode自带)创建出universal 包。
可参考如下链接,使用makeuniversal:
https://www.cnblogs.com/wqcwood/p/15138983.html
- 在一个非官方的文档看到过说低于Qt5.15.9和版本在Qt6.0~6.2之间不支持universal的构建,存疑,可能这里指的是交叉编译不支持。使用上述过程分别在对应平台构建,不使用交叉编译,按理说是通用支持的,折腾累了,没有自动化云环境建议放弃,多爱自己。
- 将编译成功的二进制lipo后,建工程测试均ok。使用命令查看,可看到支持arm64 和 x86_64两种架构
file demo.app/Contents/MacOS/demo
or
lipo -info demo.app/Contents/MacOS/demo
Qt5 编译可以参考(交叉编译尽量Qt5.15.9以上):
https://www.downtowndougbrown.com/2023/08/how-to-create-a-qt-5-arm-intel-universal-binary-for-mac/
Qt6 编译可以参考官方文档(最新Qt6.6.1):
https://doc.qt.io/qt-6/build-sources.html
一些命令:
查找clang位置
xcrun -sdk macosx -find clang
创建编译文件夹out 进入out
mkdir out && cd out
配置
../configure -skip qt3d -skip qtpdf -skip qtwebengine -no-feature-qdoc -- -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"
列出features,这个features可以在配置时候
使用-no-feature-xx 不选择,-feature-xx 选择。
../configure -list-features
最后:我选择Qt6官方的安装包,Qt5则使用之前Qt5.15.5 arm64编译版本。
https://blog.youkuaiyun.com/u011190652/article/details/126446114?spm=1001.2014.3001.5502
网上制作好的universal包
https://build-qt.fsu0413.me/
总结
- Qt5.15.9以下如果需要自己编译universal版本就去分别对应的平台下编译,在使用上面提到的makeuniversal工具调用lipo创建包。
- 编译Qt5.15.11或者Qt6最新版本,则使用交叉编译。交叉编译的前提是确保用到的工具链必须是universal版本。
- 为什么自己编译Qt,一是特殊需求官方没有,修改Qt源码自己维护一套,二是编译Qt与开发的软件编译工具链保持相同,理论上稳定性高一点。三是纯粹就想折腾下,了解过程。(差不多得了继续前进。)