honzasp / rust-turbojpeg

Rust bindings for TurboJPEG library
MIT License
16 stars 12 forks source link

Building turbojpeg-sys using CMake fails for Android x86 #9

Closed tyilo closed 1 year ago

tyilo commented 1 year ago

I'm using the following environment variables to build for Android x86:

ANDROID_ABI=x86
ANDROID_NDK=/home/tyilo/Android/Sdk/ndk/21.4.7075529
ANDROID_PLATFORM=17
AR=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
AS=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android17-clang
CARGO_BUILD_TARGET=i686-linux-android
CARGO_TARGET_I686_LINUX_ANDROID_LINKER=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android17-clang
CC=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android17-clang
CMAKE_TOOLCHAIN_FILE=/home/tyilo/Android/Sdk/ndk/21.4.7075529/build/cmake/android.toolchain.cmake
CXX=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android17-clang++
LD=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/ld
RANLIB=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
STRIP=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip

I can build libjpeg-turbo for Android x86 manually using CMake:

$ cd $(mktemp -d)
$ git clone --recursive https://github.com/honzasp/rust-turbojpeg
$ cd rust-turbojpeg/turbojpeg-sys/libjpeg-turbo
$ mkdir build
$ cd build
$ cmake ..
$ make

However if I try to build a project using turbojpeg-sys with the cmake feature, I get an error:

$ cd $(mktemp -d)
$ cargo new turbojpeg_android_test
$ cd turbojpeg_android_test
$ cargo add --no-default-features --features cmake turbojpeg-sys
    Updating crates.io index
      Adding turbojpeg-sys v0.2.2 to dependencies.
             Features:
             + cmake
             - bindgen
             - pkg-config
             - require-simd
$ cat > src/main.rs
fn main() {
    unsafe {
        turbojpeg_sys::tjAlloc(1024);
    }
}
^D
$ cargo build
   Compiling anyhow v1.0.66
   Compiling cc v1.0.77
   Compiling libc v0.2.137
   Compiling cmake v0.1.49
   Compiling turbojpeg-sys v0.2.2
   Compiling turbojpeg_android_test v0.1.0 (/tmp/tmp.sk84AUqLbu/turbojpeg_android_test)
error: linking with `/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android17-clang` failed: exit status: 1
  |
  = note: "/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/i686-linux-android17-clang" "/tmp/rustcZfoMlb/symbols.o" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/turbojpeg_android_test-1c4ad68e50ad93e7.2vod6ppifzjgbxmp.rcgu.o" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/turbojpeg_android_test-1c4ad68e50ad93e7.3a4x8z63o5kdjxem.rcgu.o" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/turbojpeg_android_test-1c4ad68e50ad93e7.597w44jmsw2lks12.rcgu.o" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/turbojpeg_android_test-1c4ad68e50ad93e7.5e5tw586s0m4cc6.rcgu.o" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/turbojpeg_android_test-1c4ad68e50ad93e7.gry6mwfxm7q2c2i.rcgu.o" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/turbojpeg_android_test-1c4ad68e50ad93e7.zrbw5pxyg4tddzf.rcgu.o" "-Wl,--as-needed" "-L" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps" "-L" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/debug/deps" "-L" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/build/turbojpeg-sys-a7073ee1dadd896f/out/lib" "-L" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib" "-Wl,-Bstatic" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/libturbojpeg_sys-2ead15d1b4f80846.rlib" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/liblibc-665123b2360d668c.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libstd-622dd9b0332e26c9.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libpanic_unwind-8eed901191a90505.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libobject-a6301f462a1afc81.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libmemchr-93e670f0c20d09fd.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libaddr2line-41b5de145182a9b6.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libgimli-bbfb84cf04d9c494.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/librustc_demangle-e7484fb8d6809e4b.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libstd_detect-d6b62c0a4eb43f93.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libhashbrown-3a9f90107e729020.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libminiz_oxide-4deb44ec92052fb6.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libadler-4a6b480a176dcdfe.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/librustc_std_workspace_alloc-c299c9753161493f.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libunwind-295a81fa953b2dbd.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libcfg_if-abe19b897bf8ce07.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/liblibc-11a826f7ccf51420.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/liballoc-87fd81c649bbeba2.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/librustc_std_workspace_core-10180754ab6ad528.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libcore-a8584b609ee8c62b.rlib" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib/libcompiler_builtins-c93094a148dc18fa.rlib" "-Wl,-Bdynamic" "-ldl" "-llog" "-lgcc" "-ldl" "-lm" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/home/tyilo/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-linux-android/lib" "-o" "/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/turbojpeg_android_test-1c4ad68e50ad93e7" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
  = note: /home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/../lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: error: /tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/libturbojpeg_sys-2ead15d1b4f80846.rlib(turbojpeg.c.o): incompatible target
          src/main.rs:3: error: undefined reference to 'tjAlloc'
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

  = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `turbojpeg_android_test` due to previous error

If I inspect the file that rust is trying to link to (/tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/libturbojpeg_sys-2ead15d1b4f80846.rlib(turbojpeg.c.o)), I can see that it is an ARM object file and not a x86 object file as expected:

$ ar x /tmp/tmp.sk84AUqLbu/turbojpeg_android_test/target/i686-linux-android/debug/deps/libturbojpeg_sys-2ead15d1b4f8084
6.rlib
$ file turbojpeg.c.o 
turbojpeg.c.o: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), with debug_info, not stripped

If I instead try to build for Android armv7a with the following environment variables, then cargo build succeeds:

ANDROID_ABI=armeabi-v7a
ANDROID_NDK=/home/tyilo/Android/Sdk/ndk/21.4.7075529
ANDROID_PLATFORM=17
AR=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
AS=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi17-clang
CARGO_BUILD_TARGET=armv7-linux-androideabi
CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi17-clang
CC=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi17-clang
CMAKE_TOOLCHAIN_FILE=/home/tyilo/Android/Sdk/ndk/21.4.7075529/build/cmake/android.toolchain.cmake
CXX=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/armv7a-linux-androideabi17-clang++
LD=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/ld
RANLIB=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib
STRIP=/home/tyilo/Android/Sdk/ndk/21.4.7075529/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip
tyilo commented 1 year ago

What I said initially about it working when using cmake manually isn't actually true. It actually produces an ARM library!

...
$ cmake ..
$ make
$ file libturbojpeg.so
libturbojpeg.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=bfdd456a454cccf0753ab537403c0b941f8788a7, with debug_info, not stripped

Only when specifying ANDROID_ABI as a cmake option does it work as expected:

...
$ cmake -DANDROID_ABI=$ANDROID_ABI ..
$ make
$ file ibturbojpeg.so
libturbojpeg.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=0da1325a2a8aaaa9fe6c4ce418aef8924ef1ff41, with debug_info, not stripped
honzasp commented 1 year ago

Thank you for reporting and fixing this issue!