Files
2026-07-13 13:33:03 +08:00

277 lines
8.5 KiB
Bash
Executable File

#!/bin/bash
# Unified Android Build Script for MNNCLI
# This script supports both single and multi-architecture builds with OpenCV support
set -e
# Check and clone libyuv if it doesn't exist
LIBYUV_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../../3rd_party/libyuv"
LIBYUV_REPO="https://github.com/bilibili/libyuv.git"
LIBYUV_COMMIT="1f337a783783776e2735d88628e3674681284d72"
if [ ! -d "$LIBYUV_DIR" ]; then
echo "Cloning libyuv from $LIBYUV_REPO..."
git clone "$LIBYUV_REPO" "$LIBYUV_DIR"
if [ $? -ne 0 ]; then
echo "Error: Failed to clone libyuv."
exit 1
fi
# (cd "$LIBYUV_DIR" && git checkout "$LIBYUV_COMMIT")
# if [ $? -ne 0 ]; then
# echo "Error: Failed to checkout libyuv commit."
# exit 1
# fi
else
echo "libyuv directory already exists. Skipping clone."
fi
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Help function
show_help() {
echo -e "${BLUE}MNNCLI Android Build Script${NC}"
echo ""
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " -a, --arch ARCH Target architecture (arm64-v8a, armeabi-v7a, x86, x86_64)"
echo " -m, --multi Build for multiple architectures"
echo " -c, --clean Clean build directory before building"
echo " -v, --verbose Enable verbose output"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " $0 # Build for default architecture (arm64-v8a)"
echo " $0 -a arm64-v8a # Build for specific architecture"
echo " $0 -m # Build for all supported architectures"
echo " $0 -c # Clean build and rebuild"
echo ""
}
# Default values
TARGET_ARCH="arm64-v8a"
BUILD_MULTI=false
CLEAN_BUILD=false
VERBOSE=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-a|--arch)
TARGET_ARCH="$2"
shift 2
;;
-m|--multi)
BUILD_MULTI=true
shift
;;
-c|--clean)
CLEAN_BUILD=true
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
-h|--help)
show_help
exit 0
;;
*)
echo -e "${RED}Unknown option: $1${NC}"
show_help
exit 1
;;
esac
done
echo -e "${GREEN}Building MNNCLI for Android with OpenCV support...${NC}"
# Get the directory where this script is located
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Check if ANDROID_NDK is set
if [ -z "$ANDROID_NDK" ]; then
echo -e "${RED}Error: ANDROID_NDK environment variable is not set${NC}"
echo -e "${YELLOW}Please set ANDROID_NDK to your Android NDK path${NC}"
echo -e "${YELLOW}Example: export ANDROID_NDK=/path/to/android-ndk${NC}"
exit 1
fi
# Check if ANDROID_NDK exists
if [ ! -d "$ANDROID_NDK" ]; then
echo -e "${RED}Error: ANDROID_NDK directory does not exist: $ANDROID_NDK${NC}"
exit 1
fi
# OpenCV configuration
OPENCV_VERSION="4.8.0"
OPENCV_ANDROID_SDK_DIR="$PROJECT_ROOT/opencv-android-sdk"
OPENCV_DOWNLOAD_URL="https://github.com/opencv/opencv/releases/download/${OPENCV_VERSION}/opencv-${OPENCV_VERSION}-android-sdk.zip"
echo -e "${YELLOW}OpenCV version: $OPENCV_VERSION${NC}"
echo -e "${YELLOW}OpenCV SDK directory: $OPENCV_ANDROID_SDK_DIR${NC}"
# Download and extract OpenCV Android SDK if not already present
if [ ! -d "$OPENCV_ANDROID_SDK_DIR" ]; then
echo -e "${YELLOW}Downloading OpenCV Android SDK...${NC}"
# Create temporary directory for download
TEMP_DIR="$PROJECT_ROOT/temp_opencv_download"
mkdir -p "$TEMP_DIR"
cd "$TEMP_DIR"
# Download OpenCV Android SDK
echo -e "${YELLOW}Downloading from: $OPENCV_DOWNLOAD_URL${NC}"
if command -v wget &> /dev/null; then
wget -O opencv-android-sdk.zip "$OPENCV_DOWNLOAD_URL"
elif command -v curl &> /dev/null; then
curl -L -o opencv-android-sdk.zip "$OPENCV_DOWNLOAD_URL"
else
echo -e "${RED}Error: Neither wget nor curl is available. Please install one of them.${NC}"
exit 1
fi
# Check if download was successful
if [ ! -f "opencv-android-sdk.zip" ]; then
echo -e "${RED}Error: Failed to download OpenCV Android SDK${NC}"
exit 1
fi
# Extract OpenCV Android SDK
echo -e "${YELLOW}Extracting OpenCV Android SDK...${NC}"
unzip -q opencv-android-sdk.zip
# Move to final location
if [ -d "OpenCV-android-sdk" ]; then
mv "OpenCV-android-sdk" "$OPENCV_ANDROID_SDK_DIR"
else
echo -e "${RED}Error: Unexpected archive structure${NC}"
exit 1
fi
# Clean up temporary files
cd "$PROJECT_ROOT"
rm -rf "$TEMP_DIR"
echo -e "${GREEN}OpenCV Android SDK downloaded and extracted successfully!${NC}"
else
echo -e "${GREEN}OpenCV Android SDK already exists at: $OPENCV_ANDROID_SDK_DIR${NC}"
fi
# Verify OpenCV Android SDK structure
if [ ! -d "$OPENCV_ANDROID_SDK_DIR/sdk/native" ]; then
echo -e "${RED}Error: Invalid OpenCV Android SDK structure${NC}"
echo -e "${YELLOW}Expected directory: $OPENCV_ANDROID_SDK_DIR/sdk/native${NC}"
exit 1
fi
# Set OpenCV environment variable for CMake
export OPENCV_ANDROID_SDK="$OPENCV_ANDROID_SDK_DIR"
echo -e "${GREEN}OpenCV Android SDK path set: $OPENCV_ANDROID_SDK${NC}"
# Build configuration
if [ "$BUILD_MULTI" = true ]; then
echo -e "${BLUE}Building for multiple architectures...${NC}"
BUILD_DIR="$PROJECT_ROOT/build_mnncli_android_multi"
# Clean build directory if requested
if [ "$CLEAN_BUILD" = true ]; then
echo -e "${YELLOW}Cleaning build directory...${NC}"
rm -rf "$BUILD_DIR"
fi
# Create build directory
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# Configure for multiple architectures
cmake .. \
-DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI="arm64-v8a;armeabi-v7a;x86;x86_64" \
-DANDROID_PLATFORM=android-24 \
-DCMAKE_BUILD_TYPE=Release \
-DMNN_BUILD_TRAIN=OFF \
-DMNN_BUILD_TRAIN_MINI=OFF \
-DMNN_BUILD_DEMO=OFF \
-DMNN_BUILD_QUANTOOLS=OFF \
-DMNN_BUILD_TEST=OFF \
-DMNN_BUILD_BENCHMARK=OFF \
-DMNN_BUILD_FOR_ANDROID=ON \
-DMNN_USE_OPENCV=ON \
-DOPENCV_ANDROID_SDK="$OPENCV_ANDROID_SDK" \
-DCMAKE_VERBOSE_MAKEFILE="$VERBOSE"
# Build
echo -e "${BLUE}Building MNNCLI for multiple architectures...${NC}"
make -j$(nproc)
else
echo -e "${BLUE}Building for single architecture: $TARGET_ARCH${NC}"
BUILD_DIR="$PROJECT_ROOT/build_mnncli_android"
# Clean build directory if requested
if [ "$CLEAN_BUILD" = true ]; then
echo -e "${YELLOW}Cleaning build directory...${NC}"
rm -rf "$BUILD_DIR"
fi
# Create build directory
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# Configure for single architecture
cmake .. \
-DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI="$TARGET_ARCH" \
-DANDROID_PLATFORM=android-24 \
-DCMAKE_BUILD_TYPE=Release \
-DMNN_BUILD_TRAIN=OFF \
-DMNN_BUILD_TRAIN_MINI=OFF \
-DMNN_BUILD_DEMO=OFF \
-DMNN_BUILD_QUANTOOLS=OFF \
-DMNN_BUILD_TEST=OFF \
-DMNN_BUILD_BENCHMARK=OFF \
-DMNN_BUILD_FOR_ANDROID=ON \
-DMNN_USE_OPENCV=ON \
-DOPENCV_ANDROID_SDK="$OPENCV_ANDROID_SDK" \
-DCMAKE_VERBOSE_MAKEFILE="$VERBOSE"
# Build
echo -e "${BLUE}Building MNNCLI for $TARGET_ARCH...${NC}"
make -j$(nproc)
fi
# Check if build was successful
if [ -f "apps/mnncli/mnncli" ]; then
echo -e "${GREEN}Build completed successfully!${NC}"
echo -e "${GREEN}Executable location: $BUILD_DIR/apps/mnncli/mnncli${NC}"
# Show file size and permissions
ls -lh "apps/mnncli/mnncli"
# Check if libMNN.so was created
if [ -f "libMNN.so" ]; then
echo -e "${GREEN}libMNN.so created successfully${NC}"
ls -lh "libMNN.so"
else
echo -e "${YELLOW}Warning: libMNN.so not found${NC}"
fi
else
echo -e "${RED}Build failed! Executable not found${NC}"
exit 1
fi
echo -e "${GREEN}Android build completed!${NC}"
echo -e "${BLUE}Next steps:${NC}"
echo -e "${BLUE}1. Run ./android_debug.sh to deploy and test on device${NC}"
echo -e "${BLUE}2. Or run ./android_debug.sh --help for more options${NC}"