From fabfba2c18863fb0429406ebbc486a2a0eb86acc Mon Sep 17 00:00:00 2001 From: Janek Bevendorff Date: Sun, 28 Jun 2026 15:25:15 +0200 Subject: [PATCH] Add -DWITH_BUILD_QT CMake option and --build-qt release-tool flags to build Qt6 via vcpkg instead of using binaries from the system Also advance vcpkg baseline to pull in Qt 6.11 and to fix compilation with macOS SDK 26. --- CMakeLists.txt | 57 +++++++++++++++++++++++-------- cmake/KPXCMacDeployHelpers.cmake | 2 +- release-tool.py | 3 ++ share/translations/CMakeLists.txt | 3 +- src/CMakeLists.txt | 4 +-- vcpkg.json | 25 ++++++++++++-- 6 files changed, 73 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84de141764..a613f8fc5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,9 +16,6 @@ cmake_minimum_required(VERSION 3.16.0) -project(KeePassXC) -set(APP_ID "org.keepassxc.${PROJECT_NAME}") - # Version Number set(KEEPASSXC_VERSION_MAJOR "2") set(KEEPASSXC_VERSION_MINOR "8") @@ -49,6 +46,7 @@ option(WITH_COVERAGE "Use to build with coverage tests (GCC only)." OFF) option(WITH_APP_BUNDLE "Enable Application Bundle for macOS" ON) option(WITH_CCACHE "Use ccache for build" OFF) option(WITH_X11 "Enable building with X11 dependencies" ON) +option(WITH_BUILD_QT "Build Qt6 as a dependency" OFF) # Advanced Features Control option(KPXC_MINIMAL "Build KeePassXC with the minimal feature set required for basic usage" OFF) @@ -89,6 +87,16 @@ add_feature_info("Networking" KPXC_FEATURE_NETWORK "Code that can reach out to e add_feature_info("Update Checks" KPXC_FEATURE_UPDATES "Periodic update checks can be performed") add_feature_info("Documentation" KPXC_FEATURE_DOCS "Offline documentation") +# VCPKG features (must come before project()) +if(WITH_BUILD_QT) + list(APPEND VCPKG_MANIFEST_FEATURES qt) + unset(ENV{Qt6_DIR}) +endif() + +# Initialize project +project(KeePassXC) +set(APP_ID "org.keepassxc.${PROJECT_NAME}") + # Retrieve git HEAD revision hash set(GIT_HEAD_OVERRIDE "" CACHE STRING "Manually set the Git HEAD hash when missing (eg, when no .git folder exists)") execute_process(COMMAND git rev-parse --short=7 HEAD @@ -456,22 +464,41 @@ if(NOT CMAKE_BUILD_TYPE_LOWER STREQUAL "debug") add_definitions(-DQT_NO_DEBUG_OUTPUT) endif() -get_filename_component(Qt6_PREFIX ${Qt6_DIR}/../../.. REALPATH) - if(APPLE) + set(_deployqt_exe_name macdeployqt) set(CMAKE_MACOSX_RPATH TRUE) - find_program(MACDEPLOYQT_EXE macdeployqt HINTS ${Qt6_PREFIX}/bin ${Qt6_PREFIX}/tools/qt/bin ENV PATH) - if(NOT MACDEPLOYQT_EXE) - message(FATAL_ERROR "macdeployqt is required to build on macOS") - endif() - message(STATUS "Using macdeployqt: ${MACDEPLOYQT_EXE}") - set(MACDEPLOYQT_EXTRA_BINARIES "") + list(APPEND CMAKE_INSTALL_RPATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib") elseif(WIN32) - find_program(WINDEPLOYQT_EXE windeployqt HINTS ${Qt6_PREFIX}/bin ${Qt6_PREFIX}/tools/qt/bin ENV PATH) - if(NOT WINDEPLOYQT_EXE) - message(FATAL_ERROR "windeployqt is required to build on Windows") + set(_deployqt_exe_name windeployqt) +endif() + +if(WITH_BUILD_QT) + get_filename_component(Qt6_PREFIX "${Qt6_DIR}/../.." REALPATH) + set(_host_triplet "${CMAKE_HOST_SYSTEM_PROCESSOR}-${CMAKE_HOST_SYSTEM_NAME}") + string(TOLOWER "${_host_triplet}" _host_triplet) + string(REPLACE "darwin" "osx" _host_triplet "${_host_triplet}") + set(Qt6_TOOLS_PREFIX "${Qt6_PREFIX}/tools/Qt6") + + if(_deployqt_exe_name) + # vcpkg installs *deployqt to the host triplet install dir, which prevents it from + # finding the Qt libraries and plugins from the target triplet install dir. + # Here, we copy it to the target dir to fix that. A qt.conf exists there already. + configure_file( + "${VCPKG_INSTALLED_DIR}/${_host_triplet}/tools/Qt6/bin/${_deployqt_exe_name}" + "${Qt6_PREFIX}/tools/Qt6/bin/${_deployqt_exe_name}" + COPYONLY) + endif() +else() + get_filename_component(Qt6_PREFIX "${Qt6_DIR}/../../.." REALPATH) + set(Qt6_TOOLS_PREFIX "${Qt6_PREFIX}") +endif() + +if(_deployqt_exe_name) + find_program(DEPLOYQT_EXE "${_deployqt_exe_name}" HINTS ${Qt6_TOOLS_PREFIX}/bin ${Qt6_TOOLS_PREFIX}/tools/qt/bin ENV PATH) + if(NOT DEPLOYQT_EXE) + message(FATAL_ERROR "Failed to find ${_deployqt_exe_name}.") endif() - message(STATUS "Using windeployqt: ${WINDEPLOYQT_EXE}") + message(STATUS "Using ${_deployqt_exe_name}: ${DEPLOYQT_EXE}") endif() # Find Botan diff --git a/cmake/KPXCMacDeployHelpers.cmake b/cmake/KPXCMacDeployHelpers.cmake index f86067cbcb..8d6ef8b2b9 100644 --- a/cmake/KPXCMacDeployHelpers.cmake +++ b/cmake/KPXCMacDeployHelpers.cmake @@ -36,7 +36,7 @@ function(kpxc_run_macdeployqt_at_install_time) endif() set(COMMAND_ARGS - ${MACDEPLOYQT_EXE} + ${DEPLOYQT_EXE} ${APP_BUNDLE_PATH} # Adjusts dependency rpaths of extra binaries diff --git a/release-tool.py b/release-tool.py index 57cf3b6959..752791f9a5 100755 --- a/release-tool.py +++ b/release-tool.py @@ -645,6 +645,7 @@ def setup_arg_parser(cls, parser: argparse.ArgumentParser): parser.add_argument('-y', '--yes', help='Bypass confirmation prompts.', action='store_true') parser.add_argument('--with-tests', help='Build and run tests.', action='store_true') parser.add_argument('--minimal', help='Build with minimal feature set.', action='store_true') + parser.add_argument('--build-qt', help='Build Qt6 dependency.', action='store_true') if sys.platform == 'darwin': parser.add_argument('--macos-target', default=12, metavar='MACOSX_DEPLOYMENT_TARGET', @@ -702,6 +703,8 @@ def run(self, version, src_dir, output_dir, tag_name, snapshot, cmake_generator, if not kwargs['use_system_deps'] and not kwargs.get('docker_image'): cmake_opts.append(f'-DCMAKE_TOOLCHAIN_FILE={self._get_vcpkg_toolchain_file()}') + if kwargs['build_qt']: + cmake_opts.append('-DWITH_BUILD_QT=ON') if snapshot: logger.info('Building a snapshot from HEAD.') diff --git a/share/translations/CMakeLists.txt b/share/translations/CMakeLists.txt index b4a14f4aa2..4165602620 100644 --- a/share/translations/CMakeLists.txt +++ b/share/translations/CMakeLists.txt @@ -27,7 +27,8 @@ if(WIN32) elseif(APPLE OR KEEPASSXC_DIST_APPIMAGE) file(GLOB QTBASE_TRANSLATIONS /usr/share/qt/translations/qtbase_*.qm - ${Qt6_PREFIX}/translations/qtbase_*.qm) + ${Qt6_PREFIX}/translations/qtbase_*.qm + ${Qt6_PREFIX}/translations/Qt6/qtbase_*.qm) endif() set(QM_FILES ${QM_FILES} ${QTBASE_TRANSLATIONS}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 66f08fb6a4..abb85a9457 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -475,7 +475,7 @@ install(TARGETS ${PROGNAME} if(WIN32) # Deploy used libraries into build directory for debugging add_custom_command(TARGET ${PROGNAME} POST_BUILD - COMMAND ${WINDEPLOYQT_EXE} + COMMAND ${DEPLOYQT_EXE} --dir $ $,--debug,--release> $) @@ -542,7 +542,7 @@ if(WIN32) set(_wdqt_mode --release) endif() execute_process( - COMMAND ${WINDEPLOYQT_EXE} ${PROGNAME}.exe \${_wdqt_mode} + COMMAND ${DEPLOYQT_EXE} ${PROGNAME}.exe \${_wdqt_mode} WORKING_DIRECTORY \${CMAKE_INSTALL_PREFIX} OUTPUT_QUIET RESULT_VARIABLE _wdqt_result diff --git a/vcpkg.json b/vcpkg.json index 468558cf1b..16b809adf5 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,7 +1,7 @@ { "name": "keepassxc", "version-string": "2.8.0", - "builtin-baseline": "66c0373dc7fca549e5803087b9487edfe3aca0a1", + "builtin-baseline": "1600ce2ba1b6b621bfc5a31a785c4963b817a1c7", "dependencies": [ "botan", "minizip", @@ -24,5 +24,26 @@ "name": "libxkbcommon", "platform": "linux | freebsd" } - ] + ], + "features": { + "qt": { + "description": "Build Qt6 dependency.", + "dependencies": [ + "qtbase", + { + "name": "qtbase", + "platform": "linux | freebsd", + "features": ["wayland"] + }, + "qtdeclarative", + "qtimageformats", + "qtsvg", + { + "name": "qttools", + "features": ["linguist", "qml"] + }, + "qttranslations" + ] + } + } }