Improving the OpenSSL Win32 Build Process


Almost two years ago I proposed on the openssl.dev mailing list that a few important tweaks be made to the Windows build process. I haven't heard anything 'official' but I must have struck a cord with some people since every now and then I get an email from someone asking how to implement the changes.

From now on, instead of replying to everyone individually (or, to be honest, neglecting to reply), this webpage will help me get the point accross.

The Problem


The current build process always produces outputs named libeay32.lib and ssleay32.lib. This is rather invoncenient because debug and release builds end up with identically named outputs. Further, no distinction is made between static (.lib only) and dynamic (.lib and dll) build outputs.

Finally, debug information files are not generated for release builds. This is just silly: debug info in a separate, private .pdb file can be very handy when tracking down certain problems with your production code.

The Solution


After you apply the proposed changes the build outputs will be named as follows:

Release static builds

    sleay32st.lib
    libeay32st.lib
    

    (no separate .pdb files: for static libraries the debug info is stored in the .lib until linking)

Release DLL builds

    ssleay32.lib
    ssleay32.dll
    ssleay32.pdb
    libeay32.lib
    libeay32.dll
    libeay32.pdb
    

Debug static builds

    ssleay32std.lib
    libeay32std.lib
    

    (no separate .pdb files: static libraries contain debug info that's transferred to a .pdb file when linking)

Debug DLL builds

    ssleay32d.lib
    ssleay32d.dll
    ssleay32d.pdb
    libeay32d.lib
    libeay32d.dll
    libeay32d.pdb
    

Static builds will be linked to the static C runtime, and DLL builds will be linked with the DLL version of the CRT.

Finally, the OpenSSL no-hw and no-engine configuration parameters currently break the build. We've also modified the affected header files so these options now work as expected.

Changes Required


Files changed to enable 'no-engine' and 'no-hw' to work properly:

apps\s_client.c
apps\s_server.c
engines\e_4758cca.c
engines\e_aep.c
engines\e_atalla.c
engines\e_chil.c
engines\e_cswift.c
engines\e_gmp.c
engines\e_nuron.c
engines\e_sureware.c
engines\e_ubsec.c

It should be noted that changes to the above files are limited to moving conditional compilation statements (#ifdefs and #endifs) a few lines up or down.

Files deleted:

Makefile
crypto\opensslconf.h

These files are generated by the Configure script so they shouldn't be included in the source distribution in the first place.

Changes to the build process:

ms\do_masm.bat  
ms\do_win64a.bat
ms\do_win64i.bat
util\pl\VC-32.pl
util\mkdef.pl   

These files have been changed to provide modified input to the linker during the build.

After applying the changes the build process will look like the following:

1) Configure

Call the Configure Perl script to set your build options. For example:

perl Configure VC-WIN32 no-idea no-md2 no-engine no-hw

or

perl Configure VC-WIN64A

2) Generate makefiles

Call the makefile-builder for your platform:

ms\do_masm

or

ms\do_win64a

Calling ms\do_masm.bat, ms\do_win64a.bat or ms\do_win64i.bat will generate the following makefiles for the corresponding platform:

ms\nt.mak
ms\ntd.mak
ms\ntdll.mak
ms\ntdlld.mak

ms\libeay32.def
ms\libeay32d.def
ms\ssleay32.def
ms\ssleay32d.def

(also shown are the library defintion files)

3) Build the library

The final step is to call the nmake utility with the correct makefile. For example:

nmake -f ms\nt.mak

This will build a statically linked release version of the library; .lib only, no DLLs. The files will be called libeay32st.lib and ssleay32st.lib.

nmake -f ms\ntdlld.mak

This will build a dynamically linked debug version of the library. The files will be called libeay32d(.lib/.dll/.pdb) and ssleay32d(.lib/.dll/.pdb).

You can also build with ms\ntd.mak (static debug) or ms\ntdll (dynamic release build).

Changing The Library


To get OpenSSL to build this way you need to apply the patch file below. The file was tested against version 0.9.8e of the library, and may work with older and newer versions as well.

Download the patch from here: openssl.patch.zip

To apply the patch you will need a copy of the GNU Patch executable.

Unpack patch.exe to a location of your choice. Download openssl.patch.zip and place it to the directory that contains your "openssl-0.9.8e" subdirectory.

Enter the "openssl-0.9.8e" directory and apply the patch with:

..\patch -p1 < ..\openssl.patch > ..\patch.log


If everything goes well ..\patch.log will contain the following:

patching file apps\s_client.c
patching file apps\s_server.c
patching file engines\e_4758cca.c
patching file engines\e_aep.c
patching file engines\e_atalla.c
patching file engines\e_chil.c
patching file engines\e_cswift.c
patching file engines\e_gmp.c
patching file engines\e_nuron.c
patching file engines\e_sureware.c
patching file engines\e_ubsec.c
patching file ms\do_masm.bat
patching file ms\do_win64a.bat
patching file ms\do_win64i.bat
patching file util\mkdef.pl
patching file util\pl\VC-32.pl


You will have to manually delete Makefile and crypto\opensslconf.h if you want to - automatic deletion would require that both files be placed in the .patch file in their entirety. You can also leave them in their place if you want to; they do not bother anyone, unless you are about to submit the tree to source control.

For the sake of completeness, here's the command line I used to generate the patch:

diff -ur openssl-0.9.8e.original openssl-0.9.8e > openssl.patch