fix(build): add SQLite conflict detection and Command Line Tools verification

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
This commit is contained in:
Jose Olarte III
2026-01-15 18:34:33 +08:00
parent 5247ebeecb
commit 2915fe7438
2 changed files with 137 additions and 76 deletions

View File

@@ -1,76 +1,47 @@
refactor(android): Complete plugin refactoring and safety fixes (Batches 0-7) fix(build): add SQLite conflict detection and Command Line Tools verification
Comprehensive refactoring to make DailyNotificationPlugin a thin adapter, Prevents iOS build failures caused by pkgx SQLite linking conflicts and
eliminate duplicated logic, remove unsafe operations, and harden security. ensures Xcode Command Line Tools are properly installed.
Batch 0 - Constants Centralization: Problem:
- Created DailyNotificationConstants.kt to eliminate magic numbers and duplicates - pkgx installs SQLite built for macOS, causing linker errors when building
- Centralized: PERMISSION_REQUEST_CODE, channel constants, intent actions/extras, for iOS simulator: "linking in dylib built for 'macOS'"
SharedPreferences keys, WorkManager tags, notification IDs - Missing Command Line Tools cause build failures without clear error messages
- Replaced duplicates across Plugin, PermissionManager, ChannelManager, Scheduler
Batch 1 - Permission Flow Unification: Changes:
- Created PermissionStatus.kt data class for unified permission reporting - Add check_sqlite_conflicts() function
- Added PermissionManager.getPermissionStatus() as single source of truth - Detects pkgx SQLite installations in ~/.pkgx
- Implemented PendingPermissionRequest tracking for reliable resume resolution - Warns about macOS dylibs that will cause iOS simulator build failures
- Replaced method-name-based resume logic with token-based tracking - Checks for system SQLite from Command Line Tools
- Plugin now delegates all permission checks to PermissionManager - Validates library paths (DYLD_LIBRARY_PATH, LD_LIBRARY_PATH)
Batch 2 - Notification Status Checker Hardening: - Add check_command_line_tools() function
- Modified NotificationStatusChecker to always check OS-level notification - Verifies Xcode Command Line Tools are installed and configured
enablement via NotificationManagerCompat.areNotificationsEnabled() - Checks for xcodebuild availability
- Added getReadinessReport() method providing comprehensive status with issues - Verifies sqlite3 is available (part of Command Line Tools)
and actionable guidance - Provides clear error messages with installation instructions
- Plugin checkStatus() now uses readiness report
Batch 3 - Cancel Semantics Safety: - Enhance pkgx detection in iOS build functions
- Removed unsafe brute-force cancellation loop (was trying request codes 0-100) - Specifically searches for pkgx SQLite dylibs
- Cancellation now only targets alarms proven to exist in database - Automatically removes pkgx paths from PATH environment variable
- Prevents accidental cancellation of other alarms and false confidence - Provides detailed warnings about detected conflicts
- Cleans all problematic environment variables before building
Batch 4 - Legacy Scheduler Removal: - Integrate checks into environment validation
- Removed unused legacy scheduleExactAlarm() method (48 lines) - Runs automatically when building for iOS
- All scheduling now goes through modern paths: - Provides early warnings before build starts
1. exactAlarmManager.scheduleAlarm() (if available) - Fails fast with clear error messages if tools are missing
2. pendingIntentManager.scheduleExactAlarm() (modern path)
3. pendingIntentManager.scheduleWindowedAlarm() (fallback)
Batch 5 - Input Contract Tightening: This fixes the linker error:
- Enforced single input shape for updateStarredPlans: { planIds: string[] } "ld: building for 'iOS-simulator', but linking in dylib
- Added validation: rejects non-array, non-string elements, empty strings (/Users/trent/.pkgx/sqlite.org/v3.44.2/lib/libsqlite3.0.dylib)
- Legacy support: single string normalized to array (with warning) built for 'macOS'"
- Clear error messages for contract violations
Batch 6 - Token Storage Security: The build script now:
- Added explicit opt-in for JWT token persistence (persistToken: true) - Detects pkgx SQLite conflicts before building
- Default behavior: tokens NOT persisted (secure default) - Automatically fixes environment variables
- Security warnings logged when persistence is enabled - Verifies Command Line Tools are installed
- Documents unencrypted storage risk - Provides clear guidance for manual fixes if needed
Batch 7 - Plugin Thinning:
- Moved getExactAlarmStatus() to PermissionManager.getExactAlarmStatus()
- Moved canRequestExactAlarmPermission() to PermissionManager
- Removed direct AlarmManager access in cancelAllNotifications()
- Delegated scheduleUserNotification/scheduleDualNotification permission
handling to PermissionManager.requestExactAlarmPermission()
- Removed unused imports: AlarmManager, PendingIntent, PowerManager,
NotificationManagerCompat
Result:
- Plugin is now a thin adapter delegating to services
- No duplicated permission logic
- No unsafe cancellation operations
- No legacy scheduler paths
- Secure token storage defaults
- Clear input contracts
- Comprehensive status reporting
Files modified: Files modified:
- DailyNotificationConstants.kt (new) - scripts/build-native.sh
- PermissionStatus.kt (new)
- DailyNotificationPlugin.kt (thinned, ~500 lines refactored)
- PermissionManager.java (enhanced with status methods)
- NotificationStatusChecker.java (hardened)
- DailyNotificationScheduler.java (legacy removed)
Refs: Cursor directive Batches 0-7

View File

@@ -47,6 +47,75 @@ get_pod_command() {
fi 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() { check_environment() {
local PLATFORM=$1 local PLATFORM=$1
@@ -86,7 +155,13 @@ check_environment() {
fi fi
if [ "$PLATFORM" = "ios" ] || [ "$PLATFORM" = "all" ]; then if [ "$PLATFORM" = "ios" ] || [ "$PLATFORM" = "all" ]; then
# iOS checks are done in build_ios() function # 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 # to avoid failing if iOS tools aren't available when building Android only
: :
fi fi
@@ -188,13 +263,25 @@ build_plugin_for_test_app() {
build_plugin_for_test_app_ios() { build_plugin_for_test_app_ios() {
log_info "Building iOS test app..." log_info "Building iOS test app..."
# Warn about pkgx interference with SQLite linking # 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 if [ -n "$PKGX_DIR" ] || [ -d "$HOME/.pkgx" ]; then
log_warn "⚠️ pkgx detected - this may interfere with iOS SQLite linking" log_warn "⚠️ pkgx detected - fixing SQLite linking conflicts..."
log_warn " Temporarily unsetting PKGX_DIR and DYLD_LIBRARY_PATH for build..."
# 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 PKGX_DIR
unset DYLD_LIBRARY_PATH unset DYLD_LIBRARY_PATH
unset LD_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 fi
# Ensure symlink is in place FIRST (before building) # Ensure symlink is in place FIRST (before building)
@@ -431,11 +518,14 @@ build_ios() {
exit 1 exit 1
fi fi
# Warn about pkgx interference with SQLite linking # Check for SQLite conflicts (already done in check_environment, but remind here)
if [ -n "$PKGX_DIR" ] || [ -d "$HOME/.pkgx" ]; then if [ -d "$HOME/.pkgx" ]; then
log_warn "⚠️ pkgx detected - this may interfere with iOS SQLite linking" PKGX_SQLITE=$(find "$HOME/.pkgx" -name "libsqlite3*.dylib" 2>/dev/null | head -1)
log_warn " If you see 'sqlite3' undefined symbol errors, try:" if [ -n "$PKGX_SQLITE" ]; then
log_warn " unset PKGX_DIR && unset DYLD_LIBRARY_PATH && ./scripts/build-native.sh --platform ios" 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 fi
# Detect project type # Detect project type