Files
BPI-CM9-Linux/amlbian/scripts/bt/build-bluez5.sh
T

907 lines
34 KiB
Bash

#!/usr/bin/env bash
# SPDX-License-Identifier: (GPL-2.0-only OR MIT)
# Copyright (C) 2026 Amlogic, Inc. All rights reserved
################################################################################
# Amlbian BlueZ5 Compilation Package
#
# Purpose: BlueZ5 compilation based on Yocto recipe bluez5_5.65.bb
# + meta-meson/recipes-connectivity/bluez/bluez5_%.bbappend
# + meta-meson/recipes-connectivity/bluez/bluez5_5.65.bbappend
# Based on Yocto recipe: poky/meta/recipes-connectivity/bluez5/bluez5_5.65.bb
#
# This script implements the base BlueZ5 5.65 recipe with complete bbappend modifications
# Optimized version based on build-bt.sh structure
################################################################################
set -e
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
AMLBIAN_DIR="$(dirname "$(dirname "${SCRIPT_DIR}")")"
BASE_DIR="$(dirname "$(dirname "${AMLBIAN_DIR}")")"
MODULE_BUILD_DIR="${SRC}/output/.tmp"
CACHE_SOURCES=${SRC}/cache/sources
# ==============================================================================
# Shared Helper Functions
# ==============================================================================
# ------------------------------------------------------------------------------
# Step 1: Package Information Definition
# ------------------------------------------------------------------------------
# Initialize BlueZ5 package metadata
function _bluez5_init_package_info() {
PKG_NAME="bluez"
PKG_VERSION="5.65"
COMPONENT="bluez5"
PKG_ARCH="${ARCH:-aarch64}"
PKG_MAINTAINER="Armbian Build <[email protected]>"
PKG_DESCRIPTION="BlueZ 5.65 Bluetooth stack with Amlogic modifications"
# Cross compilation settings
CROSS_COMPILE="${CROSS_COMPILE:-aarch64-linux-gnu-}"
# Source URL from bluez5_5.65.bb
KERNELORG_MIRROR="https://www.kernel.org/pub/linux/bluetooth"
SRC_URL="${KERNELORG_MIRROR}/bluez-${PKG_VERSION}.tar.xz"
SRC_SHA256="2565a4d48354b576e6ad92e25b54ed66808296581c8abb80587051f9993d96d4"
# Meta-meson files directory (from bbappend FILESEXTRAPATHS)
FILES_DIR="${SCRIPT_DIR}/files"
# TTY setting from bluez5_%.bbappend
TTY="${TTY:-ttyS1}"
# DISTRO_FEATURES - controls which features are enabled
DISTRO_FEATURES+=" systemd obexd aml-wifi bt-audio"
# MACHINE_EXTRA_RRECOMMENDS for RDEPENDS logic
MACHINE_EXTRA_RRECOMMENDS="${MACHINE_EXTRA_RRECOMMENDS:-}"
}
# ------------------------------------------------------------------------------
# Step 2: Build Directory Structure Setup
# ------------------------------------------------------------------------------
# Create layered build directory structure
# Parameters:
# $1 - base name (e.g. "${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}")
# Sets: TMP_DIR, BASE_BUILD_DIR, SOURCE_DIR, BUILD_DIR, INSTALL_DIR, PATCH_DIR,
# DEB_PACKAGE_DIR, DEBIAN_DIR, BUILD_LOG
function _bluez5_common_create_build_dirs() {
local base_name="$1"
mkdir -p "${MODULE_BUILD_DIR}"
# 基础构建目录
BASE_BUILD_DIR="${MODULE_BUILD_DIR}/${base_name}"
rm -rf ${BASE_BUILD_DIR}
# 分层目录
SOURCE_DIR="${BASE_BUILD_DIR}/source" # 源码目录
BUILD_DIR="${BASE_BUILD_DIR}/build" # 编译目录
INSTALL_DIR="${BASE_BUILD_DIR}/install" # 安装目录
PATCH_DIR="${BASE_BUILD_DIR}/patch" # 补丁目录
# 创建所有目录
mkdir -p "${SOURCE_DIR}"
mkdir -p "${BUILD_DIR}"
mkdir -p "${INSTALL_DIR}"
mkdir -p "${PATCH_DIR}"
# 在BUILD_DIR下创建deb/包名目录
DEB_PACKAGE_DIR="${BUILD_DIR}/deb/${base_name}"
mkdir -p "${DEB_PACKAGE_DIR}"
# 创建编译日志文件
BUILD_LOG="${BUILD_DIR}/build.log"
# 安装目录的子目录
DEBIAN_DIR="${INSTALL_DIR}/DEBIAN"
BIN_DIR="${INSTALL_DIR}/usr/bin/"
SYSTEMD_DIR="${INSTALL_DIR}/lib/systemd/system/"
ETC_DIR="${INSTALL_DIR}/etc/bluetooth/"
mkdir -p "${DEBIAN_DIR}"
mkdir -p "${BIN_DIR}"
mkdir -p "${SYSTEMD_DIR}"
mkdir -p "${ETC_DIR}"
}
# Display build directory info
# Parameters:
# $1 - log prefix
function _bluez5_common_display_build_info() {
local log_prefix="$1"
aml_log debug "${log_prefix} Source dir: ${SOURCE_DIR}"
aml_log debug "${log_prefix} Build dir: ${BUILD_DIR}"
aml_log debug "${log_prefix} Install dir: ${INSTALL_DIR}"
aml_log debug "${log_prefix} Patch dir: ${PATCH_DIR}"
aml_log debug "${log_prefix} Deb package dir: ${DEB_PACKAGE_DIR}"
aml_log debug "${log_prefix} Build log: ${BUILD_LOG}"
aml_log debug "${log_prefix} Bin dir: ${BIN_DIR}"
aml_log debug "${log_prefix} Systemd dir: ${SYSTEMD_DIR}"
aml_log debug "${log_prefix} Config dir: ${ETC_DIR}"
}
# ------------------------------------------------------------------------------
# Step 3: Source Download and Extraction
# ------------------------------------------------------------------------------
# Download and extract BlueZ5 source code
function _bluez5_download_and_extract() {
aml_log info "COMPILE-${COMPONENT} Step 1: Downloading BlueZ5 source code"
cd "${BASE_BUILD_DIR}"
# Create cache directory if it does not exist
mkdir -p "${CACHE_SOURCES}"
local SOURCE_TARBALL="bluez-${PKG_VERSION}.tar.xz"
local CACHE_TARBALL="${CACHE_SOURCES}/${SOURCE_TARBALL}"
local LOCAL_TARBALL="${BASE_BUILD_DIR}/${SOURCE_TARBALL}"
# Download source tarball
if [[ ! -f "${CACHE_TARBALL}" ]]; then
aml_log debug "COMPILE-${COMPONENT} Downloading from ${SRC_URL}"
wget -q --show-progress -O "${SOURCE_TARBALL}" "${SRC_URL}" 2>&1 >> "${BUILD_LOG}"
# Verify SHA256 checksum
local calculated_sha=$(sha256sum "${SOURCE_TARBALL}" | cut -d' ' -f1)
if [[ "$calculated_sha" != "$SRC_SHA256" ]]; then
aml_log error "COMPILE-${COMPONENT} SHA256 mismatch: expected $SRC_SHA256, got $calculated_sha"
rm -f "${SOURCE_TARBALL}"
exit 1
fi
cp -f "${SOURCE_TARBALL}" "${CACHE_TARBALL}"
else
cp -f "${CACHE_TARBALL}" "${LOCAL_TARBALL}"
aml_log debug "COMPILE-${COMPONENT} Source tarball already exists, skipping download"
fi
# Extract source
tar -xf "bluez-${PKG_VERSION}.tar.xz" -C "${SOURCE_DIR}" --strip-components=1
aml_log info "COMPILE-${COMPONENT} Source extracted to ${SOURCE_DIR}"
}
# ------------------------------------------------------------------------------
# Step 4: Apply Patches
# ------------------------------------------------------------------------------
# Apply base recipe patches from bluez5.inc
function _bluez5_apply_base_patches() {
aml_log info "COMPILE-${COMPONENT} Step 2: Applying patches from bluez5.inc"
cd "${SOURCE_DIR}"
# Patches defined in bluez5.inc SRC_URI
local patches=(
"0001-Allow-using-obexd-without-systemd-in-the-user-sessio.patch"
"0001-tests-add-a-target-for-building-tests-without-runnin.patch"
"0001-test-gatt-Fix-hung-issue.patch"
"CVE-2023-45866.patch"
"CVE-2023-27349.patch"
"CVE-2023-50229_CVE-2023-50230.patch"
)
# Patch directory from poky
local PATCH_DIR="${SCRIPT_DIR}/files"
# Apply patches
for patch in "${patches[@]}"; do
local patch_file="${PATCH_DIR}/${patch}"
if [[ -f "$patch_file" ]]; then
aml_log info "COMPILE-${COMPONENT} Applying patch: $patch"
# Try patch with -p1 first
if patch -p1 --dry-run < "$patch_file" &> /dev/null; then
patch -p1 < "$patch_file" >> "$BUILD_LOG" 2>&1
aml_log info "COMPILE-${COMPONENT} Patch applied successfully with -p1"
else
# Try with -p0
if patch -p0 --dry-run < "$patch_file" &> /dev/null; then
patch -p0 < "$patch_file" >> "$BUILD_LOG" 2>&1
aml_log info "COMPILE-${COMPONENT} Patch applied successfully with -p0"
else
aml_log warn "COMPILE-${COMPONENT} Failed to apply patch: $patch"
fi
fi
else
aml_log warn "COMPILE-${COMPONENT} Patch file not found: $patch_file"
fi
done
}
# Apply bbappend patches
function _bluez5_apply_bbappend_patches() {
aml_log info "COMPILE-${COMPONENT} Step 3: Applying bbappend patches"
cd "${SOURCE_DIR}"
local PATCH_DIR="${SCRIPT_DIR}/files"
# Apply default_agent patch from bluez5_%.bbappend
local default_agent_patch="${PATCH_DIR}/0000-bluez5-add-default_agent-3-5.patch"
if [[ -f "$default_agent_patch" ]]; then
aml_log info "COMPILE-${COMPONENT} Applying default_agent patch"
if patch -p1 --dry-run < "$default_agent_patch" &> /dev/null; then
patch -p1 < "$default_agent_patch" >> "$BUILD_LOG" 2>&1
aml_log info "COMPILE-${COMPONENT} Default_agent patch applied successfully"
else
aml_log warn "COMPILE-${COMPONENT} Failed to apply default_agent patch"
fi
fi
# Apply always-applied patches from bluez5_5.65.bbappend
local bbappend_patches_565=(
"0001-bluez-remove-bonded-check-in-hog-accept.patch"
"0002-bluez-fix-repeatedly-connect-and-disconnect.patch"
"0003-bluez-fix-rcu-reconnect.patch"
"0004-bluez-fix-pair-interrupt-error.patch"
)
for patch in "${bbappend_patches_565[@]}"; do
local patch_file="${PATCH_DIR}/${patch}"
if [[ -f "$patch_file" ]]; then
aml_log info "COMPILE-${COMPONENT} Applying patch: $patch"
if patch -p1 --dry-run < "$patch_file" &> /dev/null; then
patch -p1 < "$patch_file" >> "$BUILD_LOG" 2>&1
aml_log info "COMPILE-${COMPONENT} Patch applied successfully with -p1"
elif patch -p0 --dry-run < "$patch_file" &> /dev/null; then
patch -p0 < "$patch_file" >> "$BUILD_LOG" 2>&1
aml_log info "COMPILE-${COMPONENT} Patch applied successfully with -p0"
else
aml_log warn "COMPILE-${COMPONENT} Failed to apply patch: $patch"
fi
else
aml_log warn "COMPILE-${COMPONENT} Patch file not found: $patch_file"
fi
done
# Apply conditional patches based on DISTRO_FEATURES
# bt-qca support
if [[ "${DISTRO_FEATURES:-}" == *"bt-qca"* ]]; then
local qca_patch="${PATCH_DIR}/0001-bluez-hciattach-add-qca-support.patch"
if [[ -f "$qca_patch" ]]; then
aml_log info "COMPILE-${COMPONENT} Applying bt-qca patch: 0001-bluez-hciattach-add-qca-support.patch"
if patch -p1 --dry-run < "$qca_patch" &> /dev/null; then
patch -p1 < "$qca_patch" >> "$BUILD_LOG" 2>&1
aml_log info "COMPILE-${COMPONENT} bt-qca patch applied successfully"
else
aml_log warn "COMPILE-${COMPONENT} Failed to apply bt-qca patch"
fi
else
aml_log warn "COMPILE-${COMPONENT} bt-qca patch not found: $qca_patch"
fi
fi
# aml-wifi support
if [[ "${DISTRO_FEATURES:-}" == *"aml-wifi"* ]]; then
local aml_patches=(
"0001-bluez-hciattach-add-aml-support.patch"
"0001-BT-extract-amlbt-fw-log-1-1.patch"
)
for patch in "${aml_patches[@]}"; do
local patch_file="${PATCH_DIR}/${patch}"
if [[ -f "$patch_file" ]]; then
aml_log info "COMPILE-${COMPONENT} Applying aml-wifi patch: $patch"
if patch -p1 --dry-run < "$patch_file" &> /dev/null; then
patch -p1 < "$patch_file" >> "$BUILD_LOG" 2>&1
aml_log info "COMPILE-${COMPONENT} Patch applied successfully"
else
aml_log warn "COMPILE-${COMPONENT} Failed to apply patch: $patch"
fi
else
aml_log warn "COMPILE-${COMPONENT} Patch not found: $patch_file"
fi
done
fi
}
# Copy additional directories from bbappend
function _bluez5_copy_bbappend_directories() {
aml_log info "COMPILE-${COMPONENT} Step 4: Copying bbappend directories"
local FILES_DIR="${SCRIPT_DIR}/files"
# Copy client/ directory (from bluez5_%.bbappend do_compile:prepend)
local client_src="${FILES_DIR}/client"
if [[ -d "$client_src" ]]; then
aml_log info "COMPILE-${COMPONENT} Copying client/ directory to source"
cp -rf "${client_src}/"* "${SOURCE_DIR}/client/"
aml_log info "COMPILE-${COMPONENT} Client files copied successfully"
else
aml_log warn "COMPILE-${COMPONENT} Client directory not found: $client_src"
fi
# Copy tools/ directory (from bluez5_5.65.bbappend do_compile:prepend)
local tools_src="${FILES_DIR}/tools"
if [[ -d "$tools_src" ]]; then
aml_log info "COMPILE-${COMPONENT} Copying tools/ directory to source"
install -d "${SOURCE_DIR}/tools"
cp -rf "${tools_src}/"* "${SOURCE_DIR}/tools/"
aml_log info "COMPILE-${COMPONENT} Tools files copied successfully"
else
aml_log warn "COMPILE-${COMPONENT} Tools directory not found: $tools_src"
fi
# Copy monitor/ directory (from bluez5_5.65.bbappend do_compile:prepend, conditional on aml-wifi)
local monitor_src="${FILES_DIR}/monitor"
if [[ -d "$monitor_src" ]]; then
aml_log info "COMPILE-${COMPONENT} Copying monitor/ directory to source (aml-wifi)"
install -d "${SOURCE_DIR}/monitor"
cp -rf "${monitor_src}/"* "${SOURCE_DIR}/monitor/"
aml_log info "COMPILE-${COMPONENT} Monitor files copied successfully"
else
aml_log warn "COMPILE-${COMPONENT} Monitor directory not found: $monitor_src"
fi
}
# ------------------------------------------------------------------------------
# Step 5: Configure Build
# ------------------------------------------------------------------------------
# Configure BlueZ5 build
function _bluez5_configure_build() {
aml_log info "COMPILE-${COMPONENT} Step 5: Configuring BlueZ build"
cd "${SOURCE_DIR}"
# Clean previous build
if [[ -f "Makefile" ]]; then
aml_log info "COMPILE-${COMPONENT} Clean build"
make distclean >> "$BUILD_LOG" 2>&1 || true
fi
# 设置编译环境
: "${ARCH:=arm64}"
CROSS_COMPILE="${CROSS_COMPILE:-aarch64-linux-gnu-}"
export ARCH
export CROSS_COMPILE="${CROSS_COMPILE}"
autoreconf -fi
# Check if ROOTFS_TEMP exists, use it as sysroot, otherwise error
SYSROOT=""
if [[ -n "${ROOTFS_TEMP}" ]] && [[ -d "${ROOTFS_TEMP}" ]] && [[ -d "${ROOTFS_TEMP}/usr/lib/aarch64-linux-gnu" ]]; then
SYSROOT="${ROOTFS_TEMP}"
aml_log info "COMPILE-${COMPONENT}" "Using ROOTFS_TEMP as sysroot: ${SYSROOT}"
else
aml_log error "COMPILE-${COMPONENT}" "ROOTFS_TEMP not found or invalid: ${ROOTFS_TEMP}"
aml_log error "COMPILE-${COMPONENT}" "ROOTFS_TEMP should be created by create_base_rootfs function"
return 1
fi
mkdir -p $SYSROOT/usr/lib
# 软链接(关键)
ln -sf $SYSROOT/usr/lib/aarch64-linux-gnu/crti.o $SYSROOT/usr/lib/crti.o
ln -sf $SYSROOT/usr/lib/aarch64-linux-gnu/crtn.o $SYSROOT/usr/lib/crtn.o
ln -sf $SYSROOT/usr/lib/aarch64-linux-gnu/crt1.o $SYSROOT/usr/lib/crt1.o
# 构建所有配置选项
local all_configure_opts=()
# Base configure options from bluez5.inc
local base_opts=(
"--prefix=/usr"
"--sysconfdir=/etc"
"--localstatedir=/var"
"--mandir=/usr/share/man"
"--enable-test"
"--enable-datafiles"
"--enable-library"
"--without-zsh-completion-dir"
"--disable-manpages"
)
all_configure_opts+=("${base_opts[@]}")
# PACKAGECONFIG options (default from bluez5.inc)
local packagenconfig=(
"obex-profiles"
"readline"
"a2dp-profiles"
"avrcp-profiles"
"network-profiles"
"hid-profiles"
"hog-profiles"
"tools"
"deprecated"
"udev"
"systemd"
)
# Process PACKAGECONFIG options
for config in "${packagenconfig[@]}"; do
case "$config" in
"obex-profiles") all_configure_opts+=("--enable-obex") ;;
"readline") all_configure_opts+=("--enable-client") ;;
"systemd") all_configure_opts+=("--enable-systemd") ;;
"a2dp-profiles") all_configure_opts+=("--enable-a2dp") ;;
"avrcp-profiles") all_configure_opts+=("--enable-avrcp") ;;
"network-profiles") all_configure_opts+=("--enable-network") ;;
"hid-profiles") all_configure_opts+=("--enable-hid") ;;
"hog-profiles") all_configure_opts+=("--enable-hog") ;;
"tools") all_configure_opts+=("--enable-tools") ;;
"deprecated") all_configure_opts+=("--enable-deprecated") ;;
"udev") all_configure_opts+=("--enable-udev") ;;
esac
done
# Apply PACKAGECONFIG removals from bluez5_5.65.bbappend
# Remove a2dp-profiles and avrcp-profiles if bt-audio not in DISTRO_FEATURES
if [[ "${DISTRO_FEATURES:-}" != *"bt-audio"* ]]; then
# 从数组中移除对应的选项
for i in "${!all_configure_opts[@]}"; do
if [[ "${all_configure_opts[i]}" == "--enable-a2dp" ]] || [[ "${all_configure_opts[i]}" == "--enable-avrcp" ]]; then
unset 'all_configure_opts[i]'
fi
done
# 重新索引数组
all_configure_opts=("${all_configure_opts[@]}")
aml_log info "COMPILE-${COMPONENT} Removed a2dp-profiles and avrcp-profiles (bt-audio not enabled)"
fi
# Remove obex-profiles if obexd not in DISTRO_FEATURES
if [[ "${DISTRO_FEATURES:-}" != *"obexd"* ]]; then
for i in "${!all_configure_opts[@]}"; do
if [[ "${all_configure_opts[i]}" == "--enable-obex" ]]; then
unset 'all_configure_opts[i]'
fi
done
all_configure_opts=("${all_configure_opts[@]}")
aml_log info "COMPILE-${COMPONENT} Removed obex-profiles (obexd not enabled)"
fi
# Remove network-profiles if bt-network not in DISTRO_FEATURES
if [[ "${DISTRO_FEATURES:-}" != *"bt-network"* ]]; then
for i in "${!all_configure_opts[@]}"; do
if [[ "${all_configure_opts[i]}" == "--enable-network" ]]; then
unset 'all_configure_opts[i]'
fi
done
all_configure_opts=("${all_configure_opts[@]}")
aml_log info "COMPILE-${COMPONENT} Removed network-profiles (bt-network not enabled)"
fi
export PKG_CONFIG=/usr/bin/pkg-config
export PKG_CONFIG_SYSROOT_DIR="${SYSROOT}"
export PKG_CONFIG_LIBDIR="${SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig:${SYSROOT}/usr/share/pkgconfig"
unset PKG_CONFIG_PATH
# Set up flags with sysroot
export CPPFLAGS="${CPPFLAGS} --sysroot=${SYSROOT}"
# Add standard library definitions to avoid C23 issues
export CFLAGS="${CFLAGS} --sysroot=${SYSROOT} -fPIC"
export CXXFLAGS="${CXXFLAGS} --sysroot=${SYSROOT} -fPIC"
# Add sysroot-specific include paths
local include_flags="-I${SYSROOT}/usr/include/aarch64-linux-gnu \
-I${SYSROOT}/usr/include/glib-2.0 \
-I${SYSROOT}/usr/lib/aarch64-linux-gnu/glib-2.0/include"
export CPPFLAGS="${CPPFLAGS} ${include_flags}"
export CFLAGS="${CFLAGS} ${include_flags}"
export CXXFLAGS="${CXXFLAGS} ${include_flags}"
export LIBS="${LIBS} -ltinfo"
# Add sysroot-specific library paths with required libraries
export LDFLAGS="${LDFLAGS} --sysroot=${SYSROOT} \
-L${SYSROOT}/usr/lib/aarch64-linux-gnu \
-L${SYSROOT}/lib/aarch64-linux-gnu \
-Wl,-rpath-link=${SYSROOT}/usr/lib/aarch64-linux-gnu \
-Wl,-rpath-link=${SYSROOT}/lib/aarch64-linux-gnu \
-lpcre2-8 -lm -lsystemd -lncurses -ltinfo"
# 处理 CONFIGURE_ARGS(如果有额外的配置参数)
local extra_args=""
if [[ -n "${CONFIGURE_ARGS:-}" ]]; then
extra_args="${CONFIGURE_ARGS}"
aml_log info "COMPILE-${COMPONENT}" "Additional configure args: ${extra_args}"
fi
# Run configure
aml_log info "COMPILE-${COMPONENT} Configure options" "${all_configure_opts[*]} ${extra_args}"
./configure \
"${all_configure_opts[@]}" \
--host=aarch64-linux-gnu \
--build=x86_64-linux-gnu \
--libdir=/usr/lib/aarch64-linux-gnu \
PKG_CONFIG=/usr/bin/pkg-config \
CC="${CROSS_COMPILE}gcc" \
CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" \
${extra_args} \
2>&1 || {
aml_log error "COMPILE-${COMPONENT} configure failed"
return 1
}
aml_log info "COMPILE-${COMPONENT} Configuration successful"
}
# ------------------------------------------------------------------------------
# Step 6: Compile BlueZ5
# ------------------------------------------------------------------------------
# Compile BlueZ5
function _bluez5_compile() {
aml_log info "COMPILE-${COMPONENT} Step 6: Compiling BlueZ"
# Compile
aml_log info "COMPILE-${COMPONENT} Building with $(nproc) parallel jobs LDFLAGS ${LDFLAGS} CFLAGS ${CFLAGS}"
make CC="${CROSS_COMPILE}gcc" \
CFLAGS="${CFLAGS}" \
LDFLAGS="${LDFLAGS}" \
ARCH="${PKG_ARCH}" \
-j$(nproc) \
all 2>&1
if [[ $? -ne 0 ]]; then
aml_log error "COMPILE-${COMPONENT} Compilation failed, check $BUILD_LOG"
exit 1
fi
aml_log info "COMPILE-${COMPONENT} Compilation successful"
}
# ------------------------------------------------------------------------------
# Step 7: Install Files
# ------------------------------------------------------------------------------
# Install base recipe files
function _bluez5_install_base() {
aml_log info "COMPILE-${COMPONENT} Step 7: Installing BlueZ (base recipe)"
# Install to staging directory
mkdir -p "${INSTALL_DIR}"
make install DESTDIR="${INSTALL_DIR}" \
CC="${CROSS_COMPILE}gcc" \
CFLAGS="" \
LDFLAGS="" \
DBUS_CONFDIR="/etc" \
DBUS_SESSIONBUSDIR="/usr/share/dbus-1/services" \
DBUS_SYSTEMBUSDIR="/usr/share/dbus-1/system-services" \
SYSTEMD_SYSTEMUNITDIR="/lib/systemd/system" \
SYSTEMD_USERUNITDIR="/usr/lib/systemd/user" \
UDEV_DIR="/lib/udev" \
>> "$BUILD_LOG" 2>&1
}
# Install bbappend extra files
function _bluez5_install_bbappend_files() {
aml_log info "COMPILE-${COMPONENT} Step 7b: Installing bbappend extra files"
# Create necessary directories
install -d "${INSTALL_DIR}/usr/bin"
install -d "${INSTALL_DIR}/lib/systemd/system"
install -d "${INSTALL_DIR}/etc/bluetooth"
# Install default_agent binary
if [[ -f "${SOURCE_DIR}/client/default_agent" ]]; then
install -m 0755 "${SOURCE_DIR}/client/default_agent" "${INSTALL_DIR}/usr/bin/"
aml_log info "COMPILE-${COMPONENT} Installed: default_agent -> /usr/bin/"
else
aml_log warn "COMPILE-${COMPONENT} default_agent binary not found in build output"
fi
# Install bluez_tool.sh
local bluez_tool_src="${FILES_DIR}/bluez_tool.sh"
if [[ -f "$bluez_tool_src" ]]; then
install -m 0755 "$bluez_tool_src" "${INSTALL_DIR}/usr/bin/"
aml_log info "COMPILE-${COMPONENT} Installed: bluez_tool.sh -> /usr/bin/"
else
aml_log warn "COMPILE-${COMPONENT} bluez_tool.sh not found: $bluez_tool_src"
fi
# Install bluez.service
local bluez_service_src="${FILES_DIR}/bluez.service"
if [[ -f "$bluez_service_src" ]]; then
install -m 0644 "$bluez_service_src" "${INSTALL_DIR}/lib/systemd/system/"
aml_log info "COMPILE-${COMPONENT} Installed: bluez.service -> /lib/systemd/system/"
else
aml_log warn "COMPILE-${COMPONENT} bluez.service not found: $bluez_service_src"
fi
# Install main.conf
local main_conf_src="${FILES_DIR}/main.conf"
if [[ -f "$main_conf_src" ]]; then
install -m 0644 "$main_conf_src" "${INSTALL_DIR}/etc/bluetooth/"
aml_log info "COMPILE-${COMPONENT} Installed: main.conf -> /etc/bluetooth/"
else
aml_log warn "COMPILE-${COMPONENT} main.conf not found: $main_conf_src"
fi
# Modify main.conf based on DISTRO_FEATURES
local main_conf_installed="${INSTALL_DIR}/etc/bluetooth/main.conf"
if [[ -f "$main_conf_installed" ]]; then
# Determine Device type based on DISTRO_FEATURES
if [[ "${DISTRO_FEATURES:-}" == *"aml-wifi"* ]]; then
sed -i '/Debug/a Device=aml' "$main_conf_installed"
aml_log info "COMPILE-${COMPONENT} main.conf: Device=aml (aml-wifi enabled)"
elif [[ "${DISTRO_FEATURES:-}" == *"bt-qca"* ]]; then
sed -i '/Debug/a Device=qca' "$main_conf_installed"
aml_log info "COMPILE-${COMPONENT} main.conf: Device=qca (bt-qca enabled)"
elif [[ "${DISTRO_FEATURES:-}" == *"bt-bcm"* ]]; then
sed -i '/Debug/a Device=bcm' "$main_conf_installed"
aml_log info "COMPILE-${COMPONENT} main.conf: Device=bcm (bt-bcm enabled)"
else
sed -i '/Debug/a Device=rtk' "$main_conf_installed"
aml_log info "COMPILE-${COMPONENT} main.conf: Device=rtk (default)"
fi
# Add TTY setting
sed -i "/Debug/a TTY=/dev/${TTY}" "$main_conf_installed"
aml_log info "COMPILE-${COMPONENT} main.conf: TTY=/dev/${TTY}"
fi
# Modify bluetooth.service
local bluetooth_service_installed="${INSTALL_DIR}/lib/systemd/system/bluetooth.service"
if [[ -f "$bluetooth_service_installed" ]]; then
# Add EnvironmentFile before ExecStart
sed -i "/ExecStart/i EnvironmentFile=-/etc/aml-wifi-debug.d/bt.env" "$bluetooth_service_installed"
# Modify ExecStart to use $BLUETOOTHD_EXT_ARGS
sed -i 's|^ExecStart=/usr/libexec/bluetooth/bluetoothd.*|ExecStart=/usr/libexec/bluetooth/bluetoothd $BLUETOOTHD_EXT_ARGS|' "$bluetooth_service_installed"
aml_log info "COMPILE-${COMPONENT} bluetooth.service: Added EnvironmentFile and modified ExecStart"
fi
}
# Install NOINST_TOOLS
function _bluez5_install_noinst_tools() {
aml_log info "COMPILE-${COMPONENT} Step 8: Installing NOINST_TOOLS"
# NOINST_TOOLS definitions from bluez5_5.65.bb
local noinst_tools=(
"tools/bdaddr"
"tools/btinfo"
"tools/btsnoop"
"tools/btproxy"
)
for tool in "${noinst_tools[@]}"; do
if [[ -f "${SOURCE_DIR}/$tool" ]]; then
install -m 0755 "${SOURCE_DIR}/$tool" "${INSTALL_DIR}/usr/bin/"
aml_log info "COMPILE-${COMPONENT} Installed NOINST_TOOL: $(basename "$tool") -> /usr/bin/"
fi
done
}
# Install additional files from bluez5.inc
function _bluez5_install_additional_files() {
aml_log info "COMPILE-${COMPONENT} Step 9: Installing additional files from bluez5.inc"
# Create bluetooth config directory
mkdir -p "${INSTALL_DIR}/etc/bluetooth"
# Install network.conf if it exists
if [[ -f "${SOURCE_DIR}/profiles/network/network.conf" ]]; then
install -m 0644 "${SOURCE_DIR}/profiles/network/network.conf" "${INSTALL_DIR}/etc/bluetooth/"
aml_log info "COMPILE-${COMPONENT} Installed: network.conf -> /etc/bluetooth/"
fi
# Install input.conf if it exists
if [[ -f "${SOURCE_DIR}/profiles/input/input.conf" ]]; then
install -m 0644 "${SOURCE_DIR}/profiles/input/input.conf" "${INSTALL_DIR}/etc/bluetooth/"
aml_log info "COMPILE-${COMPONENT} Installed: input.conf -> /etc/bluetooth/"
fi
}
# ------------------------------------------------------------------------------
# Step 8: Create Debian Package
# ------------------------------------------------------------------------------
# Create Debian control file
function _bluez5_create_control_file() {
aml_log info "COMPILE-${COMPONENT} Step 10: Creating Debian package"
# Build RDEPENDS string based on bbappend logic
local rdepends="libc6, libdbus-1-3, libglib2.0-0"
# # Add amlogic-hciattach if aml-wifi enabled
# if [[ "${DISTRO_FEATURES:-}" == *"aml-wifi"* ]]; then
# rdepends="${rdepends}, amlogic-hciattach"
# aml_log info "COMPILE-${COMPONENT} Added RDEPENDS: amlogic-hciattach (aml-wifi enabled)"
# fi
# Add aml-wifi-common if MACHINE_EXTRA_RRECOMMENDS contains wifi modules
if [[ -n "$MACHINE_EXTRA_RRECOMMENDS" ]]; then
if echo "$MACHINE_EXTRA_RRECOMMENDS" | grep -q -E '\b(aml-wifi-w1|aml-wifi-w1u|aml-wifi-w2)\b'; then
rdepends="${rdepends}, aml-wifi-common"
aml_log info "COMPILE-${COMPONENT} Added RDEPENDS: aml-wifi-common (MACHINE_EXTRA_RRECOMMENDS contains wifi modules)"
fi
fi
# Create control file
aml_log info "COMPILE-${COMPONENT} Creating control file DEBIAN/control"
cat > "${DEBIAN_DIR}/control" << EOF
Package: ${PKG_NAME}
Version: ${PKG_VERSION}
Architecture: ${PKG_ARCH}
Maintainer: ${PKG_MAINTAINER}
Depends: ${rdepends}
Section: net
Priority: optional
Description: ${PKG_DESCRIPTION}
BlueZ is the official Linux Bluetooth protocol stack. It is an Open Source
project distributed under GNU General Public License (GPL).
.
This package contains BlueZ 5.65 with Amlogic-specific modifications:
- Amlogic wifi support (aml-wifi)
- Device-specific configuration (aml/qca/bcm/rtk)
- Additional tools and utilities
- Systemd service integration with bluez.service
.
Features enabled: ${DISTRO_FEATURES}
EOF
}
# Create post-installation script
function _bluez5_create_postinst() {
aml_log info "COMPILE-${COMPONENT} Creating post-installation script: DEBIAN/postinst"
cat > "${DEBIAN_DIR}/postinst" << EOF
#!/bin/bash
set -e
if [ "\$1" = "configure" ]; then
# Reload systemd daemon
if command -v systemctl >/dev/null 2>&1; then
systemctl daemon-reload 2>/dev/null || true
fi
# Create runtime directories
mkdir -p /var/lib/bluetooth
chmod 0755 /var/lib/bluetooth
# Set up bluez.service (from bbappend SYSTEMD_SERVICE)
if [ -f /lib/systemd/system/bluez.service ]; then
# Disable auto-enable as per bbappend SYSTEMD_AUTO_ENABLE
systemctl disable bluez.service 2>/dev/null || true
echo "BlueZ service (bluez.service) is installed but auto-enable is disabled"
echo "To enable manually: systemctl enable bluez.service"
fi
echo "BlueZ 5.65 (Amlogic modified) installed successfully"
echo "Configuration files are located in /etc/bluetooth/"
echo "Device type: \$(grep '^Device=' /etc/bluetooth/main.conf 2>/dev/null | cut -d= -f2 || echo 'not set')"
fi
exit 0
EOF
chmod 755 "${DEBIAN_DIR}/postinst"
}
# Create pre-removal script
function _bluez5_create_prerm() {
aml_log info "COMPILE-${COMPONENT} Creating pre-removal script: DEBIAN/prerm"
cat > "${DEBIAN_DIR}/prerm" << EOF
#!/bin/bash
set -e
if [ "\$1" = "remove" ] || [ "\$1" = "deconfigure" ]; then
# Stop bluetooth service
if command -v systemctl >/dev/null 2>&1; then
systemctl stop bluetooth 2>/dev/null || true
systemctl disable bluetooth 2>/dev/null || true
systemctl stop bluez.service 2>/dev/null || true
systemctl disable bluez.service 2>/dev/null || true
fi
fi
exit 0
EOF
chmod 755 "${DEBIAN_DIR}/prerm"
}
# Build Debian package
function _bluez5_build_deb_package() {
# 将install目录内容拷贝到deb目录
aml_log info "COMPILE-${COMPONENT} Copying install directory to deb package directory"
echo "Copying install directory to deb package directory at $(date)" >> "${BUILD_LOG}"
cp -r "${INSTALL_DIR}/"* "${DEB_PACKAGE_DIR}/" 2>&1 >> "${BUILD_LOG}"
# 基于deb目录打包
aml_log info "COMPILE-${COMPONENT} Building Debian package"
echo "Building Debian package at $(date)" >> "${BUILD_LOG}"
dpkg-deb --build "${DEB_PACKAGE_DIR}" 2>&1 >> "${BUILD_LOG}"
if [[ $? -ne 0 ]]; then
aml_log error "COMPILE-${COMPONENT} Package build failed"
exit 1
fi
# 移动生成的deb包到输出目录
OUTPUT_DEB="${SRC}/output/${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}.deb"
mkdir -p "$(dirname "${OUTPUT_DEB}")"
mv "${DEB_PACKAGE_DIR}.deb" "${OUTPUT_DEB}"
cp -r "${BASE_BUILD_DIR}" "${AMLBIAN_DIR}/.tmp"
chown -R --reference="${AMLBIAN_DIR}" "${AMLBIAN_DIR}/.tmp"
aml_log info "COMPILE-${COMPONENT} BlueZ5 package built successfully: ${OUTPUT_DEB}"
aml_log info "COMPILE-${COMPONENT} Build directories preserved:"
aml_log info "COMPILE-${COMPONENT} Source: ${SOURCE_DIR}"
aml_log info "COMPILE-${COMPONENT} Build: ${BUILD_DIR}"
aml_log info "COMPILE-${COMPONENT} Install: ${INSTALL_DIR}"
aml_log info "COMPILE-${COMPONENT} Patch: ${PATCH_DIR}"
aml_log info "COMPILE-${COMPONENT} Deb package: ${DEB_PACKAGE_DIR}"
}
# ==============================================================================
# Main BlueZ5 Build Function
# ==============================================================================
# Generic BlueZ5 package build function
function amlbian_build_bluez5App() {
set -e
# ---- Step 1: Version and Package Information ----
_bluez5_init_package_info
aml_log info "COMPILE-${COMPONENT} Building BlueZ5 version ${PKG_VERSION} for ${PKG_ARCH}"
aml_log info "COMPILE-${COMPONENT} Features: ${DISTRO_FEATURES}"
# ---- Step 2: Build Directory Setup ----
_bluez5_common_create_build_dirs "${PKG_NAME}_${PKG_VERSION}_${PKG_ARCH}"
_bluez5_common_display_build_info "COMPILE-${COMPONENT}"
# ---- Step 3: Source Download and Extraction ----
_bluez5_download_and_extract
# ---- Step 4: Apply Patches ----
_bluez5_apply_base_patches
_bluez5_apply_bbappend_patches
_bluez5_copy_bbappend_directories
# ---- Step 5: Configure Build ----
_bluez5_configure_build
# ---- Step 6: Compile BlueZ5 ----
_bluez5_compile
# ---- Step 7: Install Files ----
_bluez5_install_base
_bluez5_install_bbappend_files
_bluez5_install_noinst_tools
_bluez5_install_additional_files
# ---- Step 8: Debian Packaging Scripts ----
_bluez5_create_control_file
_bluez5_create_postinst
_bluez5_create_prerm
# ---- Step 9: Build Debian Package ----
_bluez5_build_deb_package
display_alert "COMPILE-${COMPONENT} BlueZ5 build completed. Successfully built for ${PKG_ARCH}" "success"
aml_log info "COMPILE-${COMPONENT} Features: ${DISTRO_FEATURES}"
return 0
}
function amlbian_build_bluez5() {
if ! is_unit_enabled "bt" || [ "${BT_BLUEZ:-}" != "yes" ]; then
echo "[SKIP] >> Bluetooth disabled in BUILD_UNITS or BT_BLUEZ not yes"
return
fi
amlbian_build_bluez5App
}
# ==============================================================================
# Main Execution
# ==============================================================================
aml_log info "AMLbian bulez5 Build Script" "Starting Bt build"
amlbian_build_bluez5
aml_log info "AMLOGIC: bulez5 build completed" "Check output directory for packages"