1

My question is in relation to .so shared libraries. I am building a project that uses cmake on one ubuntu machine but running the application on another ubuntu machine.

In the CMakeLists.txt file, I have the following lines:

project (clientapp)

add_executable(${PROJECT_NAME} ${SOURCES} ${WAKAAMA_SOURCES} ${SHARED_SOURCES})

LINK_DIRECTORIES(/home/user//mraa-master-built/build/src)
target_link_libraries (clientapp libmraa.so)
target_link_libraries(clientapp m)

These lines add two libraries libmraa.so and the math library to the executable and it runs successfully on the other machine.

My understanding of shared libraries is that they must be present at compile time, and when the application starts. But I do not have the libmraa.so file on the other machine and the application runs ok. I expected it not to work.

Is my assumption correct?

artic sol
  • 349
  • 6
  • 18
  • Does your program make calls to routines in that .so for the usage you have tried? I am wondering if they only are needed when accessed, not on application startup. – Scooter May 24 '17 at 15:30
  • 1
    It could also be that your program does not actually need that library, despite it's presence in the build files. – Scooter May 24 '17 at 15:37
  • 1
    @Scooter sorry but the library is actually on the machine (I didn't install the library on it). Sorry for wasting your time with a silly question. But how does the application know where to find the shared lib on the machine because I don't specify the path? – artic sol May 24 '17 at 15:46
  • please update your question accordingly. – pynexj May 24 '17 at 16:02
  • I always set LD_LIBRARY_PATH (like PATH is for executables, LD_LIBRARY_PATH is for dynamic libraries) but the answer below mentions another way. – Scooter May 24 '17 at 16:12

2 Answers2

2

In general, gcc and clang support lazy linking/binding of symbols, but not for entire libraries. This means that all of the shared objects (ie: .so files) should be present at application startup, at a minimum. The one exception to this is if you modified your makefile to not link against these libraries, and you manually call library functions via dlopen()/dlsym(), etc.

The binding of individual symbols within those libraries can be postponed until they are needed, or you can force all the symbols to be resolved at startup, using -z lazy or -z now, respectively.

It is strange that your application runs without libmraa.so being present. The two most likely reasons your application is running in the absence of the library is:

  • Your application isn't using any symbols defined in the library, so the linker ignores the library at build time (try ldd app_name and see if your library is present in the list of libraries provided by ldd).
  • Something is amiss in your build script, and you are statically linking against a .a archive of the library.

Edit: In response to how the application knows how to find the library, your linker (ld in this case) will use rpath lookup to decide which directories to use in its search for the appropriate library. You can see how this works by doing something like LD_DEBUG=libs app_name from the command line. You can also add an extra path via LD_LIBRARY_PATH=/some/path app_name.

Cloud
  • 18,753
  • 15
  • 79
  • 153
1

Is my assumption correct?

Yes.

There are two likely explanations for why the application runs anyway:

  1. You are mistaken, and there is libmraa.so somewhere on the machine (though perhaps not in the place where you looked), or
  2. Your compiler defaults to -Wl,--as-needed by default, and your binary does not in fact depend on libmraa.so despite the fact that it appears on your link line.

You can trivially confirm or disprove either of the above guesses.

To confirm guess 2, do this:

readelf -d clientapp | grep NEED | grep libmraa
# if there is no output, guess 2 is correct

If guess 2 is wrong, to confirm guess 1, do this (on machine without libmrra.so):

ldd clientapp | grep libmraa.so
# if guess 2 is incorrect, and this command produces no output, then
# your dynamic loader is broken, which is very unlikely.
Employed Russian
  • 199,314
  • 34
  • 295
  • 362