2

I'm trying to learn how to build and use dynamic library in a c++ program. Everything is fine and my program run well when I launch it from Terminal (I'm on a mac OS X El Capitan). Surprisingly that's not the case when I try to launch it by clicking on the executable. I get a dyld: Library not loaded: liblibrary.so, Reason: image not found error.

All my files are in a same repertory. I build them with commands :

g++ -c -fPIC A.cpp
g++ -c -fPIC B.cpp
g++ -shared -fPIC A.o B.o -o library.so
g++ main.cpp library.so -o Program

Thank's in advance for your help.

I tried the following solutions :

  • Add a PATH, both in LD_LIBRARY_PATH and DYLD_LIBRARY_PATH
  • Change the library extention : library.so or library.dylib
  • Add an rpath g++ main.cpp library.so -Wl,-rpath,. -o Program and g++ main.cpp library.so -Wl,-rpath,$HOME/my_dir -o Program
kipgon
  • 131
  • 14
  • 2
    When you run in from the command-line, are you in the same directory as the `library.so` file? That's why the system could find the library, because it's in your *current directory*. If it's not in the *current directory* then the system needs to find where the library is, which is done with the [`-rpath`](https://en.wikipedia.org/wiki/Rpath) **linker** option. – Some programmer dude Sep 26 '17 at 12:12
  • 1
    By the way, your main application doesn't have to be built with the `-fPIC` option, only the library. – Some programmer dude Sep 26 '17 at 12:12
  • Yes I was in the current directory but I previously tried `g++ -Wl,-rpath,. main.cpp library.so -o Program` to link with my current directory and nothing changed. – kipgon Sep 26 '17 at 13:03
  • 2
    The rpath should not be a relative directory, but some absolute path. Please **edit your question** to explain what has been tried – Basile Starynkevitch Sep 26 '17 at 13:05
  • 1
    After following your commands with a trivial program, `otool` reports that it refers to "library.so" (i.e., in `.`). Using `getcwd()`, I can see that OSX starts double-clicked programs in `~`, not the directory of the executable. You need to make your rpath reference relative to `@executable_path`. – Ssswift Sep 26 '17 at 16:02

2 Answers2

3

You may need to give an explicit rpath (as an absolute path, not a relative one) at compile time (e.g. with g++ -Wall -Wl,-rpath,$HOME/yourdir main.cpp library.so -o Program), or setup some DYLD_LIBRARY_PATH, see this. You could need a .dylib suffix, not a .so one.

(I don't have any MacOSX any more, so I forgot the details)

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

Finally, I found the solution. Actually, dynamic library creation is different for macOS. What I tried since the beginning is only working for Linux.

So the Mac solution is:

g++ -dynamiclib -install_name "absolute_path/library.dylib" A.o B.o -o library.dylib

where:

  • -dynamiclib is the Mac equivalent for -shared.
  • -install_name "absolute_path/library.dylib" create an alias of library.dylib for the linker which is necessary to use library.dylib.

After that, the traditional command:

g++ main.cpp library.dylib -o Program

creates the executable if main.cpp and library.dylib are in the same directory.

The program can then be used everywhere in the system as long as library.dylib stays in the same place.

Following the comment of @Ssswift, relative path linking can be achieved with the command:

g++ -dynamiclib -install_name "@executable_path/library.dylib" A.o B.o -o library.dylib

The library can then follow the executable.

Thanks for your help.

kipgon
  • 131
  • 14