-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Building for Android doesn't generate shared lib (.so) #1173
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
Comments
Build log looks a bit short, is that from the complete build (after "make clean") or continuing after an earlier interruption ? |
@martin-frbg Yeah you're right, it's probably not the full log, it's the log after a build was already done (or at least attempted). The original log was too long to copy out of the console as I couldn't scroll back to the beginning - is the build log saved somewhere or should I just increase the scrollback size of the terminal? I only ran the commands from the guides I referenced and I don't thinks there's a NO_SHARED=1 in any of those. Gonna try to get a full log tomorrow. |
The build log is not saved, what you could do is redirect the console output to a file. |
You can collect output by typing 'script' |
Thanks for the tips. Meanwhile I also tried the "shared" option instead of "libs" as suggested by @martin-frbg, first it gave an error saying I first need static libs to do that. I suppose one could use both the libs and shared options to get both (or just run it with first the libs. then the shared option?), but while at it, I tried the "all" option to see what happens and it actually ran all the way through with no errors and I could also successfully run the install command and saw the shared lib files were generated. Just to have it in case it's needed I also included to full log for building with the "all" option: So it looks like @martin-frbg was on point, it was just because of the options that the .so didn't got generated. I haven't actually tested it yet though and the Android guide says: So I probably shouldn't use the all option after all. I checked in the Makefile and it looks like the all option means these: libs netlib tests shared |
Yeah, my suggestion was assuming that you had already run |
@martin-frbg Thanks for the quick reply. Indeed it looks like the multiple files are symbolic links to the same file (Ubuntu file manager didn't display this for some reason). Yeah, so one of my goals would be to also include Lapack, so I'm using a custom standalone Android NDK toolchain (referenced in my first post) with Fortran support, so compiling Fortran (and Lapack) shouldn't be an issue. One thing I don't quite get (sorry, I'm pretty new at this) yet is how can I combine these options (libs, shared, netlib). Can i just call it with multiple options like I found that if I call it with options
So it looks like the shared libs needs netlib/lapack. Or you think I can just use the "all" option (which also includes tests) and ignore the warning regarding the link/run errors in the guide? (of course I probably wouldn't want to run tests on Android, I would just use the library) |
Yes, just use the "all" option. The LAPACK functions will be included in the library. |
@martin-frbg great, thanks! Now I'm trying to use the shared library in an Android project. The problem is that the generated shared lib (libopenblas_armv8p-r0.2.20.dev.so) has a versioned SONAME: (see: the .0 after the .so part). Android doesn't support versioned SONAMEs, so there shouldn't be anything after the ".so" part. Is there any easy way to modify the build process so that the SONAME entry would be libopenblas.so? |
Try removing the first occurence of |
@martin-frbg Thanks, that indeed looks like it's working! Meanwhile I also got the Android app to work by using the static lib instead of the shared one. Using a static lib allows Android build to strip away unused code, so maybe it can be even preferable to using a shared lib, especially since the full shared lib size is at around 10 MB (the full static lib would be 20 MB, but I think most of the time only a small portion of that is needed) |
Looking at the commit log, shared library support for Android was added only a few weeks ago (by xianyi on Apr 11 ), keeping the soname versioning was probably just an oversight there. I'll submit a fix over the weekend if nobody beats me to it. |
Yeah OK, great! I also tested the shared library in the Android app, but apparently I get a crash on startup when loading the lib because of some missing symbol:
Not sure why it's missing from shared while it's OK with static. |
Do you have a libgfortran.so on the Android ? You may have to modify the linker flags so that the shared openblas gets built with its dependencies all linked statically (at which point there may be even less point in having a share libopenblas, except perhaps to be able to replace it as needed). |
Where is that build log? It is apparent that your cross-compiler does not find (or have) target fortran library and cannot link resulting object. It whould be above linktest, something like gcc/gfortran/ld *.o -o libopenblas.so |
@martin-frbg Oh so it's also trying to load libgfortran.so dynamically? I'm pretty sure Android doesn't have that by default, so I think the only way to load it would be to also include that with the app - and I certainly see no such library packed in the app currently. I'm not even sure if this problem should be handled when compiling openblas itself, or when compiling the native Android app (with cmake) and linking agains openblas... Also I have a few additional questions (a bit offtopic, as they are more of general questions regarding Android) I noticed that the openblas_config.h file inside the "include" folder differs in 32 and 64 bit builds as it uses different flags to indicate specific platforms like: The other question is: how can I verify that Lapack is included in the lib? Is there any method to query this, or maybe a specific method I can call that wouldn't work if Lapack was not included? |
First the linker does not find android libgfortran.so, and does not generate android libopenblas.so |
@brada4 yeah that's what I figured. I still don't quite get is even though I supposedly compiled OpenBLAS with Lapack, I'm not sure how can I use it or even verify that it's indeed compiled and working. The include folder obtained after running the install command only contains 3 files for blas, but none for lapacke. Are there some additional steps needed to properly compile/include Lapack - or I should just manually include/use the lapacke headers? |
Looks as if your "make install" assumed NO_LAPACKE=1 for some reason (perhaps it did not find a fortran compiler if you omitted the FC= and other options from the build run ?). Try using all the options from the "make ... all" on the "make ... install" as well. |
In the build run I did specify FC, the full command (for 64 bit) I used is: Running install with all these options again though seems to do the trick as suggested, it creates 4 additional lapacke headers in the include folder. I suppose I should be able to use Lapack through these headers, gonna try that soon. |
You can examine elf libraries with nm (most likely $ aarch64-linux-android-nm libopenblas.so) |
@brada4 tried that to and definitely see a lot of methods that has Lapack included in their name, I guess that's a good sign :) BTW the default android compiler uses clang since a while, and not gcc. I think openblas was compiled with gcc though. Should I set the Android compiler to also use gcc, or clang should be fine too? |
clang is fine (think OSX), but you need fortran compiler for LAPACK. |
@brada4 what I meant was that I compiled OpenBLAS using gcc and I'm compiling the rest of the app with clang - should that be also OK? Now I'm trying to use the lapacke functions through the header lapacke.h, using the static library, but when compiling it seems like I get very similar errors I got when I tried to use shared lib with armadillo issues: "undefined reference to `_gfortran_concat_string". The full error message:
Any idea what could be wrong? Maybe the linking flags? I still haven't set the ldflags specified here: |
Seems even your static libopenblas.a actually does not have libgfortran built into it after all. Try adding -static-libgfortran to the ldflags (and/or see if your toolchain path contains static libraries libgfortran.a and libquadmath.a that you could supply in place of the -lgfortran) |
@martin-frbg yeah, this is pretty strange. It looks like the toolchain I used does contain a libgfortran.a (the 32 bit version even contains multiple versions in different folders like armv7-a/hard, armv7-a/thumb) and if I include it, it compiles. Thanks for the tip! |
I tried one sample that used LAPACKE_dgels() function and it worked, but when I tried another, I got errors - it looks like there are still a few things it can't resolve:
|
Is this from the testing suite supplied with lapacke ? The README in lapack-netlib/LAPACKE suggests you may be expected to supply a suitable implementation of this function yourself. |
@martin-frbg I found that sample code here: |
I have merged a change that should remove the soname versioning from the android builds, so I assume this issue can now be closed (?) |
@martin-frbg that's great, just tested it and can confirm that the SONAME is now generated correctly on Android by default. Yeah so there were multiple problems I ran into mentioned in this thread, so the original was just that no shared lib was generated was that because in the Android guide I linked in the first post the "libs" parameter is used instead of "all" - so this was really the only original issue I had, and this was solved. (maybe the guide could be updated to reflect this.) BTW I still haven't tested the shared libs yet as the static was working fine - last time I checked there were the unresolved references because of missing libgfortran - maybe I can still test it by linking with the same libgfortran.a I did when using openblas as static library. Some other issues I now encounter (sorry for bringing in more off-topic questions, I realize this is probably not the best place to do this) : in some combinations I get an error when linking that the openblas lib "uses VFP register arguments, output does not". I guess this is because the guide mentions you have to set the flags to use hard floating points. So both openblas and lapacke use hard floating points, so I should set all the flags in my programs to do the same also, right? I was trying the set the suggested flags in the C flags part of the Android build (gradle) file but it didn't help much so far. Maybe I'll try to do that in the cmake file. The strange thing is that when compiling for arm64, it works without setting any flags for hard floats - while 32 bit arm doesn't. |
Arm64 uses completely different assembly kernels (and I suspect there are no arm64 cpus that lack a floating point unit, making the choice between dedicated hardware and slower emulation unnecessary). From my (limited) understanding, one of the differences between the modes lies in how (in which registers) the values are passed to the functions so mixing modules that were built with different flags will only work as long as one set does not do any floating point computations at all. "Historically" the OpenBLAS codes for arm32 were written for designs with dedicated floating point hardware, xianyi has started only recently to modify them. |
@martin-frbg yes, you are right that this is a separate issue, I think this one could be closed. |
Building for Armv7 32 bit architecture with android tool chain is throwing error during make install make PREFIX=./install install /Applications/Xcode.app/Contents/Developer/usr/bin/make -j 8 -f Makefile.install install |
See above - if you want the shared library (and you are using the current "develop" version from github, not some earlier release), do not specify the "libs" option on the |
did anyone try to load the shared library in android and got it working.? |
@vinayak618 please see #1871 , it looks like x86 and arm compilers were mixed together. |
Dear scorpeeon, I have the same problem in c++. Did you resolve it? What should I do? |
That function (actually macro) compensates absent complex support in C compilerwhen including lapacke.h. It is internal/private to the degree it is hidden when compiler supports complex numbers. |
Uhhhh, You mean it is enough writing like this? for example: lapack_complex_double x = {1.0 , 2.0}; |
Use lapack_complex_double which is not hidden by macros. I think other's thread is not the right place to discuss unrelated API. |
I made a standalone NDK toolchain with Fortran support using the latest NDK (r14b) following these instructions:
https://github.com/buffer51/android-gfortran
Using latest develop branch of OpenBLAS, followed this guide to build OpenBLAS with Fortran:
https://github.com/xianyi/OpenBLAS/wiki/How-to-build-OpenBLAS-for-Android
The build itself seemingly goes fine (without error) but the install command says it can't find the .so file - I checked, and it's not generated for some reason (can't find any .so files within the folders). So the install command only generates the header files and the static (.a) lib, but not the shared (.so) lib. Tried both arm and arm64, happens in both versions.
The relevant error message (when running the install command) :
Also attached build log.
log.txt
Any ideas what's wrong?
The text was updated successfully, but these errors were encountered: