Marc Wäckerlin
Für eine libertäre Gesellschaft

Cross Compile OpenSSL for Windows on Linux

Mai 7, 2014

Views: 21230

This article explains how to configure and build the OpenSSL library on a Ubuntu Linux to run on 32bit or 64bit Windows. After you have set up your cross compile environment as described in my previous article, you are now ready to start compiling for example OpenSSL, which is a requirement for Qt5 that will be described in my next article.

To cross compile OpenSSL for Windows on an Ubuntu Linux using MinGW, you need to perform the following steps:

  1. Find and download the latest sources from https://www.openssl.org/source
  2. Unpack the file and change to that directory
  3. Chose your OpenSSL target name, which is different from the MinGW target name and is mingw for 32bit i686-w64-mingw32 and mingw64 for 64bit x86_64-w64-mingw32
  4. To configure for 32bit Windows, call ./Configure mingw shared --cross-compile-prefix=i686-w64-mingw32-
    Note: Without the addition shared, the required runtime DLLs are not built
  5. Run make and optionally make install (i.e. if you have added a --prefix=/install/path option to Configure)
  6. Note: The runtime DLLs are not installed to the installation path, you find them in your local path, try ls *.dll after your build
  7. There is a bug in OpenSSL that must be fixed manually: In the include file openssl/x509v3.h add just after line #define HEADER_X509V3_H on the top the following lines:
    #ifdef X509_NAME
    #undef X509_NAME
    #endif

It is possible to do everything fully automated, e.g. in a Jenkins build script:

MINGW=${MINGW:-x86_64-w64-mingw32}
WORKSPACE=${WORKSPACE:-$(pwd)}
BUILD_NUMBER=${BUILD_NUMBER:-0}
ARCH=${ARCH:-${MINGW%%-*}}

cd ${WORKSPACE}
source=https://www.openssl.org/source
file=$(wget -qO- $source | sed -n 's,.*<a *href="\(openssl-[0-9][^"]*\.tar\.gz\)".*,\1,p'  | head -1)
path=${file%.tar.gz}
wget -qO$file $source/$file
tar xf $file
cd $path
version=${path#openssl-}

case ${MINGW} in
    (*i?86*)
        TARGET=mingw
        ;;
    (*x86_64*)
        TARGET=mingw64
        ;;
    (*) false;;
esac

./Configure ${TARGET} shared --cross-compile-prefix=${MINGW}- --prefix=${WORKSPACE}/usr

make
make install
cp *.dll ${WORKSPACE}/usr/lib/

cd ${WORKSPACE}
zip -r ${path}~windows.${BUILD_NUMBER}_${ARCH}.zip usr

Build MinGW Targets in Docker

I support a maintained docker image that contains an Ubuntu based build environment and build scripts for several libraries and programs. This is i.e. QT and all it’s dependencies, and my own projects with all their dependencies:

List all available build scripts:

docker run -it –rm mwaeckerlin/mingw -c ‹ls /build-*.sh›

Show options for building OpenSSL:

docker run -it --rm mwaeckerlin/mingw /build-openssl.sh -h

Compile latest OpenSSL in the current working directory:

docker run -it --rm -v $(pwd):/workdir -u $(id -u) mwaeckerlin/mingw /build-openssl.sh -d

Build ICU version 57-1 in the current working directory:

docker run -it --rm -v $(pwd):/workdir -u $(id -u) mwaeckerlin/mingw /build-icu.sh -d -v 57-1

Just Download Built Archives

You can download already built images for 32bit and 64bit on my repository: https://dev.marc.waeckerlin.org/repository/windows/

comments title

[…] hacks have gone, cross-compilation is very simple. This is my first example of a 3rd-party library. Next article will talk about cross compiling […]

What’s the purpose of editing those two lines?

You mean the «undef»? This macro is defined in more than one files. At the second definition, the compiler complains. So I first undefine it, then it can be redefined later in the file.

Editing the two lines is no more necessary.

Hey,
Thank you for your efforts on this. I am facing an issue while trying to cross compile openssl-fips for windows on linux. What I have done is I have added the flag fips in ./Configure but while executing the file it gives the following stack trace error:

[ -z «libcrypto» ] || x86_64-w64-mingw32-gcc -D_WINDLL -DOPENSSL_PIC -DOPENSSL_THREADS -D_MT -DDSO_WIN32 -DL_ENDIAN -O3 -Wall -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -I/usr/local/ssl/fips-2.0/include -DRC4_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -Iinclude \
-DFINGERPRINT_PREMAIN_DSO_LOAD -o fips_premain_dso.exe \
/usr/local/ssl/fips-2.0/lib/fips_premain.c /usr/local/ssl/fips-2.0/lib/fipscanister.o \
libcrypto.a -lws2_32 -lgdi32 -lcrypt32
/usr/local/ssl/fips-2.0/lib/fipscanister.o: In function `FIPS_module_mode›:
(.text+0x143): undefined reference to `__stack_chk_fail›
/usr/local/ssl/fips-2.0/lib/fipscanister.o: In function `FIPS_selftest_failed›:
(.text+0x25a): undefined reference to `__stack_chk_fail›
/usr/local/ssl/fips-2.0/lib/fipscanister.o: In function `FIPS_incore_fingerprint›:
(.text+0x447): undefined reference to `__stack_chk_fail›
/usr/local/ssl/fips-2.0/lib/fipscanister.o: In function `FIPS_check_incore_fingerprint›:
(.text+0x5ef): undefined reference to `__stack_chk_fail›
…. and the stack trace goes on.

Do you have any pointers as to how to resolve this issue. Please let me know if you can provide any help. I will be grateful.

Also I have already installed openssl fips in the docker container.

Hi Naveed Jamil

Perhaps this could help: https://stackoverflow.com/questions/4492799/undefined-reference-to-stack-chk-fail

Hello Marc,

I want build this software for windows:

https://sourceforge.net/p/fastsvncrawler/code/HEAD/tree/

I can build this under debian 9 with some minor changes in the file

https://sourceforge.net/p/fastsvncrawler/code/HEAD/tree/trunk/CMakeLists.txt

Can you help me please using your docker mingw buildsystem to build this for windows ?

It’s my first try for cross compiling.

Greeting Dirk

Dirk, I hate cmake, so I won’t use it, it’s just another unnecessary «me-too»-build-system. Use the autotools. So I won’t actively support it. But principially it should work, if you call your build command somehow like this:

docker run -it –rm -v $(pwd):/workdir -u $(id -u) mwaeckerlin/mingw your-build-command

Hi Marc,

I don’t like cmake too, so i can understand you.
But in this case this tool works for me on my linux vm side and I’ll try to translate ist for running on windows.
It’s 10 times faster on my linux vm docker as the «svn list» command on windows host.

Thank you for your work on docker/mingw.

Did you check Cross Compile on Ubuntu Linux for Windows Using MinGW? There you find the basics for the autotools. I like them, because they simplify such a complex thing as cross compiling. You’ll need to convince your build system to use x86_64-w64-mingw32-gcc as replacement for gcc and thelike.

You know that you can run docker run -it –rm -v $(pwd):/workdir -u $(id -u) mwaeckerlin/mingw bas for your experiments?

Hi,
any plans to update to hub.docker.com/mwaeckerlin/mingw to 22.04LTS?
regards

Thanks for the hint. It is recompiled, whenever I update the base `mwaeckerlin/ubuntu-base`. That inherits latest `ubuntu`. I just triggered a rebuild that then will be in the latest Ubuntu version.