tectonic
tectonic copied to clipboard
Compile for Android
Hi, I'm trying to cross compile tectonic to android using NDK r21 and the cargo plugin cargo-ndk
At first it would give me the error:
Unable to find openssl/opensslconf.h
I had to add the following line to Cargo.toml
[target.aarch64-linux-android.dependencies]
openssl = { version = "*", features = ["vendored"] }
Now only one problem left:
error: failed to run custom build command for `tectonic v0.0.0-dev.0 (/home/naveedpash/tectonic)
Caused by:
process didn't exit successfully: `/home/naveedpash/tectonic/target/release/build/tectonic-ca4c95895b54eba9/build-script-build` (exit code: 101)
--- stdout
cargo:rerun-if-changed=src/engines/mod.rs
cargo:rustc-env=TARGET=aarch64-linux-android
cargo:rerun-if-env-changed=TECTONIC_DEP_BACKEND
cargo:rerun-if-env-changed=TECTONIC_PKGCONFIG_FORCE_SEMI_STATIC
cargo:rerun-if-env-changed=FONTCONFIG HARFBUZZ >= 1.4 HARFBUZZ_ICU ICU_UC FREETYPE2 GRAPHITE2 LIBPNG ZLIB_NO_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_aarch64-linux-android
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_aarch64_linux_android
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_aarch64-linux-android
cargo:rerun-if-env-changed=PKG_CONFIG_aarch64_linux_android
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_aarch64-linux-android
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_aarch64_linux_android
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
--- stderr
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: CrossCompilation', build.rs:67:14
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace`
Don't known how to tell pkgconfig
crate that it's ok to cross-compile. Help?
There is a hint in the error output, although it is not obvious:
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_aarch64-linux-android
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_aarch64_linux_android
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
I think you need to set the environment variable PKG_CONFIG_ALLOW_CROSS
to 1, although you might need to use one of these other variables instead.
Also, you may wish to check out the cross tool for cross-compiling Rust projects. The Tectonic CI/CD system uses a customized version for its cross-compiles to build static or "semi-static" executables that don't have a lot of dependencies on non-system libraries like harfbuzz. Depending on your needs, you might not need a custom version.
People have mentioned Android compilations a few time over the years, so if you might be able to synthesize your work into contributing a new CI/CD build for Android, that would be awesome!
@naveedpash , just passing by: I'm working on tectonic dockerization. It's ok as is in #690 , but I'm not loosing hope to fix the volume issue.
So, is it possible, that docker image will solve your issue?
Sorry for super late reply; got caught up with my day job
Yes I did try the ubuntu official docker image with stable rust toolchain and android ndk version 22
#dockerfile
RUN apt install -y libfontconfig1-dev libgraphite2-dev libharfbuzz-dev libicu-dev libssl-dev zlib1g-dev **gcc-multilib**
(notice I had to add gcc-multilib otherwise ndk gives an error saying bits/libc-header-start.h
cannot be found for reasons I don't understand but something to do with the fact that parts of android run in 32 bits)
then I created .cargo/config
with the following lines
[target.aarch64-linux-android]
ar = "/path/to/android-sdk/ndk/<version>/toolchains/llvm/prebuild/linux-x86_64/bin/aarch64-linux-android-ar"
linker = "/path/to/android-sdk/ndk/<version>/toolchains/llvm/prebuild/linux-x86_64/bin/aarch64-linux-android28-clang"
I also had to run git submodule update --init
which makes cargo build openssl-sys
rather than look for the libssl-dev. Before I did that, I was insanely struggling with trying to get PKG_CONFIG to find the libssl-dev.
Then I run cargo build --target aarch64-linux-android --release
That it gives me 3 errors while trying to compile harfbuzz/src/harfbuzz.cc
all of which look like the following
cargo:warning=harfbuzz/src/hb-ot-layout.cc:1008:63: error: cast from pointer to smaller type 'uintptr_t' (aka 'unsigned int') loses information
cargo:warning= hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) &p - (uintptr_t) &g);
cargo:warning= ^~~~~~~~~~~~~~
cargo:warning=In file included from harfbuzz/src/harfbuzz.cc:51
I think I also need to define an additional linker for the c++ files like linker = "/path/to/android-sdk/ndk/<version>/toolchains/llvm/prebuild/linux-x86_64/bin/aarch64-linux-android28-clang++"
but I'm not sure how to tell cargo to do that.
Any help? I know it's definitely possible to compile libharfbuzz-dev for android because the Termux app for Android definitely has it in their apt repository and their deb package contains both lib/libharfbuzz.so
as will as header files in the include/
directory.
@naveedpash Hmm, I would strongly suggest that you base your work off of the "cross" framework for Rust, which is what we use in our CI systems:
https://github.com/rust-embedded/cross
You can see the relevant CI plumbing here:
https://github.com/tectonic-typesetting/tectonic/blob/master/dist/azure-build-and-test-cross.yml
The challenge historically has been that because Tectonic needs its native support libraries, we've had to use custom cross-builder Docker images with those libraries preinstalled. Generated using this framework:
https://github.com/tectonic-typesetting/tectonic-ci-support/tree/master/cross-images (the supporting README and comments aren't 100% up to date unfortunately)
But one of the big goals of moving to the sub-crate setup with "bridge" crates is to be able to start running these builds on stock Cross images.