How do I build OpenSSL statically linked against Windows runtime?
c, openssl, static-libraries, static-linking, windows
Solution
To build 64-bit OpenSSL statically linked (which results in a single .exe file without any DLLs) with Visual Studio 2015, you will need the following prerequisites:
- Git for Windows. You can download it at https://git-scm.com/download/win. This guide uses version 2.11.0.3.
- Strawberry perl. You can download it at http://strawberryperl.com/ (Warning: ActivePerl is highly not recommended. It will give you strange errors during the process). This guide uses version 5.24.1.1.
- NASM assembler, which is available from http://www.nasm.us/. This guide uses version 2.12.03rc1.
You are expected to install all those tools system-wide and add them to your `%PATH%` environmental variable.
After you got everything we need, just follow this simple steps:
- Open VS2015 x64 Native Tools Command Prompt from your Start Menu. You will see command prompt.
Create `C:\build` directory and issue the following command in the command prompt:
- `cd c:\build`
Download latest zlib & OpenSSL source codes to your `build` dir by using the following commands:
- `git clone https://github.com/madler/zlib`
- `git clone https://github.com/openssl/openssl`
First we have to build static `zlib`. To do that first we will need to edit some configuration files:
- Navigate to the `zlib` source folder: `cd C:\build\zlib`
Edit the `win32\Makefile.msc` file:
- Find the line starting with `CFLAGS`
- Replace `-MD` with `-GL -MT -Zc:wchar_t-`
- Find the line starting with `LDFLAGS`
- Replace `-debug` with `-opt:icf -dynamicbase -nxcompat -ltcg /nodefaultlib:msvcrt`
Build `zlib` using the following command (should take less than a minute):
- `nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -DNDEBUG -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"`
Copy resulting files to your `OpenSSL` directory:
- `xcopy zlib.h C:\build\openssl\`
- `xcopy zconf.h C:\build\openssl\`
- `xcopy zlib.lib C:\build\openssl\`
- `xcopy zlib.pdb C:\build\openssl\`
Navigate to `OpenSSL` source: `cd C:\build\openssl\` and configure it to use static zlib & read configuration files (`openssl.cnf`) from `C:\Windows\` directory.
- `perl Configure VC-WIN64A no-shared zlib no-zlib-dynamic threads --prefix=C:\Windows\`
Now make the following edits to the `C:\build\openssl\makefile`:
- Find the line that starts with: `CFLAG`
- Append: `/Zc:wchar_t- /GL /Zi`
- Find the line that starts with: `LDFLAGS`
- Replace `/debug` with `/incremental:no /opt:icf /dynamicbase /nxcompat /ltcg /nodefaultlib:msvcrt`
- Find the line that starts with: `EX_LIBS`
- Replace `ZLIB1` with `zlib.lib`
- Save changes
Build `OpenSSL` by issuing the `nmake` command (will take around 15 minutes).
The resulting ~3MB `openssl.exe` file will be located at `C:\build\openssl\apps\` directory. It is fully portable, since all DLLs are included. If you need to use custom configuration file, copy `C:\build\openssl\apps\openssl.cnf` to your `C:\Windows\` directory & edit it to your liking.
Problem
I'm working on a C++ application for Windows that uses OpenSSL 1.0.1e library. I'm on Visual Studio 2008. For portability reasons my application is statically linked against runtime libraries (`/MT` and `/MTd` options). And I don't ship runtime libs with my application. Per the OpenSSL FAQ, the library is by default linked against multithreaded DLL runtime (`/MDd`) which is obviously incompatible with my scenario. So to make my program work I've added `applink.c` to my project. On my dev machine and on most test computers the program works fine. But unfortunately I've located computers where the app doesn't start. Windows displays error: ``` The application failed to initialize properly (0xc0150002). Click on OK to terminate the application. ``` I've opened `libeay32.dll` in Dependency Walker and I see that `MSVCR90.dll` is not found. So the trick with `applink.c` doesn't really work for me. How do I build OpenSSL with `/MT` or `/MTd` option?