Carthage è un gestore di dipendenze decentralizzato per progetti Cocoa (iOS, macOS, watchOS, tvOS) che compila framework binari dal codice sorgente. A differenza di CocoaPods, Carthage non modifica il progetto automaticamente — lo sviluppatore aggiunge manualmente i framework compilati a Xcode. Carthage è scritto in Swift, utilizza Cartfile per descrivere le dipendenze e supporta la compilazione parallela. Secondo il repository GitHub, Carthage ha raccolto oltre 15.000 stelle e rimane uno strumento di nicchia ma ricercato per progetti che richiedono un intervento minimo nella configurazione di Xcode.
Punti chiave
carthage bootstrap o carthage update — Carthage clona i repository e li compila in .xcframeworkCarthage è un gestore di dipendenze con architettura decentralizzata, creato nel 2014 da sviluppatori della comunità Swift. Carthage non utilizza un registro centrale di specifiche — ogni libreria viene collegata direttamente da un repository Git tramite URL o nome GitHub. Carthage scarica il codice sorgente, lo compila in un framework binario (.xcframework o .framework) e fornisce allo sviluppatore un artefatto pronto per l'integrazione manuale in un progetto Xcode.
L'architettura di Carthage include tre componenti: lo strumento CLI carthage, il file di configurazione Cartfile e la directory Carthage/Build/ con i framework compilati. La differenza chiave tra Carthage e CocoaPods è l'assenza di modifica automatica del .xcodeproj. Carthage non crea .xcworkspace, non configura flag del compilatore e non genera Pods.xcconfig. Lo sviluppatore aggiunge manualmente i framework al progetto tramite Xcode, offrendo il controllo completo sul processo di integrazione.
Carthage utilizza la compilazione parallela delle dipendenze, accelerando significativamente il processo su processori multi-core. Ogni dipendenza viene compilata come target separato e Carthage risolve automaticamente il grafo delle dipendenze transitive, compilandole nell'ordine corretto. Secondo i benchmark della comunità, Carthage compila 15–20 dipendenze in media in 30–60 secondi sui Mac moderni, più veloce di CocoaPods per progetti con molte librerie. Carthage supporta tutte le piattaforme Apple: iOS, macOS, watchOS e tvOS, e dalla versione 0.38+ — la compilazione di .xcframework universali per il supporto di simulatore e dispositivi Apple Silicon.
Carthage clona il repository Git di ogni dipendenza, passa alla versione specificata (tag, commit o ramo) ed esegue xcodebuild per compilare il framework. Carthage determina automaticamente il tipo di progetto Xcode (framework, dynamic framework, libreria statica) dallo schema di compilazione. Se un progetto ha più schemi, Carthage usa lo schema predefinito (il primo in ordine alfabetico). Dopo la compilazione, Carthage copia il framework finito in Carthage/Build/ e crea un file Cartfile.resolved con il blocco delle versioni esatte. Carthage supporta la memorizzazione nella cache dei framework compilati — la ricompilazione senza modifiche alle dipendenze viene saltata.
Le dipendenze transitive in Carthage vengono gestite tramite Cartfile.resolved: Carthage costruisce un grafo di tutte le dipendenze necessarie e le compila nell'ordine corretto. Se due librerie dipendono dalla stessa libreria di terze parti, Carthage la compila una volta e la usa per entrambe. Carthage segnala errori di compilazione indicando il target specifico e la causa — questo semplifica la diagnosi dei problemi.
Cartfile è un file di configurazione con sintassi simile a Ruby (formato Cartfile) che definisce le dipendenze di un progetto Carthage. Cartfile si trova nella radice del progetto accanto a .xcodeproj. Ogni riga di Cartfile descrive una dipendenza: la fonte (URL Git, repository GitHub) e la versione. La sintassi supporta il blocco delle versioni tramite tag, commit e rami.
# Dipendenze di base Carthage
github "Alamofire/Alamofire" ~> 5.9
github "SnapKit/SnapKit" ~> 5.7
github "onevcat/Kingfisher" == 8.0.0La direttiva github "Owner/Repo" è una forma abbreviata per i repository GitHub. Carthage costruisce automaticamente l'URL https://github.com/Owner/Repo.git. Per GitLab, Bitbucket e altri host Git, viene utilizzato l'URL completo: git "https://gitlab.com/owner/repo.git". Operatori di versione: ~> 5.9 (qualsiasi versione da 5.9 a 6.0, esclusa 6.0), == 8.0.0 (versione esatta), >= 1.0 (versione minima). È possibile bloccare un commit specifico tramite github "owner/repo" "abc1234".
Carthage supporta più directory per diverse configurazioni: Cartfile (principale), Cartfile.private (per dipendenze interne non pubblicate) e Cartfile.resolved (generato automaticamente). Le dipendenze private sono utili per librerie utilizzate solo nelle compilazioni di sviluppo, come i framework di test.
# Cartfile — dipendenze principali
github "Alamofire/Alamofire" ~> 5.9
github "SwiftyJSON/SwiftyJSON" ~> 4.0
github "realm/realm-swift" ~> 10.0
# URL completo URL per GitLab
git "https://gitlab.com/company/internal-lib.git" == 2.1.1
# Ramo di sviluppo
github "marmelroy/PhoneNumberKit" "development"github e git sono due tipi di fonti in Cartfile. Il primo è esclusivamente per GitHub e genera automaticamente l'URL. Il secondo è per qualsiasi repository Git pubblico o privato con URL completo. Una versione può essere specificata come tag (== 2.1.1), intervallo semantico (~> 5.9), nome ramo ("development") o hash di commit ("a1b2c3d"). Gli intervalli semantici (~>) sono raccomandati per le dipendenze che seguono SemVer — questo protegge da modifiche sostanziali durante gli aggiornamenti.
Cartfile.resolved viene generato automaticamente dopo carthage update. Blocca le versioni esatte di tutte le dipendenze installate, incluse quelle transitive. Questo file dovrebbe essere mantenuto in Git — senza di esso, il comando carthage bootstrap su un'altra macchina compilerà le librerie con le stesse regole, ma le versioni potrebbero differire. carthage outdated mostra un elenco di dipendenze obsolete per le quali sono disponibili nuove versioni.
Carthage viene installato tramite Homebrew — il gestore di pacchetti standard per macOS. Metodi alternativi: installazione da un installer .pkg compilato da GitHub o compilazione dal codice sorgente. Carthage richiede Xcode con Command Line Tools (incluso xcodebuild) e su Mac Apple Silicon — Rosetta 2 per alcune dipendenze legacy.
# Installazione Carthage tramite Homebrew
brew install carthage
# Verifica versione
carthage version
# Installazione da .pkg (se Homebrew non disponibile)
# Scarica Carthage.pkg da GitHub Releases e installare manualmenteDopo aver installato Carthage, l'inizializzazione del progetto inizia con la creazione di un Cartfile nella radice del progetto. Carthage non ha un comando init — il file viene creato manualmente in un editor di testo. Dopo aver popolato il Cartfile con le dipendenze, lo sviluppatore esegue carthage bootstrap (se Cartfile.resolved esiste già) o carthage update (installazione iniziale o aggiornamento). Carthage clona i repository, compila i framework e li colloca in Carthage/Build/.
Aggiornare Carthage si fa tramite brew upgrade carthage. La versione viene verificata con carthage version. L'ultima versione stabile a metà 2025 è la 0.40 con supporto predefinito di .xcframework, compilazione parallela migliorata e pieno supporto di Swift 6. A partire dalla versione 0.39, Carthage ha smesso di compilare i .framework legacy senza uno shim di compatibilità — si raccomanda di specificare esplicitamente --use-xcframeworks.
# Aggiornamento Carthage tramite Homebrew
brew upgrade carthage
# Installare una versione specifica
brew install carthage@0.39
# Reinstallazione completa
brew uninstall carthage && brew install carthageNota: Carthage non crea .xcworkspace e non modifica .xcodeproj. A differenza di CocoaPods, Carthage lascia il controllo completo della configurazione di Xcode allo sviluppatore. Ciò significa che dopo aver installato le dipendenze, è necessario aggiungere manualmente i framework a Xcode (vedere la sezione «Integrazione dei framework Carthage in Xcode»). Carthage richiede anche che ogni dipendenza contenga un progetto Xcode o workspace con un target framework — altrimenti la compilazione fallirà.
Carthage offre tre comandi principali per lavorare con le dipendenze: bootstrap, update e build. carthage bootstrap compila le dipendenze da un Cartfile.resolved esistente — raccomandato per ambienti CI e sviluppatori che si uniscono al progetto. carthage update aggiorna Cartfile.resolved alle ultime versioni (rispettando i vincoli di Cartfile) ed esegue la compilazione. carthage build compila tutte le dipendenze specificate senza salvare le versioni.
# Installazione iniziale (aggiorna le versioni)
carthage update --use-xcframeworks --platform iOS
# Ricompilazione con versioni bloccate
carthage bootstrap --use-xcframeworks --platform iOS
# Compilare solo una dipendenza
carthage build Alamofire --platform iOSIl flag --use-xcframeworks indica a Carthage di compilare .xcframework universali invece dei .framework legacy. Ciò garantisce il supporto sia del simulatore che di un dispositivo reale, oltre che dei Mac Apple Silicon senza script aggiuntivi. Il flag --platform iOS limita la compilazione a una singola piattaforma iOS — questo accelera significativamente il processo, specialmente se il progetto include librerie multipiattaforma.
Carthage supporta la compilazione parallela tramite il flag --cache-builds, che memorizza nella cache i framework già compilati. Durante la ricompilazione, Carthage verifica l'hash del commit Git e, se il codice non è cambiato, salta la compilazione. Per i server CI, si raccomanda di memorizzare nella cache la directory Carthage/Build/ e ~/Library/Caches/carthage/. Carthage supporta anche --verbose per la registrazione dettagliata e --no-use-binaries per la compilazione forzata dal codice sorgente (se lo sviluppatore non si fida dei binari precompilati).
| Comando | Azione |
|---|---|
carthage update | Aggiorna Cartfile.resolved e compila tutti i framework |
carthage bootstrap | Compila i framework da Cartfile.resolved esistente senza aggiornare |
carthage build | Compila le dipendenze specificate senza fissare le versioni |
carthage outdated | Mostra un elenco di dipendenze con aggiornamenti disponibili |
carthage checkout | Clona solo i repository senza compilare |
Integrazione dei framework Carthage in Xcode viene eseguita manualmente in quattro passaggi. Dopo aver eseguito carthage update o bootstrap, tutti i framework compilati si trovano in Carthage/Build/iOS/ (o nella piattaforma corrispondente). Lo sviluppatore apre il progetto Xcode, seleziona il target dell'app e aggiunge i framework in General → Frameworks, Libraries, and Embedded Content. Per i framework runtime (librerie dinamiche), è necessario selezionare «Embed & Sign» — altrimenti l'app si bloccherà all'avvio con l'errore «dyld: Library not loaded».
Carthage per le librerie statiche è più semplice — non richiedono una fase di embed poiché vengono linkate direttamente nel file eseguibile dell'app. Tuttavia, Carthage compila framework dinamici per impostazione predefinita (tranne per le librerie statiche esplicitamente configurate). Per i progetti in cui è importante ridurre al minimo le dimensioni dell'app, si consiglia il linking statico tramite le impostazioni di Xcode.
Un passaggio aggiuntivo è l'aggiunta di Input Files in Build Phase → Run Script. Carthage richiede uno script per rimuovere gli artefatti del simulatore dal framework compilato (strip simulator architectures). Questo script è necessario per le build dell'App Store:
# Run Script per App Store (strip simulator architectures)
FRAMEWORKS_DIR="${SRCROOT}/Carthage/Build/iOS"
for framework in "$FRAMEWORKS_DIR"/*.framework; do
bash "$BUILD_DIR/src/scripts/strip-framework.sh" "$framework"
doneCarthage non richiede l'uso di .xcworkspace — tutte le dipendenze sono già compilate in framework binari. Carthage funziona direttamente con .xcodeproj, a differenza di CocoaPods che crea un workspace. Ciò semplifica il controllo versione e la configurazione CI, poiché le dipendenze di Carthage non modificano la configurazione del progetto Xcode. L'unica modifica è l'aggiunta di framework al target, che viene registrata in .pbxproj.
| Passaggio | Azione |
|---|---|
| 1 | Eseguire carthage update --use-xcframeworks |
| 2 | Trascinare i framework da Carthage/Build/ in General → Frameworks |
| 3 | Impostare Embed & Sign per i framework dinamici |
| 4 | Aggiungere Run Script Phase per rimuovere le architetture del simulatore |
| 5 | Compilare il progetto — i framework dovrebbero linkarsi automaticamente |
Carthage, CocoaPods e Swift Package Manager (SPM) sono i tre principali gestori di dipendenze nello sviluppo iOS. Carthage si distingue per il suo approccio decentralizzato, CocoaPods offre un registro centralizzato e SPM è la soluzione integrata di Apple. La scelta tra di essi dipende dai requisiti del progetto, dalle dimensioni del team e dal livello di automazione desiderato.
| Criterio | Carthage | CocoaPods | SPM |
|---|---|---|---|
| Architettura | Decentralizzata | Registro centralizzato | Integrato in Xcode |
| Linguaggio di configurazione | Cartfile (simile a Ruby) | Podfile (DSL Ruby) | Package.swift (Swift) |
| Integrazione con Xcode | Manuale (trascina e rilascia) | Tramite workspace | Integrata |
| Dipendenze transitive | Automatiche | Automatiche | Automatiche |
| Registro librerie | Nessuno (repository Git) | 100.000+ in Specs | ~65.000 |
| Supporto risorse | No | Sì (resource bundles) | Sì (Resources) |
| Velocità di compilazione | Veloce (parallela) | Media | Veloce |
| Controllo dell'integrazione | Completo | Automatico | Automatico |
Carthage viene scelto per progetti che richiedono un intervento minimo nella configurazione di Xcode e il controllo completo sul processo di integrazione. Carthage è ideale per librerie e framework open source dove l'autore vuole consentire agli utenti di compilare le dipendenze in modo indipendente. Carthage è anche popolare tra gli sviluppatori che apprezzano la filosofia UNIX: ogni strumento fa bene una cosa. CocoaPods rimane lo standard per i progetti aziendali con decine di dipendenze dove l'automazione è importante. SPM è la scelta per i nuovi progetti poiché è integrato in Xcode e attivamente sviluppato da Apple.
Migrazione tra i gestori richiede approcci diversi. Carthage → SPM: rimuovere i framework da Xcode, eliminare Cartfile e aggiungere Package Dependencies tramite File → Add Package Dependencies. Carthage → CocoaPods: rimuovere i framework Carthage, creare un Podfile, aggiungere le dipendenze ed eseguire pod init && pod install. Durante la migrazione da Carthage a CocoaPods o SPM, la necessità di aggiornare manualmente i framework scompare — tutte le dipendenze vengono aggiornate con un unico comando. Carthage rimane rilevante per progetti in cui è importante evitare il vendor lock-in e mantenere la trasparenza della compilazione delle dipendenze.
Carthage è uno strumento stabile, ma gli sviluppatori incontrano periodicamente problemi tipici, specialmente durante la compilazione su server CI, l'aggiornamento di Xcode o il cambio di versioni di Swift. La maggior parte dei problemi viene risolta pulendo la cache, configurando correttamente --use-xcframeworks e verificando la versione minima di iOS.
Errore «The file manager returned an error» — si verifica quando la cache di Carthage è danneggiata o c'è un conflitto di permessi dei file. Soluzione: eliminare la cache con rm -rf ~/Library/Caches/carthage e riavviare carthage bootstrap. Aiuta anche eliminare la directory Carthage/ nel progetto e ricompilare. Sui server CI, la cache di Carthage dovrebbe essere aggiornata solo quando Cartfile.resolved cambia.
Errore «No such module» — il framework non viene trovato in Xcode nonostante la compilazione Carthage sia riuscita. Soluzione: verificare il percorso del framework in General → Frameworks, Libraries, and Embedded Content. Il framework dovrebbe trovarsi in Carthage/Build/iOS/. Assicurarsi che .xcframework sia aggiunto correttamente (trascinarlo di nuovo). Per i framework dinamici, verificare Embed & Sign. Se l'errore persiste, aggiungere FRAMEWORK_SEARCH_PATHS in Build Settings.
Errore di compilazione dovuto a incompatibilità Swift — la libreria è stata compilata per una versione di Swift diversa dal progetto. Soluzione: utilizzare carthage update --no-use-binaries per forzare la compilazione dal codice sorgente con la stessa versione di Swift. Se la libreria non compila sotto la versione corrente, utilizzare .xcconfig per specificare la versione di Swift o fare un fork della libreria. Da Carthage 0.39, --use-xcframeworks include automaticamente la versione corretta di Swift nel binario.
Problemi di compilazione CI — Carthage su CI richiede una corretta configurazione della cache. Soluzione: memorizzare nella cache Carthage/Build/ e ~/Library/Caches/carthage/. Utilizzare carthage bootstrap --use-xcframeworks --platform iOS invece di update su CI per evitare di cambiare versioni. Un'azione ufficiale Carthage è disponibile per GitHub Actions. Per Jenkins — il plugin CarthageBuild. Carthage potrebbe bloccarsi su macOS senza GUI — soluzione: installare brew install xcode-build-server o aggiungere il flag -UseModernBuildSystem=NO.
| Problema | Causa | Soluzione |
|---|---|---|
| Errore file manager | Cache danneggiata | Pulire ~/Library/Caches/carthage/ |
| No such module | Framework non aggiunto in Xcode | Verificare Frameworks nel target |
| Incompatibilità Swift | Versioni Swift diverse | --no-use-binaries o versione più recente di Carthage |
| Errore CI | Mancanza di cache o GUI | Configurare cache Carthage/Build/ |
| Libreria non compila | Nessun progetto Xcode per la libreria | Verificare struttura del repository |
Domande frequenti
Carthage è un gestore di dipendenze decentralizzato per piattaforme Apple. A differenza di CocoaPods, Carthage non utilizza un registro centrale di librerie, non modifica automaticamente il progetto Xcode e non crea .xcworkspace. Carthage compila le dipendenze in framework binari che lo sviluppatore aggiunge manualmente a Xcode. CocoaPods, invece, automatizza l'intero processo tramite Podfile.
Carthage viene installato tramite Homebrew: brew install carthage. In alternativa — scaricare Carthage.pkg da GitHub Releases o compilare dal codice sorgente. Dopo l'installazione, verificare la versione: carthage version. Carthage richiede Xcode con Command Line Tools. Su Mac Apple Silicon, potrebbe essere necessario Rosetta 2.
Cartfile è un file di configurazione scritto dallo sviluppatore: contiene nomi di librerie e operatori di versione (~> 5.9, == 8.0.0, nome ramo). Cartfile.resolved viene generato automaticamente durante carthage update e blocca le versioni esatte di tutte le dipendenze installate. Cartfile.resolved dovrebbe essere mantenuto in Git — garantisce la riproducibilità della compilazione su tutte le macchine.
Carthage richiede che la libreria contenga un progetto Xcode o workspace valido con un target framework. Verificare che il repository sia accessibile (non privato senza chiave), che la versione corretta sia specificata (il tag o commit esiste) e che la libreria supporti la versione di Xcode in uso. Utilizzare carthage build --verbose per una diagnosi dettagliata. Se la libreria non ha un target framework, Carthage non può compilarla.
Carthage rimane rilevante per progetti che richiedono gestione decentralizzata delle dipendenze, controllo completo sull'integrazione e interferenza minima con il progetto Xcode. Tuttavia, la maggior parte dei nuovi progetti sceglie Swift Package Manager (SPM) — è integrato in Xcode, non richiede installazione aggiuntiva ed è attivamente sviluppato da Apple. Carthage è raccomandato per progetti legacy in cui la pipeline di compilazione è già stabilita, o per librerie i cui autori vogliono dare agli utenti la libertà di scegliere il metodo di integrazione.
Riepilogo
brew install carthage e la compilazione delle dipendenze tramite carthage bootstrap o carthage update--no-use-binaries e la configurazione della cache CISvilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche