I've compiled a command-line tool against some C++ dynamic libraries using GCC 4.7 on Mac OS X 10.8. On the development system, the compiler was installed by MacPorts into /opt/local and the libraries reside in /usr/local/lib. The dynamic libraries are compiled from source alongside the program. (But they're built by cmake and I don't want to mess with that system.)
When I try to run it on another machine by putting the necessary dylibs into the executable's directory and DYLD_LIBRARY_PATH, it complains about an undefined symbol in the C++ standard library. It appears to be trying to load the older, builtin GNU standard library from /usr/lib/libstdc++.6.dylib.
How can I force the system to load the desired libstdc++?
Related
I am trying to do is produce a static MPI executable for Linux machines. The source code is written in C++. When I compile serial versions of the code, with gcc -static, and run ldd on the executable it shows no libraries.
However, when I try this with MPI, there are certain libraries that are not being statically linked. I have built my openmpi on my machine with see below shell commands. I also see that the exact same libraries that are not statically linking with the executable are not statically linking to the openmpi build. At the end of the openmpi build, I get
/home/bevan/Downloads/openmpi-4.0.1/opal/.libs/libopen-pal.a(dl_dlopen_module.o): In function `dlopen_open':
dl_dlopen_module.c:(.text+0x413): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/orte/.libs/libopen-rte.a(plm_rsh_module.o): In function `setup_launch':
plm_rsh_module.c:(.text+0xca2): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/opal/.libs/libopen-pal.a(if.o): In function `opal_ifaddrtoname':
if.c:(.text+0x1e4): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/orte/.libs/libopen-rte.a(ras_slurm_module.o): In function `init':
ras_slurm_module.c:(.text+0x6e4): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bevan/Downloads/openmpi-4.0.1/opal/.libs/libopen-pal.a(evutil.o): In function `evutil_unparse_protoname':
/home/bevan/Downloads/openmpi-4.0.1/opal/mca/event/libevent2022/libevent/evutil.c:758: warning: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
The sort of command chain I feel I should be using is,
tar -xvf openmpi-4.0.1
cd ./openmpi-4.0.1
./configure --prefix="$HOME/.openmpi" --without-memory-manager CXX=g++ CC=gcc LDFLAGS=--static --disable-shared --enable-static
make
sudo make install
export PATH="$PATH:$HOME/.openmpi/bin"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$HOME/.openmpi/lib/"
cd application/directory/build
cmake ..
make application
I would like to be able to run ldd application after compiling with MPI and have no dynamically linked libraries associated with the application.
In my C++ project, I'm compiling and linking against a library that makes use of OpenSSL.
I need to compile this project for my BeagleBone which has openssl installed by default. I have downloaded libssl-dev on my development machine.
Thus, I can compile the project fine if I'm compiling for my development machine on x86_64, but I am not able to successfully cross compile:
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lssl
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lcrypto
This indicates I need to have armhf binaries for OpenSSL, which seems a bit of a waste really since I have them on my BeagleBone if it can just be patient and wait until I deploy it.
Is the only way around this cross-compiling OpenSSL myself? Where would I then need to install the .so files (I guess make install would be a bad idea?)
This indicates I need to have armhf binaries for OpenSSL
Correct.
which seems a bit of a waste really since I have them on my BeagleBone if it can just be patient and wait until I deploy it.
You appear to think that shared libraries are only needed at runtime, but that is not the case.
ELF stands for executable and linking format. The .so is very much needed at static link time to construct various tables in the main executable, which will then be used by the loader at runtime to resolve references from the main executable to the .so.
If you are familiar with Win32, you can think of .so as a combination of Win32 .LIB and .DLL packed into a single file.
I want to cross compile my C++ application for ARM with cmake. Therefore I installed the arm-linux-gnueabi-g++ package on my ubuntu x86 system. However, this package does not contain all needed third party libraries for successful linking my C++ application. Example:
Ubuntu x86 system:
Contains basic stuff such as
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/libstdc++.so
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/libstdc++.a
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/libgcc.a
...
Target system (ARM):
Has further arm-specific packages installed which are needed if I would compile my application directly on the ARM-system. Therefore more libraries are available:
/usr/lib/libpq.so
/usr/lib/libpq.a
/usr/lib/arm-linux-gnueabi/libssl.so
/usr/lib/arm-linux-gnueabi/libssl.a
/usr/lib/arm-linux-gnueabi/libkrb5.so.3
Since the additional libraries are needed for cross compiling my attempt was to copy the required third party libraries manually from the target system to the x86 system. However, this ended up in a desaster since linking turns up messages such as "libssl.so -> requires lib B -> requires lib C which is missing".
How can I make these libraries available on my x86-system for cross compiling?
I am writing a program that uses the hashlib++ library (or will use it) but I don't want to add all of it's source files to my project because it's huge. Is there anyway to link to the hashlib++ source files so that I can use it in my project? I've tried linking to the header directly with a simple
#include "path/to/hashlibpp.h"
But I receive a nifty error for it as soon as I attempt to call any functions from the library. For example:
undefined reference to `sha1wrapper::sha1wrapper()
I am using the Code::Blocks IDE and GCC compiler.
First you have to have the library installed on your machine, already compiled into a static or dynamic library file. You can install from source, or you may find a pre-built package available for your OS (depending on which OS you are using). You will need to know the name of the library.
In the case of hashlib++ they have provided instructions to build a static library from source in their README; see section 3.2.
In most cases, dynamic linking is the best choice. This means that the library is linked with the library at run time, instead of adding the library to your executable when it is compiled (which would make your executable file much larger).
Unfortunately, according to their README.txt, hashlib is only available as a static lib, which limits your choices.
When compiling a program on the command line using gcc, the '-l' option links in a library:
gcc -o MyProg -lhl++ MyProg.c
When using an IDE like Code::Blocks, you normally have to specify the libraries to be linked. See this answer for details on how to do this with Code::Blocks.
I am working on a vision project using a beaglebone white. I am using an i686 machine running Ubuntu 12.04 LTS and the eclipse IDE with CDT plugin as my development machine. My beaglebone is running the latest Angstrom distro provided from beaglebone.org. My question has to do with general cross-compiling methodologies.
My program uses OpenCV and Curl c++ libraries.
So far on my host machine I have downloaded the latest OpenCV and Curl libraries and have crossed compiled them for the arm-linux architecture.
My test program compiles without errors on my development pc and generates an executable.
I use SCP to transfer the executable to the beaglebone over ethernet, and when I run my program I get the following error on the beaglebone:
"error while loading shared libraries: libopencv_core.so.3.0: cannot open shared object file: No such file or directory"
On the host computer OpenCV and Curl source and libraries are in two separate locations.
For OpenCV I used:
sudo cmake -DSOFTFP=ON -DCMAKE_TOOLCHAIN_FILE=../arm-gnueabi.toolchain.cmake ../../..
sudo make
sudo make install
which creates arm-compiled version of OpenCV in the /home/OpenCVArm/opencv/platforms/linux/build_hardfp/install/ on my host.
For Curl I used:
sudo ./configure --host=arm-linux-gnueabi --build=i686-linux CFLAGS='-Os' --with-ssl=/usr/bin/openssl --enable-smtp
sudo make
sudo make install
which creates the Arm compiled curl library is in /usr/local/ on the host.
to link all the libraries in my program I use the following script in Eclipse:
arm-linux-gnueabi-g++ -L/usr/local/lib -L/home/OpenCVArm/opencv/platforms/linux/build_hardfp/install/lib -L/usr/arm-linux-gnueabi/lib -o "HelloWorlTest" ./src/HelloWorlTest.o -lopencv_highgui -lopencv_core -lopencv_imgproc -lcurl
My questions are:
It appears I can get rid of my shared library error on the bone, by copying the appropriate libraries from my arm-compiled versions on the host to the target. So the target needs a copy of all libraries as well in order for the program to run. Since these are shared libraries and they are not included in the final executable, why do I need to compile the source for the target platform on the host in order to make the host linker happy? It appears the arm-compiled versions of the shared libraries are never used on the host. I initially thought it was so they would be packaged with the executable, but that is obviously incorrect.
If I copy the needed shared libraries from the host to the directory where the executable is stored on the target, the program still fails to find the shared libraries. The program will only run if I place a copy of the needed .so files in the /usr/lib/ folder on the target. What folders are searched for shared libraries when running an executable? Why won't it find shared libraries within its own local folder?
As I add more libraries to my project, what is the best way to manage them, and get them on the target. I really do not want to download the source on my host, cross-compile for arm, and then sift through all the libraries generated to only transfer the .so files I need on the bone. What is the proper way to provided the target with only the needed libraries for the executable? Is there a tool/plugin to manage or make this process automated?
How can I determine what are the required libraries irrespective of all the libraries I added to the eclipse linker?
If I wanted to tell eclipse to not use shared libraries how do I change the compile scripts for OpenCV, Curl, and modify eclipse so that static libraries are used instead?
When doing embedded programming, and cross-compiling is it more typical to use shared libraries or static libraries?
Thanks for the help.
You are just making the linker happy having the shared library on the host. It looks in the shared libraries to make sure the symbols your program uses are resolved. They are not linked in or used for anything else.
/lib and /usr/lib are the usual place to find shared libraries. You can add directories to the dynamic loader's search path by defining the LD_LIBRARY_PATH environment variable:
setenv LD_LIBRARY_PATH /home/me/lib:/home/me/lib2
I have no clue if there is some kind of tool/plugin for this. I use scp. ;-)
The ldd command will tell you what shared libraries an executable uses.
Good question. I've never built them. Often packages will build both shared and static libraries.
I don't know if is more typical to use shared libraries or not. I generally use static libraries. In my ELLCC cross compiler project.
I have used ELLCC to build itself. The resulting statically linked executables were actually smaller than the gcc compiled executable that uses shared libraries. Of course that is with an entirely different set of C++ and C standard libraries.