11

I’ve created simplest EXECUTABLE and SHARED_LIBRARY. SHARED_LIBRARY doesn’t get loaded without changing LD_LIBRARY_PATH:

# ./hello
./hello
link_image[1995]: failed to link ./hello
CANNOT LINK EXECUTABLE

# LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./hello
Hello, world!

All code below:

first.h

#ifndef FIRST_H
#define FIRST_H

extern int first(int x, int y);

#endif /* FIRST_H */

first.c

#include "first.h"

int first( int x, int y ) {
    return x + y;
}

hello.c

#include <stdio.h>
#include "first.h"

int main( int argc, char **argv ) {
    printf( "Hello, world!\n" );
    first( 1000, 24 );
    return 0;
}

Android.mk

include $(CLEAR_VARS)
LOCAL_MODULE    := first
LOCAL_SRC_FILES := first.c
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
LOCAL_SHARED_LIBRARIES := first
LOCAL_LDFLAGS := -Wl,-rpath,. -Wl,-rpath,/data/data/testlib/lib
include $(BUILD_EXECUTABLE)

readelf --all hello

...
Dynamic section at offset 0xef4 contains 25 entries:
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  INTERP         0x000154 0x00008154 0x00008154 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /system/bin/linker]
...
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libfirst.so]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x0000000f (RPATH)                      Library rpath: [.:/data/data/testlib/lib]

RPATH is here, but linker doesn’t use it for some reason.

Apparently dynamic linker works just fine on Android (with LD_LIBRARY_PATH and it’s no different RPATH either)

What do I do wrong?

Am I missing something obvious?

RPATH has two directories in my example, (.:/data/data/testlib/lib), one (.) should be sufficient.

There is no Java in this example. It’s not used and not needed for the project.

Basically I’m looking for a standard way to load shared libraries from "my directory" without changing LD_LIBRARY_PATH (it’s not possible sometimes) or using wrapper to dlopen all required libs.

Community
  • 1
  • 1
Same old guy...
  • 305
  • 1
  • 3
  • 15
  • Just to test my sanity, I run following on CentOS with same source files: `gcc -olibfirst.so first.c -fPIC -shared` `gcc -ohello hello.c -lfirst -L.` `./hello` ./hello: error while loading shared libraries: libfirst.so: cannot open shared object file: No such file or directory `gcc -ohello hello.c -lfirst -L. -Wl,-rpath,.` `./hello` Hello, world! Sorry, don't know how to format comment nicely. – Same old guy... Sep 28 '12 at 03:33
  • `readelf --all hello` `... Program Headers: Type Offset VirtAddr PhysAddr ... INTERP 0x0000000000000200 0x0000000000400200 0x0000000000400200 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] ... Dynamic section at offset 0x808 contains 22 entries: Tag Type Name/Value 0x0000000000000001 (NEEDED) Shared library: [libfirst.so] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 0x000000000000000f (RPATH) Library rpath: [.]` – Same old guy... Sep 28 '12 at 03:36
  • Have you tried leaving out `LOCAL_LDFLAGS`? – Olaf Dietsche Oct 23 '12 at 12:18
  • Removing LOCAL_LDFLAGS will remove RPATH setting from .SO *0x0000000f (RPATH) Library rpath: [.:/data/data/testlib/lib]* I.e. dynamic linker will use LD_LIBRARY_PATH only to find required .SO Or do you mean something else? – Same old guy... Oct 24 '12 at 15:29
  • No, since I have no clue, I'm just poking around. – Olaf Dietsche Oct 24 '12 at 16:00
  • One explanation is Andriod dynamic linker doesn’t support it RPATH attribute. But Googling shows it does support it to "some degree", "so to speak". Hopefully, it’s me doing something wrong, not dynamic linker ;-) – Same old guy... Oct 24 '12 at 17:39

1 Answers1

17

The Bionic linker-loader (android/bionic/linker/linker.c in the AOSP source, if you want to check) seems to completely ignore RPATH in the ELF. It only considers LD_LIBRARY_PATH and a hardcoded array of "/vendor/lib" and "/system/lib".

This is based on a cursory scan of the code on the Ice Cream Sandwich tree I have checked out.

This would explain the behavior you are seeing.

Yuriy Romanenko
  • 1,454
  • 10
  • 19
  • 1
    Is that what the message `WARNING: linker: ./program: unused DT entry: type 0x1d arg 0x78` related to which is the `0x0000001d (RUNPATH) Library runpath: [.]` attribute? – humanityANDpeace Mar 09 '16 at 10:20
  • 1
    Is it possible to add a library to LD_LIBRARY_PATH in android ? – RonTLV Sep 27 '18 at 11:13