Rust: Mendukung kode bit toko aplikasi Apple

Dibuat pada 24 Agu 2016  ·  89Komentar  ·  Sumber: rust-lang/rust

Bitcode adalah masa depan distribusi aplikasi Apple dan kami tidak mendukungnya sekarang. Melakukannya rumit karena Apple memilih putaran LLVM apa pun yang mereka inginkan dan memutakhirkannya sesuai keinginan mereka. Kami tidak dapat memasangkan LLVM kami dengan milik mereka karena kami memiliki kebutuhan kami sendiri dan tidak dapat dipaksa untuk memutakhirkan kapan pun Apple memutuskan.

Berikut adalah beberapa opsi:

  • Kami mengirimkan rantai alat yang sepenuhnya terpisah untuk menargetkan kode bit Apple. Ini sangat jelek.
  • Kami mengubah rustc untuk memuat LLVM secara dinamis, membuat paket rust-llvm dan paket rust-llvm-apple opsional, dan meminta rustc memuat LLVM apel untuk menangani bitcode mereka.
  • Kami membuat peti rustc_llvm_apple dan hanya menautkan dua LLVM keseluruhan ke rustc setiap saat. Ini mungkin tidak akan terbang
  • Kami membuat build rustc yang disebut rustc-apple dan mengirimkannya dalam paket rustc-apple opsional. Ini persis seperti rustc kecuali alih-alih menautkan ke rustc_llvm, ini menautkan ke rustc_llvm_apple. Ketika rustc mendapat permintaan untuk memancarkan bitcode, itu hanya tunduk sepenuhnya ke biner rustc-apple. Saya sebenarnya cukup menyukai solusi ini.
  • Kami dapat menyelidiki pembersih bitcode untuk menerjemahkan bitcode kami ke bitcode mereka. Saya pikir kemungkinan keberhasilan di sini rendah karena pemeliharaan. Saya percaya RenderScript melakukan ini.

Saya pikir pemuatan dinamis LLVM dan solusi defer-to-alternate-rustc paling menjanjikan.

cc https://users.rust-lang.org/t/ios-rust-integration/6928/4

cc @bluejekyll

A-LLVM A-rustbuild C-enhancement E-hard O-ios T-compiler T-dev-tools

Komentar yang paling membantu

Saya berhasil menautkan rustc nightly-2019-09-05 aarch64-apple-ios and rustflags = "-C lto -Z embed-bitcode" staticlib dengan aplikasi clang-1100.0.33.5 (Xcode 11 beta 7) and -fembed-bitcode . Kode sumber adalah https://github.com/saturday06/rust-ios-bitcode-test .

Semua 89 komentar

Kami mengubah rustc untuk memuat LLVM secara dinamis, membuat paket rust-llvm dan paket rust-llvm-apple opsional, dan meminta rustc memuat LLVM apel untuk menangani bitcode mereka.

Memuat LLVM secara dinamis tentu saja bukan pilihan. LLVM API kurang stabil daripada bitcode-nya dan, jika kita membangun terhadap LLVM xy, maka memiliki LLVM xz alih-alih xy hampir pasti akan merusak rustc. Cukup tautkan ke sistem LLVM secara statis (seperti yang sudah dilakukan --llvm-root ).

Kami membuat peti rustc_llvm_apple dan hanya menautkan dua LLVM keseluruhan ke rustc setiap saat. Ini mungkin tidak akan terbang

Cukup tautkan sistem LLVM (statis) untuk distribusi apel. Dalam pengalaman saya itu sudah bekerja dengan baik.

Kami dapat menyelidiki pembersih bitcode untuk menerjemahkan bitcode kami ke bitcode mereka. Saya pikir kemungkinan keberhasilan di sini rendah karena pemeliharaan. Saya percaya RenderScript melakukan ini.

Oke… jadi, masalahnya adalah format bitcode LLVM agak stabil di antara versi LLVM. Apakah apple melakukan sesuatu yang tidak biasa untuk membuat itu tidak benar, atau apakah format bitcode yang digunakan bukan LLVM sama sekali (yaitu memiliki hal-hal khusus untuk Apple)?


Saya merasa seperti saya mendengar sepanjang tahun 2013-ish bahwa menggunakan bitcode LLVM sebagai format distribusi itu bodoh. Saya tentu setuju; apakah mendistribusikan perpustakaan biner asli tidak berfungsi lagi untuk iOS?

Saya juga sangat tertarik dengan apa yang akan terjadi ketika Apple memutakhirkan ke versi LLVM dengan format bitcode yang tidak kompatibel secara internal dan orang-orang masih mengkompilasi barang dengan kompiler lama.

Saya bereksperimen secara singkat dengan ini, yaitu menghasilkan bitcode selama pembuatan kargo, kemudian mencoba membuat perpustakaan statis dengan bitcode yang disertakan. Ketika saya mencoba llvm-link ke perpustakaan bitcode, saya mendapatkan versi LLVM yang tidak kompatibel dari bitcode.

Saya tidak memiliki tes mudah untuk mereproduksi ini, tetapi tebakan saya apakah hanya ada pemeriksaan versi bodoh yang menyangkal penautan antara versi LLVM yang berbeda? Atau, saya baru saja melakukan sesuatu yang sepenuhnya salah. Saya akan mencoba membuat kasus uji ketika saya punya waktu untuk melihat ini lagi.

Akan berguna untuk memiliki pesan kesalahan yang tepat dari llvm-link.

@bluejekyll LLVM memiliki sejumlah file bitcode di direktori pengujiannya. Pengujian terhadap file bitcode ini dijalankan terus menerus (llvm-dis-3.8/opt-3.8 memahami file bitcode berusia 3 tahun dari 3.2 baik-baik saja, misalnya), jadi itu pasti beberapa barang Apple.

Cukup tautkan sistem LLVM (statis) untuk distribusi apel. Dalam pengalaman saya itu sudah bekerja dengan baik.

Ini agak lebih mudah diucapkan daripada dilakukan - sejauh yang saya ketahui, satu-satunya versi apple-llvm yang diberkati untuk unggahan App Store adalah yang dikirimkan dengan Xcode saat ini. Ini juga berpotensi berarti mempertahankan binding LLVM untuk dua versi LLVM (tidak harus dua versi minor yang berdekatan juga). Saya tidak berpikir itu valid untuk hanya menggunakan versi lama dari apple-llvm.

Saya juga sangat tertarik dengan apa yang akan terjadi ketika Apple memutakhirkan ke versi LLVM dengan format bitcode yang tidak kompatibel secara internal dan orang-orang masih mengkompilasi barang dengan kompiler lama.

Saya pikir mereka menghindari ini dengan hanya mengizinkan Xcode terbaru untuk mengirimkan aplikasi (dan saya cukup yakin itu dibakar ke dalam gambar keluaran yang versi LLVM yang Anda gunakan).

IIRC, bitcode dikemas untuk setiap arsitektur, karena bitcode lintas arsitektur tidak dihasilkan oleh dentang (saya pikir itu anti-tujuan dentang dan bitcode secara umum). Itu disimpan di bagian untuk setiap file objek jadi setidaknya itu diduplikasi. Itu bisa menjadi bagian dari mengapa seseorang menyebutkan bahwa bitcode mungkin bukan cara terbaik untuk melakukan ini.

Saya merasa agak seperti semua solusi yang direkomendasikan agak menjijikkan. Cara paling tidak berantakan yang dapat saya pikirkan adalah membiarkan target yang berbeda membebani perilaku codegen dan membuat jalur codegen Apple berada dalam peti dinamis. (Yang hanya akan menjadi jalur codegen biasa yang dikompilasi terhadap apple-llvm.)

Karena bug ini menyebutkan App Store, apakah layak membicarakan kisah penanganan pengecualian di sini? (yaitu panic=abort sangat diperlukan saat ini.)

LLVM memiliki sejumlah file bitcode di direktori pengujiannya. Pengujian terhadap file bitcode ini dijalankan terus menerus (llvm-dis-3.8/opt-3.8 memahami file bitcode berusia 3 tahun dari 3.2 baik-baik saja, misalnya), jadi itu pasti beberapa barang Apple.

@nagisa terima kasih telah memberi tahu saya tentang ini. Ini memberi saya harapan bahwa mungkin masih ada solusi di sini, dan bahwa saya mungkin melakukan sesuatu yang salah.

@ricky26 poin bagus.

sejauh yang saya ketahui, satu-satunya versi apple-llvm yang diberkati untuk unggahan App Store adalah yang dikirimkan dengan Xcode saat ini.

Bukankah Xcode LLVM di apel sama dengan sistem LLVM? Maksud saya Xcode LLVM saat itu. Kami harus memastikan xcode selalu merupakan versi terbaru saat mengirimkan kereta rustc.

Tentu saja cara Apple melakukan hal-hal yang membuat kami tidak dapat memproduksi bitcode apel yang valid dengan rustc versi lama dan pada dasarnya memaksa kami membuang semua manfaat yang diberikan oleh cerita stabilitas kami ke luar jendela, dan saya tidak melihat cara apa pun untuk memperbaikinya.

Ini juga berpotensi berarti mempertahankan binding LLVM untuk dua versi LLVM

Kami telah mempertahankan¹ dukungan untuk LLVM versi 3.7 hingga 3.9 (dan berpotensi sebagai trunk). Selama LLVM Xcode bukan versi kuno, saya pikir kami baik dalam hal itu. Jika Xcode LLVM benar-benar versi kuno/kustom/dll, maka saya tidak melihat kami dapat mendukung fitur ini sama sekali. Terutama karena kami tidak memiliki opsi untuk mengirim tambalan ke _that_ LLVM untuk menambahkan fitur yang kami butuhkan. Saya juga tidak ingin mengunci rustc untuk mendukung 3.7 selamanya jika Apple memutuskan untuk tidak memperbarui Xcode LLVM hingga 2038.

Catatan: namun, jika rustc dibangun melawan LLVM xy, itu harus ditautkan ke LLVM xy dengan tepat.

Memuat LLVM secara dinamis tentu saja bukan pilihan. LLVM API kurang stabil daripada bitcode-nya dan, jika kita membangun terhadap LLVM xy, maka memiliki LLVM xz alih-alih xy hampir pasti akan merusak rustc. Cukup tautkan ke sistem LLVM secara statis (seperti yang sudah dilakukan --llvm-root).

@nagisa C++ API tidak stabil, tetapi kami menggunakan C API dan telah banyak berhasil mendukung beberapa versi LLVM sekaligus. Saya tidak melihat perbedaan dalam hal dukungan API.

Cukup tautkan sistem LLVM (statis) untuk distribusi apel. Dalam pengalaman saya itu sudah bekerja dengan baik.

Kami hanya dapat mengirimkan LLVM Apple untuk semua platform apple, tetapi ini berarti menggabungkan LLVM kami ke Apple bahkan untuk pembuatan kode mesin desktop, dan menghalangi opsi untuk mendukung bitcode iOS pada host non-apple.

Oke… jadi, masalahnya adalah format bitcode LLVM agak stabil di antara versi LLVM. Apakah apple melakukan sesuatu yang tidak biasa untuk membuat itu tidak benar, atau apakah format bitcode yang digunakan bukan LLVM sama sekali (yaitu memiliki hal-hal khusus untuk Apple)?

Format bitcode tidak stabil antar versi.

apakah mendistribusikan perpustakaan biner asli tidak berfungsi lagi untuk iOS?

Itu bekerja hari ini. Ini bukan metode yang disukai dan tidak jelas itu akan terus didukung.

Ini juga berpotensi berarti mempertahankan binding LLVM untuk dua versi LLVM (tidak harus dua versi minor yang berdekatan juga). Saya tidak berpikir itu valid untuk hanya menggunakan versi lama dari apple-llvm.

@ricky26 Kami berhasil menjaga kompatibilitas antara beberapa versi LLVM. Selama Apple dan kita tidak menyimpang terlalu jauh, itu seharusnya bisa dilakukan, tetapi selalu ada risiko kerusakan besar sehingga kesenjangan tidak dapat dilewati, dan saya tahu akan ada perubahan API besar yang akan datang.

Selama LLVM Xcode bukan versi kuno, saya pikir kami baik dalam hal itu.

Dari halaman ini https://Gist.github.com/yamaya/2924292 :

clang-700.0.72 => LLVM 3.7.0
clang-700.1.76 => LLVM 3.7.0
clang-700.1.81 => LLVM 3.7.0
clang-703.0.29 => LLVM 3.8.0
clang-703.0.31 => LLVM 3.8.0

C++ API tidak stabil, tetapi kami menggunakan C API dan telah banyak berhasil mendukung beberapa versi LLVM sekaligus. Saya tidak melihat perbedaan dalam hal dukungan API.

Itu tidak benar. Kami memiliki (cukup besar!) sejumlah binding ke C++ API dalam bentuk rustllvm. Ada sejumlah kasus di mana kami mengkompilasi pembungkus itu tergantung pada versi LLVM yang dikompilasi. Jika versi LLVM yang digunakan dan dikompilasi tidak cocok, Anda akan mendapatkan kesalahan tautan dinamis, atau lebih buruk lagi, mengalami masalah saat runtime.

menghalangi opsi untuk mendukung bitcode iOS pada host non-apple.

Jika Apple tidak ingin mengambil bitcode yang dihasilkan oleh apa pun selain garpu LLVM mereka, maka saya tidak melihat bagaimana kami dapat melakukan apa pun di sini selain mempertahankan garpu serupa dan merekayasa balik patch internal mereka.

Format bitcode tidak stabil antar versi.

Tentu, tetapi cukup adil untuk mengasumsikan¹ bahwa bitcode antara berbagai revisi LLVM yang dikenal sebagai 3.7.0, misalnya, cukup kompatibel untuk tujuan menghasilkan bitcode untuk konsumsi oleh build lain dari LLVM dari seri 3.7.0. Ini tentu lebih baik daripada menautkan ke libLLVM secara dinamis.

Catatan: terutama mengingat bahwa bitcode dari seri 3.2 masih kompatibel dengan 3.8 LLVM, meskipun spesimennya sangat kecil.

Beberapa catatan:

  • Xcode bahkan tidak dikirimkan dengan libLLVM yang dapat ditautkan (statis atau dinamis), hanya libclang.dylib yang menautkan secara statis ke LLVM.
  • Apple mengirimkan sumber ke 'dentang' mereka (termasuk LLVM) di bawah 'Alat Pengembang' di https://opensource.apple.com , tetapi situs itu cenderung membutuhkan waktu lama untuk diperbarui.
  • Ceritanya mungkin lebih baik dengan Swift, yang memiliki garpu LLVM sendiri dengan tag rilis - tetapi mungkin tidak sesuai dengan apa yang dikirimkan dengan Xcode. (Dimungkinkan untuk menggunakan snapshot rantai alat sumber terbuka dengan Xcode, tetapi proyek yang dibuat dengan rantai alat semacam itu tidak dapat dikirimkan ke App Store.)

cc @rust-lang/compiler

Akan penasaran untuk mendengar bagaimana bahasa pemrograman lain berencana menangani ini. Secara khusus mono dan pergi.

Jawaban Unity untuk masalah ini adalah il2cpp - membangun semua rakitan IL mereka ke dalam kode C++.

Bug golang yang relevan: https://github.com/golang/go/issues/12682; saran tampaknya ada bahwa mereka dapat menggunakan LLVM go toolchain (yang tidak ditampilkan sebagai standar go toolchain).

Secara keseluruhan, cerita untuk dukungan bitcode di luar Apple buruk.

Mono yang tepat berjalan melalui apple LLVM itu akan muncul: http://tirania.org/blog/archive/2015/Sep-02.html

Satu batu sandungan adalah Anda tidak dapat membawa perakitan sebaris dalam bitcode :(

Untuk cerita mono, saya bertukar informasi singkat dengan Miguel de Icaza tentang apa yang dilakukan Mono untuk yang penasaran: https://twitter.com/mitsuhiko/status/769458873237434368

@mitsuhiko Anda _can_ memiliki perakitan sebaris dalam bitcode di iOS dan tvOS, tetapi tidak watchOS, untuk beberapa alasan.

Setiap gerakan ini? Saya sama sekali tidak merasa senang menggunakan Rust di iOS tanpa rencana untuk mendukung bitcode. Apple memiliki sejarah membuat hal-hal opsional seperti non-opsional ini cukup tiba-tiba, dan memang bitcode sudah diperlukan di watchOS dan tvOS.

Saya merasa agak seperti semua solusi yang direkomendasikan agak menjijikkan. Cara paling tidak berantakan yang dapat saya pikirkan adalah membiarkan target yang berbeda membebani perilaku codegen dan membuat jalur codegen Apple berada dalam peti dinamis. (Yang hanya akan menjadi jalur codegen biasa yang dikompilasi terhadap apple-llvm.)

Pendekatan ini (oleh @ ricky26) tampaknya paling alami bagi saya sebagai pengguna rustc.

Saya tidak percaya ada yang berubah dalam hal ini baru-baru ini untuk pengetahuan saya setidaknya. Dengan pengumuman LLVM baru ini tentang pembuatan versi, mereka menunjukkan bahwa bitcode harus (saya pikir) selalu dapat dimuat oleh versi LLVM yang akan datang. Itu mungkin berarti bahwa masalah ini "diselesaikan" pada tingkat dasar, tetapi masih memerlukan antarmuka yang lebih ergonomis untuk mengekstrak semua bitcode.

Apakah ada pembaruan tentang ini?

Komentator di HackerNews ini telah berhasil menggunakan Bitcode yang dihasilkan dari Rust di macOS dan iOS. Utas ini memiliki beberapa informasi terperinci tentang cara mengaktifkan bitcode untuk binari karat, yang terdengar seperti berita bagus!

https://news.ycombinator.com/item?id=14305084

Sebagai komentator yang dimaksud, catatan singkat:

  • Saya menggunakan -C lto --emit llvm-bc untuk membuat rustc mengeluarkan satu file .bc yang berisi peti saat ini dan semua dependensi. Ini berfungsi, tetapi pada dasarnya adalah peretasan; khususnya, itu tidak berfungsi untuk dependensi C, termasuk jemalloc (meskipun itu tidak digunakan di iOS). Akan lebih baik jika rustc mendukung pemancaran Mach-Os dengan benar dengan "bitcode tertanam"; Anda dapat melihat sumber dentang untuk melihat bagaimana hal itu dilakukan.

  • Jika Anda ingin mencobanya dan tidak keberatan dengan peretasan, sepertinya 'berfungsi', kecuali untuk masalah versi:

  • Hambatan praktis utama adalah bahwa Rust menyinkronkan dengan LLVM trunk lebih sering daripada Xcode, yang tampaknya hanya melakukannya setiap tahun. Versi LLVM yang lebih baru dapat memuat bitcode lama, tetapi tidak sebaliknya, jadi Anda harus menggunakan rustc versi lama atau membuat yang terbaru terhadap LLVM lama. (Sebenarnya, rustc 1.17 tampaknya masih berfungsi dengan Xcode 8.x, tetapi tidak setiap malam sejak pemutakhiran LLVM 4.0; itu hanya kebetulan.)

  • Idealnya Rust akan mengirimkan binari resmi yang dibuat dengan versi LLVM yang sesuai. Dalam praktiknya, tampaknya baik-baik saja menggunakan versi stok LLVM yang benar, tetapi jika Anda ingin menggunakan garpu Apple:

    • Seperti yang saya katakan di komentar sebelumnya, Xcode tidak mengirimkan binari LLVM dalam bentuk apa pun yang dapat ditautkan, bahkan secara dinamis; hanya dentang dan libclang.dylib (yang mengekspor API Dentang tetapi bukan yang LLVM).
    • Tapi, seperti yang saya juga katakan, kode sumber biasanya naik di opensource.apple.com (di bawah Alat Pengembang -> dentang; arsip mencakup semua LLVM), hanya agak tidak konsisten/setelah penundaan. Namun, terutama mengingat jaminan kompatibilitas mundur yang diperluas yang dicatat oleh @alexcrichton , mungkin bukan akhir dari dunia untuk tidak selalu up to date. Saat ini, rilis sumber terbaru adalah untuk Xcode 8.2.1, sedangkan yang terbaru adalah 8.3.2.

(Sebagai ujian, saya baru saja mencoba mengkompilasi Rust terhadap Xcode 8.2.1 Dentang. rustllvm gagal dibangun, karena sarangnya dari #if LLVM_VERSION_GE(..) conditional, yang dimaksudkan untuk memungkinkannya dikompilasi terhadap keduanya LLVM yang lebih lama dan lebih baru, menjadi bingung dengan cabang ini - yang mengklaim sebagai LLVM 3.9svn, tetapi API-bijaksana berada di antara 3,8 dan 3,9. Mungkin tidak layak diperbaiki, karena Xcode hampir jatuh tempo untuk penyegaran tahunan berikutnya.)

Apakah ada kemajuan yang dicapai dalam hal ini? Atau apakah Anda (tim inti) menganggap cobaan ini sebagai masalah dengan perbaikan permanen yang solid yang terlihat atau apakah Anda mengharapkan versi melompat ini tetap ada di masa mendatang?

Saya sedang mempertimbangkan untuk mengimplementasikan bagian dari aplikasi iOS di Rust untuk sistem tipe superior dan semantik tingkat rendah dan lebih suka tidak terjebak dengan non-bitcode atau peretasan/penundaan reguler setiap kali ada pembaruan untuk Xcode atau rustc.

@regexident

Saya pikir kami akan menerapkan versi LLVM yang dapat ditukar karena alasan lain. Jika itu diterapkan, kami seharusnya tidak memiliki masalah pengiriman trans terpisah untuk Apple, wasm, dan yang lainnya.

cc #45684

Bukankah bitcode Apple masih sangat berbahaya ala https://medium.com/@FredericJacobs/why -im-not-enabling-bitcode-f35cd8fbfcc5 Tidak mungkin memverifikasi build. Masalah untuk kriptografi. dll.

@burdges Untuk aplikasi tertentu, ini benar-benar masalah.

Tetapi untuk watchOS dan tvOS Apple memang membutuhkan Bitcode untuk pengiriman App Store. Anda tidak punya pilihan. Selain "jangan lakukan crypto atau hal-hal penting di platform itu". Kita juga harus takut Apple memberlakukan Bitcode untuk iOS di beberapa titik di masa depan. Saya lebih suka tidak memiliki produk bata pada saat itu.

Saya mencoba membangun dengan Rust 1.24.0 untuk iOS menggunakan trik -C lto --emit=llvm-bc , tetapi tautannya memberikan kesalahan berikut:

Undefined symbols for architecture x86_64:
  "_backtrace_create_state", referenced from:
      std::sys_common::gnu::libbacktrace::init_state::h686c3e443c712b0f in Logger(x86_64.o)
  "_backtrace_syminfo", referenced from:
      std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h598a932d5bb0d80b in Logger(x86_64.o)
      core::iter::iterator::Iterator::position::_$u7b$$u7b$closure$u7d$$u7d$::hbf03153d55553502 in Logger(x86_64.o)
  "_backtrace_pcinfo", referenced from:
      std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h598a932d5bb0d80b in Logger(x86_64.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Ada ide apa yang mungkin menjadi masalah?

Sunting: tampaknya saya setidaknya dapat menekan masalah itu dengan membungkus semua kode di setiap fn eksternal publik dengan AssertUnwindSafe

libbacktrace adalah pustaka C yang termasuk dalam pohon sumber Rust:

https://github.com/rust-lang/rust/tree/master/src/libbacktrace

Anda harus mengkompilasinya sebagai bitcode entah bagaimana.

Saya bingung, karena saya hanya dapat menemukan libbacktrace yang dibuat untuk laptop saya, tetapi tidak untuk OS ponsel. Bagaimana cara karat memasukkan simbol-simbol itu ke dalam stdlib? Apakah ada cara yang lebih mudah untuk melakukan ini, dengan entah bagaimana menonaktifkan fungsionalitas backtrace? Saya menghapus RUST_BACKTRACE env var tetapi itu tidak membantu. Saya telah membaca bahwa Anda dapat mengkompilasi rustc tanpa backtrace, tetapi saya mengharapkan sesuatu yang lebih mudah, misalnya dalam file cargo.toml dari proyek saya

Pada dasarnya Anda ingin membangun pohon sumber rustc sambil memerintahkannya untuk meneruskan -fembed-bitcode ke kompiler C. Idealnya Anda hanya dapat menambahkannya ke CFLAGS ; sayangnya, saya baru saja mencobanya, dan itu tidak berfungsi dengan baik karena dua masalah dengan gcc-rs (digunakan oleh sistem build rustc untuk membangun dependensi C). Namun, saya membuatnya bekerja dengan sedikit prosedur peretasan:

cd /tmp/build
cat >ccwrap.py <<END

#!/usr/bin/env python
import os, sys
os.execv('/usr/bin/xcrun', ['clang', '-fembed-bitcode'] + [arg for arg in sys.argv[1:] if arg not in {'-ffunction-sections', '-fdata-sections'}])

END

chmod 755 ccwrap.py
ln -s /usr/bin/ar ar
export CC_aarch64_apple_ios=`pwd`/ccwrap.py
/usr/src/rust/configure --target=aarch64-apple-ios
make

Ini akan memberi Anda libbacktrace.a (dalam ./build/aarch64-apple-ios/native/libbacktrace/.libs/ ) dengan bitcode yang disematkan. __LLVM,__bitcode dari apa yang dinyatakan sebagai pustaka asli, dengan cara yang sama seperti yang dilakukan dentang: maka tidak perlu mengompilasi dan menautkan file .bc secara manual.

(Sebenarnya, karena kesalahan yang Anda kutip terlihat seperti kesalahan tautan normal, saya pikir Anda dapat melewatinya hanya dengan menautkan libbacktrace.a biasa yang tidak disematkan kode bit. Tetapi yang terbaik akan menghasilkan file keluaran dengan bitcode tertanam yang rusak.)

Isu-isu tersebut di atas:

  • gcc-rs melewati -ffunction-sections dan -fdata-sections tanpa cara untuk mematikannya; dentang mengeluh tentang ini ketika digabungkan dengan -fembed-bitcode (bahkan jika -fno-function-sections dilewatkan nanti).

Saya mengajukan laporan masalah , dan sebagai solusinya, prosedur di atas menggunakan skrip pembungkus yang menghapus argumen tersebut. Tapi itu menyebabkan masalah kedua:

  • gcc-rs mencoba menemukan ar di direktori yang sama dengan CC_aarch64_apple_ios (!?); pengaturan manual AR_aarch64_apple_ios tidak berpengaruh

Saya tidak dapat mereproduksi ini dengan cc-rs (berganti nama dari gcc-rs ), jadi saya tidak mengajukan masalah. Sebagai solusinya, prosedur di atas menghubungkan ar ke dalam direktori yang sama.

Terima kasih atas sarannya! Saya sebenarnya hanya membutuhkan bitcode untuk kode saya sendiri, bukan hal-hal backtrace, jadi saya hanya menggunakan libbacktrace yang dikompilasi tanpa penyematan bitcode

Dengan peretasan yang saya coba, saya sekarang menemukan masalah lain: dsymutil segfaults ketika saya mencoba membuat dSYM untuknya. Eksekusi normal tanpa dSYM berfungsi dengan baik, tetapi pembuatan dSYM rusak karena beberapa alasan. Saya menghapus libbacktrace.a saya, menggantinya dengan fungsi placeholder kosong, dan semuanya berfungsi dengan baik, jadi sepertinya ada masalah dengan lib karat saya.

Kedengarannya seperti bug di dsymutil, yang harus dilaporkan ke hulu ke LLVM. Bisakah Anda mencoba menjalankan dsymutil di bawah LLDB dan memposting backtrace dari crash? Atau untuk mendapatkan info debug yang lebih baik, Anda dapat mencoba membangun LLVM dalam mode debug dan mereproduksinya dengan itu.

(Perhatikan bahwa biner dalam instalasi LLVM stok disebut llvm-dsymutil , tetapi hari ini dsymutil Xcode hanyalah symlink ke llvm-dsymutil . dsymutil dulu utilitas sumber tertutup yang terpisah, tetapi selama beberapa tahun versi itu telah dikirimkan sebagai dsymutil-classic dan tidak digunakan secara default.)

@comex karena penasaran, haruskah peti cc mengkompilasi semuanya dengan -fembed-bitcode ? Atau jika kita menggunakan dentang "resmi" bolehkah menghindari penyematan bitcode?

(maaf saya tidak terlalu paham dengan praktik terbaik ios!)

Untuk kode Rust itu sendiri, apakah lebih baik jika kita hanya memancarkan bytecode daripada file objek? Apakah itu sesuatu yang dapat dipahami oleh Dentang/penghubung?

@alexcrichton

haruskah peti cc mengkompilasi semuanya dengan -fembed-bitcode ? Atau jika kita menggunakan dentang "resmi" bolehkah menghindari penyematan bitcode?

Menggunakan dentang resmi tidak meniadakan kebutuhan akan bitcode yang disematkan. Sebaliknya, bitcode disertakan - selain kode asli - dalam arsip aplikasi yang diunggah ke Apple, dan kemudian Apple dapat mengkompilasi ulangnya di sisi server, misalnya untuk mengoptimalkan mikroarsitektur yang berbeda.

Mungkin masuk akal untuk meneruskan -fembed-bitcode secara default di iOS/watchOS/tvOS. Jika demikian, saat membangun dalam mode debug, -fembed-bitcode-marker harus diteruskan (sebagai gantinya atau sebagai tambahan, tidak masalah); ini memberitahu dentang untuk hanya menyertakan bagian bitcode dummy daripada bitcode yang sebenarnya, karena bitcode yang disematkan hanya diperlukan untuk arsip aplikasi akhir dan sedikit mempercepat kompilasi untuk menghilangkannya. Sebenarnya, Xcode meneruskan -fembed-bitcode-marker untuk semua hal selain membangun arsip aplikasi final, bahkan build pengembangan yang kebetulan memiliki pengoptimalan - tetapi karena cc tidak memiliki konsep terpisah "rilis yang benar-benar final mode", itu mungkin harus meneruskannya dalam mode debug. Perhatikan bahwa aman untuk menyematkan bitcode meskipun versi final tidak memerlukannya.

Untuk kode Rust itu sendiri, apakah lebih baik jika kita hanya memancarkan bytecode daripada file objek? Apakah itu sesuatu yang dapat dipahami oleh Dentang/penghubung?

Baik dentang dan ld mendukung file bitcode mentah yang diteruskan sebagai input; ini biasanya digunakan ketika LTO diaktifkan ( -flto ), dalam hal ini file .o yang dihasilkan dentang sebenarnya adalah bitcode mentah, bukan Mach-O. (Ini masih dapat dibentuk menjadi pustaka statis menggunakan perintah lipo normal.) Namun, ini terpisah dari format "bitcode tertanam", yang terdiri dari Mach-O dengan bitcode yang dimasukkan ke bagian __LLVM,__bitcode , di Selain kode asli di bagian biasa. Format ini digunakan dalam file objek saat LTO dimatikan, serta dalam file executable terakhir yang dapat dieksekusi atau pustaka dinamis terlepas dari pengaturan LTO. (Jika LTO aktif, penaut bertanggung jawab untuk membuat bagian ini; jika LTO mati, penaut hanya menggabungkan bagian __LLVM,__bitcode dari setiap file objek seperti yang akan dilakukan untuk bagian lain, daripada menghasilkan satu gabungan modul bitcode. ) EDIT: sebenarnya, ia melakukan sesuatu yang sedikit lebih rumit , menghasilkan arsip xar dari bagian bitcode dan menempatkannya di bagian bernama __LLVM,__bundle ; lagi pula, bukan sesuatu yang harus kita pedulikan.

Saya pikir idealnya rustc harus menghasilkan "bitcode tertanam" secara default di iOS, bukan bitcode mentah. Ini tidak terlalu sulit untuk dilakukan, dan menghindari pemecahan kompilasi tambahan - terutama dalam mode debug di mana Anda hanya dapat menghasilkan bagian bitcode dummy, ala -fembed-bitcode-marker , tetapi berpotensi dalam mode rilis juga, karena tautan hanya memasukkan objek ' bagian bitcode bersama-sama daripada melakukan sesuatu yang mahal pada waktu tautan.

Inilah cara dentang menghasilkan bitcode yang disematkan:

https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/BackendUtil.cpp#L1242

Relatif sederhana - sebelum menjalankan backend, ia membuang modul LLVM saat ini sebagai bitcode, lalu
memasukkan itu sebagai data biner ke dalam variabel global baru (dalam modul yang sama!), ditempatkan di bagian __LLVM,__bitcode . Sepertinya semacam desain peretasan (mengapa frontend harus melakukan ini secara manual?), Tetapi seharusnya tidak terlalu sulit untuk direproduksi di rustc.

@comex pendekatan itu masuk akal, meskipun saya pikir ada alasan (lihat #48833 yang baru saja saya buat) untuk menggunakan dentang Apple sebagai backend, sementara kami memikirkan perubahan seperti ini. Juga, seberapa mudah untuk mengkompilasi diri kita sendiri dari bitcode yang disematkan?

@michaeleiselsc Maaf, saya tidak mengerti apa yang Anda maksud dengan "kompilasi diri kita sendiri dari bitcode yang disematkan".

Seperti, alih-alih hanya memberikan biner ke App Store dengan bitcode yang disematkan, ada juga manfaat untuk mengambil bitcode dan membangunnya sendiri menggunakan dentang Apple. Dua manfaat yang saya minati adalah perbaikan hilir yang dimiliki Apple clang dan kemampuan untuk menggunakan pembersih dentang, misalnya pembersih cakupan.

@comex ok jadi gali sedikit, sepertinya implementasi di rustc cukup mudah (relatif), tapi saya punya beberapa pertanyaan:

  • Mengapa -fembed-bitcode-marker sesuatu? Menggunakan dentang secara lokal itu hanya memancarkan statis kosong ke dalam suatu bagian. Apakah itu berarti kehadiran bagian itu berarti sesuatu? Apakah beberapa alat di sepanjang jalan di iOS rusak jika bagiannya tidak ada? (tetapi sebenarnya tidak terlihat di dalam bagian karena kosong?
  • Tahukah Anda jika bagian __cmdline diperlukan? Sepertinya -fembed-bitcode juga menyematkan beberapa bentuk baris perintah ke dalam biner. Saya tidak begitu yakin apa yang akan kita taruh di sini karena itu mungkin bukan baris perintah rustc, tetapi apakah ada alat yang melihat ini? Apakah kompilasi rusak jika -fembed-bitcode=bitcode digunakan dengan iOS?
  • Dan akhirnya, apakah ada alasan untuk ingin menonaktifkan ini? Atau haruskah kita mengaktifkan ini tanpa syarat untuk target iOS dan melanjutkan?

Mengapa -fembed-bitcode-marker menjadi sesuatu?

Saya pikir ini digunakan oleh xcode untuk menunjukkan bahwa sesuatu seharusnya menggunakan bitcode tetapi bitcode sebenarnya tidak dikompilasi. Jika Anda mencoba mengarsipkan proyek seperti itu nanti, ld akan gagal dengan kesalahan.

Untuk pertanyaan apakah kami ingin selalu mengaktifkan ini, pasti ada beberapa kasus yang kami ingin berhati-hati. Misalnya, jika seseorang mengirimkannya ke platform distribusi aplikasi beta seperti HockeyApp, apakah HockeyApp akan menghapus bagian bitcode itu, atau akankah penguji beta harus mengunduh biner yang jauh lebih besar dari yang seharusnya?

@mitsuhiko Ya, idenya adalah bahwa linker dapat memverifikasi bahwa build telah diatur dengan benar untuk bitcode, bahkan jika Anda sedang melakukan pengujian build yang sebenarnya tidak memerlukan bitcode.

Misalnya, jika Anda mengkompilasi file C tanpa menyebutkan bitcode, lalu coba menautkannya dengan -fembed-bitcode-marker , Anda mendapatkan:

$ clang -c -o test.o test.c
$ clang -dynamiclib -o test.dylib test.o -fembed-bitcode-marker
ld: warning: all bitcode will be dropped because 'test.o' was built
without bitcode. You must rebuild it with bitcode enabled (Xcode
setting ENABLE_BITCODE), obtain an updated library from the vendor,
or disable bitcode for this target.

Peringatan akan hilang jika Anda memasukkan -fembed-bitcode-marker pada baris pertama juga.

@alexcrichton Adapun __cmdline … hmm… sepertinya linker membutuhkannya untuk hadir (cari "Buat bitcode"):

https://opensource.apple.com/source/ld64/ld64-274.2/src/ld/parsers/macho_relocatable_file.cpp.auto.html

Tapi saya tidak melihat apa pun yang peduli dengan nilai sebenarnya. Mungkin yang terbaik untuk menempatkan nilai dummy di sana.

Apakah masalah ini diselesaikan dengan menggabungkan #48896?

Saya telah bermain-main dengan ini di build malam, dan ini berfungsi dengan baik sampai Anda mencoba Mengarsipkan dengan Xcode. Sepertinya menambahkan fembed-bitcode-marker tetapi tidak fembed-bitcode ke output perpustakaan statis Rust. Itu dikompilasi dengan cargo lipo --release dengan:

$ cargo --version
cargo 1.27.0-nightly (af3f1cd29 2018-05-03)
$ cargo lipo --version
cargo-lipo 2.0.0-beta-2
$ rustc --version
rustc 1.27.0-nightly (565235ee7 2018-05-07)
ld: '/Users/chrisbal/Documents/Beach/rust-universal-template/target/universal/release/libexample.a(example_generic-be72fb1769c1779b.example_generic6-152d14edfb6970f54250733c74e59b7.rs.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Ketika saya menjalankan otool -arch arm64 -l /Users/chrisbal/Documents/Beach/rust-universal-template/target/universal/release/libexample.a | grep bitcode saya mendapatkan banyak sectname __bitcode , tetapi saya tidak tahu cara memeriksa apakah ini bitcode aktual dan bukan hanya penanda.

Saya menggunakan peti bersarang jadi mungkin peti "generik" bagian dalam tidak mendapatkan tanda bitcode?

edit: ini repo kami yang menunjukkan masalahnya https://github.com/Raizlabs/rust-universal-template/tree/879e7412d729e8963586c5b083d51b09733aec32

@chrisballinger , ini berfungsi dengan flag tambahan, lihat
RUSTFLAGS="-Z embed-bitcode" cargo lipo --release

$ cargo --version
cargo 1.28.0-nightly (f352115d5 2018-05-15)
$ cargo lipo --version
cargo-lipo 2.0.0-beta-2
$ rustc --version
rustc 1.28.0-nightly (952f344cd 2018-05-18)

Tetapi saya memiliki kesalahan kompilasi lain hanya untuk arm7 arch:

.rs.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7

Adakah yang tahu cara memperbaiki arm7 arch ?

Sayangnya tidak bisa berfungsi dengan baik, mendapatkan kesalahan yang sama dengan @chrisballinger :

ld: '/sandbox/target/universal/release/librgame.a(std-da6dba40351cda22.std3-d36cd881bae00a8b5fc36289b5737f78.rs.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Saya sudah mencoba mengkompilasinya dengan RUSTFLAGS="-Z embed-bitcode" cargo lipo --release dan mengaturnya di .cargo/config . Itu menambahkan bendera meskipun:

` Executing: "cargo" "build" "--target" "x86_64-apple-ios" "--lib" "--features" "" "--color" "auto" "--release" "--verbose" Compiling libc v0.2.42 Compiling rand_core v0.2.1 Running `rustc --crate-name libc /Users/aleksandrivanov/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.42/src/lib.rs --crate-type lib --emit=dep-info,link -C opt-level=3 --cfg 'feature="default"' --cfg 'feature="use_std"' -C metadata=dce309634355ac97 -C extra-filename=-dce309634355ac97 --out-dir /Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/x86_64-apple-ios/release/deps --target x86_64-apple-ios -L dependency=/Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/x86_64-apple-ios/release/deps -L dependency=/Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/release/deps --cap-lints allow -Zembed-bitcode` ...

Ada pembaruan di sini? Sangat mempertimbangkan perpustakaan inti bersama untuk aplikasi kami dan tanpa c++ tetap ini adalah opsi yang mungkin.

@chrisballinger , Bisakah itu terkait dengan https://github.com/rust-lang/rust/issues/52686?

@volodg Tidak, masalah ini sudah lama.

Dengan penggabungan #48896, apakah seharusnya berhasil?

Saya menggunakan 1.29.1 dan objek masih belum memiliki bitcode yang disematkan secara default. Seperti yang disebutkan sebelumnya oleh @volodg , Anda bisa mendapatkan karat untuk menyematkannya menggunakan RUSTFLAGS="-Z embed-bitcode" . Tapi, dari apa yang saya alami, Anda kemudian mendapat masalah di mana lib Rust sendiri (compiler_builtins, std) tidak dikompilasi dengan embed-bitcode. Mungkin membangun kembali target iOS menggunakan xargo dengan embed-bitcode akan berhasil, tetapi saya tidak mencobanya.

Saya mencoba menggunakan xargo seperti yang Anda usulkan tetapi masalahnya tampaknya masih ada di sini :(

Menggunakan Xargo.toml

[dependencies]
std = {}
[target]
features = ["jemalloc"]

Juga menambahkan ini ke Cargo.toml :

[profile.release]
panic = "abort"

Saya mengkompilasi menggunakan xargo build --release --target $TARGET untuk semua target tersebut:

  • aarch64-apple-darwin
  • armv7-apple-darwin
  • armv7s-apple-darwin
  • i386-apple-darwin
  • x86_84-apple-darwin

Kemudian saya menggunakan lipo untuk membuat satu perpustakaan statis.

Saya masih memiliki kesalahan tautan:

ld: '../../cargo/target/universal/libgreetings.a(greetings-ceeec73d35f7dbe0.greetings.9kcaav8v-cgu.2.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Mendapat sedikit lebih jauh dengan jalur xargo.

Xargo.toml

[dependencies]
std = {}

Cargo.toml

[profile.release]
panic = "abort"

Saya tidak tahu apakah itu diperlukan, tetapi dari xargo doc, Anda perlu menggunakan extern crate compiler_builtins secara eksplisit, yang saya tambahkan ke lib.rs saya.

Saya kemudian mengkompilasi dengan: RUSTFLAGS="-Z embed-bitcode" xargo build --target $TARGET --release untuk dikompilasi. Pastikan itu membangun core/std/compiler_bultins. xargo clean tidak membersihkan build sebelumnya dengan benar dari apa yang saya alami, jadi rm -rf ~/.xargo diperlukan untuk mengkompilasi ulang std ketika saya mencoba tweak Xargo.toml .

Tapi kemudian, pengarsipan di Xcode 10, saya mendapatkan (di armv7 menghubungkan):

Intrinsic has incorrect argument type!
void (i8*, i8, i32, i1)* @llvm.memset.p0i8.i32
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* @llvm.memcpy.p0i8.p0i8.i32
Intrinsic has incorrect argument type!
...
(lots of it)
...
LLVM ERROR: Broken module found, compilation aborted!
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Apakah itu berarti bug bergantung pada sisi LLVM?

EDIT : Bagaimana kami dapat membantu untuk memajukan masalah ini?

Apakah ada yang mencoba ini baru-baru ini? Sepertinya armv7 adalah masalah terbesar?

Halo semuanya. Saya telah mengikuti utas ini untuk sementara waktu sekarang dan saya sangat senang melihat bitcode Apple didukung dengan Rust. Adakah yang bisa sejauh ini membuat ini berhasil? Apa yang saat ini hilang dan bagaimana kami dapat membantu?
Terima kasih!

Setelah beberapa jam mencari masalah ini, saya menemukan alasan penyematan bitcode Rust tidak berfungsi di Xcode. Jawaban singkatnya adalah bahwa versi LLVM Xcode mengharapkan LLVM 6.0 bitcode , sementara Rust telah menabrak LLVM 7.0 pada Juli 2018 .

Sekarang, jawaban panjangnya ...

Seperti yang dapat kita lihat di changelog LLVM 7.0 , mereka mengubah tanda tangan untuk @llvm.memcpy , @llvm.memmove , dan @llvm.memset , dan kesalahan pembuatan Xcode jelas tentang jenis argumen yang salah seperti yang terlihat di komentar saya

Omong-omong, Kotlin Native menambahkan dukungan untuk embed-bitcode pada Oktober 2018 dan tampaknya berfungsi dengan baik di Xcode . Pasalnya, Kotlin masih menggunakan LLVM 6.0 .

Melihat itu, saya mencoba mengkompilasi menggunakan Rust versi lama sebelum mencapai 7.0. Saya mencoba dengan nightly-2018-06-01-x86_64-apple-darwin , dan berhasil, ini dikompilasi!

Saya juga mencoba mengkompilasi tanpa menggunakan Xargo tanpa hasil. Semua dependensi perlu dikompilasi dengan penyematan bitcode.

Jadi intinya, kecuali Apple menabrak versi LLVM mereka, saya tidak berpikir kita akan melihat dukungan untuk bitcode tertanam dalam waktu dekat ... Kecuali seseorang menemukan cara cerdas untuk mengubah bitcode tertanam ke bitcode 6.0 ...

@appaquet Terima kasih telah memahaminya! Itu cukup misteri bagi saya dan saya tidak berpikir saya akan menyelam sedalam yang Anda lakukan. Senang mengetahui bahwa itu kemungkinan akan mulai berfungsi setelah Apple menabrak versi LLVM.

Terima kasih @appaquet atas jawaban Anda yang jelas. Sekarang saya kira kita hanya perlu mengandalkan Apple untuk melakukan hal yang benar

Tampilan samping dari seseorang yang tertarik pada multiplatform untuk seluler dan membandingkan sebagian besar solusi yang menjanjikan (React Native, Flutter, Kotlin/Native, Rust)

Bereaksi Asli. Mendukung bitcode sejak awal, karena pada dasarnya bridge ditulis dalam C++ dan hanya menafsirkan kode JS saat runtime.

Berdebar. Belum mendukung bitcode - https://github.com/flutter/flutter/issues/15288

Kotlin/Asli. JetBrains sedang mempertimbangkan platform seluler sebagai prioritas dan meskipun butuh beberapa saat dan itu hanya penanda bitcode (belum bitcode penuh), itu cukup baik untuk mulai bekerja dengan - lihat https://github.com/JetBrains/kotlin-native/ tarik/1564 dan https://github.com/JetBrains/kotlin-native/issues/1202#issuecomment -444022513

Karat. Mendukung bitcode untuk LLVM 7, sedangkan Apple menggunakan versi 6.

Jika saya ingin memiliki logika bisnis dan lintas platform UI, maka saya akan menggunakan React Native atau Flutter. Tetapi bagi banyak aplikasi serius, jalur ini terlalu berisiko. React Native tidak cukup berkinerja dan stabilitas API dan ketergantungan adalah masalah (apakah v1.0 akan datang?). Flutter agak tidak dewasa tetapi tampaknya semakin menarik.

Sekarang jika saya hanya ingin berbagi logika bisnis dalam beberapa jenis modul (seperti yang dilakukan aplikasi besar sebelumnya dengan C++ dan JNI/Obj-C++) dan kemudian membangun UI yang benar-benar asli di atas, pada awalnya saya punya pilihan di antara keempatnya. Kemudian saya mencoret React Native, karena mengambil JavaScriptCore dan bridge untuk menjalankan logika bisnis antara JS<->Native tampaknya sedikit berlebihan (menginisialisasi bridge ini juga cukup mahal). Flutter berpotensi dapat digunakan tetapi tidak dimaksudkan seperti itu , jadi sekali lagi saya akhirnya menggunakan kerangka kerja UI untuk menjalankan logika bisnis. Plus itu tidak mendukung bitcode.
Rust dan Kotlin/Native sama-sama membidik ceruk ini, memiliki alat yang layak, menghasilkan biner asli (kinerja dan jejak!). Bitcode adalah masalah besar bagi mereka yang ingin mengadopsi Rust sebagai bahasa untuk membangun modul multiplatform pada platform seluler. Dan sekarang Kotlin/Native memiliki keunggulan.

Singkatnya mengapa bitcode sangat penting untuk pengembang iOS. Tidak dapat menulis apa pun di tvOS atau watchOS. Banyak kerangka kerja pihak ke-3 yang didistribusikan sebagai binari memiliki bitcode yang diaktifkan (puluhan contoh, dari atas kepala saya Google IMA - iklan video paling populer). Beberapa audit keamanan memerlukannya. Dan akhirnya, setiap kali Apple mengatakan "mulai tahun depan kami tidak menerima aplikasi tanpa bitcode yang sepenuhnya disematkan", semua orang mendapat penghitung waktu.

Sekarang saya kira kita hanya perlu mengandalkan Apple untuk melakukan hal yang benar

Ya, benar, inilah Apple yang terkenal ;)
Saya tidak tahu apa solusi terbaik (menurunkan sementara ke LLVM 6 bukanlah pilihan, kan?), Tetapi Rust kehilangan pengembang lintas platform iOS dan seluler sepenuhnya.

Terima kasih banyak atas penjelasan detailnya @oleksandr-yefremov. Saya telah membaca sedikit tentang masalah ini dan saya menemukan komentar yang menarik ini: https://Gist.github.com/yamaya/2924292#gistcomment -2738480

Versi LLVM terkait dengan versi Swift yang digunakan di XCode. Sejauh ini dukungan berikut telah diterapkan:

Xcode 8.3  --> swift 3.1 --> llvm 4.0.0
Xcode 9.0  --> swift 4.0 --> llvm 4.0.0
Xcode 9.3  --> swift 4.1 --> llvm 5.0.2
Xcode 10.0 --> swift 4.2 --> llvm 6.0.1

Saat melihat swift-5.0-branch , saya perhatikan versi LLVM yang dideklarasikan di dalamnya adalah 7.0.0 : https://github.com/apple/swift-llvm/blob/swift-5.0-branch/ CMakeLists.txt#L25 -L33

Saya tidak tahu apakah ada pemblokir lebih lanjut di sini, tetapi menurut saya kami mungkin dapat menggunakan Rust untuk menampilkan binari Bitcode

Tampaknya Xcode 10.2 akan menyertakan Swift 5.0 dan memang harus segera dirilis. Namun di sisi lain LLVM 8.0 rencananya akan dirilis minggu depan. Rust kemungkinan besar akan ditingkatkan sebelum Apple mulai menggunakannya.

Agar Rust mendukung bitcode dengan benar, kita memerlukan arsitektur ARM Apple yang dibangun dari Rust untuk menggunakan versi LLVM yang disematkan (mungkin dari https://github.com/apple/swift-llvm repo - Apple tampaknya tidak menggunakan merilis paket LLVM tetapi cabangnya sendiri). Versi LLVM itu hanya akan diperbarui ketika Apple merilis versi final Xcode baru dengan versi LLVM yang berbeda.

Btw, tampaknya Rust terbaru dapat dibangun dengan LLVM 6 sehingga sepertinya bisa dilakukan: https://github.com/rust-lang/rust/blob/master/src/bootstrap/native.rs#L282
Anda pasti akan membutuhkan orang untuk turun tangan ketika masalah dibuat untuk memperbarui versi LLVM yang diperlukan (yang untuk LLVM 6: https://github.com/rust-lang/rust/issues/55842).

@vincentisambart Rust telah menggunakan LLVM 8 untuk build malam selama 5 bulan IIRC.
LLVM 6 adalah versi minimal yang didukung jika Anda ingin membuatnya sendiri dan diuji pada CI: https://github.com/rust-lang/rust/blob/706e67b0a0143d651eb03f2fa2c30645899e81ff/src/ci/docker/x86_64-gnu-llvm-6.0 /Dockerfile

Sekarang saya kira kita hanya perlu mengandalkan Apple untuk melakukan hal yang benar

Saya telah mengejar sesuatu di sepanjang garis ini untuk sementara waktu (dan sekarang telah keluar) dan saya kira dari segi platform tidak masuk akal bagi Apple untuk melakukan ini, karena:

  • Swift ingin menjadi Rust dalam banyak hal (lihat manifesto kepemilikan untuk satu hal) tetapi sangat tertinggal
  • Apple membutuhkan Swift untuk menjadi dan tetap menjadi bahasa platform utama mereka sehingga tidak masuk akal bagi mereka untuk memfasilitasi bahasa besar lainnya di platform mereka atau bagi mereka untuk mendorong Swift ke lingkungan lain

Rust telah menggunakan LLVM 8 untuk build malam selama 5 bulan IIRC.

Kemudian bahkan jika Apple mulai mendukung bitcode LLVM 7, bitcode yang dihasilkan oleh build resmi Rust baru-baru ini mungkin tidak berfungsi. Bahkan jika ya, mungkin rusak saat berikutnya Rust pindah ke versi LLVM dengan perubahan yang tidak kompatibel pada bitcode yang dihasilkan.

LLVM 6 adalah versi minimal yang didukung jika Anda ingin membuatnya sendiri dan diuji di CI

Kemudian membuat *-apple-ios resmi Rust dibangun dengan LLVM 6 (atau lebih baik sesuatu seperti https://github.com/Apple/swift-llvm/releases/tag/swift-4.2.2-RELEASE - jika yang berfungsi) mungkin memperbaiki masalah bitcode.

Saya pikir Rust saat ini dikirimkan dengan dua backend LLVM (Emscripten dan standar) setelah penggabungan https://github.com/rust-lang/rust/issues/46819 .
Meskipun #46819 menyebutkan ios LLVM backend untuk bitcode, itu tidak diimplementasikan.

Tidak untuk menggagalkan ini sepenuhnya tetapi bukankah secara keseluruhan lebih masuk akal untuk mencoba mengaktifkan transpiling ke C untuk kasus seperti itu? Kecil kemungkinan Rust dapat mengikuti perkembangan persyaratan bitcode dari pihak Apple.

Bahkan jika memang ada potensi sumber ketidaksesuaian, ini membuka pintu untuk pengujian di mana kami dapat mencoba mengkompilasi dengan versi lama Rust yang kompatibel, yang menyematkan versi LLVM yang tepat untuk Apple.

Dalam pendekatan lintas platform yang lengkap, ini jelas masih cukup menghalangi karena kita harus dapat mengkompilasi kode sumber yang sama baik dari versi terbaru Rust untuk mendapatkan manfaat dari peningkatan terbaru dan juga untuk dapat mengkompilasi dari yang lebih lama. versi Rust, khusus untuk menghasilkan binari yang kompatibel dengan bitcode untuk ekosistem Apple. Itu bisa dilakukan, tapi tidak cocok.

Saya masih cukup bersemangat untuk melihat ini terjadi karena setidaknya akan membuka pintu bagi lebih banyak orang untuk menguji ini dan mendorong kita semua maju ke arah yang benar.

Berbicara sebagai seseorang yang saat ini mencoba memutuskan pendekatan untuk menulis kode seluler lintas platform untuk tim yang cukup besar, kami benar-benar tidak dapat menggunakan Rust jika kami tidak dapat menghasilkan bitcode. Salah satu aplikasi kami bergantung pada bitcode untuk dapat menghasilkan biner yang cukup kecil untuk diunduh melalui jaringan seluler, dan kami memiliki beberapa pelanggan besar yang bersikeras akan hal itu.

Berdasarkan semua yang saya lihat tentang Rust, saya pikir ini memiliki keuntungan jangka panjang dari semua kemungkinan yang saya lihat di luar sana (Kotlin Multiplatform, kompilasi silang Swift, Mono, Dart, C++, React Native), tetapi pasti membutuhkan bitcode untuk didukung sepenuhnya, bahkan jika itu berarti tidak dapat mengikuti rilis Rust terbaru.

Bahkan jika bitcode berfungsi, Rust masih tidak dapat menargetkan watchOS atau tvOS, kan?

Kecil kemungkinan Rust dapat mengikuti perkembangan persyaratan bitcode dari pihak Apple.

Masalahnya di sini adalah bahwa LLVM Rust terlalu baru , bukan karena terlalu lama . Saya setuju bahwa kita harus memiliki cerita kompatibilitas yang lebih baik di sini.

Seberapa layak bagi rustc untuk mendukung banyak LLVM?

Terkait: Mendukung target tvOS dan watchOS (dan simulator)

Itu sudah menggunakan beberapa LLVM. Untuk target emscripten, ia menggunakan garpu LLVM emscripten yang ada di LLVM 6 atm.

Masalahnya di sini adalah LLVM Rust _terlalu baru_, bukan _terlalu tua_. Saya setuju bahwa kita harus memiliki cerita kompatibilitas yang lebih baik di sini.

Masalahnya bukan karena terlalu lama atau terlalu baru tetapi bahkan jika karat cocok dengan versi LLVM, pada rilis iOS apa pun ini dapat rusak lagi. Apple (sejauh yang saya tahu) sama sekali tidak menjamin stabilitas apa pun terkait dengan bitcode.

Masalahnya bukan karena terlalu lama atau terlalu baru tetapi bahkan jika karat cocok dengan versi LLVM, pada rilis iOS apa pun ini dapat rusak lagi. Apple (sejauh yang saya tahu) sama sekali tidak menjamin stabilitas apa pun terkait dengan bitcode.

Dalam praktiknya, kami melihat pembaruan Xcode utama setahun sekali ketika versi iOS baru keluar. Ketika hal ini terjadi, pengembang mendapatkan informasi yang cukup jelas bahwa mereka harus mulai mengirimkan aplikasi dengan versi Xcode yang lebih baru, jadi ini jarang mengejutkan. Saya tidak akan mengatakan ini sangat sulit untuk direncanakan.

Saya tidak akan mengatakan ini sangat sulit untuk direncanakan.

Karena sama sekali tidak ada jaminan tentang bitcode sama sekali yang bisa berubah menjadi sesuatu yang sangat sulit untuk direncanakan. Bayangkan mereka akan memutuskan dari satu rilis ke rilis lainnya untuk menggunakan format bitcode mereka sendiri yang tidak berakhir dalam rilis open source LLVM.

Karena sama sekali tidak ada jaminan tentang bitcode sama sekali yang bisa berubah menjadi sesuatu yang sangat sulit untuk direncanakan. Bayangkan mereka akan memutuskan dari satu rilis ke rilis lainnya untuk menggunakan format bitcode mereka sendiri yang tidak berakhir dalam rilis open source LLVM.

Jika kita hanya akan berasumsi Apple akan membuat perubahan besar tanpa memperhatikan orang lain, tentu saja. Memiliki beberapa dokumentasi yang lebih jelas seputar rencana mereka untuk Bitcode tidak banyak meningkatkan jika kita berasumsi bahwa mereka jahat atau tidak peduli.

Tetapi mereka jelas telah menjadikan Swift sebagai bagian penting dari platform mereka dan ribuan pengembang bergantung padanya, termasuk tim mereka sendiri dan beberapa mitra terpenting mereka. Swift didasarkan pada LLVM open source sepenuhnya dan itu sendiri sedang dikembangkan sepenuhnya di tempat terbuka, termasuk toolchain yang digunakan Xcode untuk menghasilkan bitcode yang diterima apel.

Jadi, bagi mereka untuk tiba-tiba mengubah format itu tanpa ada yang memperhatikan atau peduli akan mengharuskan mereka untuk mengambil repositori Swift dan LLVM mereka secara pribadi, bukan? Itu pasti mungkin, tetapi sepertinya tidak terlalu mungkin bagi saya.

Jika tim Rust memutuskan bahwa risiko itu adalah alasan bagus untuk tidak mendukung bitcode, itu tentu hak prerogatif mereka. Saya akan sedikit sedih tentang itu, tetapi itu bukan tempat saya untuk memberi tahu orang lain di mana harus menghabiskan waktu mereka.

Karena sama sekali tidak ada jaminan tentang bitcode sama sekali yang bisa berubah menjadi sesuatu yang sangat sulit untuk direncanakan. Bayangkan mereka akan memutuskan dari satu rilis ke rilis lainnya untuk menggunakan format bitcode mereka sendiri yang tidak berakhir dalam rilis open source LLVM.

Apple merilis Xcode Beta sekitar awal Juni dan versi final pada September. Setelah 6-9 bulan kemudian berhenti menerima aplikasi yang dibuat dengan versi Xcode yang lebih lama ke Appstore.

Saya pikir ada cukup waktu untuk menyiapkan perubahan bitcode selama timeline itu.

Baru saja diuji dengan Xcode 10.2 beta 3 (yang mencakup Swift 5 w/ LLVM 7) dan saya dapat menautkan dengan Rust baru-baru ini dengan bitcode yang disematkan. Jelas, ini hanya berfungsi dengan target iOS, karena Rust tidak memiliki target watchOS/tvOS .

Saya juga setuju bahwa Rust harus dapat menggunakan garpu Apple LLVM untuk semua target terkait Apple untuk menjaga kompatibilitas bitcode.

Ya, jendela rilis beta terdengar masuk akal. Saya pikir gagasan bahwa Apple akan menutup sumber LLVM atau format bitcode mereka sangat tidak mungkin, tetapi Apple membutuhkan bitcode di rilis iOS mendatang pasti terdengar seperti itu akan terjadi. Dan siapa tahu, mungkin mereka bahkan akan mulai membutuhkan bitcode untuk pengiriman Mac App Store dengan proyek Marzipan.

Jenis cara yang tidak dijamin untuk menangani kompatibilitas yang diusulkan memang menjijikkan, tetapi saya pikir platform seluler pada akhirnya harus menjadi platform Tingkat 1 , terutama untuk kasus di mana Anda akan menggunakan C++ jika tidak, seperti untuk pengembangan video game. Plus, Anda juga dapat mengembangkan game dengan Rust untuk Apple TV.

Saya berharap pendekatan yang disetujui secara resmi oleh tim Kompilator akan mendorong seseorang untuk mengerjakan ini, tetapi saya pikir komentar sebelumnya oleh @brson meringkas keraguan:

Kami berhasil mempertahankan kompatibilitas antara beberapa versi LLVM. Selama Apple dan kita tidak hanyut terlalu jauh, itu seharusnya bisa dilakukan, tetapi selalu ada risiko kerusakan besar sehingga kesenjangan tidak dapat dilewati.

Atau mungkin bitcode akan stabil di masa depan dan kita semua akan melupakan perdebatan ini yang pernah terjadi 🙏

Saya akan makan topi saya sekarang

Di mana saya berkata:

gagasan bahwa Apple akan menutup LLVM sumber atau format bitcode mereka sangat tidak mungkin

Yang sebagian besar sebagai tanggapan atas ketidakpercayaan yang diungkapkan oleh @mitsuhiko :

Bayangkan mereka akan memutuskan dari satu rilis ke rilis lainnya untuk menggunakan format bitcode mereka sendiri yang tidak berakhir dalam rilis open source LLVM.

Tetapi jika Anda melihat masalah #48833 , pasti ada presedennya. Seperti yang @comex tulis sebelumnya:

ada kasus di mana fitur muncul di LLVM Xcode sebelum LLVM trunk - seperti seluruh port arm64, ketika awalnya dikembangkan, karena Apple ingin merahasiakannya bahwa mereka berencana untuk mengirimkan perangkat arm64

Dan kisah @michaeleiselsc dari masalah yang sama:

sebuah aplikasi yang sedang saya kerjakan mendapat pukulan keras oleh restart acak pada bulan Desember 2016, dan itu disebabkan oleh masalah khusus yang LLVM open-source hanya diperbaiki Desember 2017. Ketika kami pindah dari LLVM open-source ke LLVM Apple pada Desember 2016, masalahnya telah diperbaiki

Mengingat bahwa idenya menggunakan LLVM Apple dengan Rust, kedengarannya tidak terlalu buruk, tetapi pasti ada risiko memiliki bug jahat sesekali karena implementasi yang berbeda . Ini bukan risiko yang dapat ditanggung semua proyek. Transpiling memang terdengar seperti opsi yang lebih baik pada saat ini, tetapi sejauh ini, sepertinya tidak mungkin .

Saya masih berpikir menggunakan LLVM Apple harus didukung, tetapi harus ada peringatan yang jelas dalam dokumentasi yang menjelaskan tidak ada jaminan bahwa semuanya akan tetap berfungsi (A Tier 1.5 atau sesuatu).

Kotlin/Asli. JetBrains sedang mempertimbangkan platform seluler sebagai prioritas dan meskipun butuh beberapa saat dan itu hanya penanda bitcode (belum bitcode penuh), itu cukup baik untuk mulai bekerja dengan - lihat JetBrains/kotlin-native#1564 dan JetBrains/kotlin-native# 1202 (komentar)

Terima kasih telah menunjukkan ini @oleksandr-yefremov! Saya menggali sedikit lebih jauh dan dapat mereplikasi pendekatan kotlin/asli di golang . Saya yakin kalian harus dapat melakukan hal yang sama, yang memungkinkan untuk menggunakan rust di aplikasi iOS/tvOS/watchOS yang mendukung bitcode tanpa harus memancarkan bitcode.

Apakah bitcode berfungsi sekarang? Apakah ada yang mencoba?

@volodg Saya seorang pemula karat. Namun, saya menjalankan tutorial ini dengan rust nightly terbaru (pada saat penulisan rustc 1.37.0-nightly (088b98730 2019-07-03) ) dan itu TIDAK berhasil.

Sepertinya ada penandanya..

$ otool -arch arm64 -l librust.a  | grep bitcode
  sectname __bitcode
...

Tapi saya mendapatkan kesalahan berikut saat membangun untuk perangkat iOS (simulator berfungsi):

ld: '/Users/amrox/Documents/Projects/rust-ios-example/hello-rust/libs/librust.a(rust-e6011ffb55678675.rust.8yq9vjk7-cgu.3.rcgu.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Itu sejauh yang saya dapatkan.

Saya berhasil menautkan rustc nightly-2019-09-05 aarch64-apple-ios and rustflags = "-C lto -Z embed-bitcode" staticlib dengan aplikasi clang-1100.0.33.5 (Xcode 11 beta 7) and -fembed-bitcode . Kode sumber adalah https://github.com/saturday06/rust-ios-bitcode-test .

  • Tahukah Anda jika bagian __cmdline diperlukan?

Dua tahun kemudian saya bisa menjawab ini - untuk menyebarkan ke perangkat fisik atau membuat arsip Xcode cmdline kosong baik-baik saja, namun untuk pengiriman App Store Apple melakukan validasi baris perintah dentang. Saya telah memberikan deskripsi yang lebih panjang dalam PR ini, yang mencakup tambalan peretasan untuk membuatnya berfungsi: https://github.com/getditto/rust-bitcode/pull/7

Saya ingin meningkatkan ini entah bagaimana tetapi opsinya tidak menarik. Apakah kami membuat beberapa opsi dentang saat menargetkan iOS? Apakah kami menyediakan envvar untuk memilih dengan tepat bagaimana berbohong jika Apple mengubah aturan validasinya? Saya akan dengan senang hati melakukan perubahan jika ada pilihan yang masuk akal di sini.

-Cembed-bitcode=no tidak berfungsi untuk target ios. masih ada bagian bitcode di .a file
bagaimana membangun tanpa bitcode?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat