aboutsummaryrefslogtreecommitdiffstats
path: root/configure.py
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-12-16 02:52:12 +0000
committerlloyd <[email protected]>2009-12-16 02:52:12 +0000
commit317b76d71dca1840c9e72f9a26407590719c1423 (patch)
tree2eb49072e6e27f6ee41e704004aa8689b1e98bb3 /configure.py
parent457ce43934a4e51ead4d21e43013eef9d448d0e1 (diff)
parent12afeca214c4414a0ced0bc4654d0fc5908dc77b (diff)
propagate from branch 'net.randombit.botan' (head 744dccf92270cf16b80b50ee2759424c9866b256)
to branch 'net.randombit.botan.c++0x' (head 2aa1acac1d05e8ea9991fe39015b1db9abc3b24e)
Diffstat (limited to 'configure.py')
-rwxr-xr-xconfigure.py226
1 files changed, 196 insertions, 30 deletions
diff --git a/configure.py b/configure.py
index 6e05f5246..5298f7eb3 100755
--- a/configure.py
+++ b/configure.py
@@ -30,6 +30,9 @@ import time
from optparse import (OptionParser, OptionGroup,
IndentedHelpFormatter, SUPPRESS_HELP)
+def flatten(l):
+ return sum(l, [])
+
class BuildConfigurationInformation(object):
"""
@@ -62,14 +65,12 @@ class BuildConfigurationInformation(object):
self.pyobject_dir = os.path.join(self.build_dir, 'python')
self.include_dir = os.path.join(self.build_dir, 'include')
- self.full_include_dir = os.path.join(self.include_dir, 'botan')
-
- all_files = sum([mod.add for mod in modules], [])
+ self.botan_include_dir = os.path.join(self.include_dir, 'botan')
+ self.internal_include_dir = os.path.join(self.botan_include_dir, 'internal')
- self.headers = sorted(
- [file for file in all_files if file.endswith('.h')])
-
- self.sources = sorted(set(all_files) - set(self.headers))
+ self.sources = sorted(flatten([mod.sources() for mod in modules]))
+ self.public_headers = sorted(flatten([m.public_headers() for m in modules]))
+ self.internal_headers = sorted(flatten([m.internal_headers() for m in modules]))
checks_dir = os.path.join(options.base_dir, 'checks')
@@ -101,7 +102,8 @@ class BuildConfigurationInformation(object):
def build_dirs(self):
dirs = [self.checkobj_dir,
self.libobj_dir,
- self.full_include_dir]
+ self.botan_include_dir,
+ self.internal_include_dir]
if self.use_boost_python:
dirs.append(self.pyobject_dir)
return dirs
@@ -146,7 +148,7 @@ def process_command_line(args):
target_group.add_option('--with-isa-extension', metavar='ISALIST',
dest='with_isa_extns',
action='append', default=[],
- help='enable ISA extensions (sse2, altivec, ...)')
+ help='enable ISA extensions (sse2, altivec)')
build_group = OptionGroup(parser, 'Build options')
@@ -174,6 +176,10 @@ def process_command_line(args):
default=False, action='store_true',
help='enable Boost.Python wrapper')
+ build_group.add_option('--gen-amalgamation', dest='gen_amalgamation',
+ default=False, action='store_true',
+ help='generate amalgamation files')
+
build_group.add_option('--with-build-dir',
metavar='DIR', default='',
help='setup the build in DIR')
@@ -273,7 +279,7 @@ def process_command_line(args):
options.with_endian))
def parse_multiple_enable(modules):
- return sorted(set(sum([s.split(',') for s in modules], [])))
+ return sorted(set(flatten([s.split(',') for s in modules])))
options.enabled_modules = parse_multiple_enable(options.enabled_modules)
options.disabled_modules = parse_multiple_enable(options.disabled_modules)
@@ -287,6 +293,10 @@ Generic lexer function for info.txt and src/build-data files
"""
def lex_me_harder(infofile, to_obj, allowed_groups, name_val_pairs):
+ # Format as a nameable Python variable
+ def py_var(group):
+ return group.replace(':', '_')
+
class LexerError(Exception):
def __init__(self, msg, line):
self.msg = msg
@@ -311,7 +321,7 @@ def lex_me_harder(infofile, to_obj, allowed_groups, name_val_pairs):
lexer.wordchars += '|:.<>/,-!+' # handle various funky chars in info.txt
for group in allowed_groups:
- to_obj.__dict__[group] = []
+ to_obj.__dict__[py_var(group)] = []
for (key,val) in name_val_pairs.items():
to_obj.__dict__[key] = val
@@ -336,7 +346,7 @@ def lex_me_harder(infofile, to_obj, allowed_groups, name_val_pairs):
token = lexer.get_token()
while token != end_marker:
- to_obj.__dict__[group].append(token)
+ to_obj.__dict__[py_var(group)].append(token)
token = lexer.get_token()
if token is None:
raise LexerError('Group "%s" not terminated' % (group),
@@ -360,20 +370,28 @@ class ModuleInfo(object):
def __init__(self, infofile):
lex_me_harder(infofile, self,
- ['add', 'requires', 'os', 'arch', 'cc', 'libs'],
+ ['source', 'header:internal', 'header:public',
+ 'requires', 'os', 'arch', 'cc', 'libs'],
{ 'load_on': 'auto',
'define': None,
'need_isa': None,
'mp_bits': 0 })
- if self.add == []:
+ if self.source == [] and \
+ self.header_internal == [] and \
+ self.header_public == []:
+
for (dirpath, dirnames, filenames) in os.walk(self.lives_in):
if dirpath == self.lives_in:
- self.add = [filename for filename in filenames
- if (filename.endswith('.cpp') or
- filename.endswith('.h') or
- filename.endswith('.S'))
- and not filename.startswith('.')]
+ for filename in filenames:
+ if filename.startswith('.'):
+ continue
+
+ if filename.endswith('.cpp') or \
+ filename.endswith('.S'):
+ self.source.append(filename)
+ elif filename.endswith('.h'):
+ self.header_public.append(filename)
# Coerce to more useful types
def convert_lib_list(l):
@@ -397,10 +415,24 @@ class ModuleInfo(object):
return os.path.join(os.path.split(self.lives_in)[0],
*filename.split(':'))
- self.add = map(add_dir_name, self.add)
+ self.source = map(add_dir_name, self.source)
+ self.header_internal = map(add_dir_name, self.header_internal)
+ self.header_public = map(add_dir_name, self.header_public)
+
+ if len([f for f in self.source if f.endswith('h')]) > 0:
+ print self.lives_in
self.mp_bits = int(self.mp_bits)
+ def sources(self):
+ return self.source
+
+ def public_headers(self):
+ return self.header_public
+
+ def internal_headers(self):
+ return self.header_internal
+
def compatible_cpu(self, archinfo, options):
arch_name = archinfo.basename
@@ -437,7 +469,7 @@ class ModuleInfo(object):
def dependencies_exist(self, modules):
all_deps = map(lambda s: s.split('|'), self.dependencies())
- for missing in filter(lambda s: s not in modules, sum(all_deps, [])):
+ for missing in filter(lambda s: s not in modules, flatten(all_deps)):
logging.warn("Module '%s', dep of '%s', does not exist" % (
missing, self.basename))
@@ -501,9 +533,8 @@ class ArchInfo(object):
macros.append('TARGET_CPU_IS_%s' % (form_cpu_macro(options.cpu)))
isa_extensions = sorted(set(
- sum([self.isa_extensions_in(options.cpu),
- options.with_isa_extns],
- [])))
+ flatten([self.isa_extensions_in(options.cpu),
+ options.with_isa_extns])))
for simd in isa_extensions:
macros.append('TARGET_CPU_HAS_%s' % (simd.upper()))
@@ -852,7 +883,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo):
'target_cpu_defines': make_cpp_macros(arch.defines(options)),
- 'include_files': makefile_list(build_config.headers),
+ 'include_files': makefile_list(build_config.public_headers),
'lib_objs': makefile_list(
objectfile_list(build_config.sources,
@@ -1133,11 +1164,143 @@ def setup_build(build_config, options, template_vars):
finally:
f.close()
- logging.debug('Linking %d header files in %s' % (
- len(build_config.headers), build_config.full_include_dir))
+ logging.debug('Linking %d public header files in %s' % (
+ len(build_config.public_headers), build_config.botan_include_dir))
+
+ for header_file in build_config.public_headers:
+ portable_symlink(header_file, build_config.botan_include_dir)
+
+ logging.debug('Linking %d internal header files in %s' % (
+ len(build_config.internal_headers), build_config.internal_include_dir))
+
+ for header_file in build_config.internal_headers:
+ portable_symlink(header_file, build_config.internal_include_dir)
+
+"""
+Generate Amalgamation
+"""
+def generate_amalgamation(build_config):
+ def ending_with_suffix(suffix):
+ def predicate(val):
+ return val.endswith(suffix)
+ return predicate
+
+ def strip_header_goop(contents):
+ header_guard = re.compile('^#define BOTAN_.*_H__$')
+
+ while len(contents) > 0:
+ if header_guard.match(contents[0]):
+ contents = contents[1:]
+ break
+
+ contents = contents[1:]
+
+ while contents[0] == '\n':
+ contents = contents[1:]
+
+ while contents[-1] == '\n':
+ contents = contents[0:-1]
+ if contents[-1] == '#endif\n':
+ contents = contents[0:-1]
+
+ return contents
+
+ botan_include = re.compile('#include <botan/(.*)>$')
+ std_include = re.compile('#include <([^/\.]+)>$')
+
+ class Amalgamation_Generator:
+ def __init__(self, input_list):
+
+ self.included_already = set()
+ self.all_std_includes = set()
+
+ self.file_contents = {}
+ for f in sorted(input_list):
+ contents = strip_header_goop(open(f).readlines())
+ self.file_contents[os.path.basename(f)] = contents
+
+ self.contents = ''
+ for name in self.file_contents:
+ self.contents += ''.join(list(self.header_contents(name)))
+
+ self.header_includes = ''
+ for std_header in self.all_std_includes:
+ self.header_includes += '#include <%s>\n' % (std_header)
+ self.header_includes += '\n'
+
+ def header_contents(self, name):
+ name = name.replace('internal/', '')
+
+ if name in self.included_already:
+ return
+
+ self.included_already.add(name)
+
+ if name not in self.file_contents:
+ return
+
+ for line in self.file_contents[name]:
+ match = botan_include.search(line)
+ if match:
+ for c in self.header_contents(match.group(1)):
+ yield c
+ else:
+ match = std_include.search(line)
+
+ if match:
+ self.all_std_includes.add(match.group(1))
+ else:
+ yield line
+
+ botan_all_h = open('botan_all.h', 'w')
+
+ pub_header_amalag = Amalgamation_Generator(build_config.public_headers)
+
+ amalg_header = """/*
+* Botan %s Amalgamation
+* (C) 1999-2009 Jack Lloyd and others
+*
+* Distributed under the terms of the Botan license
+*/
+""" % (build_config.version_string)
+
+ botan_all_h.write(amalg_header)
+
+ botan_all_h.write("""
+#ifndef BOTAN_AMALGAMATION_H__
+#define BOTAN_AMALGAMATION_H__
+
+""")
+
+ botan_all_h.write(pub_header_amalag.header_includes)
+ botan_all_h.write(pub_header_amalag.contents)
+ botan_all_h.write("\n#endif\n")
+
+ internal_header_amalag = Amalgamation_Generator(
+ filter(lambda s: s.find('asm_macr_') == -1,
+ build_config.internal_headers))
+
+ botan_all_cpp = open('botan_all.cpp', 'w')
+
+ botan_all_cpp.write(amalg_header)
+
+ botan_all_cpp.write('#include "botan_all.h"\n')
+
+ botan_all_cpp.write(internal_header_amalag.header_includes)
+ botan_all_cpp.write(internal_header_amalag.contents)
+
+
+ for src in build_config.sources:
+ if src.endswith('.S'):
+ continue
+
+ contents = open(src).readlines()
+ for line in contents:
+ if botan_include.search(line):
+ continue
+ else:
+ botan_all_cpp.write(line)
- for header_file in build_config.headers:
- portable_symlink(header_file, build_config.full_include_dir)
"""
Main driver
@@ -1240,7 +1403,7 @@ def main(argv = None):
options)
build_config = BuildConfigurationInformation(options, modules_to_use)
- build_config.headers.append(
+ build_config.public_headers.append(
os.path.join(build_config.build_dir, 'build.h'))
template_vars = create_template_vars(build_config, options,
@@ -1252,6 +1415,9 @@ def main(argv = None):
# Performs the I/O
setup_build(build_config, options, template_vars)
+ if options.gen_amalgamation:
+ generate_amalgamation(build_config)
+
logging.info('Botan %s build setup is complete' % (
build_config.version_string))