Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
LagradOst opened this issue Jan 13, 2024 · 4 comments
Open

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

LagradOst opened this issue Jan 13, 2024 · 4 comments

Comments

@LagradOst
Copy link

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

@bjorn3
Copy link
Member

bjorn3 commented Jan 13, 2024

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.

@LagradOst
Copy link
Author

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
Copy link
Author

@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

@bjorn3
Copy link
Member

bjorn3 commented Jan 25, 2024

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

"aarch64-unknown-linux-gnu" => {
// We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
self.rustflags.push("-Clinker=aarch64-linux-gnu-gcc".to_owned());
self.rustdocflags.push("-Clinker=aarch64-linux-gnu-gcc".to_owned());
self.runner = vec![
"qemu-aarch64".to_owned(),
"-L".to_owned(),
"/usr/aarch64-linux-gnu".to_owned(),
];
}
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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants