-
Notifications
You must be signed in to change notification settings - Fork 108
Description
Custom Toolchain and Library Linking Implementation
The Problem
The generated projects had critical issues preventing Xcode Preview App (XOJIT) functionality because it depends on:
- Missing Library Dependencies: Preview App couldn't find required static libraries (
.a
,.dylib
.. ect) during linking, causing build failures. It parses it from the build phase. - Missing Search Paths: Library search paths weren't properly configured, leading to linker errors. After adding the above, we need to add the search paths for the PreviewApp to find the .a files.
- Toolchain Misalignment: SwiftUI Preview prevents us from injecting swiftc stub. We need to geenrate an entire new xctoolchain.
The Solution
Implement a comprehensive custom toolchain system and enhanced library linking through several interconnected components:
1. Custom Toolchain Generation System
Create a fully functional Xcode toolchain that mirrors the system toolchain but allows for specific tool overrides.
2. Enhanced Library Detection and Linking
Improve library discovery to properly detect and collect library dependencies from compilation providers.
3. Build Phase Enhancement
Ensure discovered libraries are properly included in Xcode targets' build phases.
4. Project-Level Configuration
Update project settings to use custom toolchains and proper search paths to find the libs.
Implementation Progress
Custom Toolchain System
- Toolchain Discovery: Automatic Xcode version detection and version-specific toolchain identifiers (
custom_toolchain.bzl
) - Symlink Creation: Complete toolchain structure using symlinks to system toolchain for compatibility
- Tool Override Mechanism: Flexible system allowing specific tools (swiftc, clang, etc.) to be replaced with custom implementations
- Two-Stage Process: Symlinked base toolchain creation followed by override application
- Template System: Shell script templates for toolchain creation (
custom_toolchain_symlink.sh
,custom_toolchain_override.sh
)
Library Detection Enhancement
- Comprehensive Library Collection: Proper identification of static libraries (
.a
), dynamic libraries (.dylib
), and frameworks from both Objective-C and C++ compilation providers (linker_input_files.bzl
) - Search Path Generation: Automatic generation of library search paths based on discovered library locations
- Dependency Filtering: Intelligent filtering to avoid circular dependencies by excluding target's own libraries
- Framework File Tracking: Detailed tracking of framework files and their paths for proper linking
Build Phase Integration
- Link Binary Build Phase: Enhanced
CreateLinkBinaryWithLibrariesBuildPhaseObject.swift
to generate properPBXFrameworksBuildPhase
- Framework Object Creation: New
CreateFrameworkObject.swift
for framework references in Xcode project - Build File Objects:
CreateFrameworkBuildFileObject.swift
for managing build file references
Runtime Library Support
- libclang_rt.iossim.a: Hardcoded inclusion of critical runtime library for iOS Simulator builds
- Search Path Configuration: Automatic addition of runtime library location to search paths
- Toolchain Integration: Proper integration into custom toolchain structure
Project Configuration
- Build Settings: Enhanced
PBXProjectBuildSettings.swift
for custom toolchain usage - Toolchain Selection: Generated projects automatically point to custom toolchain
- Environment Setup: Proper environment configuration for consistent custom toolchain usage
Testing and Validation
- Unit Tests: Comprehensive test suite in
test/internal/custom_toolchain/
for toolchain generation - Integration Tests: Updated fixture tests ensuring generated projects work correctly
- Build Verification: Maintained compatibility with existing build processes
Project Size Optimization (High Priority)
- Problem Analysis: Current implementation generates individual product/build file references per target dependency, causing bloated project files
- Product Reference Deduplication: Implement global registry system where each unique library has exactly one product reference regardless of target usage
- Shared Build File References: Update reference system to reuse existing references when multiple targets link same library
- Search Path Consolidation: Move library search paths from target-level to project-level configuration
- Reference Management System: Centralized tracking of target-dependency relationships without duplicating references
- Testing with Large Projects: Validate improvements with complex project structures
Complexity: Medium (equivalent to 2-3 days focused development)
Dependency Detection Improvements (High Priority)
- Root Cause Investigation: Analyze why certain dependency types aren't captured by current algorithm
- Provider Analysis Enhancement: Expand logic to handle complex dependency scenarios, mixed language targets, and transitive dependencies
- Filtering Logic Refinement: Make library filtering more precise to avoid excluding valid dependencies
- Debugging Infrastructure: Add comprehensive logging and tracing for dependency discovery process
- Fallback Mechanisms: Implement alternative discovery paths for edge cases where primary analysis fails
- Validation System: Cross-reference discovered dependencies with actual linker requirements to identify gaps
- Edge Case Testing: Create comprehensive test cases for problematic configurations
Complexity: High (equivalent to 3-4 days focused development)
Performance and Polish (Medium Priority)
- Performance Profiling: Analyze toolchain generation performance and identify bottlenecks
- File Operation Optimization: Optimize file operations and implement intelligent caching
- Build Time Impact: Monitor and minimize impact on build times
- Documentation Updates: Create comprehensive documentation for new features
- Troubleshooting Guides: Develop guides for common issues and edge cases
- Monitoring System: Establish monitoring for edge cases and validation failures
Implementation Strategy
Phase 1: Project Size Optimization (Priority: High)
Focus on architectural changes to reference generation system to improve developer experience with large project files.
Approach:
- Implement shared product reference system across targets
- Update build file reference generation to reuse existing references
- Reorganize search paths to project-level configuration
- Test with existing large projects to validate improvements
Phase 2: Dependency Detection Enhancement (Priority: High)
Systematic analysis and enhancement of dependency discovery to address core functionality gaps.
Approach:
- Conduct deep investigation into dependency detection failures
- Create comprehensive test cases for problematic edge cases
- Implement enhanced dependency detection algorithms
- Add debugging infrastructure for troubleshooting complex scenarios
Phase 3: Performance and Polish (Priority: Medium)
Performance and developer experience improvements.
Approach:
- Profile toolchain generation performance and optimize bottlenecks
- Optimize file operations and implement intelligent caching
- Create comprehensive documentation and troubleshooting guides
- Establish monitoring and validation for edge cases
Technical Details
Branch: karim/add-custom-toolchain-to-generated-project
Key Files:
xcodeproj/internal/custom_toolchain.bzl
- Custom toolchain rule implementationxcodeproj/internal/files/linker_input_files.bzl
- Enhanced library detectiontools/generators/pbxnativetargets/src/Generator/CreateLinkBinaryWithLibrariesBuildPhaseObject.swift
- Build phase generationtools/generators/pbxnativetargets/src/Generator/CreateFrameworkObject.swift
- Framework object creationtools/generators/pbxproj_prefix/src/Generator/PBXProjectBuildSettings.swift
- Project build settings
Current Status
This implementation provides foundational infrastructure that enables reliable Xcode Preview usage while maintaining Bazel build benefits. The system significantly improves Preview App functionality, with remaining work focused on optimization and edge case handling rather than fundamental architectural changes.
The completed work establishes a solid foundation for iOS development workflows, and the outstanding tasks will complete the feature set for production readiness.