Exemple #1
0
def globpattern(dir, pattern):
    """
    Return leaf names in the specified directory which match the pattern.
    """

    if not hasglob(pattern):
        if pattern == '':
            if os.path.isdir(dir):
                return ['']
            return []

        if os.path.exists(util.normaljoin(dir, pattern)):
            return [pattern]
        return []

    leaves = os.listdir(dir) + ['.', '..']

    # "hidden" filenames are a bit special
    if not pattern.startswith('.'):
        leaves = [leaf for leaf in leaves if not leaf.startswith('.')]

    leaves = fnmatch.filter(leaves, pattern)
    leaves = [l for l in leaves if os.path.exists(util.normaljoin(dir, l))]

    leaves.sort()
    return leaves
Exemple #2
0
def glob(fsdir, path):
    """
    Yield paths matching the path glob. Sorts as a bonus. Excludes '.' and '..'
    """

    dir, leaf = os.path.split(path)
    if dir == '':
        return globpattern(fsdir, leaf)

    if hasglob(dir):
        dirsfound = glob(fsdir, dir)
    else:
        dirsfound = [dir]

    r = []

    for dir in dirsfound:
        fspath = util.normaljoin(fsdir, dir)
        if not os.path.isdir(fspath):
            continue

        r.extend((util.normaljoin(dir, found)
                  for found in globpattern(fspath, leaf)))

    return r
Exemple #3
0
 def resolve(self, makefile, variables, fd, setting):
     assert os.path.isabs(makefile.workdir)
     fd.write(' '.join([
         util.normaljoin(makefile.workdir, path).replace('\\', '/')
         for path in self._arguments[0].resolvesplit(
             makefile, variables, setting)
     ]))
Exemple #4
0
def prepare_command(cline, cwd, loc):
    """
    Returns a list of command and arguments for the given command line string.
    If the command needs to be run through a shell for some reason, the
    returned list contains the shell invocation.
    """

    #TODO: call this once up-front somewhere and save the result?
    shell, msys = util.checkmsyscompat()

    shellreason = None
    executable = None
    if msys and cline.startswith('/'):
        shellreason = "command starts with /"
    else:
        argv, badchar = clinetoargv(cline, cwd)
        if argv is None:
            shellreason = "command contains shell-special character '%s'" % (
                badchar, )
        elif len(argv) and argv[0] in shellwords:
            shellreason = "command starts with shell primitive '%s'" % (
                argv[0], )
        elif argv and (os.sep in argv[0]
                       or os.altsep and os.altsep in argv[0]):
            executable = util.normaljoin(cwd, argv[0])
            # Avoid "%1 is not a valid Win32 application" errors, assuming
            # that if the executable path is to be resolved with PATH, it will
            # be a Win32 executable.
            if sys.platform == 'win32' and os.path.isfile(executable) and open(
                    executable, 'rb').read(2) == "#!":
                shellreason = "command executable starts with a hashbang"

    if shellreason is not None:
        _log.debug("%s: using shell: %s: '%s'", loc, shellreason, cline)
        if msys:
            if len(cline) > 3 and cline[1] == ':' and cline[2] == '/':
                cline = '/' + cline[0] + cline[2:]
        argv = [shell, "-c", cline]
        executable = None

    return executable, argv
Exemple #5
0
def main(args, env, cwd, cb):
    """
    Start a single makefile execution, given a command line, working directory, and environment.

    @param cb a callback to notify with an exit code when make execution is finished.
    """

    try:
        makelevel = int(env.get('MAKELEVEL', '0'))

        op = OptionParser()
        op.add_option('-f',
                      '--file',
                      '--makefile',
                      action='append',
                      dest='makefiles',
                      default=[])
        op.add_option('-d', action="store_true", dest="verbose", default=False)
        op.add_option('-k',
                      '--keep-going',
                      action="store_true",
                      dest="keepgoing",
                      default=False)
        op.add_option('--debug-log', dest="debuglog", default=None)
        op.add_option('-C', '--directory', dest="directory", default=None)
        op.add_option('-v',
                      '--version',
                      action="store_true",
                      dest="printversion",
                      default=False)
        op.add_option('-j', '--jobs', type="int", dest="jobcount", default=1)
        op.add_option('-w',
                      '--print-directory',
                      action="store_true",
                      dest="printdir")
        op.add_option('--no-print-directory',
                      action="store_false",
                      dest="printdir",
                      default=True)
        op.add_option('-s',
                      '--silent',
                      action="store_true",
                      dest="silent",
                      default=False)
        op.add_option('-n',
                      '--just-print',
                      '--dry-run',
                      '--recon',
                      action="store_true",
                      dest="justprint",
                      default=False)

        options, arguments1 = op.parse_args(parsemakeflags(env))
        options, arguments2 = op.parse_args(args, values=options)

        op.destroy()

        arguments = arguments1 + arguments2

        if options.printversion:
            _version()
            cb(0)
            return

        shortflags = []
        longflags = []

        if options.keepgoing:
            shortflags.append('k')

        if options.printdir:
            shortflags.append('w')

        if options.silent:
            shortflags.append('s')
            options.printdir = False

        if options.justprint:
            shortflags.append('n')

        loglevel = logging.WARNING
        if options.verbose:
            loglevel = logging.DEBUG
            shortflags.append('d')

        logkwargs = {}
        if options.debuglog:
            logkwargs['filename'] = options.debuglog
            longflags.append('--debug-log=%s' % options.debuglog)

        if options.directory is None:
            workdir = cwd
        else:
            workdir = util.normaljoin(cwd, options.directory)

        if options.jobcount != 1:
            longflags.append('-j%i' % (options.jobcount, ))

        makeflags = ''.join(shortflags)
        if len(longflags):
            makeflags += ' ' + ' '.join(longflags)

        logging.basicConfig(level=loglevel, **logkwargs)

        context = process.getcontext(options.jobcount)

        if options.printdir:
            print("make.py[%i]: Entering directory '%s'" %
                  (makelevel, workdir))
            sys.stdout.flush()

        if len(options.makefiles) == 0:
            if os.path.exists(util.normaljoin(workdir, 'Makefile')):
                options.makefiles.append('Makefile')
            else:
                print("No makefile found")
                cb(2)
                return

        ostmts, targets, overrides = parserdata.parsecommandlineargs(arguments)

        _MakeContext(makeflags, makelevel, workdir, context, env, targets,
                     options, ostmts, overrides, cb)
    except errors.MakeError as e:
        print(e)
        if options.printdir:
            print("make.py[%i]: Leaving directory '%s'" % (makelevel, workdir))
        sys.stdout.flush()
        cb(2)
        return
Exemple #6
0
Makefile execution.

Multiple `makes` can be run within the same process. Each one has an entirely data.Makefile and .Target
structure, environment, and working directory. Typically they will all share a parallel execution context,
except when a submake specifies -j1 when the parent make is building in parallel.
"""

import os, subprocess, sys, logging, time, traceback, re
from optparse import OptionParser
from pymake import data, parserdata, process, util
from pymake import errors

# TODO: If this ever goes from relocatable package to system-installed, this may need to be
# a configured-in path.

makepypath = util.normaljoin(os.path.dirname(__file__), '../make.py')

_simpleopts = re.compile(r'^[a-zA-Z]+(\s|$)')


def parsemakeflags(env):
    """
    Parse MAKEFLAGS from the environment into a sequence of command-line arguments.
    """

    makeflags = env.get('MAKEFLAGS', '')
    makeflags = makeflags.strip()

    if makeflags == '':
        return []