Portable binary in RocksDB - c++

I compile my code using the following set of flags
LIBS += $(EXT_DIR)/librocksdb.a -lrt -lsnappy -llz4 -lz
where librocksdb.a is generated by
PORTABLE=1 make static_lib
I need to ship the binary to several tens of machines (all are ec2 machines with the same set of packages installed, same code/directory organisation structure).
When I try to run the code however (on the remote machine, not on the local one, where it works fine), I get the following error
Error in RockDB: Compression type Snappy is not linked with the binary.
When I compile remotely and use the binary from there, it also works fine. Libsnappy is installed on both machines.
Any thoughts on how I can fix this error and generate a binary that can be executed on multiple machines?

Use ldd ./yourapplication to check the library dependency on the remote machine.
Or build & install static snappy library before build your application.
I did this on an old machine, it works.

Related

Library errors after upgrading gcc versions. Unable to figure out what part of my code depends on libgmp

I'm upgrading a project from gcc 4.3 to 12.1 (a major jump) on Centos 7 & 6 - both 64 bit. As part of that I'm having trouble with what I suspect is an indirect dependency on a very old version of libgmp.
The submodule I'm compiling does not require any external libraries, however while running make I get the error:
gcc_12.1.0_path/cc1plus: error while loading shared libraries: libgmp.so.3: cannot open shared object file: No such file or directory
Google search does not turn out anything useful, issues that turn up are different than my case, my ld_library_path vars, lib paths are set correctly. libgmp v 3 is not available on my machine, and ideally I do not wish to install it, instead figure out where the dependency is and try upgrade it to use a more recent version of libgmp.
Even more confusing is, libgmp3 is not supported by centos 7 (or gcc 12). I'm not sure what part of compilation is dependent on this library, or how that part was successfully compiling with gcc 4 on centos 6.
The command for compilation is
g++_path -g -Wno-deprecated -D_DEBUG -fPIC -m64 -DLIN64BIT -I multiple_include_paths -o object_path -c source_file no -L inclusions
I wish to know two things:
In this case, what information should I provide to seek help?
Is there any tool for 2nd level or further (indirect) dependency
analysis? Would a c++ package manager help with such cases?
Is it possible to use libgmp v 3 built on another platform and copied to my lib path to resolve this (I do not have immediate access to such a machine or lib hence cannot check immediately)
Are there any suspects based on just the message and command?

Cross Compile Cannot Link Curl and Crypto

I installed arm-linux-gnueabihf via sudo apt-get install arm-linux-gnueabihf and i want to do cross compile for Raspberry Pi.
My make file is like that:
arm-linux-gnueabihf-g++ *.cpp *.h b64.c -o file -lcurl -lcrypto -lpthread -lssl
and an error occured like that:
/usr/arm-linux-gnueabihf/bin/ld: cannot find -lcurl
/usr/arm-linux-gnueabihf/bin/ld: cannot find -lcrypto
Also I tried to link with -L/usr/lib/x86_64-linux-gnu/libcurl.so but it is still same error.
Also i don't understand why libssl a is linked but others do not.
How can I link these libraries to arm-linux-gnueabihf?
Thank you.
You cannot link x86-64 bit libraries with arm-linux-gnueabihd.
You need to get gnueabihf libraries of curl and crypto.
One way: cross-compile curl and crypto libraries, use -L to specify directories where cross-compiled libcurl.so and libcrypto.so for gnuaebihf machine reside.
Another way: copy libcurl.so and libcrypto.so from raspberrypi onto your computer, specify directory where they reside with -L and try to compile, it should work.
ssl and pthread is linked, because you provide ssl and pthread libraries compiled for gnueabihf architecture. Look in /usr/arm-* for those files, probably in /usr/arm-linux-gnueabihf/lib.
Generally, for beginners, just compile your program on your raspberry pi (with curl and crypto installed), it will spare you much trouble.
The line -L/usr/lib/x86_64-linux-gnu/libcurl.so is invalid. You don't specify file using -L command line, you specify directory which contains libcurl.so. Also you specified directory with x86-64 architecture specific libraries while using gnueabihf compiler, they will not work, they are not compatible, no. You cannot link x86_64-linux-gnu/libcurl.so or any x86-64 library with a gnueabihf program.
The whole idea of crosscompiling is that you compile for another architecture. You don't mix those architectures, as they are not compitable with each other, just like you can't run x86-64 program on you raspberry pi, and you can't run a rapberry pi program on you computer. The machine codes of two architectures are not compatible with each other.
When you compile a program for gnueabihf architecture, you need to link gnuabihf libraries and use gnuabihf object files and use a compiler that will generate gnueabihf specific machine code. When you compile program for x86-64 machine, you need to link x86-64 libraries and use x86-86 object files and use a compiler that will generate x86-64 machine code.
Probably it may be also worth to you, use file command to determine file type. You may run file /usr/lib/x86_64-linux-gnu/libcurl.so to see that this libcurl.so is a x86-64 shared object.

How to build c++ with all dependencies to run on another machine

I wrote c++ code that in including some libraries that I included using -l option. The code is right on my machine but I want finally run this code on another machine named B. I built it on my machine using c++11 and GNU GCC Compiler and attempt to run it on machine B but it errors :
error while loading shared libraries: libcppkafka.so.0.1: cannot open shared object file: No such file or directory
How can I build c++ code with all dependencies to disappear this error?
note: libcppkafka.so.0.1 is in my machine in path /usr/local/lib
note: I use codeblock IDE, so I appreciate that if solution will be codeblock compatible
note: Both machines are ubuntu 16.04
In order to achieve your goal you have 2 options.
You can copy your shared libraries(libcppkafka.so) with your executable and configure its location correctly.
Or you can avoid shared libraries by statically linking them to your program. For this you'll need to have static version of those libraries (libcppkafka in your case)
Since both machines are running the same distribution and version (Ubuntu 16.04), you could find out on the first machine the installed and useful packages, and install these on the second machine.
You'll need to copy the non-packaged things, e.g. in (some part of) /usr/local/lib
You could consider making a real .deb package for your thing (but that is more work).
Notice that an IDE is just an IDE and don't compile anything (an IDE is running external compiler commands; your compiler is GCC invoked as g++). You should perhaps compile on the command line (and you could even make that some shell script, to run on the other machine).

Compiling Crypto++ for armhf for cross compiling

I want to cross compile the library crypto++ for deployment on a beaglebone running Debian. My host PC runs Ubuntu 14.04 LTS in a 64-bit configuration.
I face the following problem when I invoke the make command from eclipse
arm-linux-gnueabihf-g++-4.8 -L/usr/include/cryptopp -o "GCMwithAES" ./main.o -lcryptopp
/usr/lib/../lib/libcryptopp.so: file not recognized: File format not recognized
My guess is that since the compiler is configured for armhf, it cannot recognize the library that was compiled for amd64.
I have successfully cross compiled and run standard (ie no external libraries) programs from my host PC to my target device.
Solutions that I have tried
Used libcrypto++ packages with the architecture specified as armhf as done in multiarch. The armhf libraries get installed ( as per apt) but I am unable to include and link my code with them.
Manually try to compile the library as per the instruction given on this wiki. However, I always run into errors whenever I try to compile the library.
How do I install the libcryptopp libraries of the armhf architecture on my x64 based PC so I can cross compile? or is there any other way to resolve this issue.
Edit
As suggested in the answer below I tried out the method suggested. I slightly modified the script setenv-embed.sh since I had gcc-4.8 instead of gcc-4.7. The results of running the script are
CPP: /usr/bin/arm-linux-gnueabihf-cpp
CXX: /usr/bin/arm-linux-gnueabihf-g++
AR: /usr/bin/arm-linux-gnueabihf-ar
LD: /usr/bin/arm-linux-gnueabihf-ld
RANLIB: /usr/bin/arm-linux-gnueabihf-gcc-ranlib-4.8
ARM_EMBEDDED_TOOLCHAIN: /usr/bin
ARM_EMBEDDED_CXX_HEADERS: /usr/arm-linux-gnueabihf/include/c++/4.8.2
ARM_EMBEDDED_FLAGS: -march=armv7-a mfloat-abi=hard -mfpu=neon -I/usr/arm-linux-gnueabihf/include/c++/4.8.2 -I/usr/arm-linux-gnueabihf/include/c++/4.8.2/arm-linux-gnueabihf
ARM_EMBEDDED_SYSROOT: /usr/arm-linux-gnueabihf
I build the library using the make command and run into the following error
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc.so.6 inside /usr/arm-linux-gnueabihf
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/libc_nonshared.a inside /usr/arm-linux-gnueabihf
/usr/lib/gcc-cross/arm-linux-gnueabihf/4.8/../../../../arm-linux-gnueabihf/bin/‌​ld: cannot find /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 inside /usr/arm-linux-gnueabihf
But when I open the location /usr/arm-linux-gnueabihf/lib I can find all the three error files mentioned above ie libc.so.6, libc_nonshared.a and ld-linux-armhf.so.3
As per the suggestions of #jww, I'm shifting this to a new question since I'm having trouble linking. My results here are left for completeness.
How do I install the libcryptopp libraries of the armhf architecture on my x64 based PC so I can cross compile? or is there any other way to resolve this issue.
Checkout ARM Embedded (Command Line) on the Crypto++ wiki.
Note: that wiki page is a bit dated. You can now use GNUmakefile-cross. I have not updated the page to reflect recent changes like GNUmakefile-cross.
GNUmakefile-cross is a special purpose built for cross-compiling on Android, iOS, Windows Phone, ARM Embedded, and bare metal (I doubt anyone would do the later, but I tested it as a platform). You will still need to run the setenv-embedded.sh script.
To fetch the latest sources from GitHub:
git clone https://github.com/weidai11/cryptopp.git cryptopp-armhf
The GitHub sources are quite active at the moment. We are preparing for a Crypto++ 5.6.3 release. 5.6.3 will include
GNUmakefile-cross.
The complete instructions will look something like (assuming you have the tools installed):
git clone https://github.com/weidai11/cryptopp.git cryptopp-armhf
cd cryptopp-armhf
# Note the leading dot!!!
. ./setenv-embedded.sh
# The command above must execute successfully
# It cannot display a message like "**CXX is not valid**"
# Build it
make -f GNUmakefile-cross static dynamic cryptest.exe
# Check it
$ find . -name cryptest.exe
./cryptest.exe
$ /usr/bin/arm-linux-gnueabi-readelf -h ./cryptest.exe | grep -i 'class\|machine'
Class: ELF32
Machine:
Because the GitHub sources are quite active at the moment, I've already added all the other files from Crypto++-Mobile.zip and Setenv-embedded.sh.zip to the official Crypto++ sources. You only need to get setenv-embedded.sh out of the Setenv-embedded.sh.zip.
In addition to jww's answer, I wanted to add some further notes. (These notes are relevant for version 5.6.3 released 20-Nov-2015.)
It may be necessary to edit the config.h file to change some options. See Config.h on the Crypto++ wiki. In particular:
CRYPTOPP_NO_UNALIGNED_DATA_ACCESS may need to be defined so that the code operates properly on systems that can't do unaligned data read/writes (e.g. ARM).
CRYPTOPP_INIT_PRIORITY and CRYPTOPP_USER_PRIORITY may need to be defined. See Static Initialization Order Fiasco - Crypto++ Wiki for details.
CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562 may need to be defined or undefined, depending on whether the project using it is using older API features or not.
After building the library, it is very much worth running the test program cryptest.exe v on the target system, to check if the library has been built okay for that system. For example, by doing this, I discovered that the library doesn't work properly on the ARM-based BeagleBone Black unless I define CRYPTOPP_NO_UNALIGNED_DATA_ACCESS in config.h (it freezes indefinitely on the test step Testing MessageDigest algorithm SHA-384.).

undefined symbol: _ZL22__gthrw_pthread_cancelm error

I have a C++/C application which needs to be compiled as a 32 bit application (as there are certain third-party libraries only available for 32 bit). However, the compilation as well as the execution will happen on CentOS 6.4 x86_64 machine.
I am using gnu autotools for building. After doing a lot of googling, finally figured a sets of options to give to ./configure to create 32 bit executables/shared objects. Set the LD_LIBRARY_PATH to search in /lib, /usr/lib/, /usr/lib/gcc/... instead of /lib64, ... Verified that all the generated .so and executable are 32 bit by using file command.
But I get the error: "undefined symbol: _ZL22__gthrw_pthread_cancelm" if I run the executable.
Any clues?
It seems you forgot to link to pthreads with -lpthread.
GCC adds a layer of abstraction over pthreads and this abstraction use weak symbols, so you can build your executable without link error but fail at runtime.
Is there a 32bits pthread library on your target host? If not, I guess you need to get one installed. Also inspect the output of ldd <my-program> on your target host, this might help you find out what is missing.