How to compile a simple program with OpenSSL? - c++

I am trying to compile a simple ssl program (it was taken from the openssl book source code).
The program has the following files: common.h common.c client.c server.c
I have installed openssl 0.9.7 so I have the same version with the book.
I have downloaded the source and ./Configure, make, make test, make install in the home directory.
In the common.h there are the following includes:
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
I run gcc -Wall common.c client.c -o client but I get the following errors:
common.c: In function ‘init_OpenSSL’:
common.c:12:5: warning: implicit declaration of function ‘THREAD_setup’
/tmp/ccvI3HX4.o: In function `handle_error':
common.c:(.text+0x3a): undefined reference to `ERR_print_errors_fp'
/tmp/ccvI3HX4.o: In function `init_OpenSSL':
common.c:(.text+0x51): undefined reference to `THREAD_setup'
common.c:(.text+0x5a): undefined reference to `SSL_library_init'
common.c:(.text+0x97): undefined reference to `SSL_load_error_strings'
/tmp/ccRA0Co9.o: In function `do_client_loop':
client.c:(.text+0x71): undefined reference to `BIO_write'
/tmp/ccRA0Co9.o: In function `main':
client.c:(.text+0xbb): undefined reference to `BIO_new_connect'
client.c:(.text+0x106): undefined reference to `BIO_ctrl'
client.c:(.text+0x18e): undefined reference to `BIO_free'
collect2: ld returned 1 exit status
Obviously it cannot link to the header files...
When I run as suggested in one forum gcc -Wall common.c client.c -o client -lcrypto -lssl I get
common.c: In function ‘init_OpenSSL’:
common.c:12:5: warning: implicit declaration of function ‘THREAD_setup’
/tmp/cc2gjx8W.o: In function `init_OpenSSL':
common.c:(.text+0x51): undefined reference to `THREAD_setup'
collect2: ld returned 1 exit status
But adding -lpthread won't help resolve the problem...
Any idea why this happens and how to solve it?
My guess is that lcrypto and lssl are installed by default in ubuntu and by doing -lcypto is telling the linker to look at the systems headers and not the openssl installation ones...
Any help or pointers is appreciated!
Thank you!

In some code versions of openssl book, the thread related functions are stored in reentrant.c, (in fact the declaration of TRHEAD_setup, in the version i've seen is there), so try with:
gcc -Wall common.c client.c reentrant.c -o client -lcrypto -lssl

Related

How to link/include c++ libraries correctly

I tried to compile program with https://github.com/yhirose/cpp-httplib "one-header" library. I wrote
#include "httplib.h"
/* example code from main github page */
and when i tried to compile program
g++ -std=c++11 -o test test.cc
i got this error:
/usr/bin/ld: /tmp/ccYMj4l8.o: in function `std::thread::thread<httplib::ThreadPool::worker, , void>(httplib::ThreadPool::worker&&)':
test.cc:(.text._ZNSt6threadC2IN7httplib10ThreadPool6workerEJEvEEOT_DpOT0_[_ZNSt6threadC5IN7httplib10ThreadPool6workerEJEvEEOT_DpOT0_]+0x2f): undefined reference to `pthread_create'
collect2: error: ld returned 1 exit status
What can i do?
And how to link libraries that have include and src directories, e.g. libcurl
It's gcc's known particular feature, its std::thread implementation is built upon pthreads so it requires specifying -pthread to correctly link programs with threads.

g++ building c++ program with boost dependencies

I want to compile and run a simple c++ websocket application with g++ on windows.
Boost was installed like this:
./bootstrap.bat mingw
./b2.exe install --prefix=C:/boostLibs toolset=gcc
My c++ includes look like this:
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <iostream>
This websocket sample was provided by https://github.com/zaphoyd/websocketpp
In order to build the project I issue this command:
g++ -Wno-deprecated -I ./cppServer/libs/ -I C:\boostLibs\include\boost-1_55 -L C:\boostLibs\lib -g ./cppServer/server.cpp -lboost_system
Which leeds me to this error message:
c:/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lboost_system
collect2.exe: error: ld returned 1 exit status
If I try to build without -lboost_system, I get a very long exception, starting with:
C:/boostLibs/include/boost-1_55/boost/system/error_code.hpp:222: undefined reference to boost::system::generic_category()'
C:/boostLibs/include/boost-1_55/boost/system/error_code.hpp:223: undefined reference toboost::system::generic_category()'
C:/boostLibs/include/boost-1_55/boost/system/error_code.hpp:224: undefined reference to boost::system::system_category()'
C:\Users\JOHANN~1.HAS\AppData\Local\Temp\ccpKMWTH.o: In functionZN5boost6system10error_codeC1Ev':
C:/boostLibs/include/boost-1_55/boost/system/error_code.hpp:323: undefined reference to boost::system::system_category()'
C:\Users\JOHANN~1.HAS\AppData\Local\Temp\ccpKMWTH.o: In functionZN5boost6system4errc20make_error_conditionENS1_6errc_tE':
C:/boostLibs/include/boost-1_55/boost/system/error_code.hpp:488: undefined reference to boost::system::generic_category()'
C:\Users\JOHANN~1.HAS\AppData\Local\Temp\ccpKMWTH.o: In functionZN5boost16thread_exceptionC2EiPKc'
So what am I missing? I can't figure it out right now.
Link to boost_system as -lboost_system-mgw63-mt-1_55, because this is what those files are called. See boost library naming for more details.
When you build boost you may like to specify --layout=system to b2.exe so that your files do not have that -mgw63-mt-1_55 in the filename and then just use -lboost_system when linking against it.

Boost.test cannot find main

I'm working with gcc 4.8, boost 1.59 on kubuntu 12.04.
I wrote a simple main.cpp file:
#define BOOST_TEST_MODULE My_Module
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE( foo )
{}
This doesn't work when I build with
g++ -std=c++11 main.cpp -I/usr/local/include -L/usr/local/lib -lboost_unit_test_framework -o test
I get a bunch of linker errors:
/usr/lib/x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to 'main'
/tmp/cc57ppN0.o: In function `__static_initialization_and_destruction_0(int, int)':
main.cpp:(.text+0x131): undefined reference to `boost::unit_test::ut_detail::auto_test_unit_registrar::auto_test_unit_registrar(boost::unit_test::test_case*, unsigned long)'
/tmp/cc57ppN0.o: In function `boost::unit_test::make_test_case(boost::unit_test::callback0<boost::unit_test::ut_detail::unused> const&, boost::unit_test::basic_cstring<char const>)':
main.cpp:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x6d): undefined reference to `boost::unit_test::test_case::test_case(boost::unit_test::basic_cstring<char const>, boost::unit_test::callback0<boost::unit_test::ut_detail::unused> const&)'
collect2: erreur: ld a retourné 1 code d'état d'exécution
What does undefined reference to 'main' means??? Well, I know that it is because it could not find main() but why? AFAIK the syntax of my file is correct. It should link, no?
You need to insert the following directive at the top of main.cpp:
#define BOOST_TEST_DYN_LINK
It seems that the example in the Boost.test documentation works for static linking only: the directive above is required, however, for dynamic linking.
See e.g C++ Unit Testing With Boost.Test for further details.
OK, I found the solution!
It seems that, since 1.34.1, boost.test no longer contains main() in dynamic (.so) version. See here. So I wanted to link with the static and I also learned that gcc prefers the dynamic libraries over the static ones for the same name!. Thus, I changed my compile command to:
g++ -std=c++11 main.cpp -I/usr/local/include -L/usr/local/lib -lboost_unit_test_framework -static -o test
...and it worked fine!
I also tested with two files ... main.cpp test1.cpp and the run executed all the test cases correctly.
Thank you, I hope this can help someone else!

Checking Boost install with MinGW

I used the MinGW installation at http://nuwen.net/mingw.html
I ran the second.cpp test found at:
http://tabreziqbal.wordpress.com/2006/03/16/how-to-test-c-boost-installation/
(I used the correct commands to run from the comments, which was
g++ -o second second.cpp -lboost_filesystem)
I get the following error:
C:\Users\user\Projects\Programming\C++\boostTest2>g++ -o second second.cpp -lboost_filesystem
C:\Users\user\AppData\Local\Temp\ccDlbKGy.o:second.cpp:(.text+0x102): undefined reference to boost::system::generic_cat
egory()'
C:\Users\user\AppData\Local\Temp\ccDlbKGy.o:second.cpp:(.text+0x10c): undefined reference toboost::system::generic_cat
egory()'
C:\Users\user\AppData\Local\Temp\ccDlbKGy.o:second.cpp:(.text+0x116): undefined reference to boost::system::system_cate
gory()'
C:\MinGW\bin/ld.exe: C:\Users\user\AppData\Local\Temp\ccDlbKGy.o: bad reloc address 0xe in section.text$_ZN5boost6syst
em14error_categoryD1Ev[__ZN5boost6system14error_categoryD1Ev]'
C:\MinGW\bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
I know there's an installation test feature of boost that I found on
http://gcc.gnu.org/testing/testing-boost.html
but those files aren't included with the distribution from nuwen.net (so I'd have to do it myself).
And help is appreciated - I figure I'm just screwing up something minor (I hope anyway).
Thanks all!
It's not correct command, you should link boost::system too (errors are undefined references to boost::system::system_category).
Correct command will be g++ -o second second.cpp -lboost_system -lboost_filesystem

undefined referance to LibSerial

So i'm writing a serial transmision program, and have just changed over to using C++, it been a while since I used C++
(I've been working with C recently, and before that java)
Now I need to use LibSerial,
(it seems much simpler to use than C's termios)
my code is:
//gen1.cpp
#include "string2num.h" // a custom header
#include <iostream>
#include <SerialStream.h>
using namespace LibSerial;
//using namespace std;
int main(int argc, char*argv[])
{
if (argc<2)
{
std::cout<<argv[0]<<"requires the device name eg \"dev/tty0\" as a parameter\nterminating.\n";
return 1;
}
SerialStream theSerialStream(argv[1]); //open the device
return 0;
}
When I compile the output:
g++ -Wall -o gen1 gen1.cpp string2num.o
/tmp/cchPBWgx.o: In function `main':
gen1.cpp:(.text+0x121): undefined reference to `LibSerial::SerialStream::SerialStream(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Ios_Openmode)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x24): undefined reference to `LibSerial::SerialStreamBuf::showmanyc()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x28): undefined reference to `LibSerial::SerialStreamBuf::xsgetn(char*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x2c): undefined reference to `LibSerial::SerialStreamBuf::underflow()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x34): undefined reference to `LibSerial::SerialStreamBuf::pbackfail(int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x38): undefined reference to `LibSerial::SerialStreamBuf::xsputn(char const*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x3c): undefined reference to `LibSerial::SerialStreamBuf::overflow(int)'
collect2: ld returned 1 exit status
make: *** [gen1] Error 1
This is the linker complaining that it cannot find the functions referenced by the libserial header file.
If I look on my Linux system to see how the shared library is called:
$ dpkg -L libserial0
...
/usr/lib/libserial.so.0.0.0
/usr/lib/libserial.so.0
On my system this implies I would add -lserial as a g++ option (aka link with libserial.so) this would turn your compilation command into
g++ -Wall -lserial -o gen1 gen1.cpp string2num.o
Including the header file is not enough - you also need to link with the library that implements SerialStream. Assuming it is a static library called serstream.a (it is almost certainly actually called something else):
g++ -Wall -o gen1 gen1.cpp string2num.o serstream.a
old thread, but i still use Libserial. here the completed answer
My working setup.
Ubuntu 18.04
g++ 7.3.0
1) Install package for libserial
apt install libserial-dev
2) check for your headers(.h) and .so files
dpkg -l libserial0
dpkg -l libserial-dev
the first command give you the directory of shared library and the second gives you the headers location.
3) Your code.
I have to change a little your code, first i delete the custom header and modifing the constuctor call to this.
SerialStream theSerialStream;
4) compile with g++
Here my compiling command
g++ -o test -I/usr/include test.cpp -L/usr/lib/x86_64-linux-gnu -lserial -lpthread
check for the -lpthread linking option, beacuse Libserial uses mutex.
In Ubuntu/Debian make sure you have to libserial-dev package installed and use the '-lserial' flag for gcc.