mirror of
https://github.com/harivansh-afk/claude-code-vertical.git
synced 2026-04-17 03:03:44 +00:00
skills
This commit is contained in:
parent
087b195b4c
commit
ae037f7bec
24 changed files with 15692 additions and 0 deletions
513
skill-index/skills/axiom-build-debugging/SKILL.md
Normal file
513
skill-index/skills/axiom-build-debugging/SKILL.md
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
---
|
||||
name: axiom-build-debugging
|
||||
description: Use when encountering dependency conflicts, CocoaPods/SPM resolution failures, "Multiple commands produce" errors, or framework version mismatches - systematic dependency and build configuration debugging for iOS projects. Includes pressure scenario guidance for resisting quick fixes under time constraints
|
||||
skill_type: discipline
|
||||
version: 1.1.0
|
||||
last_updated: TDD-tested with production crisis scenarios
|
||||
---
|
||||
|
||||
# Build Debugging
|
||||
|
||||
## Overview
|
||||
|
||||
Check dependencies BEFORE blaming code. **Core principle** 80% of persistent build failures are dependency resolution issues (CocoaPods, SPM, framework conflicts), not code bugs.
|
||||
|
||||
## Example Prompts
|
||||
|
||||
These are real questions developers ask that this skill is designed to answer:
|
||||
|
||||
#### 1. "I added a Swift Package but I'm getting 'No such module' errors. The package is in my Xcode project but won't compile."
|
||||
→ The skill covers SPM resolution workflows, package cache clearing, and framework search path diagnostics
|
||||
|
||||
#### 2. "The build is failing with 'Multiple commands produce' the same output file. How do I figure out which files are duplicated?"
|
||||
→ The skill shows how to identify duplicate target membership and resolve file conflicts in build settings
|
||||
|
||||
#### 3. "CocoaPods installed dependencies successfully but the build still fails. How do I debug CocoaPods issues?"
|
||||
→ The skill covers Podfile.lock conflict resolution, linking errors, and version constraint debugging
|
||||
|
||||
#### 4. "My build works on my Mac but fails on the CI server. Both machines have the latest Xcode. What's different?"
|
||||
→ The skill explains dependency caching differences, environment-specific paths, and reproducible build strategies
|
||||
|
||||
#### 5. "I'm getting framework version conflicts and I don't know which dependency is causing it. How do I resolve this?"
|
||||
→ The skill demonstrates dependency graph analysis and version constraint resolution strategies for complex dependency trees
|
||||
|
||||
---
|
||||
|
||||
## Red Flags — Dependency/Build Issues
|
||||
|
||||
If you see ANY of these, suspect dependency problem:
|
||||
- "No such module" after adding package
|
||||
- "Multiple commands produce" same output file
|
||||
- Build succeeds on one machine, fails on another
|
||||
- CocoaPods install succeeds but build fails
|
||||
- SPM resolution takes forever or times out
|
||||
- Framework version conflicts in error logs
|
||||
|
||||
## Quick Decision Tree
|
||||
|
||||
```
|
||||
Build failing?
|
||||
├─ "No such module XYZ"?
|
||||
│ ├─ After adding SPM package?
|
||||
│ │ └─ Clean build folder + reset package caches
|
||||
│ ├─ After pod install?
|
||||
│ │ └─ Check Podfile.lock conflicts
|
||||
│ └─ Framework not found?
|
||||
│ └─ Check FRAMEWORK_SEARCH_PATHS
|
||||
├─ "Multiple commands produce"?
|
||||
│ └─ Duplicate files in target membership
|
||||
├─ SPM resolution hangs?
|
||||
│ └─ Clear package caches + derived data
|
||||
└─ Version conflicts?
|
||||
└─ Use dependency resolution strategies below
|
||||
```
|
||||
|
||||
## Common Build Issues
|
||||
|
||||
### Issue 1: SPM Package Not Found
|
||||
|
||||
**Symptom**: "No such module PackageName" after adding Swift Package
|
||||
|
||||
**❌ WRONG**:
|
||||
```bash
|
||||
# Rebuilding without cleaning
|
||||
xcodebuild build
|
||||
```
|
||||
|
||||
**✅ CORRECT**:
|
||||
```bash
|
||||
# Reset package caches first
|
||||
rm -rf ~/Library/Developer/Xcode/DerivedData
|
||||
rm -rf ~/Library/Caches/org.swift.swiftpm
|
||||
|
||||
# Reset packages in project
|
||||
xcodebuild -resolvePackageDependencies
|
||||
|
||||
# Clean build
|
||||
xcodebuild clean build -scheme YourScheme
|
||||
```
|
||||
|
||||
### Issue 2: CocoaPods Conflicts
|
||||
|
||||
**Symptom**: Pod install succeeds but build fails with framework errors
|
||||
|
||||
**Check Podfile.lock**:
|
||||
```bash
|
||||
# See what versions were actually installed
|
||||
cat Podfile.lock | grep -A 2 "PODS:"
|
||||
|
||||
# Compare with Podfile requirements
|
||||
cat Podfile | grep "pod "
|
||||
```
|
||||
|
||||
**Fix version conflicts**:
|
||||
```ruby
|
||||
# Podfile - be explicit about versions
|
||||
pod 'Alamofire', '~> 5.8.0' # Not just 'Alamofire'
|
||||
pod 'SwiftyJSON', '5.0.1' # Exact version if needed
|
||||
```
|
||||
|
||||
**Clean reinstall**:
|
||||
```bash
|
||||
# Remove all pods
|
||||
rm -rf Pods/
|
||||
rm Podfile.lock
|
||||
|
||||
# Reinstall
|
||||
pod install
|
||||
|
||||
# Open workspace (not project!)
|
||||
open YourApp.xcworkspace
|
||||
```
|
||||
|
||||
### Issue 3: Multiple Commands Produce Error
|
||||
|
||||
**Symptom**: "Multiple commands produce '/path/to/file'"
|
||||
|
||||
**Cause**: Same file added to multiple targets or build phases
|
||||
|
||||
**Fix**:
|
||||
1. Open Xcode
|
||||
2. Select file in navigator
|
||||
3. File Inspector → Target Membership
|
||||
4. Uncheck duplicate targets
|
||||
5. Or: Build Phases → Copy Bundle Resources → remove duplicates
|
||||
|
||||
### Issue 4: Framework Search Paths
|
||||
|
||||
**Symptom**: "Framework not found" or "Linker command failed"
|
||||
|
||||
**Check build settings**:
|
||||
```bash
|
||||
# Show all build settings
|
||||
xcodebuild -showBuildSettings -scheme YourScheme | grep FRAMEWORK_SEARCH_PATHS
|
||||
```
|
||||
|
||||
**Fix in Xcode**:
|
||||
1. Target → Build Settings
|
||||
2. Search "Framework Search Paths"
|
||||
3. Add path: `$(PROJECT_DIR)/Frameworks` (recursive)
|
||||
4. Or: `$(inherited)` to inherit from project
|
||||
|
||||
### Issue 5: SPM Version Conflicts
|
||||
|
||||
**Symptom**: Package resolution fails with version conflicts
|
||||
|
||||
**See dependency graph**:
|
||||
```bash
|
||||
# In project directory
|
||||
swift package show-dependencies
|
||||
|
||||
# Or see resolved versions
|
||||
cat Package.resolved
|
||||
```
|
||||
|
||||
**Fix conflicts**:
|
||||
```swift
|
||||
// Package.swift - be explicit
|
||||
.package(url: "https://github.com/owner/repo", exact: "1.2.3") // Exact version
|
||||
.package(url: "https://github.com/owner/repo", from: "1.2.0") // Minimum version
|
||||
.package(url: "https://github.com/owner/repo", .upToNextMajor(from: "1.0.0")) // SemVer
|
||||
```
|
||||
|
||||
**Reset resolution**:
|
||||
```bash
|
||||
# Clear package caches
|
||||
rm -rf .build
|
||||
rm Package.resolved
|
||||
|
||||
# Re-resolve
|
||||
swift package resolve
|
||||
```
|
||||
|
||||
## Dependency Resolution Strategies
|
||||
|
||||
### Strategy 1: Lock to Specific Versions
|
||||
|
||||
When stability matters more than latest features:
|
||||
|
||||
**CocoaPods**:
|
||||
```ruby
|
||||
pod 'Alamofire', '5.8.0' # Exact version
|
||||
pod 'SwiftyJSON', '~> 5.0.0' # Any 5.0.x
|
||||
```
|
||||
|
||||
**SPM**:
|
||||
```swift
|
||||
.package(url: "...", exact: "1.2.3")
|
||||
```
|
||||
|
||||
### Strategy 2: Use Version Ranges
|
||||
|
||||
When you want bug fixes but not breaking changes:
|
||||
|
||||
**CocoaPods**:
|
||||
```ruby
|
||||
pod 'Alamofire', '~> 5.8' # 5.8.x but not 5.9
|
||||
pod 'SwiftyJSON', '>= 5.0', '< 6.0' # Range
|
||||
```
|
||||
|
||||
**SPM**:
|
||||
```swift
|
||||
.package(url: "...", from: "1.2.0") // 1.2.0 and higher
|
||||
.package(url: "...", .upToNextMajor(from: "1.0.0")) // 1.x.x but not 2.0.0
|
||||
```
|
||||
|
||||
### Strategy 3: Fork and Pin
|
||||
|
||||
When you need custom modifications:
|
||||
|
||||
```bash
|
||||
# Fork repo on GitHub
|
||||
# Clone your fork
|
||||
git clone https://github.com/yourname/package.git
|
||||
|
||||
# In Package.swift, use your fork
|
||||
.package(url: "https://github.com/yourname/package", branch: "custom-fixes")
|
||||
```
|
||||
|
||||
### Strategy 4: Exclude Transitive Dependencies
|
||||
|
||||
When a dependency's dependency conflicts:
|
||||
|
||||
**SPM (not directly supported, use workarounds)**:
|
||||
```swift
|
||||
// Instead of this:
|
||||
.package(url: "https://github.com/problematic/package")
|
||||
|
||||
// Fork it and remove the conflicting dependency from its Package.swift
|
||||
```
|
||||
|
||||
**CocoaPods**:
|
||||
```ruby
|
||||
# Exclude specific subspecs
|
||||
pod 'Firebase/Core' # Not all of Firebase
|
||||
pod 'Firebase/Analytics'
|
||||
```
|
||||
|
||||
## Build Configuration Issues
|
||||
|
||||
### Debug vs Release Differences
|
||||
|
||||
**Symptom**: Builds in Debug, fails in Release (or vice versa)
|
||||
|
||||
**Check optimization settings**:
|
||||
```bash
|
||||
# Compare Debug and Release settings
|
||||
xcodebuild -showBuildSettings -configuration Debug > debug.txt
|
||||
xcodebuild -showBuildSettings -configuration Release > release.txt
|
||||
diff debug.txt release.txt
|
||||
```
|
||||
|
||||
**Common culprits**:
|
||||
- SWIFT_OPTIMIZATION_LEVEL (-Onone vs -O)
|
||||
- ENABLE_TESTABILITY (YES in Debug, NO in Release)
|
||||
- DEBUG preprocessor flag
|
||||
- Code signing settings
|
||||
|
||||
### Workspace vs Project
|
||||
|
||||
**Always open workspace with CocoaPods**:
|
||||
```bash
|
||||
# ❌ WRONG
|
||||
open YourApp.xcodeproj
|
||||
|
||||
# ✅ CORRECT
|
||||
open YourApp.xcworkspace
|
||||
```
|
||||
|
||||
**Check which you're building**:
|
||||
```bash
|
||||
# For workspace
|
||||
xcodebuild -workspace YourApp.xcworkspace -scheme YourScheme build
|
||||
|
||||
# For project only (no CocoaPods)
|
||||
xcodebuild -project YourApp.xcodeproj -scheme YourScheme build
|
||||
```
|
||||
|
||||
## Pressure Scenarios: When to Resist "Quick Fix" Advice
|
||||
|
||||
### The Problem
|
||||
|
||||
Under deadline pressure, senior engineers and teammates provide "quick fixes" based on pattern-matching:
|
||||
- "Just regenerate the lock file"
|
||||
- "Increment the build number"
|
||||
- "Delete DerivedData and rebuild"
|
||||
|
||||
These feel safe because they come from experience. **But if the diagnosis is wrong, the fix wastes time you don't have.**
|
||||
|
||||
**Critical insight** Time pressure makes authority bias STRONGER. You're more likely to trust advice when stressed.
|
||||
|
||||
### Red Flags — STOP Before Acting
|
||||
|
||||
If you hear ANY of these, pause 5 minutes before executing:
|
||||
|
||||
- ❌ **"This smells like..."** (pattern-matching, not diagnosis)
|
||||
- ❌ **"Just..."** (underestimating complexity)
|
||||
- ❌ **"This usually fixes it"** (worked once ≠ works always)
|
||||
- ❌ **"You have plenty of time"** (overconfidence about 24-hour turnaround)
|
||||
- ❌ **"This is safe"** (regenerating lock files CAN break things)
|
||||
|
||||
**Your brain under pressure** Trusts these phrases because they sound confident. Doesn't ask "but do they have evidence THIS is the root cause?"
|
||||
|
||||
### Mandatory Diagnosis Before "Quick Fix"
|
||||
|
||||
When someone senior suggests a fix under time pressure:
|
||||
|
||||
#### Step 1: Ask (Don't argue)
|
||||
```
|
||||
"I understand the pressure. Before we regenerate lock files,
|
||||
can we spend 5 minutes comparing the broken build to our
|
||||
working build? I want to know what we're fixing."
|
||||
```
|
||||
|
||||
#### Step 2: Demand Evidence
|
||||
- "What makes you think it's a lock file issue?"
|
||||
- "What changed between our last successful build and this failure?"
|
||||
- "Can we see the actual error from App Store build vs our build?"
|
||||
|
||||
#### Step 3: Document the Gamble
|
||||
```
|
||||
If we try "pod install":
|
||||
- Time to execute: 10 minutes
|
||||
- Time to learn it failed: 24 hours (next submission cycle)
|
||||
- Remaining time if it fails: 6 days
|
||||
- Alternative: Spend 1-2 hours diagnosing first
|
||||
|
||||
Cost of being wrong with quick fix: High
|
||||
Cost of spending 1 hour on diagnosis: Low
|
||||
```
|
||||
|
||||
#### Step 4: Push Back Professionally
|
||||
```
|
||||
"I want to move fast too. A 1-hour diagnosis now means we
|
||||
won't waste another 24-hour cycle. Let's document what we're
|
||||
testing before we submit."
|
||||
```
|
||||
|
||||
#### Why this works
|
||||
- You're not questioning their expertise
|
||||
- You're asking for evidence (legitimate request)
|
||||
- You're showing you understand the pressure
|
||||
- You're making the time math visible
|
||||
|
||||
### Real-World Example: App Store Review Blocker
|
||||
|
||||
**Scenario** App rejected in App Store build, passes locally.
|
||||
|
||||
**Senior says** "Regenerate lock file and resubmit (7 days buffer)"
|
||||
|
||||
#### What you do
|
||||
1. ❌ WRONG: Execute immediately, fail after 24 hours, now 6 days left
|
||||
2. ✅ RIGHT: Spend 1 hour comparing builds first
|
||||
|
||||
#### Comparison checklist
|
||||
```
|
||||
Local build that works:
|
||||
- Pod versions in Podfile.lock: [list them]
|
||||
- Xcode version: [version]
|
||||
- Derived Data: [timestamp]
|
||||
- CocoaPods version: [version]
|
||||
|
||||
App Store build that fails:
|
||||
- Pod versions used: [from error message]
|
||||
- Build system: [App Store's environment]
|
||||
- Differences: [explicitly document]
|
||||
```
|
||||
|
||||
#### After comparison
|
||||
- If versions match: Lock file isn't the issue. Skip the quick fix.
|
||||
- If versions differ: Now you understand what to fix.
|
||||
|
||||
**Time saved** 24 hours of wasted iteration.
|
||||
|
||||
### When to Trust Quick Fixes (Rare)
|
||||
|
||||
Quick fixes are safe ONLY when:
|
||||
|
||||
- [ ] You've seen this EXACT error before (not "similar")
|
||||
- [ ] You know the root cause (not "this usually works")
|
||||
- [ ] You can reproduce it locally (so you know if fix worked)
|
||||
- [ ] You have >48 hours buffer (so failure costs less)
|
||||
- [ ] You documented the fix in case you need to explain it later
|
||||
|
||||
#### In production crises, NONE of these are usually true.
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### When Adding Dependencies
|
||||
- [ ] Specify exact versions or ranges (not just latest)
|
||||
- [ ] Check for known conflicts with existing deps
|
||||
- [ ] Test clean build after adding
|
||||
- [ ] Commit lockfile (Podfile.lock or Package.resolved)
|
||||
|
||||
### When Builds Fail
|
||||
- [ ] Run mandatory environment checks (xcode-debugging skill)
|
||||
- [ ] Check dependency lockfiles for changes
|
||||
- [ ] Verify using correct workspace/project file
|
||||
- [ ] Compare working vs broken build settings
|
||||
|
||||
### Before Shipping
|
||||
- [ ] Test both Debug and Release builds
|
||||
- [ ] Verify all dependencies have compatible licenses
|
||||
- [ ] Check binary size impact of dependencies
|
||||
- [ ] Test on clean machine or CI
|
||||
|
||||
## Common Mistakes
|
||||
|
||||
### ❌ Not Committing Lockfiles
|
||||
```bash
|
||||
# ❌ BAD: .gitignore includes lockfiles
|
||||
Podfile.lock
|
||||
Package.resolved
|
||||
```
|
||||
|
||||
**Why**: Team members get different versions, builds differ
|
||||
|
||||
### ❌ Using "Latest" Version
|
||||
```ruby
|
||||
# ❌ BAD: No version specified
|
||||
pod 'Alamofire'
|
||||
```
|
||||
|
||||
**Why**: Breaking changes when dependency updates
|
||||
|
||||
### ❌ Mixing Package Managers
|
||||
```
|
||||
Project uses both:
|
||||
- CocoaPods (Podfile)
|
||||
- Carthage (Cartfile)
|
||||
- SPM (Package.swift)
|
||||
```
|
||||
|
||||
**Why**: Conflicts are inevitable, pick one primary manager
|
||||
|
||||
### ❌ Not Cleaning After Dependency Changes
|
||||
```bash
|
||||
# ❌ BAD: Just rebuild
|
||||
xcodebuild build
|
||||
|
||||
# ✅ GOOD: Clean first
|
||||
xcodebuild clean build
|
||||
```
|
||||
|
||||
### ❌ Opening Project Instead of Workspace
|
||||
When using CocoaPods, always open .xcworkspace not .xcodeproj
|
||||
|
||||
## Command Reference
|
||||
|
||||
```bash
|
||||
# CocoaPods
|
||||
pod install # Install dependencies
|
||||
pod update # Update to latest versions
|
||||
pod update PodName # Update specific pod
|
||||
pod outdated # Check for updates
|
||||
pod deintegrate # Remove CocoaPods from project
|
||||
|
||||
# Swift Package Manager
|
||||
swift package resolve # Resolve dependencies
|
||||
swift package update # Update dependencies
|
||||
swift package show-dependencies # Show dependency tree
|
||||
swift package reset # Reset package cache
|
||||
xcodebuild -resolvePackageDependencies # Xcode's SPM resolve
|
||||
|
||||
# Carthage
|
||||
carthage update # Update dependencies
|
||||
carthage bootstrap # Download pre-built frameworks
|
||||
carthage build --platform iOS # Build for specific platform
|
||||
|
||||
# Xcode Build
|
||||
xcodebuild clean # Clean build folder
|
||||
xcodebuild -list # List schemes and targets
|
||||
xcodebuild -showBuildSettings # Show all build settings
|
||||
```
|
||||
|
||||
## Real-World Impact
|
||||
|
||||
**Before** (trial-and-error with dependencies):
|
||||
- Dependency issue: 2-4 hours debugging
|
||||
- Clean builds not run consistently
|
||||
- Version conflicts surprise team
|
||||
- CI failures from dependency mismatches
|
||||
|
||||
**After** (systematic dependency management):
|
||||
- Dependency issue: 15-30 minutes (check lockfile → resolve)
|
||||
- Clean builds mandatory after dep changes
|
||||
- Explicit version constraints prevent surprises
|
||||
- CI matches local builds (committed lockfiles)
|
||||
|
||||
**Key insight** Lock down dependency versions early. Flexibility causes more problems than it solves.
|
||||
|
||||
## Resources
|
||||
|
||||
**Docs**: swift.org/package-manager, /xcode/build-system
|
||||
|
||||
**GitHub**: Carthage/Carthage
|
||||
|
||||
**Skills**: axiom-xcode-debugging
|
||||
|
||||
---
|
||||
|
||||
**History:** See git log for changes
|
||||
Loading…
Add table
Add a link
Reference in a new issue