Carthage — zdecentralizowany menedżer zależności dla projektów Cocoa (iOS, macOS, watchOS, tvOS), który buduje binarne frameworki z kodu źródłowego. W przeciwieństwie do CocoaPods, Carthage nie modyfikuje projektu automatycznie — programista samodzielnie dodaje zbudowane frameworki w Xcode. Carthage jest napisany w Swift, używa Cartfile do opisywania zależności i obsługuje równoległe budowanie. Według danych repozytorium GitHub, Carthage zebrał ponad 15 000 gwiazdek i pozostaje niszowym, ale poszukiwanym narzędziem dla projektów wymagających minimalnej ingerencji w konfigurację Xcode.
Najważniejsze
carthage bootstrap lub carthage update — Carthage klonuje repozytoria i kompiluje je do .xcframeworkCarthage — menedżer zależności o zdecentralizowanej architekturze, stworzony w 2014 roku przez programistów ze społeczności Swift. Carthage nie używa centralnego rejestru specyfikacji — każda biblioteka podłączana jest bezpośrednio z repozytorium Git przez URL lub nazwę na GitHubie. Carthage pobiera kod źródłowy, buduje go w binarny framework (.xcframework lub .framework) i dostarcza programiście gotowy artefakt do ręcznej integracji z projektem Xcode.
Architektura Carthage obejmuje trzy komponenty: narzędzie CLI carthage, plik konfiguracyjny Cartfile i katalog Carthage/Build/ z zbudowanymi frameworkami. Zasadnicza różnica między Carthage a CocoaPods — brak automatycznej modyfikacji .xcodeproj. Carthage nie tworzy .xcworkspace, nie konfiguruje flag kompilatora ani nie generuje Pods.xcconfig. Programista samodzielnie dodaje frameworki do projektu przez Xcode, co daje pełną kontrolę nad procesem integracji.
Carthage używa równoległego budowania zależności, co znacząco przyspiesza proces na wielordzeniowych procesorach. Każda zależność budowana jest jako osobny target, a Carthage automatycznie rozwiązuje graf zależności przechodnich, budując je w odpowiedniej kolejności. Według benchmarków społeczności, Carthage buduje 15–20 zależności średnio w 30–60 sekund na nowoczesnych Macach, co jest szybsze niż CocoaPods dla projektów z dużą liczbą bibliotek. Carthage obsługuje wszystkie platformy Apple: iOS, macOS, watchOS i tvOS, a od wersji 0.38+ — budowanie uniwersalnych .xcframework do obsługi symulatorów i urządzeń Apple Silicon.
Carthage klonuje repozytorium Git każdej zależności, przełącza się na wskazaną wersję (tag, commit lub gałąź) i uruchamia xcodebuild do budowania frameworka. Carthage określa typ projektu Xcode (framework, dynamic framework, biblioteka statyczna) automatycznie po schemacie budowania. Jeśli projekt zawiera wiele schematów, Carthage używa schematu domyślnego (pierwszego w kolejności alfabetycznej). Po budowaniu Carthage kopiuje gotowy framework do Carthage/Build/ i tworzy plik Cartfile.resolved z ustaleniem dokładnych wersji. Carthage obsługuje buforowanie zbudowanych frameworków — ponowne budowanie bez zmian zależności nie jest wykonywane.
Zależności przechodnie w Carthage są obsługiwane przez Cartfile.resolved: Carthage buduje graf wszystkich potrzebnych zależności i buduje je w odpowiedniej kolejności. Jeśli dwie biblioteki zależą od tej samej biblioteki zewnętrznej, Carthage buduje ją raz i używa dla obu. Carthage informuje o błędach budowania z podaniem konkretnego targetu i przyczyny — upraszcza to diagnozowanie problemów.
Cartfile — plik konfiguracyjny w języku Ruby (format Cartfile), definiujący zależności projektu Carthage. Cartfile znajduje się w katalogu głównym projektu obok .xcodeproj. Każda linia Cartfile opisuje jedną zależność: źródło (URL Git, repozytorium GitHub) i wersję. Składnia obsługuje ustalanie wersji przez tagi, commity i gałęzie.
# Podstawowe zależności Carthage
github "Alamofire/Alamofire" ~> 5.9
github "SnapKit/SnapKit" ~> 5.7
github "onevcat/Kingfisher" == 8.0.0Dyrektywa github "Owner/Repo" — skrócona forma dla repozytoriów GitHub. Carthage automatycznie buduje URL w formie https://github.com/Owner/Repo.git. Dla GitLab, Bitbucket i innych hostingów Git używa się pełnego URL: git "https://gitlab.com/owner/repo.git". Operatory wersji: ~> 5.9 (dowolna wersja od 5.9 do 6.0 z wyłączeniem 6.0), == 8.0.0 (dokładna wersja), >= 1.0 (minimalna wersja). Podłączenie konkretnego commita można wykonać przez github "owner/repo" "abc1234".
Carthage obsługuje kilka katalogów dla różnych konfiguracji: Cartfile (główny), Cartfile.private (dla wewnętrznych zależności, niepublikowanych) i Cartfile.resolved (generowany automatycznie). Prywatne zależności są przydatne dla bibliotek używanych tylko w budowaniu deweloperskim, np. frameworków testowych.
# Cartfile — główne zależności
github "Alamofire/Alamofire" ~> 5.9
github "SwiftyJSON/SwiftyJSON" ~> 4.0
github "realm/realm-swift" ~> 10.0
# Pełny URL dla GitLab
git "https://gitlab.com/company/internal-lib.git" == 2.1.1
# Gałąź deweloperska
github "marmelroy/PhoneNumberKit" "development"github i git — dwa typy źródeł w Cartfile. Pierwszy przeznaczony wyłącznie dla GitHub i automatycznie formuje URL. Drugi — dla dowolnych publicznych lub prywatnych repozytoriów Git z pełnym URL. Wersja może być określona tagiem (== 2.1.1), zakresem semantycznym (~> 5.9), nazwą gałęzi ("development") lub hashem commita ("a1b2c3d"). Użycie zakresów semantycznych (~>) jest zalecane dla zależności zgodnych z SemVer — chroni to przed zmianami łamiącymi przy aktualizacji.
Cartfile.resolved jest generowany automatycznie po carthage update. Ustala dokładne wersje wszystkich zainstalowanych zależności, w tym przechodnich. Plik należy przechowywać w Git — bez niego polecenie carthage bootstrap na innym komputerze zbuduje biblioteki według tych samych zasad, ale wersje mogą się różnić. carthage outdated pokazuje listę nieaktualnych zależności, dla których dostępne są nowe wersje.
Carthage jest instalowany przez Homebrew — standardowy menedżer pakietów dla macOS. Alternatywne sposoby: instalacja z gotowego instalatora .pkg z GitHub lub budowanie z kodu źródłowego. Carthage wymaga Xcode z Command Line Tools (w tym xcodebuild), a na Apple Silicon Mac — Rosetta 2 dla niektórych starszych zależności.
# Instalacja Carthage przez Homebrew
brew install carthage
# Sprawdzenie wersji
carthage version
# Instalacja z .pkg (jeśli Homebrew niedostępny)
# Pobierz Carthage.pkg z GitHub Releases i zainstalować ręczniePo instalacji Carthage inicjalizacja projektu zaczyna się od utworzenia Cartfile w katalogu głównym projektu. Carthage nie ma polecenia init — plik tworzony jest ręcznie w edytorze tekstu. Wypełniwszy Cartfile zależnościami, programista uruchamia carthage bootstrap (jeśli już istnieje Cartfile.resolved) lub carthage update (pierwsza instalacja lub aktualizacja). Carthage klonuje repozytoria, buduje frameworki i umieszcza je w Carthage/Build/.
Aktualizacja Carthage wykonywana jest przez brew upgrade carthage. Wersja sprawdzana jest poleceniem carthage version. Ostatnia stabilna wersja na mid-2025 — 0.40 z obsługą .xcframework domyślnie, ulepszonym równoległym budowaniem i pełną obsługą Swift 6. Od wersji 0.39 Carthage przestał budować przestarzałe .framework bez mostka kompatybilności — zaleca się jawne podawanie --use-xcframeworks.
# Aktualizacja Carthage przez Homebrew
brew upgrade carthage
# Instalacja określonej wersji
brew install carthage@0.39
# Całkowita reinstalacja
brew uninstall carthage && brew install carthageUwaga: Carthage nie tworzy .xcworkspace i nie modyfikuje .xcodeproj. W przeciwieństwie do CocoaPods, Carthage pozostawia pełną kontrolę nad konfiguracją Xcode programiście. Oznacza to, że po instalacji zależności trzeba ręcznie dodać frameworki w Xcode (patrz sekcja «Integracja frameworków Carthage w Xcode»). Carthage wymaga również, aby każda zależność zawierała projekt Xcode lub workspace z targetem frameworka — w przeciwnym razie budowanie zakończy się błędem.
Carthage oferuje trzy główne polecenia do pracy z zależnościami: bootstrap, update i build. carthage bootstrap buduje zależności z istniejącego Cartfile.resolved — zalecane dla środowisk CI i programistów dołączających do projektu. carthage update aktualizuje Cartfile.resolved do najnowszych wersji (z uwzględnieniem ograniczeń Cartfile) i wykonuje budowanie. carthage build buduje wszystkie wskazane zależności bez zapisywania wersji.
# Pierwsza instalacja (aktualizuje wersje)
carthage update --use-xcframeworks --platform iOS
# Ponowne budowanie według ustalonych wersji
carthage bootstrap --use-xcframeworks --platform iOS
# Budowanie tylko jednej zależności
carthage build Alamofire --platform iOSFlaga --use-xcframeworks nakazuje Carthage budowanie uniwersalnych .xcframework zamiast przestarzałych .framework. Zapewnia to obsługę zarówno symulatora, jak i rzeczywistego urządzenia, a także Apple Silicon Mac bez dodatkowych skryptów. Flaga --platform iOS ogranicza budowanie do jednej platformy iOS — to znacząco przyspiesza proces, szczególnie jeśli w projekcie są określone wieloplatformowe biblioteki.
Carthage obsługuje równoległe budowanie przez flagę --cache-builds, która buforuje już zbudowane frameworki. Przy ponownym budowaniu Carthage sprawdza hash commita Git i, jeśli kod się nie zmienił, pomija kompilację. Dla serwerów CI zaleca się buforowanie katalogu Carthage/Build/ i ~/Library/Caches/carthage/. Carthage obsługuje także --verbose do szczegółowego logowania i --no-use-binaries do wymuszonego budowania z kodu źródłowego (jeśli programista nie ufa prekompilowanym binariom).
| Polecenie | Działanie |
|---|---|
carthage update | Aktualizuje Cartfile.resolved i buduje wszystkie frameworki |
carthage bootstrap | Buduje frameworki według istniejącego Cartfile.resolved bez aktualizacji |
carthage build | Buduje wskazane zależności bez ustalania wersji |
carthage outdated | Pokazuje listę zależności z dostępnymi aktualizacjami |
carthage checkout | Tylko klonuje repozytoria bez budowania |
Integracja frameworków Carthage w Xcode wykonywana jest ręcznie w czterech krokach. Po wykonaniu carthage update lub bootstrap wszystkie zbudowane frameworki znajdują się w Carthage/Build/iOS/ (lub odpowiedniej platformie). Programista otwiera projekt Xcode, wybiera target aplikacji i dodaje frameworki w General → Frameworks, Libraries, and Embedded Content. Dla frameworków wykonawczych (bibliotek dynamicznych) należy wybrać «Embed & Sign» — w przeciwnym razie aplikacja ulegnie awarii przy uruchomieniu z błędem «dyld: Library not loaded».
Carthage dla bibliotek statycznych działa prościej — nie wymagają one fazy embed, ponieważ linkują się bezpośrednio do pliku wykonywalnego aplikacji. Jednak Carthage domyślnie buduje dynamiczne frameworki (poza jawnie skonfigurowanymi bibliotekami statycznymi). Dla projektów, w których ważne jest zminimalizowanie rozmiaru aplikacji, zaleca się używanie statycznego linkowania przez ustawienia Xcode.
Dodatkowy krok — dodanie Input Files w Build Phase → Run Script. Carthage wymaga skryptu do usuwania artefaktów symulatora z zbudowanego frameworka (strip simulator architectures). Ten skrypt jest niezbędny dla kompilacji App Store:
# Run Script dla 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 nie wymaga używania .xcworkspace — wszystkie zależności są już zbudowane w binarne frameworki. Carthage działa bezpośrednio z .xcodeproj, w przeciwieństwie do CocoaPods, który tworzy workspace. Upraszcza to kontrolę wersji i konfigurację CI, ponieważ zależności Carthage nie zmieniają konfiguracji projektu Xcode. Jedyną zmianą jest dodanie frameworków do targetu, co jest rejestrowane w .pbxproj.
| Krok | Działanie |
|---|---|
| 1 | Wykonać carthage update --use-xcframeworks |
| 2 | Przeciągnąć frameworki z Carthage/Build/ do General → Frameworks |
| 3 | Ustawić Embed & Sign dla dynamicznych frameworków |
| 4 | Dodać Run Script Phase do usuwania architektur symulatora |
| 5 | Zbudować projekt — frameworki powinny linkować się automatycznie |
Carthage, CocoaPods i Swift Package Manager (SPM) — trzy główne menedżery zależności w programowaniu iOS. Carthage wyróżnia się zdecentralizowanym podejściem, CocoaPods oferuje scentralizowany rejestr, SPM — wbudowane rozwiązanie od Apple. Wybór między nimi zależy od wymagań projektu, wielkości zespołu i potrzebnego poziomu automatyzacji.
| Kryterium | Carthage | CocoaPods | SPM |
|---|---|---|---|
| Architektura | Zdecentralizowana | Scentralizowany rejestr | Zintegrowany z Xcode |
| Język konfiguracji | Cartfile (Ruby-podobny) | Podfile (Ruby DSL) | Package.swift (Swift) |
| Integracja z Xcode | Ręczna (drag & drop) | Przez workspace | Wbudowana |
| Zależności przechodnie | Automatycznie | Automatycznie | Automatycznie |
| Rejestr bibliotek | Nie (repozytoria Git) | 100 000+ w Specs | ~65 000 |
| Obsługa zasobów | Nie | Tak (resource bundles) | Tak (Resources) |
| Szybkość budowania | Szybka (równoległa) | Średnia | Szybka |
| Kontrola integracji | Pełna | Automatyczna | Automatyczna |
Carthage jest wybierany dla projektów, w których wymagana jest minimalna ingerencja w konfigurację Xcode i pełna kontrola nad procesem integracji. Carthage jest idealny dla otwartych bibliotek i frameworków, gdzie autor chce dać użytkownikom możliwość samodzielnego budowania zależności. Carthage jest również popularny w społeczności programistów ceniących filozofię UNIX: każde narzędzie robi jedną rzecz dobrze. CocoaPods pozostaje standardem dla projektów korporacyjnych z dziesiątkami zależności, gdzie ważna jest automatyzacja. SPM — wybór dla nowych projektów, ponieważ jest wbudowany w Xcode i aktywnie rozwijany przez Apple.
Migracja między menedżerami wymaga różnego podejścia. Carthage → SPM: usunąć frameworki z Xcode, usunąć Cartfile i dodać Package Dependencies przez File → Add Package Dependencies. Carthage → CocoaPods: usunąć frameworki Carthage, utworzyć Podfile, dodać zależności i wykonać pod init && pod install. Przy migracji z Carthage na CocoaPods lub SPM znika potrzeba ręcznej aktualizacji frameworków — wszystkie zależności aktualizowane są jednym poleceniem. Carthage pozostaje istotny dla projektów, w których ważne jest uniknięcie vendor lock-in i zachowanie przejrzystości budowania zależności.
Carthage — stabilne narzędzie, ale programiści okresowo napotykają typowe problemy, szczególnie przy budowaniu na serwerach CI, aktualizacji Xcode lub zmianie wersji Swift. Większość problemów rozwiązuje się przez czyszczenie pamięci podręcznej, prawidłową konfigurację --use-xcframeworks i sprawdzenie zgodności minimalnej wersji iOS.
Błąd «The file manager returned an error» — występuje przy uszkodzeniu pamięci podręcznej Carthage lub konflikcie praw plików. Rozwiązanie: usunąć pamięć podręczną poleceniem rm -rf ~/Library/Caches/carthage i ponownie uruchomić carthage bootstrap. Pomaga również usunięcie katalogu Carthage/ w projekcie i ponowne budowanie. Na serwerach CI pamięć podręczną Carthage należy aktualizować tylko przy zmianie Cartfile.resolved.
Błąd «No such module» — framework nie został znaleziony w Xcode, mimo że budowanie Carthage zakończyło się pomyślnie. Rozwiązanie: sprawdzić ścieżkę frameworka w General → Frameworks, Libraries, and Embedded Content. Framework powinien znajdować się w Carthage/Build/iOS/. Upewnić się, że .xcframework został dodany poprawnie (przeciągnąć ponownie). Dla frameworków dynamicznych sprawdzić Embed & Sign. Jeśli błąd się utrzymuje — dodać FRAMEWORK_SEARCH_PATHS w Build Settings.
Błąd przy budowaniu z powodu niezgodności Swift — biblioteka zbudowana dla innej wersji Swift niż projekt. Rozwiązanie: użyć carthage update --no-use-binaries do wymuszonego budowania z kodu źródłowego tą samą wersją Swift. Jeśli biblioteka nie kompiluje się pod bieżącą wersję — użyć .xcconfig do określenia wersji Swift lub sforkować bibliotekę. Od Carthage 0.39, --use-xcframeworks automatycznie dołącza prawidłową wersję Swift do binaru.
Problemy z budowaniem CI — Carthage na CI wymaga prawidłowej konfiguracji buforowania. Rozwiązanie: buforować Carthage/Build/ i ~/Library/Caches/carthage/. Używać carthage bootstrap --use-xcframeworks --platform iOS zamiast update na CI, aby nie zmieniać wersji. Dla GitHub Actions dostępna jest oficjalna akcja Carthage. Dla Jenkins — wtyczka CarthageBuild. Carthage może ulegać awarii na macOS bez GUI — rozwiązanie: zainstalować brew install xcode-build-server lub dodać klucz -UseModernBuildSystem=NO.
| Problem | Przyczyna | Rozwiązanie |
|---|---|---|
| File manager error | Uszkodzona pamięć podręczna | Wyczyścić ~/Library/Caches/carthage/ |
| No such module | Framework nie dodany w Xcode | Sprawdzić Frameworki w target |
| Niezgodność Swift | Różne wersje Swift | --no-use-binaries lub nowa wersja Carthage |
| Błąd na CI | Brak pamięci podręcznej lub GUI | Skonfigurować pamięć podręczną Carthage/Build/ |
| Biblioteka się nie buduje | Brak projektu Xcode w bibliotece | Sprawdzić strukturę repozytorium |
Często zadawane pytania
Carthage — zdecentralizowany menedżer zależności dla platform Apple. W przeciwieństwie do CocoaPods, Carthage nie używa centralnego rejestru bibliotek, nie modyfikuje projektu Xcode automatycznie i nie tworzy .xcworkspace. Carthage buduje zależności w binarne frameworki, które programista ręcznie dodaje w Xcode. CocoaPods, natomiast, automatyzuje cały proces przez Podfile.
Carthage jest instalowany przez Homebrew: brew install carthage. Alternatywnie — pobrać Carthage.pkg z GitHub Releases lub zbudować z kodu źródłowego. Po instalacji sprawdź wersję: carthage version. Carthage wymaga Xcode z Command Line Tools. Na Apple Silicon Mac dodatkowo może być potrzebna Rosetta 2.
Cartfile — plik konfiguracyjny pisany przez programistę: zawiera nazwy bibliotek i operatory wersji (~> 5.9, == 8.0.0, nazwa gałęzi). Cartfile.resolved jest generowany automatycznie przy carthage update i ustala dokładne wersje wszystkich zainstalowanych zależności. Cartfile.resolved należy przechowywać w Git — gwarantuje odtwarzalność budowania na wszystkich komputerach.
Carthage wymaga, aby biblioteka zawierała poprawny projekt Xcode lub workspace z targetem frameworka. Sprawdź, czy repozytorium jest dostępne (nie prywatne bez klucza), czy podana jest prawidłowa wersja (tag lub commit istnieje), a biblioteka obsługuje twoją wersję Xcode. Użyj carthage build --verbose do szczegółowej diagnostyki. Jeśli biblioteka nie ma targetu frameworka, Carthage nie będzie w stanie jej zbudować.
Carthage pozostaje aktualny dla projektów, w których wymagane jest zdecentralizowane zarządzanie zależnościami, pełna kontrola nad integracją i minimalna ingerencja w projekt Xcode. Jednak większość nowych projektów wybiera Swift Package Manager (SPM) — jest wbudowany w Xcode, nie wymaga dodatkowej instalacji i jest aktywnie rozwijany przez Apple. Carthage jest zalecany dla starszych projektów, w których już zbudowano potok budowania, lub dla bibliotek, których autorzy chcą dać użytkownikom swobodę wyboru sposobu integracji.
Podsumowanie
brew install carthage, a budowanie zależności przez carthage bootstrap lub carthage update--no-use-binaries i konfigurację buforowania CIOpracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również