diff --git a/CMakePresets.json b/CMakePresets.json index dd55c75..b83f485 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -41,7 +41,8 @@ "cacheVariables": { "CMAKE_BUILD_TYPE": "RelWithDebInfo", "VRDASH_DEPLOY_QT": "ON", - "VRDASH_BUILD_TESTS": "OFF" + "VRDASH_BUILD_TESTS": "OFF", + "VRDASH_WEBENGINE_PROCESS": "/opt/qt6-arm64/usr/lib/qt6/libexec/QtWebEngineProcess" } }, { diff --git a/cmake/BundleQt.cmake b/cmake/BundleQt.cmake index f26d070..5abb177 100644 --- a/cmake/BundleQt.cmake +++ b/cmake/BundleQt.cmake @@ -30,6 +30,14 @@ set(VRDASH_BUNDLE_PLUGINS wayland-shell-integration/*.so wayland-graphics-integration-client/*.so wayland-decoration-client/*.so xcbglintegrations/*.so) +# Qt WebEngine (bundled only if a dashboard needs it): its helper process, resources and +# locales. Cross builds point VRDASH_WEBENGINE_PROCESS at the target's QtWebEngineProcess +# (Debian can't install the arm64 one next to the host's; see docker/cross-arm64.Dockerfile). +set(VRDASH_WEBENGINE_PROCESS "" CACHE FILEPATH + "QtWebEngineProcess to bundle (default: the one of the Qt used for the build)") +# Locales shipped with WebEngine (the full set is about 35 MB). +set(VRDASH_WEBENGINE_LOCALES en-US de) + function(vrdash_bundle_qt) get_property(targets GLOBAL PROPERTY VRDASH_DASHBOARD_TARGETS) get_property(qml_dirs GLOBAL PROPERTY VRDASH_DASHBOARD_QML_DIRS) @@ -52,6 +60,14 @@ function(vrdash_bundle_qt) set(qt_libdir ${qt_prefix}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) # Debian multiarch endif() + # Used by the install script only if a bundled library is Qt WebEngine. + set(webengine_process ${VRDASH_WEBENGINE_PROCESS}) + if(NOT webengine_process) + set(webengine_process ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBEXECS}/QtWebEngineProcess) + endif() + set(webengine_resources ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_DATA}/resources) + set(webengine_locales ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_TRANSLATIONS}/qtwebengine_locales) + # The regexes end up inside a quoted string in the generated script: escape backslashes. string(REPLACE "\\" "\\\\" bundle_exclude "${VRDASH_BUNDLE_EXCLUDE}") diff --git a/cmake/bundle-install.cmake.in b/cmake/bundle-install.cmake.in index 839033a..3a6ef2f 100644 --- a/cmake/bundle-install.cmake.in +++ b/cmake/bundle-install.cmake.in @@ -14,6 +14,9 @@ set(qt_plugins "@QT6_INSTALL_PREFIX@/@QT6_INSTALL_PLUGINS@") set(qt_qml "@QT6_INSTALL_PREFIX@/@QT6_INSTALL_QML@") set(patchelf "@VRDASH_PATCHELF@") set(exclude "@bundle_exclude@") +set(webengine_process "@webengine_process@") +set(webengine_resources "@webengine_resources@") +set(webengine_locales "@webengine_locales@") message(STATUS "Bundling Qt into ${prefix}") @@ -78,6 +81,33 @@ file(GET_RUNTIME_DEPENDENCIES RESOLVED_DEPENDENCIES_VAR resolved UNRESOLVED_DEPENDENCIES_VAR unresolved) +# --- Qt WebEngine: helper process (and its libraries), resources, locales ---------------- +# Only if a dashboard uses it. Found through qt.conf (LibraryExecutables, Data, +# Translations; written below). +set(helper_executables "") +if(resolved MATCHES "libQt6WebEngineCore") + message(STATUS "Bundling Qt WebEngine (${webengine_process})") + file(INSTALL "${webengine_process}" DESTINATION "${prefix}/libexec" FOLLOW_SYMLINK_CHAIN) + list(APPEND helper_executables "${prefix}/libexec/QtWebEngineProcess") + file(GET_RUNTIME_DEPENDENCIES + EXECUTABLES ${helper_executables} + DIRECTORIES "@qt_libdir@" "${libdir}" + PRE_EXCLUDE_REGEXES ${exclude} + POST_EXCLUDE_REGEXES "^${libdir}/" + RESOLVED_DEPENDENCIES_VAR helper_resolved + UNRESOLVED_DEPENDENCIES_VAR helper_unresolved) + list(APPEND resolved ${helper_resolved}) + list(APPEND unresolved ${helper_unresolved}) + list(REMOVE_DUPLICATES resolved) + list(REMOVE_DUPLICATES unresolved) + file(GLOB files LIST_DIRECTORIES false "${webengine_resources}/*") + file(INSTALL ${files} DESTINATION "${prefix}/resources") + foreach(locale @VRDASH_WEBENGINE_LOCALES@) + file(INSTALL "${webengine_locales}/${locale}.pak" + DESTINATION "${prefix}/translations/qtwebengine_locales") + endforeach() +endif() + if(unresolved) message(WARNING "Unresolved (expected on target system): ${unresolved}") endif() @@ -99,7 +129,7 @@ foreach(lib IN LISTS bundled_libs) set_rpath("${lib}" "\$ORIGIN") endif() endforeach() -foreach(file IN LISTS qt_plugin_files qml_plugins) +foreach(file IN LISTS qt_plugin_files qml_plugins helper_executables) get_filename_component(dir "${file}" DIRECTORY) file(RELATIVE_PATH rel "${dir}" "${libdir}") set_rpath("${file}" "\$ORIGIN/${rel}") @@ -112,11 +142,14 @@ find_program(dpkg dpkg) if(dpkg) set(docdir "${prefix}/@CMAKE_INSTALL_DOCDIR@/third-party") set(packages "") - foreach(file IN LISTS resolved qt_plugin_files qml_plugins) + foreach(file IN LISTS resolved qt_plugin_files qml_plugins helper_executables) # Ask dpkg about the original file: map installed plugins back, resolve # symlinks and /lib -> /usr/lib (usrmerge: packages register /usr paths). string(REPLACE "${plugindir}" "${qt_plugins}" original "${file}") string(REPLACE "${qmldir}" "${qt_qml}" original "${original}") + if(file STREQUAL "${prefix}/libexec/QtWebEngineProcess") + set(original "${webengine_process}") + endif() file(REAL_PATH "${original}" original) execute_process(COMMAND "${dpkg}" -S "${original}" OUTPUT_VARIABLE owner ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) @@ -158,6 +191,9 @@ Prefix = .. Libraries = @CMAKE_INSTALL_LIBDIR@ Plugins = plugins QmlImports = qml +LibraryExecutables = libexec +Data = . +Translations = translations ") list(LENGTH resolved n_libs) diff --git a/docker/cross-arm64.Dockerfile b/docker/cross-arm64.Dockerfile index 2a92254..51088e3 100644 --- a/docker/cross-arm64.Dockerfile +++ b/docker/cross-arm64.Dockerfile @@ -19,3 +19,11 @@ RUN dpkg --add-architecture arm64 \ qt6-qpa-plugins:arm64 qt6-wayland:arm64 \ qt6-webengine-dev:arm64 qml6-module-qtwebengine:arm64 \ && rm -rf /var/lib/apt/lists/* + +# Qt WebEngine's helper process for arm64 (bundled builds): its package is Multi-Arch: foreign +# and can't be installed next to the amd64 one, so unpack it into its own directory. +RUN apt-get update \ + && cd /tmp && apt-get download libqt6webenginecore6-bin:arm64 \ + && dpkg-deb -x libqt6webenginecore6-bin_*_arm64.deb /opt/qt6-arm64 \ + && rm -f libqt6webenginecore6-bin_*_arm64.deb && rm -rf /var/lib/apt/lists/* \ + && test -x /opt/qt6-arm64/usr/lib/qt6/libexec/QtWebEngineProcess