Thursday 3 May 2012

Building OpenSSL

Of course, before one builds libssh2, one must build OpenSSL and zlib. Today, I'll talk about OpenSSL. On Windows.

First, install perl (I used Strawberry perl), and MSys. I've looked for other options for building on Windows without VC++, and found none I could use. Fortunately, everything went smoothly - the build process was long, but uneventful.

Then, I decided to build a simple example from a tutorial. I built step by step - add one line, rebuild all; repeat. Right on my first attempt, I was hit by over 1.5K lines of undefined references.

I was using Qt Creator, so I decided to build it from the command-line myself. The first thing I learned was that I wasn't configuring the libs correctly for the linker.

The linking looked something like this:
gcc -Wl,-subsystem,console -mthreads -o OpenSSLTest.exe main.o <PATH TO OPENSSL>\lib\libcrypto.a <PATH TO OPENSSL>\lib\libssl.a 

I finally got it semi-working with this:
gcc -Wl,-subsystem,console -mthreads -o OpenSSLTest.exe main.o -L"<PATH TO OPENSSL>\lib" -lssl -lcrypto

"Semi-working", because I still had a few undefined references. But these were all Windows symbols, so I was on more familiar ground. And, I finally got it working:
gcc -Wl,-subsystem,console -mthreads -o OpenSSLTest.exe main.o  -L"<PATH TO OPENSSL>\lib" -lssl -lcrypto -lws2_32 -lgdi32

Yep, there at the end it's gdi32. Those, like me, unfamiliar with OpenSSL, might be asking why a "toolkit implementing SSL v2/v3 and TLS protocols with full-strength cryptography" was BitBlting and creating and deleting DCs. I know I did. Which led me to rand_win.c, and its

static void readscreen(void)

Looking it up on the web, it apparently uses screen content to generate pseudo-random numbers. I've also found some notes about this function not being used, since processes running on a server environment are not likely to have a UI (besides, it is called from RAND_screen(), which is stated as "function available for backward compatibility"). Still, being a newbie, even though I'm not likely to need it, I've decided to keep it in the build and just link with gdi32 (as we'll see in a moment, it won't matter that much, anyway).

I also confirmed that "dynamic-link-by-default" was working. I linked that simple program against gdi32, and checked it with Process Explorer, and, sure enough, there was gdi32.dll mapped into the process. Then, I commented out all OpenSSL calls, and built it without gdi32; as expected, no gdi32.dll. As a final test, I kept the code commented out, but linked against gdi32. I was pleasantly surprised to see that Process Explorer showed no gdi32.dll. Yes, I know all this is rather obvious, but I did say I was a newbie, didn't I?

I thought about toying a bit with /DELAYLOAD, but I found out that mingw-32 doesn't have that option.

As a final test, I looked for a semi-useful complete example. I got it to build on the command line, using the exact same command I used above.

Feeling more confident, I headed back to Qt Creator, and built it from there. And got a clean build right at the first attempt, with this .pro:

TEMPLATE = app
CONFIG += console
CONFIG -= qt

SOURCES += main.c

INCLUDEPATH += "<PATH TO OPENSSL>/include"

LIBS += -L"<PATH TO OPENSSL>/lib" -lssl -lcrypto -lws2_32 -lgdi32

Oh, and I found out that Windows now accepts both "\" and "/" on paths. That's a welcome change.

No comments:

Post a Comment