Support building on Windows with Qt 6.

This commit is contained in:
John Preston 2024-06-21 11:36:18 +04:00
parent 053f8ad1c0
commit 93b7c47cda
22 changed files with 177 additions and 63 deletions

View file

@ -57,14 +57,6 @@ include(cmake/validate_d3d_compiler.cmake)
include(cmake/target_prepare_qrc.cmake)
include(cmake/options.cmake)
if (NOT DESKTOP_APP_USE_PACKAGED)
if (WIN32)
set(qt_version 5.15.13)
elseif (APPLE)
set(qt_version 6.2.8)
endif()
endif()
include(cmake/external/qt/package.cmake)
set(desktop_app_skip_libs

View file

@ -1828,12 +1828,29 @@ if (WIN32)
/DELAYLOAD:uxtheme.dll
/DELAYLOAD:crypt32.dll
/DELAYLOAD:bcrypt.dll
/DELAYLOAD:imm32.dll
/DELAYLOAD:netapi32.dll
/DELAYLOAD:userenv.dll
/DELAYLOAD:wtsapi32.dll
/DELAYLOAD:propsys.dll
)
if (QT_VERSION GREATER 6)
target_link_options(Telegram
PRIVATE
/DELAYLOAD:API-MS-Win-Core-Synch-l1-2-0.dll # Synchronization.lib
/DELAYLOAD:authz.dll # Authz.lib
/DELAYLOAD:dwrite.dll # DWrite.lib
/DELAYLOAD:dxgi.dll # DXGI.lib
/DELAYLOAD:d3d9.dll # D3D9.lib
/DELAYLOAD:d3d11.dll # D3D11.lib
/DELAYLOAD:d3d12.dll # D3D12.lib
/DELAYLOAD:setupapi.dll # SetupAPI.lib
)
else()
target_link_options(Telegram
PRIVATE
/DELAYLOAD:imm32.dll
)
endif()
endif()
target_prepare_qrc(Telegram)

View file

@ -118,7 +118,7 @@ constexpr auto kFileOpenTimeoutMs = crl::time(1000);
LaunchState GlobalLaunchState/* = LaunchState::Running*/;
void SetCrashAnnotationsGL() {
#ifdef Q_OS_WIN
#ifdef DESKTOP_APP_USE_ANGLE
CrashReports::SetAnnotation("OpenGL ANGLE", [] {
if (Core::App().settings().disableOpenGL()) {
return "Disabled";
@ -131,11 +131,11 @@ void SetCrashAnnotationsGL() {
}
Unexpected("Ui::GL::CurrentANGLE value in SetupANGLE.");
}());
#else // Q_OS_WIN
#else // DESKTOP_APP_USE_ANGLE
CrashReports::SetAnnotation(
"OpenGL",
Core::App().settings().disableOpenGL() ? "Disabled" : "Enabled");
#endif // Q_OS_WIN
#endif // DESKTOP_APP_USE_ANGLE
}
} // namespace

View file

@ -620,7 +620,7 @@ void Sandbox::processPostponedCalls(int level) {
bool Sandbox::nativeEventFilter(
const QByteArray &eventType,
void *message,
base::NativeEventResult *result) {
native_event_filter_result *result) {
registerEnterFromEventLoop();
return false;
}

View file

@ -8,7 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "mtproto/mtproto_proxy_data.h"
#include "base/qt/qt_common_adapters.h"
#include <QtWidgets/QApplication>
#include <QtNetwork/QLocalServer>
@ -87,7 +86,7 @@ private:
bool nativeEventFilter(
const QByteArray &eventType,
void *message,
base::NativeEventResult *result) override;
native_event_filter_result *result) override;
void processPostponedCalls(int level);
void singleInstanceChecked();
void launchApplication();

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "api/api_attached_stickers.h"
#include "api/api_peer_photo.h"
#include "base/qt/qt_common_adapters.h"
#include "lang/lang_keys.h"
#include "boxes/premium_preview_box.h"
#include "core/application.h"

View file

@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtWidgets/QFileDialog>
#include <QtGui/QDesktopServices>
#include <QtCore/QSettings>
#include <QtCore/QStandardPaths>
#include <Shlwapi.h>
#include <Windowsx.h>

View file

@ -43,7 +43,7 @@ WindowsIntegration &WindowsIntegration::Instance() {
bool WindowsIntegration::nativeEventFilter(
const QByteArray &eventType,
void *message,
long *result) {
native_event_filter_result *result) {
return Core::Sandbox::Instance().customEnterFromEventLoop([&] {
const auto msg = static_cast<MSG*>(message);
return processEvent(

View file

@ -29,7 +29,7 @@ private:
bool nativeEventFilter(
const QByteArray &eventType,
void *message,
long *result) override;
native_event_filter_result *result) override;
bool processEvent(
HWND hWnd,
UINT msg,

View file

@ -30,7 +30,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_controller.h"
#include "history/history.h"
#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QStyleFactory>
#include <QtWidgets/QApplication>
#include <QtGui/QWindow>
@ -81,7 +80,7 @@ private:
bool nativeEventFilter(
const QByteArray &eventType,
void *message,
long *result) override;
native_event_filter_result *result) override;
bool mainWindowEvent(
HWND hWnd,
@ -172,7 +171,7 @@ EventFilter::EventFilter(not_null<MainWindow*> window) : _window(window) {
bool EventFilter::nativeEventFilter(
const QByteArray &eventType,
void *message,
long *result) {
native_event_filter_result *result) {
return Core::Sandbox::Instance().customEnterFromEventLoop([&] {
const auto msg = static_cast<MSG*>(message);
if (msg->hwnd == _window->psHwnd()
@ -483,7 +482,7 @@ bool MainWindow::initGeometryFromSystem() {
bool MainWindow::nativeEvent(
const QByteArray &eventType,
void *message,
long *result) {
native_event_filter_result *result) {
if (message) {
const auto msg = static_cast<MSG*>(message);
if (msg->message == WM_IME_STARTCOMPOSITION) {

View file

@ -51,7 +51,7 @@ protected:
bool nativeEvent(
const QByteArray &eventType,
void *message,
long *result) override;
native_event_filter_result *result) override;
private:
struct Private;

View file

@ -29,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtCore/QOperatingSystemVersion>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtGui/QDesktopServices>
#include <QtGui/QWindow>

View file

@ -8,13 +8,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/win/windows_dlls.h"
#include "base/platform/win/base_windows_safe_library.h"
#include "ui/gl/gl_detection.h"
#include <VersionHelpers.h>
#include <QtCore/QSysInfo>
#define LOAD_SYMBOL(lib, name) ::base::Platform::LoadMethod(lib, #name, name)
#ifdef DESKTOP_APP_USE_ANGLE
bool DirectXResolveCompiler();
#endif // DESKTOP_APP_USE_ANGLE
namespace Platform {
namespace Dlls {
@ -67,6 +70,7 @@ SafeIniter kSafeIniter;
} // namespace
void CheckLoadedModules() {
#ifdef DESKTOP_APP_USE_ANGLE
if (DirectXResolveCompiler()) {
auto LibD3DCompiler = HMODULE();
if (GetModuleHandleEx(0, L"d3dcompiler_47.dll", &LibD3DCompiler)) {
@ -88,6 +92,7 @@ void CheckLoadedModules() {
} else {
LOG(("Error: Could not resolve DirectX compiler library."));
}
#endif // DESKTOP_APP_USE_ANGLE
}
} // namespace Dlls

View file

@ -822,7 +822,7 @@ void SetupHardwareAcceleration(not_null<Ui::VerticalLayout*> container) {
}, container->lifetime());
}
#ifdef Q_OS_WIN
#ifdef DESKTOP_APP_USE_ANGLE
void SetupANGLE(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container) {
@ -895,7 +895,7 @@ void SetupANGLE(
}));
});
}
#endif // Q_OS_WIN
#endif // DESKTOP_APP_USE_ANGLE
void SetupOpenGL(
not_null<Window::SessionController*> controller,
@ -938,13 +938,13 @@ void SetupPerformance(
not_null<Ui::VerticalLayout*> container) {
SetupAnimations(&controller->window(), container);
SetupHardwareAcceleration(container);
#ifdef Q_OS_WIN
#ifdef DESKTOP_APP_USE_ANGLE
SetupANGLE(controller, container);
#else // Q_OS_WIN
#else // DESKTOP_APP_USE_ANGLE
if constexpr (!Platform::IsMac()) {
SetupOpenGL(controller, container);
}
#endif // Q_OS_WIN
#endif // DESKTOP_APP_USE_ANGLE
}
void SetupWindowTitle(

View file

@ -1,7 +1,10 @@
import os, sys, pprint, re, json, pathlib, hashlib, subprocess, glob
executePath = os.getcwd()
sys.dont_write_bytecode = True
scriptPath = os.path.dirname(os.path.realpath(__file__))
sys.path.append(scriptPath + '/..')
import qt_version
def finish(code):
global executePath
@ -23,11 +26,24 @@ if win and not 'Platform' in os.environ:
win32 = win and (os.environ['Platform'] == 'x86')
win64 = win and (os.environ['Platform'] == 'x64')
winarm = win and (os.environ['Platform'] == 'arm')
arch = ''
if win32:
arch = 'x86'
elif win64:
arch = 'x64'
elif winarm:
arch = 'arm'
if not qt_version.resolve(arch):
error('Usupported platform.')
qt = os.environ.get('QT')
if win and not 'COMSPEC' in os.environ:
error('COMSPEC environment variable is not set.')
if win and not win32 and not win64:
if win and not win32 and not win64 and not winarm:
nativeToolsError()
os.chdir(scriptPath + '/../../../..')
@ -42,11 +58,8 @@ thirdPartyDir = os.path.realpath(os.path.join(rootDir, 'ThirdParty'))
usedPrefix = os.path.realpath(os.path.join(libsDir, 'local'))
optionsList = [
'qt6',
'skip-release',
'build-qt5',
'skip-qt5',
'build-qt6',
'skip-qt6',
'build-stackwalk',
]
options = []
@ -63,9 +76,6 @@ for arg in sys.argv[1:]:
customRunCommand = True
runCommand.append('shell')
buildQt5 = not 'skip-qt5' in options if win else 'build-qt5' in options
buildQt6 = 'build-qt6' in options if win else not 'skip-qt6' in options
if not os.path.isdir(os.path.join(libsDir, keysLoc)):
pathlib.Path(os.path.join(libsDir, keysLoc)).mkdir(parents=True, exist_ok=True)
if not os.path.isdir(os.path.join(thirdPartyDir, keysLoc)):
@ -435,7 +445,7 @@ if customRunCommand:
stage('patches', """
git clone https://github.com/desktop-app/patches.git
cd patches
git checkout 8639205c20
git checkout 20a7c5ffd8
""")
stage('msys64', """
@ -1398,7 +1408,9 @@ release:
lipo -create Release.arm64/libcrashpad_client.a Release.x86_64/libcrashpad_client.a -output Release/libcrashpad_client.a
""")
stage('tg_angle', """
if qt < '6':
if win:
stage('tg_angle', """
win:
git clone https://github.com/desktop-app/tg_angle.git
cd tg_angle
@ -1424,22 +1436,21 @@ release:
cd ..\\..\\..
""")
if buildQt5:
stage('qt_5_15_13', """
git clone -b v5.15.13-lts-lgpl https://github.com/qt/qt5.git qt_5_15_13
cd qt_5_15_13
stage('qt_' + qt, """
git clone -b v$QT-lts-lgpl https://github.com/qt/qt5.git qt_$QT
cd qt_$QT
git submodule update --init --recursive qtbase qtimageformats qtsvg
depends:patches/qtbase_5.15.13/*.patch
depends:patches/qtbase_""" + qt + """/*.patch
cd qtbase
win:
for /r %%i in (..\\..\\patches\\qtbase_5.15.13\\*) do git apply %%i -v
for /r %%i in (..\\..\\patches\\qtbase_%QT%\\*) do git apply %%i -v
cd ..
SET CONFIGURATIONS=-debug
release:
SET CONFIGURATIONS=-debug-and-release
win:
""" + removeDir("\"%LIBS_DIR%\\Qt-5.15.13\"") + """
""" + removeDir('"%LIBS_DIR%\\Qt-' + qt + '"') + """
SET ANGLE_DIR=%LIBS_DIR%\\tg_angle
SET ANGLE_LIBS_DIR=%ANGLE_DIR%\\out
SET MOZJPEG_DIR=%LIBS_DIR%\\mozjpeg
@ -1447,7 +1458,7 @@ win:
SET OPENSSL_LIBS_DIR=%OPENSSL_DIR%\\out
SET ZLIB_LIBS_DIR=%LIBS_DIR%\\zlib
SET WEBP_DIR=%LIBS_DIR%\\libwebp
configure -prefix "%LIBS_DIR%\\Qt-5.15.13" ^
configure -prefix "%LIBS_DIR%\\Qt-%QT%" ^
%CONFIGURATIONS% ^
-force-debug-info ^
-opensource ^
@ -1482,14 +1493,14 @@ win:
jom -j%NUMBER_OF_PROCESSORS%
jom -j%NUMBER_OF_PROCESSORS% install
mac:
find ../../patches/qtbase_5.15.13 -type f -print0 | sort -z | xargs -0 git apply
find ../../patches/qtbase_$QT -type f -print0 | sort -z | xargs -0 git apply
cd ..
CONFIGURATIONS=-debug
release:
CONFIGURATIONS=-debug-and-release
mac:
./configure -prefix "$USED_PREFIX/Qt-5.15.13" \
./configure -prefix "$USED_PREFIX/Qt-$QT" \
$CONFIGURATIONS \
-force-debug-info \
-opensource \
@ -1508,16 +1519,16 @@ mac:
make $MAKE_THREADS_CNT
make install
""")
if buildQt6:
stage('qt_6_2_8', """
mac:
git clone -b v6.2.8-lts-lgpl https://github.com/qt/qt5.git qt_6_2_8
cd qt_6_2_8
else: # qt > '6'
branch = 'v$QT' + ('-lts-lgpl' if qt < '6.3' else '')
stage('qt_' + qt, """
git clone -b """ + branch + """ https://github.com/qt/qt5.git qt_$QT
cd qt_$QT
git submodule update --init --recursive qtbase qtimageformats qtsvg
depends:patches/qtbase_6.2.8/*.patch
depends:patches/qtbase_""" + qt + """/*.patch
cd qtbase
find ../../patches/qtbase_6.2.8 -type f -print0 | sort -z | xargs -0 git apply -v
mac:
find ../../patches/qtbase_$QT -type f -print0 | sort -z | xargs -0 git apply -v
cd ..
sed -i.bak 's/tqtc-//' {qtimageformats,qtsvg}/dependencies.yaml
@ -1525,7 +1536,7 @@ depends:patches/qtbase_6.2.8/*.patch
release:
CONFIGURATIONS=-debug-and-release
mac:
./configure -prefix "$USED_PREFIX/Qt-6.2.8" \
./configure -prefix "$USED_PREFIX/Qt-$QT" \
$CONFIGURATIONS \
-force-debug-info \
-opensource \
@ -1546,6 +1557,62 @@ mac:
ninja
ninja install
win:
for /r %%i in (..\\..\\patches\\qtbase_%QT%\\*) do git apply %%i -v
cd ..
SET CONFIGURATIONS=-debug
release:
SET CONFIGURATIONS=-debug-and-release
win:
""" + removeDir('"%LIBS_DIR%\\Qt' + qt + '"') + """
SET MOZJPEG_DIR=%LIBS_DIR%\\mozjpeg
SET OPENSSL_DIR=%LIBS_DIR%\\openssl3
SET OPENSSL_LIBS_DIR=%OPENSSL_DIR%\\out
SET ZLIB_LIBS_DIR=%LIBS_DIR%\\zlib
SET WEBP_DIR=%LIBS_DIR%\\libwebp
configure -prefix "%LIBS_DIR%\\Qt-%QT%" ^
%CONFIGURATIONS% ^
-force-debug-info ^
-opensource ^
-confirm-license ^
-static ^
-static-runtime ^
-feature-c++20 ^
-openssl linked ^
-system-webp ^
-system-zlib ^
-system-libjpeg ^
-nomake examples ^
-nomake tests ^
-platform win32-msvc ^
-D ZLIB_WINAPI ^
-- ^
-D OPENSSL_FOUND=1 ^
-D OPENSSL_INCLUDE_DIR="%OPENSSL_DIR%\\include" ^
-D LIB_EAY_DEBUG="%OPENSSL_LIBS_DIR%.dbg\\libcrypto.lib" ^
-D SSL_EAY_DEBUG="%OPENSSL_LIBS_DIR%.dbg\\libssl.lib" ^
-D LIB_EAY_RELEASE="%OPENSSL_LIBS_DIR%\\libcrypto.lib" ^
-D SSL_EAY_RELEASE="%OPENSSL_LIBS_DIR%\\libssl.lib" ^
-D JPEG_FOUND=1 ^
-D JPEG_INCLUDE_DIR="%MOZJPEG_DIR%" ^
-D JPEG_LIBRARY_DEBUG="%MOZJPEG_DIR%\\Debug\\jpeg-static.lib" ^
-D JPEG_LIBRARY_RELEASE="%MOZJPEG_DIR%\\Release\\jpeg-static.lib" ^
-D ZLIB_FOUND=1 ^
-D ZLIB_INCLUDE_DIR="%ZLIB_LIBS_DIR%" ^
-D ZLIB_LIBRARY_DEBUG="%ZLIB_LIBS_DIR%\\Debug\\zlibstaticd.lib" ^
-D ZLIB_LIBRARY_RELEASE="%ZLIB_LIBS_DIR%\\Release\\zlibstatic.lib" ^
-D WebP_INCLUDE_DIR="%WEBP_DIR%\\src" ^
-D WebP_demux_INCLUDE_DIR="%WEBP_DIR%\\src" ^
-D WebP_mux_INCLUDE_DIR="%WEBP_DIR%\\src" ^
-D WebP_LIBRARY="%WEBP_DIR%\\out\\release-static\\$X8664\\lib\\webp.lib" ^
-D WebP_demux_LIBRARY="%WEBP_DIR%\\out\\release-static\\$X8664\\lib\\webpdemux.lib" ^
-D WebP_mux_LIBRARY="%WEBP_DIR%\\out\\release-static\\$X8664\\lib\\webpmux.lib"
cmake --build . --config Debug --parallel
cmake --install . --config Debug
cmake --build . --parallel
cmake --install .
""")
stage('tg_owt', """

View file

@ -0,0 +1,17 @@
import sys, os
def resolve(arch):
if sys.platform == 'darwin':
os.environ['Qt'] = '6.2.8'
elif sys.platform == 'win32':
if arch == 'arm' or 'qt6' in sys.argv:
print('Choosing Qt 6.')
os.environ['QT'] = '6.7.2'
elif os.environ.get('QT') is None:
print('Choosing Qt 5.')
os.environ['QT'] = '5.15.13'
else:
print('Choosing Qt ' + os.environ.get('QT'))
else:
return False
return True

View file

@ -8,7 +8,9 @@ function(generate_midl target_name src_loc)
set(gen_dst ${CMAKE_CURRENT_BINARY_DIR}/gen)
file(MAKE_DIRECTORY ${gen_dst})
if (build_win64)
if (build_winarm)
set(env arm64)
elseif (build_win64)
set(env x64)
else()
set(env win32)

View file

@ -34,6 +34,13 @@ PUBLIC
desktop-app::lib_tl
)
if (WIN32 AND NOT build_win64 AND NOT build_winarm AND QT_VERSION GREATER 6)
target_compile_options(td_scheme
PRIVATE
/bigobj # scheme.cpp has too many sections.
)
endif()
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "mips64")
# Sometimes final linking may fail with error "relocation truncated to fit"
# due to large scheme size.

View file

@ -11,6 +11,8 @@ sys.dont_write_bytecode = True
scriptPath = os.path.dirname(os.path.realpath(__file__))
sys.path.append(scriptPath + '/../cmake')
import run_cmake
sys.path.append(scriptPath + '/build')
import qt_version
executePath = os.getcwd()
def finish(code):
@ -41,12 +43,18 @@ if officialTarget in ['win', 'uwp']:
arch = 'x86'
elif officialTarget in ['win64', 'uwp64']:
arch = 'x64'
elif officialTarget in ['winarm', 'uwparm']:
arch = 'arm'
if not qt_version.resolve(arch):
error('Usupported platform.')
if 'qt6' in arguments:
arguments.remove('qt6')
if officialTarget != '':
officialApiIdFile = scriptPath + '/../../DesktopPrivate/custom_api_id.h'
if not os.path.isfile(officialApiIdFile):
print("[ERROR] DesktopPrivate/custom_api_id.h not found.")
finish(1)
error('DesktopPrivate/custom_api_id.h not found.')
with open(officialApiIdFile, 'r') as f:
for line in f:
apiIdMatch = re.search(r'ApiId\s+=\s+(\d+)', line)

@ -1 +1 @@
Subproject commit 953b0bf548f36213414e6f1a65dd3ebad618350e
Subproject commit 324cbc7d17b4fcacffc1faf958c5fa3d10d0e5da

@ -1 +1 @@
Subproject commit 0dd59f1a9c740d86083a80291a5081e3a9e3ecf8
Subproject commit 360464fd9d073d3919783ed800fb3b3682a261a0

2
cmake

@ -1 +1 @@
Subproject commit a7527c0e6eba1c71cd0dfd7bd8de9c1e68cb529f
Subproject commit b92244f0c21f157600484498c33a3566087526dd