سلاسل أدوات مستقلة (قديمة)

يمكنك استخدام سلاسل الأدوات المتوفّرة مع NDK في Android بشكل مستقل أو كمكوّنات إضافية مع بيئة التطوير المتكاملة (IDE) الحالية. وقد تكون هذه المرونة مفيدة إذا كان لديك نظام تصميم خاص بك، ولا تحتاج إلا إلى القدرة على استدعاء برنامج التحويل البرمجي المتبادل لإضافة دعم له إلى Android.

تحديد سلسلة الأدوات

قبل أي شيء آخر، تحتاج إلى تحديد بنية المعالج التي ستستهدفها سلسلة الأدوات المستقلة الخاصة بك. ويتم ذلك باستخدام العلامة --arch.

اختَر sysroot

الخطوة التالية التي ينبغي عليك إجراؤها هي تحديد sysroot. يُعد sysroot دليل يحتوي على عناوين ومكتبات النظام لهدفك. لتحديد نظام sysroot، يجب أن تعرف مستوى واجهة برمجة تطبيقات Android الذي تريد استهدافه للحصول على الدعم الأصلي، وتختلف واجهات برمجة التطبيقات الأصلية المتاحة حسب مستوى واجهة برمجة تطبيقات Android.

تتوفّر مكتبات لواجهات برمجة التطبيقات الأصلية التي تخص مستويات واجهة برمجة تطبيقات Android المعنيّة ضمن $NDK/platforms/، ويحتوي كل دليل على مستوى واجهة برمجة التطبيقات بدوره على أدلة فرعية لمختلف وحدات المعالجة المركزية (CPU) والبُنى الأساسية. تتوفّر العناوين في $NDK/sysroot.

لمزيد من التفاصيل حول مستويات واجهة برمجة تطبيقات Android وواجهات برمجة التطبيقات الأصلية ذات الصلة التي تدعمها، يُرجى الاطّلاع على واجهات برمجة التطبيقات الأصلية.

إنشاء سلسلة الأدوات

يوفر NDK النص البرمجي make_standalone_toolchain.py للسماح لك بتنفيذ تثبيت سلسلة أدوات مخصص من سطر الأوامر.

هذه أداة جديدة تحل محل "make-standalone-toolchain.sh" القديم. وقد تمت إعادة دمجه في بايثون بحيث لا يحتاج مستخدمو Windows إلى تثبيت Cygwin أو MSYS لتشغيله.

يتوفّر النص البرمجي في دليل $NDK/build/tools/، حيث يشير $NDK إلى جذر التثبيت لـ NDK.

في ما يلي مثال على استخدام هذا النص البرمجي:

$NDK/build/tools/make_standalone_toolchain.py \
    --arch arm --api 21 --install-dir /tmp/my-android-toolchain

ينشئ هذا الأمر دليلاً باسم /tmp/my-android-toolchain/ يحتوي على نسخة من android-21/arch-arm sysroot ومن البرامج الثنائية لسلسلة الأدوات ضمن هدف ARM بحجم 32 بت.

تجدر الإشارة إلى أن ثنائيات سلسلة الأدوات لا تعتمد على مسارات خاصة بالمضيف ولا تحتوي عليها. بمعنى آخر، يمكنك تثبيتها في أي مكان أو حتى نقلها عند الحاجة.

الوسيطة --arch مطلوبة، ولكن سيتم ضبط مستوى واجهة برمجة التطبيقات تلقائيًا على الحد الأدنى من المستوى المتوافق مع البنية المحددة (حاليًا 16 للبنية 32 بت و21 للبُنى الأساسية 64 بت).

ومنذ الإصدار r18، تستخدم جميع سلاسل الأدوات المستقلة Clang وlibc++. وسيتم استخدام المكتبة المشتركة libc++ تلقائيًا ما لم يتم إنشاء ملف تنفيذي ثابت. لفرض استخدام المكتبة الثابتة، مرِّر -static-libstdc++ عند الربط. ويتطابق هذا السلوك مع سلوك سلسلة أدوات المضيف العادية.

كما هو مذكور في دعم مكتبة C++، غالبًا ما تحتاج إلى تمرير -latomic عند الربط مع libc++.

تجدر الإشارة إلى أنّه إذا حذفت الخيار --install-dir، ستنشئ الأداة الكرة في الدليل الحالي باسم $TOOLCHAIN_NAME.tar.bz2. يمكن وضع لعبة tarball في دليل مختلف باستخدام --package-dir.

لمزيد من الخيارات والتفاصيل، استخدِم "--help".

العمل باستخدام Clang

يتم تضمين برامج Clang الثنائية تلقائيًا في سلاسل الأدوات المستقلة.

هناك أيضًا نصان برمجيّان لبرامج تضمين، باسم clang وclang++، ضمن <install-dir>/bin. تستدعي هذه النصوص البرمجية ثنائي clang باستخدام علامات البنية المستهدفة الصحيحة. بعبارة أخرى، يجب أن تعمل هذه الرموز بدون أي تعديل، كما يجب أن تتمكّن من استخدامها في إصداراتك الخاصة من خلال ضبط متغيّرات بيئة CC وCXX للإشارة إليها.

هناك أيضًا نصوص برمجية لبرامج تضمين تسمى gcc وg++ وتسمى أيضًا Clang. يوفر هذا توفير مستوى من التوافق لملفات الإصدار التي تشير صراحةً إلى GCC على الرغم من أن NDK لم يعد يحتوي على GCC. وبالطبع، إذا كان ملف الإصدار يستخدم خيارات سطر أوامر غير متوافقة مع Clang، فستحتاج إلى إزالتها أو استبدالها.

أهداف Clang مع ARM

عند إنشاء محتوى من أجل ARM، تغيّر Clang الهدف استنادًا إلى توفُّر علامات المحول البرمجي -march=armv7-a و/أو -mthumb:

الجدول 1. قيم -march القابلة للتحديد وأهدافها الناتجة عن ذلك

قيمة -march الهدف الناتج
-march=armv7-a armv7-none-linux-androideabi
-mthumb thumb-none-linux-androideabi
كل من -march=armv7-a و-mthumb thumbv7-none-linux-androideabi

ويمكنك أيضًا إلغاء هذا الخيار باستخدام -target الخاصة بك إذا أردت ذلك.

يجب الاستغناء عن clang وclang++ كبديل لـ gcc وg++ في ملف شخصي. إذا كانت لديك شكوك، استخدم الخيارات التالية عند استدعاء برنامج التجميع للتحقق من أنها تعمل بشكل صحيح:

  • -v لتفريغ الأوامر المرتبطة بمشاكل برنامج تشغيل المحوِّل البرمجي
  • -### لتفريغ خيارات سطر الأوامر، بما في ذلك الخيارات المحددة مسبقًا بشكل ضمني.
  • -x c < /dev/null -dM -E لتفريغ تعريفات المعالجات المسبقة التحديد مسبقًا
  • -save-temps لمقارنة ملفات *.i أو *.ii تمت معالجتها مسبقًا.

التوافق مع واجهة التطبيق الثنائية (ABI)

ستستهدف سلسلة أدوات ARM Clang المستقلة armeabi-v7a ABI بشكل تلقائي. يمكن إلغاء هذا الإجراء من خلال تمرير الخيار المناسب -march أو -target.

ننصحك باستخدام علامة برنامج التجميع -mthumb لفرض إنشاء تعليمات "الإبهام 2" بتنسيق 16 بت. في حال حذفها، ستصدر سلسلة الأدوات تعليمات ARM ذات 32 بت.

لاستخدام تعليمات NEON، يجب عليك استخدام علامة برنامج التجميع -mfpu: -mfpu=neon.

وتجدُر الإشارة إلى أنّ هذا الإعداد يفرض استخدام VFPv3-D32 وفقًا لمواصفات ARM.

تأكَّد أيضًا من تقديم العلامتَين التاليتَين إلى الرابط: -march=armv7-a -Wl,--fix-cortex-a8.

توجِّه العلامة الأولى الرابط إلى اختيار مكتبات سلسلة الأدوات المصمَّمة خصيصًا لـ Armv7-a. تكون العلامة الثانية مطلوبة كحل بديل لخطأ وحدة المعالجة المركزية (CPU) في بعض عمليات تنفيذ Cortex-A8.

ولن تضطر إلى استخدام أي علامة محددة في برنامج التحويل البرمجي عند استهداف واجهات ABI الأخرى.

لمزيد من المعلومات عن توافق واجهة التطبيق الثنائية (ABI) مع واجهة التطبيق الثنائية (ABI)، يُرجى الاطّلاع على واجهات التطبيق الثنائية (ABI) في Android.

التحذيرات والقيود

دعم Windows

ولا تعتمد ثنائيات Windows على Cygwin. هذا النقص في التبعية يجعلهم أسرع. ومع ذلك، تكمن التكلفة في أنهم لا يفهمون مواصفات مسار Cygwin مثل cygdrive/c/foo/bar، على عكس C:/foo/bar.

الاستثناءات وRTTI وSTL

تدعم البرامج الثنائية لسلسلة الأدوات استثناءات C++ وRTTI بشكل افتراضي. لإيقاف استثناءات C++ وRTTI عند إنشاء مصادر (لإنشاء رمز جهاز أخف وزنًا، على سبيل المثال)، استخدِم -fno-exceptions و-fno-rtti.

دعم C++ STL

تتضمن سلسلة الأدوات المستقلة تنفيذ مكتبة النماذج القياسية لـ C++ (STL).

  • استخدِم -static-libstdc++ للحصول على إصدار المكتبة الثابت من libc++. يؤدي ذلك إلى ضمان إدراج جميع رموز C++ STL المطلوبة في برنامجك الثنائي النهائي. هذه الطريقة مثالية إذا كنت تقوم فقط بإنشاء مكتبة مشتركة أو قابلة للتنفيذ، وهو ما ننصح به.

  • وسيتم استخدام إصدار المكتبة المشتركة من libc++ تلقائيًا. لا يلزم وضع علامات إضافية للربط بالمكتبة المشتركة. يجب حزم libc++_shared.so في تطبيقك، وإلا لن يتم تحميل الرمز.

    يوضح الجدول 2 مكان هذا الملف لكل بنية.

    الجدول 2. قيم -march القابلة للتحديد وأهدافها الناتجة عن ذلك

    سلسلة أدوات الموقع الجغرافي
    ذراع $TOOLCHAIN/arm-linux-androideabi/lib/
    ذراع64 $TOOLCHAIN/aarch64-linux-android/lib/
    x86 $TOOLCHAIN/i686-linux-android/lib/
    x86_64 $TOOLCHAIN/x86_64-linux-android/lib/

أنشِئ مشاريع مفتوحة المصدر باستخدام سلاسل أدوات مستقلة

بالنظر إلى مثال سلسلة الأدوات هذا:

# Create an arm64 API 26 libc++ toolchain.
$NDK/build/tools/make_standalone_toolchain.py \
  --arch arm64 \
  --api 26 \
  --install-dir=my-toolchain

إليك كيفية إعداد بيئتك لاستخدامها في إنشاء مشروع تقليدي مفتوح المصدر:

# Add the standalone toolchain to the search path.
export PATH=$PATH:`pwd`/my-toolchain/bin

# Tell configure what tools to use.
target_host=aarch64-linux-android
export AR=$target_host-ar
export AS=$target_host-clang
export CC=$target_host-clang
export CXX=$target_host-clang++
export LD=$target_host-ld
export STRIP=$target_host-strip

# Tell configure what flags Android requires.
export CFLAGS="-fPIE -fPIC"
export LDFLAGS="-pie"

المشروعات ذات أنظمة الإنشاء المخصصة

على سبيل المثال، إليك كيفية بناء صندوق الألعاب بعد تنفيذ الخطوات السابقة:

git clone https://github.com/landley/toybox.git
cd toybox
make defconfig && make

المشاريع التي تستخدم ميزة "الاعتماد التلقائي"

وبدلاً من ذلك، سيبدو المشروع المستند إلى الإعداد التلقائي كما يلي:

tar zxvf make-4.2.tar.gz
cd make-4.2
./configure --host=$target_host && make

وتجدر الإشارة إلى أنّ المشاريع المستندة إلى الإعداد التلقائي تختلف اختلافًا كبيرًا في دعمها لميزة "التجميع المتبادل". يُرجى العِلم أيضًا أنّه في حال git clone مشروع مستنِد إلى التأكيد التلقائي، من غير المرجّح أن يتم تسجيل الوصول إلى نص برمجي configure، لذا عليك اتّباع مستندات ذلك المشروع لمعرفة كيفية بدء التنفيذ.