After a comment on my blog attracted my attention to some interesting failures when trying to build Crypt::SSLeay with Strawberry Perl, I was perplexed.
I don’t really use Strawberry. I have always used either ActivePerl, or built my own perl
, depending on my taste for experimentation. So, I went over to Strawberry Perl’s web site, and downloaded their latest portable 64-bit distribution, unzipped, and tried to install Crypt::SSLeay
.
And, I got a similar failure at link stage:
dlltool --def SSLeay.def --output-exp dll.exp
g++.exe -o blib\arch\auto\Crypt\SSLeay\SSLeay.dll -Wl,
--base-file -Wl,dll.base -
mdll -s -L"C:\…\strawberry\perl\lib\CORE"
-L"C:\…\strawberry\c\lib" SSLeay.o
C:\…\strawberry\perl\lib\CORE\libperl518.a
C:\…\strawberry\c\lib\libssl32.a
C:\…\strawberry\c\lib\libssleay32.a
C:\…\strawberry\c\lib\libz.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libmoldname.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libkernel32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libuser32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libgdi32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libwinspool.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libcomdlg32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libadvapi32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libshell32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libole32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\liboleaut32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libnetapi32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libuuid.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libws2_32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libmpr.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libwinmm.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libversion.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libodbc32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libodbccp32.a
C:\…\strawberry\c\x86_64-w64-mingw32\lib\libcomctl32.a
dll.exp
SSLeay.o:SSLeay.c:(.text+0x403):
undefined reference to `X509_get_issuer_name'
SSLeay.o:SSLeay.c:(.text+0x410):
undefined reference to `X509_NAME_oneline'
SSLeay.o:SSLeay.c:(.text+0x42f):
undefined reference to `CRYPTO_free'
SSLeay.o:SSLeay.c:(.text+0x573):
undefined reference to `X509_get_subject_name'
SSLeay.o:SSLeay.c:(.text+0x580):
undefined reference to `X509_NAME_oneline'
SSLeay.o:SSLeay.c:(.text+0x59f):
undefined reference to `CRYPTO_free'
SSLeay.o:SSLeay.c:(.text+0x6d7):
undefined reference to `X509_free'
SSLeay.o:SSLeay.c:(.text+0x2756):
undefined reference to `d2i_PKCS12_fp'
SSLeay.o:SSLeay.c:(.text+0x2798):
undefined reference to `PKCS12_parse'
SSLeay.o:SSLeay.c:(.text+0x27be)
: undefined reference to `EVP_PKEY_free'
SSLeay.o:SSLeay.c:(.text+0x27e0):
undefined reference to `X509_free'
SSLeay.o:SSLeay.c:(.text+0x27e8):
undefined reference to `PKCS12_free'
SSLeay.o:SSLeay.c:(.text+0x314e):
undefined reference to `RAND_load_file'
SSLeay.o:SSLeay.c:(.text+0x3211):
undefined reference to `OPENSSL_add_all_algorithms_noconf'
SSLeay.o:SSLeay.c:(.text+0x321b):
undefined reference to `ERR_load_crypto_strings'
SSLeay.o:SSLeay.c:(.text+0x3270):
undefined reference to `RAND_seed'
SSLeay.o:SSLeay.c:(.text+0x3316):
undefined reference to `ERR_get_error'
SSLeay.o:SSLeay.c:(.text+0x3397):
undefined reference to `ERR_get_error'
SSLeay.o:SSLeay.c:(.text+0x33b0):
undefined reference to `ERR_error_string'
*Sigh!*
So, the libraries we want to link to are there, but …
At this point, I am actually using Devel::CheckLib to check if compiling programs against the requested libraries succeeds, so I know the libraries are there. Why is linking failing?
I mean, look at this:
C:\…\strawberry\c\lib> strings libeay32.a
| perl -ne "print if /X509_NAME_oneline/"
X509_NAME_oneline
__imp_X509_NAME_oneline
X509_NAME_oneline
X509_NAME_oneline
__imp_X509_NAME_oneline
So, at least superficially, it looks like everything is there. Why the failures?
Also, it turns out the January 2014 release of Strawberry Perl (/w perl 5.18) comes with OpenSSL 1.0.1e. Is there a better excuse to build OpenSSL from scratch?
But, that would require putting together a whole MinGW environment.
Of course, don’t use outdated versions of OpenSSL. But, the solution to the linking problem was much simpler. The candidate library list I am using was ssl crypto ssl32 ssleay32 libeay32 z
. Well, using GCC, libeay32.a
would be linked by specifying -leay32
. If you use -llibeay32
, the linker will look for liblibeay32.a
.
Therefore, changing that list of libraries to ssl crypto ssl32 ssleay32 eay32 z
works for Strawberry. It does, however, fail when I try it using Windows SDK 7.1 build environment. Therefore, the new list of candidate libraries is ssl crypto ssl32 ssleay32 eay32 libeay32 z
. I’ll push the change to CPAN and GitHub.