diff --git a/.docker/third-party.bake.Dockerfile b/.docker/third-party.bake.Dockerfile new file mode 100644 index 0000000000..94f1927a29 --- /dev/null +++ b/.docker/third-party.bake.Dockerfile @@ -0,0 +1,98 @@ +FROM ubuntu:18.04 AS third-party-builder + + # Prevent interactive prompts + ENV DEBIAN_FRONTEND=noninteractive + + # Install build dependencies for 18.04 + # Note: python-is-python3 doesn't exist here, so we link it manually + RUN apt-get update && apt-get install -y \ + build-essential \ + wget \ + tar \ + curl \ + file \ + lsb-release \ + procps \ + git \ + python3 \ + python3-pip \ + pkg-config \ + libgstreamer1.0-dev \ + libgstreamer-plugins-base1.0-dev \ + libgl1-mesa-dev \ + libxcb1-dev \ + libdbus-1-dev \ + libicu-dev \ + libfreetype6-dev \ + libfontconfig1-dev \ + libharfbuzz-dev \ + #libxkbcommon-dev \ + #libxkbcommon-x11-dev \ + libxcb-xinput-dev \ + libsm-dev \ + libatspi2.0-dev \ + libglib2.0-dev \ + libxi-dev \ + libasound2-dev \ + libpulse-dev \ + #libssl-dev \ + #libssl1.0-dev \ + libcups2-dev \ + libgtk-3-dev \ + libxcomposite-dev \ + libx11-xcb-dev \ + libxrender-dev \ + libxrandr-dev \ + libxinerama-dev \ + libxcursor-dev \ + libgirepository1.0-dev \ + libcairo2-dev \ + libnss3-dev \ + libgnome-keyring-dev \ + libgbm-dev \ + gperf \ + locales \ + uuid-dev \ + libcurl4-openssl-dev \ + libkrb5-dev \ + libpci-dev \ + && ln -s /usr/bin/python3 /usr/bin/python \ + && rm -rf /var/lib/apt/lists/* + + RUN apt-get update && apt-get install -y \ + wget build-essential libssl-dev zlib1g-dev libbz2-dev \ + libreadline-dev libsqlite3-dev libffi-dev liblzma-dev \ + libncursesw5-dev xz-utils && \ + wget -q https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz && \ + tar xzf Python-3.10.13.tgz && \ + cd Python-3.10.13 && \ + ./configure --prefix=/usr/local && \ + make -j"$(nproc)" && \ + make altinstall && \ + cd .. && rm -rf Python-3.10.13* && \ + python3.10 --version + + RUN apt-get update && apt-get install -y sudo && \ + curl 'https://chromium.googlesource.com/chromium/src/+/refs/tags/109.0.5414.120/build/install-build-deps.sh?format=TEXT' \ + | base64 -d > install-build-deps.sh && \ + chmod +x install-build-deps.sh && \ + ./install-build-deps.sh --no-arm --no-chromeos-fonts --no-nacl --no-prompt && \ + python3 -m pip install dataclasses importlib_metadata && \ + locale-gen en_US.UTF-8 && \ + update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 && \ + rm -rf /var/lib/apt/lists/* + + + COPY /core/Common/3dParty /3dParty + + + RUN --mount=type=secret,id=nextcloud_user \ + --mount=type=secret,id=nextcloud_pass \ + export NEXTCLOUD_USER="$(cat /run/secrets/nextcloud_user)" && \ + export NEXTCLOUD_PASS="$(cat /run/secrets/nextcloud_pass)" && \ + python3.10 /3dParty/build_3rdparty.py \ + --only=qt,cef \ + /third_party/work \ + /third_party/install + + \ No newline at end of file diff --git a/Common/3dParty/build_3rdparty.py b/Common/3dParty/build_3rdparty.py index 9ffc7f0e92..787941ce5d 100644 --- a/Common/3dParty/build_3rdparty.py +++ b/Common/3dParty/build_3rdparty.py @@ -26,6 +26,9 @@ 'socketio', 'hunspell', 'v8', + 'icu-desktop', + 'cef', + 'qt' ] force_redo_subfolders = [] @@ -154,7 +157,7 @@ def print_help(): time_meas = nc.MeasurementObj( subfolder ) subprocess.run( - [sys.executable, sub_script, work_dir / subfolder, install_dir / subfolder, "force-redo" if force_redo else "" ], + [sys.executable, "-u", sub_script, work_dir / subfolder, install_dir / subfolder, "force-redo" if force_redo else "" ], check=True, text=True, stdout=None, diff --git a/Common/3dParty/cef/nc-build.py b/Common/3dParty/cef/nc-build.py new file mode 100644 index 0000000000..565f3c7413 --- /dev/null +++ b/Common/3dParty/cef/nc-build.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +import sys +import shutil +import os +import time +import subprocess +from pathlib import Path + +script_path = Path(sys.argv[0]).resolve() +script_dir = script_path.parent + +cef_branch = "5414" +cef_checkout = "f1c41e4b1392ef8816171c4d51a2fca308db5501" +automate_git_url = "https://raw.githubusercontent.com/chromiumembedded/cef/master/tools/automate/automate-git.py" + +gn_defines = ( "is_official_build=true use_sysroot=true symbol_level=0 " + "is_cfi=false use_thin_lto=true use_vaapi=false " + "use_gtk=true use_dbus=true use_partition_alloc_as_malloc=false" ) + +max_gclient_retries = 20 +max_recovery_tries = 3 + +third_party_root = ( script_dir / ".." ).resolve() +if str( third_party_root ) not in sys.path: + sys.path.insert( 0, str( third_party_root ) ) + +import build_3rdparty_common as nc + +nc.init_for_dep( + depname = "cef", + workdir = Path( sys.argv[1] ).resolve(), + installdir = Path( sys.argv[2] ).resolve(), + forceredo = len(sys.argv) > 3 and sys.argv[3] == "force-redo" +) + +automate_dir = nc.work_dir / "automate" +download_dir = nc.work_dir / "chromium_git" + + +def fetch_and_patch(): + nc.create_workdir() + + automate_dir.mkdir( parents = True, exist_ok = True ) + download_dir.mkdir( parents = True, exist_ok = True ) + + nc.run_command( + [ "wget", automate_git_url, "-O", str( automate_dir / "automate-git.py" ) ], + "Download automate-git.py", + automate_dir + ) + + nc.create_work_dir_ok_marker() + print( "Fetch & patch completed" ) + + +def setup_build_env(): + os.environ["LANG"] = "en_US.UTF-8" + os.environ["LC_ALL"] = "en_US.UTF-8" + os.environ["GN_DEFINES"] = gn_defines + os.environ["CEF_ARCHIVE_FORMAT"] = "tar.bz2" + + +def run_gclient_recovery(): + print( "!!! automate-git.py failed. Attempting to recover via gclient sync..." ) + + # automate-git.py downloads depot_tools inside the download dir. + # Add it to PATH so we can use 'gclient'. + depot_tools_dir = download_dir / "depot_tools" + os.environ["PATH"] = os.environ["PATH"] + os.pathsep + str( depot_tools_dir ) + + chromium_dir = download_dir / "chromium" + + retry_count = 0 + while True: + result = subprocess.run( + [ "gclient", "sync", "--force", "--reset", + "--with_branch_heads", "--with_tags" ], + cwd = chromium_dir + ) + if result.returncode == 0: + break + retry_count += 1 + if retry_count > max_gclient_retries: + nc.abort_op( f"Failed to sync after {max_gclient_retries} attempts" ) + print( f"gclient sync failed (Attempt {retry_count}/{max_gclient_retries}). " + "Retrying in 10 seconds..." ) + time.sleep( 10 ) + + print( "!!! gclient sync succeeded. Resuming build..." ) + + shutil.rmtree( download_dir / "cef", ignore_errors = True ) + shutil.rmtree( depot_tools_dir, ignore_errors = True ) + + +def run_automate_git(): + # Not using nc.run_command here because failure is expected and + # handled by the recovery loop instead of aborting. + result = subprocess.run( + [ sys.executable, + str( automate_dir / "automate-git.py" ), + f"--download-dir={download_dir}", + f"--checkout={cef_checkout}", + f"--branch={cef_branch}", + "--minimal-distrib", + "--client-distrib", + "--force-clean", + "--no-chromium-history", + "--build-target=cefsimple", + "--x64-build", + "--with-pgo-profiles" + ], + cwd = automate_dir + ) + return result.returncode == 0 + + +def find_binary_distrib_dir(): + binary_distrib = download_dir / "chromium" / "src" / "cef" / "binary_distrib" + matches = sorted( binary_distrib.glob( "cef_binary_*_linux64" ) ) + if not matches: + nc.abort_op( f"No cef_binary_*_linux64 found in {binary_distrib}" ) + return matches[0] + +def build_and_install(): + nc.create_install_dir() + + setup_build_env() + + # Main build loop: if automate-git.py fails, run gclient recovery and + # retry. After max_recovery_tries failed recoveries, wipe the chromium + # checkout entirely and start over. + recovery_count = 0 + while True: + if run_automate_git(): + print( "Build completed successfully!" ) + break + run_gclient_recovery() + recovery_count += 1 + if recovery_count > max_recovery_tries: + print( "!!! Too many failed recoveries. Wiping chromium checkout..." ) + shutil.rmtree( download_dir / "chromium", ignore_errors = True ) + recovery_count = 0 + + cef_binary_dir = find_binary_distrib_dir() + + # Copy the binary distribution into the install dir + target_dir = nc.install_dir / f"cef" + try: + if target_dir.exists(): + shutil.rmtree( target_dir ) + shutil.copytree( cef_binary_dir, target_dir, copy_function = shutil.copy2 ) + except Exception as e: + nc.abort_op( f"Copy of binary distrib failed: {e}" ) + + nc.create_install_dir_ok_marker() + nc.fix_terminal_encoding() + print( "Build and install completed" ) + + +def build_all(): + if not nc.work_dir_looks_ok(): + fetch_and_patch() + if not nc.install_dir_looks_ok(): + build_and_install() + + +nc.ensure_dep( build_all ) \ No newline at end of file diff --git a/Common/3dParty/icu-desktop/.gitignore b/Common/3dParty/icu-desktop/.gitignore new file mode 100644 index 0000000000..2e89fda59e --- /dev/null +++ b/Common/3dParty/icu-desktop/.gitignore @@ -0,0 +1,6 @@ +* +# Except this file +!.gitignore +!fetch_mobile.sh +!icu.pri +!icu_ios.sh \ No newline at end of file diff --git a/Common/3dParty/icu-desktop/fetch_mobile.sh b/Common/3dParty/icu-desktop/fetch_mobile.sh new file mode 100755 index 0000000000..d931f6979c --- /dev/null +++ b/Common/3dParty/icu-desktop/fetch_mobile.sh @@ -0,0 +1,48 @@ +#!/bin/bash +SCRIPTPATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" + +ICU_MAJOR_VER=62 +ICU_MINOR_VER=1 + +SHARED_LIB_VER=$ICU_MAJOR_VER.$ICU_MINOR_VER + +os=$(uname -s) +platform="" + +case "$os" in + Linux*) + platform="linux" + BUILD_PLATFORM=Linux + SHARED_LIB_EXT=.so.$SHARED_LIB_VER + SHARED_LIB_SHORT_EXT=.so.$ICU_MAJOR_VER + ;; + Darwin*) + platform="mac" + BUILD_PLATFORM=MacOSX + SHARED_LIB_EXT=.$SHARED_LIB_VER.dylib + SHARED_LIB_SHORT_EXT=.$ICU_MAJOR_VER.dylib + ;; + *) exit ;; +esac + + +architecture=$(uname -m) +arch="" + +case "$architecture" in + x86_64*) arch="_64" ;; + *) arch="_32" ;; +esac + +rm -rf "$SCRIPTPATH/$platform$arch" + +if [[ -d "$SCRIPTPATH/$platform$arch" ]] +then +echo +else +mkdir "$SCRIPTPATH/$platform$arch" +fi + +cd "$SCRIPTPATH/$platform$arch" + +svn export https://github.com/unicode-org/icu/tags/release-$ICU_MAJOR_VER-$ICU_MINOR_VER/icu4c ./icu diff --git a/Common/3dParty/icu-desktop/icu.pri b/Common/3dParty/icu-desktop/icu.pri new file mode 100644 index 0000000000..187c8ce044 --- /dev/null +++ b/Common/3dParty/icu-desktop/icu.pri @@ -0,0 +1,64 @@ +ICU_MAJOR_VER = 74 + +core_windows { + exists($$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/icu) { + INCLUDEPATH += $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/icu/include + } else { + build_xp { + INCLUDEPATH += $$PWD/icu58/include + } else { + INCLUDEPATH += $$PWD/icu/include + } + } + + ICU_LIBS_PATH_WIN = $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build + build_xp { + ICU_LIBS_PATH_WIN = $$ICU_LIBS_PATH_WIN/xp + } + LIBS += -L$$ICU_LIBS_PATH_WIN -licuuc +} + +core_linux { + INCLUDEPATH += $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build/include + + LIBS += $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build/libicuuc.so.$$ICU_MAJOR_VER + LIBS += $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build/libicudata.so.$$ICU_MAJOR_VER +} + +core_mac { + INCLUDEPATH += $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build/include + + ICU_LIBS_PATH_MAC = $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build + bundle_dylibs { + LIBS += $$ICU_LIBS_PATH_MAC/libicudata.a + LIBS += $$ICU_LIBS_PATH_MAC/libicui18n.a + LIBS += $$ICU_LIBS_PATH_MAC/libicuuc.a + } else { + LIBS += $$ICU_LIBS_PATH_MAC/libicuuc.$${ICU_MAJOR_VER}.dylib + LIBS += $$ICU_LIBS_PATH_MAC/libicudata.$${ICU_MAJOR_VER}.dylib + } +} + +core_ios { + INCLUDEPATH += $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build/include + + ICU_LIBS_PATH_IOS = $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build + bundle_xcframeworks { + xcframework_platform_ios_simulator { + ICU_LIBS_PATH_IOS = $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build_xc/simulator + } else { + ICU_LIBS_PATH_IOS = $$PWD/$$CORE_BUILDS_PLATFORM_PREFIX/build_xc + } + } + + LIBS += $$ICU_LIBS_PATH_IOS/libicudata.a + LIBS += $$ICU_LIBS_PATH_IOS/libicui18n.a + LIBS += $$ICU_LIBS_PATH_IOS/libicuuc.a +} + +core_android { + INCLUDEPATH += $$PWD/android/build/include + + LIBS += $$PWD/android/build/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libicuuc.a + LIBS += $$PWD/android/build/$$CORE_BUILDS_PLATFORM_PREFIX_DST/libicudata.a +} diff --git a/Common/3dParty/icu-desktop/icu_ios.sh b/Common/3dParty/icu-desktop/icu_ios.sh new file mode 100755 index 0000000000..9f3df4ea83 --- /dev/null +++ b/Common/3dParty/icu-desktop/icu_ios.sh @@ -0,0 +1,295 @@ +#!/bin/bash + +ICU_DIR="$PWD/icu" + +ICU_SOURCE="${ICU_DIR}/source" + +PREBUILD="$PWD/ios/icu_build" + +CONFIG_PREFIX=" --enable-extras=yes \ +--enable-tools=yes \ +--enable-icuio=yes \ +--enable-strict=no \ +--enable-static \ +--enable-shared=no \ +--enable-tests=yes \ +--disable-renaming \ +--enable-samples=no \ +--enable-dyload=no \ +--with-data-packaging=static" + +CFLAGS="-O3 -D__STDC_INT64__ -fno-exceptions -fno-short-wchar -fno-short-enums" + +CXXFLAGS="${CFLAGS} -std=c++11" + +#will set value to 1 +defines_config_set_1=( + "UCONFIG_NO_BREAK_ITERATION" + "UCONFIG_NO_FORMATTING" + "UCONFIG_NO_REGULAR_EXPRESSIONS" + "CONFIG_NO_CONVERSION" + "U_DISABLE_RENAMING" +) + +#will set value to 0 +defines_config_set_0=( + "U_HAVE_NL_LANGINFO_CODESET" + "UCONFIG_NO_TRANSLITERATION" + "U_USING_ICU_NAMESPACE" +) + +#will set value to 1 +defines_utypes=( + "U_CHARSET_IS_UTF8" +) + +function prebuild() { + + echo "===== REMOVING data from bundle =====" + + #Data bundle reduction + { + echo "GENRB_CLDR_VERSION = 32.0.1" + echo "GENRB_SYNTHETIC_ALIAS = " + echo "GENRB_ALIAS_SOURCE = \$(GENRB_SYNTHETIC_ALIAS) " + echo "GENRB_SOURCE = " + } >"${ICU_SOURCE}/data/locales/reslocal.mk" + + { + echo "LANG_CLDR_VERSION = 32.0.1" + echo "LANG_SYNTHETIC_ALIAS = " + echo "LANG_ALIAS_SOURCE = \$(LANG_SYNTHETIC_ALIAS) " + echo "LANG_SOURCE = " + } >"${ICU_SOURCE}/data/lang/reslocal.mk" + + { + echo "CURR_CLDR_VERSION = 32.0.1" + echo "CURR_SYNTHETIC_ALIAS = " + echo "CURR_ALIAS_SOURCE = \$(CURR_SYNTHETIC_ALIAS) " + echo "CURR_SOURCE = " + } >"${ICU_SOURCE}/data/curr/reslocal.mk" + + { + echo "REGION_CLDR_VERSION = 32.0.1" + echo "REGION_SYNTHETIC_ALIAS = " + echo "REGION_ALIAS_SOURCE = \$(REGION_SYNTHETIC_ALIAS) " + echo "REGION_SOURCE = " + } >"${ICU_SOURCE}/data/region/reslocal.mk" + + { + echo "UNIT_CLDR_VERSION = 32.0.1" + echo "UNIT_SYNTHETIC_ALIAS = " + echo "UNIT_ALIAS_SOURCE = \$(UNIT_SYNTHETIC_ALIAS) " + echo "UNIT_SOURCE = " + } >"${ICU_SOURCE}/data/unit/reslocal.mk" + + { + echo "ZONE_CLDR_VERSION = 32.0.1" + echo "ZONE_SYNTHETIC_ALIAS = " + echo "ZONE_ALIAS_SOURCE = \$(ZONE_SYNTHETIC_ALIAS) " + echo "ZONE_SOURCE = " + } >"${ICU_SOURCE}/data/zone/reslocal.mk" + + #find "${ICU_SOURCES}/data/mappings/" -name '*.mk' ! -name 'ucmcore.mk' -type f -exec rm -f {} + + + mv "${ICU_SOURCE}/data/mappings/ucmcore.mk" "${ICU_SOURCE}/data/mappings/ucmcore.not_used" 2>/dev/null + mv "${ICU_SOURCE}/data/mappings/ucmfiles.mk" "${ICU_SOURCE}/data/mappings/ucmfiles.not_used" 2>/dev/null + mv "${ICU_SOURCE}/data/mappings/ucmebcdic.mk" "${ICU_SOURCE}/data/mappings/ucmebcdic.not_used" 2>/dev/null + mv "${ICU_SOURCE}/data/mappings/ucmlocal.mk" "${ICU_SOURCE}/data/mappings/ucmlocal.not_used" 2>/dev/null + + echo "===== Modify icu/source/common/unicode/uconfig.h =====" + + cp "${ICU_SOURCE}/common/unicode/uconfig" "${ICU_SOURCE}/common/unicode/uconfig.h" 2>/dev/null + cp "${ICU_SOURCE}/common/unicode/uconfig.h" "${ICU_SOURCE}/common/unicode/uconfig" 2>/dev/null + + for var in "${defines_config_set_1[@]}"; do + sed "/define __UCONFIG_H__/a \\ +#ifndef ${var} \\ +#define ${var} 1 \\ +#endif \\ +" "${ICU_SOURCE}/common/unicode/uconfig.h" >"${ICU_SOURCE}/common/unicode/uconfig.tmp" + + mv "${ICU_SOURCE}/common/unicode/uconfig.tmp" "${ICU_SOURCE}/common/unicode/uconfig.h" + done + + for var in "${defines_config_set_0[@]}"; do + sed "/define __UCONFIG_H__/a \\ +#ifndef ${var} \\ +#define ${var} 0 \\ +#endif \\ +" "${ICU_SOURCE}/common/unicode/uconfig.h" >"${ICU_SOURCE}/common/unicode/uconfig.tmp" + + mv "${ICU_SOURCE}/common/unicode/uconfig.tmp" "${ICU_SOURCE}/common/unicode/uconfig.h" + done + + echo "===== Modify icu/source/common/unicode/utypes.h =====" + + cp "${ICU_SOURCE}/common/unicode/utypes" "${ICU_SOURCE}/common/unicode/utypes.h" 2>/dev/null + cp "${ICU_SOURCE}/common/unicode/utypes.h" "${ICU_SOURCE}/common/unicode/utypes" 2>/dev/null + + for var in "${defines_utypes[@]}"; do + sed "/define UTYPES_H/a \\ +#ifndef ${var} \\ +#define ${var} 1 \\ +#endif \\ +" "${ICU_SOURCE}/common/unicode/utypes.h" >"${ICU_SOURCE}/common/unicode/utypes.tmp" + + mv "${ICU_SOURCE}/common/unicode/utypes.tmp" "${ICU_SOURCE}/common/unicode/utypes.h" + + done + + echo "===== Patching icu/source/tools/pkgdata/pkgdata.cpp for iOS =====" + + cp "${ICU_SOURCE}/tools/pkgdata/pkgdata" "${ICU_SOURCE}/tools/pkgdata/pkgdata.cpp" 2>/dev/null + cp "${ICU_SOURCE}/tools/pkgdata/pkgdata.cpp" "${ICU_SOURCE}/tools/pkgdata/pkgdata" 2>/dev/null + + sed "s/int result = system(cmd);/ \\ +#if defined(IOS_SYSTEM_FIX) \\ +pid_t pid; \\ +char * argv[2]; argv[0] = cmd; argv[1] = NULL; \\ +posix_spawn(\&pid, argv[0], NULL, NULL, argv, environ); \\ +waitpid(pid, NULL, 0); \\ +int result = 0; \\ +#else \\ +int result = system(cmd); \\ +#endif \\ +/g" "${ICU_SOURCE}/tools/pkgdata/pkgdata.cpp" >"${ICU_SOURCE}/tools/pkgdata/pkgdata.tmp" + + sed "/#include /a \\ +#if defined(IOS_SYSTEM_FIX) \\ +#include \\ +extern char **environ; \\ +#endif \\ +" "${ICU_SOURCE}/tools/pkgdata/pkgdata.tmp" >"${ICU_SOURCE}/tools/pkgdata/pkgdata.cpp" + + #mv "${ICU_SOURCE}/tools/pkgdata/pkgdata.tmp" "${ICU_SOURCE}/tools/pkgdata/pkgdata.cpp" + + echo "===============================" + echo "===== Run build for MacOS =====" + echo "===============================" + + export PLATFORM_PREFIX="${PWD}/mac-build" + + export CPPFLAGS=${CFLAGS} + + mkdir -p ${PREBUILD} + + cd ${PREBUILD} + + sh ${ICU_SOURCE}/runConfigureICU MacOSX --prefix=${PLATFORM_PREFIX} ${CONFIG_PREFIX} + + make clean + make -j4 + make install + + cd .. +} + +function build() { + + unset CXX + unset CC + unset CFLAGS + unset CXXFLAGS + unset LDFLAGS + + echo "preparing $1 toolchain" + + export BUILD_DIR="${PWD}/build-${5}" + + SDKROOT="$(xcodebuild -version -sdk $4 | grep -E '^Path' | sed 's/Path: //')" + ARCH=$2 + + ICU_FLAGS="-I$ICU_SOURCE/common/ -I$ICU_SOURCE/tools/tzcode/ " + + IOS_MIN_VER = "-miphoneos-version-min=11.0" + if [ "$4" = "iphonesimulator" ]; then + IOS_MIN_VER = "-mios-simulator-version-min=11.0" + fi; + + export ADDITION_FLAG="-DIOS_SYSTEM_FIX" + + export CXX="$(xcrun -find clang++)" + export CC="$(xcrun -find clang)" + export CFLAGS="-isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS $CFLAGS ${ADDITION_FLAG}" + export CXXFLAGS="${CXXFLAGS} -stdlib=libc++ -isysroot $SDKROOT -I$SDKROOT/usr/include/ -I./include/ -arch $ARCH $IOS_MIN_VER $ICU_FLAGS ${ADDITION_FLAG}" + export LDFLAGS="-stdlib=libc++ -L$SDKROOT/usr/lib/ -isysroot $SDKROOT -Wl,-dead_strip $IOS_MIN_VER -lstdc++ ${ADDITION_FLAG}" + + mkdir -p ${BUILD_DIR} + cd ${BUILD_DIR} + + sh ${ICU_SOURCE}/configure --host=$3 --with-library-suffix=${2} --with-cross-build=${PREBUILD} ${CONFIG_PREFIX} + + make clean + make -j4 + + cd .. +} + +prebuild + +echo "------------------------------------------------------" +echo " ICU build armv7 libraries" +echo "------------------------------------------------------" + +build "armv7" "armv7" "armv7-apple-darwin" "iphoneos" "armv7" + +echo "------------------------------------------------------" +echo " ICU build arm64 libraries" +echo "------------------------------------------------------" + +build "arm64" "arm64" "aarch64-apple-darwin" "iphoneos" "arm64" + +echo "------------------------------------------------------" +echo " ICU combining x86_64 libraries" +echo "------------------------------------------------------" + +build "x86_64" "x86_64" "x86_64-apple-darwin" "iphonesimulator" "x86_64" + +echo "------------------------------------------------------" +echo " ICU combining arm64 (simulator) libraries" +echo "------------------------------------------------------" + +build "arm64" "arm64" "aarch64-apple-darwin" "iphonesimulator" "sim-arm64" + +cd .. + +echo "------------------------------------------------------" +echo " ICU combining x86_64, armv7 and arm64 libraries" +echo "------------------------------------------------------" + +function buildUniversal() { + lipo -create -output "${PWD}/ios/build/$1.a" \ + "${PWD}/ios/build-x86_64/lib/$1x86_64.a" \ + "${PWD}/ios/build-arm64/lib/$1arm64.a" \ + "${PWD}/ios/build-armv7/lib/$1armv7.a" +} + +function buildUniversalXC() { + lipo -create -output "${PWD}/ios/build_xc/$1.a" \ + "${PWD}/ios/build-arm64/lib/$1arm64.a" + + lipo -create -output "${PWD}/ios/build_xc/simulator/${1}.a" \ + "${PWD}/ios/build-sim-arm64/lib/$1arm64.a" \ + "${PWD}/ios/build-x86_64/lib/$1x86_64.a" +} + +mkdir -p build +mkdir -p ios/build +mkdir -p ios/build_xc +mkdir -p ios/build_xc/simulator +mkdir -p ios/build/include +mkdir -p ios/build_xc/include +mkdir -p ios/build/include/unicode +mkdir -p ios/build_xc/include/unicode + +cp ${ICU_SOURCE}/common/unicode/*.h ios/build/include/unicode +cp ${ICU_SOURCE}/common/unicode/*.h ios/build_xc/include/unicode + +buildUniversal "libicuuc" +buildUniversal "libicui18n" +buildUniversal "libicudata" + +buildUniversalXC "libicuuc" +buildUniversalXC "libicui18n" +buildUniversalXC "libicudata" diff --git a/Common/3dParty/icu-desktop/nc-build-cygwin.sh b/Common/3dParty/icu-desktop/nc-build-cygwin.sh new file mode 100644 index 0000000000..09c93b0215 --- /dev/null +++ b/Common/3dParty/icu-desktop/nc-build-cygwin.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +install_dir="$1" + +# If the install dir comes from wsl, convert that to cygwin path +if [[ $install_dir == /mnt/* ]]; then + install_dir="/cygdrive/${install_dir#/mnt/}" +fi + +export PATH="$PATH:/usr/bin" +export PYTHON=/usr/bin/python3 + +abort_op() +{ + echo "ICU-CygWin aborted: $1" >&2 + exit 1 +} + +if [ ! -f "./runConfigureICU" ] +then + abort_op "This script has to be run from the icu/source directory (cannot find runConfigureICU)" +fi + +if [ ! -d "$install_dir" ] +then + mkdir -p "$install_dir" || abort_op "Failed to create install dir" +fi + +"./runConfigureICU" Cygwin/MSVC \ + --prefix="$install_dir" \ + --enable-shared \ + --disable-static || abort_op "Configuration failed" + +# Build and install +make -j$(nproc) || abort_op "Build failed" +make install || abort_op "Install failed" + +# --------------------------------------------------------------------------- +# Replace symlinks with real copies of their targets. +# +# Cygwin's `make install` creates symlinks (e.g. lib/icu/Makefile.inc) as +# WSL-style reparse points. Cygwin can read those, but native Windows +# programs cannot even open them (CreateFile fails with "Invalid argument"), +# which breaks anything that walks the install tree afterwards — like the +# CI cache upload (Windows Python tarfile -> OSError errno 22). +# Dereferencing them here makes the install tree fully portable. +# --------------------------------------------------------------------------- +while IFS= read -r -d '' link +do + target="$(readlink -f "$link")" || abort_op "Cannot resolve symlink: $link" + [ -e "$target" ] || abort_op "Symlink target missing: $link -> $target" + rm -f "$link" || abort_op "Cannot remove symlink: $link" + cp -rL "$target" "$link" || abort_op "Cannot copy symlink target: $target -> $link" +done < <(find "$install_dir" -type l -print0) + +remaining=$(find "$install_dir" -type l | wc -l) +[ "$remaining" -eq 0 ] || abort_op "Symlinks still present in install dir after dereferencing" +echo "Install tree contains no symlinks — safe for native Windows consumers." \ No newline at end of file diff --git a/Common/3dParty/icu-desktop/nc-build.bat b/Common/3dParty/icu-desktop/nc-build.bat new file mode 100644 index 0000000000..d9a03ba619 --- /dev/null +++ b/Common/3dParty/icu-desktop/nc-build.bat @@ -0,0 +1,77 @@ +@echo off +setlocal + +REM ---- defaults ---- +set "CYGWIN_BIN=%~1" +if "%CYGWIN_BIN%"=="" if defined CYGWIN_ROOT set "CYGWIN_BIN=%CYGWIN_ROOT%\bin" +if "%CYGWIN_BIN%"=="" set "CYGWIN_BIN=C:\cygwin64\bin" + +set "VCVARS=%~2" +if not "%VCVARS%"=="" goto :vcvars_done + +REM No vcvars given: locate the newest Visual Studio (any edition: +REM Community/Professional/Enterprise/BuildTools) via vswhere, which +REM ships with every VS 2017+ installation at a fixed location. +set "VSWHERE=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" +if exist "%VSWHERE%" ( + for /f "usebackq delims=" %%i in (`"%VSWHERE%" -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do set "VCVARS=%%i\VC\Auxiliary\Build\vcvarsx86_amd64.bat" +) +REM Last-resort fallback for machines without vswhere +if "%VCVARS%"=="" set "VCVARS=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsx86_amd64.bat" +:vcvars_done + +REM ---- required args ---- +set "ICU_SOURCE=%~3" +set "ICU_INSTALL=%~4" + +if "%ICU_SOURCE%"=="" goto :usage +if "%ICU_INSTALL%"=="" goto :usage + +REM ---- fail early with explicit errors instead of mysterious error 3 ---- +if not exist "%CYGWIN_BIN%\bash.exe" ( + echo ERROR: Cygwin bash not found at "%CYGWIN_BIN%\bash.exe" 1>&2 + exit /b 1 +) +if not exist "%VCVARS%" ( + echo ERROR: vcvars script not found at "%VCVARS%" 1>&2 + exit /b 1 +) +echo Using Cygwin: %CYGWIN_BIN% +echo Using vcvars: %VCVARS% + +REM ---- PATH ORDER: MSVC first, Cygwin second ---- +set "PATH=%CYGWIN_BIN%;%PATH%" +call "%VCVARS%" || exit /b 1 + +echo "------------- DBG 1" + +REM ---- run build ---- +cd /D "%ICU_SOURCE%" || exit /b 1 + +echo "------------- DBG 2" + +for /f "delims=" %%i in ('cygpath "%~dp0"') do set SCRIPT_DIR=%%i + +for /f "delims=" %%i in ('cygpath "%ICU_INSTALL%"') do set INSTALL_DIR=%%i + +echo "Script dir : %SCRIPT_DIR%" +echo "Install dir: %INSTALL_DIR%" + +"%CYGWIN_BIN%\bash.exe" "%SCRIPT_DIR%nc-build-cygwin.sh" "%INSTALL_DIR%" + +exit /b %errorlevel% + +:usage +echo. +echo Usage: +echo %~nx0 [cygwin_bin] [vcvars_bat] ^ ^ +echo. +echo Arguments: +echo 1. cygwin_bin Optional. Default: %%CYGWIN_ROOT%%\bin, else C:\cygwin64\bin +echo 2. vcvars_bat Optional. Default: located via vswhere (latest VS, any edition) +echo 3. icu_source Required. Path of the ICU sources dir, e.g. +echo C:\Users\superdev\Repos\icu\source +echo 4. icu_install Required. Path of the ICU output/install dir, e.g. +echo C:\Users\superdev\icu_install +echo. +exit /b 2 \ No newline at end of file diff --git a/Common/3dParty/icu-desktop/nc-build.py b/Common/3dParty/icu-desktop/nc-build.py new file mode 100644 index 0000000000..affeaa269f --- /dev/null +++ b/Common/3dParty/icu-desktop/nc-build.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 + +import sys +import shutil +import os +from pathlib import Path + +script_path = Path(sys.argv[0]).resolve() +script_dir = script_path.parent +icu_major = "60" +icu_minor = "3" + +third_party_root = ( script_dir / ".." ).resolve() +if str( third_party_root ) not in sys.path: + sys.path.insert( 0, str( third_party_root ) ) +import build_3rdparty_common as nc + +nc.init_for_dep( + depname = "ICU-DESKTOP", + workdir = Path( sys.argv[1] ).resolve(), + installdir = Path( sys.argv[2] ).resolve(), + forceredo = len(sys.argv) > 3 and sys.argv[3] == "force-redo" +) + +def fetch_and_patch(): + nc.create_workdir() + + nc.run_command( + [ "git", "-c", "core.autocrlf=false", "-c", "core.eol=lf", "clone", + "--depth", "1", "--branch", f"release-{icu_major}-{icu_minor}", + "https://github.com/unicode-org/icu.git", str(nc.work_dir / "icu2") + ], + "Checkout git repo", + ) + + try: + shutil.copytree( + nc.work_dir / "icu2" / "icu4c", + nc.work_dir / "icu", + copy_function=shutil.copy2 + ) + except Exception as e: + nc.abort_op( f"Copy failed: {e}" ) + + try: + shutil.copy2( nc.work_dir / "icu" / "LICENSE", nc.work_dir / "LICENSE" ) + except Exception as e: + nc.abort_op( f"License copy failed: {e}" ) + + try: + shutil.rmtree( nc.work_dir / "icu2" ) + except FileNotFoundError: + pass + + nc.create_work_dir_ok_marker() + + print( "Fetch & patch completed" ) + +def build_and_install(): + nc.create_install_dir() + + if nc.is_linux(): + nc.run_command( + [ "./configure", + f"--prefix={nc.install_dir}", + "--enable-rpath", + "CC=gcc", + "CXX=g++", + "AR=ar", + "RANLIB=ranlib", + "CXXFLAGS=-static-libstdc++ -static-libgcc -std=c++11", + "LDFLAGS=-Wl,-rpath,$ORIGIN" + ], + "Configure", + nc.work_dir / "icu" / "source" + ) + + nc.run_command( + [ "make", f"-j{os.cpu_count()}" ], + "Build", + nc.work_dir / "icu" / "source" + ) + + nc.run_command( + [ "make", "install" ], + "Install", + nc.work_dir / "icu" / "source" + ) + + elif nc.is_windows(): + icu_source_dir = nc.work_dir / "icu" / "source" + bat_path = script_dir / "nc-build.bat" + nc.run_command( + [ "cmd.exe", + "/c", + "call", + str(bat_path), + "", "", + str(icu_source_dir), + str(nc.install_dir) + ], + "Cygwin build", + nc.work_dir / "icu" / "source" + ) + + else: + nc.abort_op( f"Unkown target platform: {sys.platform}" ) + + nc.create_install_dir_ok_marker() + nc.fix_terminal_encoding() + print( "Build and install completed" ) + +def build_all(): + if not nc.work_dir_looks_ok(): + fetch_and_patch() + + if not nc.install_dir_looks_ok(): + build_and_install() + +nc.ensure_dep( build_all ) \ No newline at end of file diff --git a/Common/3dParty/icu-desktop/nc-build.sh b/Common/3dParty/icu-desktop/nc-build.sh new file mode 100755 index 0000000000..4b94edb305 --- /dev/null +++ b/Common/3dParty/icu-desktop/nc-build.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +work_dir="$1" +install_dir="$2" +icu_major=$3 +icu_minor=$4 +fetch_only=${5:-0} + +abort_op() +{ + rm -rf "$work_dir" + rm -rf "$install_dir" + echo "ICU aborted: $1" >&2 + exit 1 +} + +if [ $# -lt 4 ] +then + echo "Needs 4 arguments: work_dir_path install_dir_path major_ver minor_ver" >&2 + exit 1 +fi + +if [ -d $install_dir ] +then + echo "Skipping ICU (done already)." + exit 0 +else + mkdir -p "$install_dir" || abort_op "Failed to create install dir: [$install_dir]" +fi + +if [ -d "$work_dir" ] +then + rm -rf $work_dir +fi +mkdir -p "$work_dir" || abort_op "Failed to create work dir: [$work_dir]" + +echo "Fetching ICU into: [$work_dir]" +git clone --depth 1 --branch release-$icu_major-$icu_minor https://github.com/unicode-org/icu.git "$work_dir/icu2" \ + || abort_op "Git clone failed!" + +cd "$work_dir" +cp -r icu2/icu4c ./icu +cp icu2/LICENSE ./ +rm -rf icu2 + +echo "Building icu" +mkdir build_linux_x64 || abort_op "Failed to create build dir" +cd build_linux_x64 +$work_dir/icu/source/configure \ +--prefix="$install_dir" \ +--enable-rpath \ +CC=gcc \ +CXX=g++ \ +AR=ar \ +RANLIB=ranlib \ +CXXFLAGS="-static-libstdc++ -static-libgcc" \ +LDFLAGS='-Wl,-rpath,$$ORIGIN' \ +|| abort_op "Configure failed" + +if [ "$fetch_only" -eq 0 ]; then + make -j10 && make install || abort_op "Build failed" + + echo "ICU ready! (work dir will be removed)" + rm -rf "$work_dir" +fi + +exit 0 diff --git a/Common/3dParty/icu/nc-build.py b/Common/3dParty/icu/nc-build.py index 8431d830cf..78a00e6327 100644 --- a/Common/3dParty/icu/nc-build.py +++ b/Common/3dParty/icu/nc-build.py @@ -104,7 +104,7 @@ def build_and_install(): ) else: - abort_op( f"Unkown target platform: {sys.platform}" ) + nc.abort_op( f"Unkown target platform: {sys.platform}" ) nc.create_install_dir_ok_marker() nc.fix_terminal_encoding() diff --git a/Common/3dParty/openssl/nc-build.py b/Common/3dParty/openssl/nc-build.py index 6191508309..cec22230d8 100644 --- a/Common/3dParty/openssl/nc-build.py +++ b/Common/3dParty/openssl/nc-build.py @@ -94,7 +94,7 @@ def build_and_install(): ) else: - abort_op( f"Unkown target platform: {sys.platform}" ) + nc.abort_op( f"Unkown target platform: {sys.platform}" ) nc.create_install_dir_ok_marker() diff --git a/Common/3dParty/qt/nc-build.py b/Common/3dParty/qt/nc-build.py new file mode 100644 index 0000000000..dba14c1246 --- /dev/null +++ b/Common/3dParty/qt/nc-build.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 +import sys +import shutil +import os +from pathlib import Path + +script_path = Path(sys.argv[0]).resolve() +script_dir = script_path.parent + +qt_major = "5.9" +qt_version = "5.9.9" +qt_src_name = f"qt-everywhere-opensource-src-{qt_version}" +qt_url = f"https://download.qt.io/archive/qt/{qt_major}/{qt_version}/single/{qt_src_name}.tar.xz" + +third_party_root = ( script_dir / ".." ).resolve() +if str( third_party_root ) not in sys.path: + sys.path.insert( 0, str( third_party_root ) ) + +import build_3rdparty_common as nc + +nc.init_for_dep( + depname = "Qt", + workdir = Path( sys.argv[1] ).resolve(), + installdir = Path( sys.argv[2] ).resolve(), + forceredo = len(sys.argv) > 3 and sys.argv[3] == "force-redo" +) + + +def fetch_and_patch(): + nc.create_workdir() + + tarball = nc.work_dir / f"qt_source_{qt_version}.tar.xz" + + nc.run_command( + [ "wget", qt_url, "-O", str( tarball ) ], + "Download Qt source", + nc.work_dir + ) + + nc.run_command( + [ "tar", "-xf", str( tarball ) ], + "Extract Qt source", + nc.work_dir + ) + + try: + tarball.unlink() + except FileNotFoundError: + pass + + nc.create_work_dir_ok_marker() + print( "Fetch & patch completed" ) + + +def build_and_install(): + nc.create_install_dir() + + qt_source_dir = nc.work_dir / qt_src_name + + if nc.is_linux(): + # Keep the same install layout as the previous docker build + # (prefix was ../qt_build/Qt-5.9.9/gcc_64) + qt_prefix = nc.install_dir / f"qt" + + nc.run_command( + [ "./configure", + "-opensource", + "-confirm-license", + "-release", + "-shared", + "-accessibility", + "-prefix", str( qt_prefix ), + "-qt-zlib", + "-qt-libpng", + "-qt-libjpeg", + "-qt-xcb", + "-qt-pcre", + "-no-sql-sqlite", + "-no-qml-debug", + "-gstreamer", "1.0", + "-nomake", "examples", + "-nomake", "tests", + "-skip", "qtenginio", + "-skip", "qtlocation", + "-skip", "qtserialport", + "-skip", "qtsensors", + "-skip", "qtxmlpatterns", + "-skip", "qt3d", + "-skip", "qtwebview", + "-skip", "qtwebengine", + # flags to match target build after comparison to onlyoffice build + "-dbus-linked", + "-icu", + "-no-iconv", + "-fontconfig", + "-system-freetype", + "-system-harfbuzz", + "-alsa", + "-pulseaudio", + # "-openssl-linked", + "-cups", + "-gtk" + ], + "Configure", + qt_source_dir + ) + + nc.run_command( + [ "make", f"-j{os.cpu_count()}" ], + "Build", + qt_source_dir + ) + + nc.run_command( + [ "make", "install" ], + "Install", + qt_source_dir + ) + + elif nc.is_windows(): + nc.abort_op( "Windows build is not implemented yet" ) + + else: + nc.abort_op( f"Unkown target platform: {sys.platform}" ) + + nc.create_install_dir_ok_marker() + nc.fix_terminal_encoding() + print( "Build and install completed" ) + + +def build_all(): + if not nc.work_dir_looks_ok(): + fetch_and_patch() + if not nc.install_dir_looks_ok(): + build_and_install() + + +nc.ensure_dep( build_all ) \ No newline at end of file diff --git a/OfficeUtils/CMakeLists.txt b/OfficeUtils/CMakeLists.txt index 506a2be3c2..9b07c92a25 100644 --- a/OfficeUtils/CMakeLists.txt +++ b/OfficeUtils/CMakeLists.txt @@ -21,8 +21,8 @@ function(add_officeutils TARGET OFFICE_UTILS_DIR) ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/compress.c ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/ioapi.c ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/ioapibuf.c - ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/miniunz.c - ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/minizip.c + #${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/miniunz.c + #${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/minizip.c ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/mztools.c ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/unzip.c ${OFFICE_UTILS_SOURCES_DIR}/zlib-1.2.11/contrib/minizip/zip.c diff --git a/common.cmake b/common.cmake index 56e47a0b79..422add4ae1 100644 --- a/common.cmake +++ b/common.cmake @@ -95,12 +95,16 @@ if( EMSCRIPTEN ) else() if(NOT THIRD_PARTY_PREPARED) + if(NOT BUILD_DESKTOP) + set(NO_DESKTOP_EXCLUDE ",icu-desktop") + endif() + cmake_path( APPEND BUILDER_PATH "${CMAKE_CURRENT_LIST_DIR}" "Common" "3dParty" "build_3rdparty.py" ) execute_process( COMMAND_ECHO STDOUT COMMAND "${PYTHON_BIN}" "${BUILDER_PATH}" - "--except=openssl-hash,icu-wasm" + "--except=openssl-hash,icu-wasm,cef,qt${NO_DESKTOP_EXCLUDE}" # cef and qt need old build environment, cannot be built here "${EO_CORE_3RD_PARTY_WORK_DIR}" "${EO_CORE_3RD_PARTY_INSTALL_DIR}" RESULT_VARIABLE result OUTPUT_VARIABLE output @@ -124,6 +128,37 @@ else() endforeach() endif() + if(BUILD_DESKTOP) + # Setup icu desktop + # These version numbers don't affect what build_3rdparty.py builds. They just have to match. + set(ICU_DESKTOP_MAJOR_VER "60") + set(ICU_DESKTOP_MINOR_VER "3") + set(ICU_DESKTOP_INSTALL_DIR "${EO_CORE_3RD_PARTY_INSTALL_DIR}/icu-desktop") + get_filename_component(ICU_DESKTOP_INSTALL_DIR_ABS "${ICU_DESKTOP_INSTALL_DIR}" ABSOLUTE) + if( MSVC ) + set(LIBICUUC_DESKTOP "${ICU_DESKTOP_INSTALL_DIR_ABS}/lib/icuuc.lib") + set(LIBICUDATA_DESKTOP "${ICU_DESKTOP_INSTALL_DIR_ABS}/lib/icudt.lib") + else() + set(LIBICUUC_DESKTOP "${ICU_DESKTOP_INSTALL_DIR_ABS}/lib/libicuuc.so.${ICU_DESKTOP_MAJOR_VER}") + set(LIBICUDATA_DESKTOP "${ICU_DESKTOP_INSTALL_DIR_ABS}/lib/libicudata.so.${ICU_DESKTOP_MAJOR_VER}") + set(LIBICUI_DESKTOP "${ICU_DESKTOP_INSTALL_DIR_ABS}/lib/libicui18n.so.${ICU_DESKTOP_MAJOR_VER}") + endif() + + # Setup qt + set(QT_ROOT "${EO_CORE_3RD_PARTY_INSTALL_DIR}/qt/qt") + set(QT_DIR "${QT_ROOT}/lib/cmake/Qt5") + set(Qt5_DIR "${QT_ROOT}/lib/cmake/Qt5") + set(QT_VERSION_MAJOR "5") + find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Widgets PrintSupport Svg LinguistTools Multimedia MultimediaWidgets) + + # Setup cef + set(CEF_ROOT "${EO_CORE_3RD_PARTY_INSTALL_DIR}/cef") + list(APPEND CMAKE_MODULE_PATH "${CEF_ROOT}/cmake") + find_package(CEF REQUIRED) + + endif() + + # Setup icu # These version numbers don't affect what build_3rdparty.py builds. They just have to match. set(ICU_MAJOR_VER "74")