Toolchain Mandiri

Anda dapat menggunakan toolchain yang disediakan bersama Android NDK secara mandiri atau sebagai plug-in dengan IDE yang ada. Fleksibilitas ini dapat berguna jika Anda sudah memiliki sistem build sendiri, dan hanya perlu kemampuan untuk memanggil lintas compiler agar dapat menambahkan dukungan ke Android.

Memilih Toolchain

Pertama-tama, Anda perlu memutuskan arsitektur prosesor mana yang akan ditargetkan oleh toolchain mandiri. Tindakan ini dilakukan dengan 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 level API Android yang ingin Anda targetkan untuk dukungan native; API native yang tersedia bervariasi sesuai level API Android.

Library API native untuk masing-masing level API Android terletak di $NDK/platforms/; setiap direktori level API memuat subdirektori untuk berbagai CPU dan arsitektur. Header-nya terletak di $NDK/sysroot.

Untuk informasi selengkapnya tentang level API Android dan API native terkait yang didukung, buka API Native.

Membuat Toolchain

NDK menyediakan skrip make_standalone_toolchain.py untuk memungkinkan Anda melakukan penginstalan toolchain yang disesuaikan dari command line.

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

Script ini terletak di direktori $NDK/build/tools/, di mana $NDK adalah root 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 toolchain untuk target ARM 32-bit.

Perhatikan 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 secara default level API akan ditetapkan ke level minimum yang didukung untuk arsitektur yang diberikan (saat ini level 16 untuk arsitektur 32-bit dan level 21 untuk arsitektur 64-bit).

Sejak r18, semua toolchain mandiri menggunakan Clang dan libc++. Library bersama libc++ akan digunakan secara default kecuali jika membuat executable statis. Untuk memaksakan penggunaan library statis, lewati -static-libstdc++ saat menautkan. Perilaku ini sesuai dengan toolchain host normal.

Seperti disebutkan dalam Dukungan Library C++, Anda sering kali perlu melewati -latomic saat menautkan ke libc++.

Perhatikan bahwa jika Anda menghilangkan opsi --install-dir, fitur ini akan membuat tarball di direktori saat ini dengan nama $TOOLCHAIN_NAME.tar.bz2. Tarball dapat ditempatkan di direktori berbeda dengan menggunakan --package-dir.

Untuk opsi dan detail lainnya, gunakan --help.

Menangani Clang

Biner Clang akan otomatis disertakan dalam toolchain mandiri.

Ada juga dua skrip wrapper, bernama clang dan clang++, di bagian <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 Anda dapat menggunakannya di build Anda sendiri hanya dengan menetapkan variabel lingkungan CC dan CXX agar mengarah ke sana.

Ada juga skrip wrapper bernama gcc dan g++ yang juga memanggil Clang. Hal ini untuk memberikan tingkat kompatibilitas tertentu pada file build yang secara eksplisit merujuk ke GCC meskipun NDK tidak lagi memuat GCC. Tentu saja, jika file build menggunakan opsi command line yang tidak didukung oleh Clang, Anda harus menghapus atau menggantinya.

Target Clang pada ARM

Saat membuat model 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 dihasilkan.

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

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

clang dan clang++ akan menjadi pengganti drop-in untuk gcc dan g++ pada makefile. Jika ragu-ragu, gunakan opsi berikut saat memanggil compiler untuk memverifikasi bahwa keduanya berfungsi dengan baik:

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

Kompatibilitas ABI

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

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

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

Perhatikan bahwa setelan ini memaksakan penggunaan VFPv3-D32, sesuai spesifikasi ARM.

Pastikan juga untuk menyediakan dua tanda berikut ke linker: -march=armv7-a -Wl,--fix-cortex-a8.

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

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

Untuk mempelajari lebih lanjut dukungan ABI, buka ABI.

Peringatan dan Batasan

Dukungan Windows

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

Pengecualian, RTTI, dan STL

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

Dukungan C++ STL

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

  • Gunakan -static-libstdc++ untuk mendapatkan versi library statis libc++. Dengan begitu, semua kode C++ STL 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; jika tidak, kode Anda tidak akan dimuat.

    Tabel 2 menampilkan lokasi file ini untuk setiap arsitektur.

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

    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
    

Perhatikan bahwa project berbasis autoconf sangat bervariasi dalam dukungannya terhadap kompilasi silang. Perhatikan juga bahwa jika Anda git clone project berbasis autoconf, kemungkinan skrip configure check-in tidak ada, sehingga Anda harus mengikuti dokumentasi project tersebut terkait cara melakukan bootstrap.