|
30 | 30 | # - Ubuntu/Debian: Native ROS2 installation with apt + venv |
31 | 31 | # - macOS: RoboStack with mamba/conda environment |
32 | 32 | # |
| 33 | +# MACOS-SPECIFIC HANDLING: |
| 34 | +# This script includes special handling for common macOS development environment |
| 35 | +# conflicts, particularly the Homebrew/conda library conflict that affects git |
| 36 | +# operations within conda environments. |
| 37 | +# |
| 38 | +# Git Package Conflict Resolution: |
| 39 | +# - Problem: Homebrew's git + conda's libiconv = symbol conflicts |
| 40 | +# - Solution: Pre-download git-based packages using system libraries, |
| 41 | +# then install from local copies within conda environment |
| 42 | +# - Packages affected: Any using git+https:// URLs in requirements.txt |
| 43 | +# - Fallback: If conflicts persist, install git via conda |
| 44 | +# |
33 | 45 | # REQUIREMENTS: |
34 | 46 | # Ubuntu: sudo privileges, apt package manager |
35 | 47 | # macOS: miniforge/mamba installed (script will guide if missing) |
@@ -115,6 +127,11 @@ NOTES: |
115 | 127 | - RoboStack channels are configured automatically for the selected ROS2 distribution |
116 | 128 | - For humble: ./scripts/setup_workspace.sh --ros-distro humble |
117 | 129 |
|
| 130 | +MACOS-SPECIFIC NOTES: |
| 131 | + - The script handles Homebrew/conda git conflicts automatically |
| 132 | + - Git-based packages (git+https://) are pre-downloaded to avoid library conflicts |
| 133 | + - If git issues persist, try: mamba install git -c conda-forge |
| 134 | +
|
118 | 135 | For more information, see: https://github.com/your-repo/coffee-buddy |
119 | 136 | EOF |
120 | 137 | } |
@@ -290,6 +307,97 @@ setup_ubuntu() { |
290 | 307 | log_success "ROS2 packages built successfully" |
291 | 308 | } |
292 | 309 |
|
| 310 | +# Helper function: Handle git-based packages for macOS (Homebrew/conda conflict workaround) |
| 311 | +handle_git_packages_macos() { |
| 312 | + log_info "Checking for git-based packages that need special handling..." |
| 313 | + |
| 314 | + # Create temporary directory for git package downloads |
| 315 | + local temp_dir=$(mktemp -d) |
| 316 | + local git_packages_found=false |
| 317 | + |
| 318 | + # Extract git-based packages from requirements.txt |
| 319 | + while IFS= read -r package || [[ -n "$package" ]]; do |
| 320 | + # Skip empty lines and comments |
| 321 | + [[ -z "$package" || "$package" =~ ^#.*$ ]] && continue |
| 322 | + |
| 323 | + # Check if this is a git-based package |
| 324 | + if [[ "$package" =~ ^git\+ ]]; then |
| 325 | + git_packages_found=true |
| 326 | + log_info "Found git-based package: $package" |
| 327 | + |
| 328 | + # Extract the git URL and package name |
| 329 | + local git_url=$(echo "$package" | sed 's/^git+//') |
| 330 | + local package_name=$(basename "$git_url" .git) |
| 331 | + |
| 332 | + log_info "Pre-downloading $package_name to avoid Homebrew/conda git conflicts..." |
| 333 | + |
| 334 | + # Download using system git (outside conda environment library conflicts) |
| 335 | + # We temporarily unset library search paths to use system libraries |
| 336 | + local orig_dyld_library_path="$DYLD_LIBRARY_PATH" |
| 337 | + unset DYLD_LIBRARY_PATH |
| 338 | + |
| 339 | + if git clone "$git_url" "$temp_dir/$package_name"; then |
| 340 | + log_success "Successfully downloaded $package_name" |
| 341 | + |
| 342 | + # Install from local directory using pip |
| 343 | + export DYLD_LIBRARY_PATH="$orig_dyld_library_path" |
| 344 | + log_info "Installing $package_name from local copy..." |
| 345 | + pip install "$temp_dir/$package_name" |
| 346 | + log_success "Installed $package_name" |
| 347 | + else |
| 348 | + # Restore library path and report error |
| 349 | + export DYLD_LIBRARY_PATH="$orig_dyld_library_path" |
| 350 | + log_error "Failed to download $package_name" |
| 351 | + log_error "You may need to install git in conda environment:" |
| 352 | + log_error " mamba install git -c conda-forge" |
| 353 | + |
| 354 | + # Clean up and exit |
| 355 | + rm -rf "$temp_dir" |
| 356 | + return 1 |
| 357 | + fi |
| 358 | + |
| 359 | + # Restore library path |
| 360 | + export DYLD_LIBRARY_PATH="$orig_dyld_library_path" |
| 361 | + fi |
| 362 | + done < "$REQUIREMENTS_FILE" |
| 363 | + |
| 364 | + # Clean up temporary directory |
| 365 | + rm -rf "$temp_dir" |
| 366 | + |
| 367 | + if [[ "$git_packages_found" == true ]]; then |
| 368 | + log_success "All git-based packages installed successfully" |
| 369 | + else |
| 370 | + log_info "No git-based packages found in requirements.txt" |
| 371 | + fi |
| 372 | +} |
| 373 | + |
| 374 | +# Helper function: Install regular (non-git) packages for macOS |
| 375 | +install_regular_packages_macos() { |
| 376 | + log_info "Installing regular packages via conda-forge and pip..." |
| 377 | + |
| 378 | + # Process non-git packages from requirements.txt |
| 379 | + while IFS= read -r package || [[ -n "$package" ]]; do |
| 380 | + # Skip empty lines and comments |
| 381 | + [[ -z "$package" || "$package" =~ ^#.*$ ]] && continue |
| 382 | + |
| 383 | + # Skip git-based packages (already handled) |
| 384 | + if [[ "$package" =~ ^git\+ ]]; then |
| 385 | + continue |
| 386 | + fi |
| 387 | + |
| 388 | + package_name=$(echo "$package" | cut -d'=' -f1 | cut -d'>' -f1 | cut -d'<' -f1) |
| 389 | + |
| 390 | + # Try conda-forge first |
| 391 | + if mamba install -c conda-forge "$package_name" -y 2>/dev/null; then |
| 392 | + log_info "Installed $package_name via conda" |
| 393 | + else |
| 394 | + # Fallback to pip |
| 395 | + log_info "Installing $package_name via pip..." |
| 396 | + pip install "$package" |
| 397 | + fi |
| 398 | + done < "$REQUIREMENTS_FILE" |
| 399 | +} |
| 400 | + |
293 | 401 | # macOS setup function |
294 | 402 | setup_macos() { |
295 | 403 | log_info "Setting up macOS environment with RoboStack..." |
@@ -347,22 +455,12 @@ setup_macos() { |
347 | 455 | # Step 4: Install additional Python packages |
348 | 456 | log_info "[4/5] Installing additional Python packages..." |
349 | 457 | if [ -f "$REQUIREMENTS_FILE" ]; then |
350 | | - # Try to install via conda first, fallback to pip |
351 | | - while IFS= read -r package || [[ -n "$package" ]]; do |
352 | | - # Skip empty lines and comments |
353 | | - [[ -z "$package" || "$package" =~ ^#.*$ ]] && continue |
354 | | - |
355 | | - package_name=$(echo "$package" | cut -d'=' -f1 | cut -d'>' -f1 | cut -d'<' -f1) |
356 | | - |
357 | | - # Try conda-forge first |
358 | | - if mamba install -c conda-forge "$package_name" -y 2>/dev/null; then |
359 | | - log_info "Installed $package_name via conda" |
360 | | - else |
361 | | - # Fallback to pip |
362 | | - log_info "Installing $package_name via pip..." |
363 | | - pip install "$package" |
364 | | - fi |
365 | | - done < "$REQUIREMENTS_FILE" |
| 458 | + # Step 4a: Handle git-based packages separately (macOS Homebrew/conda conflict workaround) |
| 459 | + handle_git_packages_macos |
| 460 | + |
| 461 | + # Step 4b: Install regular packages |
| 462 | + install_regular_packages_macos |
| 463 | + |
366 | 464 | log_success "Additional Python packages installed" |
367 | 465 | else |
368 | 466 | log_warning "requirements.txt not found, skipping additional Python packages" |
|
0 commit comments