diff --git a/README.md b/README.md index 0f42a57..f7a4cd1 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,37 @@ device (SD/eMMC card or USB/SATA disk) on target board or on host machine. ## Build Environment -------------------- +- Docker-free build with local ARM GNU Toolchain - Cross-build in Debian Docker container hosted on x86 Ubuntu or any other distro for arm64 target - Cross-build on x86 host machine running Debian 12 for arm64 target - Native-build on ARM board running Debian for arm64 target ## Host system requirement + +### Docker-Free Build (Recommended) +This fork supports building without Docker by using a locally downloaded ARM GNU Toolchain. +No root access or Docker installation required! + +```bash +# One-time toolchain setup (downloads ~500MB ARM GCC toolchain) +bld toolchain-setup + +# Or manually: +./tools/toolchain_manager setup + +# Check toolchain status +bld toolchain-check +``` + +The toolchain will be automatically downloaded to `flexbuild/toolchain/` directory. +Supported GCC versions: 11.x, 12.x, 13.x, 14.x (default: 13.3.rel1) + +### Docker-based Build (Alternative) - Docker hosted on Ubuntu LTS host (e.g. 22.04, 20.04) or other any distro Refer to [docker-setup](docs/FAQ-docker-setup.md) User can run 'bld docker' to create a Debian docker and build it in docker. -- Debian 12 host + +### Debian 12 Host Refer to [host_requirement](docs/host_requirement.md) @@ -82,6 +104,7 @@ Most used example with separate command: bld apps -r debian:server -p LS # compile NXP-specific components against the runtime dependencies of Debian Server rootfs for LS machines bld ml [ -r ] # compile NXP-specific eIQ AI/ML components against the library dependencies of Debian rootfs bld merge-apps [ -r ] # merge NXP-specific components into target Debian rootfs (Desktop by default,add '-r debian:server' for Server) + bld merge-bootpart-rfs [ -r ] # merge boot partition files into target Debian rootfs bld create_recovery_sdcard_image # Create Variscite recovery sd card (IMAGE_SIZE=5G IMAGE_NAME=example.img) bld packrfs [ -r ] # pack and compress target rootfs as rootfs_xx.tar.zst (or add '-r debian:server' for Server) bld packapps [ -r ] # pack and compress target app components as apps_xx.tar.zst (add '-p LS' for Layerscape platforms) @@ -95,6 +118,8 @@ Most used example with separate command: bld clean-linux # clean obsolete linux image bld list # list enabled machines and supported various components bld host-dep # automatically install the depended deb packages on host + bld toolchain-setup # download and setup local ARM toolchain (no Docker needed!) + bld toolchain-check # check if local toolchain is installed ``` ## More info diff --git a/configs/sdk-var.yml b/configs/sdk-var.yml index 23bf4e8..b9c35f7 100644 --- a/configs/sdk-var.yml +++ b/configs/sdk-var.yml @@ -33,8 +33,16 @@ PKG_GROUPS_ROBOTICS: n # default IMX if '-p' option is not specified, change to LS for Layerscape SoC DEFAULT_SOC_FAMILY: IMX -# force build in docker environment -FORCE_BUILD_IN_DOCKER: y +# force build in docker environment (set to 'n' when using local toolchain) +FORCE_BUILD_IN_DOCKER: n + +# Local toolchain configuration (eliminates Docker requirement) +# Run 'bld toolchain-setup' or './tools/toolchain_manager setup' to download +# Supported versions: 11.3.rel1, 12.2.rel1, 12.3.rel1, 13.2.rel1, 13.3.rel1 +# NXP officially supports GCC 11.x, 12.x, 13.x - use 13.3.rel1 for best compatibility +USE_LOCAL_TOOLCHAIN: y +TOOLCHAIN_VERSION: "13.3.rel1" +TOOLCHAIN_DIR: $FBDIR/toolchain # choose one of the 3 ways to fetch/update repo for various use cases UPDATE_REPO_PER_TAG: y @@ -82,7 +90,7 @@ repo: # BSP component repositories atf: url: https://github.com/varigit/imx-atf.git - commit: bed39c167c883b335d5fc1046ce16e10a611b4c4 + commit: 3b57a2b9cc3bb103f7ed5d044b1d1a8fcf3a42f6 uboot: url: https://github.com/varigit/uboot-imx.git diff --git a/tools/distro_debian b/tools/distro_debian index fcf2593..cf4d09c 100644 --- a/tools/distro_debian +++ b/tools/distro_debian @@ -57,7 +57,7 @@ build_distro_rfs_debian() { fi # clean cached packages - rm -f $RFSDIR/etc/resolv.conf + $sudopt rm -f $RFSDIR/etc/resolv.conf $sudopt chroot $RFSDIR apt clean $sudopt chroot $RFSDIR apt autoclean $sudopt chroot $RFSDIR apt autoremove -y diff --git a/tools/flex-builder b/tools/flex-builder index 9a98bd3..d4b9da5 100755 --- a/tools/flex-builder +++ b/tools/flex-builder @@ -42,6 +42,8 @@ Most used example with separate command: bld packrfs [ -r ] # pack and compress target rootfs as rootfs_xx.tar.zst (or add '-r debian:server' for Server) bld packapps [ -r ] # pack and compress target app components as apps_xx.tar.zst (add '-p LS' for Layerscape platforms) bld repo-fetch [ ] # fetch git repository of all or specified component from remote repos if not exist locally + bld toolchain-setup # download and setup local ARM toolchain (no Docker needed!) + bld toolchain-check # check if local toolchain is installed bld docker # create or attach docker container to build in docker bld docker-clean # stop and remove the docker container bld clean # clean all obsolete firmware/linux/apps binary images except distro rootfs @@ -65,31 +67,79 @@ EOF check_toolchain() { - tc_version='11.x or 12.x or 13.x' + # Supported toolchain versions (local or system) + tc_version='11.x or 12.x or 13.x or 14.x' + + # Check for local toolchain first (downloaded via toolchain_manager) + TOOLCHAIN_DIR="${TOOLCHAIN_DIR:-$FBDIR/toolchain}" + LOCAL_TOOLCHAIN_BIN="$TOOLCHAIN_DIR/bin" + if [ $DESTARCH = arm32 ] && [ $HOSTARCH = x86_64 -o $HOSTARCH = aarch64 -o $HOSTARCH = i686 ]; then + # Try local toolchain first + if [ -f "$LOCAL_TOOLCHAIN_BIN/arm-linux-gnueabihf-gcc" ]; then + gccversion=$("$LOCAL_TOOLCHAIN_BIN/arm-linux-gnueabihf-gcc" --version | head -1 | cut -d' ' -f4) + fbprint_n "Using local ARM32 toolchain: $gccversion" + export PATH="$LOCAL_TOOLCHAIN_BIN:$PATH" + export ARCH=arm + export CROSS_COMPILE=arm-linux-gnueabihf- + return 0 + fi + + # Fall back to system toolchain [ -f /usr/bin/arm-linux-gnueabihf-gcc ] && gccversion=$(arm-linux-gnueabihf-gcc --version | head -1 | cut -d' ' -f4) || gccversion=0 if [ $gccversion = 0 ]; then + # Offer to download local toolchain instead of system install + if [ "$USE_LOCAL_TOOLCHAIN" = y ] || [ "$FORCE_LOCAL_TOOLCHAIN" = y ]; then + fbprint_w "Local toolchain not found. Run: ./tools/toolchain_manager setup" + exit 1 + fi fbprint_w "Installing toolchain for arm32 ..." + fbprint_w "TIP: For Docker-free builds, run: ./tools/toolchain_manager setup" sudo apt-get install -y crossbuild-essential-armhf gcc-arm-linux-gnueabihf cpp-arm-linux-gnueabihf g++-arm-linux-gnueabihf elif ! echo $tc_version | grep -q `echo $gccversion|cut -d. -f1` && [ $DISTROTYPE != buildroot ]; then - fbprint_w "Please build on Debian $DEBIAN_VERSION host or build in docker (run 'bld docker') to use the verified toolchain" - exit + fbprint_w "System toolchain version $gccversion may cause issues." + fbprint_w "TIP: For verified toolchain without Docker, run: ./tools/toolchain_manager setup" + if [ "$FORCE_LOCAL_TOOLCHAIN" = y ]; then + exit 1 + fi fi export ARCH=arm export CROSS_COMPILE=arm-linux-gnueabihf- + elif [ $DESTARCH = arm64 ] && [ $HOSTARCH = x86_64 -o $HOSTARCH = armv7l -o $HOSTARCH = i686 ]; then + # Try local toolchain first + if [ -f "$LOCAL_TOOLCHAIN_BIN/aarch64-linux-gnu-gcc" ]; then + gccversion=$("$LOCAL_TOOLCHAIN_BIN/aarch64-linux-gnu-gcc" --version | head -1 | cut -d' ' -f4) + fbprint_n "Using local ARM64 toolchain: $gccversion" + export PATH="$LOCAL_TOOLCHAIN_BIN:$PATH" + export ARCH=arm64 + export CROSS_COMPILE=aarch64-linux-gnu- + return 0 + fi + + # Fall back to system toolchain [ -f /usr/bin/aarch64-linux-gnu-gcc ] && gccversion=$(aarch64-linux-gnu-gcc --version | head -1 | cut -d' ' -f4) || gccversion=0 if [ $gccversion = 0 ]; then + # Offer to download local toolchain instead of system install + if [ "$USE_LOCAL_TOOLCHAIN" = y ] || [ "$FORCE_LOCAL_TOOLCHAIN" = y ]; then + fbprint_w "Local toolchain not found. Run: ./tools/toolchain_manager setup" + exit 1 + fi fbprint_w "Installing toolchain for arm64 ..." + fbprint_w "TIP: For Docker-free builds, run: ./tools/toolchain_manager setup" sudo apt-get install -y crossbuild-essential-arm64 gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu elif ! echo $tc_version | grep -q `echo $gccversion | cut -d. -f1` && [ $DISTROTYPE != buildroot ]; then - fbprint_w "The existing toolchain version $gccversion on this host may result in build failure for some components." - fbprint_w "Please build on Debian $DEBIAN_VERSION or Ubuntu 22.04 host or build in docker (run 'bld docker') to use the verified toolchain version $tc_version" - exit + fbprint_w "System toolchain version $gccversion may cause issues." + fbprint_w "TIP: For verified toolchain without Docker, run: ./tools/toolchain_manager setup" + if [ "$FORCE_LOCAL_TOOLCHAIN" = y ]; then + exit 1 + fi fi export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- + elif [ $HOSTARCH = aarch64 -o $HOSTARCH = armv7l ]; then + # Native compilation on ARM if [ $DESTARCH = arm32 ]; then export ARCH=arm elif [ $DESTARCH = arm64 ]; then @@ -720,9 +770,28 @@ check_proxy() { } check_debian_version() { + # Skip Debian version check if local toolchain exists (regardless of USE_LOCAL_TOOLCHAIN setting) + TOOLCHAIN_DIR="${TOOLCHAIN_DIR:-$FBDIR/toolchain}" + if [ -d "$TOOLCHAIN_DIR/bin" ] && [ -f "$TOOLCHAIN_DIR/bin/aarch64-linux-gnu-gcc" ]; then + fbprint_n "Local toolchain detected, skipping Debian version check" + check_binfmt_qemu 2>/dev/null || true + return 0 + fi + + # Also skip if USE_LOCAL_TOOLCHAIN is set (toolchain will be downloaded on demand) + if [ "$USE_LOCAL_TOOLCHAIN" = y ]; then + fbprint_n "USE_LOCAL_TOOLCHAIN=y, toolchain will be downloaded if needed" + check_binfmt_qemu 2>/dev/null || true + return 0 + fi + if [[ ! -f /etc/os-release ]] || [[ ! `cat /etc/issue | grep -iE '^Debian GNU/Linux 12'` ]]; then if [ "$FORCE_BUILD_IN_DOCKER" = y -a "$FORCE" != y ]; then - fbprint_w "The host is not Debian 12 system, please install docker (refer to docs/FAQ-docker-setup.md) and run 'bld docker' to build in docker" && exit + fbprint_w "The host is not Debian 12 system." + fbprint_w "Options:" + fbprint_w " 1. Run 'bld toolchain-setup' to download local toolchain (no Docker needed)" + fbprint_w " 2. Install docker and run 'bld docker' to build in docker" + exit fi else [ -f /usr/bin/lsb_release ] || sudo apt-get install -y lsb-release @@ -731,7 +800,10 @@ check_debian_version() { result=$(echo "$releaseVersion < $DEBIAN_VERSION" | bc) if [ "$result" -eq "1" ]; then fbprint_e "The distro version installed on this host is older than Debian $DEBIAN_VERSION" - fbprint_e "please upgrade it or install docker and run 'bld docker' to build in docker" && exit + fbprint_w "Options:" + fbprint_w " 1. Run 'bld toolchain-setup' to download local toolchain (no Docker needed)" + fbprint_w " 2. Install docker and run 'bld docker' to build in docker" + exit else check_binfmt_qemu fi @@ -1110,6 +1182,10 @@ elif [ "$1" = docker-clean ]; then docker ps -a --format "{{.ID}} {{.Image}}" | grep '^.* fbdebian:' | awk '{print $1}' | xargs -r docker rm echo "Done" exit +elif [ "$1" = toolchain-setup ]; then + $FBDIR/tools/toolchain_manager setup; exit +elif [ "$1" = toolchain-check ]; then + $FBDIR/tools/toolchain_manager check; exit elif [ "$1" = connect ]; then host_connect_target $2 $3; exit elif [ "$1" = disconnect ]; then @@ -1238,6 +1314,10 @@ case "$1" in generate_initrd_cpio; exit;; toolchain) build_distro_rfs_buildroot toolchain $DESTARCH; exit;; + toolchain-setup) + $FBDIR/tools/toolchain_manager setup; exit;; + toolchain-check) + $FBDIR/tools/toolchain_manager check; exit;; boot) generate_bootpartition_tarball; exit;; auto|autobuild) diff --git a/tools/toolchain_manager b/tools/toolchain_manager new file mode 100755 index 0000000..ee0d7ce --- /dev/null +++ b/tools/toolchain_manager @@ -0,0 +1,328 @@ +#!/usr/bin/env bash + +# Toolchain Manager for Flexbuild +# Downloads and manages ARM GNU Toolchain locally +# Eliminates the need for Docker or system-wide toolchain installation + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +FBDIR="$(dirname "$SCRIPT_DIR")" + +# Default configuration (can be overridden by sdk-var.yml) +# NXP officially supports GCC 11.x, 12.x, 13.x - default to 13.3.rel1 +TOOLCHAIN_VERSION="${TOOLCHAIN_VERSION:-13.3.rel1}" +TOOLCHAIN_DIR="${TOOLCHAIN_DIR:-$FBDIR/toolchain}" + +# Toolchain URLs and checksums +TOOLCHAIN_BASE_URL="https://developer.arm.com/-/media/Files/downloads/gnu" + +# ARM64 toolchain (aarch64-none-linux-gnu) +TOOLCHAIN_ARM64_NAME="arm-gnu-toolchain-${TOOLCHAIN_VERSION}-x86_64-aarch64-none-linux-gnu" +TOOLCHAIN_ARM64_URL="${TOOLCHAIN_BASE_URL}/${TOOLCHAIN_VERSION}/binrel/${TOOLCHAIN_ARM64_NAME}.tar.xz" + +# ARM32 toolchain (arm-none-linux-gnueabihf) +TOOLCHAIN_ARM32_NAME="arm-gnu-toolchain-${TOOLCHAIN_VERSION}-x86_64-arm-none-linux-gnueabihf" +TOOLCHAIN_ARM32_URL="${TOOLCHAIN_BASE_URL}/${TOOLCHAIN_VERSION}/binrel/${TOOLCHAIN_ARM32_NAME}.tar.xz" + +# Colors +RED='\e[1;31m' +GREEN='\e[1;32m' +YELLOW='\e[1;33m' +NC='\e[0m' + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +show_usage() { + cat < [options] + +Commands: + setup Download and setup both ARM64 and ARM32 toolchains + setup-arm64 Download and setup ARM64 toolchain only + setup-arm32 Download and setup ARM32 toolchain only + check Check if toolchains are installed and working + clean Remove downloaded toolchains + info Show toolchain information + env Print environment variables for shell export + +Options: + --version VER Specify toolchain version (default: $TOOLCHAIN_VERSION) + --dir PATH Specify toolchain directory (default: $TOOLCHAIN_DIR) + -h, --help Show this help message + +Examples: + $(basename "$0") setup # Download both toolchains + $(basename "$0") check # Verify installation + $(basename "$0") env >> ~/.bashrc # Add to shell config + source <($(basename "$0") env) # Load in current shell + +Supported toolchain versions: + 14.2.rel1 (recommended, GCC 14.2) + 13.3.rel1 (GCC 13.3) + 13.2.rel1 (GCC 13.2) + 12.3.rel1 (GCC 12.3) + 12.2.rel1 (GCC 12.2) + 11.3.rel1 (GCC 11.3) + +EOF +} + +download_toolchain() { + local url="$1" + local name="$2" + local target_dir="$3" + local archive_name="${name}.tar.xz" + local download_path="${TOOLCHAIN_DIR}/downloads/${archive_name}" + + mkdir -p "${TOOLCHAIN_DIR}/downloads" + mkdir -p "$target_dir" + + if [ -d "${target_dir}/${name}" ] && [ -f "${target_dir}/${name}/bin/"*gcc ]; then + log_info "Toolchain ${name} already installed" + return 0 + fi + + log_info "Downloading ${name}..." + log_info "URL: ${url}" + + if [ -f "$download_path" ]; then + log_info "Archive already downloaded, skipping download" + else + if command -v wget &> /dev/null; then + wget --progress=bar:force -O "$download_path" "$url" || { + log_error "Failed to download toolchain" + rm -f "$download_path" + return 1 + } + elif command -v curl &> /dev/null; then + curl -L --progress-bar -o "$download_path" "$url" || { + log_error "Failed to download toolchain" + rm -f "$download_path" + return 1 + } + else + log_error "Neither wget nor curl found. Please install one of them." + return 1 + fi + fi + + log_info "Extracting ${archive_name}..." + tar -xf "$download_path" -C "$target_dir" || { + log_error "Failed to extract toolchain" + return 1 + } + + log_info "Toolchain ${name} installed successfully" + return 0 +} + +setup_arm64() { + log_info "Setting up ARM64 toolchain (aarch64-none-linux-gnu)..." + download_toolchain "$TOOLCHAIN_ARM64_URL" "$TOOLCHAIN_ARM64_NAME" "$TOOLCHAIN_DIR" + + # Create convenience symlinks + local tc_bin="${TOOLCHAIN_DIR}/${TOOLCHAIN_ARM64_NAME}/bin" + if [ -d "$tc_bin" ]; then + mkdir -p "${TOOLCHAIN_DIR}/bin" + + # Create aarch64-linux-gnu-* symlinks pointing to aarch64-none-linux-gnu-* + for tool in "$tc_bin"/aarch64-none-linux-gnu-*; do + if [ -f "$tool" ]; then + local toolname=$(basename "$tool") + local newname="${toolname/aarch64-none-linux-gnu/aarch64-linux-gnu}" + ln -sf "$tool" "${TOOLCHAIN_DIR}/bin/${newname}" 2>/dev/null || true + ln -sf "$tool" "${TOOLCHAIN_DIR}/bin/${toolname}" 2>/dev/null || true + fi + done + log_info "Created symlinks in ${TOOLCHAIN_DIR}/bin" + fi +} + +setup_arm32() { + log_info "Setting up ARM32 toolchain (arm-none-linux-gnueabihf)..." + download_toolchain "$TOOLCHAIN_ARM32_URL" "$TOOLCHAIN_ARM32_NAME" "$TOOLCHAIN_DIR" + + # Create convenience symlinks + local tc_bin="${TOOLCHAIN_DIR}/${TOOLCHAIN_ARM32_NAME}/bin" + if [ -d "$tc_bin" ]; then + mkdir -p "${TOOLCHAIN_DIR}/bin" + + # Create arm-linux-gnueabihf-* symlinks pointing to arm-none-linux-gnueabihf-* + for tool in "$tc_bin"/arm-none-linux-gnueabihf-*; do + if [ -f "$tool" ]; then + local toolname=$(basename "$tool") + local newname="${toolname/arm-none-linux-gnueabihf/arm-linux-gnueabihf}" + ln -sf "$tool" "${TOOLCHAIN_DIR}/bin/${newname}" 2>/dev/null || true + ln -sf "$tool" "${TOOLCHAIN_DIR}/bin/${toolname}" 2>/dev/null || true + fi + done + log_info "Created symlinks in ${TOOLCHAIN_DIR}/bin" + fi +} + +check_toolchain() { + local status=0 + + echo "=== Toolchain Status ===" + echo "Toolchain directory: ${TOOLCHAIN_DIR}" + echo "Toolchain version: ${TOOLCHAIN_VERSION}" + echo "" + + # Check ARM64 + echo "ARM64 Toolchain (aarch64-linux-gnu):" + if [ -f "${TOOLCHAIN_DIR}/bin/aarch64-linux-gnu-gcc" ]; then + local version=$("${TOOLCHAIN_DIR}/bin/aarch64-linux-gnu-gcc" --version 2>/dev/null | head -1) + echo -e " Status: ${GREEN}Installed${NC}" + echo " Version: $version" + else + echo -e " Status: ${RED}Not installed${NC}" + status=1 + fi + echo "" + + # Check ARM32 + echo "ARM32 Toolchain (arm-linux-gnueabihf):" + if [ -f "${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-gcc" ]; then + local version=$("${TOOLCHAIN_DIR}/bin/arm-linux-gnueabihf-gcc" --version 2>/dev/null | head -1) + echo -e " Status: ${GREEN}Installed${NC}" + echo " Version: $version" + else + echo -e " Status: ${RED}Not installed${NC}" + status=1 + fi + echo "" + + return $status +} + +print_env() { + cat </dev/null || true + + # Check if toolchain exists + if [ ! -f "$TOOLCHAIN_BIN/aarch64-linux-gnu-gcc" ]; then + log_warn "Local toolchain not found at $TOOLCHAIN_BIN" + log_info "Downloading ARM GNU Toolchain (GCC 13.3)..." + + if ! "$SCRIPT_DIR/toolchain_manager" setup-arm64; then + log_error "Failed to setup toolchain" + log_info "You can manually run: ./tools/toolchain_manager setup" + return 1 + fi + fi + + # Verify toolchain + if [ -f "$TOOLCHAIN_BIN/aarch64-linux-gnu-gcc" ]; then + local gcc_version=$("$TOOLCHAIN_BIN/aarch64-linux-gnu-gcc" --version | head -1) + log_info "Using toolchain: $gcc_version" + + export CROSS_COMPILE=aarch64-linux-gnu- + export ARCH=arm64 + + return 0 + else + log_error "Toolchain verification failed" + return 1 + fi +} validate_distro() { case "$DISTRO" in @@ -15,7 +85,8 @@ validate_distro() { return 0 ;; *) - echo "Error: Unsupported distribution. Valid options are:" + log_error "Unsupported distribution: $DISTRO" + echo "Valid options are:" echo " - debian:base (minimal Debian installation)" echo " - debian:server (Debian with server packages)" echo " - debian:desktop (Debian with desktop environment)" @@ -24,102 +95,230 @@ validate_distro() { esac } +validate_machine() { + local config_file="$FBDIR/configs/board/$MACHINE.conf" + if [ ! -f "$config_file" ]; then + log_error "Unknown machine: $MACHINE" + echo "Available machines:" + ls -1 "$FBDIR/configs/board/"*.conf 2>/dev/null | xargs -I{} basename {} .conf | sed 's/^/ - /' + return 1 + fi + return 0 +} + build_system() { - echo "=== BUILD PROCESS STARTED ===" - echo "Target Device: $MACHINE" - echo "Components: $COMPONENTS" - echo "Distribution: $DISTRO" - echo "Config File: $SDK_CONFIG_FILE" + echo "" + echo "╔════════════════════════════════════════════════════════════════╗" + echo "║ VARISCITE BUILD SYSTEM ║" + echo "╚════════════════════════════════════════════════════════════════╝" + echo "" + log_info "Target Device: $MACHINE" + log_info "Components: ${COMPONENTS:-auto}" + log_info "Distribution: $DISTRO" + log_info "Config File: $SDK_CONFIG_FILE" + echo "" + + # Validate inputs + if ! validate_machine; then + return 1 + fi if ! validate_distro; then return 1 fi - for component in $COMPONENTS; do - echo "Building $component for $MACHINE..." - bld -f "$SDK_CONFIG_FILE" -m "$MACHINE" "$component" || { - echo "Error: Failed to build $component" + # Setup toolchain + if [ "$SKIP_TOOLCHAIN_CHECK" != true ]; then + log_step "Setting up toolchain..." + if ! setup_toolchain; then return 1 - } - done + fi + fi + + # Build components + if [ -n "$COMPONENTS" ]; then + for component in $COMPONENTS; do + log_step "Building $component for $MACHINE..." + bld -f "$SDK_CONFIG_FILE" -m "$MACHINE" "$component" || { + log_error "Failed to build $component" + return 1 + } + done + fi - echo "Building $DISTRO root filesystem..." + # Build root filesystem + log_step "Building $DISTRO root filesystem..." bld rfs -r "$DISTRO" -f "$SDK_CONFIG_FILE" -m "$MACHINE" || { - echo "Error: Root filesystem build failed" + log_error "Root filesystem build failed" return 1 } - echo "Building applications for $DISTRO..." + # Build applications + log_step "Building applications for $DISTRO..." bld apps -r "$DISTRO" -f "$SDK_CONFIG_FILE" -m "$MACHINE" || { - echo "Error: Applications build failed" + log_error "Applications build failed" return 1 } - echo "Integrating components..." + # Integrate components + log_step "Integrating components..." bld merge-apps -r "$DISTRO" -f "$SDK_CONFIG_FILE" -m "$MACHINE" && \ bld merge-bootpart-rfs -r "$DISTRO" -f "$SDK_CONFIG_FILE" -m "$MACHINE" || { - echo "Error: System integration failed" + log_error "System integration failed" return 1 } - echo "Building Recovery SD Card..." - bld -r "$DISTRO" -f "$SDK_CONFIG_FILE" -m "$MACHINE" create-recovery-sdcard-image + # Build recovery SD card image + log_step "Building Recovery SD Card image..." + bld -r "$DISTRO" -f "$SDK_CONFIG_FILE" -m "$MACHINE" create-recovery-sdcard-image || { + log_warn "Recovery SD card image creation failed (non-fatal)" + } + + echo "" + echo "╔════════════════════════════════════════════════════════════════╗" + echo "║ BUILD SUCCESSFUL ║" + echo "╚════════════════════════════════════════════════════════════════╝" + echo "" + log_info "Output directory: $FBDIR/build_lsdk2412/images/" - echo "BUILD SUCCESSFUL" return 0 } clean_system() { - echo "=== CLEANUP PROCESS STARTED ===" - echo "Cleaning $DISTRO environment..." + echo "" + log_step "Cleaning $DISTRO environment..." - if [ -n "$DISTRO" ]; then - BLD_ARGS="-r $DISTRO" - fi + local bld_args="" + [ -n "$DISTRO" ] && bld_args="-r $DISTRO" + [ -n "$SDK_CONFIG_FILE" ] && bld_args="$bld_args -f $SDK_CONFIG_FILE" - bld clean "$BLD_ARGS" - bld clean-linux "$BLD_ARGS" - bld clean-rfs "$BLD_ARGS" - bld clean-apps "$BLD_ARGS" + bld clean $bld_args || true + bld clean-linux $bld_args || true + bld clean-rfs $bld_args || true + bld clean-apps $bld_args || true - echo "CLEANUP COMPLETED" + log_info "Cleanup completed" return 0 } cleanall() { - echo "=== FULL CLEANUP PROCESS STARTED ===" - echo "Cleaning ALL build environments..." + echo "" + log_warn "This will remove ALL build artifacts and downloaded components!" + read -p "Are you sure? (y/N) " -n 1 -r + echo + + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + log_info "Operation cancelled" + return 0 + fi + + log_step "Full cleanup started..." clean_system - git clean -dxf + + cd "$FBDIR" + git clean -dxf --exclude=toolchain/ || true rm -rf components_lsdk2412/ build_lsdk2412/ - . setup.env + # Re-source environment + [ -f "$FBDIR/setup.env" ] && . "$FBDIR/setup.env" + log_info "Full cleanup completed" + log_info "Note: Local toolchain preserved in toolchain/" return 0 } -show_usage() { - echo "Usage: $SCRIPT_NAME [options]" - echo "Options:" - echo " --clean Clean the specified distribution" - echo " --cleanall Clean all build environments" - echo " --config Specify custom config file (default: sdk-var.yml)" - echo "" - echo "Supported Debian distributions:" - echo " debian:base - Minimal Debian installation" - echo " debian:server - Debian with server packages" - echo " debian:desktop - Debian with desktop environment" +setup_only() { + log_step "Setting up build environment..." + + # Setup toolchain + if ! setup_toolchain; then + return 1 + fi + + # Source environment (ignore errors from setup.env) + cd "$FBDIR" + export FBDIR="$FBDIR" + export PATH="$FBDIR:$FBDIR/tools:$PATH" + + # Create bld symlink if needed + [ ! -L "$FBDIR/tools/bld" ] && ln -sf flex-builder "$FBDIR/tools/bld" 2>/dev/null || true + + log_info "Environment ready!" + log_info "You can now run: bld -m $MACHINE -f $SDK_CONFIG_FILE " + + # Print environment info echo "" - echo "Examples:" - echo " $SCRIPT_NAME imx8mm-var-dart debian:desktop \"uboot linux\"" - echo " $SCRIPT_NAME imx8mm-var-dart debian:desktop --clean" - echo " $SCRIPT_NAME --cleanall" + echo "Environment variables set:" + echo " FBDIR=$FBDIR" + echo " PATH includes: $TOOLCHAIN_BIN" + echo " CROSS_COMPILE=$CROSS_COMPILE" + echo " ARCH=$ARCH" + + return 0 +} + +show_usage() { + cat < [components] [options] + or: $SCRIPT_NAME [options] + +Arguments: + Target machine (e.g., imx8mp-var-dart, imx8mm-var-dart) + Target distribution (debian:base, debian:server, debian:desktop) + [components] Components to build (e.g., "uboot linux atf") + +Options: + --setup Only setup toolchain and environment (no build) + --clean Clean the specified distribution build + --cleanall Clean all build environments (preserves toolchain) + --config FILE Specify config file (default: sdk-var.yml) + --skip-tc Skip toolchain check (use system toolchain) + -h, --help Show this help message + +Supported machines: +EOF + ls -1 "$FBDIR/configs/board/"*.conf 2>/dev/null | xargs -I{} basename {} .conf | grep -E '^imx' | sed 's/^/ /' + + cat <