From 01a5d7692c9de7d505918a5cbd9394ecbbc9b667 Mon Sep 17 00:00:00 2001 From: Saya Andy Date: Mon, 7 Sep 2026 05:22:19 +0700 Subject: initial commit --- build.sh | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100755 build.sh (limited to 'build.sh') diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..7e32f3b --- /dev/null +++ b/build.sh @@ -0,0 +1,101 @@ +#!/usr/bin/env bash +# +# Rebuild Fedora's libcamera with this board's patches on top. +# +# libcamera has no plugin mechanism for CameraSensorHelper: the per-sensor gain +# models are compiled into libcamera.so, so teaching the software ISP about the +# Surface Pro 12"'s front sensor means shipping a rebuilt package. The patches +# in patches/ are held against Fedora's source RPM rather than an upstream git +# checkout, so the result stays a drop-in replacement for the distribution +# package -- same name, same subpackages, same soname. +# +# Usage: ./build.sh [-o OUTPUT_DIR] [-w WORK_DIR] [-n] +# +# -o where the built binary RPMs are copied (default: ./RPMS) +# -w scratch directory, reused between runs (default: ./.libcamera-build) +# -n resolve only: print the binary RPM file names the build would produce, +# one per line, and exit without building. Lets a caller check whether +# the packages are already published before paying for a build. +# +# Environment: +# +# RELEASE_SUFFIX what to append to Fedora's release (default: sp12in1) + +set -euo pipefail + +script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +patch_dir="${script_dir}/patches" +suffix=${RELEASE_SUFFIX:-sp12in1} + +output_dir="$(pwd)/RPMS" +work_dir="$(pwd)/.libcamera-build" +resolve_only=false + +while getopts ':o:w:nh' opt; do + case "${opt}" in + o) output_dir=${OPTARG} ;; + w) work_dir=${OPTARG} ;; + n) resolve_only=true ;; + h) sed -n '2,30p' "${BASH_SOURCE[0]}"; exit 0 ;; + *) echo "unknown option -${OPTARG}" >&2; exit 2 ;; + esac +done + +topdir="${work_dir}/rpmbuild" +spec="${topdir}/SPECS/libcamera.spec" + +if [[ ! -f ${spec} ]]; then + rm -rf "${work_dir}" + mkdir -p "${work_dir}" "${topdir}"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} + + ( cd "${work_dir}" && dnf download --source libcamera ) + srpm=$(echo "${work_dir}"/libcamera-*.src.rpm) + [[ -f ${srpm} ]] || { echo "no libcamera source RPM was downloaded" >&2; exit 1; } + rpm --define "_topdir ${topdir}" -i "${srpm}" + + shopt -s nullglob + patches=("${patch_dir}"/*.patch) + shopt -u nullglob + [[ ${#patches[@]} -gt 0 ]] || { echo "no patches in ${patch_dir}" >&2; exit 1; } + + # The spec uses %autosetup -p1, so a PatchNN: line is the whole of it -- + # nothing has to call %patch. Number them after the last one Fedora ships. + last_num=$(grep -oE '^Patch[0-9]+:' "${spec}" | grep -oE '[0-9]+' | sort -n | tail -1) + last_num=${last_num:-0} + last_line=$(grep -nE '^Patch[0-9]+:' "${spec}" | tail -1 | cut -d: -f1) + [[ -n ${last_line} ]] || { echo "no Patch lines in ${spec} to append after" >&2; exit 1; } + + insert="${work_dir}/patch-lines" + : > "${insert}" + for patch in "${patches[@]}"; do + cp "${patch}" "${topdir}/SOURCES/" + last_num=$((10#${last_num} + 1)) + printf 'Patch%02d: %s\n' "${last_num}" "$(basename "${patch}")" >> "${insert}" + done + sed -i "${last_line}r ${insert}" "${spec}" + + sed -i -E "0,/^Release:/s/^(Release:[[:space:]]*[^%]*)(%\{\?dist\})/\1.${suffix}\2/" "${spec}" + grep -qE "^Release:.*\.${suffix}%\{\?dist\}" "${spec}" || { + echo "failed to add the .${suffix} release suffix to ${spec}" >&2 + exit 1 + } +fi + +mapfile -t rpm_files < <(rpmspec -q --queryformat '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}.rpm\n' "${spec}") +[[ ${#rpm_files[@]} -gt 0 ]] || { echo "rpmspec -q produced no packages" >&2; exit 1; } + +if [[ ${resolve_only} == true ]]; then + printf '%s\n' "${rpm_files[@]}" + exit 0 +fi + +dnf --assumeyes builddep "${spec}" +rpmbuild --define "_topdir ${topdir}" -bb "${spec}" + +mkdir -p "${output_dir}" +for rpm_file in "${rpm_files[@]}"; do + built=$(find "${topdir}/RPMS" -type f -name "${rpm_file}" -print -quit) + [[ -n ${built} ]] || { echo "rpmbuild did not produce ${rpm_file}" >&2; exit 1; } + cp "${built}" "${output_dir}/" + echo "${output_dir}/${rpm_file}" +done -- cgit v1.3.1+17