Carthage: cos'è, gestore di dipendenze decentralizzato

Autore: IT Sectr Pubblicato: 2026-02-12 Tempo di lettura: 8 min

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 è un gestore di dipendenze decentralizzato: nessun registro centrale, le librerie sono collegate direttamente da repository Git
  • Cartfile è un file di configurazione che elenca le dipendenze, le loro versioni e fonti (Git, GitHub, GitLab)
  • La compilazione dei framework viene eseguita con carthage bootstrap o carthage update — Carthage clona i repository e li compila in .xcframework
  • L'integrazione con Xcode è manuale: lo sviluppatore aggiunge i framework compilati in General → Frameworks, Libraries, and Embedded Content
  • Cartfile.resolved fissa le versioni esatte delle dipendenze, garantendo la riproducibilità della compilazione simile a Podfile.lock
  • Carthage vs CocoaPods vs SPM: Carthage dà il massimo controllo ma richiede più lavoro manuale; CocoaPods automatizza tutto; SPM è integrato in Xcode

Cos'è Carthage?

Carthage è 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.

Come funziona Carthage

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: struttura, sintassi ed esempi

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.

ruby
# Dipendenze di base Carthage
github "Alamofire/Alamofire" ~> 5.9
github "SnapKit/SnapKit" ~> 5.7
github "onevcat/Kingfisher" == 8.0.0

La 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".

Esempio completo di Cartfile

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.

ruby
# 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.

Installazione e configurazione di Carthage

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.

bash
# 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 manualmente

Dopo 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.

bash
# Aggiornamento Carthage tramite Homebrew
brew upgrade carthage

# Installare una versione specifica
brew install carthage@0.39

# Reinstallazione completa
brew uninstall carthage && brew install carthage

Nota: 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à.

Compilazione di framework: bootstrap e update

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.

bash
# 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 iOS

Il 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).

ComandoAzione
carthage updateAggiorna Cartfile.resolved e compila tutti i framework
carthage bootstrapCompila i framework da Cartfile.resolved esistente senza aggiornare
carthage buildCompila le dipendenze specificate senza fissare le versioni
carthage outdatedMostra un elenco di dipendenze con aggiornamenti disponibili
carthage checkoutClona solo i repository senza compilare

Integrazione dei framework Carthage in Xcode

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:

bash
# 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"
done

Carthage 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.

PassaggioAzione
1Eseguire carthage update --use-xcframeworks
2Trascinare i framework da Carthage/Build/ in General → Frameworks
3Impostare Embed & Sign per i framework dinamici
4Aggiungere Run Script Phase per rimuovere le architetture del simulatore
5Compilare il progetto — i framework dovrebbero linkarsi automaticamente

Carthage vs CocoaPods vs Swift Package Manager

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.

CriterioCarthageCocoaPodsSPM
ArchitetturaDecentralizzataRegistro centralizzatoIntegrato in Xcode
Linguaggio di configurazioneCartfile (simile a Ruby)Podfile (DSL Ruby)Package.swift (Swift)
Integrazione con XcodeManuale (trascina e rilascia)Tramite workspaceIntegrata
Dipendenze transitiveAutomaticheAutomaticheAutomatiche
Registro librerieNessuno (repository Git)100.000+ in Specs~65.000
Supporto risorseNoSì (resource bundles)Sì (Resources)
Velocità di compilazioneVeloce (parallela)MediaVeloce
Controllo dell'integrazioneCompletoAutomaticoAutomatico

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.

Problemi comuni e loro soluzioni

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.

ProblemaCausaSoluzione
Errore file managerCache danneggiataPulire ~/Library/Caches/carthage/
No such moduleFramework non aggiunto in XcodeVerificare Frameworks nel target
Incompatibilità SwiftVersioni Swift diverse--no-use-binaries o versione più recente di Carthage
Errore CIMancanza di cache o GUIConfigurare cache Carthage/Build/
Libreria non compilaNessun progetto Xcode per la libreriaVerificare struttura del repository

Domande frequenti

Cos'è Carthage e in cosa è diverso da CocoaPods?

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.

Come installare Carthage su macOS?

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.

In cosa differisce Cartfile da Cartfile.resolved?

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.

Perché Carthage non compila una libreria dal mio Cartfile?

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.

Dovrei usare Carthage nel 2025–2026?

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

  • Carthage è un gestore di dipendenze decentralizzato per iOS, macOS, watchOS e tvOS che compila framework da fonti di repository Git
  • Cartfile è un file di configurazione con sintassi che supporta repository GitHub, URL Git arbitrari e versionamento semantico
  • Installazione viene effettuata tramite brew install carthage e la compilazione delle dipendenze tramite carthage bootstrap o carthage update
  • Integrazione con Xcode è manuale: i framework vengono aggiunti in General → Frameworks, Libraries, and Embedded Content con l'opzione Embed & Sign
  • Cartfile.resolved blocca le versioni esatte di tutte le dipendenze, garantendo la riproducibilità della compilazione su CI e tutte le macchine del team
  • Problemi comuni (cache, incompatibilità Swift, errori CI) vengono risolti pulendo la cache, con il flag --no-use-binaries e la configurazione della cache CI
  • Scelta del gestore: Carthage — per il controllo completo, CocoaPods — per l'automazione, SPM — per nuovi progetti con integrazione incorporata

Svilupperemo 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.

Discuti il progetto

Leggi anche