Carthage هو مدير تبعيات لامركزي لمشاريع Cocoa (iOS، macOS، watchOS، tvOS) يقوم ببناء أطر ثنائية من الكود المصدري. على عكس CocoaPods، لا يقوم Carthage بتعديل المشروع تلقائياً — المطور يضيف الأطر المبنية يدوياً إلى Xcode. Carthage مكتوب بلغة Swift، ويستخدم Cartfile لوصف التبعيات ويدعم البناء المتوازي. وفقاً لمستودع GitHub، جمع Carthage أكثر من 15,000 نجمة ولا يزال أداة متخصصة لكن مطلوبة للمشاريع التي تتطلب الحد الأدنى من التدخل في إعدادات Xcode.
الخلاصة
carthage bootstrap أو carthage update — Carthage يستنسخ المستودعات ويجمعها في .xcframeworkCarthage هو مدير تبعيات بهندسة لا مركزية، تم إنشاؤه في 2014 بواسطة مطورين من مجتمع Swift. Carthage لا يستخدم سجل مواصفات مركزي — كل مكتبة تُوصَل مباشرة من مستودع Git عبر URL أو اسم على GitHub. Carthage يقوم بتحميل الكود المصدري، يبنيه إلى إطار ثنائي (.xcframework أو .framework) ويوفر للمطور قطعة جاهزة للتكامل اليدوي في مشروع Xcode.
هندسة Carthage تتضمن ثلاثة مكونات: أداة CLI carthage، ملف الإعداد Cartfile ودليل Carthage/Build/ مع الأطر المبنية. الفرق الرئيسي بين Carthage و CocoaPods هو غياب التعديل التلقائي لـ .xcodeproj. Carthage لا ينشئ .xcworkspace، ولا يضبط أعلام المترجم، ولا يولد Pods.xcconfig. المطور يضيف الأطر يدوياً إلى المشروع عبر Xcode، مما يوفر تحكماً كاملاً في عملية التكامل.
Carthage يستخدم بناء تبعيات متوازياً، مما يسرع العملية بشكل كبير على المعالجات متعددة النوى. كل تبعية تُبنى كهدف منفصل، و Carthage يحل تلقائياً رسم بياني للتبعيات المتعدية، ببنائها بالترتيب الصحيح. وفقاً لمعايير المجتمع، Carthage يبني 15–20 تبعية في متوسط 30–60 ثانية على أجهزة Mac الحديثة، وهو أسرع من CocoaPods للمشاريع التي تحتوي على مكتبات كثيرة. Carthage يدعم جميع منصات Apple: iOS، macOS، watchOS و tvOS، ومنذ الإصدار 0.38+ — بناء .xcframework عالمي لدعم المحاكي وأجهزة Apple Silicon.
Carthage يستنسخ مستودع Git لكل تبعية، يتحول إلى الإصدار المحدد (tag، commit أو فرع) ويشغل xcodebuild لبناء الإطار. Carthage يحدد تلقائياً نوع مشروع Xcode (إطار، إطار ديناميكي، مكتبة ثابتة) حسب مخطط البناء. إذا كان المشروع يحتوي على مخططات متعددة، Carthage يستخدم المخطط الافتراضي (الأول ترتيباً أبجدياً). بعد البناء، Carthage ينسخ الإطار النهائي إلى Carthage/Build/ وينشئ ملف Cartfile.resolved مع تثبيت الإصدارات الدقيقة. Carthage يدعم التخزين المؤقت للأطر المبنية — إعادة البناء دون تغييرات في التبعيات يتم تخطيها.
التبعيات المتعدية في Carthage تُعالج عبر Cartfile.resolved: Carthage يبني رسم بياني لجميع التبعيات المطلوبة ويبنيها بالترتيب الصحيح. إذا كانت مكتبتان تعتمدان على نفس المكتبة الخارجية، Carthage يبنيها مرة واحدة ويستخدمها لكلتيهما. Carthage يبلغ عن أخطاء البناء مع تحديد الهدف المحدد والسبب — هذا يبسط تشخيص المشكلات.
Cartfile هو ملف إعداد بصيغة شبيهة بـ Ruby (تنسيق Cartfile) يحدد تبعيات مشروع Carthage. Cartfile يقع في جذر المشروع بجانب .xcodeproj. كل سطر في Cartfile يصف تبعية واحدة: المصدر (URL Git، مستودع GitHub) والإصدار. الصيغة تدعم تثبيت الإصدارات عبر tags، commits والفروع.
# التبعيات الأساسية Carthage
github "Alamofire/Alamofire" ~> 5.9
github "SnapKit/SnapKit" ~> 5.7
github "onevcat/Kingfisher" == 8.0.0التوجيه github "Owner/Repo" هو صيغة مختصرة لمستودعات GitHub. Carthage يبني تلقائياً URL https://github.com/Owner/Repo.git. لـ GitLab، Bitbucket ومستضيفات Git الأخرى، يُستخدم URL الكامل: git "https://gitlab.com/owner/repo.git". عوامل الإصدار: ~> 5.9 (أي إصدار من 5.9 حتى 6.0 باستثناء 6.0)، == 8.0.0 (إصدار دقيق)، >= 1.0 (إصدار أدنى). يمكن تثبيت commit محدد عبر github "owner/repo" "abc1234".
Carthage يدعم أدلة متعددة لإعدادات مختلفة: Cartfile (رئيسي)، Cartfile.private (للتبعيات الداخلية غير المنشورة) و Cartfile.resolved (يُولد تلقائياً). التبعيات الخاصة مفيدة للمكتبات المستخدمة فقط في بنيات التطوير، مثل أطر الاختبار.
# Cartfile — التبعيات الرئيسية
github "Alamofire/Alamofire" ~> 5.9
github "SwiftyJSON/SwiftyJSON" ~> 4.0
github "realm/realm-swift" ~> 10.0
# كامل URL لـ GitLab
git "https://gitlab.com/company/internal-lib.git" == 2.1.1
# فرع التطوير
github "marmelroy/PhoneNumberKit" "development"github و git هما نوعا مصادر في Cartfile. الأول مخصص حصرياً لـ GitHub ويولد URL تلقائياً. الثاني لأي مستودعات Git عامة أو خاصة مع URL كامل. يمكن تحديد الإصدار كـ tag (== 2.1.1)، نطاق دلالي (~> 5.9)، اسم فرع ("development") أو hash commit ("a1b2c3d"). النطاقات الدلالية (~>) موصى بها للتبعيات التي تتبع SemVer — هذا يحمي من التغييرات الجذرية أثناء التحديثات.
Cartfile.resolved يُولد تلقائياً بعد carthage update. يثبت الإصدارات الدقيقة لجميع التبعيات المثبتة، بما في ذلك المتعدية. يجب حفظ هذا الملف في Git — بدونه، أمر carthage bootstrap على جهاز آخر سيبني المكتبات بنفس القواعد، لكن الإصدارات قد تختلف. carthage outdated يعرض قائمة بالتبعيات القديمة التي تتوفر لها إصدارات جديدة.
Carthage يُثبت عبر Homebrew — مدير الحزم القياسي لنظام macOS. طرق بديلة: التثبيت من مثبت .pkg من GitHub أو البناء من المصدر. Carthage يتطلب Xcode مع Command Line Tools (بما في ذلك xcodebuild)، وعلى Apple Silicon Mac — Rosetta 2 لبعض التبعيات القديمة.
# تثبيت Carthage عبر Homebrew
brew install carthage
# التحقق من الإصدار
carthage version
# تثبيت من .pkg (إذا كان Homebrew غير متاح)
# تنزيل Carthage.pkg من GitHub Releases وتثبيته يدويًابعد تثبيت Carthage، تبدأ تهيئة المشروع بإنشاء Cartfile في جذر المشروع. Carthage ليس لديه أمر init — الملف يُنشأ يدوياً في محرر نصوص. بعد ملء Cartfile بالتبعيات، المطور يشغل carthage bootstrap (إذا كان Cartfile.resolved موجوداً بالفعل) أو carthage update (التثبيت الأولي أو التحديث). Carthage يستنسخ المستودعات، يبني الأطر ويضعها في Carthage/Build/.
تحديث Carthage يتم عبر brew upgrade carthage. يتم التحقق من الإصدار بأمر carthage version. آخر إصدار مستقر في منتصف 2025 هو 0.40 مع دعم افتراضي لـ .xcframework، بناء متوازي محسن ودعم كامل لـ Swift 6. ابتداءً من الإصدار 0.39، توقف Carthage عن بناء .framework القديمة بدون طبقة توافق — يُوصى بتحديد --use-xcframeworks صراحة.
# تحديث Carthage عبر Homebrew
brew upgrade carthage
# تثبيت إصدار محدد
brew install carthage@0.39
# إعادة تثبيت كاملة
brew uninstall carthage && brew install carthageملاحظة: Carthage لا ينشئ .xcworkspace ولا يعدل .xcodeproj. على عكس CocoaPods، Carthage يترك التحكم الكامل في إعدادات Xcode للمطور. هذا يعني أنه بعد تثبيت التبعيات، تحتاج إلى إضافة الأطر يدوياً إلى Xcode (انظر قسم «دمج أطر Carthage في Xcode»). Carthage يتطلب أيضاً أن تحتوي كل تبعية على مشروع Xcode أو workspace مع هدف إطار — وإلا سيفشل البناء.
Carthage يقدم ثلاثة أوامر رئيسية للعمل مع التبعيات: bootstrap، update و build. carthage bootstrap يبني التبعيات من Cartfile.resolved موجود — موصى به لبيئات CI والمطورين المنضمين حديثاً للمشروع. carthage update يحدث Cartfile.resolved إلى أحدث الإصدارات (مع احترام قيود Cartfile) وينفذ البناء. carthage build يبني جميع التبعيات المحددة بدون حفظ الإصدارات.
# التثبيت الأولي (يحدث الإصدارات)
carthage update --use-xcframeworks --platform iOS
# إعادة البناء بإصدارات مثبتة
carthage bootstrap --use-xcframeworks --platform iOS
# بناء تبعية واحدة فقط
carthage build Alamofire --platform iOSالعلم --use-xcframeworks يوجه Carthage لبناء .xcframework عالمي بدلاً من .framework القديمة. هذا يضمن دعم كل من المحاكي والجهاز الحقيقي، بالإضافة إلى Apple Silicon Mac بدون نصوص إضافية. العلم --platform iOS يحدد البناء لمنصة iOS واحدة — هذا يسرع العملية بشكل كبير، خاصة إذا كان المشروع يتضمن مكتبات متعددة المنصات.
Carthage يدعم البناء المتوازي عبر العلم --cache-builds، الذي يخزن مؤقتاً الأطر المبنية بالفعل. عند إعادة البناء، Carthage يتحقق من hash commit Git، وإذا لم يتغير الكود، يتخطى التجميع. لخوادم CI، يُوصى بتخزين الدليل Carthage/Build/ و ~/Library/Caches/carthage/ مؤقتاً. Carthage يدعم أيضاً --verbose للتسجيل المفصل و --no-use-binaries للبناء الإجباري من المصدر (إذا كان المطور لا يثق بالملفات الثنائية المجمعة مسبقاً).
| الأمر | الإجراء |
|---|---|
carthage update | يحدث Cartfile.resolved ويبني جميع الأطر |
carthage bootstrap | يبني الأطر من Cartfile.resolved الموجود بدون تحديث |
carthage build | يبني التبعيات المحددة بدون تثبيت إصدارات |
carthage outdated | يعرض قائمة بالتبعيات المتاحة لها تحديثات |
carthage checkout | يستنسخ المستودعات فقط بدون بناء |
دمج أطر Carthage في Xcode يتم يدوياً في أربع خطوات. بعد تشغيل carthage update أو bootstrap، جميع الأطر المبنية موجودة في Carthage/Build/iOS/ (أو المنصة المقابلة). المطور يفتح مشروع Xcode، يختار هدف التطبيق ويضيف الأطر في General → Frameworks, Libraries, and Embedded Content. للأطر وقت التشغيل (المكتبات الديناميكية)، يجب اختيار «Embed & Sign» — وإلا سيتعطل التطبيق عند التشغيل مع خطأ «dyld: Library not loaded».
Carthage للمكتبات الثابتة أبسط — لا تتطلب مرحلة embed لأنها تُربط مباشرة في الملف التنفيذي للتطبيق. لكن Carthage يبني أطراً ديناميكية افتراضياً (باستثناء المكتبات الثابتة المكونة صراحة). للمشاريع التي يكون فيها تقليل حجم التطبيق مهماً، يُوصى بالربط الثابت عبر إعدادات Xcode.
خطوة إضافية هي إضافة Input Files في Build Phase → Run Script. Carthage يتطلب نصاً لإزالة قطع المحاكي من الإطار المبني (strip simulator architectures). هذا النص ضروري لبنيات App Store:
# Run Script لـ 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 لا يتطلب استخدام .xcworkspace — جميع التبعيات مبنية بالفعل في أطر ثنائية. Carthage يعمل مباشرة مع .xcodeproj، على عكس CocoaPods الذي ينشئ workspace. هذا يبسط التحكم في الإصدارات وإعداد CI، لأن تبعيات Carthage لا تغير إعدادات مشروع Xcode. التغيير الوحيد هو إضافة الأطر إلى الهدف، الذي يُسجل في .pbxproj.
| الخطوة | الإجراء |
|---|---|
| 1 | تشغيل carthage update --use-xcframeworks |
| 2 | سحب الأطر من Carthage/Build/ إلى General → Frameworks |
| 3 | تعيين Embed & Sign للأطر الديناميكية |
| 4 | إضافة Run Script Phase لإزالة معماريات المحاكي |
| 5 | بناء المشروع — الأطر يجب أن تُربط تلقائياً |
Carthage و CocoaPods و Swift Package Manager (SPM) هم مديري التبعيات الرئيسيين الثلاثة في تطوير iOS. Carthage يتميز بنهجه اللامركزي، CocoaPods يقدم سجلاً مركزياً، و SPM هو الحل المدمج من Apple. الاختيار بينهم يعتمد على متطلبات المشروع، حجم الفريق ومستوى الأتمتة المطلوب.
| المعيار | Carthage | CocoaPods | SPM |
|---|---|---|---|
| الهندسة | لامركزية | سجل مركزي | مدمج في Xcode |
| لغة الإعداد | Cartfile (شبيه بـ Ruby) | Podfile (DSL Ruby) | Package.swift (Swift) |
| التكامل مع Xcode | يدوي (سحب وإفلات) | عبر workspace | مدمج |
| التبعيات المتعدية | تلقائي | تلقائي | تلقائي |
| سجل المكتبات | لا يوجد (مستودعات Git) | 100,000+ في Specs | ~65,000 |
| دعم الموارد | لا | نعم (حزم موارد) | نعم (Resources) |
| سرعة البناء | سريع (متوازي) | متوسط | سريع |
| التحكم في التكامل | كامل | تلقائي | تلقائي |
Carthage يُختار للمشاريع التي تتطلب الحد الأدنى من التدخل في إعدادات Xcode وتحكماً كاملاً في عملية التكامل. Carthage مثالي للمكتبات مفتوحة المصدر حيث يريد المؤلف تمكين المستخدمين من بناء التبعيات بشكل مستقل. Carthage أيضاً شائع بين المطورين الذين يقدرون فلسفة UNIX: كل أداة تقوم بشيء واحد جيداً. CocoaPods يبقى المعيار للمشاريع المؤسسية التي تحتوي على عشرات التبعيات حيث الأتمتة مهمة. SPM هو الخيار للمشاريع الجديدة لأنه مدمج في Xcode ويُطور بنشاط من قبل Apple.
الترحيل بين المديرين يتطلب نهجاً مختلفاً. Carthage → SPM: إزالة الأطر من Xcode، حذف Cartfile وإضافة Package Dependencies عبر File → Add Package Dependencies. Carthage → CocoaPods: إزالة أطر Carthage، إنشاء Podfile، إضافة التبعيات وتشغيل pod init && pod install. عند الترحيل من Carthage إلى CocoaPods أو SPM، تختفي الحاجة لتحديث الأطر يدوياً — جميع التبعيات تُحدث بأمر واحد. Carthage يبقى ذا صلة للمشاريع حيث من المهم تجنب vendor lock-in والحفاظ على شفافية بناء التبعيات.
Carthage أداة مستقرة، لكن المطورين يواجهون بشكل دوري مشاكل نموذجية، خاصة عند البناء على خوادم CI، تحديث Xcode أو تغيير إصدارات Swift. معظم المشاكل تُحل بتنظيف الذاكرة المؤقتة، إعداد --use-xcframeworks بشكل صحيح والتحقق من الحد الأدنى لإصدار iOS.
خطأ «The file manager returned an error» — يحدث عند تلف ذاكرة Carthage المؤقتة أو تضارب صلاحيات الملفات. الحل: حذف الذاكرة المؤقتة بأمر rm -rf ~/Library/Caches/carthage وإعادة تشغيل carthage bootstrap. يساعد أيضاً حذف دليل Carthage/ في المشروع وإعادة البناء. على خوادم CI، يجب تحديث ذاكرة Carthage المؤقتة فقط عند تغيير Cartfile.resolved.
خطأ «No such module» — الإطار غير موجود في Xcode رغم نجاح بناء Carthage. الحل: التحقق من مسار الإطار في General → Frameworks, Libraries, and Embedded Content. يجب أن يكون الإطار في Carthage/Build/iOS/. التأكد من إضافة .xcframework بشكل صحيح (سحبه مرة أخرى). للأطر الديناميكية، التحقق من Embed & Sign. إذا استمر الخطأ، إضافة FRAMEWORK_SEARCH_PATHS في Build Settings.
خطأ في البناء بسبب عدم توافق Swift — المكتبة بُنيت لإصدار Swift مختلف عن المشروع. الحل: استخدام carthage update --no-use-binaries لفرض البناء من المصدر بنفس إصدار Swift. إذا كانت المكتبة لا تترجم تحت الإصدار الحالي، استخدام .xcconfig لتحديد إصدار Swift أو عمل fork للمكتبة. منذ Carthage 0.39، --use-xcframeworks يتضمن تلقائياً إصدار Swift الصحيح في الملف الثنائي.
مشاكل بناء CI — Carthage على CI يتطلب إعداداً صحيحاً للذاكرة المؤقتة. الحل: تخزين Carthage/Build/ و ~/Library/Caches/carthage/ مؤقتاً. استخدام carthage bootstrap --use-xcframeworks --platform iOS بدلاً من update على CI لتجنب تغيير الإصدارات. هناك إجراء رسمي لـ Carthage متاح لـ GitHub Actions. لـ Jenkins — إضافة CarthageBuild. Carthage قد يفشل على macOS بدون GUI — الحل: تثبيت brew install xcode-build-server أو إضافة العلم -UseModernBuildSystem=NO.
| المشكلة | السبب | الحل |
|---|---|---|
| خطأ file manager | ذاكرة مؤقتة تالفة | تنظيف ~/Library/Caches/carthage/ |
| No such module | الإطار غير مضاف في Xcode | التحقق من Frameworks في الهدف |
| عدم توافق Swift | إصدارات Swift مختلفة | --no-use-binaries أو إصدار أحدث من Carthage |
| خطأ في CI | ذاكرة مؤقتة أو GUI مفقودة | إعداد ذاكرة Carthage/Build/ المؤقتة |
| المكتبة لا تُبنى | لا يوجد مشروع Xcode للمكتبة | التحقق من هيكل المستودع |
الأسئلة الشائعة
Carthage هو مدير تبعيات لامركزي لمنصات Apple. على عكس CocoaPods، Carthage لا يستخدم سجل مكتبات مركزي، لا يعدل مشروع Xcode تلقائياً ولا ينشئ .xcworkspace. Carthage يبني التبعيات في أطر ثنائية يضيفها المطور يدوياً إلى Xcode. CocoaPods، على النقيض، يؤتمت العملية بأكملها عبر Podfile.
Carthage يُثبت عبر Homebrew: brew install carthage. بديلاً — تنزيل Carthage.pkg من GitHub Releases أو البناء من المصدر. بعد التثبيت، تحقق من الإصدار: carthage version. Carthage يتطلب Xcode مع Command Line Tools. على Apple Silicon Mac، قد يكون Rosetta 2 ضرورياً.
Cartfile هو ملف إعداد يكتبه المطور: يسرد أسماء المكتبات وعوامل الإصدار (~> 5.9، == 8.0.0، اسم فرع). Cartfile.resolved يُولد تلقائياً أثناء carthage update ويثبت الإصدارات الدقيقة لجميع التبعيات المثبتة. Cartfile.resolved يجب حفظه في Git — يضمن إمكانية إعادة البناء على جميع الأجهزة.
Carthage يتطلب أن تحتوي المكتبة على مشروع Xcode أو workspace صالح مع هدف إطار. تحقق من أن المستودع قابل للوصول (ليس خاصاً بدون مفتاح)، وأن الإصدار المحدد صحيح (tag أو commit موجود)، والمكتبة تدعم إصدار Xcode الخاص بك. استخدم carthage build --verbose للتشخيص المفصل. إذا لم يكن للمكتبة هدف إطار، لا يمكن لـ Carthage بناؤها.
Carthage يبقى ذا صلة للمشاريع التي تتطلب إدارة تبعيات لا مركزية، تحكماً كاملاً في التكامل وتدخلاً أدنى في مشروع Xcode. لكن معظم المشاريع الجديدة تختار Swift Package Manager (SPM) — فهو مدمج في Xcode، لا يتطلب تثبيت إضافي ويُطور بنشاط من قبل Apple. Carthage يُوصى به للمشاريع القديمة حيث خط أنابيب البناء قائم بالفعل، أو للمكتبات التي يريد مؤلفوها منح المستخدمين حرية اختيار طريقة التكامل.
الملخص
brew install carthage، وبناء التبعيات عبر carthage bootstrap أو carthage update--no-use-binaries وإعداد ذاكرة CI المؤقتةسنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.