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

Cannot cross-compile for Android NDK 19C #16809

Closed
mklaust opened this issue Aug 9, 2024 · 3 comments · Fixed by #17470
Closed

Cannot cross-compile for Android NDK 19C #16809

mklaust opened this issue Aug 9, 2024 · 3 comments · Fixed by #17470
Assignees
Milestone

Comments

@mklaust
Copy link

mklaust commented Aug 9, 2024

Describe the bug

After upgrading to Conan 2.6.0, the recipe for libjpeg fails to build when cross-compiling for Android using NDK 19C. (This may be an issue for other recipes/packages as well.)

This issue has been observed when using Ubuntu 22.04 and Windows 11 build systems.

Here are the key/related items from the host profile:

[settings]
os=Android
os.api_level=16
arch=armv7
compiler=clang
compiler.version=8
compiler.cppstd=gnu17
compiler.libcxx=c++_shared
build_type=Release

[conf]
tools.android:ndk_path=<This is set to the unzipped path of Android NDK 19c>

(I can't share our entire setup, but if you need additional information, please let me know.)

The following Conan command triggers this problem:

conan install --requires libjpeg/9e -pr:b gcc11-linux-x64 -pr:h clang8-android-armv7 -s:b build_type=Debug -s:h build_type=Debug --build="libjpeg/9e"

Here's the offending error from the output...

./libtool: line 1720: /opt/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ranlib: No such file or directory

This may have been caused by a recent change to Conan file gnutoolchain.py. Starting at line 159 it sets several variables used for the cross-compile. For some, it uses the file based on the target and API level. However, for the RANLIB variable, it uses the hard-coded filename of llvm-ranlib. In the most recent version of the NDK (and possibly others) this file exists. However, in the 19C version, this file does NOT exist, which causes the build to fail. Due to factors outside of our control, we need to use version 19C, so we're trying to figure out a solution that will work for that version.

I've tried various approaches to set RANLIB in the host profile we're using but nothing seems to overwrite the value set by this script. The only ways I've been able to get this to work thus far is to:

  • Manually modify the generated libtool and Makefile files generated to specify the correct ranlib filename.
  • Create a symbolic link for the file it is looking for (llvm-ranlib) that points to the actual file arm-linux-androideabi-ranlib.

I would consider both of these a hack, not a fix.

It seems that line 164 should be using a value that correlates with the information provided in host profile rather than just hard-coding it to llvm-ranlib.

I'm struggling to figure out a non-ugly workaround for this. We build for various target platforms including 4 different Android configurations. I can't just use the symbolic link approach as it would only work for ARM-based builds.

Is there any way to configure the profile (or some other file) that would force Conan to use a custom value for RANLIB? I know that some of the settings for doing cross-compiles for Android have changed over the versions. I'm hoping that there is some new way to do this that I just haven't found yet.

How to reproduce it

The following Conan command triggers this problem:

conan install --requires libjpeg/9e -pr:b gcc11-linux-x64 -pr:h clang8-android-armv7 -s:b build_type=Debug -s:h build_type=Debug --build="libjpeg/9e"
@jcar87
Copy link
Contributor

jcar87 commented Aug 10, 2024

Thanks for reporting this @mklaust

Tagging @franramirez688 - as we may need some improvements:

  • document and check the minimum required version of the android ndk for those variables to be set - I think the ones we are setting are valid since ndk 22
  • check if the files exist before setting the variables

@mklaust we'll look into this and if necessary issue a patch release for 2.6.0 - as I can see that the variables set by the autotoolstoolchain do take precedence over any variable set (or unset) by the user.

Due to factors outside of our control, we need to use version 19C, so we're trying to figure out a solution that will work for that version.

Our understanding of the Android NDK is that newer versions of the NDK can be used to target older versions of Android - so one could still generate the same binaries with newer versions of the NDK. Is this not correct? Any information would be appreciated as it can inform of our policy of how far we should go in supporting older versions, since 19C is arguably quite old.

@mklaust
Copy link
Author

mklaust commented Aug 12, 2024

@jcar87 you are correct in that newer versions of the NDK can be used to target older versions of Android. Our challenge is that we're linking in other binaries (not ours) that are also built with 19C, which is what's holding us to that version. There are efforts/plans to upgrade. (As you said...19C is quite old.) Unfortunately, until that happens, we're stuck at this version.

I appreciate the feedback and the possibility of a patch! If you discover a way for us to override this behavior (using the existing logic), I'm good with that too. The workarounds I listed in the original post are the only ones I've found thus far, but there are some challenges associated with them.

Thanks again!

@memsharded
Copy link
Member

This has been closed by #17470, that will prioritize Conan defined buildenv (from profiles or from tool-requires). So if the environment define CC/CXX/... variables, then the AutotoolsToolchain will not automatically deduce and define it from the ndk_path. This will be part of Conan 2.11 to be released asap.

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

Successfully merging a pull request may close this issue.

4 participants