Hi all,

Here's the first of a set of six patches that fix various issues with
the Python-based build system. Also, some clarifying comments have been
added to the existing code. After this patchset is merged it's possible
to build openvpnserv.exe in addition to openvpn.exe and the TAP drivers.
NSI installer integration is still mostly missing, but is coming up.

This patch could be simplified by removing the #ifdef / #ifndef "depth"
detection code. That code is a leftover from earlier implementation
where all defines - not just #define ENABLE_SOMETHING - were parsed. The
idea was to skip any defines inside an #ifdef block as there is no
(easy) way to detect if they're enabled or not.

Samuli
From 6a42c8c5aa90296be8d6a383d410414c8d9800c7 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Samuli=20Sepp=C3=A4nen?= <sam...@openvpn.net>
Date: Mon, 3 Jan 2011 15:52:59 +0200
Subject: [PATCH 1/6] Added automated configure.h creation to Python-based build system.

The configure.h file is generated from config-win32 and is used to embed build
flags into openvpn. These build flags can be viewed with "openvpn --version".
Only defines that start with ENABLE are included (e.g. "ENABLE_MANAGEMENT 1").
---
 win/config.py |    3 +-
 win/wb.py     |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/win/config.py b/win/config.py
index cf38cac..c9956cc 100644
--- a/win/config.py
+++ b/win/config.py
@@ -1,6 +1,7 @@
-from wb import preprocess, autogen, mod_fn, home_fn, build_autodefs, make_headers_objs, dict_def
+from wb import preprocess, autogen, mod_fn, home_fn, build_configure_h, build_autodefs, make_headers_objs, dict_def
 
 def main(config):
+    build_configure_h(config, mod_fn(home_fn('configure.h')), head_comment='/* %s */\n\n' % autogen)
     build_autodefs(config, mod_fn('autodefs.h.in'), home_fn('autodefs.h'))
     ho = make_headers_objs(home_fn('Makefile.am'))
 
diff --git a/win/wb.py b/win/wb.py
index 8e23684..f673bba 100644
--- a/win/wb.py
+++ b/win/wb.py
@@ -19,6 +19,12 @@ def get_config():
 
     return kv
 
+def get_build_params():
+    kv = {}
+    parse_config_win32_h(kv,home_fn('config-win32.h'))
+
+    return kv
+
 def mod_fn(fn, src=__file__, real=True):
     p = os.path.join(os.path.dirname(src), os.path.normpath(fn))
     if real:
@@ -57,6 +63,40 @@ def parse_settings_in(kv, settings_in):
             kv[g[0]] = g[1] or ''
     f.close()
 
+def parse_config_win32_h(kv, config_win32_h):
+    r = re.compile(r'^#define\s+(ENABLE_\w+)\s+(\w+)')
+    s = re.compile(r'^#ifdef|^#ifndef')
+    e = re.compile(r'^#endif')
+
+    # How "deep" in nested conditional statements are we?
+    depth=0
+
+    f = open(config_win32_h)
+
+    for line in f:
+	line = line.rstrip()
+
+	# Check if this is a #define line
+        m = re.match(r, line)
+
+	# Calculate how deep we're in (nested) conditional statements. A simple 
+	# #ifdef/#endif state switcher would get confused by an #endif followed 
+	# by a #define.
+	if re.match(s, line):
+		depth=depth+1
+	if re.match(e, line):
+		depth=depth-1
+	
+        if m:
+	    # Only add this #define if it's not inside a conditional statement 
+	    # block
+	    if depth == 0:
+		    g = m.groups()
+        	    kv[g[0]] = g[1] or ''
+    f.close()
+
+
+
 def dict_def(dict, newdefs):
     ret = dict.copy()
     ret.update(newdefs)
@@ -70,6 +110,26 @@ def build_autodefs(kv, autodefs_in, autodefs_out):
                quote_end='@',
                head_comment='/* %s */\n\n' % autogen)
 
+'''Generate a fake configure.h dynamically'''
+def build_configure_h(kv, configure_h_out, head_comment):
+    fout = open(configure_h_out, 'w')
+    configure_defines='#define CONFIGURE_DEFINES \"'
+    configure_call='#define CONFIGURE_CALL \" config_all.py \"'
+
+    fout.write(head_comment)
+
+    dict = get_build_params()
+
+    for key, value in dict.iteritems():
+        configure_defines = configure_defines + " " + key + "=" + value + ","
+
+    configure_defines = configure_defines + "\"" + "\n"
+
+    fout.write(configure_defines)
+    fout.write(configure_call)
+    fout.close()
+
+
 def preprocess(kv, in_fn, out_fn, quote_begin=None, quote_end=None, if_prefix=None, head_comment=None):
     def repfn(m):
         var, = m.groups()
@@ -115,6 +175,7 @@ def print_key_values(kv):
     for k, v in sorted(kv.items()):
         print "%s%s%s" % (k, ' '*(32-len(k)), repr(v))
 
+'''Parse ../Makefile.am to obtain a list of .h and .c files. Returns a list.'''
 def get_sources(makefile_am):
     c = set()
     h = set()
@@ -146,6 +207,7 @@ def output_mak_list(title, srclist, ext):
     ret += '\n\n'
     return ret
 
+'''Generate HEADER and OBJS entries dynamically from ../Makefile.am'''
 def make_headers_objs(makefile_am):
     c, h = get_sources(makefile_am)
     ret = output_mak_list('HEADERS', h, 'h')
-- 
1.6.3.3

Reply via email to