ninja-build / ninja

a small build system with a focus on speed
https://ninja-build.org/
Apache License 2.0
11.24k stars 1.6k forks source link

Build targets listed on ninja command line in order #1055

Closed NiklasRosenstein closed 8 years ago

NiklasRosenstein commented 8 years ago

I have a ninja file that has a target "nr.container_object.plugin" and "maxon.c4d.run". The run target has no dependency of the plugin target. But when I invoke it with `ninja nr.container_object.plugin maxon.c4d.run", I would like to build/invoke the targets in order, because the plugin target should be built before the run target starts the application.

Is there any way to achive this with a single ninja command?

sgraham commented 8 years ago

That's kind of the definition of dependencies. Why don't you add an dependency on the plugin target? On Nov 21, 2015 5:55 AM, "Niklas Rosenstein" notifications@github.com wrote:

I have a ninja file that has a target "nr.container_object.plugin" and "maxon.c4d.run". The run target has no dependency of the plugin target. But when I invoke it with `ninja nr.container_object.plugin maxon.c4d.run", I would like to build/invoke the targets in order, because the plugin target should be built before the run target starts the application.

Is there any way to achive this with a single ninja command?

— Reply to this email directly or view it on GitHub https://github.com/ninja-build/ninja/issues/1055.

NiklasRosenstein commented 8 years ago

It would be nice if that wouldn't be required. My meta build system uses modules, and one module exposes the "run" target, the uses that module to create build targets for the plugin. In a greater scope, you might have multiple plugin but only want to build one and run, hence you don't want all plugins to be a dependency for the "run" target. Currently, I solve this with running ninja multiple times.

def main_build(args, session, module):
  from craftr.backend.ninja import ident

  targets = [session.resolve_target(t, module) for t in args.targets]
  if not os.path.exists('build.ninja') or args.export:
    args.export = False
    args.backend = 'ninja'
    args.backend_args = []
    main_export(args, session, module)

  if args.rebuild:
    clean_cmd = ['ninja', '-t', 'clean']
    clean_cmd += [ident(t.identifier) for t in targets]
    res = subprocess.call(clean_cmd, shell=True)
    if res:
      return res

  if not targets:
    return subprocess.call(['ninja'], shell=True)
  else:
    # xxx: ninja (1.6.0) does not make sure the targets are built in the
    # order they are specified. We ensure this by making multiple calls.
    for t in targets:
      res = subprocess.call(['ninja', ident(t.identifier)], shell=True)
      if res:
        return res

  return 0
sgraham commented 8 years ago

For the second part, maybe an order-only dep. https://ninja-build.org/manual.html#ref_dependencies On Nov 21, 2015 6:03 AM, "Niklas Rosenstein" notifications@github.com wrote:

It would be nice if that wouldn't be required. My meta build system uses modules, and one module exposes the "run" target, the uses that module to create build targets for the plugin. In a greater scope, you might have multiple plugin but only want to build one and run, hence you don't want all plugins to be a dependency for the "run" target. Currently, I solve this with running ninja multiple times.

def main_build(args, session, module): from craftr.backend.ninja import ident

targets = [session.resolve_target(t, module) for t in args.targets] if not os.path.exists('build.ninja') or args.export: args.export = False args.backend = 'ninja' args.backend_args = [] main_export(args, session, module)

if args.rebuild: clean_cmd = ['ninja', '-t', 'clean'] clean_cmd += [ident(t.identifier) for t in targets] res = subprocess.call(clean_cmd, shell=True) if res: return res

if not targets: return subprocess.call(['ninja'], shell=True) else:

xxx: ninja (1.6.0) does not make sure the targets are built in the

# order they are specified. We ensure this by making multiple calls.
for t in targets:
  res = subprocess.call(['ninja', ident(t.identifier)], shell=True)
  if res:
    return res

return 0

— Reply to this email directly or view it on GitHub https://github.com/ninja-build/ninja/issues/1055#issuecomment-158645003.

NiklasRosenstein commented 8 years ago

I didn't know about order only deps. It works, thanks!