Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compile source that uses dylib path on macOS Sierra from the shell

I'm compiling some source code that requires some dylibs from other project that I have already built. I'm getting

ld: symbol(s) not found for architecture x86_64`

Whenever I execute

g++ some_code.cpp -I/usr/local/include -o executable_binary

I know that g++ is not able to find the compiled the dylibs (installed at /usr/local/include) since the error also mentions a lot of specific symbols that are part of the dylibs.

I have already tried this:

  1. Executing install_name_tool -id "@/usr/local/lib/requiredlib.dylib" /usr/local/lib/requiredlib.dylib
  2. Adding -L/usr/local/lib to the compilation options.
  3. Adding all the dylib paths explicitly to the compilation options.
  4. Try to add DYLD_LIBRARY_PATH unsuccessfully since Sierra doesn't allow to set that variable for security reasons.

I know that it might possible to add DYLD_LIBRARY_PATH but that requires to disable SIP. I can do it by I do not want to if there is a cleaner way to do this.

P.S.: I am trying to compile the tutorial examples for Tulip graph library.

The missing symbols are related to the the graph library I have installed. The error message is:

Undefined symbols for architecture x86_64:
  "tlp::saveGraph(tlp::Graph*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, tlp::PluginProgress*)", referenced from:
      _main in tutorial001-02ee7e.o
  "operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, tlp::Graph const*)", referenced from:
      _main in tutorial001-02ee7e.o
ld: symbol(s) not found for architecture x86_64

Whenever I do ls /usr/local/lib/requiredlib.dylib the all the compiled libraries from Tulip are there.

g++ -v produces:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

After doing ls /usr/local/include/tulip/ I get the list of *.h files of the libraries I intend to use.

like image 434
JPCF Avatar asked May 04 '17 17:05

JPCF


2 Answers

In addition, you could also look into the undefined option of ld

Specifies how undefined symbols are to be treated. Options are: error, warning, suppress, or dynamic_lookup. The default is error.

That you would call like -Wl,-undefined,dynamic_lookup while compiling your binary.

You can also leverage -lazy-lx or -lazy-library path so that the library is not loaded until the first function in it is called, which might help in some cases.

Then add the rpath flag too, after having changed the name with install_name_tool like @macmoonshine showed, but make sure to point to the right path. By default Tulip is installed in the default library folder /usr/local but it's recommended in the install guide to do it in a user managed directory.

Something like the following command, for all the libraries required by tulip.

install_name_tool -change ./build-release/lib/libtulip-core-4.11.dylib '@rpath/libtulip-core-4.11.dylib' tutorial001

And also use -Wl,-rpath,./build-release/lib while compiling the tutorial.

like image 79
Preview Avatar answered Oct 25 '22 10:10

Preview


You can set the -rpath to search libraries. After linking your binary you have to modify the search path of the lib, e. g.:

g++ some_code.cpp -I/usr/local/include -o binary \
    -L/usr/local/lib -lrequiredlib -Wl,-rpath,/usr/local/lib
install_name_tool -change /usr/local/lib/librequiredlib.dylib \
    '@rpath/librequiredlib.dylib' binary

The install_name_tool command changes the name of the library in the binary such that the lib will be searched in the rpath. If you are unsure about the correct name, use otool -L binary to see all libraries linked with your executable.

See man page of ld and install_name_tool to get more information about rpath. install_name_tool can add more rpaths with -add_rpath as well.

like image 39
clemens Avatar answered Oct 25 '22 10:10

clemens