Toolchain Mandiri (Dihentikan)

Anda dapat menggunakan toolchain yang disediakan dengan Android NDK secara mandiri atau sebagai plugin dengan IDE yang ada. Fleksibilitas ini akan berguna jika Anda sudah memiliki sistem build sendiri dan hanya memerlukan kemampuan untuk memanggil compiler silang agar dapat menambahkan dukungan untuknya di Android.

Memilih Toolchain

Anda perlu memutuskan terlebih dahulu arsitektur prosesor mana yang akan ditargetkan oleh toolchain mandiri. Untuk melakukannya, gunakan tanda --arch.

Memilih Sysroot

Hal berikutnya yang perlu Anda lakukan adalah menentukan sysroot. Sysroot adalah direktori yang memuat header dan library sistem untuk target Anda. Untuk menentukan sysroot, Anda harus mengetahui API level Android yang ingin Anda targetkan untuk dukungan native; API native yang tersedia bervariasi sesuai API level Android.

Library untuk API native bagi setiap API level Android terletak di bawah $NDK/platforms/; sebaliknya, setiap direktori level API berisi subdirektori untuk berbagai CPU dan arsitektur. Header berada di $NDK/sysroot.

Untuk mengetahui detail selengkapnya tentang API level Android dan API native terkait yang didukungnya, buka API Native.

Membuat Toolchain

NDK menyediakan skrip make_standalone_toolchain.py untuk memungkinkan Anda melakukan penginstalan toolchain yang disesuaikan dari baris perintah.

Ini merupakan fitur baru yang menggantikan make-standalone-toolchain.sh lama. Fitur ini telah diterapkan ulang di Python sehingga pengguna Windows tidak perlu menginstal Cygwin atau MSYS untuk menjalankannya.

Skripnya terletak dalam direktori $NDK/build/tools/, dengan $NDK yang merupakan direktori utama penginstalan untuk NDK.

Berikut adalah contoh penggunaan skrip ini:

$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 toolchain untuk target ARM 32-bit.

Perlu diketahui bahwa biner toolchain tidak bergantung pada atau berisi jalur khusus host. Dengan kata lain, Anda dapat menginstalnya di lokasi mana pun atau bahkan memindahkannya jika perlu.

Argumen --arch diperlukan, tetapi API level akan ditetapkan secara default ke level minimal yang didukung untuk arsitektur yang ditentukan (saat ini adalah 16 untuk arsitektur 32-bit dan 21 untuk arsitektur 64-bit).

Dimulai dari r18, semua toolchain mandiri menggunakan Clang dan libc++. Library bersama libc++ akan digunakan secara default kecuali Anda akan mem-build executable statis. Untuk memaksa penggunaan library statis, teruskan -static-libstdc++ saat melakukan penautan. Perilaku ini sesuai dengan toolchain host normal.

Seperti yang disebutkan dalam Dukungan Library C++, Anda biasanya harus meneruskan -latomic ketika akan menautkan libc++.

Perlu diketahui bahwa jika Anda mengabaikan opsi --install-dir, fitur tersebut akan membuat tarball dalam direktori saat ini yang bernama $TOOLCHAIN_NAME.tar.bz2. Tarball dapat diletakkan dalam direktori yang berbeda menggunakan --package-dir.

Untuk opsi dan detail selengkapnya, gunakan --help.

Menangani Clang

Biner Clang akan otomatis disertakan dalam toolchain mandiri.

Selain itu, ada juga dua skrip wrapper, yang diberi nama clang dan clang++, di bawah <install-dir>/bin. Skrip ini memanggil biner clang dengan tanda arsitektur target yang benar. Dengan kata lain, skrip tersebut dapat digunakan tanpa modifikasi apa pun, dan dapat digunakan di build Anda sendiri hanya dengan menetapkan variabel lingkungan CC dan CXX agar mengarah ke skrip tersebut.

Kemudian, ada juga skrip wrapper bernama gcc dan g++ yang juga memanggil Clang. Skrip ini berfungsi untuk menyediakan level kompatibilitas bagi file build yang secara eksplisit merujuk ke GCC, meskipun NDK tidak lagi berisi GCC. Tentunya, jika ada file build yang menggunakan opsi command line yang tidak didukung oleh Clang, Anda harus menghapus atau menggantinya.

Target Clang pada ARM

Saat melakukan proses build untuk ARM, Clang mengubah target berdasarkan keberadaan tanda compiler -march=armv7-a dan/atau -mthumb:

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

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

Anda juga dapat menggantinya dengan -target Anda sendiri jika menginginkannya.

clang dan clang++ harus menjadi pengganti drop-in untuk gcc dan g++ dalam makefile. Jika tidak yakin, gunakan opsi berikut saat memanggil compiler untuk memastikan keduanya berfungsi dengan baik:

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

Kompatibilitas ABI

Secara default, toolchain mandiri Clang ARM akan menargetkan armeabi-v7a ABI. Anda dapat menggantinya dengan meneruskan opsi -march atau -target yang sesuai.

Sebaiknya gunakan tanda compiler -mthumb untuk memaksa pembuatan instruksi Thumb-2 16-bit. Jika dihilangkan, toolchain akan mengeluarkan petunjuk ARM 32-bit.

Untuk menggunakan instruksi NEON, Anda harus menggunakan tanda compiler -mfpu: -mfpu=neon.

Perlu diketahui bahwa setelan ini akan memaksa penggunaan VFPv3-D32, sesuai spesifikasi ARM.

Selain itu, pastikan untuk memberikan dua tanda berikut pada linker: -march=armv7-a -Wl,--fix-cortex-a8.

Tanda pertama memerintahkan linker untuk memilih library toolchain yang dirancang bagi armv7-a. Tanda kedua diperlukan sebagai solusi untuk bug CPU pada beberapa implementasi Cortex-A8.

Anda tidak perlu menggunakan tanda compiler tertentu saat menargetkan ABI lain.

Untuk mempelajari dukungan ABI lebih lanjut, buka ABI.

Peringatan dan Batasan

Dukungan Windows

Biner Windows tidak bergantung pada Cygwin. Tidak adanya dependensi ini menjadikannya lebih cepat. Namun, konsekuensinya adalah, biner tersebut tidak memahami spesifikasi jalur Cygwin seperti cygdrive/c/foo/bar, dibandingkan dengan C:/foo/bar.

Pengecualian, RTTI, dan STL

Secara default, biner toolchain mendukung pengecualian C++ dan RTTI. Untuk menonaktifkan pengecualian C++ dan RTTI saat mem-build sumber (untuk membuat kode mesin yang lebih ringan, misalnya), gunakan -fno-exceptions dan -fno-rtti.

Dukungan C++ STL

Toolchain mandiri menyertakan implementasi Library Template Standar (STL) C++.

  • Gunakan -static-libstdc++ untuk mendapatkan versi library statis libc++. Dengan demikian, semua kode STL C++ yang diperlukan akan disertakan dalam biner akhir Anda. Metode ini ideal jika Anda hanya menghasilkan satu library bersama atau executable, yang merupakan rekomendasi kami.

  • Secara default, versi library bersama ibc++ akan digunakan. Tidak ada tanda tambahan yang diperlukan untuk menautkan ke library bersama. Anda harus mengemas libc++_shared.so dalam aplikasi, atau kode Anda tidak akan dimuat.

    Tabel 2 menampilkan lokasi file ini untuk setiap arsitektur.

    Tabel 2. Nilai -march yang dapat ditentukan dan target yang dihasilkannya.

    Toolchain 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/

Membuat Project Open Source Menggunakan Toolchain Mandiri

Misalkan toolchain dalam contoh ini:

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

Berikut ini cara menyiapkan lingkungan untuk digunakan dalam membuat project 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"
    

Project dengan sistem build kustom

Sebagai contoh, berikut cara membuat toybox setelah menjalankan langkah-langkah sebelumnya:

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

Project menggunakan autoconf

Sebagai alternatif, project berbasis autoconf akan terlihat seperti ini:

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

Perlu diketahui bahwa project berbasis autoconf sangat bervariasi dalam dukungannya terhadap kompilasi silang. Selain itu, perlu diperhatikan bahwa jika Anda melakukan git clone pada project berbasis autoconf, project tersebut kemungkinan tidak memiliki skrip configure yang terdaftar sehingga Anda harus mengikuti dokumentasi project tentang cara melakukan bootstrap.