Linking with versioned shared library in Android NDK

后端 未结 3 1982
我在风中等你
我在风中等你 2021-02-04 18:57

I am trying to load two shared libraries in my Android application through the loadLibrary call:

System.loadLibrary(\"mywrapper\");
System.loadLibra         


        
相关标签:
3条回答
  • 2021-02-04 19:22

    It seems android has an issue with loading versioned libraries.The issue at hand was because of library so-name in my case libcrypto.so.1.0.0. Even if you rename the library and try to load it as a prebuilt shared library in an android make file it fails.( It has to be because the library name is somehow embedded in the file. And any library that links with it expects to be linked with a library of with the same name )

    I hope there are other ways out there when it comes to handling libraries with version names in android.

    For now I am evading the problem all together by using static libraries of openssl and linking them with my own shared library.

    0 讨论(0)
  • 2021-02-04 19:25

    Year 2014 and still no support for versioned shared libs. So I made a script to patch SONAME. Just point the script to input dir where all versioned libs placed. Then check output dir "unver".

    #!/bin/bash
    
    DIR="$1"
    
    if [ "$DIR" == "" ]; then
        echo "Usage: fix-soname.sh <target dir>"
        exit
    fi
    
    if [ ! -d $DIR ]; then
        echo "Not found: $DIR"
        exit
    fi
    
    OUT="$DIR/unver"
    echo "Input=$DIR"
    echo "Output=$OUT"
    
    CWD=$(pwd)
    cd $DIR
    
    # prep dirs
    mkdir -p $OUT
    rm -f -R $OUT/*
    
    # rename libs and copy to out dir
    find "$DIR" -type f -name '*.so*' | while read FILE; do
    
        NAME=$(basename "$FILE")
        SONAME=$NAME
    
        while read SYMLINK; do
            X=$(basename "$SYMLINK")
            #echo "$X (${#X}) -> $NAME (${#NAME})"
            if [ "${#X}" -lt "${#SONAME}" ]; then
                SONAME=$X
            fi
    done<<EOT
    `find -L $DIR -samefile $FILE`
    EOT
    
        #echo $SONAME
        cp -f $SONAME $OUT/
    done
    
    # patch libs in out dir
    find "$OUT" -type f -name '*.so*' | while read FILE; do
    
        # get file name without path
        NAME=$(basename "$FILE")
    
        # extract SONAME from shared lib
        SONAME=`readelf -d $FILE | grep '(SONAME)' | grep -P '(?<=\[)(lib.*?)(?=\])' -o`
    
        #echo "$NAME [$SONAME]"
    
        # patch SONAME if required
        if [ "$NAME" != "$SONAME" ]; then
            L1=${#NAME}
            L2=${#SONAME}
            LDIFF=$((L2-L1))
            #echo "$NAME [$SONAME] ($LDIFF)"
    
            if [ "$LDIFF" -gt "0" ]; then
                SONEW=$NAME
                for (( c=1; c<=$LDIFF; c++ )); do
                    SONEW+="\x00"
                done
                echo "$NAME [$SONAME] -> $SONEW ($LDIFF)"
                rpl -R -e "$SONAME" "$SONEW" $OUT
            fi
        fi
    done
    
    cd $CWD
    
    0 讨论(0)
  • 2021-02-04 19:30

    I had the same problem on building libwebsockets for Android, which needs to link with OpenSSL. I use libssl.so as example. You should do the same for related .so files.

    Before:
    huiying@huiying-PORTEGE-R835:~$ objdump -p libssl.so | grep so
    libssl.so:     file format elf32-little
      NEEDED               libcrypto.so.1.0.0
      NEEDED               libdl.so
      NEEDED               libc.so
      SONAME               libssl.so.1.0.0
    
    After 
    huiying@huiying-PORTEGE-R835:~$ rpl -R -e .so.1.0.0 "_1_0_0.so" libssl.so 
    Replacing ".so.1.0.0" with "_1_0_0.so" (case sensitive) (partial words matched)
    .
    A Total of 2 matches replaced in 1 file searched.
    huiying@huiying-PORTEGE-R835:~$ objdump -p libssl.so | grep so
    libssl.so:     file format elf32-little
      NEEDED               libcrypto_1_0_0.so
      NEEDED               libdl.so
      NEEDED               libc.so
      SONAME               libssl_1_0_0.so
    
    And don't forget to change file name "libssl.so" to "libssl_1_0_0.so".

    The hack works. I have running Android app to prove it. See my rant at http://computervisionandjava.blogspot.com/2015/05/trouble-with-versioned-shared-libraries.html.

    0 讨论(0)
提交回复
热议问题