This is a compilation problem, specifically with referencing shared libraries with NDK.
I have the SDL2 + GLEW program running fine on my mac (obviously with a different makefile/build system), and I have it running fine on Android as well (so long as I don't use GLEW). But now I need to use GLEW, and can't find a straightforward reference for how/where/what the heck is going on with including libraries in the NDK.
Anyways- in my android-project folder, I have jni/src/Android.mk (which I assume is where I should be looking?)
There's a line with LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image, and I assume that's the magic variable that I shlould add GLEW to? But what even is that? How does that know what GLEW even means? Should it be -lGLEW? (that last question is rhetorical- I've tried all of them and nothing works). I've even tried commenting out that line totally and get the same build error:
jni/src/src/main.cpp:8:21: fatal error: GL/glew.h: No such file or directory
#include <GL/glew.h>
I'm pretty much totally lost... does anyone have any resources I could look into?
Also, as a note, I'd also prefer an explanation regarding why/what is going on, as I'm sure I'll be including other stuff as I go on.
Edit:
As Drop pointed out below, this wasn't a linking problem- the compiler needed to know where to find GL/glew.h. So I added /usr/local/Cellar/glew/1.12.0/include to the LOCAL_C_INCLUDES := line, and that works. But now, there's an error compiling glew.h- GL/glu.h: No such file or directory.
So now,
is there a more general/clean/better way than hardcoding the whole /usr/local/Cellar/glew/1.12.0/include line to let the compiler know where GLEW is? Should glew.h be located somewhere more general?
Why do I only need this when compiling for android? The mac build doesn't need these flags...
I can't find clear documentation anywhere about this, but in compiling the mac build with GLEW, I didn't need to also install GLU and GLUT (like GLEW's website implied...), and further, neither GLU nor GLUT are available as packages via brew.
I've been looking around for documentation about this, but I feel like I don't know what I don't know. Is there some insight you could give to where I'm going wrong regarding how includes and libraries and stuff are expected to be referenced across platforms?
Welp. Turns out there isn't a straightforward way to include GLEW/GLU/GLUT with NDK? (I have a question mark because I'm still not 100% sure...).
However, I found the solution to my problem, and that was- I didn't need GLEW (or GLU, or GLUT, etc...)!
Like I said, I'm building for OSX and android, so I'm using OpenGL 2.1 and OpenGLES2.
I chose to do this because I was told that OpenGLES2 is simply a subset of OpenGL2, so I didn't expect any issues (so long as I didn't use any func's only in OpenGL 2.1).
I needed GLEW because I wanted to use framebuffers (glGenFramebuffers, etc...), which only exist as an extension in OpenGL 2.1. Once I got that working, I assumed I would need the same extension wrangling for OpenGLES2 on Android- turns out I simply don't! It just kinda works out of the box! (Well, once you get NDK working, and linked with OpenGL, and blah blah blah).
Related
My program needs to read jpeg-images from a file native. For that purpose I downloaded official jpeglib c-source code and that works flawlessly on a Windows version of this program, which is programmed using Embarcadero RAD Studio 8.
But when I try to use the same source code in Android Studio JNI, I see lots of errors almost every c-source file :( Below is a screenshot:
As you can see, there's errors on both
-Macro expansions (ERREXIT, red underlines), which complain "class 'blahblah' doesn't have a field 'blahblah'".
-member methods (red text in code), which complain also "class 'blahblah' doesn't have a field 'blahblah'".
Looks like there are many C-language classes and fields, or probably all, which are not working. But the jpeglib source definitely contains them all, something is just not working in Android Studio! Probably Android Studio C-compiler is somehow limited, but there must be some way to bypass it...
This problem doesn't exist in C++ source files. I have different source folders for java and C++ source files (and there are also separate jni folder, but I don't use it, probably I should), but C source files resides inside the C++ folder. I have added all c, cpp, h and hpp source files inside the parentheses of the CMakeLists.txt's add_library() directive, but that's all. I don't know is it enough...
I'm glad to get any suggestions how to fix this.
It is not enough to add all libjpeg files to your add_library(). The library expects to be configured for the specific toolchain, see e.g. this example.
I prefer an optimized version of the library, called libjpeg-turbo. On GitHub you can find step-by-step instructions how the library can be cross-compiled for Android.
Well, there seems to be happy ending...
I have to admit that Android Studio most likely can compile JPEG c-library:) The problem "class 'blahblah' doesn't have a field 'blahblah'" was because the library needs to be configured for the specific toolchain, like #Alex Cohn said. But the configuration doesn't happen in CMakeLists.txt, instead you need to rewrite the code itself at some extent. For example, you need to change
-INT32 to int32_t
-#define boolean bool
-#define EXTERN extern
-add lots of #include <> and #include ""
-and more...
If you need to do that, start from header files: don't touch C files until you have headers error free. As a side note, I had exactly the same build order in Android Studio than I had in Embarcadero Studio, but that didn't helped to succeed... I don't know yet, will this modified library work, but at least I think I will get rid of compilation errors!
I would like to use a shared library, that is compiled for arm64, on Android. I have my .so file inside a aarch64-linux-gnu folder, but for other libraries I have instead a aarch64-linux-android folder.
Please can these libraries compiled for aarch64-linux-gnu run on an arm64 Android device? What do these names stand for precisely? I know that aarch64 refers to the arm64 processor architecture but I don't know how the operating system is related here.
Thank you!
Android and ARM my have some libraries that are the same. Basically the SO file has to be able to find all the libraries it was linked against to run, and the versions need to match up so nothing breaks. This is risky, and it is generally safest to compile the entire program on your target machine. You can see if everything can be located/what is missing using:
ldd /path/to/file.so
this will give you a list of libraries and where the file thinks they are - or ??? if it can't find it. You need to double check and see if the results of this look OK.
Even if all dependencies are found, mismatch in versions or architecture will cause the program to break at run-time. You need to extensively test the use of the externally linked library and even then you may miss some cases that break your program. For this reason I would try and get the source code if possible, and re-compile everything on the target machine.
Is there a way/tool to enumerate all the C function prototypes (not sure if that's the right term) from the .h files in the NDK folder subdirectories (i.e. C:\android-ndk-r8b\platforms\android-9\arch-arm\usr\include) and produce something like a javadoc? The reason I'm asking is because we have a developer on our end who is trying to port his Windows code over to the android platform and before he begins to go forward with such an effort, he needs to know what API calls are supported so he can begin changing his code base to make it Android-NDK compliant. I've run across the following links in my search for an answer:
http://mobilepearls.com/labs/native-android-api/#c++
C:/android-ndk-r8b/docs/STABLE-APIS.html
C:/android-ndk-r8b/docs/CPLUSPLUS-SUPPORT.html
The right way to check if the code is compliant is to compile it and see what breaks. Win32 API surely would - there's even no point in checking if an NDK counterpart exists. The C/C++ RTL is a little more tricky - some functions have counterparts, some don't. But enumerating them all and matching by hand is, frankly, a waste of time. A compiler will do the same much faster.
For starters, let the code be Linux compliant. The minute differences between Android libs and Linux can usually be resolved incrementally. Note that you have a moving target here: platform-14 supports much more Linux headers than 9.
http://www.tenouk.com/Module000linuxnm3.html
can you use libs instead of .h files?
the link explains using 'nm' to dump symbols from libs
I don't know if what I'm trying to do is even possible, and while it may be undesirable I'd like to know whether I can make this work.
I have a Linux kernel compiled for an Android tablet and I need to make some changes to one of the built-in modules. (Compiling a new kernel from source is not, in this particular case, an option for me).
I've gotten as far as compiling using my modified source and compiling the .ko files I need. However, when compiling these modules, I get a list of errors that look like the following:
WARNING: "alarm_start_range" [/modules/p3_battery.ko] undefined!
It seems as though my Makefile isn't correctly linking this header:
#include <linux/power/p3_battery.h>
Anyway, I tried to load those modules on the device, and when I try to do insmod p3_battery.ko, I get a failure message (which I expected). Looking at dmesg, I see messages that tell me the following:
p3_battery: Unknown symbol alarm_start_range (err 0)
As mentioned above, those functions do exist in the kallsyms table.
I can provide more detail by supplying my Makefile if that will help, but I wanted to offer a concise formulation of the problem to see if what I'm doing here makes any sense.
The function calls are implemented in an .so file. When I build from command line, I get UnsatisfiedLinkError when the code attempts to call the native functions from Java (C-to-Java works correctly). The strangest part is that, when I externed the calls and obtained a pointer to them, the pointers are valid, then the UnsatisfiedLinkError still happens.
I guess the main question is, what does Eclipse do that command line doesn't (or vice versa)? I am at a loss, and need to get this working because other developers and the build server are incapable of building via Eclipse.
Another question would be, how does the function get found and called when using this mechanism (in Android)? I read a little bit of information on this, but nothing that helped me work out this problem.
Since it works within Eclipse, I am confident my JNI naming conventions are correct.
I have looked online quite extensively, but can't seem to get a good answer for this.
FYI, the .so file is included in the APK files (which look almost identical), and it is the only .so file.
How do you compile your .so files? Do you pass the -fvisibility=hidden flag to g++ (provided that you use g++ for compiling)? And -fPIC?