Skip to content

Instantly share code, notes, and snippets.

@terrillmoore
Last active October 28, 2022 00:38
Show Gist options
  • Save terrillmoore/995421ea6171a9aa50552f6aa4be0998 to your computer and use it in GitHub Desktop.
Save terrillmoore/995421ea6171a9aa50552f6aa4be0998 to your computer and use it in GitHub Desktop.
Building OpenSSL 1.1.0 with Microsoft VS 2015

Building OpenSSL 1.1.0 with Microsoft VS 2015

MCCI needs OpenSSL for a Windows project (that will be cross-platform). A casual search didn't turn up either a good source for cross-platform libraries, which meant we have to build them ourselves. A deeper search found a detailed guide here, and yet the details don't match what I found when I checked out the code; and the post doesn't talk about doing it directly from GitHub (which I wanted to do).

Here's the procedure for building OpenSSL on 64-bit Windows 10, with Visual Studio 2015. Others (July 2019) report that this procedure works with Visual Studio 2017 as well. I've not had a chance to try with Visual Studio 2019.

As this procedure dates from late 2016, you may find that there's a CMake or other, newer, procedure that's more suitable.

  1. If you don't have it, please install git bash from git-scm.com.

  2. Start a git bash window.

    In the following, I'll use lines beginning with {dir} $ to designate input to a bash Window. We'll also have to use a cmd.exe Window for much of the build, and those lines will be marked {dir}>, just as on Windows..

  3. Create a directory for your work.

    ~ $ mkdir c:/work
    ~ $ cd c:/work
    /c/work $
  4. Clone the SSL repository from github.

    /c/work $ git clone https://github.com/openssl/openssl.git
  5. At this point, we have the bleeding edge checked out in your sandbox. We don't want that for this project. Update the repository checkout to the 1.1 stable branch.

    /c/work $ cd openssl
    /c/work/openssl $ git checkout --track origin/OpenSSL_1_1_0-stable

    This is when we looked into NOTES.WIN and NOTES.PERL.

  6. Get ActiveState Perl from https://www.activestate.com/activeperl. My normal style is to download the file and then run the install as a second step. I got the 64-bit version.

  7. Install ActiveState Perl. Select a typical install, but don't let it change PATH or add automatic execution of ".pl" extensions (uncheck the boxes on the install menu). (Well, you can let it change them if you want; but on my system I don't normally use Perl, and I don't want any more random things on my path,)

  8. Use Visual Studio to open a 64-bit compile window. In my case, I clicked the Windows button, then typed VS2015 x64, and then clicked on VS2015 x64 Native Tools Command Prompt.

  9. In that window, change directory to the repo created above.

    C> cd c:\work\openssl
  10. Add c:\perl64\bin to your path.

     C:\work\openssl> path=%path%;c:\perl64\bin
  11. We need Text::Template, and with ActivePerl, we need to use the Package Manager.

    • Start Perl Package manager (press the Windows key and type perl, and Windows will offer you "Perl Package Manger").
    • On the menu bar, select "View>All packages".
    • Search for "Text-template" (not "Text::Template"). Select it; I used version 1.46. Be careful, as there are several packages starting with "Text-template"; the one we want is named exactly "Text-template".
    • On the menu bar, select "Action->Install". This is sort of like git add -- it stages the package for installation, but doesn't install it yet
    • On the menu bar, select "File>Run Marked Actions"
  12. Download and install nasm from nasm.us. I installed it at c:\tools\nasm; and I manually added it to my path using:

    C:\work\openssl> path=%path%;c:\tools\nasm
  13. Choose where you're going to install OpenSSL. I did not want to add this in C:\Program Files, which is the default. I've run into lots of problems in the past trying to mix debug and release builds with Visual Studio, and it seems even more exciting with VS 2015; so I want to do side-by-side installs. I decided to put the release build in {destdir}\vc-win64a, and the debug build in {destdir}\vc-win64a-debug. I want to put the configuration files in {destdir}\SSL.

  14. I didn't want assembly language (even though I got nasm above -- the build seems to require it). So I used the following configuration.

    C:\Work\openssl> perl Configure VC-WIN64A --prefix=c:\tools\OpenSSL\vc-win64a --openssldir=c:\tools\OpenSSL\SSL no-asm

    Note: while Configure is running, it pops up a window suggesting that nmake is not in the path, and offering to download dmake. Ignore this message! If you are running a VS2015 command window, as suggested above, nmake is certainly in your path.

    Several variations on this Configure command are possible.

    • You can select different targets by changing VC-WIN64A whatever target you want to build for. I have heard that VC-WIN32 works for 32-bit targets. But in that case, don't forget that you need to launch a different kind of command window from Visual Studio, targeting 32-bit x86).

    • I am told that the no-shared keyword will suppress builds of DLLs.

  15. After configuring, do this to build:

    c:\work\openssl> nmake

    On my system, that took about 3 minutes. There were some warnings, but nothing that stopped the compile.

  16. The instructions suggest doing a test using nmake test, so let's do that.

    c:\work\openssl> nmake test

    That also ran for about 3 minutes. During one of the tests, Windows firewall pops up a box about network access. I simply denied permission. The test passed anyway.

  17. To install:

    c:\work\openssl> nmake install
  18. We need to repeat this for a debug build. For sanity, we start by once again cloning the repo. Go back to the github shell (do you remember the github shell from above?) and clone the local repo to another.

    /c/work/openssl $ cd ..
    /c/work $ git clone openssl openssl-debug
    /c/work $ cd openssl-debug
    /c/work/openssl-debug $

    It might also be possible to say nmake clean and just rebuild; but the instructions in INSTALL seem to indicate that if you change the configuration significantly, you need a new sandbox.

  19. Again, we need to configure, so back to the cmd.exe window. This time, we need to change the prefix so that the debug components get installed at a different location.

    c:\work\openssl> cd ..\openssl-debug
    c:\work\openssl-debug> perl Configure VC-WIN64A --debug --prefix=c:\tools\OpenSSL\vc-win64a-dbg --openssldir=c:\tools\OpenSSL\SSL no-asm
    c:\work\openssl-debug> nmake
    c:\work\openssl-debug> nmake test
    c:\work\openssl-debug> nmake install

    Apart from adding the --debug switch and changing the target directory, you should use the same options to Configure as were used for the non-debug configuration.

  20. As a sanity check, we want to try running openssl. In the cmd.exe window, we'll enter c:\tools\OpenSSL\vc-win64a\bin\openssl.exe help. We should get the usual output:

    c:\work\openssl-debug> c:\tools\OpenSSL\vc-win64a\openssl.exe help
    Standard commands
    asn1parse         ca                ciphers           cms
    crl               crl2pkcs7         dgst              dhparam
    dsa               dsaparam          ec                ecparam
    enc               engine            errstr            exit
    gendsa            genpkey           genrsa            help
    list              nseq              ocsp              passwd
    pkcs12            pkcs7             pkcs8             pkey
    ...

That's all there is to it.

With this procedure you will, unfortunately, get two copies of everything (including the HTML stuff), not just two copies of the executables. I leave it as an exercise for the interested reader to determine how to get only the binaries installed side-by-side, with a common "shared" directory for the html and include fies.

Miscellany

Written with StackEdit and then a lot of help from @clintel's post Fenced code blocks inside ordered and unordered lists. Polished with David Anson's markdownlint plugin (davidanson.vscode-markdownlint) for VS Code.

Updated 2019-07-20 to fix formatting and typos.

Copoyright (C) 2016, 2019 MCCI Corporation. Written by Terry Moore, MCCI. License: CC-BY-SA 4.0

@Tigzy
Copy link

Tigzy commented Jun 19, 2018

Hey, thanks for the nice write-up !
With this method however I only get the shared binaries, how do I produce static libs? Specific flags to pass to Configure or nmake?

@DimitriosNT
Copy link

Try also passing no-shared to Configure

@gregbown
Copy link

gregbown commented Jul 25, 2018

Wow, this was super helpful. Thank you. The only initial problem I had was bash and cmd not finding nmake, most likely because I don't write C++ or use Visual Studio in my every day work. Ended up finding the shortcut to x64 Native Tools Command Prompt for VS 2017.
I had already installed Perl and NASM along with adding them to my path variables.

After building OpenSSL_1_1_0-stable branch, I went ahead and built the latest branch (OpenSSL 1.1.1-pre9-dev) as well, using your instructions. I also added the "no-shared" flag. It built perfectly and passed all the tests along with building a rootCA pem, key and crt locally.

You really helped fill in the missing pieces from the documentation in the openssl project.
I am curious what is the difference between perl Configure VC-WIN64A and perl Configure VC-WIN64I?
The openssl documents just say pick one, not very helpful. I thought that it had something to do with the processor being AMD or Intel, however; now I think VC-WIN64I is for building on an Itanium processor machine. Forgive my naivety and thank you again.

@bwedding
Copy link

bwedding commented Sep 7, 2018

If you want to build 32-bit, just change:
perl Configure VC-WIN64A --prefix=c:\tools\OpenSSL\vc-win64a --openssldir=c:\tools\OpenSSL\SSL no-asm

to:
perl Configure VC-WIN32 --prefix=c:\tools\OpenSSL\vc-win32 --openssldir=c:\tools\OpenSSL\SSL no-asm

@Cantstahpsendhalp
Copy link

Thanks! I had to end up installing Windows 10 SDK (10.0.14393) since mysteriously my RC.exe was missing but that plus your fix did the trick, thanks!

@assarbad
Copy link

I think VC-WIN64I is for building on an Itanium processor machine.

Correct. It would be more helpful if they stuck with the names conventionally used on Windows, but the only sane naming I've found is something along the lines of x86-32 versus x86-64 ... it's most to the point and unambiguous. On Windows the existing naming is inconsistent. For example we have AMD64, amd64 and x64 to refer to x86-64.

x86-32, was known as IA-32 (IA for Intel Architecture, a subset of x86). However, IA-64 referred to Itanium. So even though x86-64 CPUs usually contain backward compatibility with IA-32, they aren't IA-32 (nor are they IA-64).

@rsobies
Copy link

rsobies commented Jul 20, 2019

is it possible to create visual studio solution for openssl?

@terrillmoore
Copy link
Author

All, thanks for the positive feedback, which I didn't see till today.

@rsobies, no doubt it is possible to create a pure VS solution, but I have no time to do so. Since 2016, Microsoft has come a long way with CMake and so forth; it may be that by now there's a project with all the pieces.

@terrillmoore
Copy link
Author

Try also passing no-shared to Configure

@DmitriosNT, thanks for helping out.

@rsobies
Copy link

rsobies commented Jul 20, 2019

on openssl repository, i tried to click clone and download -> open in visual studio, and after cloning the repository, VS 2019 run cmake scripts but at the end there is no vs solution generated.

@terrillmoore
Copy link
Author

on openssl repository, i tried to click clone and download -> open in visual studio, and after cloning the repository, VS 2019 run cmake scripts but at the end there is no vs solution generated.

@rsobies, sorry to hear it. Probably you should ask on that page for support.

@avalyaev
Copy link

great article ,thank you. I have follow it and it's really keep my time. It might be useful to simplify some steps.
OpenSSL can be configured to build in a build directory separate from the directory with the source code.
To do this:
In step 9.
mkdir tmp
cd c:\work\tmp

and run configure step14. from tmp directory:
C:\Work\tmp>perl c:\work\OPENSSL\Configure Configure VC-WIN64A --prefix=c:\tools\OpenSSL\vc-win64a --openssldir=c:\tools\OpenSSL\SSL no-asm

This way you escape cloning the repo second time.

@terrillmoore
Copy link
Author

@avalyaev: thanks. That might have been changed since I did the original write-up. If I have a moment, I'll re-run the procedure with current OpenSSL and update.

@avalyaev
Copy link

avalyaev commented Oct 9, 2019

@terrillmoore
Another problem that I faced up and might be interesting other is the names of dll that generated by default in 64x build.
After build you got: libcrypto-1_1_64x.dll and libssl-1_1_64x.dll . It might be good but what to do if you wonna
to have exactly the same names of the dll as in 32 build: libcrypto-1_1.dll and libssl-1_1.dll
I don't find any way in the documentation of open- ssl. Happy to know how?

Anyway the next trick solved the problem. here you are:
After configure and before running nmake rename all
libcrypto-1_1_64x to libcrypto-1_1
and
libssl-1_1_64x to libssl-1_1 in
tmp/makefile and tmp/conffigdata.pm files.

after nmake, nmake install you will get :libcrypto-1_1.dll and libssl-1_1.dll for 64x build

@bisenpiyush
Copy link

If you want to build 32-bit, just change:
perl Configure VC-WIN64A --prefix=c:\tools\OpenSSL\vc-win64a --openssldir=c:\tools\OpenSSL\SSL no-asm

to:
perl Configure VC-WIN32 --prefix=c:\tools\OpenSSL\vc-win32 --openssldir=c:\tools\OpenSSL\SSL no-asm

Just wanted to add information, about the issue I faced during building for 32 bit, after I successfully created DLLs for 64 bit. The one might face issue while building (nmake) for 32 bit,

"fatal error LNK1112: module machine type 'X86' conflicts with target machine type 'x64'"
Solution: Just run the "nmake clean" before running "nmake"

@lijk8890
Copy link

lijk8890 commented Apr 3, 2020

Win64 targets,
WIN64I denotes IA-64/Itanium and WIN64A - AMD64

@lrasmus
Copy link

lrasmus commented Apr 17, 2020

Absolutely brilliant write-up! Just used it with VS 2019, after spinning my wheels trying other options.

@bryanmobrien
Copy link

Amazing job, thank you very much. Followed the instructions to the letter, but failed at initial nmake attempt.
I'm using Visual Studio 2019.
I initially tried the Developer Command Prompt for VS2019 and got 32-bit versus 64-bit errors during nmake.
Once I used the x64 Native Tools Command Prompt for VS 2019 - nmake, nmake test and nmake install all worked perfectly.
I've been looking for instructions like yours for some time. Again, thank you!

@bardonolado
Copy link

Can't use PPM on ActivePerl. Installed Strawberry and used CPAN, like this:

  • Enter CPAN with "perl -MCPAN -e shell"
  • RUN "install Text::Template" and exit CPAN
  • RUN "perl Configure VC-WIN64A --prefix=c:\tools\OpenSSL\vc-win64a --openssldir=c:\tools\OpenSSL\SSL no-asm"
  • RUN "nmake"
  • RUN "nmake install"

Worked fine.

@Shahul24
Copy link

Shahul24 commented Dec 3, 2020

I am trying to build OpenSSL on VS2013 while generating the build file, I got this error. Does anyone know the reason for this?? TA

Failure! build file wasn't produced.
Please read INSTALL.md and associated NOTES-* files. You may also have to
look over your available compiler toolchain or change your configuration.

target already defined - VC-WIN32A (offending arg: build\DLL\x32\Release)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment