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
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