diff options
author | lloyd <[email protected]> | 2009-12-16 02:52:12 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-12-16 02:52:12 +0000 |
commit | 317b76d71dca1840c9e72f9a26407590719c1423 (patch) | |
tree | 2eb49072e6e27f6ee41e704004aa8689b1e98bb3 /configure.py | |
parent | 457ce43934a4e51ead4d21e43013eef9d448d0e1 (diff) | |
parent | 12afeca214c4414a0ced0bc4654d0fc5908dc77b (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-x | configure.py | 226 |
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)) |