How to Change the Filename of a Shared Library After Building a Program That Depends on It

How can I change the filename of a shared library after building a program that depends on it?

HT - this might be helpful.

HT is a file editor/viewer/analyzer for executables. The goal is to combine the low-level functionality of a debugger and the usability of IDEs. We plan to implement all (hex-)editing features and support of the most important file formats.

I couldn't find something much different from ZorbaTHut's solution, but perhaps it's possible to put a name with different length and still keep the binary valid.

gelf - this could be useful too.

GElf is a generic, ELF class-independent API for manipulat-
ing ELF object files. GElf provides a single, common inter-
face for handling 32-bit and 64-bit ELF format object files.

Linking with an specific shared library using its filename with Scons

The items in the LIBS variable are meant to be the stem part of each of your libraries only. SCons will add a prefix and suffix (LIBLINKPREFIX and LIBLINKSUFFIX, respectively) to them automatically when compiling the final "link" command.

In your case you should simply add the "-l:kntlm.so" option to the variable LINKFLAGS directly:

env = Environment()

hello = env.Program(["hello.cc"], LIBPATH=['.'], LINKFLAGS=['-l:kntlm.so'])

Note, that this isn't platform-independent anymore...which is the whole point behind using the LIBS list under normal circumstances.

And yes, the User Guide tells you to not set a "-l" option via the "LINKFLAGS", but this is an exception from the default rule.

Finally, if you create shared libraries you'll have to use SHLINKFLAGS instead.

c- Use different shared libraries in the main program and the so loaded inside the program

Self-answer:

Use dlmopen with LM_ID_NEWLM flag to load mylib.so in the main program.

Moreover, to compile the main program, use -Wl,-rpath,/path-to/orig-openssl/lib for dynamic linking. In other words, you should set the rpath for the shared object and the main program.

How to resolve shared library location when it changes between compile & run time?


How can I resolve this

There are several ways.

  1. Rename foodependency.so to libfoodependency.so, and use -L../path/to -lfoodependency when linking, or
  2. Use -L../path/to -l:foodependency.so when linking, or
  3. When linking foodependency.so, add -Wl,--soname=foodependency.so and use your original link line.

forcing linking with a different SONAME than this of library

patchelf is your friend. You can do something like: patchelf --replace-needed libcapi10.so.3 libcapi10.so.4 <your_thing>.

Patchelf is useful for a variety of other things such as changing RPATH, too. Check out the manpage. Very nifty toy.

Adding an updated shared native library (.so file) to an Android Studio app leads to an UnsatisfiedLinkError

It turned out to be a problem with linking a versioned shared library in android studio. Similar as in this question and as described here.

The problem is that the internal version number of "libthird_party_library.so" is actually "libthird_party_library.so.2". This can be found by running objdump under linux on the .so file, that is:

objdump -p libthird_party_library.so | grep so

which outputs:

libthird_party_library.so:     file format elf64-little
NEEDED libm.so
NEEDED libc.so
NEEDED libdl.so
SONAME libthird_party_library.so.2
required from libdl.so:
required from libm.so:
required from libc.so:

Since the file name as seen by android is "libthird_party_library.so" and android tries to load "libthird_party_library.so.2" it can obviously not find the required library.

Solution

An obvious solution would be to change the filename to "libthird_party_library.so.2", but this doesn't work because android studio only includes libraries ending on .so in the apk (aaargh).

The solution is to change the internal version number to "libthird_party_library_2.so", renaming the file to "libthird_party_library_2.so" and changing the Cmake file to reflect this change.

1) Changing the internal version number can be done under linux with:

rpl -R -e libthird_party_library.so.2 libthird_party_library_2.so libthird_party_library.so

Where the first argument is the internal version number, the second the one we need to change it to and the third the filename. MAKE SURE THE LENGTH OF THE OLD INTERNAL VERSION NUMBER IS THE SAME AS THE NEW ONE!!

2) Change the filename to "libthird_party_library_2.so" using your favorite tool

3) Change this line in the CMake file to

set_target_properties( libthird_party_library PROPERTIES IMPORTED_LOCATION ${pathToProject}/src/main/jniLibs/${ANDROID_ABI}/libthird_party_library_2.so)

Hope this helps!

makefile with dependency on a shared library sub project

This is exactly what make is made for: manage a dependency tree. Just tell make that your library depends on its sources:

libmytest.so: mytestlib.cpp
g++ mytestlib.cpp -fPIC ... etc ...
cc -fPIC -Wl,-soname,libmytest.so ... etc...

With this extra piece of information make will compare the last modification times of the target and its prerequisites. If the target is missing or older than any of its prerequisites, make will rebuild it. And this is recursive. If a prerequisite is missing or itself out of date with respect to its own prerequisites, make will rebuild it first.

By the way, instead of a build target, which is not the name of a real file, it would be better to use directly the file name of the product:

test: libmytest.so
g++ test.cpp -lmytest.so

This way, if test is up to date (more recent than libmytest.so) make will not rebuild it. You will save time.

If you really want an alias for this, you can add a phony target:

.PHONY: build

build: test

All prerequisites of the special .PHONY target are treated differently: make knows that they are not real file names, even if a file named build exists, and that they must always be rebuilt. In this case, make will check that test exists and is up to date, rebuild test if needed, and stop here because there is nothing to do for build (it has no recipe). You can thus consider it as a kind of alias for test.



Related Topics



Leave a reply



Submit