12

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?

jww
  • 97,681
  • 90
  • 411
  • 885
user2724991
  • 121
  • 1
  • 2
  • 6
  • *"But unfortunately I've located computers where the app doesn't start... I see that MSVCR90.dll is not found"* - be sure the problem computers have the proper version of the MSVC runtime. You can download them from the Microsoft site. They should be included in you package installer. – jww Aug 23 '14 at 01:37
  • I have the same problem, openssl 1.1.1c compiled in windows 10, and using its libssl-1_1-x64.dll and libcrypto-1_1-x64.dll, get runtime error msvcrt90.dll not found. After copying msvcrt90.dll beside cpp files, get R6034 error. :( – Reza Akraminejad Jul 20 '19 at 12:26

6 Answers6

7

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:

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:

  1. Open VS2015 x64 Native Tools Command Prompt from your Start Menu. You will see command prompt.
  2. Create C:\build directory and issue the following command in the command prompt:

    • cd c:\build
  3. 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
  4. 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:

      1. Find the line starting with CFLAGS
      2. Replace -MD with -GL -MT -Zc:wchar_t-
      3. Find the line starting with LDFLAGS
      4. Replace -debug with -opt:icf -dynamicbase -nxcompat -ltcg /nodefaultlib:msvcrt
  5. 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"
  6. 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\
  7. 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\
  8. 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
  9. 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.

Anubioz
  • 435
  • 7
  • 13
6

Use the nt.mak makefile rather than the ntdll.mak makefile.

As an aside, I have written some scripts around the standard OpenSSL build scripts which make it 'easier' (for me at least) to use OpenSSL on Windows with a mix of both x86 and x64, you can get them from here.

Len Holgate
  • 21,282
  • 4
  • 45
  • 92
  • Yup, found it. Thank you very much. – user2724991 Aug 28 '13 at 11:44
  • Help, how do I compile for /MTd ? – Lefteris E Jun 25 '14 at 06:34
  • In "Install.w32" in the OpenSSL distribution there's this note: " There are various changes you can make to the Win32 compile environment. By default the library is not compiled with debugging symbols. If you add 'debug' to the mk1mf.pl lines in the do_* batch file then debugging symbols will be compiled in. Note that mk1mf.pl expects the platform to be the last argument on the command line, so 'debug' must appear before that, as all other options."... Or use nt-dbg.mak – Len Holgate Jun 25 '14 at 20:54
  • 1
    Doesn't using `nt.mak` instead of `ntdll.mak` creates static OpenSSL libraries instead of dynamic libraries with statically linked runtime? – bobeff Aug 23 '17 at 19:50
  • The __nt.mak__ makefile generate the __.lib__ instead of __.dll__ so this doesn't answer to the question which is how to create a __.dll__ with a static linked Windows runtime. – Bemipefe Feb 20 '23 at 10:46
3

The most elegant option I have found for Windows involves using the scripts provided at http://p-nand-q.com/programming/windows/building_openssl_with_visual_studio_2013.html

They provide scripts for VS2010/VS2013/VS2015 for each script version it builds all combinations of x86/x86-64 with runtimes MDd/MD/MTd/MT.

Quoting the instructions:

PREREQUISITES:

The script assumes you are on Windows.

The script assumes you have Visual Studio 2010, 2013 or 2015 installed in all the usual places. Important: If you have a different installation folder, your mileage may vary

The script assumes you have downloaded an OpenSSL tarball, like this one.

The script assumes you have Python (2.7 or 3.x) installed and on your PATH

The script assumes you have 7-zip installed (doesn't need to be on your PATH) Choose the script you want to use and edit it. For example, let's take a look at the top of rebuild_openssl_vs2015.cmd:

T:

set OPENSSL_VERSION=1.0.1p

set SEVENZIP="C:\Program Files\7-Zip\7z.exe"

set VS2015="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"

set VS2015_AMD64="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat"

so it is pretty easy to see: you must enter the OpenSSL version manually, the rest should have sensible defaults...

Note: The script uses the SUBST T:\ drive for building OpenSSL.

I tested and it works, in less than 10 min! KUDOS for the authors of the scripts!!

UPDATE: For the x64 builds to be generated you need to install nasm assembler and have it in the PATH.

2

If you want precompiled OpenSSL libraries with MT look here: http://www.npcglib.org/~stathis/blog/precompiled-openssl/ You will find a patch for the OpenSSL sources that enables producing libraries with suffixes MT/MD and "d" for debug to make identifying the libraries easier.

What's more, you will also find the actual build script to build all of them at once for many different version of Visual Studio. I build and use them myself to exactly produce binaries that need no DLLs for my projects and you may find them useful.

sigma
  • 91
  • 2
  • 4
  • Note: "All statically built libraries link against the Static Runtimes (/MT instead of /MD)." So if you're looking to build static libs compiled with /MD[d], keep looking, although I found it useful to see how the patches have modified the build files. – tekHedd Jul 20 '16 at 16:18
  • This has nothing to do with OpenSSL, but if you mix linking static (/MT) and dynamic (/MD) C runtimes you are heading towards some pretty nasty crashes that will be very hard to debug. Maybe you can show us how you have mixed the two and what the results are. In the meantime: "So if you're looking to build static libs compiled with /MD[d]" ... please don't do that. just be consistent and save yourself the trouble; especially with old MSVC. – sigma Oct 05 '16 at 18:52
  • I need openssl as static libs compiled with /MD[d], as I am building a statically linked DLL for various reasons that have a lot to do with customers and nothing to do with making R&D more fun. Believe me, if there were another option, I would have taken it. Be grateful that you've never needed to. – tekHedd Oct 07 '16 at 20:03
  • 1
    @tekHedd your blog post saved my life http://tekhedd.com/?p=2305 By the way it's working with asm for me and I'm hacking the nt.mak via powershell, overall my batch file looks like that: call cd src\openssl-1.0.2k call "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" call set path=C:\Perl64\bin;C:\Users\m\AppData\Local\NASM;%path% call perl Configure VC-WIN32 --prefix="../../build/1.0.2k-x86_rel_MD" call ms\do_nasm.bat powershell -Command "(Get-Content ms\nt.mak).replace('/MT', '/MD') | Set-Content ms\nt.mak" call nmake -f ms\nt.mak call nmake -f ms\nt.mak install – Daboul Mar 28 '17 at 13:54
  • @Daboul Glad it was helpful! May I add your code to the blog post? It might help someone else someday. Or even me. – tekHedd May 17 '17 at 20:09
0

It appears OpenSSL now links with -MT -Zl (at least when using msvc) meaning it discards default named libraries which are then decided in your final binary. Applications appear to use the static runtime by default.

In other words, no action needs to be taken in order to use it with your binary, just provide whatever flag you want and the OpenSSL library will just work with it. Unfortunate there isn't a lot of concrete documentation on building such an important library.

computerquip
  • 123
  • 7
0

I solved this problem by manually editing the ntdll.mak file. You only need to change two lines:

  • in the CFLAG line change /MD with /MT
  • in the EX_LIBS line append these libraries: libcmt.lib libvcruntime.lib

Save the makefile then run nmake as per OpenSSL instructions. You can check that the Windows runtime dependencies has been removed with these commands (VS Command Line):

dumpbin /dependents out32dll\libeay32.dll
dumpbin /dependents out32dll\ssleay32.dll
Bemipefe
  • 1,397
  • 4
  • 17
  • 30