diff --git a/.gitmodules b/.gitmodules index f65bd875a51..92d3bdfe13f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,59 +1,59 @@ [submodule "qtbase"] path = qtbase - url = ../qtbase.git + url = https://github.com/shinyTang/qtbase.git branch = 5.12.3 status = essential [submodule "qtsvg"] depends = qtbase path = qtsvg - url = ../qtsvg.git + url = https://github.com/qt/qtsvg.git branch = 5.12.3 status = addon [submodule "qtdeclarative"] depends = qtbase recommends = qtsvg path = qtdeclarative - url = ../qtdeclarative.git + url = https://github.com/qt/qtdeclarative.git branch = 5.12.3 status = essential [submodule "qtactiveqt"] depends = qtbase path = qtactiveqt - url = ../qtactiveqt.git + url = https://github.com/qt/qtactiveqt.git branch = 5.12.3 status = addon [submodule "qtscript"] depends = qtbase recommends = qttools path = qtscript - url = ../qtscript.git + url = https://github.com/qt/qtscript.git branch = 5.12.3 status = deprecated [submodule "qtmultimedia"] depends = qtbase recommends = qtdeclarative path = qtmultimedia - url = ../qtmultimedia.git + url = https://github.com/shinyTang/qtmultimedia.git branch = 5.12.3 status = essential [submodule "qttools"] depends = qtbase recommends = qtdeclarative qtactiveqt path = qttools - url = ../qttools.git + url = https://github.com/qt/qttools.git branch = 5.12.3 status = essential [submodule "qtxmlpatterns"] depends = qtbase recommends = qtdeclarative path = qtxmlpatterns - url = ../qtxmlpatterns.git + url = https://github.com/qt/qtxmlpatterns.git branch = 5.12.3 status = addon [submodule "qttranslations"] depends = qttools path = qttranslations - url = ../qttranslations.git + url = https://github.com/qt/qttranslations.git branch = 5.12.3 status = essential priority = 30 @@ -61,20 +61,20 @@ depends = qtdeclarative qttools recommends = qtmultimedia qtquickcontrols qtquickcontrols2 path = qtdoc - url = ../qtdoc.git + url = https://github.com/qt/qtdoc.git branch = 5.12.3 status = essential priority = 40 [submodule "qtrepotools"] path = qtrepotools - url = ../qtrepotools.git + url = https://github.com/qt/qtrepotools.git branch = master status = essential project = - [submodule "qtqa"] depends = qtbase path = qtqa - url = ../qtqa.git + url = https://github.com/qt/qtqa.git branch = master status = essential priority = 50 @@ -82,226 +82,227 @@ depends = qtbase recommends = qtdeclarative qtquickcontrols qtquickcontrols2 qtserialport path = qtlocation - url = ../qtlocation.git + url = https://github.com/qt/qtlocation.git branch = 5.12.3 status = addon [submodule "qtsensors"] depends = qtbase recommends = qtdeclarative path = qtsensors - url = ../qtsensors.git + url = https://github.com/qt/qtsensors.git branch = 5.12.3 status = addon [submodule "qtsystems"] depends = qtbase recommends = qtdeclarative path = qtsystems - url = ../qtsystems.git + url = https://github.com/qt/qtsystems.git branch = dev status = ignore [submodule "qtfeedback"] depends = qtdeclarative recommends = qtmultimedia path = qtfeedback - url = ../qtfeedback.git + url = https://github.com/qt/qtfeedback.git branch = master status = ignore [submodule "qtdocgallery"] depends = qtdeclarative path = qtdocgallery - url = ../qtdocgallery.git + url = https://github.com/qt/qtdocgallery.git branch = master status = ignore [submodule "qtpim"] depends = qtdeclarative path = qtpim - url = ../qtpim.git + url = https://github.com/qt/qtpim.git branch = dev status = ignore [submodule "qtconnectivity"] depends = qtbase recommends = qtdeclarative qtandroidextras path = qtconnectivity - url = ../qtconnectivity.git + url = https://github.com/qt/qtconnectivity.git branch = 5.12.3 status = addon [submodule "qtwayland"] depends = qtbase recommends = qtdeclarative path = qtwayland - url = ../qtwayland.git + url = https://github.com/qt/qtwayland.git branch = 5.12.3 status = addon [submodule "qt3d"] depends = qtbase recommends = qtdeclarative qtimageformats qtgamepad path = qt3d - url = ../qt3d.git + url = https://github.com/qt/qt3d.git branch = 5.12.3 status = addon [submodule "qtimageformats"] depends = qtbase path = qtimageformats - url = ../qtimageformats.git + url = https://github.com/qt/qtimageformats.git branch = 5.12.3 status = addon [submodule "qtgraphicaleffects"] depends = qtdeclarative path = qtgraphicaleffects - url = ../qtgraphicaleffects.git + url = https://github.com/qt/qtgraphicaleffects.git branch = 5.12.3 status = addon [submodule "qtquickcontrols"] depends = qtdeclarative recommends = qtgraphicaleffects path = qtquickcontrols - url = ../qtquickcontrols.git + url = https://github.com/qt/qtquickcontrols.git branch = 5.12.3 status = addon [submodule "qtserialbus"] depends = qtserialport path = qtserialbus - url = ../qtserialbus.git + url = https://github.com/qt/qtserialbus.git branch = 5.12.3 status = addon [submodule "qtserialport"] depends = qtbase path = qtserialport - url = ../qtserialport.git + url = https://github.com/qt/qtserialport.git branch = 5.12.3 status = addon [submodule "qtx11extras"] depends = qtbase path = qtx11extras - url = ../qtx11extras.git + url = https://github.com/qt/qtx11extras.git branch = 5.12.3 status = addon [submodule "qtmacextras"] depends = qtbase path = qtmacextras - url = ../qtmacextras.git + url = https://github.com/qt/qtmacextras.git branch = 5.12.3 status = addon [submodule "qtwinextras"] depends = qtbase recommends = qtdeclarative qtmultimedia path = qtwinextras - url = ../qtwinextras.git + url = https://github.com/qt/qtwinextras.git branch = 5.12.3 status = addon [submodule "qtandroidextras"] depends = qtbase path = qtandroidextras - url = ../qtandroidextras.git + url = https://github.com/qt/qtandroidextras.git branch = 5.12.3 status = addon [submodule "qtwebsockets"] depends = qtbase recommends = qtdeclarative path = qtwebsockets - url = ../qtwebsockets.git + url = https://github.com/qt/qtwebsockets.git branch = 5.12.3 status = addon [submodule "qtwebchannel"] depends = qtbase recommends = qtdeclarative qtwebsockets path = qtwebchannel - url = ../qtwebchannel.git + url = https://github.com/qt/qtwebchannel.git branch = 5.12.3 status = addon [submodule "qtwebengine"] depends = qtdeclarative recommends = qtquickcontrols qtquickcontrols2 qtlocation qtwebchannel qttools path = qtwebengine - url = ../qtwebengine.git + url = https://github.com/qt/qtwebengine.git branch = 5.12.3 status = addon priority = 10 [submodule "qtcanvas3d"] depends = qtdeclarative path = qtcanvas3d - url = ../qtcanvas3d.git + url = https://github.com/qt/qtcanvas3d.git branch = 5.12.3 status = addon [submodule "qtwebview"] depends = qtdeclarative recommends = qtwebengine path = qtwebview - url = ../qtwebview.git + url = https://github.com/qt/qtwebview.git branch = 5.12.3 status = addon [submodule "qtquickcontrols2"] depends = qtgraphicaleffects recommends = qtimageformats path = qtquickcontrols2 - url = ../qtquickcontrols2.git + url = https://github.com/qt/qtquickcontrols2.git branch = 5.12.3 status = essential [submodule "qtpurchasing"] depends = qtbase recommends = qtdeclarative qtandroidextras path = qtpurchasing - url = ../qtpurchasing.git + url = https://github.com/qt/qtpurchasing.git branch = 5.12.3 status = addon [submodule "qtcharts"] depends = qtbase recommends = qtdeclarative qtmultimedia path = qtcharts - url = ../qtcharts.git + url = https://github.com/qt/qtcharts.git branch = 5.12.3 status = addon [submodule "qtdatavis3d"] depends = qtbase recommends = qtdeclarative qtmultimedia path = qtdatavis3d - url = ../qtdatavis3d.git + url = https://github.com/qt/qtdatavis3d.git branch = 5.12.3 status = addon [submodule "qtvirtualkeyboard"] depends = qtbase qtdeclarative qtsvg recommends = qtmultimedia qtquickcontrols path = qtvirtualkeyboard - url = ../qtvirtualkeyboard.git + url = https://github.com/qt/qtvirtualkeyboard.git branch = 5.12.3 status = addon [submodule "qtgamepad"] depends = qtbase recommends = qtdeclarative path = qtgamepad - url = ../qtgamepad.git + url = https://github.com/qt/qtgamepad.git branch = 5.12.3 status = addon [submodule "qtscxml"] depends = qtbase qtdeclarative path = qtscxml - url = ../qtscxml.git + url = https://github.com/qt/qtscxml.git branch = 5.12.3 status = addon [submodule "qtspeech"] depends = qtbase recommends = qtdeclarative qtmultimedia path = qtspeech - url = ../qtspeech.git + url = https://github.com/qt/qtspeech.git branch = 5.12.3 status = addon [submodule "qtnetworkauth"] depends = qtbase path = qtnetworkauth - url = ../qtnetworkauth.git + url = https://github.com/qt/qtnetworkauth.git branch = 5.12.3 status = addon [submodule "qtremoteobjects"] depends = qtbase recommends = qtdeclarative path = qtremoteobjects - url = ../qtremoteobjects.git + url = https://github.com/qt/qtremoteobjects.git branch = 5.12.3 status = addon [submodule "qtwebglplugin"] depends = qtbase qtwebsockets recommends = qtdeclarative path = qtwebglplugin - url = ../qtwebglplugin.git + url = https://github.com/qt/qtwebglplugin.git branch = 5.12.3 status = addon + diff --git a/README b/README.md similarity index 57% rename from README rename to README.md index dd4af0d545a..7dec8c685df 100644 --- a/README +++ b/README.md @@ -1,3 +1,65 @@ +# Qt 5.12.3 Universal (Apple Silicon/macOS) + +**Source Repository:** [https://github.com/qt/qt5](https://github.com/qt/qt5) + +--- + +## Purpose + +> The official Qt 5.12.3 release lacks support for compilation on macOS ARM (Apple Silicon) architectures. +> This branch provides a patch for Qt 5.12.3 that enables compilation and native execution for both Intel (x86_64) and ARM (arm64) architectures, as well as legacy 32-bit Intel (i386). + +--- + +## 🚩 **Branch Modifications (Differences)** + +This branch is based on the Qt dev branch at commit `8337e20fadddf` (Qt 5.12.3 release). +**Key changes:** + +### 1. `qtbase` Module: +- **Fixed:** Missing `#include ` in libpng to resolve compilation errors. +- **Removed:** `#error "32-bit builds are not supported"` directives and related code in Cocoa platform plugins to enable 32-bit (i386) compilation support on macOS. +- **Added:** Necessary includes (e.g., `#include `) for the macOS graphics stack. + +### 2. `qtmultimedia` Module: +- **Refactored:** AVFoundation plugin code replacing deprecated C++98 functional utilities (`std::binary_function`, `std::unary_function`, `std::not2`) with modern C++11/14 equivalents (lambda functions, etc.). + +**Summary:** +These changes ensure Qt 5.12.3 can be compiled for both Intel (x86_64) and ARM (arm64) architectures on macOS, as well as for the legacy 32-bit Intel (i386) target, creating a more universal build. + +--- + +## 🛠️ **Build Instructions** + +This project uses the `build_opensource.sh` script to compile Qt libraries for both x86_64 and ARM64 architectures, then merges them into a single Universal 2 binary. + +### Building Universal Libraries (macOS) + +1. **Prerequisite – Install Identical `libxcb`:** + Before running the build script, install the **same version** of the `libxcb` library on both your x86_64 (Intel) and ARM64 (Apple Silicon) machines. + +2. **Create a Merged `libxcb` Library:** + - On each machine, locate the `libxcb.dylib` file (usually in `/usr/local/lib` or `/opt/homebrew/lib`). + - Use the `lipo` tool to merge: + ```sh + lipo -create /path/on/x86_machine/libxcb.dylib /path/on/arm_machine/libxcb.dylib -output ./lib/libxcb.dylib + ``` + - Replace the system library: Copy the universal `./lib/libxcb.dylib` and overwrite the existing `libxcb.dylib` in your library directory (e.g., `/usr/local/lib`). + +3. **Execute the Build Script:** + ```sh + cd qt5.12.3_universal + bash build_opensource.sh + ``` + +### Building a Single Architecture + +If you **do not need** a universal library, you can modify the `build_opensource.sh` script to compile for only one architecture (either x86_64 or arm64). +Edit the script to comment out or remove the lines for the other architecture. + +## +## Original Qt README + HOW TO BUILD QT5 ================ diff --git a/build_opensource.sh b/build_opensource.sh new file mode 100644 index 00000000000..8bce3384992 --- /dev/null +++ b/build_opensource.sh @@ -0,0 +1,60 @@ +#!bash + +SCRIPT=$(dirname "$0") +cd $SCRIPT +BASEDIR=`pwd` +ENABLE_QT_DEBUG_VER_BUILD=0 +echo $BASEDIR +prj_path="build_opensource" +if [ "$1" != "" ]; then + prj_path="$1" +fi +echo $prj_path + +mkdir -p $prj_path && cd $prj_path + +build_fun() +{ + BUILD_DIRNAME="build_$1" + QT_INSTALL_DIR="$BASEDIR/$prj_path/Qt5.12.3_$1" + + if [ $ENABLE_QT_DEBUG_VER_BUILD == 1 ]; then + BUILD_DIRNAME="build_$1_debug" + QT_INSTALL_DIR="$BASEDIR/$prj_path/Qt5.12.3_$1_debug" + fi + + + mkdir -p $BUILD_DIRNAME && cd $BUILD_DIRNAME + if [ ! -f Makefile ];then + $BASEDIR/configure -prefix $QT_INSTALL_DIR -skip qt3d -skip qtwebengine -skip qtlocation -skip qtconnectivity -nomake examples -nomake tests -device-option QMAKE_APPLE_DEVICE_ARCHS="$1" QMAKE_MACOSX_DEPLOYMENT_TARGET=10.13 -opensource -confirm-license + + if [ $ENABLE_QT_DEBUG_VER_BUILD == 1 ]; then + $BASEDIR/configure -prefix $QT_INSTALL_DIR -debug -skip qt3d -skip qtwebengine -skip qtlocation -skip qtconnectivity -nomake examples -nomake tests -device-option QMAKE_APPLE_DEVICE_ARCHS="$1" QMAKE_MACOSX_DEPLOYMENT_TARGET=10.13 -opensource -confirm-license + fi + + sed -i "" '/QMAKE *=/ s/$/ QMAKE_APPLE_DEVICE_ARCHS="'$1'"/' Makefile + cd qtbase/qmake/ + make clean + sed -i "" '/CXX =/ s/$/ -arch '$1'/' Makefile + make + cd - + fi + set -e + make -j8 > /dev/null + set +e + make -j8 install > /dev/null + + cd .. +} + +echo build x86_64 debug_ver=$ENABLE_QT_DEBUG_VER_BUILD +build_fun "x86_64" +echo build arm64 debug_ver=$ENABLE_QT_DEBUG_VER_BUILD +build_fun "arm64" +echo make universal +cd $BASEDIR +python3 make_universal.py $prj_path/Qt5.12.3 $prj_path/Qt5.12.3_x86_64 $prj_path/Qt5.12.3_arm64 +# arm64 版本的 macdeployqt 无法正确运行,于是使用 x86_64 的版本 +cp $prj_path/Qt5.12.3_x86_64/bin/macdeployqt $prj_path/Qt5.12.3/bin +# qt.conf 用来指定当前 qmake 所依赖的的 Qt 库 +cp qt.conf $prj_path/Qt5.12.3/bin diff --git a/make_universal.py b/make_universal.py new file mode 100644 index 00000000000..327af82b366 --- /dev/null +++ b/make_universal.py @@ -0,0 +1,65 @@ +#!/usr/local/bin/python3 +# -*- coding: UTF-8 -*- +import os +import sys +from os import listdir + +success = 0 +failed = 0 +skipped = 0 + +def check_arch(file_name, arch): +# print("lipo " + file_name + " -verify_arch " + arch) + return os.system("lipo " + file_name + " -verify_arch " + arch) + + +def lipo(universal_path, arm64_path, x86_64_path): +# print("lipo -create -output " + universal_path + " " + arm64_path + " " + x86_64_path) + return os.system("lipo -create -output " + universal_path + " " + arm64_path + " " + x86_64_path) + + +def merge_binary(universal_path, arm64_path, x86_64_path): + global failed + global success + global skipped + if check_arch(universal_path, "arm64") != 0: + if check_arch(arm64_path, "arm64") == 0: + if lipo(universal_path, arm64_path, x86_64_path) == 0: +# print("success adding arm64 arch to binary") + success += 1 + else: + print("failed adding arm64 arch to binary") + failed += 1 + else: +# print(arm64_path) + print("failed doesn't has arm64 arch in binary") + failed += 1 + else: + skipped += 1 + + +def traverse_path(universal_path, arm64_path, x86_64_path): + for filename in os.listdir(x86_64_path): + x86_64_full_path = x86_64_path + '/' + filename + arm64_full_path = arm64_path + '/' + filename + universal_full_path = universal_path + '/' + filename + if os.path.isdir(x86_64_full_path) is True and os.path.islink(x86_64_full_path) is False: + traverse_path(universal_full_path, arm64_full_path, x86_64_full_path) + elif os.path.isfile(x86_64_full_path) and (os.access(x86_64_full_path, os.X_OK) or x86_64_full_path.endswith(".a")) and check_arch(x86_64_full_path, "x86_64") == 0: + merge_binary(universal_full_path, arm64_full_path, x86_64_full_path) + + +def copy_x86_to_universal(x86_64_path, universal_path): + os.system("rsync -av --progress -l -r " + x86_64_path + "/ " + universal_path) + + +def main(universal_path, x86_64_path, arm64_path): + copy_x86_to_universal(x86_64_path, universal_path) + traverse_path(universal_path, arm64_path, x86_64_path) + print("success file", success, "failed", + failed, "skipped", skipped) + + +if __name__ == '__main__': + if len(sys.argv) != 4: + print("usage: python3 make_universal.py universal_path x86_64_path arm64_path") + main(sys.argv[1], sys.argv[2], sys.argv[3]) diff --git a/qt.conf b/qt.conf new file mode 100644 index 00000000000..7c8013cf9ae --- /dev/null +++ b/qt.conf @@ -0,0 +1,3 @@ +[Paths] +Prefix=.. +Plugins=../plugins diff --git a/qtbase b/qtbase index 534df5a33bd..a46c2553f44 160000 --- a/qtbase +++ b/qtbase @@ -1 +1 @@ -Subproject commit 534df5a33bd6a3d0d00194212cf868a9ef57bd53 +Subproject commit a46c2553f4402f113629138ba8db3d7498ef22bf diff --git a/qtmultimedia b/qtmultimedia index c7e735198c6..6191083e483 160000 --- a/qtmultimedia +++ b/qtmultimedia @@ -1 +1 @@ -Subproject commit c7e735198c6cc01201f90b64c8a6d35fc40584fc +Subproject commit 6191083e4837fad094ca4eff7406c3e4f8bc1c4e