Weird things with libCurl and OpenSSL - c++

It's me again. I just can't understand, why it goes that way!
I downloaded compiled static libs of OpenSSL, from here, this link is on the official cUrl site in Download page. I downloaded Zlib and compiled them, then I compiled libcurl with
mingw32-make mingw32-ssl-zlib
I changed in all makefile.m32 pathes to the Zlib and OpenSSL files. All went fine, I recieved libcurl.a and libcurldll.a. I added into lib folder of my project libcurl.a and libeay32.a, libssleay32.a and libz.a.
I built project - it says that everything is fine. I run - and it just terminated. I'm using MinGW and Eclipse.
It is compiled with this:
g++ -DCURL_STATICLIB -O0 -g3 -Wall -c -fmessage-length=0 -osrc\main.o ..\src\main.cpp
g++ -L..\lib -oYTUploader.exe src\main.o -lcurl -lws2_32 -lwldap32 -leay32 -lssleay32 -lz
I run DependencyWalker, and it says that it's missing ieshims.dll, libeay32.dll and ssleay32.dll. But WHY? Why it want OpenSSL dll, I'm using static linking! I built static libCurl library, with static libs of OpenSSL. About ieshims.dll I also can't get why it needs it!
Help, please, I have no idea what is wrong! I compiled cUrl according to the instruction, everything should be fine..

The openssl-libs you link against seem to be import-libraries. That means they only contain the information your code needs to call functions and then load and call the corresponding functions from the dll.
So the problem is: although you link to static libs, the libs then load and use dynamic dlls. They are no "real" static libs.
One solution is getting other libs (or compile them yourself), or even easier: you just copy the dlls into the directory where your .exe resides and you should be fine.

Use the configure script to tell ld where openssl has installed the files. the defaults are as follows:
tar -zxf curl-7.33.0.tar.gz
cd curl-7.33.0
./configure --prefix=/opt/curlssl --with-ssl=/usr/local/ssl --enable-http --enable-ftp LDFLAGS=-L/usr/local/ssl/lib CPPFLAGS=-I/usr/local/ssl/include
make
make install

Related

Can't use static lib of mongo-cxx-driver on Linux

So I follow the official tutorial for the installation : https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/installation/
Neverless, I can't use the produced libraries as static.
So I managed to compile the C version of the driver as described, I've enabled the flag --enable-static=yes with the ./configure before doing make && sudo make install and I got the libmongoc-1.0.a and the libbson-1.0.a which are static. So this far, everything it's alright.
Then I have done the cxx version of the driver, except that there is no configuration file as in the C version. So I've juste done a
cmake -DCMAKE_BUILD_TYPE=Release -DBSONCXX_POLY_USE_BOOST=1 -DCMAKE_INSTALL_PREFIX=/usr/local
from the build folder, followed by a make && sudo make install
So I got the libmongocxx.a and the libbsoncxx.a, but when I try to compile with them, I can't run the binary because I got the following error :
error while loading shared libraries: libmongocxx.so._noabi: cannot open shared object file: No such file or directory
So I understand that is because there is some symbols missing and then I need to use the shared library to run the binary but I don't want this to happend, I want the symbols within the binary that I can run it without any LD_PRELOAD.
Any suggestions ?
I had the same issue in an Ubuntu 16.04 and I run a apt-get update & apt-get upgrade and the problem was solved.
It seems that there were some update to the compiler and some libraries that prevent some test from reaching the shared libraries.
I have a similar question, and solved, now I compiled and run my binary with static libs successfully.
I write my build script using newlisp, but the static link options are very helpful, I paste it here.
c++ /to/your/path/site/code/back_end/builder/object/files1.cc.o ... /to/your/path/site/code/back_end/builder/object/files10.cc.o -o bin/site -static-libgcc -static-libstdc++ -L/usr/lib -lpthread -l:libmongocxx.a -l:libbsoncxx.a -l:libmongoc-1.0.a -l:libbson-1.0.a -lrt -lssl -lcrypto -lsasl2 -l:libboost_log.a -l:libboost_log_setup.a -l:libboost_system.a -l:libboost_thread.a -l:libboost_filesystem.a -lcppcms -lbooster -lcurl -ljsoncpp

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.

Linking OpenSSL into a dynamic library

I'm trying to static link OpenSSL into my program.
It works fine when linking into the executable. I need to use OpenSSL in a shared library (so, or dll) that I dynamically load later on when the process executes.
Trying to statically link OpenSSL into the shared library causes errors due to OpenSSL not being compiled with -fPIC. Is it possible to do this without recompiling openssl?
Also, is there a better way to do this?
I'm trying to static link OpenSSL into my program.
In this case, its as simple as:
gcc prog.c /usr/local/lib/libssl.a /usr/local/lib/libcrypto.a -o prog.exe -ldl
It works fine when linking into the executable.
Devil's advocate... Does it work fine with Position Independent Code (PIE)? PIE on a program is the equivalent to PIC on a shared object (some hand waiving).
gcc -fPIE prog.c /usr/local/lib/libssl.a /usr/local/lib/libcrypto.a -o prog.exe -ldl
According to the GCC folks, you can compile with fPIC, and then build a shared object with -fPIC or a relocatable executable with -fPIE. That is, its OK to use -fPIC for both.
Trying to statically link OpenSSL into the shared library causes errors due to OpenSSL not being compiled with -fPIC.
That's easy enough to fix. You simply specify shared in configure:
./config shared no-ssl2 no-ssl3 no-comp --openssldir=/usr/local/ssl
make
sudo make install
I think you can also (notice the lack of shared):
export CFLAGS="-fPIC"
./config no-ssl2 no-ssl3 no-comp --openssldir=/usr/local/ssl
make
sudo make install
not being compiled with -fPIC. Is it possible to do this without recompiling openssl?
NO, you have to compile with PIC to ensure GCC generates relocatable code.
Also, is there a better way to do this?
Usually you just configure with shared. That triggers -fPIC, which gets you relocatable code.
There's other things you can do, but they are more intrusive. For example, you can modify Configure line (like linux-x86_64), and add -fPIC in the second field. The fields are separated by colons, and the second field is $cflags used by the OpenSSL build system.
You can see an example of modifying Configure at Build OpenSSL with RPATH?

libxml/parser.h: in c++ ubuntu

Even though I have installed libxml++2.6-2 libxml++2.6-doc etc in my ubuntu 12.04 version again I am getting the below error
fatal error: libxml/parser.h: No such file or directory
I am using make for building the project
Kindly suggest any other libxml libraries which I need to install
libxml/parser.h is a part o libxml library, not libxml++
For any given library, you need development packages (the ones with names ending in -dev) in order to build applications using that library.
You need to pass additional flags to your compiler: xml2-config --cflags and to linker xml2-config --libs.
I don't have access to an Ubuntu system now, but: Maybe you need to install the libxml developer package? Maybe you only have the library but not the include file(s)?
Check in /usr/include, /usr/local/include, ... for the directory libxml and the file parser.h.
If you find the file, you may need to adapt your makefile so that the parent-directory is in the list of include paths, e.g.:
INC = -I/usr/local/include
g++ $(INC) ...
If you did not find the file: Check the available libxml packages for a developer package and install that.
Before Posting the answer THANKS to the people who have answered, but those answers were not worked for me
I have just copied libxml folder from the directory usr/lib/libxml2 and pasted in usr/lib directory and compiled my code it is not giving any error. It is working fine now.
Please read #el.pescado answer before reading this. I wanted to comment on that answer but felt the need to format my code better.
gcc -c <files to compile> `xml2-config --cflags` -o <object files>
gcc <object files> -L<libxml2 lib location> `xml2-config --libs` -o <binary file>
Assuming we have a file names xmltest.c that have code that included libxml2 header like #include <libxml/parser.h>, standard location of libxml2 shared library i.e. /usr/lib64/libxml2, the above code will evaluate like this:
gcc -c xmltest.c -I/usr/include/libxml2 -o xmltest.o
gcc xmltest.o -L/usr/lib64/libxml2 -lxml2 -lz -lm -o xmltest
A better idea is to put together a Makefile that does this automatically.

Boost installation and library paths

I have been using Boost (the header only library part) for sometime now. I recently started on a project that required the compiled libraries (filesystem etc).
I followed the instructions given in the documentation, and was under the impression that the libraries to installed (directly) in the usr/local folder. After a lot of trial and error, I found that the correct (*.a) files to use were in:
/usr/local/boost_1_45_0/stage/lib/
Is this the correct folder to use for linking the boost built shlibs (shared libraries)?
An example for linking regex static(*.a) lib:
g++ -I /usr/local/boost_1_45_0 -c your_regex_prog
g++ -static -o static_regex your_regex_prog.o -lboost_regex