mavlink / MAVSDK-Java

MAVSDK client for Java.
71 stars 41 forks source link

Missing filesystem symbols when linking libc on Android #65

Closed Katawann closed 3 years ago

Katawann commented 3 years ago

Hello,

The issue I have is when I build the mavsdk_server from source with version v0.38.0-1-2 of mavsdk (I build the mavsdk_server from source because I need to have static library instead of shared). No issue with mavsdk v0.37.0 or version before. The output error I get in Android Studio is:

2021-03-30 19:00:48.493 6573-6685/com.modulesaero41 E/AndroidRuntime: FATAL EXCEPTION: create_react_context
    Process: com.modulesaero41, PID: 6573
    java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE" referenced by "/data/app/com.modulesaero41-1/lib/arm64/libmavsdk_server.so"...
        at java.lang.Runtime.loadLibrary0(Runtime.java:989)
        at java.lang.System.loadLibrary(System.java:1562)
        at io.mavsdk.mavsdkserver.MavsdkServer.<clinit>(MavsdkServer.java:6)
        at com.modulesaero41.mavsdk.MavsdkModule.<init>(MavsdkModule.java:43)
        at com.modulesaero41.mavsdk.MavsdkPackage.createNativeModules(MavsdkPackage.java:24)
        at com.facebook.react.ReactPackageHelper.getNativeModuleIterator(ReactPackageHelper.java:42)
        at com.facebook.react.NativeModuleRegistryBuilder.processPackage(NativeModuleRegistryBuilder.java:42)
        at com.facebook.react.ReactInstanceManager.processPackage(ReactInstanceManager.java:1347)
        at com.facebook.react.ReactInstanceManager.processPackages(ReactInstanceManager.java:1318)
        at com.facebook.react.ReactInstanceManager.createReactContext(ReactInstanceManager.java:1225)
        at com.facebook.react.ReactInstanceManager.access$1100(ReactInstanceManager.java:131)
        at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:1016)
        at java.lang.Thread.run(Thread.java:761)

I guess the issue can also come from the integration I do into a react-nativ app. I'll try to figure it out on my side and I will come with more accurate description if nobody faced this situation so far.

JonasVautherin commented 3 years ago

Can you show how you build it? The cmake commands?

Katawann commented 3 years ago

Not sure if it's the good way to proceed, but I'm just changing one line in the build.gradle file from:

android {

       ....    

        externalNativeBuild {
            cmake {
                arguments "-DANDROID_STL=c++_shared"
            }
        }

       ....    

}

to:

android {

       ....    

        externalNativeBuild {
            cmake {
                arguments "-DANDROID_STL=c++_static"
            }
        }

       ....    

}

Then I integrate the mavsdk-server-debug.aar generated in my application by adding it in File > New > New Module... And then implementation project(':mavsdk-server-debug') in the build.gradle of my app.

Should I change something in the CMakeLists.txt as well ? It was working until now so I did not try to adapt anything else

JonasVautherin commented 3 years ago

I don't think that you want to change this line. But I don't really understand what the issue is. Doesn't the MavenCentral dependency work in your app? I don't know react-native :sweat_smile:

Katawann commented 3 years ago

MavenCentral dependency provides a shared library of mavsdk_server. There is an issue with React-Native when we use libc++_shared.so and this is issue also happen with MAVSDK. The only workaround I found is to get static library for mavsdk_server.

I guess the best is to build a pure Android app and see if the issue still happen

JonasVautherin commented 3 years ago

MavenCentral dependency provides a shared library of mavsdk_server.

But you are, too, by changing this line.

There are two things:

If you want to use a static libc, you have to recompile libmavsdk_server.so as well :+1:.

Katawann commented 3 years ago

ok so I guess I'm lucky it is working. I'm closing the issue and will try your proposition and see if I still have the same problem. Thank you !

divyanshupundir commented 3 years ago

I just updated the dependencies to 0.8.0 and I too am getting the same error. I'm not using react-native.

def mavsdk_version = "0.8.0"
implementation "io.mavsdk:mavsdk:$mavsdk_version"
implementation "io.mavsdk:mavsdk-server:$mavsdk_version"
Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE" referenced by "/data/app/<package>-gPP2YdUfzajwPSPZR8usKw==/base.apk!/lib/arm64-v8a/libmavsdk_server.so"...
        at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
        at java.lang.System.loadLibrary(System.java:1669)
        at io.mavsdk.mavsdkserver.MavsdkServer.<clinit>(MavsdkServer.java:6)

Things work perfectly fine with 0.7.0

JonasVautherin commented 3 years ago

Aha! I think I did not update the NDK correctly, and this is a feature coming with C++17. Let me have a look!

JonasVautherin commented 3 years ago

I am not completely sure, but I believe that this happens because you are using an Android NDK older than r22. Could it be?

The mavsdk_server package links libc as a shared library (which @Katawann wants to change), but then I would think that libc is coming from the final app, and hence from your NDK. For @divyanshu1234, I believe that updating the NDK may just do it. Could you please try?

For @Katawann, if you want to link libc statically, then you'll have to do that when building mavsdk_server, and if you use dockcross (like the MAVSDK CI), then I think it will need to wait until dockcross is updated.

Please let me know how it goes!

JonasVautherin commented 3 years ago

For the record, I believe that this is related

divyanshupundir commented 3 years ago

I believe that this happens because you are using an Android NDK older than r22. Could it be?

I was using NDK 22.0.7... earlier. Even after updating it to 22.1.7... I'm getting the same problem.

Is it possible that you are using platform headers that are higher than android-28 to build the library? That's probably why it isn't running on my test device. I'll try to run it on newer versions of android to see if it still gives a problem there.

This answer may be of help.

JonasVautherin commented 3 years ago

Is it possible that you are using platform headers that are higher than android-28 to build the library?

You mean those values?

minSdkVersion 21
targetSdkVersion 29

My intuition is that "_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE" is a libc symbol (coming with C++17), and therefore I would expect the problem to come from the NDK version. Also, in my link above they talk about filesystem support coming with NDK 22. And I could reproduce the problem with an older NDK, and then it worked when I updated to NDK 22.

Now, maybe it also requires libmavsdk_server.so to be built with NDK 22. Let me try again...

divyanshupundir commented 3 years ago

I'll try to run it on newer versions of android to see if it still gives a problem there.

The same problem persists even with API level 29.

You mean those values?

I meant something like this.

Now, maybe it also requires libmavsdk_server.so

Yes, I was thinking the same. It had skipped my mind that libmavsdk_server.so was added externally and not built using NDK. (Please correct me if I'm wrong)

JonasVautherin commented 3 years ago

I think that mavsdk-server needs to be built with NDK 22 (and I failed that for mavsdk-server:0.8.0). I am publishing a new version mavsdk-server:0.8.1 which will be out on MavenCentral in a few hours.

In the meantime, if you want to try, you can try building it yourself: Build the android-client example after you have uncommented this line (so that it will fetch mavsdk:0.8.0 from MavenCentral, and it will build mavsdk-server using your NDK 22).

divyanshupundir commented 3 years ago

I am publishing a new version mavsdk-server:0.8.1 which will be out on MavenCentral in a few hours.

mavsdk-server:0.8.1 is working perfectly.

Thank you.

JonasVautherin commented 3 years ago

Awesome! @Katawann would you mind testing with mavsdk-server:0.8.1 as well?

Katawann commented 3 years ago

mmmh it's still failing to run with error java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE" referenced by "/data/app/com.modulesaero41-2/lib/arm64/libmavsdk_server.so"...

I'll try to find some time to do the modifications you proposed to build libmavsdk_server as well

JonasVautherin commented 3 years ago

@Katawann using the shared libc?

Katawann commented 3 years ago

@Katawann using the shared libc?

No the dlopen failed error happen if I change the arguments -DANDROID_STL=c++_shared to -DANDROID_STL=c++_static

If I use the shared libc, I failed back to the issue I have because I have multiple libc++_shared.so:

More than one file was found with OS independent path 'lib/x86/libc++_shared.so'. If you are using jniLibs and CMake IMPORTED targets, 
see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake

I gave more details few weeks ago in a post on the PX4 discussion forum

JonasVautherin commented 3 years ago

Ok, I'm sorry I'm not really active on discuss :innocent:.

If you don't mind, I'll close this issue (that became dedicated to the filesystem bug) and we can continue in MAVSDK: https://github.com/mavlink/MAVSDK/issues/1397.

divyanshupundir commented 3 years ago

I just updated the dependencies to 0.8.0 and I too am getting the same error. I'm not using react-native.

def mavsdk_version = "0.8.0"
implementation "io.mavsdk:mavsdk:$mavsdk_version"
implementation "io.mavsdk:mavsdk-server:$mavsdk_version"
Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE" referenced by "/data/app/<package>-gPP2YdUfzajwPSPZR8usKw==/base.apk!/lib/arm64-v8a/libmavsdk_server.so"...
        at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
        at java.lang.System.loadLibrary(System.java:1669)
        at io.mavsdk.mavsdkserver.MavsdkServer.<clinit>(MavsdkServer.java:6)

Things work perfectly fine with 0.7.0

I am facing the same problem with mavsdk-server:0.9.0

I think that mavsdk-server needs to be built with NDK 22 (and I failed that for mavsdk-server:0.8.0).

@JonasVautherin do you think it's the same problem as before? If yes, can you please publish the fixed version?

JonasVautherin commented 3 years ago

Hmm could be, though I thought that I had updated dockcross to use NDK22 :thinking:. I'll have a look ASAP!

JonasVautherin commented 3 years ago

I pushed 0.9.1, let me know if that's better :-). If yes, I think I found a way to solve that once and for all :+1:

divyanshupundir commented 3 years ago

Just tried and tested it. Works great.

Thank you.

JonasVautherin commented 3 years ago

Great, thanks for testing! FYI, the required ndkVersion is now set here, so I should not forget it anymore :wink:

nachod30 commented 3 years ago

I pushed 0.9.1, let me know if that's better :-). If yes, I think I found a way to solve that once and for all

Hello, I have the same error with react native app (dlopen failed: cannot locate symbol "_ZNSt6ndk14fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE"), I have compiled aar mavsdk server 0.9.0 with c++_static flag. Where can I found 0.9.1 version of mavsdk server? Thanks.

julianoes commented 3 years ago
echo "_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE" | c++filt
std::__ndk1::__fs::filesystem::__status(std::__ndk1::__fs::filesystem::path const&, std::__ndk1::error_code*)

Where did you get the mavsdk_server binary from?

JonasVautherin commented 3 years ago

I have compiled aar mavsdk server 0.9.0 with c++_static flag. Where can I found 0.9.1 version of mavsdk server?

That's the issue, you need 0.9.1. It is available with maven: https://mvnrepository.com/artifact/io.mavsdk/mavsdk-server.

It you want to build it, just take the latest state here, I would say.

nachod30 commented 3 years ago

@julianoes I compiled the main branch binary and it gave the above error. (https://github.com/mavlink/MAVSDK-Java/tree/main/mavsdk_server)

@JonasVautherin I just tried 0.9.1 , adding in gradle: implementation group: 'io.mavsdk', name: 'mavsdk-server', version: '0.9.1'

and it gave me an old error: More than one file was found with OS independent path 'lib/x86/libc++_shared.so'. If you are using jniLibs and CMake IMPORTED targets...

Any ideas or suggestions? Thanks.

JonasVautherin commented 3 years ago

I think that this is similar to what @Katawann was doing. Would you mind opening a new issue for that and tag @Katawann there?

divyanshupundir commented 2 years ago

This problem has returned when I tried to add the VLC Android dependency:

java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSt6__ndk14__fs10filesystem8__statusERKNS1_4pathEPNS_10error_codeE" referenced by "/data/app/~~_P1dshRgTSb_pMXk3WYdzw==/com.urbanmatrix.android.launchpad-MykqlwyrHRV-o-L0UFgDvQ==/base.apk!/lib/arm64-v8a/libmavsdk_server.so"...

The problem came earlier because MAVSDK-Java wasn't using the latest NDK. VLC apparently is using NDK 23.2 LTS (here).

julianoes commented 2 years ago

@divyanshu1234 so we should update the NDK version for mavsdk?

divyanshupundir commented 2 years ago

I did some tests and used a release with the updated NDK, and the problem persisted. I noticed that this problem comes only with the VLC NDK. It may be that it's a problem from their side only.

But we should shift to the LTD NDK anyway.