Rantai Alat Mandiri

Anda bisa menggunakan rantai alat yang disediakan bersama Android NDK secara independen, atau sebagai plug-in bersama ID yang sudah ada. Fleksibilitas ini bisa berguna jika Anda sudah memiliki sistem pembangunan sendiri, dan hanya perlu kemampuan memanggil pengompilasi-silang agar bisa menambahkan padanya dukungan untuk Android.

Memilih Rantai Alat Anda

Pertama-tama, Anda perlu memutuskan arsitektur pemrosesan manakah yang akan ditargetkan oleh rantai alat mandiri Anda. Proses ini is selesai dengan bendera --arch.

Memilih Sysroot

Hal berikutnya yang perlu Anda lakukan adalah menentukan sysroot. Sysroot adalah direktori yang berisi header dan pustaka sistem untuk target. Untuk mendefinisikan sysroot, Anda harus mengetahui Android API level yang ingin ditargetkan untuk dukungan asli; API asli yang tersedia bervariasi menurut level Android API.

Pustaka untuk API asli untuk masing-masing level Android API berada di $NDK/platforms/; setiap direktori API-level, berisi subdirektori untuk beragam CPU dan arsitektur. Header berada di $NDK/sysroot.

Untuk detail selengkapnya tentang Android API level dan masing-masing API asli yang didukungnya, lihat Android NDK Native API.

Membuat Rantai Alat

NDK menyediakan skrip shell make_standalone_toolchain.py agar Anda dapat melakukan penginstalan rantai alat yang disesuaikan dari baris perintah.

Ini alat baru yang mengganti yang lama make-standalone-toolchain.sh. Ini telah diterapkan ulang di Python, sehingga penggu Windows tidak perlu menginstal Cygwin atau MSYS untuk menjalankannya.

Skrip ini berada di direktori $NDK/build/tools/, dalam hal ini $NDK adalah akar penginstalan untuk NDK.

Contoh penggunaan skrip ini tampak seperti di bawah:

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

Perintah ini membuat direktori bernama /tmp/my-android-toolchain/, yang berisi salinan sysroot android-21/arch-arm, dan biner rantai alat untuk arsitektur ARM 32-bit.

Perhatikan bahwa biner rantai alat tidak tergantung pada atau berisi jalur khusus host. Dengan kata lain, Anda bisa menginstalnya di lokasi apa pun atau bahkan memindahnya jika perlu.

Argumen --arch diperlukan, tetapi level API akan dikembalikan ke default level minimum yang didukung untuk arsitektur yang diberikan (saat ini 16 untuk arsitektur 32-bit dan 21 for arsitektur 64-bit).

Sejak r18, semua rantai mandiri menggunakan Clang dan libc++. Pustaka bersama libc++ akan digunakan oleh default kecuali membangun eksekutabel statis. Untuk memaksa penggunaan pustaka statis, teruskan -static-libstdc++ saat menautkan. Perilaku ini cocok dengan rantai alat host normal.

Seperti yang disebutkan di dalam Dukungan Pustaka C++, Anda akan sering meneruskan -latomic saat menautkan ke libc++.

Perhatikan bahwa jika Anda menghilangkan opsi --install-dir, alat ini menciptakan tarball di direktori saat ini bernama $TOOLCHAIN_NAME.tar.bz2. Tarball bisa ditempatkan di direktori lain menggunakan --package-dir.

Untuk opsi selengkapnya dan detail, gunakan --help.

Menggunakan Clang

Biner Clang akan otomatis dimasukkan dalam rantai kunci mandiri.

Ada dua skrip pembungkus, bernama clang dan clang++, di <install-dir>/bin. Skrip ini memanggil biner clang dengan bendera arsitektur target yang benar. Dengan kata lain, semuanya bekerja tanpa modifikasi apa pun, dan Anda akan dapat menggunakannya dalam versi sendiri cukup dengan menyetel variabel lingkungan CC dan CXX untuk menunjuk ke sana.

Ada juga skrip pembungkus bernama gcc dan g++ yang juga memanggil Clang. Hal ini dilakukan untuk menyediakan beberapa level kompatibilitas untuk file pembangunan yang secara eksplisit mengacu ke GCC meski NDK tidak lagi berisi GCC. Ternyata, jika file pembangunan menggunakan opsi baris perintah yang tidak didukung Clang, Anda harus menghapus atau menggantinya.

Target Clang pada ARM

Saat membangun untuk ARM, Clang mengubah target berdasarkan adanya opsi -march=armv7-a dan/atau -mthumb bendera pengompilasi:

Tabel 1. Nilai -march yang dapat ditetapkan dan target yang dihasilkannya.

-march nilai Target yang dihasilkan
-march=armv7-a armv7-none-linux-androideabi
-mthumb thumb-none-linux-androideabi
Baik -march=armv7-a dan -mthumb thumbv7-none-linux-androideabi

Anda juga dapat menggantinya dengan -target milik sendiri sesuai keinginan.

clang dan clang++ akan menjadi drop-in untuk gcc dan g++ dalam makefile. Jika ragu, gunakan opsi berikut saat memanggil pengompilasi untuk memastikan opsi ini berfungsi dengan benar:

  • -v untuk membuang perintah terkait dengan masalah driver pengompilasi
  • -### untuk membuang opsi baris, termasuk opsi yang telah ditentukan sebelumnya secara implisit.
  • -x c < /dev/null -dM -E untuk membuang definisi preprosesor yang telah ditentukan sebelumnya
  • -save-temps untuk membandingkan *.i atau *.ii file yang telah diproses sebelumnya.

Kompatibilitas ABI

Secara default, rantai kunci mandiri Clang ARM akan menargetkan ABI armeabi-v7a. Ini bisa diganti dengan meneruskan opsi -march atau -target.

Sebaiknya gunakan bendera pengompilasi -mthumb untuk memaksa dihasilkannya petunjuk Thumb-2 16-bit. Jika dihilangkan, rantai kunci akan mengeluarkan petunjuk ARM 32-bit.

Untuk menggunakan petunjuk NEON, Anda harus menggunakan bendera pengompilasi -mfpu: -mfpu=neon.

Perhatikan, setelan ini akan memaksa penggunaan VFPv3-D32, sesuai spesifikasi ARM.

Pastikan juga menyediakan dua bendera berikut pada penaut: -march=armv7-a -Wl,--fix-cortex-a8.

Bendera pertama memerintahkan penaut untuk memilih pustaka rantai alat yang disesuaikan untuk armv7-a. Flag ke-2 diperlukan sebagai solusi bagi bug CPU di beberapa implementasi Cortex-A8.

Anda tidak perlu menggunakan bendera pengompilasi tertentu saat menargetkan ABI lain.

Untuk mengetahui selengkapnya tentang dukungan ABI, lihat ABI.

Peringatan dan Batasan

Dukungan Windows

Biner Windows tidak bergantung pada Cygwin. Tidak adanya dependensi ini membuatnya jadi lebih cepat. Akan tetapi konsekuensinya adalah tidak memahami spesifikasi jalur Cygwin seperti cygdrive/c/foo/bar, yang kebalikan dari C:/foo/bar.

Pengecualian, RTTI, dan STL

Biner rantai alat mendukung pengecualian C++ dan RTTI secara default. Untuk menonaktifkan pengecualian C++dan RTTI saat membangun sumber (untuk menghasilkan kode mesin kelas ringan, misalnya), gunakan -fno-exceptions dan -fno-rtti.

Dukungan C++ STL

Rantai alat mandiri meliputi implementasi C++ Standard Template Library (STL).

  • Gunakan -static-libstdc++ untuk mendapatkan versi pustaka statis dari libc++. Hal itu akan memastikan semua kode C++ STL yang diperlukan akan disertakan ke dalam biner akhir. Metode ini ideal jika Anda hanya menghasilkan satu pustaka bersama atau eksekutabel, yang mana adalah rekomendasi kami.

  • Versi pustaka bersama dari libc++ akan digunakan secara default. Tidak ada tambahan bendera yang diperlukan untuk menautkan ke pustaka bersama. Anda harus mengemas libc++_shared.so dalam apikasi, atau kode tidak akan memuat.

    Tabel 2 menampilkan lokasi ini untuk setiap arsitektur.

    Tabel 2. Nilai -march yang ditetapkan dan target yang dihasilkannya.

    Rantai Alat Lokasi
    arm $TOOLCHAIN/arm-linux-androideabi/lib/
    arm64 $TOOLCHAIN/aarch64-linux-android/lib/
    x86 $TOOLCHAIN/i686-linux-android/lib/
    x86_64 $TOOLCHAIN/x86_64-linux-android/lib/

Membangun Proyek Open Source Menggunakan Rantai Alat Mandiri

Contoh rantai alat yang diberikan:

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

Inilah cara Anda menyetel lingkungan untuk menggunakannya untuk membangun proyek open source tradisional:

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

Proyek dengan sistem pembangunan khusus

Sebagai contoh, inilah cara membangun toybox setelah melakukan langkah-langkah sebelumnya:

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

Proyek yang menggunakan autoconf

Atau proyek berbasis autoconf akan lebih terlihat seperti ini:

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

Perhatikan bahwa proyek berbasis autoconf sangat bervariasi dalam dukungannya untuk kompilasi silang. Perhatikan juga bahwa jika git clone proyek berbasis autoconf, tidak mungkin proyek ini memiliki skrip configure yang terdaftar, jadi Anda harus mengikuti dokumentasi proyek untuk mengetahui cara bootstrap.