17db96d56Sopenharmony_ci"""distutils.core
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciThe only module that needs to be imported to use the Distutils; provides
47db96d56Sopenharmony_cithe 'setup' function (which is to be called from the setup script).  Also
57db96d56Sopenharmony_ciindirectly provides the Distribution and Command classes, although they are
67db96d56Sopenharmony_cireally defined in distutils.dist and distutils.cmd.
77db96d56Sopenharmony_ci"""
87db96d56Sopenharmony_ci
97db96d56Sopenharmony_ciimport os
107db96d56Sopenharmony_ciimport sys
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_cifrom distutils.debug import DEBUG
137db96d56Sopenharmony_cifrom distutils.errors import *
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci# Mainly import these so setup scripts can "from distutils.core import" them.
167db96d56Sopenharmony_cifrom distutils.dist import Distribution
177db96d56Sopenharmony_cifrom distutils.cmd import Command
187db96d56Sopenharmony_cifrom distutils.config import PyPIRCCommand
197db96d56Sopenharmony_cifrom distutils.extension import Extension
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci# This is a barebones help message generated displayed when the user
227db96d56Sopenharmony_ci# runs the setup script with no arguments at all.  More useful help
237db96d56Sopenharmony_ci# is generated with various --help options: global help, list commands,
247db96d56Sopenharmony_ci# and per-command help.
257db96d56Sopenharmony_ciUSAGE = """\
267db96d56Sopenharmony_ciusage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
277db96d56Sopenharmony_ci   or: %(script)s --help [cmd1 cmd2 ...]
287db96d56Sopenharmony_ci   or: %(script)s --help-commands
297db96d56Sopenharmony_ci   or: %(script)s cmd --help
307db96d56Sopenharmony_ci"""
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_cidef gen_usage (script_name):
337db96d56Sopenharmony_ci    script = os.path.basename(script_name)
347db96d56Sopenharmony_ci    return USAGE % vars()
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_ci# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'.
387db96d56Sopenharmony_ci_setup_stop_after = None
397db96d56Sopenharmony_ci_setup_distribution = None
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci# Legal keyword arguments for the setup() function
427db96d56Sopenharmony_cisetup_keywords = ('distclass', 'script_name', 'script_args', 'options',
437db96d56Sopenharmony_ci                  'name', 'version', 'author', 'author_email',
447db96d56Sopenharmony_ci                  'maintainer', 'maintainer_email', 'url', 'license',
457db96d56Sopenharmony_ci                  'description', 'long_description', 'keywords',
467db96d56Sopenharmony_ci                  'platforms', 'classifiers', 'download_url',
477db96d56Sopenharmony_ci                  'requires', 'provides', 'obsoletes',
487db96d56Sopenharmony_ci                  )
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci# Legal keyword arguments for the Extension constructor
517db96d56Sopenharmony_ciextension_keywords = ('name', 'sources', 'include_dirs',
527db96d56Sopenharmony_ci                      'define_macros', 'undef_macros',
537db96d56Sopenharmony_ci                      'library_dirs', 'libraries', 'runtime_library_dirs',
547db96d56Sopenharmony_ci                      'extra_objects', 'extra_compile_args', 'extra_link_args',
557db96d56Sopenharmony_ci                      'swig_opts', 'export_symbols', 'depends', 'language')
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_cidef setup (**attrs):
587db96d56Sopenharmony_ci    """The gateway to the Distutils: do everything your setup script needs
597db96d56Sopenharmony_ci    to do, in a highly flexible and user-driven way.  Briefly: create a
607db96d56Sopenharmony_ci    Distribution instance; find and parse config files; parse the command
617db96d56Sopenharmony_ci    line; run each Distutils command found there, customized by the options
627db96d56Sopenharmony_ci    supplied to 'setup()' (as keyword arguments), in config files, and on
637db96d56Sopenharmony_ci    the command line.
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci    The Distribution instance might be an instance of a class supplied via
667db96d56Sopenharmony_ci    the 'distclass' keyword argument to 'setup'; if no such class is
677db96d56Sopenharmony_ci    supplied, then the Distribution class (in dist.py) is instantiated.
687db96d56Sopenharmony_ci    All other arguments to 'setup' (except for 'cmdclass') are used to set
697db96d56Sopenharmony_ci    attributes of the Distribution instance.
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci    The 'cmdclass' argument, if supplied, is a dictionary mapping command
727db96d56Sopenharmony_ci    names to command classes.  Each command encountered on the command line
737db96d56Sopenharmony_ci    will be turned into a command class, which is in turn instantiated; any
747db96d56Sopenharmony_ci    class found in 'cmdclass' is used in place of the default, which is
757db96d56Sopenharmony_ci    (for command 'foo_bar') class 'foo_bar' in module
767db96d56Sopenharmony_ci    'distutils.command.foo_bar'.  The command class must provide a
777db96d56Sopenharmony_ci    'user_options' attribute which is a list of option specifiers for
787db96d56Sopenharmony_ci    'distutils.fancy_getopt'.  Any command-line options between the current
797db96d56Sopenharmony_ci    and the next command are used to set attributes of the current command
807db96d56Sopenharmony_ci    object.
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci    When the entire command-line has been successfully parsed, calls the
837db96d56Sopenharmony_ci    'run()' method on each command object in turn.  This method will be
847db96d56Sopenharmony_ci    driven entirely by the Distribution object (which each command object
857db96d56Sopenharmony_ci    has a reference to, thanks to its constructor), and the
867db96d56Sopenharmony_ci    command-specific options that became attributes of each command
877db96d56Sopenharmony_ci    object.
887db96d56Sopenharmony_ci    """
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci    global _setup_stop_after, _setup_distribution
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ci    # Determine the distribution class -- either caller-supplied or
937db96d56Sopenharmony_ci    # our Distribution (see below).
947db96d56Sopenharmony_ci    klass = attrs.get('distclass')
957db96d56Sopenharmony_ci    if klass:
967db96d56Sopenharmony_ci        del attrs['distclass']
977db96d56Sopenharmony_ci    else:
987db96d56Sopenharmony_ci        klass = Distribution
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci    if 'script_name' not in attrs:
1017db96d56Sopenharmony_ci        attrs['script_name'] = os.path.basename(sys.argv[0])
1027db96d56Sopenharmony_ci    if 'script_args'  not in attrs:
1037db96d56Sopenharmony_ci        attrs['script_args'] = sys.argv[1:]
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci    # Create the Distribution instance, using the remaining arguments
1067db96d56Sopenharmony_ci    # (ie. everything except distclass) to initialize it
1077db96d56Sopenharmony_ci    try:
1087db96d56Sopenharmony_ci        _setup_distribution = dist = klass(attrs)
1097db96d56Sopenharmony_ci    except DistutilsSetupError as msg:
1107db96d56Sopenharmony_ci        if 'name' not in attrs:
1117db96d56Sopenharmony_ci            raise SystemExit("error in setup command: %s" % msg)
1127db96d56Sopenharmony_ci        else:
1137db96d56Sopenharmony_ci            raise SystemExit("error in %s setup command: %s" % \
1147db96d56Sopenharmony_ci                  (attrs['name'], msg))
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci    if _setup_stop_after == "init":
1177db96d56Sopenharmony_ci        return dist
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci    # Find and parse the config file(s): they will override options from
1207db96d56Sopenharmony_ci    # the setup script, but be overridden by the command line.
1217db96d56Sopenharmony_ci    dist.parse_config_files()
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_ci    if DEBUG:
1247db96d56Sopenharmony_ci        print("options (after parsing config files):")
1257db96d56Sopenharmony_ci        dist.dump_option_dicts()
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci    if _setup_stop_after == "config":
1287db96d56Sopenharmony_ci        return dist
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci    # Parse the command line and override config files; any
1317db96d56Sopenharmony_ci    # command-line errors are the end user's fault, so turn them into
1327db96d56Sopenharmony_ci    # SystemExit to suppress tracebacks.
1337db96d56Sopenharmony_ci    try:
1347db96d56Sopenharmony_ci        ok = dist.parse_command_line()
1357db96d56Sopenharmony_ci    except DistutilsArgError as msg:
1367db96d56Sopenharmony_ci        raise SystemExit(gen_usage(dist.script_name) + "\nerror: %s" % msg)
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci    if DEBUG:
1397db96d56Sopenharmony_ci        print("options (after parsing command line):")
1407db96d56Sopenharmony_ci        dist.dump_option_dicts()
1417db96d56Sopenharmony_ci
1427db96d56Sopenharmony_ci    if _setup_stop_after == "commandline":
1437db96d56Sopenharmony_ci        return dist
1447db96d56Sopenharmony_ci
1457db96d56Sopenharmony_ci    # And finally, run all the commands found on the command line.
1467db96d56Sopenharmony_ci    if ok:
1477db96d56Sopenharmony_ci        try:
1487db96d56Sopenharmony_ci            dist.run_commands()
1497db96d56Sopenharmony_ci        except KeyboardInterrupt:
1507db96d56Sopenharmony_ci            raise SystemExit("interrupted")
1517db96d56Sopenharmony_ci        except OSError as exc:
1527db96d56Sopenharmony_ci            if DEBUG:
1537db96d56Sopenharmony_ci                sys.stderr.write("error: %s\n" % (exc,))
1547db96d56Sopenharmony_ci                raise
1557db96d56Sopenharmony_ci            else:
1567db96d56Sopenharmony_ci                raise SystemExit("error: %s" % (exc,))
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci        except (DistutilsError,
1597db96d56Sopenharmony_ci                CCompilerError) as msg:
1607db96d56Sopenharmony_ci            if DEBUG:
1617db96d56Sopenharmony_ci                raise
1627db96d56Sopenharmony_ci            else:
1637db96d56Sopenharmony_ci                raise SystemExit("error: " + str(msg))
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci    return dist
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_ci# setup ()
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci
1707db96d56Sopenharmony_cidef run_setup (script_name, script_args=None, stop_after="run"):
1717db96d56Sopenharmony_ci    """Run a setup script in a somewhat controlled environment, and
1727db96d56Sopenharmony_ci    return the Distribution instance that drives things.  This is useful
1737db96d56Sopenharmony_ci    if you need to find out the distribution meta-data (passed as
1747db96d56Sopenharmony_ci    keyword args from 'script' to 'setup()', or the contents of the
1757db96d56Sopenharmony_ci    config files or command-line.
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci    'script_name' is a file that will be read and run with 'exec()';
1787db96d56Sopenharmony_ci    'sys.argv[0]' will be replaced with 'script' for the duration of the
1797db96d56Sopenharmony_ci    call.  'script_args' is a list of strings; if supplied,
1807db96d56Sopenharmony_ci    'sys.argv[1:]' will be replaced by 'script_args' for the duration of
1817db96d56Sopenharmony_ci    the call.
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci    'stop_after' tells 'setup()' when to stop processing; possible
1847db96d56Sopenharmony_ci    values:
1857db96d56Sopenharmony_ci      init
1867db96d56Sopenharmony_ci        stop after the Distribution instance has been created and
1877db96d56Sopenharmony_ci        populated with the keyword arguments to 'setup()'
1887db96d56Sopenharmony_ci      config
1897db96d56Sopenharmony_ci        stop after config files have been parsed (and their data
1907db96d56Sopenharmony_ci        stored in the Distribution instance)
1917db96d56Sopenharmony_ci      commandline
1927db96d56Sopenharmony_ci        stop after the command-line ('sys.argv[1:]' or 'script_args')
1937db96d56Sopenharmony_ci        have been parsed (and the data stored in the Distribution)
1947db96d56Sopenharmony_ci      run [default]
1957db96d56Sopenharmony_ci        stop after all commands have been run (the same as if 'setup()'
1967db96d56Sopenharmony_ci        had been called in the usual way
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci    Returns the Distribution instance, which provides all information
1997db96d56Sopenharmony_ci    used to drive the Distutils.
2007db96d56Sopenharmony_ci    """
2017db96d56Sopenharmony_ci    if stop_after not in ('init', 'config', 'commandline', 'run'):
2027db96d56Sopenharmony_ci        raise ValueError("invalid value for 'stop_after': %r" % (stop_after,))
2037db96d56Sopenharmony_ci
2047db96d56Sopenharmony_ci    global _setup_stop_after, _setup_distribution
2057db96d56Sopenharmony_ci    _setup_stop_after = stop_after
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci    save_argv = sys.argv.copy()
2087db96d56Sopenharmony_ci    g = {'__file__': script_name}
2097db96d56Sopenharmony_ci    try:
2107db96d56Sopenharmony_ci        try:
2117db96d56Sopenharmony_ci            sys.argv[0] = script_name
2127db96d56Sopenharmony_ci            if script_args is not None:
2137db96d56Sopenharmony_ci                sys.argv[1:] = script_args
2147db96d56Sopenharmony_ci            with open(script_name, 'rb') as f:
2157db96d56Sopenharmony_ci                exec(f.read(), g)
2167db96d56Sopenharmony_ci        finally:
2177db96d56Sopenharmony_ci            sys.argv = save_argv
2187db96d56Sopenharmony_ci            _setup_stop_after = None
2197db96d56Sopenharmony_ci    except SystemExit:
2207db96d56Sopenharmony_ci        # Hmm, should we do something if exiting with a non-zero code
2217db96d56Sopenharmony_ci        # (ie. error)?
2227db96d56Sopenharmony_ci        pass
2237db96d56Sopenharmony_ci
2247db96d56Sopenharmony_ci    if _setup_distribution is None:
2257db96d56Sopenharmony_ci        raise RuntimeError(("'distutils.core.setup()' was never called -- "
2267db96d56Sopenharmony_ci               "perhaps '%s' is not a Distutils setup script?") % \
2277db96d56Sopenharmony_ci              script_name)
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_ci    # I wonder if the setup script's namespace -- g and l -- would be of
2307db96d56Sopenharmony_ci    # any interest to callers?
2317db96d56Sopenharmony_ci    #print "_setup_distribution:", _setup_distribution
2327db96d56Sopenharmony_ci    return _setup_distribution
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci# run_setup ()
235