Apakah kompilasi silang itu? Apa alat untuk membangun file biner untuk Windows di Linux ? Bagaimana cara mengkonfigurasi wadah buruh pelabuhan untuk semua ini? Berikut adalah beberapa masalah yang akan dibahas di bawah ini.
Alat-alatnya
Kompilasi silang memungkinkan Anda mendapatkan kode yang dapat dieksekusi untuk platform selain dari yang digunakan untuk menjalankan proses ini.
Dalam artikel ini, kita akan melihat kompilasi silang untuk platform Windows di Linux .
Contoh kompilator silang adalah Mingw-w64 . Bahkan, ini hanya menyediakan alat untuk membangun aplikasi, tetapi jika Anda membutuhkan perpustakaan pihak ketiga yang bukan bagian dari STL , Anda harus mengumpulkannya dan dependensi. Anda juga dapat menggunakan file biner yang sudah jadi, seperti yang dijelaskan dalam artikel ini .
Proyek mxe , yang tidak hanya menyediakan alat, tetapi juga pustaka, menyederhanakan pengaturan perakitan. Daftar mereka dapat ditemukan di situs web resmi. Saat memasang pustaka, kontrol dependensi digunakan, mis. paket yang diperlukan dan semua yang diperlukan untuk operasinya akan diinstal. Alat-alat disampaikan dalam konfigurasi pra-konfigurasi, misalnya, untuk perakitan statis aplikasi 64-bit. Ini sangat memudahkan perakitan.
Lingkungan mxe digunakan untuk folder lokal pengguna. Untuk melakukan ini, cukup instal dependensi melalui manajer paket dan klon repositori. Di root repositori adalah Makefile , yang melakukan instalasi perpustakaan yang ditetapkan untuk tujuan tersebut, menambahkan alat untuk perakitan, dll.
Penting untuk dicatat bahwa lingkungan build dilokalkan dalam foldernya, ini memungkinkan Anda untuk mengonfigurasi lingkungan individu untuk setiap aplikasi.
Wadah itu
Katakanlah build rilis untuk Windows dikonfigurasikan pada mesin lokal. Rilis keluar cukup sering, dalam beberapa versi perpustakaan baru ditambahkan, dan beberapa, misalnya, dihapus. Suatu hari, bos menuntut untuk membuang rilis untuk pemula. Bagaimana cara mengkonfigurasi lingkungan build-nya? Pustaka apa yang harus diambil dari repositori mxe , dan untuk yang mana dibangun dari sumber?
Dalam hal ini, Anda bisa mendapatkan skrip bash yang akan menyebarkan seluruh lingkungan dalam folder yang diberikan. Dan setelah mencoba memperbarui skrip ini. Tetapi, seperti dokumentasi untuk proyek, pada satu saat kritis, itu bisa menjadi usang.
Solusi yang baik adalah dengan mengisolasi lingkungan build kami di dalam wadah buruh pelabuhan . File buruh pelabuhan itu sendiri akan berisi serangkaian instruksi mandiri untuk menyebarkan lingkungan, dan keberadaan kontainer akan membantu untuk menghindari mengacaukan sistem rumah dengan perpustakaan yang tidak perlu.
Menyatukan semuanya
Untuk demonstrasi, mari ambil proyek Qt sederhana - SimpleQtProject . Proyek ini dibangun oleh utilitas qmake , dan terdiri dari satu bentuk tunggal. Ini, tentu saja, dilakukan untuk kesederhanaan. Juga di folder buruh pelabuhan adalah file untuk membangun wadah.
Pertimbangkan file proyek buruh pelabuhan . Bahkan, itu terdiri dari beberapa bagian utama:
- menginstal dependensi untuk sistem build
- instalasi dan konfigurasi sistem perakitan
- mengkompilasi proyek dan menyalin artefak ke sistem host
Hanya perintah dasar dari file yang dipertimbangkan di bawah ini, untuk pengenalan lengkap disarankan untuk berkonsultasi dengan repositori .
Kami melewatkan titik pertama dan melanjutkan langsung ke instalasi mxe .
Kloning repositori:
RUN mkdir /cross \ && cd /cross \ && git clone https://github.com/mxe/mxe.git \ && cd mxe \ && git checkout build-2019-06-02
Pada saat penulisan, rilis terbaru adalah build-2019-06-02 . Cabang master tidak digunakan di sini karena alasan sederhana: pengulangan perakitan diperlukan. Kalau tidak, saat menambahkan komit baru ke master, majelis mungkin pecah.
Selanjutnya, kami mengkonfigurasi sistem build:
RUN make MXE_TARGETS=x86_64-w64-mingw32.static qtbase -j4 JOBS=4
Perintah ini akan menambahkan alat (contoh cmake dan Mingw-w64 , dll.) Untuk perakitan statis proyek di bawah arsitektur 64-bit, dan kemudian mengumpulkan Qt menggunakannya.
Langkah selanjutnya adalah menambahkan path ke file mxe yang dapat dieksekusi di PATH :
ENV PATH="/cross/mxe/usr/bin:${PATH}"
Setelah lingkungan build dikonfigurasikan, Anda dapat langsung menuju ke item terakhir:
ENTRYPOINT x86_64-w64-mingw32.static-qmake-qt5 /app/src/SimpleQtProject.pro \ && make release \ && cp release/SimpleQtProject.exe /app/res/
Berikut adalah beberapa hal untuk diklarifikasi. Diasumsikan bahwa ketika wadah mulai, folder sumber yang berisi file * .pro akan dipasang di folder / app / src / , dan tempat di mana hasil perakitan harus ditambahkan akan dipasang di direktori / app / res / .
Berikut ini adalah contoh dari perintah untuk membuat docker-image , itu harus dijalankan di folder docker dari proyek yang bersangkutan:
docker build -t simple-qt-build --file windows.docker .
Majelis dimulai di sana:
docker run --mount type=bind,source=$(pwd)/result/,target=/app/res --mount type=bind,source=$(pwd)/../,target=/app/src simple-qt-build
Sebelum menjalankan perintah, Anda harus membuat folder hasil di direktori buruh pelabuhan untuk menyalin hasilnya.
Kustomisasi perakitan
Secara default, mxe menyediakan MinGW versi 5.5.0 (setidaknya ini berlaku untuk build-2019-06-02 ).
Jika proyek menggunakan fitur baru C ++ 17 , maka versi kompiler seperti itu tidak memuaskan. Untungnya, lingkungan build menyediakan versi yang lebih baru sebagai plugin terpisah. Untuk mengatasi masalah kami, kami perlu menambahkan instruksi untuk menggunakan plugin yang sesuai untuk tim pembuat perpustakaan:
make MXE_TARGETS=x86_64-w64-mingw32.static MXE_PLUGIN_DIRS=plugins/gcc7 qtbase -j4 JOBS=4
Perintah ini akan membuat kit untuk rakitan statis aplikasi 64-bit menggunakan kompiler dari versi ketujuh ( 7.4.0 ). Jika kit semacam itu sudah ada , maka itu tidak akan berubah.
Daftar semua plugin yang tersedia dapat ditemukan di halaman .
Direktori mxe / src berisi file * .mk yang menjelaskan parameter perakitan dari paket tertentu. Jika perlu, Anda dapat melakukan penyesuaian yang diperlukan untuk paket yang ada atau menambahkan paket Anda sendiri. Struktur file dijelaskan di sini - https://github.com/mxe/mxe/wiki/Add-a-New-Package:-Full-Version .
Untuk menyalin dependensi, proyek mxe menyediakan utilitas copydlldeps.sh . Tapi ini bukan satu-satunya alat yang berguna, daftar lengkapnya dapat ditemukan di halaman .
CMake dan tautan statis Qt
Kebetulan di proyek saya, saya menggunakan sistem Qt dan CMake build. Ketika diputuskan untuk membangun proyek untuk Windows , solusi terbaik adalah membangun semuanya menggunakan tautan statis untuk memberikan pengguna satu binar, tanpa ketergantungan apa pun.
Mem-parsing segunung kesalahan linker, adalah mungkin untuk mengetahui bahwa perakitan seperti itu di luar kotak tidak berfungsi, di tempat lain. Faktanya adalah bahwa ketika menggunakan tautan statis, qmake menghasilkan file * .cpp , yang berisi instruksi untuk mengimpor plugin, tentang jenis ini:
// This file is autogenerated by qmake. It imports static plugin classes for // static plugins specified using QTPLUGIN and QT_PLUGIN_CLASS.<plugin> variables. #include <QtPlugin> Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) Q_IMPORT_PLUGIN(QGifPlugin) Q_IMPORT_PLUGIN(QICOPlugin) Q_IMPORT_PLUGIN(QJpegPlugin)
Bendera dan pustaka untuk tahap penautan di Makefile juga ditambahkan.
Anda dapat mencoba bereksperimen dengan desain ini di CMakeLists.txt :
foreach(plugin ${Qt5Gui_PLUGINS}) get_target_property(_loc ${plugin} LOCATION) message("Plugin ${plugin} is at location ${_loc}") set(plugin_libs ${plugin_libs} ${_loc}) endforeach()
Dan kemudian tambahkan penggunaan plugin_libs
. Tetapi bagi saya, pendekatan ini tidak membuahkan hasil.
Pada akhirnya, saya sampai pada keputusan untuk menautkan secara dinamis (jika mungkin) semua pustaka eksternal dan menyalin, bersama dengan file yang dapat dieksekusi, dll yang diperlukan menggunakan copydlldeps.sh . Lebih detail tentang penyebaran di bawah Qt di Windows itu dijelaskan dalam artikel .
Kesimpulannya
Itu ditunjukkan di atas bagaimana, dalam beberapa langkah sederhana, Anda dapat mengkonfigurasi lingkungan untuk kompilasi silang proyek. Tapi, sayangnya, dalam kondisi nyata, semuanya tidak begitu cerah.
Meskipun proyek mxe menyediakan daftar pustaka yang mengesankan, mungkin masih belum termasuk yang Anda butuhkan atau menyertakan versi yang terlalu baru. Ya, ada peluang untuk membuat paket sendiri atau, paling buruk, membangun perpustakaan dari sumber. Tetapi tidak semuanya dapat dibangun dengan cross-compiler, jadi saya tidak dapat melakukannya dengan proyek cpprestsdk , karena itu membutuhkan vcpkg yang diinstal.
Banyak masalah yang mungkin timbul ketika membangun proyek dengan cross-compiler adalah tipikal untuk pengembangan lintas platform secara umum. Sebagai contoh, saya memiliki kesalahan aneh karena elemen enumerasi ERROR
. Ternyata di salah satu file header Windows ada makro dengan nama yang sama. Substitusi ini memecahkan semua kode.
Adalah urusan semua orang untuk menggunakan kompilasi silang atau tidak. Ini memberi saya keuntungan yang baik. Saya mengkonfigurasi perakitan untuk beberapa distribusi Linux dan Windows dalam wadah buruh pelabuhan terpisah untuk proyek SecureDialogues saya, menambahkan satu file makefile untuk memulai proses satu per satu untuk setiap kontainer. Selanjutnya, jalankan make dan setelah beberapa saat saya mendapatkan file biner untuk OS yang diperlukan di folder lokal.