Prevents iOS build failures caused by pkgx SQLite linking conflicts and ensures Xcode Command Line Tools are properly installed. Problem: - pkgx installs SQLite built for macOS, causing linker errors when building for iOS simulator: "linking in dylib built for 'macOS'" - Missing Command Line Tools cause build failures without clear error messages Changes: - Add check_sqlite_conflicts() function - Detects pkgx SQLite installations in ~/.pkgx - Warns about macOS dylibs that will cause iOS simulator build failures - Checks for system SQLite from Command Line Tools - Validates library paths (DYLD_LIBRARY_PATH, LD_LIBRARY_PATH) - Add check_command_line_tools() function - Verifies Xcode Command Line Tools are installed and configured - Checks for xcodebuild availability - Verifies sqlite3 is available (part of Command Line Tools) - Provides clear error messages with installation instructions - Enhance pkgx detection in iOS build functions - Specifically searches for pkgx SQLite dylibs - Automatically removes pkgx paths from PATH environment variable - Provides detailed warnings about detected conflicts - Cleans all problematic environment variables before building - Integrate checks into environment validation - Runs automatically when building for iOS - Provides early warnings before build starts - Fails fast with clear error messages if tools are missing This fixes the linker error: "ld: building for 'iOS-simulator', but linking in dylib (/Users/trent/.pkgx/sqlite.org/v3.44.2/lib/libsqlite3.0.dylib) built for 'macOS'" The build script now: - Detects pkgx SQLite conflicts before building - Automatically fixes environment variables - Verifies Command Line Tools are installed - Provides clear guidance for manual fixes if needed Files modified: - scripts/build-native.sh
624 lines
22 KiB
Bash
Executable File
624 lines
22 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Exit on error
|
||
set -e
|
||
|
||
# Colors for output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Logging functions
|
||
log_info() {
|
||
echo -e "${GREEN}[INFO]${NC} $1"
|
||
}
|
||
|
||
log_warn() {
|
||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||
}
|
||
|
||
log_error() {
|
||
echo -e "${RED}[ERROR]${NC} $1"
|
||
}
|
||
|
||
# Validation functions
|
||
check_command() {
|
||
if ! command -v $1 &> /dev/null; then
|
||
# Try rbenv shims for pod command
|
||
if [ "$1" = "pod" ] && [ -f "$HOME/.rbenv/shims/pod" ]; then
|
||
log_info "Found pod in rbenv shims"
|
||
return 0
|
||
fi
|
||
log_error "$1 is not installed. Please install it first."
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Get pod command (handles rbenv)
|
||
get_pod_command() {
|
||
if command -v pod &> /dev/null; then
|
||
echo "pod"
|
||
elif [ -f "$HOME/.rbenv/shims/pod" ]; then
|
||
echo "$HOME/.rbenv/shims/pod"
|
||
else
|
||
log_error "CocoaPods (pod) not found. Please install CocoaPods first."
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
check_sqlite_conflicts() {
|
||
local PLATFORM=$1
|
||
|
||
if [ "$PLATFORM" != "ios" ] && [ "$PLATFORM" != "all" ]; then
|
||
return 0
|
||
fi
|
||
|
||
# Check for pkgx SQLite that might interfere with iOS builds
|
||
if [ -d "$HOME/.pkgx" ]; then
|
||
# Look for pkgx SQLite installations
|
||
PKGX_SQLITE=$(find "$HOME/.pkgx" -name "libsqlite3*.dylib" 2>/dev/null | head -1)
|
||
|
||
if [ -n "$PKGX_SQLITE" ]; then
|
||
log_warn "⚠️ pkgx SQLite detected: $PKGX_SQLITE"
|
||
log_warn " This may cause iOS build failures (linking macOS dylib for iOS simulator)"
|
||
log_warn " The build script will unset problematic environment variables"
|
||
|
||
# Check if library paths point to pkgx
|
||
if [ -n "$DYLD_LIBRARY_PATH" ] && echo "$DYLD_LIBRARY_PATH" | grep -q "\.pkgx"; then
|
||
log_warn " DYLD_LIBRARY_PATH contains pkgx paths - will be unset for build"
|
||
fi
|
||
if [ -n "$LD_LIBRARY_PATH" ] && echo "$LD_LIBRARY_PATH" | grep -q "\.pkgx"; then
|
||
log_warn " LD_LIBRARY_PATH contains pkgx paths - will be unset for build"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Check for system SQLite (from Command Line Tools)
|
||
if command -v sqlite3 &> /dev/null; then
|
||
SQLITE_PATH=$(which sqlite3)
|
||
if [ "$SQLITE_PATH" = "/usr/bin/sqlite3" ]; then
|
||
log_info "✅ System SQLite found (from Command Line Tools): $SQLITE_PATH"
|
||
else
|
||
log_warn "⚠️ SQLite found at non-standard location: $SQLITE_PATH"
|
||
log_warn " Ensure this is compatible with iOS builds"
|
||
fi
|
||
else
|
||
log_warn "⚠️ sqlite3 command not found - Command Line Tools may not be installed"
|
||
log_warn " Install with: xcode-select --install"
|
||
fi
|
||
}
|
||
|
||
check_command_line_tools() {
|
||
if [ "$(uname)" != "Darwin" ]; then
|
||
return 0
|
||
fi
|
||
|
||
# Check if xcode-select points to a valid developer directory
|
||
if ! xcode-select -p &> /dev/null; then
|
||
log_error "Xcode Command Line Tools not configured"
|
||
log_error " Run: xcode-select --install"
|
||
exit 1
|
||
fi
|
||
|
||
# Check if xcodebuild is available
|
||
if ! command -v xcodebuild &> /dev/null; then
|
||
log_error "xcodebuild not found - Command Line Tools may be incomplete"
|
||
log_error " Run: xcode-select --install"
|
||
exit 1
|
||
fi
|
||
|
||
# Verify sqlite3 is available (part of Command Line Tools)
|
||
if ! command -v sqlite3 &> /dev/null; then
|
||
log_warn "⚠️ sqlite3 not found - Command Line Tools may be incomplete"
|
||
log_warn " This may cause iOS build issues"
|
||
log_warn " Run: xcode-select --install"
|
||
fi
|
||
}
|
||
|
||
check_environment() {
|
||
local PLATFORM=$1
|
||
|
||
# Check for required tools (always needed)
|
||
check_command "node"
|
||
check_command "npm"
|
||
|
||
# Check Node.js version
|
||
NODE_VERSION=$(node -v | cut -d. -f1 | tr -d 'v')
|
||
if [ "$NODE_VERSION" -lt 14 ]; then
|
||
log_error "Node.js version 14 or higher is required"
|
||
exit 1
|
||
fi
|
||
|
||
# Platform-specific checks
|
||
if [ "$PLATFORM" = "android" ] || [ "$PLATFORM" = "all" ]; then
|
||
check_command "java"
|
||
|
||
# Check for Gradle Wrapper instead of system gradle
|
||
if [ ! -f "android/gradlew" ]; then
|
||
log_error "Gradle wrapper not found at android/gradlew"
|
||
exit 1
|
||
fi
|
||
|
||
# Check Java version
|
||
JAVA_VERSION=$(java -version 2>&1 | head -n 1 | cut -d'"' -f2 | cut -d. -f1)
|
||
if [ "$JAVA_VERSION" -lt 11 ]; then
|
||
log_error "Java version 11 or higher is required"
|
||
exit 1
|
||
fi
|
||
|
||
# Check for Android SDK
|
||
if [ -z "$ANDROID_HOME" ]; then
|
||
log_error "ANDROID_HOME environment variable is not set"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
if [ "$PLATFORM" = "ios" ] || [ "$PLATFORM" = "all" ]; then
|
||
# Check Command Line Tools
|
||
check_command_line_tools
|
||
|
||
# Check for SQLite conflicts
|
||
check_sqlite_conflicts "$PLATFORM"
|
||
|
||
# iOS-specific checks are done in build_ios() function
|
||
# to avoid failing if iOS tools aren't available when building Android only
|
||
:
|
||
fi
|
||
}
|
||
|
||
# Build functions
|
||
build_typescript() {
|
||
log_info "Building TypeScript..."
|
||
npm run clean
|
||
if ! npm run build; then
|
||
log_error "TypeScript build failed"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
build_plugin_for_test_app() {
|
||
log_info "Building plugin for test app..."
|
||
|
||
# Ensure symlink is in place FIRST (before building)
|
||
# The test app expects the plugin at node_modules/@timesafari/daily-notification-plugin
|
||
SYMLINK="test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin"
|
||
if [ ! -L "$SYMLINK" ] || [ ! -e "$SYMLINK" ]; then
|
||
log_info "Creating symlink to plugin..."
|
||
mkdir -p "$(dirname "$SYMLINK")"
|
||
rm -f "$SYMLINK"
|
||
ln -sf "../../../" "$SYMLINK"
|
||
fi
|
||
|
||
# Navigate to test app directory
|
||
cd test-apps/daily-notification-test || exit 1
|
||
|
||
# Sync Capacitor Android (creates necessary project structure)
|
||
log_info "Syncing Capacitor Android..."
|
||
if ! npm run cap:sync:android; then
|
||
log_error "Capacitor Android sync failed"
|
||
exit 1
|
||
fi
|
||
|
||
# Navigate to android directory
|
||
cd android || exit 1
|
||
|
||
# Fix capacitor.build.gradle if it references missing cordova.variables.gradle
|
||
# This file is auto-generated by Capacitor and may reference files that don't exist
|
||
if [ -f "app/capacitor.build.gradle" ]; then
|
||
if grep -q "^apply from: \"../capacitor-cordova-android-plugins/cordova.variables.gradle\"" "app/capacitor.build.gradle"; then
|
||
# Check if the referenced file actually exists
|
||
if [ ! -f "capacitor-cordova-android-plugins/cordova.variables.gradle" ]; then
|
||
log_info "🔧 Applying fix to capacitor.build.gradle..."
|
||
log_info " Reason: Referenced cordova.variables.gradle doesn't exist"
|
||
log_info " Fix: Commenting out problematic 'apply from' line"
|
||
|
||
# Apply the fix by commenting out the problematic line
|
||
# Handle macOS vs Linux sed differences
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
# macOS sed requires empty string after -i
|
||
# Use a simpler approach: just comment out the line
|
||
sed -i '' 's|^apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"|// &|' "app/capacitor.build.gradle"
|
||
else
|
||
# Linux sed
|
||
sed -i 's|^apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"|// &|' "app/capacitor.build.gradle"
|
||
fi
|
||
|
||
log_info "✅ Fix applied successfully"
|
||
log_warn "⚠️ Note: This fix will be lost if you run 'npx cap sync' or 'npx cap update'"
|
||
fi
|
||
fi
|
||
fi
|
||
|
||
# Build the plugin and test app from within the test app's Android project context
|
||
# This is necessary because Capacitor Android is only available as a project dependency
|
||
# The plugin will be built automatically as a dependency of the app
|
||
log_info "Building plugin and test app from test app context..."
|
||
|
||
# Build test app (this will automatically build the plugin as a dependency)
|
||
if ! ./gradlew clean assembleDebug; then
|
||
log_error "Build failed"
|
||
exit 1
|
||
fi
|
||
|
||
# Verify plugin was built (optional check)
|
||
PLUGIN_AAR="$(find . -name "*.aar" -path "*/timesafari-daily-notification-plugin/*" 2>/dev/null | head -1)"
|
||
if [ -n "$PLUGIN_AAR" ]; then
|
||
log_info "Plugin AAR built: $PLUGIN_AAR"
|
||
fi
|
||
|
||
# Verify APK was built
|
||
APK_FILE="app/build/outputs/apk/debug/app-debug.apk"
|
||
if [ ! -f "$APK_FILE" ]; then
|
||
log_error "APK file not found at $APK_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
log_info "Build successful: $APK_FILE"
|
||
log_info "Install with: adb install -r $APK_FILE"
|
||
|
||
cd ../../..
|
||
}
|
||
|
||
build_plugin_for_test_app_ios() {
|
||
log_info "Building iOS test app..."
|
||
|
||
# Fix pkgx interference with SQLite linking
|
||
# pkgx installs SQLite built for macOS, which causes linker errors when building for iOS simulator
|
||
if [ -n "$PKGX_DIR" ] || [ -d "$HOME/.pkgx" ]; then
|
||
log_warn "⚠️ pkgx detected - fixing SQLite linking conflicts..."
|
||
|
||
# Check for pkgx SQLite specifically
|
||
PKGX_SQLITE=$(find "$HOME/.pkgx" -name "libsqlite3*.dylib" 2>/dev/null | head -1)
|
||
if [ -n "$PKGX_SQLITE" ]; then
|
||
log_warn " Found pkgx SQLite: $PKGX_SQLITE"
|
||
log_warn " This is built for macOS and will cause iOS simulator build failures"
|
||
fi
|
||
|
||
log_warn " Temporarily unsetting PKGX_DIR and library paths for build..."
|
||
unset PKGX_DIR
|
||
unset DYLD_LIBRARY_PATH
|
||
unset LD_LIBRARY_PATH
|
||
|
||
# Also unset any pkgx-related paths that might be in PATH
|
||
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v "\.pkgx" | tr '\n' ':' | sed 's/:$//')
|
||
fi
|
||
|
||
# Ensure symlink is in place FIRST (before building)
|
||
# The test app expects the plugin at node_modules/@timesafari/daily-notification-plugin
|
||
SYMLINK="test-apps/daily-notification-test/node_modules/@timesafari/daily-notification-plugin"
|
||
if [ ! -L "$SYMLINK" ] || [ ! -e "$SYMLINK" ]; then
|
||
log_info "Creating symlink to plugin..."
|
||
mkdir -p "$(dirname "$SYMLINK")"
|
||
rm -f "$SYMLINK"
|
||
ln -sf "../../../" "$SYMLINK"
|
||
fi
|
||
|
||
# Navigate to test app directory
|
||
cd test-apps/daily-notification-test || exit 1
|
||
|
||
# Install dependencies if node_modules doesn't exist or is missing key packages
|
||
if [ ! -d "node_modules" ] || [ ! -f "node_modules/.bin/run-p" ]; then
|
||
log_info "Installing test app dependencies..."
|
||
if ! npm install; then
|
||
log_error "Failed to install test app dependencies"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# Build Vue app
|
||
log_info "Building Vue app..."
|
||
if ! npm run build; then
|
||
log_error "Vue app build failed"
|
||
exit 1
|
||
fi
|
||
|
||
# Sync Capacitor iOS (handles Podfile fixes and pod install)
|
||
log_info "Syncing Capacitor iOS..."
|
||
if ! npm run cap:sync:ios; then
|
||
log_error "Capacitor iOS sync failed"
|
||
exit 1
|
||
fi
|
||
|
||
# Build with xcodebuild
|
||
cd ios/App || exit 1
|
||
|
||
# Find workspace
|
||
if [ -d "App.xcworkspace" ]; then
|
||
WORKSPACE="App.xcworkspace"
|
||
SCHEME="App"
|
||
elif [ -d "App.xcodeproj" ]; then
|
||
PROJECT="App.xcodeproj"
|
||
SCHEME="App"
|
||
else
|
||
log_error "No Xcode workspace or project found in ios/App"
|
||
log_info "Expected: App.xcworkspace or App.xcodeproj"
|
||
exit 1
|
||
fi
|
||
|
||
# Auto-detect available iPhone simulator
|
||
log_info "Detecting available iPhone simulator..."
|
||
SIMULATOR_LINE=$(xcrun simctl list devices available 2>&1 | grep -i "iPhone" | head -1)
|
||
|
||
if [ -n "$SIMULATOR_LINE" ]; then
|
||
# Extract device ID (UUID in parentheses)
|
||
SIMULATOR_ID=$(echo "$SIMULATOR_LINE" | sed -E 's/.*\(([A-F0-9-]+)\).*/\1/')
|
||
# Extract device name (everything before the first parenthesis)
|
||
SIMULATOR_NAME=$(echo "$SIMULATOR_LINE" | sed -E 's/^[[:space:]]*([^(]+).*/\1/' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
||
|
||
if [ -n "$SIMULATOR_ID" ] && [ "$SIMULATOR_ID" != "Shutdown" ] && [ "$SIMULATOR_ID" != "Booted" ]; then
|
||
DESTINATION="platform=iOS Simulator,id=$SIMULATOR_ID"
|
||
log_info "Building for iOS Simulator ($SIMULATOR_NAME, ID: $SIMULATOR_ID)..."
|
||
elif [ -n "$SIMULATOR_NAME" ]; then
|
||
DESTINATION="platform=iOS Simulator,name=$SIMULATOR_NAME"
|
||
log_info "Building for iOS Simulator ($SIMULATOR_NAME)..."
|
||
else
|
||
DESTINATION="platform=iOS Simulator,name=iPhone 14"
|
||
log_warn "Using default simulator destination: iPhone 14"
|
||
fi
|
||
else
|
||
DESTINATION="platform=iOS Simulator,name=iPhone 14"
|
||
log_warn "No iPhone simulators found, using default: iPhone 14"
|
||
fi
|
||
|
||
# Build for simulator
|
||
log_info "Building iOS app for simulator..."
|
||
if [ -n "$WORKSPACE" ]; then
|
||
if ! xcodebuild build \
|
||
-workspace "$WORKSPACE" \
|
||
-scheme "$SCHEME" \
|
||
-configuration Debug \
|
||
-sdk iphonesimulator \
|
||
-destination "$DESTINATION" \
|
||
CODE_SIGN_IDENTITY="" \
|
||
CODE_SIGNING_REQUIRED=NO \
|
||
CODE_SIGNING_ALLOWED=NO; then
|
||
log_error "iOS build failed"
|
||
exit 1
|
||
fi
|
||
else
|
||
if ! xcodebuild build \
|
||
-project "$PROJECT" \
|
||
-scheme "$SCHEME" \
|
||
-configuration Debug \
|
||
-sdk iphonesimulator \
|
||
-destination "$DESTINATION" \
|
||
CODE_SIGN_IDENTITY="" \
|
||
CODE_SIGNING_REQUIRED=NO \
|
||
CODE_SIGNING_ALLOWED=NO; then
|
||
log_error "iOS build failed"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
log_info "iOS build successful!"
|
||
log_info "App built in DerivedData. To run: xcrun simctl boot <simulator-id> && xcrun simctl install booted <app-path>"
|
||
|
||
cd ../../..
|
||
}
|
||
|
||
build_android() {
|
||
log_info "Building Android..."
|
||
|
||
# Detect project type
|
||
if [ -d "test-apps/daily-notification-test" ]; then
|
||
log_info "Detected test app. Building plugin and test app together..."
|
||
build_plugin_for_test_app
|
||
return 0
|
||
fi
|
||
|
||
cd android || exit 1
|
||
|
||
# Check if this is a plugin development project
|
||
if [ ! -f "capacitor-cordova-android-plugins/cordova.variables.gradle" ]; then
|
||
log_warn "This appears to be a plugin development project"
|
||
log_warn "Android test app not properly initialized"
|
||
|
||
# =============================================================================
|
||
# AUTOMATIC FIX: capacitor.build.gradle for Plugin Development Projects
|
||
# =============================================================================
|
||
#
|
||
# PROBLEM: The capacitor.build.gradle file is auto-generated by Capacitor CLI
|
||
# and includes a line that tries to load a file that doesn't exist in plugin
|
||
# development projects:
|
||
# apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||
#
|
||
# WHY THIS HAPPENS:
|
||
# - This file is generated by 'npx cap sync', 'npx cap update', etc.
|
||
# - It assumes a full Capacitor app with proper plugin integration
|
||
# - Plugin development projects don't have the full Capacitor setup
|
||
#
|
||
# THE FIX:
|
||
# - Comment out the problematic line to prevent build failures
|
||
# - Add explanatory comment about why it's commented out
|
||
# - This fix gets applied automatically every time the build script runs
|
||
#
|
||
# WHEN THIS FIX GETS OVERWRITTEN:
|
||
# - Running 'npx cap sync' will regenerate the file and remove our fix
|
||
# - Running 'npx cap update' will regenerate the file and remove our fix
|
||
# - Running 'npx cap add android' will regenerate the file and remove our fix
|
||
#
|
||
# HOW TO RESTORE THE FIX:
|
||
# - Run this build script again (it will reapply the fix automatically)
|
||
# - Or run: ./scripts/fix-capacitor-build.sh
|
||
# - Or manually comment out the problematic line
|
||
#
|
||
# =============================================================================
|
||
|
||
if [ -f "app/capacitor.build.gradle" ]; then
|
||
if grep -q "^apply from: \"../capacitor-cordova-android-plugins/cordova.variables.gradle\"" "app/capacitor.build.gradle"; then
|
||
log_info "🔧 Applying automatic fix to capacitor.build.gradle..."
|
||
log_info " Reason: Plugin development project missing Capacitor integration files"
|
||
log_info " Fix: Commenting out problematic 'apply from' line"
|
||
|
||
# Apply the fix by commenting out the problematic line
|
||
# Handle macOS vs Linux sed differences
|
||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||
# macOS sed requires empty string after -i
|
||
sed -i '' 's/^apply from: "\.\.\/capacitor-cordova-android-plugins\/cordova\.variables\.gradle"/\/\/ Plugin development project - no Capacitor integration files needed\n\/\/ &/' "app/capacitor.build.gradle"
|
||
else
|
||
# Linux sed
|
||
sed -i 's/^apply from: "\.\.\/capacitor-cordova-android-plugins\/cordova\.variables\.gradle"/\/\/ Plugin development project - no Capacitor integration files needed\n\/\/ &/' "app/capacitor.build.gradle"
|
||
fi
|
||
|
||
log_info "✅ Fix applied successfully"
|
||
log_warn "⚠️ Note: This fix will be lost if you run 'npx cap sync' or 'npx cap update'"
|
||
log_info "💡 To restore the fix later, run this build script again or use: ./scripts/fix-capacitor-build.sh"
|
||
else
|
||
log_info "ℹ️ capacitor.build.gradle already has the fix applied"
|
||
fi
|
||
else
|
||
log_warn "⚠️ capacitor.build.gradle not found - this may indicate a different project structure"
|
||
fi
|
||
|
||
log_warn "Plugin source code has been built successfully"
|
||
log_warn "To test the plugin, use it in a Capacitor app instead"
|
||
cd ..
|
||
return 0
|
||
fi
|
||
|
||
# Check for gradle wrapper
|
||
if [ ! -f "./gradlew" ]; then
|
||
log_error "Gradle wrapper not found"
|
||
exit 1
|
||
fi
|
||
|
||
# Clean and build
|
||
if ! ./gradlew clean; then
|
||
log_error "Android clean failed"
|
||
exit 1
|
||
fi
|
||
|
||
if ! ./gradlew assembleRelease; then
|
||
log_error "Android build failed"
|
||
exit 1
|
||
fi
|
||
|
||
# Verify AAR file exists
|
||
AAR_FILE="capacitor-cordova-android-plugins/build/outputs/aar/capacitor-cordova-android-plugins-release.aar"
|
||
if [ ! -f "$AAR_FILE" ]; then
|
||
log_error "AAR file not found at $AAR_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
log_info "Android build successful: $AAR_FILE"
|
||
cd ..
|
||
}
|
||
|
||
build_ios() {
|
||
log_info "Building iOS..."
|
||
|
||
# Check iOS-specific requirements
|
||
check_command "xcodebuild"
|
||
check_command "pod"
|
||
|
||
# Check for Xcode
|
||
if ! xcodebuild -version &> /dev/null; then
|
||
log_error "Xcode is not installed or not properly configured"
|
||
exit 1
|
||
fi
|
||
|
||
# Check for SQLite conflicts (already done in check_environment, but remind here)
|
||
if [ -d "$HOME/.pkgx" ]; then
|
||
PKGX_SQLITE=$(find "$HOME/.pkgx" -name "libsqlite3*.dylib" 2>/dev/null | head -1)
|
||
if [ -n "$PKGX_SQLITE" ]; then
|
||
log_warn "⚠️ pkgx SQLite detected - build script will handle this automatically"
|
||
log_warn " If you still see linker errors, manually run:"
|
||
log_warn " unset PKGX_DIR DYLD_LIBRARY_PATH LD_LIBRARY_PATH && ./scripts/build-native.sh --platform ios"
|
||
fi
|
||
fi
|
||
|
||
# Detect project type
|
||
if [ -d "test-apps/daily-notification-test" ]; then
|
||
log_info "Detected test app. Building plugin and test app together..."
|
||
build_plugin_for_test_app_ios
|
||
return 0
|
||
fi
|
||
|
||
# For plugin-only builds, navigate to iOS directory
|
||
cd ios || exit 1
|
||
|
||
log_warn "This appears to be a plugin development project"
|
||
log_warn "iOS plugin source code has been built successfully"
|
||
log_warn "To test the plugin, use it in a Capacitor app instead"
|
||
|
||
# Install CocoaPods dependencies if Podfile exists
|
||
if [ -f "Podfile" ]; then
|
||
log_info "Installing CocoaPods dependencies..."
|
||
POD_CMD=$(get_pod_command)
|
||
if ! $POD_CMD install; then
|
||
log_error "CocoaPods installation failed"
|
||
exit 1
|
||
fi
|
||
fi
|
||
|
||
# Build plugin framework (if workspace exists)
|
||
if [ -d "DailyNotificationPlugin.xcworkspace" ]; then
|
||
log_info "Building iOS plugin framework..."
|
||
if ! xcodebuild build \
|
||
-workspace DailyNotificationPlugin.xcworkspace \
|
||
-scheme DailyNotificationPlugin \
|
||
-configuration Release \
|
||
-sdk iphoneos \
|
||
CODE_SIGN_IDENTITY="" \
|
||
CODE_SIGNING_REQUIRED=NO \
|
||
CODE_SIGNING_ALLOWED=NO; then
|
||
log_error "iOS plugin build failed"
|
||
exit 1
|
||
fi
|
||
log_info "iOS plugin build successful"
|
||
else
|
||
log_warn "No Xcode workspace found - plugin may need to be built in a host app"
|
||
fi
|
||
|
||
cd ..
|
||
}
|
||
|
||
# Main build process
|
||
main() {
|
||
log_info "Starting build process..."
|
||
|
||
# Parse command line arguments
|
||
BUILD_PLATFORM="all"
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--platform)
|
||
BUILD_PLATFORM="$2"
|
||
shift 2
|
||
;;
|
||
*)
|
||
log_error "Unknown option: $1"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Build TypeScript (needed for all platforms)
|
||
build_typescript
|
||
|
||
# Check environment (after parsing platform so we can check conditionally)
|
||
check_environment "$BUILD_PLATFORM"
|
||
|
||
# Build based on platform
|
||
case $BUILD_PLATFORM in
|
||
"android")
|
||
build_android
|
||
;;
|
||
"ios")
|
||
build_ios
|
||
;;
|
||
"all")
|
||
build_android
|
||
build_ios
|
||
;;
|
||
*)
|
||
log_error "Invalid platform: $BUILD_PLATFORM. Use 'android', 'ios', or 'all'"
|
||
exit 1
|
||
;;
|
||
esac
|
||
|
||
log_info "Build completed successfully!"
|
||
}
|
||
|
||
# Run main function with all arguments
|
||
main "$@" |