Files
RedBear-OS/local/scripts/lib/qt-sysroot.sh
T
vasilito 44c054e37d qt: dual-stage plugins to <stage>/plugins (qtwayland/qtsvg/qtdeclarative)
Qt cmake plugin targets resolve each plugin .so via <sysroot>/plugins (the
_IMPORT_PREFIX is computed from the cmake files under <sysroot>/lib/cmake, i.e.
the sysroot root, not <sysroot>/usr), but cmake --install --prefix .../usr puts
plugins at usr/plugins. qtbase already works around this by staging plugins to
BOTH usr/plugins and plugins (recipe.toml ~L739); qtwayland/qtsvg/qtdeclarative
did not, so their plugins (wayland decorations, svg imageformats/iconengines,
qmltooling) were unreachable at <sysroot>/plugins and any Qt6Gui/Qt6Qml consumer
failed: imported target references "<sysroot>/plugins/.../foo.so" but this file
does not exist. This blocked kf6-kwindowsystem (sddm dep) on the Adwaita
decoration plugin. Add a shared redbear_qt_dual_stage_plugins helper and call it
after install in all three. (Note qml already resolves via the qml symlink since
qtbase does not dual-stage qml, so <sysroot>/qml is a symlink not a real dir.)
2026-07-25 00:30:27 +09:00

189 lines
6.5 KiB
Bash

#!/usr/bin/env bash
redbear_qt_link_sysroot_dir() {
local sysroot="$1"
local dir_name="$2"
if [ -d "${sysroot}/usr/${dir_name}" ] && [ ! -e "${sysroot}/${dir_name}" ]; then
ln -s "usr/${dir_name}" "${sysroot}/${dir_name}"
fi
}
redbear_qt_link_sysroot_dirs() {
local sysroot="$1"
shift
local dir_name
for dir_name in "$@"; do
redbear_qt_link_sysroot_dir "$sysroot" "$dir_name"
done
}
redbear_qt_link_plugins_dir() {
local sysroot="$1"
if [ -d "${sysroot}/usr/plugins" ] && [ ! -e "${sysroot}/plugins" ]; then
ln -s "usr/plugins" "${sysroot}/plugins"
fi
}
# Qt's generated cmake plugin targets resolve each plugin .so via
# <sysroot>/plugins (the _IMPORT_PREFIX is computed from the cmake files under
# <sysroot>/lib/cmake, i.e. the sysroot root, NOT <sysroot>/usr). But
# `cmake --install --prefix .../usr` puts plugins at usr/plugins. qtbase works
# around this by staging plugins to BOTH usr/plugins and plugins; any Qt module
# that ships plugins (qtwayland decorations, qtsvg imageformats, qtdeclarative
# qmltooling, ...) must do the same or a consumer's find_package fails: imported
# target references "<sysroot>/plugins/.../foo.so" but this file does not exist.
# Call this after `cmake --install` with the stage root ($COOKBOOK_STAGE).
redbear_qt_dual_stage_plugins() {
local stage="$1"
if [ -d "${stage}/usr/plugins" ]; then
mkdir -p "${stage}/plugins"
cp -a "${stage}/usr/plugins/." "${stage}/plugins/" 2>/dev/null || true
fi
}
redbear_qt_prepare_common_sysroot() {
local sysroot="$1"
redbear_qt_link_sysroot_dirs "$sysroot" plugins mkspecs metatypes modules qml
redbear_qt_link_plugins_dir "$sysroot"
}
redbear_qt_reset_cmake_cache_dir() {
rm -f CMakeCache.txt
if [ -d CMakeFiles ]; then
python3 - <<'PY'
from pathlib import Path
import os
import shutil
path = Path("CMakeFiles")
for node in path.rglob('*'):
try:
os.chmod(node, 0o700)
except OSError:
pass
shutil.rmtree(path, ignore_errors=False)
PY
fi
}
redbear_qt_rewrite_stage_build_paths() {
local stage_usr="$1"
local build_dir="$2"
find "${stage_usr}/lib/cmake" -name '*.cmake' -exec sed -i \
"s|${build_dir}|/usr|g" {} + 2>/dev/null || true
}
redbear_qt_copy_common_stage_to_sysroot() {
local stage_usr="$1"
local sysroot="$2"
mkdir -p "${sysroot}/include" "${sysroot}/lib"
cp -a "${stage_usr}/include/"* "${sysroot}/include/" 2>/dev/null || true
cp -a "${stage_usr}/lib/libQt6"* "${sysroot}/lib/" 2>/dev/null || true
}
redbear_qt_copy_stage_cmake_subdir_to_sysroot() {
local stage_usr="$1"
local sysroot="$2"
local subdir="$3"
mkdir -p "${sysroot}/lib/cmake/${subdir}"
cp -a "${stage_usr}/lib/cmake/${subdir}/"* "${sysroot}/lib/cmake/${subdir}/" 2>/dev/null || true
}
redbear_qt_rewrite_stage_include_paths() {
local stage_cmake_dir="$1"
local sysroot="$2"
find "${stage_cmake_dir}" -name '*.cmake' -exec sed -i \
"s|/usr/include|${sysroot}/include|g" {} + 2>/dev/null || true
}
redbear_qt_rewrite_stage_lib_paths() {
local stage_cmake_dir="$1"
local sysroot="$2"
find "${stage_cmake_dir}" -name '*.cmake' -exec sed -i \
"s|/usr/lib|${sysroot}/lib|g" {} + 2>/dev/null || true
}
redbear_qt_rewrite_stage_source_metatype_paths() {
local stage_cmake_dir="$1"
local sysroot="$2"
local source_root="$3"
find "${stage_cmake_dir}" -name '*.cmake' -exec sed -i \
"s|/usr/src|${source_root}/src|g" {} + 2>/dev/null || true
find "${stage_cmake_dir}" -name '*.cmake' -exec sed -i \
"s|${source_root}/src/.*/meta_types/|${sysroot}/metatypes/|g" {} + 2>/dev/null || true
}
redbear_qt_rewrite_usr_src_metatype_paths() {
local stage_cmake_dir="$1"
local sysroot="$2"
find "${stage_cmake_dir}" -name '*.cmake' -exec sed -i \
"s|/usr/src/.*/meta_types/|${sysroot}/metatypes/|g" {} + 2>/dev/null || true
}
redbear_qt_rewrite_stage_path_literal() {
local stage_cmake_dir="$1"
local from_path="$2"
local to_path="$3"
find "${stage_cmake_dir}" -name '*.cmake' -exec sed -i \
"s|${from_path}|${to_path}|g" {} + 2>/dev/null || true
}
redbear_qt_copy_stage_qt6_cmake_to_sysroot() {
local stage_usr="$1"
local sysroot="$2"
mkdir -p "${sysroot}/lib/cmake"
cp -a "${stage_usr}/lib/cmake/Qt6"* "${sysroot}/lib/cmake/" 2>/dev/null || true
}
redbear_qt_copy_optional_stage_dir_to_sysroot() {
local stage_usr="$1"
local sysroot="$2"
local dir_name="$3"
if [ -d "${stage_usr}/${dir_name}" ]; then
mkdir -p "${sysroot}/${dir_name}"
cp -a "${stage_usr}/${dir_name}/"* "${sysroot}/${dir_name}/" 2>/dev/null || true
fi
}
redbear_qt_resolve_forwarding_headers() {
local stage_usr="$1"
local build_dir="$2"
find "${stage_usr}/include" -name '*.h' -exec grep -l "${build_dir}" {} \; 2>/dev/null | while read -r fwd_header; do
local build_path
build_path=$(grep '#include "' "${fwd_header}" | head -1 | sed 's/#include "\([^"]*\)".*/\1/')
if [ -n "${build_path}" ] && [ -f "${build_path}" ]; then
cp "${build_path}" "${fwd_header}"
fi
done
}
redbear_qt_ensure_dep_sysroots() {
local cookbook_root="$1"
local sysroot="$2"
local cmake_dir="${sysroot}/usr/lib/cmake"
[ -d "${cmake_dir}" ] || cmake_dir="${sysroot}/lib/cmake"
[ -d "${cmake_dir}" ] || return 0
# Qt cmake macros record absolute sysroot paths during build. When the
# cookbook rebuilds a later recipe, the earlier recipe's sysroot may have
# been cleaned, leaving dangling references. We recreate each missing
# directory as a symlink to the dependency's own stage.
grep -roh "${cookbook_root}/local/recipes/[^ \";]*target/x86_64-unknown-redox/sysroot" "${cmake_dir}" 2>/dev/null | sort -u | while read -r dep_sysroot; do
local dep_target_dir dep_stage_usr
dep_target_dir=$(dirname "${dep_sysroot}")
dep_stage_usr="${dep_target_dir}/stage/usr"
[ -d "${dep_stage_usr}" ] || continue
for qt_dir in include lib metatypes plugins mkspecs modules qml; do
if [ -d "${dep_sysroot}/${qt_dir}" ] && [ ! -L "${dep_sysroot}/${qt_dir}" ]; then
continue
fi
if [ -L "${dep_sysroot}/${qt_dir}" ] || [ -e "${dep_sysroot}/${qt_dir}" ]; then
rm -f "${dep_sysroot}/${qt_dir}"
fi
if [ -d "${dep_stage_usr}/${qt_dir}" ]; then
mkdir -p "${dep_sysroot}"
ln -sf "${dep_stage_usr}/${qt_dir}" "${dep_sysroot}/${qt_dir}"
fi
done
done
}