#!/usr/bin/env python ############################################################################## # Copyright (c) 2013, Lawrence Livermore National Security, LLC. # Produced at the Lawrence Livermore National Laboratory. # # This file is part of Spack. # Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved. # LLNL-CODE-647188 # # For details, see https://github.com/llnl/spack # Please also see the LICENSE file for our notice and the LGPL. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License (as published by # the Free Software Foundation) version 2.1 dated February 1999. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and # conditions of the GNU General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## import sys if not sys.version_info[:2] >= (2,6): v_info = sys.version_info[:3] sys.exit("Spack requires Python 2.6 or higher. This is Python %d.%d.%d." % v_info) import os # Find spack's location and its prefix. SPACK_FILE = os.path.realpath(os.path.expanduser(__file__)) os.environ["SPACK_FILE"] = SPACK_FILE SPACK_PREFIX = os.path.dirname(os.path.dirname(SPACK_FILE)) # Allow spack libs to be imported in our scripts SPACK_LIB_PATH = os.path.join(SPACK_PREFIX, "lib", "spack") sys.path.insert(0, SPACK_LIB_PATH) SPACK_EXTERNAL_LIBS = os.path.join(SPACK_LIB_PATH, "external") sys.path.insert(0, SPACK_EXTERNAL_LIBS) import warnings # Avoid warnings when nose is installed with the python exe being used to run # spack. Note this must be done after Spack's external libs directory is added # to sys.path. with warnings.catch_warnings(): warnings.filterwarnings("ignore", ".*nose was already imported") import nose # Quick and dirty check to clean orphaned .pyc files left over from # previous revisions. These files were present in earlier versions of # Spack, were removed, but shadow system modules that Spack still # imports. If we leave them, Spack will fail in mysterious ways. # TODO: more elegant solution for orphaned pyc files. orphaned_pyc_files = [os.path.join(SPACK_EXTERNAL_LIBS, n) for n in ('functools.pyc', 'ordereddict.pyc')] for pyc_file in orphaned_pyc_files: if not os.path.exists(pyc_file): continue try: os.remove(pyc_file) except OSError as e: print "WARNING: Spack may fail mysteriously. Couldn't remove orphaned .pyc file: %s" % pyc_file # If there is no working directory, use the spack prefix. try: working_dir = os.getcwd() except OSError: os.chdir(SPACK_PREFIX) working_dir = SPACK_PREFIX # clean up the scope and start using spack package instead. del SPACK_FILE, SPACK_PREFIX, SPACK_LIB_PATH import llnl.util.tty as tty from llnl.util.tty.color import * import spack from spack.error import SpackError from external import argparse # Command parsing parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter, description="Spack: the Supercomputing PACKage Manager." + colorize(""" spec expressions: PACKAGE [CONSTRAINTS] CONSTRAINTS: @c{@version} @g{%compiler @compiler_version} @B{+variant} @r{-variant} or @r{~variant} @m{=architecture} [^DEPENDENCY [CONSTRAINTS] ...]""")) parser.add_argument('-d', '--debug', action='store_true', help="Write out debug logs during compile") parser.add_argument('-D', '--pdb', action='store_true', help="Run spack under the pdb debugger") parser.add_argument('-k', '--insecure', action='store_true', help="Do not check ssl certificates when downloading.") parser.add_argument('-m', '--mock', action='store_true', help="Use mock packages instead of real ones.") parser.add_argument('-p', '--profile', action='store_true', help="Profile execution using cProfile.") parser.add_argument('-v', '--verbose', action='store_true', help="Print additional output during builds") parser.add_argument('-V', '--version', action='version', version="%s" % spack.spack_version) # each command module implements a parser() function, to which we pass its # subparser for setup. subparsers = parser.add_subparsers(metavar='SUBCOMMAND', dest="command") import spack.cmd for cmd in spack.cmd.commands: module = spack.cmd.get_module(cmd) subparser = subparsers.add_parser(cmd, help=module.description) module.setup_parser(subparser) # Just print help and exit if run with no arguments at all if len(sys.argv) == 1: parser.print_help() sys.exit(1) # actually parse the args. args = parser.parse_args() def main(): # Set up environment based on args. tty.set_verbose(args.verbose) tty.set_debug(args.debug) spack.debug = args.debug if spack.debug: import spack.util.debug as debug debug.register_interrupt_handler() spack.spack_working_dir = working_dir if args.mock: from spack.repository import RepoPath spack.repo.swap(RepoPath(spack.mock_packages_path)) # If the user asked for it, don't check ssl certs. if args.insecure: tty.warn("You asked for --insecure, which does not check SSL certificates.") spack.curl.add_default_arg('-k') # Try to load the particular command asked for and run it command = spack.cmd.get_command(args.command) try: return_val = command(parser, args) except SpackError as e: e.die() except KeyboardInterrupt: sys.stderr.write('\n') tty.die("Keyboard interrupt.") # Allow commands to return values if they want to exit with some other code. if return_val is None: sys.exit(0) elif isinstance(return_val, int): sys.exit(return_val) else: tty.die("Bad return value from command %s: %s" % (args.command, return_val)) if args.profile: import cProfile cProfile.run('main()', sort='tottime') elif args.pdb: import pdb pdb.run('main()') else: main()