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
*************************************************************************
# 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
# 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
done
cat /dev/null >autodefs/guidefs.nsi
+
+echo '#include "autodefs/defs.h"' >autodefs.h
+echo '#include "config.h"' >>autodefs.h
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
!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
// 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
#include <ntverp.h>
/* get VERSION */
-#include "../config-win32.h"
#include "common.h"
/* VER_FILETYPE, VER_FILESUBTYPE, VER_FILEDESCRIPTION_STR
#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."
#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)"
// 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
#include "lock.h"
#include "constants.h"
-#include "common.h"
#include "proto.h"
#include "error.h"
#include "endian.h"
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;
}
{
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,
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])
--- /dev/null
+#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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+# 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
--- /dev/null
+# 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 ""
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+# 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