#executable_path not working - c++

I have installed SDL2. I can link my program with
clang++ -lSDL2 -lv8 main.o test.o -o nano8
However, for distributing reasons, I'd like to give SDL2 away with the binary, and hence i've copied libSDL2-2.0.0.dylib under /myapp/lib/libSDL2-2.0.0.dylib
As for the documentation, #executable_path should allow me to link to that dylib instead of the one in /usr/local/lib, but if I run
clang++ #executable_path/lib/libSDL2-2.0.0.dylib -lv8 main.o test.o -o nano8
I get the error
clang: error: no such file or directory: '#executable_path/lib/libSDL2-2.0.0.dylib'
How to set the search path for a dylib?

This is a pain to get right.
I assume that /myapp can be anywhere in the filesystem, and want to load the library from #executable_path/../lib/libSDL2.dylib?
If so you have to use the Run Path and copy and modify the library during linking (this needs to be done every build):
cp /usr/local/lib/libSDL2.dylib build_dir/lib.
Change the install name of the .dylib using install_name_tool:
install_name_tool -change /usr/local/lib/libSDL2.dylib #rpath/libSDL2.dylib build_dir/lib/libSDL2.dylib
Link against build_dir/lib/libSDL2.dylib and set the rpath during linking:
cd build_dir/bin
clang++ obj_dir/main.o obj_dir/test.o -o nano8 -L ../lib -lv8 -lSDL2 -Xlinker -rpath -Xlinker "#executable_path/../lib"
I have not tested this and there is likely to be errors. Use otool -L to examine the library references in both the binary and the libraries in order to home-in on this issue.
A cleaner way:
Install your binaries into /usr/local/bin and provide any .dylibs to be installed into /usr/local/lib. This is better as /usr/local is the place for user-binaries and you don't need the faff above.

Related

Program compiles, but cannot run because of missing library that exists

I have an OpenGL program. I have all the include directories, and everything.
Directory Structure:
Main.cpp
Lib/
GL/
GLEW/
glm/
I compile the program by running:
g++ main.cpp -lGL -lm -lX11 -lpthread -lXi -lXrandr -ldl -I. -lglfw -Llib/ -o main -lGLEW
The error is on -lGLEW. The program compiles with no errors, but when I run ./main, it gives me this:
Error while loading shared libraries: libGLEW.so.2.2: No such file or directory.
This is confusing, as in my lib/ directory, libGLEW.so.2.2 is present, so is libGLEW.so and libGLEW.a.
Can someone please help me?
When running a dynamic linked executable, the linker must be able to find all the libraries it needs. It always searches
a list of fixed default paths like /lib and /usr/lib
additional paths defined by the environment variable LD_LIBRARY_PATH
any non-standard paths hard-coded in the binary by the -Wl,-rpath g++ option.
These are your options for making this non-standard library known to the runtime linker.
So either use export LD_LIBRARY_PATH=<somepath>/lib when running or use -Wl,-rpath=<somepath>/lib (with comma and without spaces) when building.

Xcode Library not loaded mosek (#loader_path)

I just downloaded the Mosek library and tried adding it to my project. I followed all the steps from the API and I managed to run the lo1 example using the provided Makefile
INCPATHS=-I../../platform/osx64x86/h -I.
LIBPATHS=-L../../platform/osx64x86/bin
MOSEKLIB=-lmosek64
CCOPT=
LDOPT=-Wl,-rpath,#loader_path/../../platform/osx64x86/bin -pthread -lSystem -lm -Xlinker -bind_at_load
CC=gcc -m64
LD=gcc -m64
lo1: lo1.c
$(CC) -c $(INCPATHS) $(CCOPT) -o lo1.o lo1.c
$(LD) $(LIBPATHS) lo1.o $(MOSEKLIB) $(LDOPT) -o lo1
install_name_tool -change #loader_path/libmosek64.7.1.dylib ../../platform/osx64x86/bin/libmosek64.7.1.dylib lo1
Now when I want to build my Xcode project, I get the error:
dyld: Library not loaded: #loader_path/libmosek64.7.1.dylib
Referenced from: /Users/John/Library/Developer/Xcode/DerivedData/quantstrat-cetdhtrlbbvomigzrlcbzwxogqwy/Build/Products/Debug/quantstrat
Reason: image not found
I have already added libraries in the past so this is how i proceeded :
In Build Phases I added the library to Link Binary With Libraries
In Build Settings I added the path to Library Search Paths
/Users/John/mosek/7/tools/platform/osx64x86/h
In Build Settings I added the path to Header Search Paths /Users/John/mosek/7/tools/platform/osx64x86/bin
I have been checking the web all day and I think what I'm missing is the install_name_tool in the MakeFile. What setting should I change to let Xcode know where the library is located?
Thanks,
John

How to create a dynamic library for c++ on linux?

I would like to create a dynamic library for c++ program on linux.
In c++ program/system I`m using libconfig++ library, libpqxx library, some boost and c++11.
My steps:
1)
g++ -Wall -I/usr/local/include/ -std=c++0x -lconfig++ -Wall -lpqxx -lpq -fPIC -c ../SourceFiles/DBHandler.cpp ../SourceFiles/ParamServer.cpp ../SourceFiles/Functions.cpp
2)
g++ -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
3)
ln -sf libctest.so.1.0 libctest.so.1
4)
ln -sf libctest.so.1.0 libctest.so
5) compile
g++ -Wall -I/path/to/include-files -L/path/to/libraries program.cpp -I/usr/local/include/ -std=c++0x -lconfig++ -lpqxx -lpq -lctest -o prog
After execute above command :
/usr/bin/ld: cannot find -lctest
collect2: ld returned 1 exit status
What am I doing wrong?
Here is the reference:
enter link description here
In step 5, you forgot -L. to look for libraries in the current directory.
By default, only a [long] list of system directories is used when searching for libraries.
You will also need to add . to the LD_LIBRARY_PATH environment variable before executing your program, so that the current directory is searched at runtime, too. Running ldconfig will avoid this, but if you are only testing your library and do not want to persistently affect your system, I would stick to the LD_LIBRARY_PATH approach.
An alternative is to "install" your library into one of those directories, such as /usr/local/lib (or your equivalent). You should use ldconfig after doing this, so that the dynamic library cache and all your symlinks are set up for you. This is the canonical approach but may not be suitable during iterative development of said library.
You need to ldconfig update the dynamic library cache -- it will also create the symbolic links for you.
See eg Section 3.5 of this Linux Documentation Project HOWTO

Linux - find the path of g++ lib

I installed these two libraries: glut and curl.
sudo apt-get install libcurl4-gnutls-dev
sudo apt-get install freeglut3-dev
when I have to compile a program I use:
g++ -o executable file11.cpp file2.cpp -lglut -lcurl
and it works!
How can I know where the linker search for "-lglut" or "-lcurl"?
"-lsomething" correspond to a path, How can I find out?
It checks /lib, /usr/lib, and any paths passed to -L.
The linker will look in directories specified by the -L option and in standard system directories, which are usually /lib and /usr/lib. Although you're not using any -L options GCC will usually pass some to the linker so it can find GCC's own libraries (e.g. the C++ standard library) unless you use -nostdlib. GCC will also add -L options for the contents of the LIBRARY_PATH environment variable.
To see the options GCC passes to the linker you can compile with -v (for verbose) and to see which libraries the linker uses you can pass -Wl,--trace to GCC, which causes it to pass --trace to the linker, which makes it output something like:
/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o
/tmp/ccJHrbSx.o
-lglut (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libglut.so)
-lcurl (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/libcurl.so)
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/libgcc_s.so)
/lib64/libc.so.6
(/usr/lib64/libc_nonshared.a)elf-init.oS
/lib64/ld-linux-x86-64.so.2
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.7.2/libgcc_s.so)
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crtn.o
This shows the libraries that were found for the -lglut and lcurl libs on my system. The libs are found in that path because on my system GCC passed -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64 to the linker (shown by compiling with -v)
You can canonicalize those paths using readlink
$ readlink -f /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/
/usr/lib64/
http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
It just turns the string into a filename, and checks normal locations for it, it seems.
Try
ldd /path/to/your/executable

-L option not working for mingw gcc

I am trying to get mingw gcc to work.
I need it to link with libopengl32.a.
Said file exists in C:/mingw/lib.
I used g++ as follows:
g++ -L"C:/mingw/lib" main.o -o test.exe -llibopengl32.a
It has no trouble finding the includes, it just complains that it can't find the library.
It seems unable to find any other library as well.
Also: I installed all the mingw components manually by downloading them from sourceforge, since using the automatic installer produced a broken installation on my system.
The -l flag automatically adds the lib prefix and the .a extension- you want:
g++ -LC:/mingw/lib main.o -o test.exe -lopengl32
Note you don't need the quotes around the path either. You could also just specify the whole library name & path:
g++ main.o -o test.exe C:/mingw/lib/libopengl32.a
As regards your installation problems, use either http://tdragon.net/recentgcc/ or http://nuwen.net/mingw.html - using the MinGW site itself is a recipe for pain.
You need to use -lopengl32 without "lib" and ".a"