Build openssl with mingw to support Windows XP

Using pre-built openssl such as this one always causes trouble. They may require vc runtime dll like msvcr120.dll that is not available on deployed machine, or they are not compatible with Qt lib that uses it. They may not support Windows XP, such as the “bcrypt.dll is missing” error. In the end, you may have to compile openssl yourself.

The openssl source code can be downloaded from its official website. After downloading and unzipping it to a directory, how to build from the source? I hope there would be a command in the source directory that I can cd to the source directory to run that command to build. But they decide not to make things that easy. In order to build openssl from source, you need to install the msys software first. I recall there is a msys sub-directory when I installed mingw. Unfortunately, when I tried to build openssl in that msys, it complains the perl version is too old and needs to be upgraded. I do not know how to upgrade perl in msys. But I hear msys2 has the latest perl version so I decide to use msys2 to build openssl.

What is msys2?

You can think msys/msys2 as a linux console on Windows. You can run linux commands such as “ls” in that console. msys was once in a sub-directory of mingw but now mingw is in a sub-directory of msys2.

How to download msys2?

I misunderstood that I should use msys2 32 bit to build a 32 bit app. But it is not true. You can build both 32 bit and 64 bit programs in either msys2 32 bit or msys2 64 bit. The 32 bit/64 bit is determined by the tool-chain mingw32/mingw64, not by msys2. The worst thing is although you can download msys2 32 bit on this webpage, it actually does not work. You have no choice but to download the latest msys2 64 bit from its home page.

How to use msys2?

After downloading and installing msys2 64 bit, you can click the menu item msys2 64bit/msys2 msys in Windows start menu to run msys2, then get the linux console. To use msys2, you have only one obstacle to overcome: the mapping from windows path to msys path. If msys2 is installed to c:/msys2, this directory will be mapped to the root directory / in msys2 window. But that does not mean you can only access the files/sub-folders in c:/msys2 in msys2 environment. You can access any files/folders in your windows system in msys2. For example, if you want to see the files under d:\myprogrammingnotes.com\dir in msys2, you should use  ls “/d/myprogrammintes.com/dir”, no colon, \ is replaced with /, and there is a / at the beginning. In other words, the windows path  d:\myprogrammingnotes.com\dir  is mapped to   /d/myprogrammintes.com/dir in msys2. But in msys2, you can cd to that directory using cd d:/myprogrammintes.com/dir. Note that \ must be replaced with /, but you can keep the colon. Now it is time to cd to the source directory of openssl and start to build it.

How to build openssl with mingw32 to support Windows XP?

Firstly, you need to install a Qt version that supports Windows XP. From Qt 5.8.0, they ceased supporting of Windows XP. The apps built with Qt 5.8.0 or later won’t run on Windows XP and complain “The procedure entry point CancelIoEx could not be located in the dynamic link library KERNEL32.dll“. You can install an earlier version of Qt that supports Windows XP. But Qt supports Windows XP does not mean openssl you build supports Windows XP. You may get the “bcrypt.dll not found” error when you deploy your app and openssl dlls to Windows XP system. That is because Windows XP does not have that dll and openssl built on later Windows version such as Windows 10 requires that .dll by default. The solution is to either edit the file crypto/rand/rand_win.c under the openssl source directory to remove/comment the following lines:

# if defined(_MSC_VER) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0601
#  define USE_BCRYPTGENRANDOM
# endif

, or modify the Make file generated by the configure command(will talk later) to add the new _WIN32_WINNT definition(reference):

LIB_CPPFLAGS=-D "_WIN32_WINNT = 0x502" -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ ......
Or, 
LIB_CPPFLAGS=-D_WIN32_WINNT=0x501 -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ ......

After modifying the source code, the actual configure/compiling commands are not complex:

  1. Step 1, you need to set the correct path to include the mingw compiler/linker:
    export PATH="/C/Qt/Qt5.7.0/Tools/mingw480_32/bin:$PATH"
    

    In the above example, we are trying to use the mingw shipped by Qt to build openssl.

  2. Step 2, configure openssl:
    ./Configure --prefix="/C/opensslbuild" shared mingw

    This command is used to build openssl dll(shared) with mingw 32 bit and would install openssl to c:/opensslbuild afterwards. If you want to build openssl 64 bit, you should change mingw to mingw64, i.e., using 64 bit mingw tool-chain.

  3. Step 3: do not know what is done in this stage, just follow the instructions in this article.
    mingw32-make depend
  4. Step 4: actual compiling and linking:
    mingw32-make
  5. Step 5: install the built results to destination directory,i.e.,c:\opensslbuild\:
    mingw32-make install

     

Now, you’ve built and installed openssl. You can link to this openssl lib in your app. Note that there are two libs in the openssl installation directory:libcrypto.a and libcrypto.dll.a. Do not link to libcrypto.a, otherwise, you will encounter “undefined references” error.

If you build old versions of openssl such as openssl 1.0.2 in msys2, you should run the following commands first:

export MAKE=mingw32-make
pacman -S diffutils

Otherwise, the buggy configure script will complain “make not found” or “cmp not found”. The Makefile can be generated but it is also buggy, and you cannot complete the “make depend” step.

If you like my content, please consider buying me a coffee. Buy me a coffeeBuy me a coffee Thank you for your support!
Posted in

Leave a Reply