Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to change the embedded rpath of shared library (.so)?



  • We have libqtforandroid.so here, right?
    \qtbase\src\plugins\platforms\android

    In this shared library, it has a rpath embedded as below:

    $ aarch64-linux-android-readelf.exe -d libqtforandroid.so
    
    Dynamic section at offset 0x102df8 contains 37 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libjnigraphics.so]
     0x0000000000000001 (NEEDED)             Shared library: [libandroid.so]
     0x0000000000000001 (NEEDED)             Shared library: [libc++_shared.so]
     0x0000000000000001 (NEEDED)             Shared library: [liblog.so]
     0x0000000000000001 (NEEDED)             Shared library: [libz.so]
     0x0000000000000001 (NEEDED)             Shared library: [libm.so]
     0x0000000000000001 (NEEDED)             Shared library: [libdl.so]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so]
     0x0000000000000001 (NEEDED)             Shared library: [libEGL.so]
     0x0000000000000001 (NEEDED)             Shared library: [libQt5Gui.so]
     0x0000000000000001 (NEEDED)             Shared library: [libQt5Core.so]
     0x0000000000000001 (NEEDED)             Shared library: [libGLESv2.so]
     0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so]
     0x000000000000000e (SONAME)             Library soname: [libqtforandroid.so]
     0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../../../lib]
    

    0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../../../lib]

    I traced to the Makefile, which is generated by qmake.

    LFLAGS        = --sysroot=D:/android/android-ndk-r16b/platforms/android-27/arch-arm64/ -Wl,--no-undefined -Wl,-z,origin -Wl,-rpath=\$$ORIGIN/../../../lib -Wl,--no-undefined -Wl,-z,noexecstack -shared -Wl,-soname,libqtforandroid.so
    

    My question is where and how "../../../lib" is determined? What do I do if I want to change it? Thank you.


  • Moderators

    Paths are embeded into .so files, that's just how Qt works, even though it is a pain in the rear end.

    You can use qt.conf to get around it. And/ or use standard Qt directory layout, just like windeployqt, androiddeployqt, macdeployqt and linuxdeployqt are using.

    Why do you need to change it?



  • @sierdzio
    I am having strange UnsatisfiedLinkError error when loading libqtforandroid.so.

    The logs look like:

    01-01 05:33:19.616  4412  4412 D QtJAVA  : Try to load /vendor/app/MyQtApp/plugins/platforms/android/libqtforandroid.so
    01-01 05:33:19.624  4412  4412 E QtJAVA  : UnsatisfiedLinkError '/vendor/app/MyQtApp/plugins/platforms/android/libqtforandroid.so'
    01-01 05:33:19.624  4412  4412 E QtJAVA  : java.lang.UnsatisfiedLinkError: dlopen failed: library "libQt5Gui.so" not found
    

    The libQt5Gui.so locates at /vendor/app/MyQtApp/lib/arm64.

    libqtforandroid.so depends on libQt5Gui.so. It is understandable that linker tries to load libQt5Gui.so.
    It seems that linker doesn't append 'arm64' on the rpath. I am not sure about that, so I want try setting rpath to $ORIGIN/../../../lib/arm64.

    There is another mystery. Why does linker try to load libQt5Gui.so again when libQt5Gui.so has been loaded in the same function (qt\qtbase\src\android\jar\src\org\qtproject\qt5\android\QNative.loadQtLibraries())?
    The loading events just happen in the same for loop.



  • In qcoreapplication.cpp, I see this comment:

        The return value of this function may change when a QCoreApplication
        is created. It is not recommended to call it before creating a
        QCoreApplication. The directory of the application executable (\b not
        the working directory) is part of the list if it is known. In order
        to make it known a QCoreApplication has to be constructed as it will
        use \c {argv[0]} to find it.
    
        Qt provides default library paths, but they can also be set using
        a \l{Using qt.conf}{qt.conf} file. Paths specified in this file
        will override default values. Note that if the qt.conf file is in
        the directory of the application executable, it may not be found
        until a QCoreApplication is created. If it is not found when calling
        this function, the default library paths will be used.
    

    Unfortunately, for an Android application, the QtLoader in Java level loads libraries before the QCoreApplication is created.
    I doubt that qt.conf would help on this matter.


Log in to reply