mirror of
https://github.com/orbbec/OrbbecSDK_ROS2.git
synced 2026-10-04 12:07:46 +08:00
feat: add script to update bundled Orbbec SDK for ARM64 and x86-64 architectures
This commit is contained in:
Executable
+322
@@ -0,0 +1,322 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||
readonly PACKAGE_DIR="$(cd -- "${SCRIPT_DIR}/.." && pwd -P)"
|
||||
readonly SDK_ROOT="${PACKAGE_DIR}/SDK"
|
||||
readonly ROS_CONFIG_FILE="${PACKAGE_DIR}/config/OrbbecSDKConfig_v2.0.xml"
|
||||
|
||||
dry_run=false
|
||||
work_dir=""
|
||||
arm64_backup_dir=""
|
||||
x64_backup_dir=""
|
||||
config_backup_file=""
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage:
|
||||
$(basename "$0") [--dry-run] <arm64-or-x86_64-sdk-directory>
|
||||
|
||||
Replace the bundled Orbbec SDK for both supported ROS package architectures.
|
||||
The other SDK directory is inferred by swapping the input path suffix between
|
||||
"_arm64" and "_x86_64".
|
||||
|
||||
Only the files used or distributed by orbbec_camera are copied:
|
||||
- include/libobsensor/
|
||||
- lib/libOrbbecSDK.so*
|
||||
- lib/OrbbecSDKConfig-release.cmake
|
||||
- lib/OrbbecSDKConfig.cmake
|
||||
- lib/OrbbecSDKVersion.cmake
|
||||
- lib/extensions/
|
||||
- lib/OrbbecSDKConfig.xml -> config/OrbbecSDKConfig_v2.0.xml
|
||||
|
||||
SDK/licenses/ is left unchanged.
|
||||
|
||||
Example:
|
||||
$(basename "$0") \\
|
||||
/home/user/Downloads/SDK/OrbbecSDK_v2.10.2_linux_arm64
|
||||
EOF
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "Error: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
cleanup_work_dir() {
|
||||
if [[ -n "${work_dir}" && "${work_dir}" == "${PACKAGE_DIR}"/.sdk-update.* ]]; then
|
||||
rm -rf -- "${work_dir}"
|
||||
fi
|
||||
}
|
||||
|
||||
backup_exists() {
|
||||
[[ -n "${arm64_backup_dir}" && -d "${arm64_backup_dir}" ]] ||
|
||||
[[ -n "${x64_backup_dir}" && -d "${x64_backup_dir}" ]] ||
|
||||
[[ -n "${config_backup_file}" && -e "${config_backup_file}" ]]
|
||||
}
|
||||
|
||||
restore_backup() {
|
||||
backup_exists || return 0
|
||||
|
||||
echo "Update failed; restoring the original SDK libraries and runtime configuration..." >&2
|
||||
if [[ -n "${config_backup_file}" && -e "${config_backup_file}" ]]; then
|
||||
if [[ -e "${ROS_CONFIG_FILE}" ]]; then
|
||||
mv -- "${ROS_CONFIG_FILE}" "${work_dir}/OrbbecSDKConfig.failed.xml" || return 1
|
||||
fi
|
||||
mv -- "${config_backup_file}" "${ROS_CONFIG_FILE}" || return 1
|
||||
fi
|
||||
|
||||
if [[ -n "${x64_backup_dir}" && -d "${x64_backup_dir}" ]]; then
|
||||
if [[ -e "${SDK_ROOT}/x64" ]]; then
|
||||
mv -- "${SDK_ROOT}/x64" "${work_dir}/x64.failed" || return 1
|
||||
fi
|
||||
mv -- "${x64_backup_dir}" "${SDK_ROOT}/x64" || return 1
|
||||
fi
|
||||
|
||||
if [[ -n "${arm64_backup_dir}" && -d "${arm64_backup_dir}" ]]; then
|
||||
if [[ -e "${SDK_ROOT}/arm64" ]]; then
|
||||
mv -- "${SDK_ROOT}/arm64" "${work_dir}/arm64.failed" || return 1
|
||||
fi
|
||||
mv -- "${arm64_backup_dir}" "${SDK_ROOT}/arm64" || return 1
|
||||
fi
|
||||
}
|
||||
|
||||
on_exit() {
|
||||
local status=$?
|
||||
trap - EXIT
|
||||
|
||||
if ((status != 0)) && backup_exists; then
|
||||
if ! restore_backup; then
|
||||
echo "Error: automatic rollback failed; recovery files remain in ${work_dir}" >&2
|
||||
exit "${status}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! backup_exists; then
|
||||
cleanup_work_dir
|
||||
fi
|
||||
exit "${status}"
|
||||
}
|
||||
|
||||
trap on_exit EXIT
|
||||
trap 'exit 130' INT TERM HUP
|
||||
|
||||
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--dry-run" ]]; then
|
||||
dry_run=true
|
||||
shift
|
||||
fi
|
||||
|
||||
[[ $# -eq 1 ]] || {
|
||||
usage >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
for command_name in basename cat cmp cp dirname file find mkdir mktemp mv readlink rm wc; do
|
||||
command -v "${command_name}" >/dev/null 2>&1 || die "required command not found: ${command_name}"
|
||||
done
|
||||
|
||||
[[ -d "${SDK_ROOT}" && ! -L "${SDK_ROOT}" ]] ||
|
||||
die "bundled SDK must be a real directory: ${SDK_ROOT}"
|
||||
[[ -d "${SDK_ROOT}/arm64" && ! -L "${SDK_ROOT}/arm64" ]] ||
|
||||
die "bundled ARM64 SDK must be a real directory: ${SDK_ROOT}/arm64"
|
||||
[[ -d "${SDK_ROOT}/x64" && ! -L "${SDK_ROOT}/x64" ]] ||
|
||||
die "bundled x86-64 SDK must be a real directory: ${SDK_ROOT}/x64"
|
||||
[[ -d "${SDK_ROOT}/licenses" && ! -L "${SDK_ROOT}/licenses" ]] ||
|
||||
die "bundled SDK licenses must be a real directory: ${SDK_ROOT}/licenses"
|
||||
[[ -f "${ROS_CONFIG_FILE}" && ! -L "${ROS_CONFIG_FILE}" ]] ||
|
||||
die "ROS SDK configuration must be a real file: ${ROS_CONFIG_FILE}"
|
||||
|
||||
[[ -d "$1" ]] || die "SDK directory not found: $1"
|
||||
input_source="$(readlink -f -- "$1")"
|
||||
|
||||
case "${input_source}" in
|
||||
*_arm64)
|
||||
arm64_source="${input_source}"
|
||||
x64_source="${input_source%_arm64}_x86_64"
|
||||
;;
|
||||
*_x86_64)
|
||||
x64_source="${input_source}"
|
||||
arm64_source="${input_source%_x86_64}_arm64"
|
||||
;;
|
||||
*)
|
||||
die "SDK directory name must end with _arm64 or _x86_64: ${input_source}"
|
||||
;;
|
||||
esac
|
||||
|
||||
[[ -d "${arm64_source}" ]] || die "paired ARM64 SDK directory not found: ${arm64_source}"
|
||||
[[ -d "${x64_source}" ]] || die "paired x86-64 SDK directory not found: ${x64_source}"
|
||||
case "${arm64_source}" in
|
||||
"${SDK_ROOT}" | "${SDK_ROOT}"/*) die "the ARM64 source cannot be inside ${SDK_ROOT}" ;;
|
||||
esac
|
||||
case "${x64_source}" in
|
||||
"${SDK_ROOT}" | "${SDK_ROOT}"/*) die "the x86-64 source cannot be inside ${SDK_ROOT}" ;;
|
||||
esac
|
||||
|
||||
core_library_path() {
|
||||
local source_dir=$1
|
||||
local core_link="${source_dir}/lib/libOrbbecSDK.so"
|
||||
|
||||
[[ -e "${core_link}" ]] || die "missing core SDK library: ${core_link}"
|
||||
readlink -f -- "${core_link}"
|
||||
}
|
||||
|
||||
sdk_version() {
|
||||
local core_library
|
||||
core_library="$(core_library_path "$1")"
|
||||
local filename=${core_library##*/}
|
||||
|
||||
[[ "${filename}" == libOrbbecSDK.so.* ]] ||
|
||||
die "cannot determine SDK version from core library: ${core_library}"
|
||||
echo "${filename#libOrbbecSDK.so.}"
|
||||
}
|
||||
|
||||
verify_architecture() {
|
||||
local source_dir=$1
|
||||
local expected_arch=$2
|
||||
local core_library
|
||||
local description
|
||||
core_library="$(core_library_path "${source_dir}")"
|
||||
description="$(file -Lb -- "${core_library}")"
|
||||
|
||||
case "${expected_arch}" in
|
||||
arm64)
|
||||
[[ "${description}" == *"ARM aarch64"* || "${description}" == *"AArch64"* ]] ||
|
||||
die "${source_dir} is not an ARM64 SDK (${description})"
|
||||
;;
|
||||
x64)
|
||||
[[ "${description}" == *"x86-64"* ]] ||
|
||||
die "${source_dir} is not an x86-64 SDK (${description})"
|
||||
;;
|
||||
*)
|
||||
die "internal error: unsupported architecture ${expected_arch}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
verify_symlinks_within() {
|
||||
local root_dir
|
||||
local link_path
|
||||
local resolved_path
|
||||
root_dir="$(readlink -f -- "$1")"
|
||||
|
||||
while IFS= read -r -d '' link_path; do
|
||||
if ! resolved_path="$(readlink -f -- "${link_path}")"; then
|
||||
die "broken symbolic link: ${link_path}"
|
||||
fi
|
||||
case "${resolved_path}" in
|
||||
"${root_dir}"/*) ;;
|
||||
*) die "symbolic link points outside ${root_dir}: ${link_path} -> ${resolved_path}" ;;
|
||||
esac
|
||||
done < <(find "${root_dir}" -type l -print0)
|
||||
}
|
||||
|
||||
verify_source_layout() {
|
||||
local source_dir=$1
|
||||
local expected_arch=$2
|
||||
local required_path
|
||||
|
||||
for required_path in \
|
||||
include/libobsensor/ObSensor.h \
|
||||
include/libobsensor/ObSensor.hpp \
|
||||
lib/OrbbecSDKConfig-release.cmake \
|
||||
lib/OrbbecSDKConfig.cmake \
|
||||
lib/OrbbecSDKVersion.cmake \
|
||||
lib/OrbbecSDKConfig.xml; do
|
||||
[[ -f "${source_dir}/${required_path}" ]] ||
|
||||
die "missing required ${expected_arch} SDK file: ${source_dir}/${required_path}"
|
||||
done
|
||||
|
||||
[[ -d "${source_dir}/lib/extensions" ]] ||
|
||||
die "missing ${expected_arch} SDK extensions directory: ${source_dir}/lib/extensions"
|
||||
|
||||
verify_architecture "${source_dir}" "${expected_arch}"
|
||||
verify_symlinks_within "${source_dir}/lib"
|
||||
}
|
||||
|
||||
copy_architecture() {
|
||||
local source_dir=$1
|
||||
local target_arch=$2
|
||||
local destination_dir=$3
|
||||
local cmake_file
|
||||
local copied_core_library=false
|
||||
|
||||
mkdir -p -- "${destination_dir}/include" "${destination_dir}/lib"
|
||||
cp -a -- "${source_dir}/include/libobsensor" "${destination_dir}/include/"
|
||||
|
||||
while IFS= read -r -d '' library; do
|
||||
cp -a -- "${library}" "${destination_dir}/lib/"
|
||||
copied_core_library=true
|
||||
done < <(find "${source_dir}/lib" -maxdepth 1 \( -type f -o -type l \) \
|
||||
-name 'libOrbbecSDK.so*' -print0)
|
||||
[[ "${copied_core_library}" == true ]] ||
|
||||
die "no core SDK libraries were copied for ${target_arch}"
|
||||
|
||||
for cmake_file in \
|
||||
OrbbecSDKConfig-release.cmake \
|
||||
OrbbecSDKConfig.cmake \
|
||||
OrbbecSDKVersion.cmake; do
|
||||
cp -a -- "${source_dir}/lib/${cmake_file}" "${destination_dir}/lib/"
|
||||
done
|
||||
|
||||
cp -a -- "${source_dir}/lib/extensions" "${destination_dir}/lib/"
|
||||
}
|
||||
|
||||
verify_source_layout "${arm64_source}" arm64
|
||||
verify_source_layout "${x64_source}" x64
|
||||
cmp -s -- "${arm64_source}/lib/OrbbecSDKConfig.xml" \
|
||||
"${x64_source}/lib/OrbbecSDKConfig.xml" ||
|
||||
die "ARM64 and x86-64 OrbbecSDKConfig.xml files do not match"
|
||||
|
||||
arm64_version="$(sdk_version "${arm64_source}")"
|
||||
x64_version="$(sdk_version "${x64_source}")"
|
||||
[[ "${arm64_version}" == "${x64_version}" ]] ||
|
||||
die "SDK versions do not match: ARM64=${arm64_version}, x86-64=${x64_version}"
|
||||
|
||||
work_dir="$(mktemp -d -- "${PACKAGE_DIR}/.sdk-update.XXXXXX")"
|
||||
staged_sdk="${work_dir}/SDK.new"
|
||||
staged_config="${work_dir}/OrbbecSDKConfig_v2.0.xml.new"
|
||||
mkdir -p -- "${staged_sdk}"
|
||||
|
||||
copy_architecture "${arm64_source}" arm64 "${staged_sdk}/arm64"
|
||||
copy_architecture "${x64_source}" x64 "${staged_sdk}/x64"
|
||||
|
||||
cp -a -- "${x64_source}/lib/OrbbecSDKConfig.xml" "${staged_config}"
|
||||
|
||||
verify_architecture "${staged_sdk}/arm64" arm64
|
||||
verify_architecture "${staged_sdk}/x64" x64
|
||||
verify_symlinks_within "${staged_sdk}"
|
||||
|
||||
sdk_file_count="$(find "${staged_sdk}" \( -type f -o -type l \) | wc -l)"
|
||||
file_count=$((sdk_file_count + 1))
|
||||
echo "Validated Orbbec SDK ${arm64_version} for ARM64 and x86-64."
|
||||
echo "Staged ${file_count} ROS package files, including ${ROS_CONFIG_FILE}."
|
||||
|
||||
if [[ "${dry_run}" == true ]]; then
|
||||
echo "Dry run complete; SDK libraries, licenses, and runtime configuration were not changed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
arm64_backup_dir="${work_dir}/arm64.old"
|
||||
x64_backup_dir="${work_dir}/x64.old"
|
||||
config_backup_file="${work_dir}/OrbbecSDKConfig_v2.0.xml.old"
|
||||
mv -- "${SDK_ROOT}/arm64" "${arm64_backup_dir}"
|
||||
mv -- "${SDK_ROOT}/x64" "${x64_backup_dir}"
|
||||
mv -- "${ROS_CONFIG_FILE}" "${config_backup_file}"
|
||||
mv -- "${staged_sdk}/arm64" "${SDK_ROOT}/arm64"
|
||||
mv -- "${staged_sdk}/x64" "${SDK_ROOT}/x64"
|
||||
mv -- "${staged_config}" "${ROS_CONFIG_FILE}"
|
||||
|
||||
# The verified SDK and runtime configuration are now active. Mark the
|
||||
# transaction as committed; the exit handler removes the temporary backups.
|
||||
arm64_backup_dir=""
|
||||
x64_backup_dir=""
|
||||
config_backup_file=""
|
||||
|
||||
echo "Updated bundled ARM64, x86-64, and runtime configuration to Orbbec SDK ${arm64_version}."
|
||||
echo "Left ${SDK_ROOT}/licenses unchanged."
|
||||
Reference in New Issue
Block a user