From ca16c56ff3fd194aee8e568fac665039a5db1b93 Mon Sep 17 00:00:00 2001 From: re2zero Date: Tue, 27 Oct 2026 21:47:50 +0800 Subject: [PATCH] build: migrate linglong.yaml to buildext.apt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Replace manual apt --download-only, install_dep, deploy_dep and .install generation with declarative buildext.apt build_depends/depends. 2. Add sed to fix include path (${CMAKE_INSTALL_PREFIX}/include -> /usr/include) in src/CMakeLists.txt at build time, since buildext.apt installs to system paths. 3. Copy libblas.so.3/liblapack.so.3 from alternatives subdirs to $PREFIX/lib/$TRIPLET/ so ffmpegthumbnailer passes ldd runtime check. Log: Migrate linglong.yaml from manual install_dep/deploy_dep to buildext.apt. Influence: 1. linglong build uses buildext.apt for dependency management. 2. ll-builder build passes including ldd runtime check. PMS:Task-396575 Multica: V-6803 --- deploy_dep | 81 -------------------------- install_dep | 158 -------------------------------------------------- linglong.yaml | 86 +++++++++++---------------- 3 files changed, 33 insertions(+), 292 deletions(-) delete mode 100644 deploy_dep delete mode 100644 install_dep diff --git a/deploy_dep b/deploy_dep deleted file mode 100644 index b766b76c..00000000 --- a/deploy_dep +++ /dev/null @@ -1,81 +0,0 @@ -# SPDX-FileCopyrightText: 2023-2024 UnionTech Software Technology Co., Ltd. -# -# SPDX-License-Identifier: GPL-3.0-or-later - -#!/bin/bash -set -e - -# 生成安装目录/文件和运行时依赖的必要库 -# 获取应用id -ID_VALUE=$(awk -F ': ' '/^ id: / {print $2}' linglong.yaml) - -## 获取安装的文件列表并写入安装脚本(排除头文件、pc和cmake文件) -# cmake 安装 -if ! grep -- "-- Installing:" install.log | sed 's/-- Installing: //' | grep -vE '\.(h|cmake|pc)$' > ${ID_VALUE}.install; then - echo "cmake install files are empty!" -fi -# qmake 安装 -if ! grep -- "-install qinstall" install.log | awk '{print $NF}' | grep -vE '\.(h|cmake|pc)$' >> ${ID_VALUE}.install; then - echo "qmake install files are empty!" -fi -# 动态库软连接 -if ! grep -- "^ln -f -s " install.log | awk '{print $NF}' >> ${ID_VALUE}.install; then - echo "Get library softlink empty!" -fi - -# glib-compile-schemas 文件添加到 install 文件 -for SCHEMAS in "${PREFIX}"/share/glib-2.0/schemas/gschema*; do - if [[ -f "$SCHEMAS" ]]; then - echo "$SCHEMAS" >> "${ID_VALUE}.install" - fi -done - -# 获取依赖的所有文件 -for LDFILE in "$@"; do - - # 判断文件是否以 .so 结尾 - if [[ "$LDFILE" == *.so ]]; then - FILE_PATH="${PREFIX}/lib/${TRIPLET}/$LDFILE" - - # 添加依赖库到 install 文件 - for SOFILE in "${PREFIX}/lib/${TRIPLET}"/${LDFILE}*; do - if [[ -f "$SOFILE" ]]; then - echo "$SOFILE" >> "${ID_VALUE}.install" - fi - done - else - FILE_PATH="${PREFIX}/bin/$LDFILE" - fi - - # 检查库缺失 - EXIST_NOT_FOUND=`ldd $FILE_PATH | grep found | wc -l` - if [ $EXIST_NOT_FOUND -ne 0 ]; then - echo $FILE_PATH - ldd $FILE_PATH | grep found - fi - - # 获取依赖库 - DEPENDENCIES=$(ldd "$FILE_PATH" | grep "$PREFIX") || continue - if [[ ! -z "$DEPENDENCIES" ]]; then - echo "$DEPENDENCIES" | while IFS= read -r line; do - LIB_PATH=${line##*=> } - LIB_PATH=${LIB_PATH%%(*} - - # 获取基本库名并匹配相关库 - LIB_DIR=$(dirname "$LIB_PATH") - BASE_LIB_NAME=$(basename "$LIB_PATH") - - # 使用通配符查找相关库文件并将结果倒序存储到 install 文件 - for FILE in "$LIB_DIR"/${BASE_LIB_NAME%.*}*; do - if [[ -f "$FILE" ]]; then - echo "$FILE" - fi - done | sort -r >> "${ID_VALUE}.install" - - done - fi -done - -# 排除静态链接库 -#echo '^'${PREFIX}'/'${TRIPLET}'/.+(?> "${ID_VALUE}.install" -#echo '^'${PREFIX}'/lib/.+(?> "${ID_VALUE}.install" diff --git a/install_dep b/install_dep deleted file mode 100644 index ff5f3300..00000000 --- a/install_dep +++ /dev/null @@ -1,158 +0,0 @@ -#!/bin/bash -set -e -project_dir=$PWD -cache_dir=${LINGLONG_FETCH_CACHE:-$PWD/linglong/cache} -mkdir -p "$cache_dir" -# 文件名 deb-source.bash -# 包含要解压的deb目录 -deb_dir=$(realpath "$1") -# 将deb解压到输出目录 -target=$(realpath "$2") -# 默认会跳过base已安装的包,可以强制解压已安装的包 -include="$3" -# 临时目录,将内容处理后再移动到 target -out_dir="$(mktemp -d)" -cd "$out_dir" -# 临时文件,用于记录deb文件列表 -deb_list_file="$out_dir/deb.list" -# 临时文件,用于记录强制安装的包名 -include_list_file="$out_dir/include.packages.list" -# 临时文件,用于记录跳过安装的包名 -exclude_list_file="$out_dir/exclude.packages.list" -# 包数据存放的临时目录 -data_list_dir="$out_dir/data" -# 生成文件列表 -find "$deb_dir" -type f -name "*.deb" >"$deb_list_file" -echo "$include" | tr ',' '\n' >"$include_list_file" -# 用于记录安装的所有文件来自哪个包 -mkdir /tmp/deb-source-file || true - -# 如果base和runtime已安装则跳过,旧版本base没有/packages.list文件就使用/var/lib/dpkg/status -grep 'Package: ' /var/lib/dpkg/status >"$exclude_list_file" || true -# 跳过base和runtime已安装的包,也可使用install_dep_skip.list文件控制跳过哪些包 -cat /packages.list /runtime/packages.list "$PREFIX/packages.list" "$project_dir/install_dep_skip.list" >>"$exclude_list_file" || true - -# 遍历文件列表 -while IFS= read -r deb_file; do - # 输出deb名,但不换行,便于在包名后面加skip - echo -n "$deb_file" - # 提取control文件 - control_file=$(ar -t "$deb_file" | grep control.tar) - ar -x "$deb_file" "$control_file" - # 获取包名 - pkg=$(tar -xf "$control_file" ./control -O | grep '^Package:' | awk '{print $2}') - rm "$control_file" - # 如果在base和runtime中已安装,并且不包含在include(强制安装)列表则跳过安装,否则安装到$PREFIX目录 - if grep -q "^Package: $pkg$" "$exclude_list_file" && ! grep -q "^$pkg$" "$include_list_file"; then - echo " skip" - echo "$deb_file" >>/tmp/deb-source-file/skip.list - continue - fi - # 记录到 packages.list - echo "Package: $pkg" >>"$PREFIX/packages.list" - # 换行 - echo "" - # 缓存解压后的data.tar文件,便于在下次使用时,加快安装速度 - deb_sha=$(sha256sum "$deb_file" | awk '{print $1}') - data_cache="$cache_dir/install_dep_$deb_sha" - if [ ! -e "$data_cache" ]; then - data_cache_tmp="$cache_dir/install_dep_tmp_$deb_sha" - # 查找data.tar文件,文件会因为压缩格式不同,有不同的后缀,例如data.tar.xz、data.tar.gz - data_file=$(ar -t "$deb_file" | grep data.tar) - case "$data_file" in - *.xz) ar -p "$deb_file" "$data_file" | unxz >"$data_cache_tmp" ;; - *.gz) ar -p "$deb_file" "$data_file" | gunzip >"$data_cache_tmp" ;; - *.zst) ar -p "$deb_file" "$data_file" | unzstd >"$data_cache_tmp" ;; - *) - echo "unknown file type" - exit 1 - ;; - esac - mv "$data_cache_tmp" "$data_cache" - fi - # 解压data.tar文件到输出目录 - mkdir "$data_list_dir" - tar -xvf "$data_cache" -C "$data_list_dir" >>"/tmp/deb-source-file/$(basename "$deb_file").list" - # 清理不需要复制的目录 - rm -r "${data_list_dir:?}/usr/share/applications"* 2>/dev/null || true - # 修改pc文件的prefix - sed -i "s#/usr#$PREFIX#g" "$data_list_dir"/usr/lib/"$TRIPLET"/pkgconfig/*.pc 2>/dev/null || true - sed -i "s#/usr#$PREFIX#g" "$data_list_dir"/usr/share/pkgconfig/*.pc 2>/dev/null || true - # 修改指向/lib的绝对路径的软链接 - find "$data_list_dir" -type l | while IFS= read -r file; do - linkTarget=$(readlink "$file") - # 如果指向的路径以/lib开头,并且文件不存在,则添加 /runtime 前缀 - # 部分 dev 包会创建 so 文件的绝对链接指向 /lib 目录下 - if echo "$linkTarget" | grep -q ^/lib && ! [ -f "$linkTarget" ]; then - ln -sf "$target$linkTarget" "$file" - echo " FIX LINK" "$linkTarget" "=>" "$target$linkTarget" - fi - done - - # 修复动态库的RUNPATH - find "$data_list_dir" -type f | while IFS= read -r file; do - fileinfo=$(file "$file") - # skip non-dynamic librarie - if ! echo "$fileinfo" | grep -q 'shared object'; then - continue - fi - # skip debug file - if echo "$fileinfo" | grep -q 'with debug_info'; then - continue - fi - runpath=$(readelf -d "$file" | grep RUNPATH | awk '{print $NF}') - # skip without runpath - if ! echo "$runpath" | grep -q '^\[/'; then - continue - fi - # 如果RUNPATH使用绝对路径,则添加/runtime前缀 - runpath=${runpath#[} - runpath=${runpath%]} - newRunpath=${runpath//usr\/lib/runtime\/lib} - newRunpath=${newRunpath//usr/runtime} - patchelf --set-rpath "$newRunpath" "$file" - echo " FIX RUNPATH" "$file" "$runpath" "=>" "$newRunpath" - done - # 复制/lib,/bin,/usr目录 - cp -rP "$data_list_dir/lib" "$target" 2>/dev/null || true - cp -rP "$data_list_dir/bin" "$target" 2>/dev/null || true - cp -rP "$data_list_dir"/usr/* "$target" || true - rm -r "$data_list_dir" -done <"$deb_list_file" - -# 修复相对路径的软链接(dev包内的软连接尝试修复指向base) -find "$target" -type l | while IFS= read -r file; do - # 获取链接的绝对路径 - linkTarget=$(readlink -m "$file") - # 如果链接指向的文件不存在 - if [ ! -e "$linkTarget" ]; then - # 去掉前缀查看/lib下是否存在 - linkTarget="${linkTarget#$target}" - if [ -e "$linkTarget" ]; then - ln -sf "$linkTarget" "$file" - echo " FIX LINK" "$file" "=>" "$target$linkTarget" - fi - # 添加usr前缀查看/usr/lib下是否存在 - linkTarget="/usr$target" - if [ -e "$linkTarget" ]; then - ln -sf "$target$linkTarget" "$file" - echo " FIX LINK" "$file" "=>" "$target$linkTarget" - fi - # 添加 /runtime 前缀查看是否存在 - linkTarget=$(readlink -m "$file") - linkTargetNoPrefix="${linkTarget#$target}" - runtimeLib="/runtime$linkTargetNoPrefix" - if [ -e "$runtimeLib" ]; then - ln -sf "$runtimeLib" "$file" - echo " FIX LINK" "$file" "=>" "$runtimeLib" - fi - fi -done - -# 更新ld.so.cache -if [ -n "$LINGLONG_LD_SO_CACHE" ]; then - ldconfig -C "$LINGLONG_LD_SO_CACHE" -fi - -# 清理临时目录 -rm -r "$out_dir" diff --git a/linglong.yaml b/linglong.yaml index 0ab4158e..eb31ede5 100644 --- a/linglong.yaml +++ b/linglong.yaml @@ -19,18 +19,12 @@ command: - deepin-camera build: | - # 下载和安装依赖 - apt -y install --download-only qt6-base-dev libdtk6gui-dev libdtk6widget-dev qt6-multimedia-dev libavutil-dev libavformat-dev libavcodec-dev libavfilter-dev qt6-tools-dev qt6-tools-dev-tools deepin-gettext-tools qt6-svg-dev libv4l-dev libsdl2-dev portaudio19-dev libpng-dev libasound2-dev libpciaccess-dev libusb-1.0-0-dev zlib1g-dev libudev-dev libswscale-dev libswresample-dev libffmpegthumbnailer-dev libx11-dev libva-dev libimageeditor6-dev libimageeditor6 libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-good deepin-event-log - bash ./install_dep /var/cache/apt/archives "$PREFIX" - - # 移动部分库到应用库目录,否则无法找到 - mv ${PREFIX}/lib/${TRIPLET}/blas/* ${PREFIX}/lib/${TRIPLET} - mv ${PREFIX}/lib/${TRIPLET}/lapack/* ${PREFIX}/lib/${TRIPLET} - ldconfig -C "$LINGLONG_LD_SO_CACHE" - # 修改路径 find src -type f -name "*.service" -exec sed -i 's|^Exec=.*|Exec=deepin-camera|g' {} + + # buildext.apt 安装依赖到系统路径而非 $PREFIX,修正 CMakeLists.txt 中的 include 路径 + sed -i 's|${CMAKE_INSTALL_PREFIX}/include|/usr/include|g' src/CMakeLists.txt + # 构建 VERSION=$(head -1 debian/changelog | awk -F'[()]' '{print $2}') cmake -B build ${conf_args} \ @@ -42,52 +36,38 @@ build: | cmake --build build -j`nproc` cmake --build build --target install > install.log 2>&1 - # 项目生成应用名和动态隐式加载的依赖库,ldd无法找到的其他库 - LDD_FILES=( - deepin-camera - libv4l2.so - libportaudio.so - libusb-1.0.so - # 已包含在 runtime 中 - # libudev.so - libavutil.so - libavformat.so - libswscale.so - libswresample.so - libffmpegthumbnailer.so - libavcodec.so - ../libdeepin-event-log.so - ) - - # 生成.install 文件 - bash ./deploy_dep "${LDD_FILES[@]}" - - # Add resource files from libimageeditor (any version) - ID_VALUE=$(awk -F ': ' '/^ id: / {print $2}' linglong.yaml) - - echo "=== QT Version Detection ===" >&2 - if [ -z "$QT_VERSION_MAJOR" ]; then - if command -v qmake >/dev/null 2>&1; then - QT_VERSION=$(qmake -query QT_VERSION 2>/dev/null || echo "unknown") - QT_MAJOR=$(qmake -query QT_VERSION 2>/dev/null | cut -d. -f1 || echo "6") - echo "Using QT_MAJOR from qmake: $QT_MAJOR" >&2 - else - QT_MAJOR=6 # default value - echo "qmake not found, using default QT_MAJOR: $QT_MAJOR" >&2 - fi - else - QT_MAJOR=$QT_VERSION_MAJOR - echo "Using QT_MAJOR from environment: $QT_MAJOR" >&2 - fi - - version=$QT_MAJOR - lib_path="${PREFIX}/share/libimagevisualresult${version}" - echo "Full library path: $lib_path" >&2 - find "$lib_path" >> "${ID_VALUE}.install" - echo "================================" + # blas/lapack 通过 alternatives 安装到子目录,复制到主库目录以供 ldd 检查通过 + mkdir -p ${PREFIX}/lib/${TRIPLET} + cp -aL /usr/lib/${TRIPLET}/blas/libblas.so.3* ${PREFIX}/lib/${TRIPLET}/ 2>/dev/null || true + cp -aL /usr/lib/${TRIPLET}/lapack/liblapack.so.3* ${PREFIX}/lib/${TRIPLET}/ 2>/dev/null || true # allow apt download in build and do apt update buildext: apt: build_depends: - - libc6 + - cmake + - deepin-gettext-tools + - libavutil-dev + - libavformat-dev + - libavcodec-dev + - libavfilter-dev + - libv4l-dev + - libsdl2-dev + - portaudio19-dev + - libasound2-dev + - libpciaccess-dev + - libusb-1.0-0-dev + - libswscale-dev + - libswresample-dev + - libffmpegthumbnailer-dev + - libva-dev + - libimageeditor6-dev + - libgstreamer1.0-dev + - libgstreamer-plugins-base1.0-dev + depends: + - libffmpegthumbnailer4v5 + - libportaudio2 + - deepin-event-log + - libimageeditor6 + - libsdl2-2.0-0 + - gstreamer1.0-plugins-good