Пример #1
0
def main(argv=None):
  if argv is None:
    argv = sys.argv[1:]
  args = parser.parse_args(argv)

  if args.no_export and args.export:
    parser.error('conflicting options -n/--no-export and -e/--export')
  if args.dry and args.export:
    parser.error('conflicting options -d/--dry and -e/--export')
  if args.clean_with_dependencies:
    args.clean = True
  if args.clean and args.export:
    parser.error('conflicting options -c/--clean and -e/--export')
  if args.clean:
    args.no_export = True

  workspace = creator.unit.Workspace()
  workspace.path.extend(args.unitpath)

  # Evaluate the Defines and Macros passed via the command line.
  for define in args.define:
    key, _, value = define.partition('=')
    if key:
      workspace.context[key] = creator.macro.TextNode(value)

  for macro in args.macro:
    key, _, value = macro.partition('=')
    if key:
      workspace.context[key] = value

  # Look at the current directory and figure out the main unit
  # that should be used by this session.
  if not args.unit:
    if os.path.exists('Creator'):
      filename = 'Creator'
    elif os.path.exists('.creator'):
      filename = '.creator'
    else:
      files = glob.glob('*.creator')
      if not files:
        workspace.error("no 'Creator' or '*.creator' files in current directory")
      elif len(files) > 1:
        workspace.error("multiple '*.creator' files in the current directory, "
          "use -u/--unit to specify which to use.")
      filename = files[0]

    metadata = creator.utils.read_metadata(filename)
    if not 'creator.unit.name' in metadata:
      workspace.error("'{0}' missing @creator.unit.name".format(filename))
    args.unit = metadata['creator.unit.name']

  # Load the active unit and set up all targets.
  unit = workspace.load_unit(args.unit)
  workspace.setup_targets()

  # Exit if this is just a dry run.
  if args.dry:
    return 0

  # Figure the output path for the build definitions.
  if not args.output:
    args.output = unit.eval('$self:NinjaOut').strip()
    if args.output:
      args.output = creator.utils.normpath(args.output)
      dirname = os.path.dirname(args.output)
      if not os.path.isdir(dirname):
        os.makedirs(dirname)
      args.output = os.path.relpath(args.output)
  if not args.output:
      args.output = 'build.ninja'

  # Collect a list of all targets and tasks.
  targets = [unit.get_target(x) for x in args.targets]

  # We must not complete the target list if we're only cleaning
  # without dependencies.
  if not args.clean or args.clean_with_dependencies:
    complete_target_list(targets)

  # Collect a list of all targets that will be processed by Ninja.
  ninja_targets = [
    t.identifier for t in targets if isinstance(t, creator.unit.Target)]

  if args.export:
    # Print a warning for each specified non-buildable target.
    for target in targets:
      if isinstance(target, creator.unit.Task):
        workspace.info("warning: {0} is a task".format(target.identifier))

  # If there are not targets specified and there are no targets
  # in the workspace, we don't have to export a ninja.build file
  # nor invoke Ninja.
  if not targets and not ninja_targets:
    if not any(isinstance(t, creator.unit.Target) for t in workspace.all_targets()):
      args.dry = True
      args.no_export = True

  # If we have any buildable targets specified, no targets specified at
  # all or if we should only export the build definitions, do exactly that.
  if not args.no_export and (args.export or ninja_targets or not targets):
    workspace.info("exporting to: {0}".format(args.output))
    with open(args.output, 'w') as fp:
      creator.ninja.export(fp, workspace, unit, ninja_targets)
    if args.export:
      return 0

  # Clean the target output files if --clean or --clean-with-dependencies
  # is specified.
  if args.clean or args.clean_with_dependencies:
    if not targets:
      targets = workspace.all_targets()
    cleaned_files = 0
    for target in targets:
      if isinstance(target, creator.unit.Target):
        for entry in target.command_data:
          for filename in entry['outputs']:
            if os.path.isfile(filename):
              try:
                os.remove(filename)
                cleaned_files += 1
              except OSError:
                workspace.error("Could not remove '{}'.".format(filename))
    workspace.info('Cleaned {} files.'.format(cleaned_files))
    return 0

  ninja_args = ['ninja', '-f', args.output] + args.args
  if args.verbose:
    ninja_args.append('-v')

  # No targets specified on the command-line? Build it all.
  if not targets and not args.dry:
    return call_subprocess(ninja_args, workspace)
  else:
    targets = collapse_target_list(targets)

    # Run each target with its own call to ninja and the tasks in between.
    for target in targets:
      if isinstance(target, creator.unit.Task):
        workspace.info("running task '{0}'".format(target.identifier))
        target.func()
      elif isinstance(target, list):
        idents = [creator.ninja.ident(t.identifier) for t in target]
        idents = [creator.utils.quote(x) for x in idents]
        res = call_subprocess(ninja_args + idents, workspace)
        if res != 0:
          return res

    return 0
Пример #2
0
def main(argv=None):
  if argv is None:
    argv = sys.argv[1:]
  args = parser.parse_args(argv)

  if args.no_export and args.export:
    parser.error('conflicting options -n/--no-export and -e/--export')
  if args.dry and args.export:
    parser.error('conflicting options -d/--dry and -e/--export')

  workspace = creator.unit.Workspace()
  workspace.path.extend(args.unitpath)

  # Evaluate the Defines and Macros passed via the command line.
  for define in args.define:
    key, _, value = define.partition('=')
    if key:
      workspace.context[key] = creator.macro.TextNode(value)

  for macro in args.macro:
    key, _, value = macro.partition('=')
    if key:
      workspace.context[key] = value

  # If not Unit Identifier was specified on the command-line,
  # look at the current directory and use the only .crunit that
  # is in there.
  if not args.unit:
    files = glob.glob('*.crunit')
    if not files:
      parser.error('no *.crunit file in the current directory')
    elif len(files) > 1:
      parser.error('multiple *.crunit files in the current '
        'directory, use -u/--unit to specify which.')
    args.unit = creator.utils.set_suffix(os.path.basename(files[0]), '')

  # Load the active unit and set up all targets.
  unit = workspace.load_unit(args.unit)
  workspace.setup_targets()

  # Exit if this is just a dry run.
  if args.dry:
    return 0

  # Figure the output path for the build definitions.
  if not args.output:
    args.output = unit.eval('$self:NinjaOut').strip()
    if args.output:
      args.output = creator.utils.normpath(args.output)
      dirname = os.path.dirname(args.output)
      if not os.path.isdir(dirname):
        os.makedirs(dirname)
      args.output = os.path.relpath(args.output)
  if not args.output:
      args.output = 'build.ninja'

  # Collect a list of all targets and tasks.
  targets = [unit.get_target(x) for x in args.targets]
  defaults = [t.identifier for t in targets if isinstance(t, creator.unit.Target)]

  if args.export:
    # Print a warning for each specified non-buildable target.
    for target in targets:
      if isinstance(target, creator.unit.Task):
        log("warning: {0} is a task".format(target.identifier))

  # If we have any buildable targets specified, no targets specified at
  # all or if we should only export the build definitions, do exactly that.
  if not args.no_export and (args.export or defaults or not targets):
    log("exporting to: {0}".format(args.output))
    with open(args.output, 'w') as fp:
      creator.ninja.export(fp, workspace, unit, defaults)
    if args.export:
      return 0

  ninja_args = ['ninja', '-f', args.output] + args.args
  if args.clean:
    ninja_args.extend(['-t', 'clean'])
  if args.verbose:
    ninja_args.append('-v')

  # No targets specified on the command-line? Build it all.
  if not targets:
    return call_subprocess(ninja_args)
  else:
    # Run each target with its own call to ninja and the tasks in between.
    for target in targets:
      if isinstance(target, creator.unit.Task):
        log("running task '{0}'".format(target.identifier))
        target.func()
      elif isinstance(target, creator.unit.Target):
        ident = creator.ninja.ident(target.identifier)
        res = call_subprocess(ninja_args + [ident])
        if res != 0:
          return res

    return 0