streaming c++ program and shared libraries - c++

I have a C++ program which I am trying to run as a streaming job on hadoop (it has only mappers, no reducers). While a simple C++ program works correctly. Another C++ program which links with lot of shared libraries is not working on the grid. ldd on this C++ program shows following: (it uses lot of third party libraries like opencv and boost_serialization)
/usr/local/lib/libboost_serialization.so.1.48.0 /usr/local/lib/libfftw3f.so.3 /usr/local/lib/libconfig++.so.9 /usr/local/lib/liblog4cpp.so.4 /usr/local/lib/libopencv_core.so.2.3 /usr/local/lib/libopencv_contrib.so.2.3
I think because these shared libraries are not installed on data-nodes, its failing. I tried to put these libraries in a tarball and specified this to streaming job using -archives option (Distributed cache). This also did not work (I am not sure if contents from tarball were installed in the appropriate directory on data-nodes).
Any idea how to go about this?

Compile your C++ program statically. Basically:
g++ -o <progra> -static <object-files>
This will produce a binary that has no dependencies. It will be bulky (run strip on it!) but if it runs continuously you shouldn't have a problem.

Related

What are the binaries files needed to my SDL2 program so it works in another computer without SDL2 installed

What binary files I have to ship with my SDL2-based program so it can works on another computer without SDL installed?
Libraries required for my program:
iostream
SDL2/SDL.h
SDL2/SDL_image.h
ctime
cstdlib
Binary files which I already tried to use:
libSDL2.so
libSDL2-2.0.so.0.8.0
libSDL2_image.so
libSDL2_image-2.0.so.0.2.1
PS: I'm testing whether my program package works or not with a bootable Xubuntu pen drive
The short answer is "use ldd". The long answer follows.
ldd ./your_program will show recursive list of all runtime dependencies (yours and dependencies of every library you use, and their dependencies, ...).
readelf -d ./your_program | grep NEEDED will show your direct dependencies (only ones your program actually links against - doesn't necesserily mean you can copy only those).
LD_DEBUG envvar could be utilised to trace what libraries are loaded at runtime (e.g. with dlopen).
If you target one specific distribution it may be siplier to build package with dependencies specified so e.g. apt would install SDL for you.
Next big question is where did you get your SDL. Many distributions disables SDL dynamic loaders so it wouldn't run without e.g. libX11, wayland, libXi, pulseaudio, ... It is very much ok for that distribution to do so, as it was never intended you'll just copy some libraries to another machine. If you build it yourself you can have much less direct dependencies and SDL will try to dlopen whateven it needs. SDL2_image is probably easier example - it could depend on libjpeg, libpng, libz, ..., it is possible you don't need some formats but if you have linked with that libraries you can't run without them.
Consider what libraries you could consider 'always there'. E.g. it makes no sense to carry libX11 or libc and many others. This part is shared for all OS - you can't get half of OS with your program, for multiple reasons.
To sum it up, use SDL build with dynamic loading enabled (I think it is default for quite a time now), copy SDL/SDL_image, use LD_LIBRARIES_PATH to set your libs location, verify list with ldd, and you should be fine. Do not copy libc, libstdc++, libpthread, libm.

How does the GNU linker decide what C/C++ library files are needed?

I'm building PHP7 on an OpenWRT machine (an ARM router). I wanted to include MySQL, so I had to build that as well. OpenWRT is 99.5% ordinary linux, but there are some weird building / shared library things that probably don't get exercised often, so I've run into some difficulties.
MySQL builds OK (after some screwing around) and I have a libmysqlclient.so that works. However, the configure process for PHP7 fails when trying to link the MySQL test program, because libmysqlclient.so must be linked with the C++ standard libraries, not the C standard libs. (MySQL is apparently at least partially C++, and it uses std::...stuff....) Configure tries to compile the test program with gcc, which doesn't include the C++ libraries in the link, so the test fails.
I bodged over this by making a simple C/C++ switching script: if the command line includes -lmysqlclient then I exec g++ $* else exec gcc $*. Then I told configure to use my script as the C compiler.
It occurs to me that there must be a better way to handle this, though. It seems like libmysqlclient.so should have some way to tell the linker that it also needs libstdc++.so, so that even if gcc is used to link, all the necessary libraries would get pulled in.
Is there some way to mark dependencies in libmysqlclient.so? Or to make configure smarter about running test programs?
You should virtually never try to link with the C++ standard library manually. Use g++ for linking C++ programs. gcc knows the minute details of what library to use and where it lives, so you don't have to.
Now the question is, when to use g++, and when not to. One possible answer to that question is "always use g++". There is no harm in it. g++ can link C programs just fine. There is no overhead in the produced program. There might be some performance loss in the link process itself, but it probably won't be noticeable for any but the most humongous of programs.

open cv and c++ compile release without need library for run

first i have simple code with c++ and opencv
its no matter what is the code
now in windows i used visual studio and i add the open cv library to visual stuio and compile it and its work but when i send it to another pc its need open cv library its hard to send all library so i find the program need some files like
opencv_highgui2410.dll
..... .dll
opencv_objdetect2410.dll
that's make my program run without the library
now i turned to ubuntu linux after i compile with codeblocks
this photo will show you how i linker the library
and
and i build the program and run it its work now when i sent the program to another pc its give an error some files not found like
error while loading shared libraries: libopencv_core.so.2.4
i copy this file libopencv_core.so.2.4 and add it beside the program still same error seems not like windows
any solution made me compile opencv program and run program without need full library just some of its file
or any idea to add files (libs) that's project needed to run beside program just like windows
I think this should help you.
But from the comments, i fear you have very little linux experience, I hope this will help, anyway:
https://s1meonov.wordpress.com/2010/12/27/opencv-static-linking-gnulinux-gcc/
(first, be sure to understand what shared and static libraries, how they work and how they impact on software licenses, and also be sure to understand how to install programs in linux. For installing have a look at this link: http://www.makeuseof.com/tag/beginners-guide-installing-software-ubuntu-apt/)

Moving around the lblas library and using it with the g++ compiler

So on my current computer I Have a library to use BLAS functions, but I need to run my c++ program on an external server. I know how to transfer files to the server, but I'm having trouble figuring out how to find my blas library that's on my current computer and then how to link it to the compiler.
So here's the command I use current on my computer g++ program -lblas
And this works great. I run the program and everything is swell. How do I move this library to the external server?
Ideally, I'd like to move this library to the same folder as where my program resides and then link the compiler to that library somehow. Does anyone know how to do this?
If it helps, I know how to download a blas library and get a ".a" file out. I have no idea what to do from there though.
Never mind, simple question. I thought it was a lot more complicated.
For anyone that stumbles upon this, here's what you do:
Get your .a file. For me, I downloaded all the Makefile components necessary to make the .a file from here for blas: http://www.netlib.org/blas/
Next, put it in the same folder as your program if you want to do what I'm doing.
Finally, the command! Compiler, code, library
For me, this was g++ program.cpp blas.a

How can I compile a C++ project (with g++) to use on other computers?

This may be obvious, but I want to make sure what to do before I do anything rash. I want to compile my C++ program, libraries and all, to a release executable such that the file can be run on any computer (running the same OS). Right now, I'm on Mac OS X (10.7.4) and I need to be able to run my executable on other Macs. The problem is I am using the OpenCV library in my project, and I only have it installed on this computer. Is there a way to compile with g++ such that if I open this program on a computer that doesn't have the OpenCV library installed, it will work anyway? As in, build all the dependencies into the executable. Or does this happen automatically?
I am also quite new to the ".o" object files, so can those have anything to do with it? I would prefer a way to get it all into a single file, but I'll settle for a package as long as it works.
Thank you.
To expand on molbdnilo's answer, you'll need to create an application bundle (see the Apple Bundle Programming guide). You'll need to move your console application to MyApp.app/Contents/MacOS/MyApp. There's also a Frameworks directory in which you'll need to add the OpenCV library as a framework. See the OpenCV Wiki for some information on the OpenCV framework. A framework (at its simplest) is pretty much a dynamic library wrapped in a particular directory structure.
I would suggest looking into using Xcode on the mac as it simplifies the construction of bundles and linking to frameworks compared to doing it yourself via scripting and Makefiles.
There are two ways to do this. You can static link if you aren't going to run into licensing issues with any of the libraries you are linking to. This is pretty easily handled by using g++ -o myApp -static -lopencv myapp.cpp However, this also depends on static libraries existing for the libraries you want to link to. Most distribute static libs with the shared libs these days.
The other way is to distribute the shared libraries and tell your application to force it to look in a certain spot for the shared library using -rpath. Note: I am telling you the Linux way to do this, it will probably work on a Mac but I have no way to test.
So say all of your shared libraries are in the same directory as your executable, you can compile with: g++ -rpath ./ -lopencv -o YourApp yourApp.cpp
I hope this helps.