I'm trying to link a program with 2 libraries this way:
LNOPT = -Wl,-rpath,$(MKLROOT)/lib/intel64 -Wl,-rpath,/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin
However I either get one of these errors:
./dftb+: error while loading shared libraries: libmkl_gf_lp64.so: cannot open shared object file: No such file or directory
./dftb+: error while loading shared libraries: libiomp5.so: cannot open shared object file: No such file or directory
Depending on which -rpath I put first. How can I address this problem?
Is putting both paths (separated by :) in the environment variable LD_LIBRARY_PATH at runtime an option? (This way, the hard-coded rpath doesn't have to work.)
Example:
LD_LIBRARY_PATH=$(MKLROOT)/lib/intel64:/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin ./dftb+
Or put export LD_LIBRARY_PATH=$(MKLROOT)/lib/intel64:/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin in some profile rc file so that the library path is always set.
In either case, if there are already other paths which are needed in LD_LIBRARY_PATH add the above to it via LD_LIBRARY_PATH=$(MKLROOT)/lib/intel64:/opt/intel/compilers_and_libraries_2019.0.117/linux/compiler/lib/intel64_lin:$LD_LIBRARY_PATH instead of simply overriding LD_LIBRARY_PATH completely.
What could/should also work is sourceing the environment variable setup .sh files shipped with both the Intel compilers and the MKL, which, among other variables such as MKLROOT, should setup LD_LIBRARY_PATH pointing to both libiomp5.so and also the dynamic MKL link libraries.
Related
I am trying to use gurobi in OMNet++. I have included gurobi_c++.h and in order to detect this file, I have already told the compiler where it can find it and the libraries. To do so, I went to Makemake options, custom, Makefrag and added two lines: EXTRA_OBJS += -LC:/gurobi701/win32/lib and CFLAGS += -IC:/gurobi701/win32/include. The first contains the path to gurobi C++ libraries and second contains the path to header file gurobi_c++.h. I also added the path to the include file in the Includes section in Path and symbols part for GNU C++ and path to libraries to Library Paths.
Despite all these, when I compile it says undefined reference to error for all functions used from gurobi_c++.h. I can see that it detects gurobi_c++.h, but I still have those errors.
Any ideas on what may cause the problem?
contents of bin folder:
contents of lib folder:
You need to link with gurobi_c++ library file. Change EXTRA_OBJS into:
EXTRA_OBJS += -LC:/gurobi701/win32/lib -lgurobi_c++
assuming that the library is called libgurobi_c++.a or libgurobi_c++.dll.
i build and installed gcc-4.6.4 into my home dir (i don't have root proviliges).
When I link a few object files to an executable with g++, it links the "wrong" libstdc++.so.6.
It does not use the newer one wich is located in the install dir but the one of the system.
Is there a way to specify an exclusive search path for libraries?
My bashrc:
PATH=$PATH:/home/testuser/selfcompiled/gcc-4.6.4/bin:/usr/local/cuda/bin
export PATH
C_INCLUDE_PATH=/home/testuser/selfcompiled/gcc-4.6.4/include
export C_INCLUDE_PATH
CPLUS_INCLUDE_PATH=/home/testuser/selfcompiled/gcc-4.6.4/include
export CPLUS_INCLUDE_PATH
LIBRARY_PATH=/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib
export LIBRARY_PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/local/cuda/cudaprof/bin:/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib
export LD_LIBRARY_PATH
GCC_EXEC_PREFIX=/home/testuser/selfcompiled/gcc-4.6.4/lib/gcc/
export GCC_EXEC_PREFIX
COMPILER_PATH=/home/testuser/selfcompiled/gcc-4.6.4/bin/:/home/testuser/selfcompiled/gcc-4.6.4/libexec/:/home/testuser/selfcompiled/gcc-4.6.4/lib/gcc/
export COMPILER_PATH
Even if I specify the dir with the local libstdc++.so.6 via g++ -L...., the one located in /usr/... is linked to the executable according to ldd.
Thanks very much!
Nothing goes wrong when linking (or you'd get a linker error to symbols not present in the old library version).
This is a runtime thing. This:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/local/cuda/cudaprof/bin:/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib
export LD_LIBRARY_PATH
Should be
LD_LIBRARY_PATH=/home/testuser/selfcompiled/gcc-4.6.4/lib:/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib:$LD_LIBRARY_PATH:/usr/local/cuda/lib:/usr/local/cuda/lib64:/usr/local/cuda/cudaprof/bin
export LD_LIBRARY_PATH
The executable loader needs to look at your new libraries first, before it looks at the old ones. Of course, there is strong binary compatibility, so if no new symbols are used, the old libs will do just fine.
I am guessing you have built 64-bit executable. This path:
/home/testuser/selfcompiled/gcc-4.6.4/lib64/lib
looks wrong, and should likely be:
/home/testuser/selfcompiled/gcc-4.6.4/lib64
To use it, set LD_LIBRARY_PATH, or better use -Wl,-rpath=/home/testuser/selfcompiled/gcc-4.6.4/lib64
I have a collection of projects that I'm compiling as dynamic libraries. Each of these .dylibs depend on other various .dylibs that I would like to place in various other directories (i.e. some at the executable path, some at the loader path, some at a fixed path).
When I run otool -L on the compiled libraries, I get a list of paths to those dependencies but I have know idea how those paths are being set/determined. They almost appear pseudo random. I've spent hours messing with the "Build Settings" in Xcode to try and change these paths (w/ #rpath, #executable_path, #loader_path, etc.) but I can't seem to change anything (as checked by running otool -L). I'm not even entirely sure where to add these flags and don't really understand the difference between the following or how to properly use them:
Linking - "Dynamic Library Install Name"
Linking - "Runpath Search Paths"
Linking - "Other Linking Flags"
Search Paths - "Library Search Paths"
When I run install_name_tool -change on the various libraries, I am able to successfully change the run path search paths (again as verified by running otool -L to confirm).
I'm running Xcode 4.2 and I'm very close to giving up and just using a post-build script that runs install_tool_name to make the changes. But its a kludge hack fix and I'd prefer not to do it.
Where can I see how the search/run paths for the dylib dependencies are being set?
Anyone have any ideas on what I might be doing wrong?
Typically, in my dylib's target, I set INSTALL_PATH aka "Installation Directory" to the prefix I want (e.g. #executable_path/../Frameworks).
I leave LD_DYLIB_INSTALL_NAME aka "Dynamic Library Install Name" set to its default value, which is $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH).
Xcode expands that based on your target's name, so it might end up being #executable_path/../Frameworks/MyFramework.framework/Versions/A/MyFramework, for instance.
The important thing to realize is that the install path is built into the dylib, as part of its build process. Later on, when you link B.dylib that refers to A.dylib, A.dylib's install path is copied into B.dylib. (That's what otool is showing you -- those copied install paths.) So it's best to get the correct install path built into the dylib in the first place.
Before trying to get all the dylibs working together, check each one individually. Build it, then otool -L on the built dylib. The first line for each architecture should be what LD_DYLIB_INSTALL_NAME was showing you.
Once you have that organized, try to get the dylibs linking against each other. It should be much more straightforward.
install_name_tool is very useful for setting the names and paths. Its especially useful if the program runs its self-tests in the build directory, and then things change during a make install. In this case, you can use install_name_tool without the need for a separate build.
install_name_tool is also useful because Apple's LD does not honor rpath linker options like Linux/GCC does. That is, you need to use a different set of commands to set them.
Here's the man page for it. Its included in its entirety because it discusses other options, like -headerpad_max_install_names.
INSTALL_NAME_TOOL(1) INSTALL_NAME_TOOL(1)
NAME
install_name_tool - change dynamic shared library install names
SYNOPSIS
install_name_tool [-change old new ] ... [-rpath old new ] ...
[-add_rpath new ] ... [-delete_rpath new ] ... [-id name] file
DESCRIPTION
Install_name_tool changes the dynamic shared library install names and
or adds, changes or deletes the rpaths recorded in a Mach-O binary.
For this tool to work when the install names or rpaths are larger the
binary should be built with the ld(1) -headerpad_max_install_names
option.
-change old new
Changes the dependent shared library install name old to new in
the specified Mach-O binary. More than one of these options can
be specified. If the Mach-O binary does not contain the old
install name in a specified -change option the option is
ignored.
-id name
Changes the shared library identification name of a dynamic
shared library to name. If the Mach-O binary is not a dynamic
shared library and the -id option is specified it is ignored.
-rpath old new
Changes the rpath path name old to new in the specified Mach-O
binary. More than one of these options can be specified. If
the Mach-O binary does not contain the old rpath path name in a
specified -rpath it is an error.
-add_rpath new
Adds the rpath path name new in the specified Mach-O binary.
More than one of these options can be specified. If the Mach-O
binary already contains the new rpath path name specified in
-add_rpath it is an error.
-delete_rpath old
deletes the rpath path name old in the specified Mach-O binary.
More than one of these options can be specified. If the Mach-O
binary does not contains the old rpath path name specified in
-delete_rpath it is an error.
SEE ALSO
ld(1)
There is a laptop on which I have no root privilege.
onto the machine I have a library installed using configure --prefix=$HOME/.usr .
after that, I got these files in ~/.usr/lib :
libXX.so.16.0.0
libXX.so.16
libXX.so
libXX.la
libXX.a
when I compile a program that invokes one of function provided by the library with this command :
gcc XXX.c -o xxx.out -L$HOME/.usr/lib -lXX
xxx.out was generated without warning, but when I run it error like this was thrown:
./xxx.out: error while loading shared libraries: libXX.so.16: cannot open shared object file: No such file or directory , though libXX.so.16 resides there.
my clue-less assumption is that ~/.usr/lib wasn't searched when xxx.out is invoked.
but what can I do to specify path of .so , in order that xxx.out can look there for .so file?
An addition is when I feed -static to gcc, another error happens like this:
undefined reference to `function_proviced_by_the_very_librar'
It seems .so does not matter even though -L and -l are given to gcc.
what should I do to build a usable exe with that library?
For other people who has the same question as I did
I found a useful article at tldp about this.
It introduces static/shared/dynamic loaded library, as well as some example code to use them.
There are two ways to achieve that:
Use -rpath linker option:
gcc XXX.c -o xxx.out -L$HOME/.usr/lib -lXX -Wl,-rpath=/home/user/.usr/lib
Use LD_LIBRARY_PATH environment variable - put this line in your ~/.bashrc file:
export LD_LIBRARY_PATH=/home/user/.usr/lib
This will work even for a pre-generated binaries, so you can for example download some packages from the debian.org, unpack the binaries and shared libraries into your home directory, and launch them without recompiling.
For a quick test, you can also do (in bash at least):
LD_LIBRARY_PATH=/home/user/.usr/lib ./xxx.out
which has the advantage of not changing your library path for everything else.
Should it be LIBRARY_PATH instead of LD_LIBRARY_PATH.
gcc checks for LIBRARY_PATH which can be seen with -v option
I have created a new cocoa framework in Xcode, removed all the libraries and files it includes at the beginning except the supporting files.
I have 2 files:
add.h
#ifndef add_add_h
#define add_add_h
void add(void);
#endif
and
add.c
#include <stdio.h>
#include "add.h"
void add(void)
{
printf("adfding");
}
in build phases I add add.c to compile sources and add.h to compile headers public. The project build without a problem but in the framework there is no dylib file and when I drag and drop the framework to another project it says that dylib file could not be found.
dyld: Library not loaded: #rpath/add.framework/Versions/A/add
Referenced from: /Users/vjoukov/Desktop/Projects/test/build/Debug/test.app/Contents/MacOS/test
Reason: image not found
How can I make a simple framework and keep dylib files inside it ?
I think you're misunderstanding the error message.
A .framework works as a dynamic library, but there won't be any Mach-O loadable object file with an actual .dylib filename extension inside the .framework folder.
There are a couple of reasons you might be getting that error message from dyld, the dynamic link library loader, at runtime. The first is that you forgot to copy the .frameworks into the built application bundle during the build process. While they can be copied to about any location inside the app bundle, the traditional place is in AppName.app/Contents/Frameworks/. If you haven't done so already, choose Project > New Build Phase > New Copy Files Build Phase. Change the Destination popup to Frameworks like in the image below.
You'll then drag the icon of the framework into the folder so that it's copied during the build process.
The second and more likely reason the framework can't be found at runtime is that you haven't specified any runpath search paths for your main executable. (This is needed, because, as we saw from your error message, your framework was built using the newer #rpath/ style install name (#rpath/add.framework/Versions/A/add) rather than the older #executable_path/ or #loader_path/ styles).
Provided you copy the custom frameworks to the location mentioned above, you'd add a runpath search path entry of #loader_path/../Frameworks, like shown in the image below:
The following excerpt that explains how dynamic libraries are found at runtime is from the manpage of dyld:
DYNAMIC LIBRARY LOADING
Unlike many other operating systems, Darwin does not locate
dependent dynamic libraries via their leaf file name. Instead the
full path to each dylib is used (e.g.
/usr/lib/libSystem.B.dylib). But there are times when a full
path is not appropriate; for instance, may want your binaries to be
installable in anywhere on the disk. To support that, there are three
#xxx/ variables that can be used as a path prefix. At runtime dyld
substitutes a dynamically generated path for the #xxx/ prefix.
#executable_path/
This variable is replaced with the path to the directory
containing the main executable for the process. This is useful for
loading dylibs/frameworks embedded in a .app directory. If the
main executable file is at /some/path/My.app/Contents/MacOS/My
and a framework dylib file is at
/some/path/My.app/Contents/Frameworks/Foo.framework/Versions/A/Foo,
then the framework load path could be encoded as
#executable_path/../Frameworks/Foo.framework/Versions/A/Foo and the
.app directory could
be moved around in the file system and dyld will still be able
to load the embedded framework.
#loader_path/
This variable is replaced with the path to the directory
containing the mach-o binary which contains the load command using
#loader_path. Thus, in every binary, #loader_path resolves to a
different path, whereas #executable_path always resolves to the
same path. #loader_path is useful as the load path for a
framework/dylib embedded in a plug-in, if the final file system
location of the plugin-in unknown (so absolute paths cannot be used)
or if the plug-in is used by multiple applications (so
#executable_path cannot be used). If the plug-in mach-o file is at
/some/path/Myfilter.plugin/Contents/MacOS/Myfilter and a
framework dylib file is at
/some/path/Myfilter.plugin/Contents/Frameworks/Foo.framework/Versions/A/Foo,
then the framework load path
could be encoded as
#loader_path/../Frameworks/Foo.framework/Versions/A/Foo and the
Myfilter.plugin directory could be
moved around in the file system and dyld will still be able to
load the embedded framework.
#rpath/
Dyld maintains a current stack of paths called the run path
list. When #rpath is encountered it is substituted with each
path in the run path list until a loadable dylib if found. The
run path stack is built from the LC_RPATH load commands in the
depencency chain that lead to the current dylib load. You can
add an LC_RPATH load command to an image with the -rpath option
to ld(1). You can even add a LC_RPATH load command path that
starts with #loader_path/, and it will push a path on the run
path stack that relative to the image containing the LC_RPATH.
The use of #rpath is most useful when you have a complex
directory structure of programs and dylibs which can be installed
anywhere, but keep their relative positions. This scenario
could be implemented using #loader_path, but every client of a
dylib could need a different load path because its relative
position in the file system is different. The use of #rpath
introduces a level of indirection that simplies things. You
pick a location in your directory structure as an anchor point.
Each dylib then gets an install path that starts with #rpath and
is the path to the dylib relative to the anchor point. Each main
executable is linked with -rpath #loader_path/zzz, where zzz is
the path from the executable to the anchor point. At runtime
dyld sets it run path to be the anchor point, then each dylib is
found relative to the anchor point.