diff options
Diffstat (limited to 'configure.py')
-rwxr-xr-x | configure.py | 145 |
1 files changed, 85 insertions, 60 deletions
diff --git a/configure.py b/configure.py index 529d3efe1..4739a8937 100755 --- a/configure.py +++ b/configure.py @@ -359,6 +359,10 @@ def process_command_line(args): mods_group = optparse.OptionGroup(parser, 'Module selection') + mods_group.add_option('--module-policy', dest='module_policy', + help="module policy file (see src/build-data/policy)", + metavar='POL', default=None) + mods_group.add_option('--enable-modules', dest='enabled_modules', metavar='MODS', action='append', help='enable specific modules') @@ -715,6 +719,11 @@ class ModuleInfo(object): return 0 return 1 +class ModulePolicyInfo(object): + def __init__(self, infofile): + lex_me_harder(infofile, self, + ['required', 'if_available', 'prohibited'], {}) + class ArchInfo(object): def __init__(self, infofile): lex_me_harder(infofile, self, @@ -1398,7 +1407,7 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): """ Determine which modules to load based on options, target, etc """ -def choose_modules_to_use(modules, archinfo, ccinfo, options): +def choose_modules_to_use(modules, module_policy, archinfo, ccinfo, options): for mod in modules.values(): mod.dependencies_exist(modules) @@ -1410,6 +1419,18 @@ def choose_modules_to_use(modules, archinfo, ccinfo, options): def cannot_use_because(mod, reason): not_using_because.setdefault(reason, []).append(mod) + def check_usable(module, modname, options): + if not module.compatible_os(options.os): + cannot_use_because(modname, 'incompatible OS') + return False + elif not module.compatible_compiler(ccinfo, archinfo.basename): + cannot_use_because(modname, 'incompatible compiler') + return False + elif not module.compatible_cpu(archinfo, options): + cannot_use_because(modname, 'incompatible CPU') + return False + return True + for modname in options.enabled_modules: if modname not in modules: logging.error("Module not found: %s" % (modname)) @@ -1419,19 +1440,35 @@ def choose_modules_to_use(modules, archinfo, ccinfo, options): logging.warning("Disabled module not found: %s" % (modname)) for (modname, module) in modules.items(): + usable = check_usable(module, modname, options) + + if module_policy is not None: + + if modname in module_policy.required: + if not usable: + logging.error('Module policy requires module %s not usable on this platform' % (modname)) + elif modname in options.disabled_modules: + logging.error('Module %s was disabled but is required by policy' % (modname)) + to_load.append(modname) + continue + elif modname in module_policy.if_available: + if modname in options.disabled_modules: + cannot_use_because(modname, 'disabled by user') + elif usable: + logging.debug('Enabling optional module %s' % (modname)) + to_load.append(modname) + continue + elif modname in module_policy.prohibited: + if modname in options.enabled_modules: + logging.error('Module %s was requested but is prohibited by policy' % (modname)) + cannot_use_because(modname, 'prohibited by module policy') + continue + if modname in options.disabled_modules: cannot_use_because(modname, 'disabled by user') elif modname in options.enabled_modules: to_load.append(modname) # trust the user - - elif not module.compatible_os(options.os): - cannot_use_because(modname, 'incompatible OS') - elif not module.compatible_compiler(ccinfo, archinfo.basename): - cannot_use_because(modname, 'incompatible compiler') - elif not module.compatible_cpu(archinfo, options): - cannot_use_because(modname, 'incompatible CPU') - - else: + elif usable: if module.load_on == 'never': cannot_use_because(modname, 'disabled as buggy') elif module.load_on == 'request': @@ -1451,7 +1488,7 @@ def choose_modules_to_use(modules, archinfo, ccinfo, options): to_load.append(modname) elif module.load_on == 'auto': - if options.no_autoload: + if options.no_autoload or module_policy is not None: maybe_dep.append(modname) else: to_load.append(modname) @@ -1487,7 +1524,7 @@ def choose_modules_to_use(modules, archinfo, ccinfo, options): cannot_use_because(modname, 'dependency failure') for not_a_dep in maybe_dep: - cannot_use_because(not_a_dep, 'loaded only if needed by dependency') + cannot_use_because(not_a_dep, 'only used if needed or requested') for reason in sorted(not_using_because.keys()): disabled_mods = sorted(set([mod for mod in not_using_because[reason]])) @@ -1514,52 +1551,6 @@ def choose_modules_to_use(modules, archinfo, ccinfo, options): return to_load """ -Load the info files about modules, targets, etc -""" -def load_info_files(options): - - def find_files_named(desired_name, in_path): - for (dirpath, dirnames, filenames) in os.walk(in_path): - if desired_name in filenames: - yield os.path.join(dirpath, desired_name) - - modules = dict([(mod.basename, mod) for mod in - [ModuleInfo(info) for info in - find_files_named('info.txt', options.lib_dir)]]) - - def list_files_in_build_data(subdir): - for (dirpath, dirnames, filenames) in \ - os.walk(os.path.join(options.build_data, subdir)): - for filename in filenames: - if filename.endswith('.txt'): - yield os.path.join(dirpath, filename) - - def form_name(filepath): - return os.path.basename(filepath).replace('.txt', '') - - archinfo = dict([(form_name(info), ArchInfo(info)) - for info in list_files_in_build_data('arch')]) - - osinfo = dict([(form_name(info), OsInfo(info)) - for info in list_files_in_build_data('os')]) - - ccinfo = dict([(form_name(info), CompilerInfo(info)) - for info in list_files_in_build_data('cc')]) - - def info_file_load_report(type, num): - if num > 0: - logging.debug('Loaded %d %s info files' % (num, type)) - else: - logging.warning('Failed to load any %s info files' % (type)) - - info_file_load_report('CPU', len(archinfo)); - info_file_load_report('OS', len(osinfo)) - info_file_load_report('compiler', len(ccinfo)) - - return (modules, archinfo, ccinfo, osinfo) - - -""" Choose the link method based on system availablity and user request """ def choose_link_method(options): @@ -1860,7 +1851,35 @@ def main(argv = None): options.build_data = os.path.join(options.src_dir, 'build-data') options.makefile_dir = os.path.join(options.build_data, 'makefile') - (modules, info_arch, info_cc, info_os) = load_info_files(options) + def find_files_named(desired_name, in_path): + for (dirpath, dirnames, filenames) in os.walk(in_path): + if desired_name in filenames: + yield os.path.join(dirpath, desired_name) + + modules = dict([(mod.basename, mod) for mod in + [ModuleInfo(info) for info in + find_files_named('info.txt', options.lib_dir)]]) + + def load_build_data(descr, subdir, class_t): + info = {} + + subdir = os.path.join(options.build_data, subdir) + + for fsname in os.listdir(subdir): + if fsname.endswith('.txt'): + info[fsname.replace('.txt', '')] = class_t(os.path.join(subdir, fsname)) + if len(info) == 0: + logging.warning('Failed to load any %s files' % (descr)) + else: + logging.debug('Loaded %d %s files' % (len(info), descr)) + + return info + + info_arch = load_build_data('CPU info', 'arch', ArchInfo) + info_os = load_build_data('OS info', 'os', OsInfo) + info_cc = load_build_data('compiler info', 'cc', CompilerInfo) + + module_policies = load_build_data('module policy', 'policy', ModulePolicyInfo) if options.list_modules: for k in sorted(modules.keys()): @@ -1936,6 +1955,12 @@ def main(argv = None): cc = info_cc[options.compiler] arch = info_arch[options.arch] osinfo = info_os[options.os] + module_policy = None + + if options.module_policy != None: + if options.module_policy not in module_policies: + logging.error("Unknown module set %s", options.module_policy) + module_policy = module_policies[options.module_policy] if options.with_visibility is None: options.with_visibility = True @@ -1952,7 +1977,7 @@ def main(argv = None): raise Exception('Botan does not support building as shared library on the target os. ' 'Build static using --disable-shared.') - loaded_mods = choose_modules_to_use(modules, arch, cc, options) + loaded_mods = choose_modules_to_use(modules, module_policy, arch, cc, options) for m in loaded_mods: if modules[m].load_on == 'vendor': |