How to use ported library in NaCl module? - c++

I want to use openssl library in my NaCl module. Luckily it is ported already as in https://code.google.com/p/naclports/. However, its kind of pity but I don't know how to add the library to the toolchain. I did as instructed in the Readme file:
...nacl_sdk/pepper_33/naclports/src$ python build_tools/naclports.py install openssl
Already installed 'openssl' [x86_64/newlib]
And then I tried to compile this simple C code, and the compiler complaint some errors which are because of linking problem with openssl/evp.h.
This is my Makefile: link. Please let me know how to make it run.

NaCl actually consists of several different toolchains. naclports will build and install a given library to just one of them at time. The libraries and headers get installed directly into the toolchain so there is no need to -L or -I on the command line.
In this case you have built and installed the x86_64 newlib version of openssl. This means that you should be able to build the x86_64 newlib version of your app (add TOOLCHAIN=newlib NACL_ARCH=x86_64 to your make call).
To build all the other versions of openssh you can use the "make_all.sh" script at the top level of naclports (e.g. ./make_all.sh openssl).

Build naclports. Look in naclports/README.rst for instructions.

Related

What is needed to use a newer version of GCC than the platform provides

I am looking at the potential to use a newer version of GCC (e.g. 5.2) than is provided by some of the platforms that I need to support (GCC 4.1) as I would like to at least have C++11 features, and maybe even some C++14 things. I just provide an executable program, not static or shared libraries that I expect users of the platform to be able to link with.
I was able to compile GCC 5.2 and Boost 1.59 (the only lib with a C++ API I am using currently) and get it working with the so's for those placed alongside the executable and adding $ORIGIN to RPATH on a test system which has 4.4.
But I am unclear on what else I need to do this fully and ensure everything is correct/safe. e.g. I noticed libc, libm, libpthread, etc. are not part of the GCC build, and it still uses the system version, as with many other third party libraries (e.g. zlib, libpng, etc.). Do I need to rebuild and distribute all those to be safe? Is their a standard set of rules to tell?
Also wondering if I should statically link some things and again what the rules are? e.g. just using "-static" fails because it goes looking for a static pthread that I don't have on that system (and I assume other system-provided libraries). Ideally I want to keep the size of my package down.
But I am unclear on what else I need to do this fully and ensure everything is correct/safe. e.g. I noticed libc, libm, libpthread, etc. are not part of the GCC build, and it still uses the system version, as with many other third party libraries (e.g. zlib, libpng, etc.). Do I need to rebuild and distribute all those to be safe? Is their a standard set of rules to tell?
Run ldd on your executables and shared libraries to make sure that it loads libstdc++ and libgcc_s from the correct location, if you link them dynamically. These are the only two dependencies normally required to run your applications built with g++.
Normally, you do not need to provide your own versions of libraries with C interface, unless your application requires newer versions with incompatible APIs.
Recent GCC compilers have a lot of dependencies.
On some distributions, you could ask for them : on Debian or related you might aptitude build-dep gcc (provided you have deb-src: in your /etc/apt/sources.list) which would dowload the build dependencies of the system's gcc (which might have a lot of common dependencies with the latest GCC).
Otherwise, GCC source code contain a contrib/download_prerequisites script which should be handy.
Read carefully the GCC building procedure. Don't forget to compile it outside of the source tree. You might want to pass --program-suffix=-5-mine to its configure
Of course you'll also need to build all the other software needed to compile (or to cross-compile) your code with the newly built GCC, including binutils, gdb, and perhaps a C library
Alternatively use a chroot (or some container à la docker) to install a newer Linux system...
I noticed libc, libm, libpthread, etc. are not part of the GCC build, and it still uses the system version, as with many other third party libraries (e.g. zlib, libpng, etc.). Do I need to rebuild and distribute all those to be safe?
No. If you build GCC on the system you want to deploy to then the GCC binaries and shared libraries will depend on the system versions of libc, libpthread etc.
If you then use that GCC to compile your software, and deploy the new libstc++.so.6 alongside your software (using $ORIGIN so it will be found), then it will still use the system versions of those libraries. Which is exactly what should happen and what you want to happen. Rebuilding them would achieve nothing and simply mean you have more libraries to deploy alongside your software.
Follow directions to build from source. Revise your question if you face a problem.
I think there is an easier way then compiling GCC yourself. [Unfortunately I figured that out after compiling it from source a number of time :) ]
For example in Ubuntu there is a PPA for precompiled GCC versions which are not there yet in the official repository.
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-5 g++-5
sudo update-alternatives
sudo update-alternatives --remove-all gcc
sudo update-alternatives --remove-all g++
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 20
sudo update-alternatives --config gcc
sudo update-alternatives --config g++

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.).

How can I link to an older version of a shared library

I'm building my program on my computer, on which libtiff.so -> libtiff.so.5.
And then pushing the builds on another machine on which libtiff.so -> libtiff.so.4.
At runtime, my program exists : « error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory ».
I cannot upgrade the other machine, and I would like to avoid compiling on a virtual machine (with the same linux version than the executing machine). Therefore, I would like to force the compiler to use the libtiff.so.4 instead of libtiff.so.5.
I have libtiff.so.4 installed on my computer (as well as libtiff.so.5). How can I force the linkage with this version instead of the newer version. I thought about moving the libtiff.so -> libtiff.so.4, but I'm afraid of breaking my system if it needs the latest version (apt-get purge libtiff5 gives an error because some other package needs it).
Is it possible to link with an older (installed) version of a library? If yes, how?
And is it harmfull to change the symbolic link of libtiff.so to the older version? If not, will it solve my issue?
You can use this syntax to link to a specific version of a library:
gcc [other options] -l:libtiff.so.4
You do not need to specify a path; the usual directories are searched in order to find the library.
Note: as Michael Wild mentioned, you should have the header files for that version installed instead of the newest ones.
As others have mentioned, you can force the linker by specifying the full versioned name, or even the absolute path.
However, I would strongly advice against doing so. The problem is, that the installed headers correspond to the newer version of the library. If there have been API/ABI-breaking changes between these library versions, the program might work, crash intermittently, or if you're lucky, not work at all.
Instead you should temporarily install the development package that corresponds to the libtiff.so.4 library. If on Debian/Ubuntu or similar, this would be the libtiff4-dev package.
Specify the full path to the .so: instead of -ltiff pass /lib64/libtiff.so.4 to the linker.
You see that error when application is running. So you can either stop your application and then exrract your library tar file. Or, force to link the lib file to the newer version after you extract. In second case, you will use something like:
ln -fs libversionname libfile
Example:
ln -fs libomyapp.1.1.3 libomyapp.lib
This links your libomyapp.lib to the version specified. This can be your older vsersion or your newer version.
But as said, best way to work is to bring down your application to properly match to the expected lib functionality to work without errors or issues.

How do you link to a library from the software manager on Linux?

So I recently got fed up with Windows and installed Linux Mint. I am trying to get a project to build I have in Code::Blocks. I have installed Code::Blocks but I need glew(as well as a few other libraries). I found it in the software manager and installed it. I've managed to locate and include the header files. But I feel like the next step should be relatively straightforward and all over the internet but (perhaps due to lack of proper terminology) I have been as of yet unable to locate an answer.
Do I need to locate the files on my system and link to each library manually? This is what I did on windows but I just downloaded the binaries and knew where they were. I found one library from the software manager and linked to it manually but it just feels like I'm doing it the wrong way. Since it's "installed" on the system is there some quick way to link?
You should use two flags for linker '-l' and '-L'. You can set these flags somewhere in project properties.
The first one '-l' tells linker to link with particular library. For example glew, probably in /usr/lib is a file named libglew.so, when you link your program with '-lglew' flag, it will link it with glew library. Linker looks for libraries in few standard places: /usr/lib, /usr/local/lib and few extra. If you have your libs in nonstandard place, use '-L' flag to point these dirs.
Many linux distributions provide two kinds of packages with libraries, regular ones just with runtime, and devel ones (usually prefixed or suffixed with dev or devel) with header files and development version of libraries.
use build systems, Luke!
the typical way to develop/build software in *nix world is 3 steps:
configure stage -- before building smth you have to realize in what environment you are going to build your software... is everything that required is installed... it wouldn't be good if at compile stage (after few hours of compilation) you (or user who build your soft) got an error: unable to #include the 'xxx.h'. the most popular build systems are: cmake, my favorite after autotools. yout may try also scons or maybe crazy (b)jam...
compile stage -- usually just make all
install stage -- deploy just built software into the system. or other way: build packages for target distro (.deb/.rpm/&etc)
at configuration stage using test scripts (don't worry there are plenty of them for various use cases) you can find all required headers/libraries/programs/compiler options/whatever you need to compile your package... and yes: do not use hardcoded paths in your Makefiles (or whatever you use to make your binaries)
Answer to this question really depends on what you want to achieve. If you want just to build you app by yourself then you can just write path to libraries in your makefile, or your code editor settings. You may not even have to do that as if libraries installed by your linux distribution package manager, headers usually go to /usr/include and libraries to /usr/lib or /urs/lib64 etc. That locations are standard and you do not need to specify them explicitly. Anyway you need to specify libraries you want to link to.
If you want to create application that can be build by others, or by you on many different configurations/environments using something like cmake would be very helpful.

How to install the program depending on libstdc++ library

My program is written in C++, using GCC on Ubuntu 9.10 64 bit. If depends on /usr/lib64/libstdc++.so.6 which actually points to /usr/lib64/libstdc++.so.6.0.13. Now I copy this program to virgin Ubuntu 7.04 system and try to run it. It doesn't run, as expected. Then I add to the program directory the following files:
libstdc++.so.6.0.13
libstdc++.so.6 (links to libstdc++.so.6.0.13)
Execute command:
LD_LIBRARY_PATH=. ./myprogram
Now everything is OK. The question: how can I write installation script for such program? myprogram file itself should be placed to /usr/local/bin. What can I do with dependencies? For example, on destination computer, /usr/lib64/libstdc++.so.6 link points to /usr/lib64/libstdc++.so.6.0.8. What can I do with this?
Note: the program is closed-source, I cannot provide source code and makefile.
If you're working on Ubuntu, making a .deb (Debian Package) seems to way to go. Here is a link to get you started.
Your package will state it depends on some other packages (typically the packages that includes libstdc++.so.6.0.13 - i guess the package name is something like libstdc++) and dependencies will be installed when you install your own package using dpkg -i <yourpackage>.deb.
Afterwards, you'll be able to uninstall it using dpkg -r <yourpackage>.
Anyway, never ship such standards files with your own archive. Dependencies exists for this exact purpose.
Hope it helps.
The real problem is that you try to install a binary that use newer versions os common libraries that the ones available on Ubuntu 9.10. The best option should be to make a specific target for the old Ubuntu 7.10 an compile it with the old libraries (that's a backport).
Then you should make two (or more) .deb packages, one for Ubuntu 9.10 and one for Ubuntu 7.10.
Another possibility is to continue doing what you are doing now : set LD_LIBRARY_PATH to point to the desired version of libstdc++ and other necessary libraries. You just set this environment variable in a launcher shell script. In you script you check if the new libraries are available or not and you set your LB_LIBRARY_PATH (say to /usr/local/lib/myprogram/) only if needed. But as others poster pointed out : that's a very bad practice. Anyway, never try to put these provided libraries at their standard place in Ubuntu 9.10, you would risk broking the target system and causing update problems for users or your program if these libraries are officially backported someday.
But if you choose to include your own set of system libraries there is still another way to go than the above one: just link these libraries statically. If a program is the only user of a library as it will probably be in the above scenario you'll lose all advantages of using a shared dynamic library, then why bother with using it at all ? And with stacically linked libraries you won't have to install them.