aboutsummaryrefslogtreecommitdiffstats
path: root/configure.py
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-03-06 06:31:02 -0500
committerJack Lloyd <[email protected]>2016-03-06 06:31:02 -0500
commitdd40d492fc8c76954909445e1af6e32a3e03600e (patch)
treef8b041df0d69011ac90ae8a72c047375a5e4a8de /configure.py
parent7827c50cbddec094412745d877dcf3ea118ad4d7 (diff)
parent028a5126095e4eecd4dd213218f241a990fcbddd (diff)
Merge GH #446 add --module-policy option
Diffstat (limited to 'configure.py')
-rwxr-xr-xconfigure.py145
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':