How to build OpenSSL for Windows with MingW and MSYS

4758 ワード

How to build OpenSSL for Windows with MingW and MSYS


Today I need to build a static openssl library for Windows.
The compiling environment is MingW/MSYS/gcc 4.4.1/perl
It turns out a few tweaks have to be made to compile from the latest OpenSSL 0.9.8m source package:
Step 1:  Setup the working environment. Perl is needed to configure the make file, and you can download a perl 5 package from ActiveState. Please ensure all of the MingW/bin, MSYS/bin and Perl binaries folder are in your current PATH variable.
[
make]
The "make"version does matter for the compiling, you need the Unix-style make, unfortunately in my machine there are multiple versions of "make"(Borland Delphi7 & BDS2010) which cause fatal conflicts so I have to disable them by simply renaming the Borland/BDS2010 folder name.
[
sed]
Please ensure the sed utility is already in your PATH folder, if not it can be downloaded from MSYS/MINGW website.
Unzip the tar ball with 7-zip, launch a DOS box and go to the folder where the source is extracted,
Step 2:  Fix Configure script
Open Configure script with text editor, find line
$IsMK1MF=1 if ($target eq "mingw" && $^O ne "cygwin" && !is_msys());
and comment it out (or delete altogether).
Step 3: Disable export_var_as_fn
In Configure script, find line:
"mingw", "gcc:-mno-cygwin -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall -D_WIN32_WINNT=0x333:::MINGW32:-lwsock32 -lgdi32:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts} EXPORT_VAR_AS_FN:${x86_coff_asm}:win32:cygwin-shared:-D_WINDLL -DOPENSSL_USE_APPLINK:-mno-cygwin -shared:.dll.a",
Remove the
EXPORT_VAR_AS_FN macro so we get:
"mingw", "gcc:-mno-cygwin -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall -D_WIN32_WINNT=0x333:::MINGW32:-lwsock32 -lgdi32:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts} :${x86_coff_asm}:win32:cygwin-shared:-D_WINDLL -DOPENSSL_USE_APPLINK:-mno-cygwin -shared:.dll.a",
The reason to do it is that (1) to build static library we do not need exporting global variables as functions; (2) the current OpenSSL source code has a compiling bug and cannot be easily fixed without lots of source code change:
e_os2.h:
#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
# define
OPENSSL_IMPLEMENT_GLOBAL(type,name)                \
extern type _hide_##name;                    \
type *_shadow_##name(void) { return &_hide_##name; }        \
static type _hide_##name
In the source code it is used in two formats:
(use 1)
OPENSSL_IMPLEMENT_GLOBAL(int, check_key); //check_key not initialized.
(use 2)
OPENSSL_IMPLEMENT_GLOBAL(int, check_key) = 1; //check_key is 1 by default.
Unfortunately the macro cannot compile in gcc 4.4.1 (also I guess including a lot of other C compilers) because it first declare the _hide_name as external and then re-declare it as static scope.
A simple fix is :
# define
OPENSSL_IMPLEMENT_GLOBAL(type,name)                \
type *_shadow_##name(void) { static type _hide_##name; return &_hide_##name; }
# define
OPENSSL_IMPLEMENT_GLOBAL_INIT(type,name, val)                \
type *_shadow_##name(void) { static type _hide_##name = (val); return &_hide_##name; }
Step 4: Fix the zero-length test cases
Go to $(openssl)/test, dir *.c, you might find several test c sources with zero length! It is because that the original openssl tar ball is created in real UNIX and those zero-length files are actually softlinks to a file called dummytest.c. when unzipping in Windows platform 7-Zip (and other unzip utilities you are using) might not be able to cope with soft-link correctly thus just leaves those empty source files.
Fortunately these files are not many and can be fixed manually as following:
rm xx.c; ln -s dummytest.c xx.c
Step 5:  Configure
Run the following command :
perl Configure mingw
If everything works fine you should get makefile configured for MingW target.
Step 6: Make
Just run make to begin the building process:
make
Hopefully you will get the following after several minutes:
$(openssl)/libssl.a
$(openssl)/libcrypto.a
$(openssl)/apps/openssl.exe
also all of the test cases are run automatically to verify everything works as expected, or you can run the test with command : 
make test
The
libssl.a and
libcrypto.a is just what I need to embed the openssl features in a project ;-)
Wish the above memo can help others someday.
http://hi.baidu.com/007ware/blog/item/72a4424f70a380c6d0c86a1c.html