Statically linking libtcod - c++

I'm trying to statically link libtcod to my C++ project without success. I get many linking errors, including:
./tuto: error while loading shared libraries: libtcodxx.so.1: cannot open shared object file: No such file or directory
Has anyone had similar problems with that library?

There are dynamic libs provided in current libtcod (1.6.0) distribution.
You can link libtcod dynamically, but you need to create symbolic links:
cd /var/lib/libtcod
ln -s libtcod.so libtcod.so.1
ln -s libtcodxx.so libtcodxx.so.1
Compile with following command:
g++ src/*.cpp -o tuto -I/var/lib/libtcod/include -L/var/lib/libtcod -ltcod -ltcodxx -Wl,-rpath=/var/lib/libtcod -Wall

Which flags do you use while linking to the library? Did you used -static flag, do you specified -ltcod? If not, add -static -ltcod to the end of command line.
Or you can force tell gcc to link with static builded library:
gcc %YOUR_OTHER_FLAGS_ANDFILES% -l:libtcod.a -L%PATH_TO_TCOD_STATIC_BUILDED_FILE%

Related

How to link to shared object library in msys2?

I have some c++ code in msys2 that I am trying to link dynamically to show how a dynamic link library works.
In linux, showing the call is no problem. stepping in gdb, we can watch the call go through the jump vector, eventually landing in the desired function.
But in msys2, they wanted to eliminated dlls and all the libraries I can find are .dll.a, I think they are really static libraries.
I build a trivial little function like this:
#include <cstdint>
extern "C" {
uint64_t f(uint64_t a, uint64_t b) {
return a + b;
}
}
compiling in the makefile with:
g++ -g -fPIC -c lib1.cc
g++ -g -shared lib1.o -o libtest1.so
When I run the file utility, it says that:
libtest1.so: PE32+ executable (DLL) (console) x86-64, for MS Windows
When I compile the code using it:
g++ -g main.cc -ltest1 -o prog
The error is -ltest1 no such file or directory.
MinGW uses the .dll extension for shared libraries, not .so.
lib??.dll.a is an import library, a shim that will load the corresponding lib??.dll at runtime.
At some point in time, you couldn't link .dlls directly, and had to link .dll.as instead. The modern MinGW can link .dlls directly, so you shouldn't need to use import libraries anymore.
-ltest1 no such file or directory
Wouldn't you get the same error on Linux? You have to specify the library search path with -L. -ltest1 needs either libtest1.a or libtest1.dll.a or libtest1.dll (perhaps some other variants are checked too).
The reason your linker cannot find the library is because your current working directory is not in the search path for libraries. Add -L. to your linking command.
It is untrue that MSYS2 "wanted to eliminate DLLs". Just run ls /mingw64/bin/*.dll and you will see plenty of DLLs (assuming you have some MINGW64 packages installed). The .dll.a files used for linking are called import libraries.

g++ link against static library does not work

I have a simle file main.cpp and static library MyLib.lib and I am trying to link program against static library like this:
g++ -o m main.cpp -static -L c:\lib\path -l MyLib
or like this:
g++ -o m main.cpp -L c:\lib\path -Wl,-Bstatic -l MyLib -Wl,-Bdynamic
The compilation process exits successfully and without error. However when I try to run m.exe from command line I get error that it cannot be run because MyLib.dll cannot be found.
I specificaly said it should compile against static lib MyLib.lib so why is it searching for a dynamic library? Did I made an error in commands above?
It really looks like you linked with a shared library.
You need to add the location of the folder containing MyLib.dll to the PATH.
In a Command Prompt type this:
SET PATH=<dll_location>;%PATH%
m.exe
or make sure MyLib.dll is in the same folder as m.exe.
If gcc only finds a shared library there is a chance the static flags didn't work.
Why is your library not called libMyLib.a? The name MyLib.lib seems to imply you got it prebuilt from MSVC. If so, how do you know MyLib.lib is not a shared library?
Is there a way you can build MyLib yourself as a static library?

How can I override shared library in LD_LIBRARY_PATH with clang++?

I'm trying to compile a shared library I wrote in C++ to use a specific version of another shared library in the current directory, however it seems to be ignoring that and it uses the (older and incompatible) .so file in my LD_LIBRARY_PATH at runtime. How would I go about overriding the .so file it uses to use my own? I also need to retain the older version for another use on the same system.
Here's my command I'm using to compile: clang++ /data/openpilot/selfdrive/df/libs/libSNPE.so -lsymphony-cpu -lsymphonypower -I/data/openpilot/phonelibs/snpe/include -std=c++14 -lstdc++ -fPIC -o d_f.so dynamic_follow.cc -shared
/data/openpilot/selfdrive/df/libs/libSNPE.so being the library I want to use.
I also tried to use the -l flag before my library file, however it returns cannot find -l/data/openpilot/selfdrive/df/libs/libSNPE.so
Confirmed to still use the library in LD_LIBRARY_PATH with this command as well: clang++ -Wl,-rpath,/data/openpilot/selfdrive/df/libs -L/data/openpilot/selfdrive/df/libs -lSNPE -lsymphony-cpu -lsymphonypower -I/data/openpilot/phonelibs/snpe/include -std=c++14 -stdlib=libc++ -fPIC -o d_f.so dynamic_follow.cc -shared
The -L flag tells where to look for libraries at link time, while LD_LIBRARY_PATH tells where to look for libraries at run-time. So whatever path you set at link-time, this will be ignored when running the executable.
You need to have LD_LIBRARY_PATH include the directory of your dynamic library at run-time for your executable to find it. So you may run your executable like this:
LD_LIBRARY_PATH=/data/openpilot/selfdrive/df/libs:"$LD_LIBRARY_PATH" ./your-exec

Can't make executable portable

I made a little c++ program with this library: http://libtins.github.io
I compile with: g++ -o arp arp.cpp -ltins
It runs fine (Ubuntu 14.04 64 bit), however if i send the executable to a friend, he gets this error when running:
error while loading shared libraries: libtins.so.3.4: cannot open shared object file: No such file or directory
I've looked up on stackoverflow and found something about statically linking and dynamically linking, also tried some g++ arguments but no success.
Is it even possible, to create a binary that "contains" the shared object itself?
Thanks
You can use -static to link the libraries statically.
g++ -o arp arp.cc -ltins -static
To build libtins statically, you could refer to the following section in its README:
Static/shared build
Note that by default, only the shared object is compiled. If you would
like to generate a static library file, run:
cmake ../ -DLIBTINS_BUILD_SHARED=0

Executing cross-compiled C++ program using Boost on Raspberry Pi

I have built a GCC cross toolchain for the RPi and can cross-compile C++ source and successfully run it after copying the executable to the RPi.
Next I built the Boost libraries targeting ARM, using the cross toolchain. I can successfully build and link C++ source to those Boost libraries using the cross toolchain on my PC.
I then copied the program, dynamically linked to Boost, to the RPi and copied all built libraries into /usr/local/lib on the Pi. However, executing fails:
$ ./my_program
./my_program: error while loading shared libraries: libboost_system.so.1.60.0: cannot open shared object file: No such file or directory
Again, this library, libboost_system.so.1.60.0, exists in /usr/local/lib.
I also tried
export LD_LIBRARY_PATH='/usr/local/lib'
but that doesn't change anything. What am I doing wrong?
EDIT:
I build all source files like this (rpi-g++ is a symlink to my cross-compiler):
rpi-g++ -c -std=c++1y -Wall -Wextra -pedantic -O2 -I /path/to/cross/boost/include *.cpp
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -lboost_system -pthread
EDIT 2:
When linked with
rpi-g++ -o myprog *.o -L /path/to/cross/boost/lib/ -rdynamic -lboost_system -pthread
the problem remains the same. I have checked and verified everything suggested by Technaton as well. Strangely, ldd insists that the created executable is "not a dynamic executable" (checked that on my PC and on the RPi), which doesn't make sense to me.
There are several things you can check. I've posted a complete check list here, but judging from your linker command line, number 5 is probably the culprit.
Check that your library and your program are correctly build for the target architecture. You can verify that by using file ./myprog and file libboost_system.so.1.60.0.
Make sure that you have copied the actual shared object, and not a link to it.
Ensure that the shared object file's permissions are sane (0755).
Run ldconfig -v and check that your shared object file is picked up. Normally, /usr/local/lib is in the standard library search path, and LD_LIBRARY_PATH is not required.
Make sure that your program is actually dynamically linked by running ldd ./myprog. Judging from your linker command line, that is the problem: You're missing -rdynamic.
Check the paths returned from ldd: If you have linked with rpath, the library search path might be screwed up. Try again without -rpath.