diff --git a/.reuse/dep5 b/.reuse/dep5 index 14f77dac..a9747030 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -73,8 +73,3 @@ License: GPL-3.0-or-later Files: libcam/* Copyright: 2007 Free Software Foundation, Inc. License: BSD-3-Clause - -# linglong -Files: install_dep arm64/org.deepin.camera.install org.deepin.camera.install loong64/org.deepin.camera.install -Copyright: UnionTech Software Technology Co., Ltd. -License: GPL-3.0-or-later 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..5861d073 100644 --- a/linglong.yaml +++ b/linglong.yaml @@ -19,75 +19,78 @@ 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" + # 调整头文件查找路径:gstreamer / libusb 开发头文件经 buildext 装入 /usr/include + # (原脚本由 install_dep 解包到 ${PREFIX}/include),修正 src/CMakeLists.txt + # Qt6 分支的硬编码路径;glib 头文件由 pkg_check_modules(gobject-2.0) 提供 + sed -i 's|${CMAKE_INSTALL_PREFIX}/include/gstreamer-1.0|/usr/include/gstreamer-1.0|g' src/CMakeLists.txt + sed -i 's|${CMAKE_INSTALL_PREFIX}/include/libusb-1.0|/usr/include/libusb-1.0|g' src/CMakeLists.txt # 修改路径 find src -type f -name "*.service" -exec sed -i 's|^Exec=.*|Exec=deepin-camera|g' {} + # 构建 VERSION=$(head -1 debian/changelog | awk -F'[()]' '{print $2}') - cmake -B build ${conf_args} \ + cmake -B build-linglong ${conf_args} \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=${PREFIX} \ -DCMAKE_INSTALL_LIBDIR=${PREFIX}/lib/${TRIPLET} \ -DVERSION=${VERSION} \ -DLINGLONG_BUILD_ON=1 - 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) + cmake --build build-linglong -j`nproc` + cmake --build build-linglong --target install > install.log 2>&1 - 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 + # libblas3/liblapack3 经 apt 闭包(libimageeditor6 推荐链)带入层,其顶层 + # libblas.so.3/liblapack.so.3 是指向 /etc/alternatives 的软链(层内不存在), + # 复制真实库到应用库目录,保证层内 ffmpegthumbnailer/ffmpeg 等二进制的 + # 依赖可解析(ldd 运行时检查),替代旧配方的 mv blas/lapack 逻辑 + install -d -m 0755 ${PREFIX}/lib/${TRIPLET} + for n in libblas.so.3 liblapack.so.3; do + src=$(readlink -f /usr/lib/${TRIPLET}/$n 2>/dev/null || true) + if [ -n "$src" ] && [ -e "$src" ]; then + cp -L "$src" ${PREFIX}/lib/${TRIPLET}/$n fi - else - QT_MAJOR=$QT_VERSION_MAJOR - echo "Using QT_MAJOR from environment: $QT_MAJOR" >&2 - fi + done - version=$QT_MAJOR - lib_path="${PREFIX}/share/libimagevisualresult${version}" - echo "Full library path: $lib_path" >&2 - find "$lib_path" >> "${ID_VALUE}.install" - echo "================================" + # deepin-camera 运行时用 dlopen 按裸名加载库(libPath()/load_libs.c),层内 + # 与 base 均无裸名符号链接,需按旧层配方补齐,否则缩略图等功能失效;仅补 + # base 缺失且由 depends 闭包带入层的项(base 有的项应用代码可通过版本名命中)。 + # build: 阶段依赖库已在构建容器 /usr(build_depends -dev 包提供),取真实 + # 版本名建裸名链接;depends 合并采用 skip_existing,不会被闭包内容覆盖 + cd ${PREFIX}/lib/${TRIPLET} + for n in libswscale.so libffmpegthumbnailer.so libportaudio.so; do + src=$(readlink -f /usr/lib/${TRIPLET}/$n 2>/dev/null || true) + [ -n "$src" ] && [ -e "$src" ] && ln -sf "$(basename "$src")" $n + done + cd - >/dev/null -# allow apt download in build and do apt update buildext: apt: + # 构建依赖:仅声明 base/runtime 层未提供的构建期包。 + # Qt6/DTK6/X11/glib/udev 等开发包与工具链由 runtime 层和 base 层提供。 build_depends: - - libc6 + - cmake + - libavutil-dev + - libavformat-dev + - libavcodec-dev + - libswscale-dev + - libswresample-dev + - libv4l-dev + - portaudio19-dev + - libpciaccess-dev + - libusb-1.0-0-dev + - libffmpegthumbnailer-dev + - libva-dev + - libimageeditor6-dev + - libgstreamer1.0-dev + - libgstreamer-plugins-base1.0-dev + # 运行依赖:仅声明 base/runtime 层未提供的直接运行时包。 + # ffmpeg/udev/v4l2/usb 等运行库已在 base/runtime 中;deepin-event-log + # 提供代码 dlopen 的裸名 libdeepin-event-log.so。 + depends: + - deepin-event-log + - libimageeditor6 + - libportaudio2 + - libffmpegthumbnailer4v5 + - gstreamer1.0-plugins-base + - gstreamer1.0-plugins-good + - dmidecode