Comments (29)
This is something that's been fixed a few days ago for a similar issue: bytedeco/javacpp-presets#127
Make sure your source code includes this commit: bytedeco/javacpp-presets@f594e8d
from javacpp.
Thanks, but firstly if I change the edition to 1.2-SNAPSHOT the gradle could not download the jar.
compile 'org.bytedeco.javacpp-presets:gsl:1.2-SNAPSHOT'
And secondly, I've noticed that one line of code was added in the cppbuild.sh before the ./configure->make->make install:
patch -Np1 < ../../../gsl-$GSL_VERSION-android.patch
And I read the android.patch file and runs it. But it's not totally correct. I've tried the gsl-1.6 and gsl-2.1 both. Something didn't match the patch file. For example, in the version gsl-2.1 the cblas/Makefile.in was like this:
libgslcblas_la_LDFLAGS = $(GSLCBLAS_LDFLAGS) -version-info $(GSL_LT_CBLAS_VERSION)
But the patch file is like this and so the patch won't work.
-libgslcblas_la_LDFLAGS = -version-info $(GSL_LT_CBLAS_VERSION)
So I do this manually. That is edit the cblas/Makefile.am, cblas/Makefile.in, Makefile.am and Makefile.in and replace the "-version-info $(GSL_LT_CBLAS_VERSION)" with "-avoid-version". Then ./configure and make and make install. This work fine too and no version information in the generated library files. For example, I got a libgsl.so.19 before but now it's libgsl.so.
But my problem is when I'm using the compiled gsl library in my android studio, the app installs well but crash when running. Without any linking error or compile error. It just says the libgsl.so not found:
12-23 20:19:53.224 17215-17215/com.ict.hci.iwatcher E/dalvikvm: dlopen("/data/app-lib/com.ict.hci.iwatcher-1/libjniJavacppDemo.so") failed: Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library "libgsl.so" needed by "libjniJavacppDemo.so"; caused by load_library(linker.cpp:745): library "libgsl.so" not found
12-23 20:19:53.227 17215-17215/com.ict.hci.iwatcher W/dalvikvm: Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/ict/hci/iwatcher/service/JavacppDemo$NativeDemo;
12-23 20:19:53.227 17215-17215/com.ict.hci.iwatcher W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40d01930)
And the libgsl.so is not packaged into the apk file.
from javacpp.
I've copid the libgsl.so and libgslcblas.so into a folder lib/armeabi and then zip the lib folder into lib.zip and then rename it to lib.jar. And finally copy the lib.jar to my android libs folder. In this way the libgsl.so and libgslcblas.so was successfully packaged into the apk file. But I got the .so file not found error too and if I remember correctly the error was exactly the same error I got when I'm using gsl of javacpp-presets directly.
12-23 21:01:01.609 18106-18106/com.ict.hci.iwatcher E/dalvikvm: dlopen("/data/app-lib/com.ict.hci.iwatcher-2/libgsl.so") failed: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "cblas_sdsdot" referenced by "libgsl.so"...
12-23 21:01:01.609 18106-18106/com.ict.hci.iwatcher E/dalvikvm: dlopen("/data/app-lib/com.ict.hci.iwatcher-2/libjniJavacppDemo.so") failed: Cannot load library: soinfo_link_image(linker.cpp:1635): could not load library "libgsl.so" needed by "libjniJavacppDemo.so"; caused by find_library(linker.cpp:889): "libgsl.so" failed to load previously
12-23 21:01:01.609 18106-18106/com.ict.hci.iwatcher W/dalvikvm: Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lcom/ict/hci/iwatcher/service/JavacppDemo$NativeDemo;
12-23 21:01:01.609 18106-18106/com.ict.hci.iwatcher W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40d01930)
from javacpp.
I didn't notice GSL 2.x was released. We'll have to update that!
Anyway, for now, to get new binaries for 1.16, please try to follow the instructions here:
https://github.com/bytedeco/javacpp-presets/wiki/Build-Environments#android-arm-and-x86
from javacpp.
I've found this link.
It says something about APP_PLATFORM in the android.mk. But we have no android.mk file in javacpp project. So does this really matters?
from javacpp.
What error exactly do you get when running bash cppbuild.sh install
?
from javacpp.
Sorry, but I didn't run this bash directly. But I run the code in cppbuild.sh manually. The cppbuild.sh runs something like downloading the gsl.tgz and unzip it and then running the patch and configure->make->make install. The patch file has some errors cause it does not match my gsl library source code. But I can fix it by manually edit every file described upside. Until now no errors.
So I think "bash cppbuild.sh install" will have no error too(but need some edit to the patch file).
The error comes in the runtime. I'm sure the libgsl.so and libgslcblas.so and my own generated .so file was packaged and installed on my phone. But when I load the library with this:
Loader.load();
//or
//System.loadLibrary("gslcblas");
//System.loadLibrary("gsl");
//System.loadLibrary("jniJavacppDemo");
The error come out when loading gsl.
12-24 10:01:20.034 30345-30345/com.ict.hci.iwatcher E/dalvikvm: dlopen("/data/app-lib/com.ict.hci.iwatcher-1/libgsl.so") failed: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "cblas_sdsdot" referenced by "libgsl.so"...
from javacpp.
By the way, which version of ndk did you used to compile the gsl-1.6? Some says r10 will lead to the "Cannot load library: soinfo_relocate" problem.
from javacpp.
As per the message above, I've updated the presets for GSL 2.1, so executing bash cppbuild.sh install --platform android-arm
should work now.
from javacpp.
The patch file is OK now. But I've run the bash cppbuild.sh install --platform android-arm
, there was some mistakes I think. I'm not familar with bash, but if I run this command the first "if" of cppbuild.sh will be true:
if [[ -z "$PLATFORM" ]]; then
and then when it goes to
pushd ..
bash cppbuild.sh "$@" gsl
popd
the bash cppbuild.sh "$@" gsl
will fail and says that cppbuild.sh not found, I don't know why.
and what's more, the command download is not install on my ubuntu. And I can't install it with apt-get install.
But anyway, the cppbuild.sh is not my problem. I've make it work manually. So you could think that I can run bash cppbuild.sh install --platform android-arm
without any errors.
My problem is in the runtime. I've packaged the libgsl.so and libgslcblas.so into my apk file. But when I excute
System.loadLibrary("gsl");
The error come out tells me that
12-24 23:42:25.820 21735-21735/com.ict.hci.iwatcher E/art: dlopen("/data/app/com.ict.hci.iwatcher-1/lib/arm/libgsl.so", RTLD_LAZY) failed: dlopen failed: cannot locate symbol "cblas_sdsdot" referenced by "libgsl.so"...
from javacpp.
Right, so try to use libraries built with the cppbuild.sh scripts. The error that you are getting indicates that the parent cppbuild.sh file is missing. So make sure that you haven't deleted it by mistake.
from javacpp.
Indeed, I missed the parent cppbuild.sh and now I've added it to the parent directory. But then the case $PLATFORM in
will go to linux-x86_64
branch. And what's more, if I change the code and make it go into the android-arm branch, the ANDROID_ROOT and ANDROID-BIN need to be set up to. I've set them to this:
ANDROID_ROOT=/home/shekmun/android/android-ndk-r10e/platforms/android-14/arch-arm
ANDROID_BIN=/home/shekmun/android/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi
Is this right? Now it runs and generates the library.
And... even though, I don't think this will make any difference to my manual way. In fact I've checked the md5 of generated libgsl.so and libgslcblas.so, they are the same file to my manual way. In fact it's executing the same commands in both ways.
from javacpp.
Calling System.loadLibrary("gsl")
isn't needed. If you want to do that though, make sure to call System.loadLibrary("gslcblas")
beforehand.
from javacpp.
I'm doing this:
Loader.load();
//or
//System.loadLibrary("gslcblas");
//System.loadLibrary("gsl");
//System.loadLibrary("jniJavacppDemo");
Then I got the error. So how can I use the library without loading it?
This is my java code:
@Name("Demo")
public static class NativeDemo extends Pointer {
static {
System.loadLibrary("gslcblas");
System.loadLibrary("gsl");
System.loadLibrary("jniJavacppDemo");
//Loader.load();
}
public NativeDemo() {
allocate();
}
private native void allocate();
private native int get();
}
In the C++ code of get(), I used the gsl function.
from javacpp.
I checked the symbol link of libgsl.a and libgslcblas.a:
shekmun@shekmun-desktop:~/android/libs/lib$ nm libgsl.a | grep cblas_sdsdot
U cblas_sdsdot
shekmun@shekmun-desktop:~/android/libs/lib$ nm libgslcblas.a | grep cblas_sdsdot
00000000 T cblas_sdsdot
Note that I'm checking the .a file not .so. The .so gives nothing. Does this help?
from javacpp.
Why are you looking at the .a files?
Anyway, make sure your app's target SDK version is not 23 or higher: bytedeco/javacv#245
from javacpp.
The output of .so:
shekmun@shekmun-desktop:~/android/libs/lib$ nm libgsl.so
nm: libgsl.so: no symbols
Targeting 20 gives the same error.
12-28 10:39:22.120 726-726/com.ict.hci.iwatcher E/art: dlopen("/data/app/com.ict.hci.iwatcher-2/lib/arm/libgsl.so", RTLD_LAZY) failed: dlopen failed: cannot locate symbol "cblas_sdsdot" referenced by "libgsl.so"...
from javacpp.
It's weird. I run nm libgsl.a | grep U
to see all the undefined symbol link, and some line of output and cblas_sdsdot is not the first one:
......
U cblas_scnrm2
U cblas_scopy
U cblas_sdot
U cblas_sdsdot
U cblas_sgemm
U cblas_sgemv
U cblas_sger
......
And I've used the readelf command to check the .so file:
shekmun@shekmun-desktop:~/android/libs/lib$ readelf -Ws libgsl.so | grep cblas_sdsdot
189: 00000000 0 NOTYPE GLOBAL DEFAULT UND cblas_sdsdot
shekmun@shekmun-desktop:~/android/libs/lib$ readelf -Ws libgslcblas.so | grep cblas_sdsdot
12: 0000298c 268 FUNC GLOBAL DEFAULT 8 cblas_sdsdot
from javacpp.
if I use readelf to check the undefined symbol link, the cblas_sdsdot is the first one of cblas library:
shekmun@shekmun-desktop:~/android/libs/lib$ readelf -Ws libgsl.so | grep UND
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_finalize
2: 00000000 0 FUNC GLOBAL DEFAULT UND __cxa_atexit
6: 00000000 0 FUNC GLOBAL DEFAULT UND malloc
7: 00000000 0 FUNC GLOBAL DEFAULT UND free
10: 00000000 0 FUNC GLOBAL DEFAULT UND memset
52: 00000000 0 FUNC GLOBAL DEFAULT UND fread
54: 00000000 0 FUNC GLOBAL DEFAULT UND fwrite
62: 00000000 0 FUNC GLOBAL DEFAULT UND putc
63: 00000000 0 FUNC GLOBAL DEFAULT UND fprintf
65: 00000000 0 FUNC GLOBAL DEFAULT UND fscanf
189: 00000000 0 NOTYPE GLOBAL DEFAULT UND cblas_sdsdot
191: 00000000 0 NOTYPE GLOBAL DEFAULT UND cblas_dsdot
193: 00000000 0 NOTYPE GLOBAL DEFAULT UND cblas_sdot
195: 00000000 0 NOTYPE GLOBAL DEFAULT UND cblas_ddot
So I think the error comes because of the system doesn't know where to find the symbol link. Maybe we should tell it to find it from "libgslcblas.so"? But how?
from javacpp.
On Android, the official way is to call System.loadLibrary("gslcblas"). If that doesn't work on your version of Android, you should report this issue upstream to Google so they can have it fixed.
from javacpp.
Ok, I will try as you said and do a bit more work on this. And if it works at last, I will post my solution here.
Thanks all the same!
from javacpp.
Well, it looks like a bug in Android, but it would be nice to know the workaround, yes. I'll try out the new version myself next week, just to make sure that it still works :)
from javacpp.
from javacpp.
Still no lucky for the ReLinker library. It's the same error. Thanks.
I tried to load the library in c++ code:
int ret = 0;
void *cblas = dlopen("/sdcard/Download/libgslcblas.so", RTLD_LAZY | RTLD_GLOBAL);
if (cblas == NULL) ret += 1;
else {
void (*sdsdot)() = (void (*)()) dlsym(cblas, "cblas_sdsdot");
ret += (sdsdot == NULL) ? 10 : 100;
}
void *gsl = dlopen("/sdcard/Download/libgsl.so", RTLD_LAZY | RTLD_GLOBAL);
if (gsl == NULL) ret += 1000;
return ret;
And the ret's value always be 1100! It seems that the RTLD_LAZY and RTLD_GLOBAL do not make any differences.
from javacpp.
I've just tested here, and I'm getting the same exact problem, so it looks like a bug in Android. It should be reported upstream to the Android team, but if you're looking for a quick solution, I guess linking everything statically would work.
from javacpp.
Ok, I found a workaround. Check the latest commit I've made above, it works here. Basically, it looks like not only do we need to load manually all the libraries at runtime, but also we need to make sure that their names are linked in at build time as well.
from javacpp.
Great Job!!! Now it works, fantastic, it's long time since I was stuck on the problem.
I'v added the GSL_LDFLAGS="-Lcblas/.libs/ -lgslcblas"
to the ./configure
to declare the dependency as the newly updated cppbuild.sh file, and nothing else changed, and it finally worked.
Thanks again. I've almost given it up. Really nice job and I appreciate it very very much. It helps me a lot 👍
from javacpp.
Work around included in version 1.2. Thanks for reporting and spending time debugging this!
from javacpp.
BTW, a build plugin for Gradle is now available here:
https://github.com/bytedeco/gradle-javacpp
If you try it out and find anything missing, please let me know!
from javacpp.
Related Issues (20)
- Optional pair HOT 2
- ParserException for valid c++ code HOT 1
- Function pointer returning shared_ptr HOT 10
- LNK2001: Unresolved external, issue with namespace? HOT 7
- infinite recursion when calling virtualized inherited function HOT 4
- Mapping Template Constraints, Parser Error HOT 5
- Parser cannot compile because of QT HOT 4
- Template class with template functions HOT 15
- Inadequate Error Handling HOT 1
- `@StdVector` default annotation causing `Parser` to ignore templated constructors and operator overloads with `std::vector` arguments HOT 10
- Crash when passing a unique_ptr by value HOT 12
- Potential class loading deadlock when call static methods of Loader or Pointer HOT 13
- Multiple pointer types and automatic generation of function overloads HOT 1
- Parser doesn't add @Virtual annotations HOT 2
- A question about garbage collection on native objects HOT 3
- Pointer types don't work on the native side if allocated in java HOT 16
- Missing dependencies reported by gradle HOT 1
- Not found libs based on x86 in 1.5.10 HOT 4
- Marking an interface with virtualize() causes compilation failure when returning byte array
- Panama HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from javacpp.