Files
alibaba--mnn/tools/script/generate_podspec.sh
T
2026-07-13 13:33:03 +08:00

387 lines
12 KiB
Bash
Executable File

#!/bin/bash
# =============================================================================
# generate_podspec.sh
# Auto-generate MNN.podspec from CMake targets and optionally validate it
#
# Uses the same CMake configuration as production build
#
# Usage:
# ./tools/script/generate_podspec.sh # Generate podspec
# ./tools/script/generate_podspec.sh -c # Check if podspec is in sync
# ./tools/script/generate_podspec.sh -v 3.2.0 # Override version
# ./tools/script/generate_podspec.sh --validate # Generate + validate syntax
# ./tools/script/generate_podspec.sh --validate-full # Generate + full validation (requires Xcode)
# ./tools/script/generate_podspec.sh --ci # CI mode (no colors, strict exit)
# =============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MNN_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Options
VERSION=""
CHECK_MODE=false
VALIDATE_MODE=false
VALIDATE_FULL=false
CI_MODE=false
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--version|-v)
VERSION="$2"
shift 2
;;
--check|-c)
CHECK_MODE=true
shift
;;
--validate)
VALIDATE_MODE=true
shift
;;
--validate-full)
VALIDATE_FULL=true
VALIDATE_MODE=true
shift
;;
--ci)
CI_MODE=true
RED=''
GREEN=''
YELLOW=''
BLUE=''
NC=''
shift
;;
--help|-h)
echo "Usage: $0 [options]"
echo ""
echo "Generate MNN.podspec from CMake targets"
echo "Version defaults to MNN_VERSION from CMakeLists.txt"
echo ""
echo "Options:"
echo " --check, -c Check if podspec is in sync (for CI)"
echo " --version, -v VERSION Override podspec version"
echo " --validate Generate + validate syntax"
echo " --validate-full Generate + full validation (requires Xcode)"
echo " --ci CI mode (no colors, strict exit)"
echo " --help, -h Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Helper functions for logging
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[PASS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[FAIL]${NC} $1"; }
# =============================================================================
# Check mode: backup current podspec first
# =============================================================================
if [ "$CHECK_MODE" = true ]; then
echo "=========================================="
echo "Checking MNN.podspec is in sync"
echo "=========================================="
if [ ! -f "$MNN_ROOT/MNN.podspec" ]; then
echo "❌ Error: MNN.podspec not found!"
echo ""
echo "Please run: ./tools/script/generate_podspec.sh"
exit 1
fi
cp "$MNN_ROOT/MNN.podspec" "$MNN_ROOT/MNN.podspec.backup"
else
echo "=========================================="
echo "Generating MNN.podspec from CMake targets"
echo "=========================================="
fi
echo "MNN Root: $MNN_ROOT"
if [ -n "$VERSION" ]; then
echo "Version: $VERSION (override)"
else
echo "Version: (from MNN_VERSION in CMakeLists.txt)"
fi
echo ""
# =============================================================================
# CMake configuration
# =============================================================================
BUILD_DIR="$MNN_ROOT/build_podspec_gen"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# COMMON flags (same as online build script)
COMMON_FLAGS=(
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_TOOLCHAIN_FILE="$MNN_ROOT/cmake/ios.toolchain.cmake"
-DENABLE_BITCODE=0
-DMNN_AAPL_FMWK=ON
-DMNN_SEP_BUILD=OFF
-DMNN_BUILD_SHARED_LIBS=OFF
-DMNN_USE_THREAD_POOL=OFF
-DMNN_KLEIDIAI=OFF
-DMNN_REDUCE_SIZE=OFF
)
# EXTRA flags (same as online build script)
EXTRA_FLAGS=(
-DCMAKE_SYSTEM_NAME=iOS
-DMNN_BUILD_LLM=ON
-DMNN_SUPPORT_TRANSFORMER_FUSE=ON
-DMNN_LOW_MEMORY=ON
-DMNN_BUILD_AUDIO=OFF
-DLLM_SUPPORT_VISION=OFF
-DMNN_BUILD_OPENCV=ON
-DMNN_IMGCODECS=OFF
-DMNN_SME2=OFF
-DLLM_SUPPORT_HTTP_RESOURCE=OFF
)
# iOS arm64 flags (same as online build script - NO CoreML!)
IOS_FLAGS=(
-DMNN_METAL=ON
-DARCHS="arm64"
# Optimization flags same as online build
'-DCMAKE_CXX_FLAGS_RELEASE=-Oz'
'-DCMAKE_C_FLAGS_RELEASE=-Oz'
)
# Podspec generation flags
PODSPEC_FLAGS=(
-DMNN_GENERATE_PODSPEC=ON
)
if [ -n "$VERSION" ]; then
PODSPEC_FLAGS+=(-DMNN_PODSPEC_VERSION="$VERSION")
fi
echo "Configuring CMake..."
cmake "$MNN_ROOT" \
"${COMMON_FLAGS[@]}" \
"${EXTRA_FLAGS[@]}" \
"${IOS_FLAGS[@]}" \
"${PODSPEC_FLAGS[@]}" \
> /dev/null 2>&1
# Cleanup
cd "$MNN_ROOT"
rm -rf "$BUILD_DIR"
# =============================================================================
# Check mode: compare and report
# =============================================================================
if [ "$CHECK_MODE" = true ]; then
echo ""
if diff -q "$MNN_ROOT/MNN.podspec.backup" "$MNN_ROOT/MNN.podspec" > /dev/null 2>&1; then
echo "✅ MNN.podspec is in sync!"
rm -f "$MNN_ROOT/MNN.podspec.backup"
exit 0
else
echo "❌ MNN.podspec is out of sync!"
echo ""
echo "Differences:"
echo "=========================================="
diff -u "$MNN_ROOT/MNN.podspec.backup" "$MNN_ROOT/MNN.podspec" | head -30 || true
echo "=========================================="
echo ""
echo "To fix, run:"
echo " ./tools/script/generate_podspec.sh"
echo " git add MNN.podspec"
echo " git commit -m 'Update MNN.podspec'"
# Restore original
mv "$MNN_ROOT/MNN.podspec.backup" "$MNN_ROOT/MNN.podspec"
exit 1
fi
fi
# =============================================================================
# Validation functions
# =============================================================================
# Check if podspec file exists
validate_file_exists() {
log_info "Checking podspec file exists..."
if [ ! -f "$MNN_ROOT/MNN.podspec" ]; then
log_error "MNN.podspec not found at: $MNN_ROOT/MNN.podspec"
return 1
fi
log_success "Podspec file exists: $MNN_ROOT/MNN.podspec"
return 0
}
# Validate podspec syntax
validate_syntax() {
log_info "Validating podspec syntax..."
if ! command -v pod &> /dev/null; then
log_warning "CocoaPods not installed, skipping syntax validation"
echo " Install CocoaPods to enable validation: sudo gem install cocoapods"
return 0
fi
# Use pod spec lint for quick syntax check (no download/compile)
if pod spec lint "$MNN_ROOT/MNN.podspec" --quick --no-clean --allow-warnings 2>&1; then
log_success "Podspec syntax is valid"
return 0
else
log_error "Podspec syntax validation failed"
return 1
fi
}
# Validate file references in podspec
validate_file_references() {
log_info "Checking file references..."
local errors=0
# Extract source_files patterns and check if they exist
while IFS= read -r pattern; do
# Remove quotes and commas
pattern=$(echo "$pattern" | sed "s/['',]//g" | xargs)
# Skip empty lines and comments
if [ -z "$pattern" ] || [[ "$pattern" == \#* ]]; then
continue
fi
# Check if pattern contains glob
if [[ "$pattern" == *"*"* ]]; then
# Expand glob and check if any files match
expanded=$(eval echo "$pattern" 2>/dev/null)
if [ -z "$expanded" ]; then
log_warning "Pattern matches no files: $pattern"
fi
else
# Check if file exists
if [ ! -e "$MNN_ROOT/$pattern" ]; then
log_error "File not found: $pattern"
errors=$((errors + 1))
fi
fi
done < <(grep -E "^\s*'" "$MNN_ROOT/MNN.podspec" | grep -v "^\s*#" | head -100)
if [ $errors -eq 0 ]; then
log_success "File references are valid"
return 0
else
log_error "Found $errors invalid file references"
return 1
fi
}
# Full validation using pod lib lint (requires Xcode)
validate_full() {
log_info "Running full validation (this may take a while)..."
if ! command -v pod &> /dev/null; then
log_error "CocoaPods not installed"
echo " Install CocoaPods to enable full validation: sudo gem install cocoapods"
return 1
fi
if [[ "$(uname)" != "Darwin" ]]; then
log_warning "Full validation requires macOS, skipping"
return 0
fi
# Run pod lib lint
if pod lib lint "$MNN_ROOT/MNN.podspec" --allow-warnings --verbose 2>&1; then
log_success "Full validation passed"
return 0
else
log_error "Full validation failed"
return 1
fi
}
# =============================================================================
# Validation mode: run validation after generation
# =============================================================================
if [ "$VALIDATE_MODE" = true ]; then
echo ""
echo "=========================================="
echo "Validating MNN.podspec"
echo "=========================================="
VALIDATE_FAILED=0
# Step 1: Check file exists
if ! validate_file_exists; then
VALIDATE_FAILED=1
fi
# Step 2: Validate syntax (only if file exists)
if [ $VALIDATE_FAILED -eq 0 ]; then
if ! validate_syntax; then
VALIDATE_FAILED=1
fi
fi
# Step 3: Validate file references
if ! validate_file_references; then
VALIDATE_FAILED=1
fi
# Step 4: Full validation (if requested)
if [ "$VALIDATE_FULL" = true ]; then
if ! validate_full; then
VALIDATE_FAILED=1
fi
fi
# Report results
echo ""
echo "=========================================="
if [ $VALIDATE_FAILED -eq 0 ]; then
log_success "All validations passed!"
echo "=========================================="
else
log_error "Validation failed!"
echo "=========================================="
echo ""
echo "To fix issues:"
echo " 1. Review the errors above"
echo " 2. Regenerate podspec if needed"
echo " 3. Commit the updated podspec:"
echo " git add MNN.podspec"
echo " git commit -m 'Update MNN.podspec'"
exit 1
fi
fi
# =============================================================================
# Normal mode: show success message
# =============================================================================
if [ "$VALIDATE_MODE" = false ] && [ "$CHECK_MODE" = false ]; then
echo ""
echo "=========================================="
echo "Done! Generated: $MNN_ROOT/MNN.podspec"
echo "=========================================="
echo ""
echo "To validate the generated podspec:"
echo " ./tools/script/generate_podspec.sh --validate"
echo ""
echo "For full validation (requires Xcode):"
echo " ./tools/script/generate_podspec.sh --validate-full"
fi