Saya ingin memberi tahu Anda bagaimana saya mengumpulkan kompiler silang untuk Raspberry Pi4 menggunakan crosstool-ng. Mungkin seseorang akan menganggap topik itu terlalu primitif dan membosankan. Pada awalnya saya sendiri berpikir bahwa saya dapat dengan cepat menyusun cross-compiler, tetapi saya harus mengotak-atik dan mempelajari masalah tersebut, beberapa nuansa tidak terduga bagi saya. Kemudian saya akan memberi tahu Anda apa dan bagaimana saya melakukannya.
Mungkin pertanyaan pertama yang perlu Anda tanyakan pada diri sendiri adalah: "Untuk apa cross-compiler itu?" Faktanya, Raspberry Pi4 cukup cepat dan Anda dapat mengkompilasi program langsung di atasnya. Jika proyeknya sederhana, maka sangat mungkin untuk melakukannya. Tetapi ketika proyek tumbuh dan menjadi lebih kompleks, maka lebih baik beralih ke kompilasi silang. Maka lebih mudah untuk menyelesaikan masalah lain, misalnya, Anda dapat mengatur perakitan otomatis proyek di server integrasi. Kompilasi silang pada PC yang cepat dapat meningkatkan kecepatan build secara signifikan, dan Anda dapat menemukan alat yang lebih baik untuk mengedit program di PC.
Pertanyaan kedua: Apakah saya dapat menggunakan cross-compiler yang sudah jadi? Mengapa mengambil milik Anda sendiri? " Sejujurnya, saya belum menemukan kompiler silang normal untuk Raspberry. Mungkin saya terlihat buruk? Di github dari Rasberryada proyek alat dan ada beberapa kompiler silang, tetapi mereka kuno! Nah, ada apa disana? Versi 4.9.3? Entah bagaimana tidak serius. Di halaman unduh Linaro, saya hanya melihat versi 7.5, sudah lebih baik, tetapi, pertama, pada Raspberry Buster OS itu sendiri, versi 8.3 sudah, dan kedua, kompiler Linaro bekerja untuk saya hanya setelah beberapa tambalan. Agak aneh ...
Setelah mencoba menjalankan compiler Linaro, saya berpikir bahwa saya mungkin bisa membuat sendiri cross-compiler saya. Saya sudah memiliki pengalaman dengan crosstool-ng. Saya melakukan kompiler silang untuk Amber SoC .
Apa kerumitan perakitan? Alat bantu silang memiliki banyak pengaturan berbeda yang tidak selalu jelas. Membangun kompiler silang di laptop saya membutuhkan waktu sekitar 45 menit. Jika Anda membuat kesalahan dengan pengaturan, maka kompilator silang yang dihasilkan entah bagaimana tidak berfungsi seperti itu, tidak mengumpulkan sesuatu, atau mengumpulkan, tetapi biner yang dihasilkan tidak berjalan di Raspberry. Setelah memeriksa cross-compiler yang dihasilkan, saya sekali lagi harus mengubah sesuatu dalam pengaturan dan membuatnya lagi dari awal. Ya, saya mencoba beberapa kali sampai berhasil seperti yang saya inginkan.
Mungkin hal utama yang saya tidak terlalu mengerti pada awalnya adalah kompilator harus cocok dengan sistem operasi. Kelihatannya agak aneh, tapi ternyata seperti itu. Memang, OS sudah berisi pustaka standar c / c ++. Mereka mengekspor satu set fungsi. Kode yang dihasilkan oleh kompilator silang harus berisi panggilan ke fungsi perpustakaan ini. Oleh karena itu, versi pustaka dalam kompiler silang itu sendiri dan di OS yang akan menghasilkan kode harus cocok.
Mari kita coba membuat kompiler silang.
Prosedurnya adalah sebagai berikut:
1) Periksa apakah paket berikut diinstal pada sistem host kami (Saya menggunakan Ubuntu 18):
gcc g++ gperf bison flex texinfo help2man make libncurses5-dev python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip patch libstdc++6 rsync git
Jika ada yang hilang, maka Anda perlu menginstal melalui sudo apt install.
2) Unduh crosstool-ng versi 1.24.0 dari situs web mereka:
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.24.0.tar.bz2
3) Buka kemasan arsip yang dihasilkan:
tar xjf crosstool-ng-1.24.0.tar.bz2 cd crosstool-ng-1.24.0
4) Menyusun crosstool-ng:
./configure make make install
5) Menambal crosstool-ng
Ini adalah tindakan yang agak aneh, tetapi tanpanya saya tidak mendapatkan hasil yang baik. Tanpa tambalan ini, kompilator silang secara default menolak untuk mencari pustaka di folder / usr / lib / arm-linux-gnueabihf yang berhubungan dengan sysroot.
Tambalan harus diperoleh di bagian paling raspberry.
Pada raspberry pi4 dengan OS Buster diinstal (ini penting, saya membuat kompiler silang untuk OS khusus ini), Anda perlu mengambil sumber binutils:
sudo apt install binutils-source
dan lihat
/usr/src/binutils/patches/129_multiarch_libpath.patch
File ini kita letakkan di folder crosstool-ng-1.24.0 / packages / binutils / 2.31.1 di komputer host kita. Penting untuk meletakkannya di folder ini, karena pada Raspberry Pi OS Buster itu sendiri, versi binutils adalah 2.31.1. Periksa ini dengan perintah di konsol pada raspberry:
ld --version
Selain itu, Anda perlu memeriksa GLIB mana yang ada di OS Anda untuk memeras:
ldd --version
Saya memiliki 2.28 di Buster, yang berarti crosstool-ng itu sendiri perlu dikonfigurasi di versi GLIB 2.28 ini, ada versi yang berbeda secara default. Jika ini tidak dilakukan, maka kompilator silang akan menghasilkan kode yang tidak akan berjalan di Raspberry di Buster OS - biner dapat merujuk ke fungsi yang tidak ada di pustaka eksternal.
6) Siapkan konfigurasi crosstool-ng awal
Sudah ada beberapa konfigurasi tipikal dalam crosstool-ng itu sendiri. Termasuk, ada konfigurasi yang sangat mirip dengan yang kita butuhkan untuk Raspberry Pi3.
Daftar semua kemungkinan konfigurasi dapat dilihat dengan perintah:
./ct-ng list-samples
Kemudian konfigurasi yang dipilih harus "diaktifkan" dengan perintah:
./ct-ng armv8-rpi3-linux-gnueabihf
File konfigurasi baru .config akan muncul, yang secara lengkap mendefinisikan properti dari cross-compiler masa depan. Sekarang perlu dikoreksi sedikit. Anda dapat mengeditnya secara manual, tetapi lebih mudah memperbaikinya dari menu:
./ct-ng menuconfig
Menu pertama terlihat seperti ini:
7) Selanjutnya, ubah opsi aneh, mungkin opsional.
Hampir di semua tempat di mana setidaknya ada sesuatu yang ditulis tentang pembuatan kompilator silang untuk Raspberry, mereka menulis untuk menghapus centang pada opsi "Render the toolchain read-only". Pengaturan ini ada di menu "Paths and misc options". Dokumentasi crosstool-ng mengatakan bahwa secara default kompilator yang dihasilkan akan menjadi hanya-baca sehingga program yang dikompilasi tidak diinstal secara tidak sengaja di sysroot dari kompilator itu sendiri. Menurut pendapat saya, ini adalah keputusan yang masuk akal. Saya tidak tahu mengapa ada penulis yang menulis untuk menghapus centang dari sini ...
8) Berikutnya. Buka item "Opsi target" dan atur nilainya sesuai dengan tangkapan layar:
Saya harus mengatakan bahwa, pada kenyataannya, Raspberry Pi4 memiliki prosesor Cortex-A72 dan ini dapat ditetapkan di sini di menu. Namun, saya menyimpan Cortex-A53 untuk diri saya sendiri karena saya akan mengkompilasi tidak hanya untuk Pi4, tetapi juga untuk Pi3. Meskipun, pengaturan yang tepat sudah dapat ditentukan saat memulai kompiler gcc menggunakan parameter baris perintah -mcpu = cortex-a72
Saya juga ingin menambahkan bahwa saya lebih suka kompiler silang memiliki tupel yang sama persis dengan kompiler di papan Raspberry itu sendiri. Artinya, kompiler terakhir adalah arm-linux-gueabihf dan tidak ada yang lain. Lebih mudah bagiku. Banyak paket yang ada menyertakan file cmake siap pakai, di mana kompilernya ditugaskan ke arm-linux-gnueabihf. Kami tidak ingin memperbaiki semua file cmake ini dengan tangan dan menulis sesuatu seperti armv8-mygcc-linux-gnueabihf di sana? Untuk melakukan ini, saya menonaktifkan opsi "Abaikan bagian vendor dari tuple target".
9) Masuk ke menu "Binary utilities" dan instal versi binutils 2.31.1 (Ingat bahwa kami masih memiliki patch untuk itu?)
10) Buka menu "Sistem operasi" dan instal kernel versi 4.20
Sebenarnya Raspberry Buster OS sudah memiliki kernel 5.10, namun maksimal yang bisa anda instal hanya 4.20
11) Masuk ke menu "C-libraries" dan instal GLIB 2.28 versi
12) Buka "C-compiler" menu
Instal versi yang diinginkan dari cross-compiler 8.3.0 mendatang dan tambahkan opsi --enable-multiarch ke pengaturan kompiler konfigurasi ekstra gcc inti. Penting bahwa kompilator silang menemukan pustaka di sysroot di sepanjang jalur / usr / lib / arm-linux-gnueabihf
Sekarang kita keluar dari semua menu, simpan perubahan yang dibuat saat diminta dan mulai membangun.
13) Perakitan dilakukan dengan perintah sederhana:
export DEB_TARGET_MULTIARCH=arm-linux-gnueabihf ./ct-ng build
Akan harus menunggu. Butuh waktu sekitar 45 menit untuk merakit di laptop saya. Setelah membangun, kompilator silang baru Anda terletak di jalur ~ / x-tools / arm-linux-gnueabihf
Anda dapat memeriksa jalur perpustakaan mana yang akan digunakan oleh kompilator silang secara default. Apakah akan terlihat di jalur / usr / lib / arm-linux-gnueabihf?
Untuk melakukan ini, jalankan perintah:
~/x-tools/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ld --verbose | grep "SEARCH"
Perintah tersebut harus mengembalikan sesuatu seperti ini:
SEARCH_DIR("=/usr/local/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/usr/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/home/nick/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/lib");
Perhatikan bahwa jalur dimulai dengan tanda "=". Ini berarti bahwa ini adalah jalur sysroot-relative jika ditentukan saat menjalankan gcc dengan opsi baris perintah --sysroot = PATH_TO_YOUR_SYSROOT.
Mungkin itu saja. Tetap memutuskan di mana mendapatkan sysroot. Cara termudah adalah dengan menginstal semua paket pengembangan yang diperlukan pada Raspberry Pi dan kemudian, mencabut kartu SD dari perangkat, mentransfernya ke PC host. Tetapi ada juga beberapa nuansa.
Sekarang kita memiliki kompilator silang, kita dapat membangun semacam program khusus parser. Misalnya, demo userland dari Raspberry itu sendiri:
git clone https://github.com/raspberrypi/userland.git cd userland export PATH=${HOME}/x-tools/arm-linux-gnueabihf/bin:$PATH ./buildme
Hasil kompilasi akan berada di folder build / bin.
Di akhir artikel, saya ingin memberikan tabel parameter tambahan untuk kompiler gcc saat membangun proyek untuk berbagai versi raspberry:
Raspberry Pi 1: -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp (alias for vfpv2) Raspberry Pi 2: -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 Raspberry Pi 3: -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits Raspberry Pi 4: -mcpu=cortex-a72 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits
Semoga artikel saya bermanfaat bagi seseorang.