[[TOC(inline, depth=1)]] = Introduction = The traditional way to build OpenVPN for Windows is to cross-compile it on *NIX. This works, but does not allow signing the TUN/TAP driver, which is required for Windows Vista/7 and later. Due to this a new, relatively simple Python-based build system was written. This new build system allows building OpenVPN on Windows more easily, but some parts of the build may require a commercial version of the Visual Studio development environment. Fortunately the new build system only uses Visual Studio tools (nmake, compiler, linker, etc.), so learning VS's graphical user interface is not necessary. Full integration with Visual Studio ''should'' be possible, too. = Installing prequisites = == Visual Studio 2008 Professional == Visual Studio 2008 Professional is used to build OpenVPN on Windows. Note that the free Express edition might not work. Also make sure you select "Typical installation", not "Full installation". Full installation installs ''x86 cross-tools'' which may cause nasty, hard to debug issues. See ''Troubleshooting'' section for details. == Windows Software Development Kit == [http://msdn.microsoft.com/en-us/windows/bb980924.aspx Windows Software Development Kit] ([http://en.wikipedia.org/wiki/Microsoft_Windows_SDK Wikipedia page]) ''may'' be necessary to build OpenVPN (verify this). == Windows Driver Kit == [http://www.microsoft.com/whdc/devtools/WDK/default.mspx Windows Driver Kit] ([http://en.wikipedia.org/wiki/Windows_Driver_Kit Wikipedia page]) is required to build the TUN/TAP driver. == Python == The new Windows build system is written in [http://www.python.org Python]. The Windows installer does not seem to add the ''python.exe'' to the PATH, so you need to do it [[http://vlaurie.com/computers2/Articles/environment.htm manually]. == WinRAR == [http://www.rarlab.com WinRAR] or some other tool capable of extracting .tar.gz and .tar.bz2 archives is necessary to extract the LZO and OpenSSL release archives. == !ActivePerl == [http://www.activestate.com/activeperl ActivePerl] is required to build OpenSSL, which in turn is required to build OpenVPN. Look [http://ehsanakhgari.org/blog/2008-05-04/compiling-openvpn-windows here] for details. Probably a [http://www.perl.org/get.html standard Perl installation] would also do the trick. = Installing Git support (optional) = Git support is needed if you want to conveniently build the latest development code. You don't need Git support if you fetch the sources from another computer and copy them over, or use source code from release tar.gz or zip files. == Git for Windows == [http://code.google.com/p/msysgit/ Git for Windows] or ''msysgit'' is required to work with Git repositories on Windows. == !GitExtensions == [http://code.google.com/p/gitextensions/ GitExtensions] makes working with Git easier on Windows. It includes Visual Studio 2008 plugin, Windows explorer support and a GUI to configure and use Git repositories. It also includes ''Git Bash'', which allows running Git (and other GNU tools) from Bash command-line. == KDiff3 == [http://kdiff3.sourceforge.net/ KDiff3] is used in handling merge conflicts. It's required by ''!GitExtensions''. == Git Source Control Provider (optional) == [http://gitscc.codeplex.com/ Git Source Control Provider] is a Visual Studio 2008/2010 plugin. It can also be used to launch ''Git for Windows'' and ''!GitExtensions'' from within Visual Studio. = Building pkcs11-helper = Download latest release of ''pkcs11-helper'' from http://www.opensc-project.org and extract it somewhere. The install process for Visual Studio is described in the ''INSTALL'' file. To build ''pkcs11-helper'', do the following: * Go to ''pkcs11-helper-/lib'' * Copy ''/lib/libeay32.lib'' to that directory - this is required by the linker * Run ''nmake -f Makefile.w32-vc OPENSSL=1 OPENSSL_HOME='' In theory this should do it. If you need to rebuild, clean up first with {{{ $ nmake -f Makefile.w32-vc clean }}} and then repeat the above steps. Unless you're using 1.08 or later, you probably get this error message during build: {{{ pkcs11h-threading.c(477) : error C2036: 'void *' : unknown size }}} If so, edit that file as suggested [http://thread.gmane.org/gmane.comp.encryption.opensc.devel/8381 here]. After this build should succeed, as long as ''libeay32.lib'' is present in the build directory. OpenVPN is only interested is ''lib/libpkcs11-helper-1.dll'' and uses it when generating the NSI installer. = Building OpenSSL = First download OpenSSL from [http://www.openssl.org/source here] and extract it somewhere. Using the latest one ensures there are no (known) security holes in OpenSSL. For the most part you can then follow the instructions in ''INSTALL.W32'' and ''INSTALL.W64'' files. Before you start, though, launch the ''Visual Studio 2008 Command Prompt'', which can be found from the ''Start menu''. Unlike the standard command prompt it has all the paths to VC binaries set correctly. From within this command prompt you'll first configure OpenSSL using the provided Perl script: {{{ C:\openssl-1.0.0> perl Configure VC-WIN32 --prefix=c:/ }}} Some of the crypto routines are written in assembler to increase performance, so you need to/should use an assembler in the next step. If you're building OpenSSL 0.9.8x you can choose between [http://en.wikipedia.org/wiki/Microsoft_Macro_Assembler Microsoft Macro Assembler] and [http://www.nasm.us/ NASM assembler]. On OpenSSL-1.0.0 you need to use NASM as MASM is not supported anymore. Note that you need to add ''nasm.exe'' to the PATH. There are good generic instructions [http://vlaurie.com/computers2/Articles/environment.htm here]. If you're using MASM, run {{{ C:\openssl-1.0.0> ms\do_masm }}} If you're using NASM, run {{{ C:\openssl-1.0.0> ms\do_nasm }}} Next compile OpenSSL using the generated makefile: {{{ C:\openssl-1.0.0> nmake -f ms\ntdll.mak C:\openssl-1.0.0> nmake -f ms\ntdll.mak test C:\openssl-1.0.0> nmake -f ms\ntdll.mak install }}} = Building LZO = The [http://www.oberhumer.com/opensource/lzo/ LZO library] is required to build OpenVPN. Once you've unpacked the source package, open the ''B/00README.txt'' file to get an overview of the Windows build process. If all goes well, you'll only need to run one .bat file: {{{ C:\lzo-2.0.4> B\win32\vc_dll.bat }}} Note that this ''does not'' install lzo; in fact, you need to copy the relevant files to openvpn's build directory manually as shown below. = OpenVPN build = == Setting up dependencies == The new Python-based build system we're using in this article has gone through significant changes during late 2010 and early 2011. You're strongly encouraged to fetch latest Git development code using ''Git for Windows'' (Git shell) or ''!GitExtensions'' (GUI). Check [wiki:TesterDocumentation these instructions] to see which Git URI to use. Alternatively get OpenVPN 2.2-RC2 or later, where most of the buildsystem changes have been implemented. OpenVPN has several build and runtime dependencies that need to be placed into a strict directory hierarchy along with OpenVPN sources: * '''''': root build directory, e.g. ''C:\openvpn-build'' * '''''': a directory containing openvpn sources * '''tapinstall''' * '''7600''': copy of devcon.exe ''build directory''. Can be found from ''C:\WINDDK\7600.16385.1\src\setup\devcon'' or similar, depending on the version of WINDDK. Note that in OpenVPN world ''devcon.exe'' is (confusingly) also known as ''tapinstall.exe''. * '''pkcs11-helper''': copy of pkcs11-helper ''build directory'' * '''lib''': must also contain ''libpkcs11-helper-1.dll'' and ''libpkcs11-helper-1.dll.manifest'' files produced by pkcs11-helper build * '''openssl''': copy of the openssl ''install directory'' * '''lzo''' * '''include''': a copy of the ''include'' directory in the lzo ''build directory'' * '''bin''': must also contain the ''lzo2.dll'' and ''lzo2.dll.manifest'' files generated by lzo build * '''lib''': must also contain the ''lzo2.lib'' file generated by lzo build * '''Microsoft.VC90.CRT''': a copy of ''C:\Program Files\MicrosofT Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT'' directory; the exact path may vary. Note that using the wrong version will cause issues on 32-bit or 64-bit Windows versions. * '''signtool''': this directory should contain ''signtool.exe'', which can be found from the Microsoft SDK directory (e.g. ''C:\Program Files\Microsoft SDKs\Windows\V6.0A\bin''). However, it's Python wrapper (''Sign'' class) is only available internally at OpenVPN Technologies, so you can skip this dependency. == Setting build parameters == After setting up the directories, you should check if OpenVPN's build configuration files need modifications: * ''\win\config.h.in'': static header file, functionally the same as config.h generated by autotools * ''\win\settings.in'': build configuration for Python-based builds. * ''\win'' directory. You should now build OpenVPN + the TAP driver using {{{ C:\openvpn-build\openvpn-testing\win> python build_all.py --unsigned }}} This builds ''openvpn.exe'', ''openvpnserv.exe'' and the TAP driver and copies the results to ''\dist''. The ''--unsigned'' switch disables TAP driver signing, which would not work anyways because the ''Sign'' Python module is only available internally at OpenVPN Technologies. If you intend to use signed TAP drivers from an existing OpenVPN installer, you can skip building the TAP driver altogether: {{{ C:\openvpn-build\openvpn-testing\win> python build_all.py --unsigned --notap }}} To clean up before or after the build, issue {{{ C:\openvpn-build\openvpn-testing\win> python build.py clean }}} To see all available build options, use {{{ C:\openvpn-build\openvpn-testing\win> python build_all.py --help }}} == Packaging OpenVPN == Once OpenVPN build is finished, you may want to make an installer executable. OpenVPN installers are packaged using [http://nsis.sourceforge.net/Main_Page NSIS], which you can download from [http://nsis.sourceforge.net/Download here]. The buildsystem, or more correctly ''\win\make_dist.py'' - puts everything the NSI script (''\win\openvpn.nsi'') needs to ''\dist''. However, as of OpenVPN 2.2-RC there are still a few manual steps involved: * If you need to run OpenVPN on Windows Vista/7 64-bit you have to use signed TAP drivers. Unless you sign them yourself, you need to do two extra steps: * Extract TAP-drivers and ''tapinstall.exe'' from an official OpenVPN installer using [http://www.7-zip.org/ 7-zip]. * Place the signed TAP drivers and corresponding ''tapinstall.exe'' to ''\dist\i386'' and ''\dist\amd64'', respectively. Put 32-bit files to the ''i386'' directory and 64-bit files to the ''amd64'' directory. * [http://msdn.microsoft.com/en-us/library/ms235591%28v=vs.80%29.aspx Embed manifest files manually] to ''openvpn.exe'', ''openvpnserv.exe'', ''lzo2.dll'' and ''libpkcs11-helper-1.dll''. The purpose of the manifest file (whether embedded or not) is to declare the run-time dependencies of the EXE/DLL. This step is required because the NSI script is not configured to install external manifest files and a manifest file is needed for proper operation. All of this has been automated in OpenVPN 2.2-RC2 and later. In case you want to test new TAP-driver versions on Windows Vista/7 64-bit you need to self-sign them and jump through several hoops. For details, look at ''TAP-driver signing'' section. OpenVPN installer is driven by the ''\win\openvpn.nsi'' NSI script, which has to be loaded with the [http://nsis.sourceforge.net/Main_Page MakeNSIS] application to generate an installer. If the ''\dist'' directory has been properly set up, you should not encounter any errors. However, if ''MakeNSIS'' complains about missing files, make sure the ''\dist'' directory contains all of the packaging dependencies: * '''amd64''' * OemWin2k.inf * tap0901.cat * tap0901.sys * tapinstall.exe * '''bin''' * '''Microsoft.VC90.CRT''' * msvcr90.dll * Microsoft.VC90.CRT.manifest * libeay32.dll * libpkcs11-helper-1.dll * lzo2.dll * openssl.exe * openvpn-gui-1.0.3.exe * openvpn.exe * openvpnserv.exe * ssleay32.dll * '''i386''' * OemWin2k.inf * tap0901.cat * tap0901.sys * tapinstall.exe * '''samples''' * client.ovpn * sample.ovpn * server.ovpn = Integrating Git with Visual Studio (optional) = If you wish to use Windows for OpenVPN development integrating Git with Visual Studio (2008) may make sense. = TAP-driver signing = The 64-bit versions of Windows Vista/7 (and later) only allow installing drivers with certificates that have Microsoft as CA. Or, in other words, drivers verified by Microsoft. Installation of unsigned nor unauthorized device drivers is not allowed by default. This is very problematic when testing the TAP-driver, as signing it after every small change makes no sense. Fortunately it ''is'' possible to self-sign the TAP-driver and configure Windows to accept self-signed (unauthorized) drivers. As the steps involved are not trivial, they are described here. = Troubleshooting = == Compiler warnings during OpenSSL build == When building OpenSSL you're most likely encounter issues with trivial compiler warnings stopping the entire build. To circumvent this remove the ''/WX'' flag in the makefile as suggested in ''INSTALL.W32'' file. This is harder than it seems for two reasons: * The correct makefile is ''ms\ntdll.mak'' (not the ''Makefile'' in build root) * You need to use ''Wordpad'' or other UNIX linefeed-aware editor to open and save the makefile == VS 2008 cross-tools issues during OpenSSL build == OpenSSL build is likely to break at several places if you're running ''Visual Studio 2008 x64 Cross-Tools Command Prompt'' instead of plain ''Visual Studio 2008 Command prompt''. Consider reinstalling Visual Studio without cross-tools if you encounter either of these errors: * ''fatal error LNK1112: module machine type X86 conflicts with target machine type x64'' (in the middle of the build) * ''Linker can't find link.obj'' (at the end of the build) = External links = * Building OpenVPN using GNU autotools * [http://ehsanakhgari.org/blog/2008-05-04/compiling-openvpn-windows Compiling OpenVPN on Windows] * [http://rfc2324.org/howto/openvpn4win Build OpenVPN for Windows using Mingw32] * [http://article.gmane.org/gmane.network.openvpn.user/22590 Compiling 2.1rc7 on Windows with VC] (email thread) * Visual studio toolchain * [http://msdn.microsoft.com/en-us/library/ff547649.aspx Installing Test-Signed Driver Packages] * [http://en.wikipedia.org/wiki/Visual_studio Visual Studio article on Wikipedia] * [http://editor.html.it/guide/leggi/139/guida-visual-studio-2008/ Visual Studio Guide] (in Italian) * [http://www.mrwebmaster.it/editor/guide/guida-visual-studio-2008/ Another Visual Studio Guide] (in Italian) * [http://blog.kowalczyk.info/article/clexe-cmd-line-args.html Visual Studio C compiler command-line arguments] * [http://msdn.microsoft.com/en-us/library/aa314791%28v=VS.60%29.aspx NMAKE Reference] * [http://msdn.microsoft.com/en-us/library/ms235591%28v=vs.80%29.aspx How to: Embed a Manifest Inside a C/C++ Application] * Windows driver signing * [http://msdn.microsoft.com/en-us/windows/hardware/gg487317 Driver Signing Requirements for Windows] * [http://msdn.microsoft.com/en-us/library/bfsktky3%28v=vs.80%29.aspx Makecert.exe reference] * [http://msdn.microsoft.com/en-us/library/8s9b9yaz%28v=vs.80%29.aspx Signtool.exe reference] * Other tools * [http://www.7-zip.org/ 7-zip]: useful for extracting files (e.g. OpenVPN's signed TAP drivers) from NSI installers * Debugging * [http://www.gtopala.com/ System Information for Windows]: a useful tool for debugging processor architecture issues * [http://www.dependencywalker.com/ Dependency Walker]: a tool to debug DLL issues in DLLs and EXEs * [http://weblogs.asp.net/kennykerr/archive/2007/07/10/manifest-view-1-0.aspx Manifest view]: a tool to view contents of embedded manifests in EXEs and DLLs