rustc_codegen_cranelift icon indicating copy to clipboard operation
rustc_codegen_cranelift copied to clipboard

How do you build this for Android ("Tier 2 without Host Tools")

Open LagradOst opened this issue 1 year ago • 4 comments

7 mo ago I tried to build this project for android and being successfully able to compile rust project on android, however I was unable to link it (missing libc.so.6 ect) and JIT PTE was not implemented. Now I tested https://github.com/bytecodealliance/cranelift-jit-demo and it worked on an android device, and now I want to port the entirety of the compiler to android using JIT to run the code.

I use https://github.com/cross-rs/cross to "cross build --target aarch64-linux-android --release" this project and add to the toml

rustc_middle = { path = "../rustc_middle" }
rustc_ast = { path = "../rustc_ast" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_hir = { path = "../rustc_hir" }
rustc_incremental = { path = "../rustc_incremental" }
rustc_index = { path = "../rustc_index" }
rustc_interface = { path = "../rustc_interface" }
rustc_span = { path = "../rustc_span" }
rustc_metadata = { path = "../rustc_metadata" }
rustc_session = { path = "../rustc_session" }
rustc_target = { path = "../rustc_target" }
rustc_driver = { path = "../rustc_driver" }

and

[env] 
CFG_RELEASE="1.77.0-nightly"
CFG_RELEASE_CHANNEL="nightly" # https://github.com/rust-lang/rust/blob/fabf9298633ca64450fa2af535252dc44a3b1080/src/bootstrap/tool.rs#L179
RUSTC_INSTALL_BINDIR = "C:\\Users\\v\\.cargo\\bin"
CFG_COMPILER_HOST_TRIPLE = "aarch64-linux-android"
REAL_LIBRARY_PATH_VAR="LD_LIBRARY_PATH"
CFG_VERSION="1.77.0-nightly (62d7ed4a6 2024-01-11)"
CFG_RELEASE_NUM = "1.77.0"
DOC_RUST_LANG_ORG_CHANNEL="nightly" 
CFG_VER_DATE="2024-01-11"
CFG_SHORT_COMMIT_HASH = "62d7ed4a6"
CFG_COMMIT_HASH = "62d7ed4a6775c4490e493093ca98ef7c215b835b"

And this works fine for building the librustc_driver.so and librustc_codegen_cranelift.so, however it cant compile without a sysroot.

How can I compile the sysroot (to target android) to be able to compile it? Screenshot_20240113_171757_com example teest

LagradOst avatar Jan 13 '24 16:01 LagradOst

If I understand correctly what you are doing, you are making cargo compile rustc_driver + dependencies and then rustc_codegen_cranelift for android and then loading it into an existing rustc executable. That won't work. You need to link codegen backends against the exact same librustc_driver.so as rustc itself. Otherwise you either have abi mismatches or duplicated thread local storage. Both of which will lead to the compiler crashing. Or did I misunderstand what you did?

If I did misunderstand what you did and it does work, then you could try building the sysroot by changing rust-toolchain.toml to match the nightly you compiled librustc_codegen_cranelift.so for and then with an unmodified source of cg_clif run TARGET_TRIPLE="aarch64-linux-android" ./y.sh build. This should build the standard library for aarch64-linux-android and put it in dist/lib/rustlib/aarch64-linux-android. You need to put this dir at lib/rustlib/aarch64-linux-android of the sysroot of the rustc running on your phone.

I did however recommend building rustc itself with the cranelift backend enabled using a config.toml like the following in your local checkout of https://github.com/rust-lang/rust/

profile = "compiler"

[rust]
codegen-backends = ["llvm", "cranelift"]

[target.aarch64-linux-android]
cc = "/path/to/clang"
cxx = "/path/to/clang++"
linker = "/path/to/clang"

where you need to point it to the clang included in the android ndk and then doing ./x.py build --host aarch64-linux-android --target aarch64-linux-android. I haven't tested this though. Also the resulting rustc will use LLVM by default, but you can switch to cg_clif using -Zcodegen-backend=cranelift. Rust's build system unfortunately doesn't support specifying a different set of codegen backends to compile for each target and compiling rustc itself with cg_clif will result in a pretty slow compiler.

bjorn3 avatar Jan 13 '24 17:01 bjorn3

If I understand correctly what you are doing, you are making cargo compile rustc_driver + dependencies and then rustc_codegen_cranelift for android and then loading it into an existing rustc executable. That won't work. You need to link codegen backends against the exact same librustc_driver.so as rustc itself. Otherwise you either have abi mismatches or duplicated thread local storage. Both of which will lead to the compiler crashing. Or did I misunderstand what you did?

What I am actually doing is compiling this repo, but including the rustc_driver as a dependency, last time I did this I somehow got it working fine but the linker refused to work. The reason why I use cranelift over LLVM is because that is a real pain in the ass to compile and cranelift supports JIT so I can avoid linking.

All I want to do is to be able to compile a simple rust program with std on android and run it, but because it is not a host target shit just refuses to work.

LagradOst avatar Jan 13 '24 20:01 LagradOst

@bjorn3 using the default library does not work with JIT, however not using JIT forces me to link it, and I cant for the love of god get it to link correctly. I also tried compiling both the compiler and cranelift, but got weird errors.

eg TARGET_TRIPLE="aarch64-linux-android" ./y.sh build gave build/stdlib_target/aarch64-linux-android/release/deps/std-c3180c3c34b5771d.104560jli91o8tef.rcgu.o: error adding symbols: file in wrong format

So I am wondering how I should compile the sysroot to give JIT lib files, because right now -C llvm-args=mode=jit causes Screenshot_20240124_195824_com example teest

and not using it causes Screenshot_20240124_224715_com example teest

LagradOst avatar Jan 24 '24 21:01 LagradOst

eg TARGET_TRIPLE="aarch64-linux-android" ./y.sh build gave build/stdlib_target/aarch64-linux-android/release/deps/std-c3180c3c34b5771d.104560jli91o8tef.rcgu.o: error adding symbols: file in wrong format

You probably need to copy https://github.com/rust-lang/rustc_codegen_cranelift/blob/24361a1b99b122806afdc01c3aae1c43fdcc7e0a/build_system/utils.rs#L25-L34 to and adapt it for the "aarch64-linux-android" target, pointing to the linker in the NDK. You can remove the self.runner as that only matters for running tests.

So I am wondering how I should compile the sysroot to give JIT lib files, because right now -C llvm-args=mode=jit causes

The JIT mode requires all dependencies to be available as linked dylibs. I've got a branch somewhere to add a fake LTO mode to cg_clif which would likely help here, but that branch is quite out of date and doesn't actually wire it up to the JIT mode, only the default AOT mode.

bjorn3 avatar Jan 25 '24 11:01 bjorn3