import setuptools # noqa from setuptools import Extension def count_down_delay(delay): from time import sleep import sys while delay: sys.stdout.write("Continuing in %d seconds... \r" % delay) sys.stdout.flush() delay -= 1 sleep(1) print("") DASH_SEPARATOR = 75 * "-" def setup(*args, **kwargs): from setuptools import setup try: setup(*args, **kwargs) except KeyboardInterrupt: raise except SystemExit: raise except: print(DASH_SEPARATOR) print("Sorry, your build failed. Try rerunning configure.py with " "different options.") print(DASH_SEPARATOR) raise class NumpyExtension(Extension): # nicked from # http://mail.python.org/pipermail/distutils-sig/2007-September/008253.html # solution by Michael Hoffmann def __init__(self, *args, **kwargs): Extension.__init__(self, *args, **kwargs) self._include_dirs = self.include_dirs del self.include_dirs # restore overwritten property def get_numpy_incpath(self): from imp import find_module # avoid actually importing numpy, it screws up distutils file, pathname, descr = find_module("numpy") from os.path import join return join(pathname, "core", "include") def get_include_dirs(self): return self._include_dirs + [self.get_numpy_incpath()] def set_include_dirs(self, value): self._include_dirs = value def del_include_dirs(self): pass include_dirs = property(get_include_dirs, set_include_dirs, del_include_dirs) class PyUblasExtension(NumpyExtension): def get_module_include_path(self, name): from pkg_resources import Requirement, resource_filename return resource_filename(Requirement.parse(name), "%s/include" % name) @property def include_dirs(self): return self._include_dirs + [ self.get_numpy_incpath(), self.get_module_include_path("pyublas"), ] class HedgeExtension(PyUblasExtension): @property def include_dirs(self): return self._include_dirs + [ self.get_numpy_incpath(), self.get_module_include_path("pyublas"), self.get_module_include_path("hedge"), ] # {{{ tools def flatten(list): """For an iterable of sub-iterables, generate each member of each sub-iterable in turn, i.e. a flattened version of that super-iterable. Example: Turn [[a,b,c],[d,e,f]] into [a,b,c,d,e,f]. """ for sublist in list: for j in sublist: yield j def humanize(sym_str): words = sym_str.lower().replace("_", " ").split(" ") return " ".join([word.capitalize() for word in words]) # }}} # {{{ siteconf handling def get_config(schema=None, warn_about_no_config=True): if schema is None: from setup import get_config_schema schema = get_config_schema() if (not schema.have_config() and not schema.have_global_config() and warn_about_no_config): print("*************************************************************") print("*** I have detected that you have not run configure.py.") print("*************************************************************") print("*** Additionally, no global config files were found.") print("*** I will go ahead with the default configuration.") print("*** In all likelihood, this will not work out.") print("*** ") print("*** See README_SETUP.txt for more information.") print("*** ") print("*** If the build does fail, just re-run configure.py with the") print("*** correct arguments, and then retry. Good luck!") print("*************************************************************") print("*** HIT Ctrl-C NOW IF THIS IS NOT WHAT YOU WANT") print("*************************************************************") count_down_delay(delay=10) return expand_options(schema.read_config()) def hack_distutils(debug=False, fast_link=True, what_opt=3): # hack distutils.sysconfig to eliminate debug flags # stolen from mpi4py def remove_prefixes(optlist, bad_prefixes): for bad_prefix in bad_prefixes: for i, flag in enumerate(optlist): if flag.startswith(bad_prefix): optlist.pop(i) break return optlist import sys if not sys.platform.lower().startswith("win"): from distutils import sysconfig cvars = sysconfig.get_config_vars() cflags = cvars.get('OPT') if cflags: cflags = remove_prefixes(cflags.split(), ['-g', '-O', '-Wstrict-prototypes', '-DNDEBUG']) if debug: cflags.append("-g") else: if what_opt is None: pass else: cflags.append("-O%s" % what_opt) cflags.append("-DNDEBUG") cvars['OPT'] = str.join(' ', cflags) cvars["CFLAGS"] = cvars["BASECFLAGS"] + " " + cvars["OPT"] if fast_link: for varname in ["LDSHARED", "BLDSHARED"]: ldsharedflags = cvars.get(varname) if ldsharedflags: ldsharedflags = remove_prefixes(ldsharedflags.split(), ['-Wl,-O']) cvars[varname] = str.join(' ', ldsharedflags) # }}} # {{{ configure guts def default_or(a, b): if a is None: return b else: return a def expand_str(s, options): import re def my_repl(match): sym = match.group(1) try: repl = options[sym] except KeyError: from os import environ repl = environ[sym] return expand_str(repl, options) return re.subn(r"\$\{([a-zA-Z0-9_]+)\}", my_repl, s)[0] def expand_value(v, options): if isinstance(v, str): return expand_str(v, options) elif isinstance(v, list): result = [] for i in v: try: exp_i = expand_value(i, options) except: pass else: result.append(exp_i) return result else: return v def expand_options(options): return dict( (k, expand_value(v, options)) for k, v in options.items()) class ConfigSchema: def __init__(self, options, conf_file="siteconf.py", conf_dir="."): self.optdict = dict((opt.name, opt) for opt in options) self.options = options self.conf_dir = conf_dir self.conf_file = conf_file from os.path import expanduser self.user_conf_file = expanduser("~/.aksetup-defaults.py") import sys if not sys.platform.lower().startswith("win"): self.global_conf_file = "/etc/aksetup-defaults.py" else: self.global_conf_file = None def get_conf_file(self): import os return os.path.join(self.conf_dir, self.conf_file) def set_conf_dir(self, conf_dir): self.conf_dir = conf_dir def get_default_config(self): return dict((opt.name, opt.default) for opt in self.options) def read_config_from_pyfile(self, filename): result = {} filevars = {} infile = open(filename, "r") try: contents = infile.read() finally: infile.close() exec(compile(contents, filename, "exec"), filevars) for key, value in filevars.items(): if key in self.optdict: result[key] = value return result def update_conf_file(self, filename, config): result = {} filevars = {} try: exec(compile(open(filename, "r").read(), filename, "exec"), filevars) except IOError: pass if "__builtins__" in filevars: del filevars["__builtins__"] for key, value in config.items(): if value is not None: filevars[key] = value keys = filevars.keys() keys.sort() outf = open(filename, "w") for key in keys: outf.write("%s = %s\n" % (key, repr(filevars[key]))) outf.close() return result def update_user_config(self, config): self.update_conf_file(self.user_conf_file, config) def update_global_config(self, config): if self.global_conf_file is not None: self.update_conf_file(self.global_conf_file, config) def get_default_config_with_files(self): result = self.get_default_config() import os confignames = [] if self.global_conf_file is not None: confignames.append(self.global_conf_file) confignames.append(self.user_conf_file) for fn in confignames: if os.access(fn, os.R_OK): result.update(self.read_config_from_pyfile(fn)) return result def have_global_config(self): import os result = os.access(self.user_conf_file, os.R_OK) if self.global_conf_file is not None: result = result or os.access(self.global_conf_file, os.R_OK) return result def have_config(self): import os return os.access(self.get_conf_file(), os.R_OK) def read_config(self, warn_if_none=True): import os cfile = self.get_conf_file() result = self.get_default_config_with_files() if os.access(cfile, os.R_OK): filevars = {} exec(compile(open(cfile, "r").read(), cfile, "exec"), filevars) for key, value in filevars.items(): if key in self.optdict: result[key] = value elif key == "__builtins__": pass else: raise KeyError("invalid config key in %s: %s" % ( cfile, key)) return result def add_to_configparser(self, parser, def_config=None): if def_config is None: def_config = self.get_default_config_with_files() for opt in self.options: default = default_or(def_config.get(opt.name), opt.default) opt.add_to_configparser(parser, default) def get_from_configparser(self, options): result = {} for opt in self.options: result[opt.name] = opt.take_from_configparser(options) return result def write_config(self, config): outf = open(self.get_conf_file(), "w") for opt in self.options: value = config[opt.name] if value is not None: outf.write("%s = %s\n" % (opt.name, repr(config[opt.name]))) outf.close() def make_substitutions(self, config): return dict((opt.name, opt.value_to_str(config[opt.name])) for opt in self.options) class Option(object): def __init__(self, name, default=None, help=None): self.name = name self.default = default self.help = help def as_option(self): return self.name.lower().replace("_", "-") def metavar(self): last_underscore = self.name.rfind("_") return self.name[last_underscore+1:] def get_help(self, default): result = self.help if self.default: result += " (default: %s)" % self.value_to_str( default_or(default, self.default)) return result def value_to_str(self, default): return default def add_to_configparser(self, parser, default=None): default = default_or(default, self.default) default_str = self.value_to_str(default) parser.add_option( "--" + self.as_option(), dest=self.name, default=default_str, metavar=self.metavar(), help=self.get_help(default)) def take_from_configparser(self, options): return getattr(options, self.name) class Switch(Option): def add_to_configparser(self, parser, default=None): if not isinstance(self.default, bool): raise ValueError("Switch options must have a default") if default is None: default = self.default option_name = self.as_option() if default: option_name = "no-" + option_name action = "store_false" else: action = "store_true" parser.add_option( "--" + option_name, dest=self.name, help=self.get_help(default), default=default, action=action) class StringListOption(Option): def value_to_str(self, default): if default is None: return None return ",".join([str(el).replace(",", r"\,") for el in default]) def get_help(self, default): return Option.get_help(self, default) + " (several ok)" def take_from_configparser(self, options): opt = getattr(options, self.name) if opt is None: return None else: if opt: import re sep = re.compile(r"(?