]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Added Python-based build system for Windows in
authorJames Yonan <james@openvpn.net>
Thu, 22 Apr 2010 12:53:31 +0000 (12:53 +0000)
committerJames Yonan <james@openvpn.net>
Thu, 22 Apr 2010 12:53:31 +0000 (12:53 +0000)
win directory.

Fixed minor issue in TAP driver DEBUG builds where
non-null-terminated unicode strings were being
printed incorrectly.

Version 2.1.1g

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5577 e7ae566f-a301-0410-adde-c780ea21d3b5

24 files changed:
INSTALL
install-win32/settings.in
install-win32/winconfig
tap-win32/SOURCES.in
tap-win32/common.h
tap-win32/resource.rc
tap-win32/tapdrvr.c
version.m4
win/__init__.py [new file with mode: 0644]
win/autodefs.h.in [new file with mode: 0644]
win/build.py [new file with mode: 0644]
win/build_all.py [new file with mode: 0644]
win/build_ddk.py [new file with mode: 0644]
win/config.py [new file with mode: 0644]
win/config_all.py [new file with mode: 0644]
win/config_tap.py [new file with mode: 0644]
win/config_ti.py [new file with mode: 0644]
win/js.py [new file with mode: 0644]
win/make_dist.py [new file with mode: 0644]
win/msvc.mak.in [new file with mode: 0644]
win/settings.in [new file with mode: 0644]
win/show.py [new file with mode: 0644]
win/sign.py [new file with mode: 0644]
win/wb.py [new file with mode: 0644]

diff --git a/INSTALL b/INSTALL
index 961fbd608b98af606dcef61d78c431c0956e0272..4c756d29677621ff9764f2b24aae15851467350e 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -15,9 +15,8 @@ QUICK START:
   Windows MinGW, using MSYS bash shell:
     ./domake-win (see comments in the script for more info)
 
-  Windows MSVC using Visual Studio 2008 Command Prompt window:
-    python msvc\config.py
-    nmake /f msvc\msvc.mak
+  Windows Visual Studio:
+    python win\build_all.py
 
 *************************************************************************
 
index 643ef99b5543cd40a7df05772a944ddf541262ed..edebd4435b0d38745e75f4c6a50ef16878a597f6 100644 (file)
 # tapinstall.exe source code.
 # Not needed if DRVBINSRC is defined
 # (or if using pre-built mode).
-!define TISRC  "../tapinstall"
+!define TISRC  "../tapinstall/5600"
 
 # TAP Adapter parameters.  Note that PRODUCT_TAP_ID is
 # defined in version.m4.
 !define PRODUCT_TAP_DEVICE_DESCRIPTION  "TAP-Win32 Adapter V9"
 !define PRODUCT_TAP_PROVIDER            "TAP-Win32 Provider V9"
 !define PRODUCT_TAP_MAJOR_VER           9
-!define PRODUCT_TAP_MINOR_VER           6
-!define PRODUCT_TAP_RELDATE             "06/22/2009"
+!define PRODUCT_TAP_MINOR_VER           7
+!define PRODUCT_TAP_RELDATE             "04/19/2010"
 
 # TAP adapter icon -- visible=0x81 or hidden=0x89
 !define PRODUCT_TAP_CHARACTERISTICS     0x81
@@ -58,7 +58,7 @@
 
 # Code Signing.
 # If undefined, don't sign any files.
-!define SIGNTOOL        "../signtool"
+!define SIGNTOOL        "../signtool.old"
 !define PRODUCT_SIGN_CN "openvpn"
 
 # -j parameter passed to make
index 9beaca38334ea2c0f347328a3af7234c3e4eeac1..9d686c94c8b40046a8402eedc7350729b718e8ab 100644 (file)
@@ -13,3 +13,6 @@ for g in "h" "sh" "nsi" "in" ; do
 done
 
 cat /dev/null >autodefs/guidefs.nsi
+
+echo '#include "autodefs/defs.h"' >autodefs.h
+echo '#include "config.h"' >>autodefs.h
index 58e4c59c98461160d5b7e5258c7bd19fe3588482..b7f0e18288779428cbcc7ddc8f2787048e0cb494 100755 (executable)
@@ -8,7 +8,7 @@ TARGETNAME=@@PRODUCT_TAP_ID@@
 TARGETTYPE=DRIVER
 TARGETPATH=.
 TARGETLIBS=$(DDK_LIB_PATH)\ndis.lib $(DDK_LIB_PATH)\ntstrsafe.lib
-INCLUDES=$(DDK_INCLUDE_PATH)
+INCLUDES=$(DDK_INCLUDE_PATH) ..
 
 # The TAP version numbers here must be >=
 # TAP_WIN32_MIN_x values defined in
@@ -53,7 +53,7 @@ MSC_OPTIMIZATION=/Od /Oi /Fc
 !ENDIF
 
 # Generate a linker map file just in case we need one for debugging
-LINKER_FLAGS=$(LINKER_FLAGS) /MAP /MAPINFO:EXPORTS /MAPINFO:LINES
+LINKER_FLAGS=$(LINKER_FLAGS) /INCREMENTAL:NO /MAP /MAPINFO:EXPORTS
 
 # Generate a browser information file for use in IDE development
 #BROWSER_INFO=1
index c8dcd5d767a02b6f96eac917a419d6b1959be552..7ec344045cafe529d5f113be319c30a931dbeb21 100755 (executable)
 // common to both.
 //===============================================
 
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#else
-#if defined(_MSC_VER) && !defined(TAP_DRIVER_MAJOR_VERSION)
-#include "config-win32.h"
-#else
-#include "../config.h"
-#endif
-#endif
+#include "autodefs.h"
 
 //=============
 // TAP IOCTLs
index d7f25a8b93e80ea6e26b8c3651ad3aa522ed0d3f..84884cf1d0bcda0cfe7e9ed9d5e8dbc2f770cc5f 100755 (executable)
@@ -2,7 +2,6 @@
 #include <ntverp.h>
 
 /* get VERSION */
-#include "../config-win32.h"
 #include "common.h"
 
 /* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR
@@ -36,7 +35,7 @@
 #define VER_COMPANYNAME_STR         "The OpenVPN Project"
 #define VER_FILEDESCRIPTION_STR     "TAP-Win32 Virtual Network Driver"
 #define VER_ORIGINALFILENAME_STR    TAP_COMPONENT_ID ".sys"
-#define VER_LEGALCOPYRIGHT_YEARS    "2003-2009"
+#define VER_LEGALCOPYRIGHT_YEARS    "2003-2010"
 #define VER_LEGALCOPYRIGHT_STR      "OpenVPN Technologies, Inc."
 
 
@@ -46,7 +45,7 @@
 #define XSTR(s) STR(s)
 #define STR(s) #s
 
-#define VSTRING VERSION " " XSTR(TAP_DRIVER_MAJOR_VERSION) "/" XSTR(TAP_DRIVER_MINOR_VERSION)
+#define VSTRING PACKAGE_VERSION " " XSTR(TAP_DRIVER_MAJOR_VERSION) "/" XSTR(TAP_DRIVER_MINOR_VERSION)
 
 #ifdef DBG
 #define VER_PRODUCTVERSION_STR      VSTRING " (DEBUG)"
index 2c6af4853360fa7434e85b696a2c9f5f8fb585d8..49fc3b2976871a928c9619bebc0da010e2970b36 100755 (executable)
@@ -35,7 +35,7 @@
 // TAP_IOCTL_CONFIG_TUN ioctl.
 //======================================================
 
-#include "../../autodefs/defs.h"
+#include "common.h"
 #ifndef DDKVER_MAJOR
 #error DDKVER_MAJOR must be defined as the major number of the DDK Version
 #endif
@@ -78,7 +78,6 @@
 
 #include "lock.h"
 #include "constants.h"
-#include "common.h"
 #include "proto.h"
 #include "error.h"
 #include "endian.h"
@@ -209,7 +208,7 @@ DriverEntry (IN PDRIVER_OBJECT p_DriverObject,
                 TAP_DRIVER_MINOR_VERSION,
                 __DATE__,
                 __TIME__));
-       DEBUGP (("Registry Path: '%S'\n", p_RegistryPath->Buffer));
+       DEBUGP (("Registry Path: '%.*S'\n", p_RegistryPath->Length/2, p_RegistryPath->Buffer));
        break;
       }
 
@@ -414,7 +413,9 @@ NDIS_STATUS AdapterCreate
        {
          if (parm->ParameterType == NdisParameterString)
            {
-             DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%S)\n", parm->ParameterData.StringData.Buffer));
+             DEBUGP (("[TAP] NdisReadConfiguration (MiniportName=%.*S)\n",
+                      parm->ParameterData.StringData.Length/2,
+                      parm->ParameterData.StringData.Buffer));
 
              if (RtlUnicodeStringToAnsiString (
                                                &l_Adapter->m_NameAnsi,
index e7f1d583268b889a3e60b6e957245c1aab7aaf58..5723d3c50eb91623e7a959bed92e9a2389b30ea3 100644 (file)
@@ -1,5 +1,5 @@
 dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1.1f])
+define(PRODUCT_VERSION,[2.1.1g])
 dnl define the TAP version
 define(PRODUCT_TAP_ID,[tap0901])
 define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])
diff --git a/win/__init__.py b/win/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/win/autodefs.h.in b/win/autodefs.h.in
new file mode 100644 (file)
index 0000000..2edd9b6
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef AUTODEFS_H\r
+#define AUTODEFS_H\r
+\r
+/*\r
+ * Minimum TAP-Win32 version number expected by userspace\r
+ *\r
+ * The TAP-Win32 version number is defined in tap-win32/SOURCES\r
+ */\r
+#define TAP_ID "@PRODUCT_TAP_ID@"\r
+#define TAP_WIN32_MIN_MAJOR @PRODUCT_TAP_WIN32_MIN_MAJOR@\r
+#define TAP_WIN32_MIN_MINOR @PRODUCT_TAP_WIN32_MIN_MINOR@\r
+\r
+/* Friendly name for TAP driver */\r
+#define PRODUCT_TAP_DEVICE_DESCRIPTION "@PRODUCT_TAP_DEVICE_DESCRIPTION@"\r
+\r
+/* Version number of DDK/WDK used to build TAP driver */\r
+#define DDKVER_MAJOR @DDKVER_MAJOR@\r
+\r
+/* Name of package */\r
+#define PACKAGE "@PRODUCT_UNIX_NAME@"\r
+\r
+/* Define to the full name of this package. */\r
+#define PACKAGE_NAME "@PRODUCT_NAME@"\r
+\r
+/* Define to the one symbol short name of this package. */\r
+#define PACKAGE_TARNAME "@PRODUCT_UNIX_NAME@"\r
+\r
+/* Define to the version of this package. */\r
+#define PACKAGE_VERSION "@PRODUCT_VERSION@"\r
+\r
+#endif\r
diff --git a/win/build.py b/win/build.py
new file mode 100644 (file)
index 0000000..f42715b
--- /dev/null
@@ -0,0 +1,15 @@
+import os\r
+from wb import system, config, home_fn, cd_home\r
+\r
+os.environ['PATH'] += ";%s\\VC" % (os.path.normpath(config['MSVC']),)\r
+\r
+def build_vc(cmd):\r
+    system('cmd /c "vcvarsall.bat x86 && %s"' % (cmd,))\r
+\r
+def main():\r
+    cd_home()\r
+    build_vc("nmake /f %s" % (home_fn('msvc.mak'),))\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    main()\r
diff --git a/win/build_all.py b/win/build_all.py
new file mode 100644 (file)
index 0000000..92d2bf4
--- /dev/null
@@ -0,0 +1,18 @@
+from config_all import main as config_all\r
+from build import main as build_openvpn\r
+from build_ddk import main as build_ddk\r
+from sign import main as sign\r
+from make_dist import main as make_dist\r
+\r
+def main(config):\r
+    config_all(config)\r
+    build_openvpn()\r
+    build_ddk(config, 'tap', 'all')\r
+    build_ddk(config, 'tapinstall', 'all')\r
+    sign(config, 'all')\r
+    make_dist(config)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    from wb import config\r
+    main(config)\r
diff --git a/win/build_ddk.py b/win/build_ddk.py
new file mode 100644 (file)
index 0000000..ca68e81
--- /dev/null
@@ -0,0 +1,50 @@
+import os\r
+from wb import system, home_fn, choose_arch\r
+\r
+def build_ddk(config, dir, x64):\r
+    setenv_bat = os.path.realpath(os.path.join(config['DDK_PATH'], 'bin/setenv.bat'))\r
+    ddk_major = int(config['DDKVER_MAJOR'])\r
+    debug = 'PRODUCT_TAP_DEBUG' in config\r
+    target = 'chk' if debug else 'fre'\r
+    if x64:\r
+        target += ' x64'\r
+    else:\r
+        target += ' x86'\r
+    if ddk_major >= 7600:\r
+        if x64:\r
+            target += ' wlh'  # vista\r
+        else:\r
+            target += ' wnet' # server 2003\r
+    else:\r
+        if x64:\r
+            target += ' wnet' # server 2003\r
+        else:\r
+            target += ' w2k'  # 2000\r
+\r
+    system('cmd /c "%s %s %s && cd %s && build -cef"' % (\r
+           setenv_bat,\r
+           os.path.realpath(config['DDK_PATH']),\r
+           target,\r
+           dir\r
+           ))\r
+\r
+def main(config, proj, arch):\r
+    if proj == 'tap':\r
+        dir = home_fn('tap-win32')\r
+    elif proj == 'tapinstall':\r
+        dir = home_fn('tapinstall')\r
+    else:\r
+        raise ValueError("unknown project: %s" % (proj,))\r
+\r
+    for x64 in choose_arch(arch):\r
+        build_ddk(config, dir, x64)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    import sys\r
+    from wb import config\r
+    if len(sys.argv) >= 3:\r
+        main(config, sys.argv[1], sys.argv[2])\r
+    else:\r
+        print "usage: build <tap|tapinstall> <x64|x86|all>"\r
+        sys.exit(2)\r
diff --git a/win/config.py b/win/config.py
new file mode 100644 (file)
index 0000000..67c1d82
--- /dev/null
@@ -0,0 +1,17 @@
+from wb import preprocess, autogen, mod_fn, home_fn, build_autodefs, make_headers_objs, dict_def\r
+\r
+def main(config):\r
+    build_autodefs(config, mod_fn('autodefs.h.in'), home_fn('autodefs.h'))\r
+    ho = make_headers_objs(home_fn('Makefile.am'))\r
+\r
+    preprocess(dict_def(config, [('HEADERS_OBJS', ho)]),\r
+               in_fn=mod_fn('msvc.mak.in'),\r
+               out_fn=home_fn('msvc.mak'),\r
+               quote_begin='@',\r
+               quote_end='@',\r
+               head_comment='# %s\n\n' % autogen)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    from wb import config\r
+    main(config)\r
diff --git a/win/config_all.py b/win/config_all.py
new file mode 100644 (file)
index 0000000..2686780
--- /dev/null
@@ -0,0 +1,13 @@
+from config import main as config_main\r
+from config_tap import main as config_tap\r
+from config_ti import main as config_ti\r
+\r
+def main(config):\r
+    config_main(config)\r
+    config_tap(config)\r
+    config_ti(config)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    from wb import config\r
+    main(config)\r
diff --git a/win/config_tap.py b/win/config_tap.py
new file mode 100644 (file)
index 0000000..e69ee9b
--- /dev/null
@@ -0,0 +1,35 @@
+import os\r
+from wb import preprocess, home_fn, autogen, dict_def\r
+\r
+def main(config):\r
+    preprocess(config,\r
+               in_fn=home_fn('tap-win32/SOURCES.in'),\r
+               out_fn=home_fn('tap-win32/SOURCES'),\r
+               quote_begin='@@',\r
+               quote_end='@@',\r
+               head_comment='# %s\n\n' % autogen)\r
+\r
+    preprocess(config,\r
+               in_fn=home_fn('tap-win32/i386/OemWin2k.inf.in'),\r
+               out_fn=home_fn('tap-win32/i386/OemWin2k.inf'),\r
+               quote_begin='@@',\r
+               quote_end='@@',\r
+               if_prefix='!',\r
+               head_comment='; %s\n\n' % autogen)\r
+\r
+    try:\r
+        os.mkdir(home_fn('tap-win32/amd64'))\r
+    except:\r
+        pass\r
+    preprocess(dict_def(config, [('AMD64', '1')]),\r
+               in_fn=home_fn('tap-win32/i386/OemWin2k.inf.in'),\r
+               out_fn=home_fn('tap-win32/amd64/OemWin2k.inf'),\r
+               quote_begin='@@',\r
+               quote_end='@@',\r
+               if_prefix='!',\r
+               head_comment='; %s\n\n' % autogen)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    from wb import config\r
+    main(config)\r
diff --git a/win/config_ti.py b/win/config_ti.py
new file mode 100644 (file)
index 0000000..4facaff
--- /dev/null
@@ -0,0 +1,18 @@
+import os, shutil\r
+from wb import preprocess, home_fn, autogen\r
+\r
+def main(config):\r
+    src = os.path.join(home_fn(config['TISRC']), config['DDKVER_MAJOR'])\r
+    dest = home_fn('tapinstall')\r
+    shutil.rmtree(dest, ignore_errors=True)\r
+    shutil.copytree(src, dest)\r
+    preprocess(config,\r
+               in_fn=os.path.join(dest, 'sources.in'),\r
+               out_fn=os.path.join(dest, 'sources'),\r
+               if_prefix='!',\r
+               head_comment='# %s\n\n' % autogen)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    from wb import config\r
+    main(config)\r
diff --git a/win/js.py b/win/js.py
new file mode 100644 (file)
index 0000000..c515824
--- /dev/null
+++ b/win/js.py
@@ -0,0 +1,10 @@
+import json\r
+\r
+# usage:\r
+#   print JSON().encode(kv)\r
+\r
+class JSON(json.JSONEncoder):\r
+    def __init__(self, **kwargs):\r
+        args = dict(sort_keys=True, indent=2)\r
+        args.update(kwargs)\r
+        json.JSONEncoder.__init__(self, **args)\r
diff --git a/win/make_dist.py b/win/make_dist.py
new file mode 100644 (file)
index 0000000..3011279
--- /dev/null
@@ -0,0 +1,54 @@
+import os\r
+from wb import home_fn, rm_rf, mkdir, cp_a, cp\r
+\r
+def main(config):\r
+    dist = config['DIST']\r
+    assert dist\r
+    dist = home_fn(dist)\r
+    bin = os.path.join(dist, 'bin')\r
+    i386 = os.path.join(dist, 'i386')\r
+    amd64 = os.path.join(dist, 'amd64')\r
+\r
+    # build dist and subdirectories\r
+    rm_rf(dist)\r
+    mkdir(dist)\r
+    mkdir(bin)\r
+    mkdir(i386)\r
+    mkdir(amd64)\r
+\r
+    # copy openvpn.exe and manifest\r
+    cp(home_fn('openvpn.exe'), bin)\r
+    cp(home_fn('openvpn.exe.manifest'), bin)\r
+\r
+    # copy DLL dependencies\r
+    cp(home_fn(config['LZO_DIR']+'/bin/lzo2.dll'), bin)\r
+    cp(home_fn(config['OPENSSL_DIR']+'/bin/libeay32.dll'), bin)\r
+    cp(home_fn(config['OPENSSL_DIR']+'/bin/ssleay32.dll'), bin)\r
+\r
+    # copy MSVC CRT\r
+    cp_a(home_fn(config['MSVC_CRT']), bin)\r
+\r
+    # copy TAP drivers\r
+    for dir_name, dest in (('amd64', amd64), ('i386', i386)):\r
+        dir = home_fn(os.path.join('tap-win32', dir_name))\r
+        for dirpath, dirnames, filenames in os.walk(dir):\r
+            for f in filenames:\r
+                root, ext = os.path.splitext(f)\r
+                if ext in ('.inf', '.cat', '.sys'):\r
+                    cp(os.path.join(dir, f), dest)\r
+            break\r
+\r
+    # copy tapinstall\r
+    dest = {'amd64' : amd64, 'i386' : i386}\r
+    for dirpath, dirnames, filenames in os.walk(home_fn('tapinstall')):\r
+        for f in filenames:\r
+            if f == 'tapinstall.exe':\r
+                dir_name = os.path.basename(dirpath)\r
+                src = os.path.join(dirpath, f)\r
+                if dir_name in dest:\r
+                    cp(src, dest[dir_name])\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    from wb import config\r
+    main(config)\r
diff --git a/win/msvc.mak.in b/win/msvc.mak.in
new file mode 100644 (file)
index 0000000..3f8102a
--- /dev/null
@@ -0,0 +1,52 @@
+# This makefile builds the user-mode component\r
+# of OpenVPN for Windows in the Visual Studio 2008 environment.\r
+\r
+# To build:\r
+#    python win\config.py\r
+#    nmake /f msvc.mak\r
+\r
+# Each of the OPENSSL and LZO dirs should have 'lib' and 'include'\r
+# directories under them.\r
+\r
+OPENSSL = @OPENSSL_DIR@\r
+OPENSSL_DYNAMIC = libeay32.lib ssleay32.lib\r
+\r
+LZO = @LZO_DIR@\r
+LZO_DYNAMIC = lzo2.lib\r
+\r
+INCLUDE_DIRS = -I$(OPENSSL)/include -I$(LZO)/include\r
+\r
+LIBS = $(OPENSSL_DYNAMIC) $(LZO_DYNAMIC) ws2_32.lib crypt32.lib iphlpapi.lib winmm.lib user32.lib gdi32.lib advapi32.lib wininet.lib\r
+\r
+LIB_DIRS = -LIBPATH:$(OPENSSL)\lib -LIBPATH:$(LZO)\lib\r
+\r
+EXE = openvpn.exe\r
+\r
+CPP=cl.exe\r
+CPP_ARG_COMMON=/nologo /W3 /O2 -DWIN32 -DWIN32_LEAN_AND_MEAN -D_CONSOLE -D_MBCS -D_CRT_SECURE_NO_DEPRECATE $(INCLUDE_DIRS) /FD /c\r
+# release:\r
+CPP_PROJ=$(CPP_ARG_COMMON) /MD -DNDEBUG\r
+# debug:\r
+#CPP_PROJ=$(CPP_ARG_COMMON) /MDd /Zi /Od -D_DEBUG\r
+\r
+LINK32=link.exe\r
+# release:\r
+LINK32_FLAGS=/nologo /subsystem:console /incremental:no /out:"$(EXE)"\r
+# debug:\r
+#LINK32_FLAGS=/nologo /subsystem:console /incremental:no /debug /out:"$(EXE)"\r
+\r
+# HEADERS and OBJS definitions, automatically generated\r
+@HEADERS_OBJS@\r
+\r
+openvpn : $(OBJS)\r
+       $(LINK32) @<<\r
+       $(LINK32_FLAGS) $(LIB_DIRS) $(LIBS) $(OBJS)\r
+<<\r
+\r
+clean :\r
+       del /Q $(OBJS) $(EXE) *.idb *.pdb\r
+\r
+.c.obj::\r
+   $(CPP) @<<\r
+   $(CPP_PROJ) $<\r
+<<\r
diff --git a/win/settings.in b/win/settings.in
new file mode 100644 (file)
index 0000000..044834a
--- /dev/null
@@ -0,0 +1,62 @@
+# Version numbers, settings, and dependencies
+# for Windows OpenVPN installer.
+
+# Branding
+!define PRODUCT_NAME      "OpenVPN"
+!define PRODUCT_UNIX_NAME "openvpn"
+!define PRODUCT_FILE_EXT  "ovpn"
+
+# Allow --askpass and --auth-user-pass passwords to be read from a file
+;!define ENABLE_PASSWORD_SAVE
+
+# Include the OpenVPN GUI exe in the installer.
+# May be undefined.
+!define OPENVPN_GUI_DIR "../openvpn-gui"
+!define OPENVPN_GUI     "openvpn-gui-1.0.3.exe"
+
+# Prebuilt libraries.  DMALLOC is optional.
+!define OPENSSL_DIR      "../openssl"
+!define LZO_DIR                  "../lzo"
+
+# write output files here
+!define DIST   "dist"
+
+# tapinstall.exe source code.
+# Not needed if DRVBINSRC is defined
+# (or if using pre-built mode).
+!define TISRC  "../tapinstall"
+
+# TAP Adapter parameters.  Note that PRODUCT_TAP_ID is
+# defined in version.m4.
+!define PRODUCT_TAP_DEVICE_DESCRIPTION  "TAP-Win32 Adapter V9"
+!define PRODUCT_TAP_PROVIDER            "TAP-Win32 Provider V9"
+!define PRODUCT_TAP_MAJOR_VER           9
+!define PRODUCT_TAP_MINOR_VER           7
+!define PRODUCT_TAP_RELDATE             "04/19/2010"
+
+# TAP adapter icon -- visible=0x81 or hidden=0x89
+!define PRODUCT_TAP_CHARACTERISTICS     0x81
+
+# Build debugging version of TAP driver
+;!define PRODUCT_TAP_DEBUG
+
+# DDK path -- currently Windows 7 WDK
+!define DDK_PATH "c:/winddk/7600.16385.1"
+;!define DDK_PATH "c:/winddk/6001.18002"
+
+# Visual studio path
+!define MSVC "C:/Program Files/Microsoft Visual Studio 9.0"
+
+# Visual studio C run-time library path
+!define MSVC_CRT "../Microsoft.VC90.CRT"
+
+# Code Signing.
+# If undefined, don't sign any files.
+!define SIGNTOOL        "../signtool"
+!define PRODUCT_SIGN_CN "openvpn"
+
+; DEBUGGING -- set to something like "-DBG2"
+!define OUTFILE_LABEL ""
+
+; DEBUGGING -- set to something like "DEBUG2"
+!define TITLE_LABEL ""
diff --git a/win/show.py b/win/show.py
new file mode 100644 (file)
index 0000000..9558c87
--- /dev/null
@@ -0,0 +1,10 @@
+from wb import get_config\r
+from js import JSON\r
+\r
+def main():\r
+    kv = get_config()\r
+    print JSON().encode(kv)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    main()\r
diff --git a/win/sign.py b/win/sign.py
new file mode 100644 (file)
index 0000000..ee4ae72
--- /dev/null
@@ -0,0 +1,19 @@
+import sys\r
+from wb import config, choose_arch, home_fn\r
+\r
+if 'SIGNTOOL' in config:\r
+    sys.path.append(home_fn(config['SIGNTOOL']))\r
+\r
+def main(conf, arch):\r
+    from signtool import SignTool\r
+    st = SignTool(conf)\r
+    for x64 in choose_arch(arch):\r
+        st.sign_verify(x64=x64)\r
+\r
+# if we are run directly, and not loaded as a module\r
+if __name__ == "__main__":\r
+    if len(sys.argv) >= 2:\r
+        main(config, sys.argv[1])\r
+    else:\r
+        print "usage: sign <x64|x86|all>"\r
+        sys.exit(2)\r
diff --git a/win/wb.py b/win/wb.py
new file mode 100644 (file)
index 0000000..7c2c8b9
--- /dev/null
+++ b/win/wb.py
@@ -0,0 +1,185 @@
+# Python module containing general build functions\r
+# for OpenVPN on Windows\r
+\r
+import os, re, shutil\r
+\r
+autogen = "Automatically generated by OpenVPN Windows build system"\r
+\r
+def get_config():\r
+    kv = {}\r
+    parse_version_m4(kv, home_fn('version.m4'))\r
+    parse_settings_in(kv, mod_fn('settings.in'))\r
+\r
+    # config fixups\r
+    kv['DDKVER'] = os.path.basename(kv['DDK_PATH'])\r
+    kv['DDKVER_MAJOR'] = re.match(r'^(\d+)\.', kv['DDKVER']).groups()[0]\r
+\r
+    if 'VERSION_SUFFIX' in kv:\r
+        kv['PRODUCT_VERSION'] += kv['VERSION_SUFFIX']\r
+\r
+    return kv\r
+\r
+def mod_fn(fn, src=__file__, real=True):\r
+    p = os.path.join(os.path.dirname(src), os.path.normpath(fn))\r
+    if real:\r
+        p = os.path.realpath(p)\r
+    return p\r
+\r
+def home_fn(fn, real=True):\r
+    return mod_fn(os.path.join('..', fn), real=real)\r
+\r
+def cd_home():\r
+    os.chdir(os.path.join(os.path.dirname(__file__), '..'))\r
+\r
+def system(cmd):\r
+    print "RUN:", cmd\r
+    os.system(cmd)\r
+\r
+def parse_version_m4(kv, version_m4):\r
+    r = re.compile(r'^define\((\w+),\[(.*)\]\)$')\r
+    f = open(version_m4)\r
+    for line in f:\r
+        line = line.rstrip()\r
+        m = re.match(r, line)\r
+        if m:\r
+            g = m.groups()\r
+            kv[g[0]] = g[1]\r
+    f.close()\r
+\r
+def parse_settings_in(kv, settings_in):\r
+    r = re.compile(r'^!define\s+(\w+)(?:\s+"?(.*?)"?)?$')\r
+    f = open(settings_in)\r
+    for line in f:\r
+        line = line.rstrip()\r
+        m = re.match(r, line)\r
+        if m:\r
+            g = m.groups()\r
+            kv[g[0]] = g[1] or ''\r
+    f.close()\r
+\r
+def dict_def(dict, newdefs):\r
+    ret = dict.copy()\r
+    ret.update(newdefs)\r
+    return ret\r
+\r
+def build_autodefs(kv, autodefs_in, autodefs_out):\r
+    preprocess(kv,\r
+               in_fn=autodefs_in,\r
+               out_fn=autodefs_out,\r
+               quote_begin='@',\r
+               quote_end='@',\r
+               head_comment='/* %s */\n\n' % autogen)\r
+\r
+def preprocess(kv, in_fn, out_fn, quote_begin=None, quote_end=None, if_prefix=None, head_comment=None):\r
+    def repfn(m):\r
+        var, = m.groups()\r
+        return kv.get(var, '')\r
+\r
+    re_macro = re_ifdef = None\r
+\r
+    if quote_begin and quote_end:\r
+        re_macro = re.compile(r'%s(\w+)%s' % (re.escape(quote_begin), re.escape(quote_end)))\r
+\r
+    if if_prefix:\r
+        re_ifdef = re.compile(r'^\s*%sifdef\s+(\w+)\b' % (re.escape(if_prefix),))\r
+        re_else = re.compile(r'^\s*%selse\b' % (re.escape(if_prefix),))\r
+        re_endif = re.compile(r'^\s*%sendif\b' % (re.escape(if_prefix),))\r
+\r
+    if_stack = []\r
+    fin = open(in_fn)\r
+    fout = open(out_fn, 'w')\r
+    if head_comment:\r
+        fout.write(head_comment)\r
+    for line in fin:\r
+        if re_ifdef:\r
+            m = re.match(re_ifdef, line)\r
+            if m:\r
+                var, = m.groups()\r
+                if_stack.append(int(var in kv))\r
+                continue\r
+            elif re.match(re_else, line):\r
+                if_stack[-1] ^= 1\r
+                continue\r
+            elif re.match(re_endif, line):\r
+                if_stack.pop()\r
+                continue\r
+        if not if_stack or min(if_stack):\r
+            if re_macro:\r
+                line = re.sub(re_macro, repfn, line)\r
+            fout.write(line)\r
+    assert not if_stack\r
+    fin.close()\r
+    fout.close()\r
+\r
+def print_key_values(kv):\r
+    for k, v in sorted(kv.items()):\r
+        print "%s%s%s" % (k, ' '*(32-len(k)), repr(v))\r
+\r
+def get_sources(makefile_am):\r
+    c = set()\r
+    h = set()\r
+    f = open(makefile_am)\r
+    state = False\r
+    for line in f:\r
+        line = line.rstrip()\r
+        if line == 'openvpn_SOURCES = \\':\r
+            state = True\r
+        elif not line:\r
+            state = False\r
+        elif state:\r
+            for sf in line.split():\r
+                if sf.endswith('.c'):\r
+                    c.add(sf[:-2])\r
+                elif sf.endswith('.h'):\r
+                    h.add(sf[:-2])\r
+                elif sf == '\\':\r
+                    pass\r
+                else:\r
+                    print >>sys.stderr, "Unrecognized filename:", sf\r
+    f.close()\r
+    return [ sorted(list(s)) for s in (c, h) ]\r
+\r
+def output_mak_list(title, srclist, ext):\r
+    ret = "%s =" % (title,)\r
+    for x in srclist:\r
+        ret += " \\\n\t%s.%s" % (x, ext)\r
+    ret += '\n\n'\r
+    return ret\r
+\r
+def make_headers_objs(makefile_am):\r
+    c, h = get_sources(makefile_am)\r
+    ret = output_mak_list('HEADERS', h, 'h')\r
+    ret += output_mak_list('OBJS', c, 'obj')\r
+    return ret\r
+\r
+def choose_arch(arch_name):\r
+    if arch_name == 'x64':\r
+        return (True,)\r
+    elif arch_name == 'x86':\r
+        return (False,)\r
+    elif arch_name == 'all':\r
+        return (True, False)\r
+    else:\r
+        raise ValueError("architecture ('%s') must be x86, x64, or all" % (arch_name,))\r
+\r
+def rm_rf(dir):\r
+    print "REMOVE", dir\r
+    shutil.rmtree(dir, ignore_errors=True)\r
+\r
+def mkdir(dir):\r
+    print "MKDIR", dir\r
+    os.mkdir(dir)\r
+\r
+def cp_a(src, dest, dest_is_dir=True):\r
+    if dest_is_dir:\r
+        dest = os.path.join(dest, os.path.basename(src))\r
+    print "COPY_DIR %s %s" % (src, dest)\r
+    shutil.copytree(src, dest)\r
+\r
+def cp(src, dest, dest_is_dir=True):\r
+    if dest_is_dir:\r
+        dest = os.path.join(dest, os.path.basename(src))\r
+    print "COPY %s %s" % (src, dest)\r
+    shutil.copyfile(src, dest)\r
+\r
+config = get_config()\r