##### MakeTargets (.MF? -> Builders) def makeTargetsEmitter(target, source, env): for t in target: t.set_always_build() t.set_ignore_missing() return (target, source) def makeTargets(target, source, env, for_signature): if for_signature: return "" if hasattr(SCons.Job, 'parallel_lock'): # print 'acquire builder' SCons.Job.parallel_lock.acquire() # print 'acquired builder' try: cache_clear_needed = {} conglomerates = {} mft = source[0] for x in target: if env["VERBOSITY"]: print>>sys.stderr, 'INF: Building DAG for "%s"' % mft for y in x.children(): if env["SYNC_PERFORCE"] and y.has_builder() and y.has_src_builder() and (id(y.builder) == id(y.src_builder())): y.builder_set(None) if not y.has_builder(): skey = y.scanner_key().lower() if not skey: continue name = os.path.basename(str(y)).lower() # Find a builder that matches this suffix for k, v in env["BUILDERS"].items(): if v.get_suffix(env, [y]) == skey: if not hasattr(y.attributes, 'mfp_source'): raise BuilderException('Cannot build a DAG for "%s" because it was handled by an invalid scanner in "%s"' % (y, mft)) if y.attributes.mfp_source: source = env.File(y.attributes.mfp_source) else: source = None if not source: if not v.overrides.get("allow_no_source", None): raise BuilderException('%%SOURCE directive missing for "%s" to be able to apply the builder "%s" in "%s"' % (y, k, mft)) else: src_mutator = v.overrides.get("src_mutator", None) if src_mutator: source = src_mutator(y, source, env) if source.scanner_key() not in v.src_suffixes(env): raise BuilderException('The %%SOURCE suffix does not match for "%s" from "%s" in "%s": %s' % (source, y, mft, v.src_suffixes(env))) source.set_intermediate_path(y.dir) if v.overrides.get('conglomerate', 0): if k not in conglomerates: conglomerates[k] = (v, [], []) conglomerates[k][1].append(y) if source: conglomerates[k][2].append(source) continue if env["VERBOSITY"] > 2: print 'INF: Builder:', k, y, source, y.attributes.mfp_overrides try: rule = v(*(env, y, source), **y.attributes.mfp_overrides) markForCacheClear(cache_clear_needed, rule) except CrushException, b: print>>sys.stderr, 'ERR: Got an exception while creating build rules for "%s" in "%s"' % (y, mft) raise break for k, v in conglomerates.items(): if env["VERBOSITY"] > 2: print 'INF: ConglomerateBuilder:', k, v[0], map(str, v[1]), map(str, v[2]) try: rule = v[0](*(env, v[1], v[2])) markForCacheClear(cache_clear_needed, rule) except CrushException, b: print>>sys.stderr, 'ERR: Got an exception while creating build rules for "%s" in "%s"' % (' '.join(map(str, v[1])), mft) raise break # Sanity check if not env.GetOption('clean'): missing = 0 for x in target: for y in x.children(): if not y.has_builder() and not os.path.exists(str(y)): print>>sys.stderr, 'ERR: Do not know how to build the target "%s"' % y missing += 1 if missing: raise BuilderException('Do not know how to build %d targets needed by "%s"' % (missing, x.children()[0])) if not len(cache_clear_needed): if env["VERBOSITY"] > 1: print>>sys.stderr, 'INF: No targets for "%s" were auto-generated' % mft else: cleared = doCacheClear(cache_clear_needed, env) if env["VERBOSITY"] > 1: print>>sys.stderr, "INF: Cleared %d of %d DAG dependencies for %s" % (cleared, len(cache_clear_needed), mft) finally: if hasattr(SCons.Job, 'parallel_lock'): # print 'release builder' SCons.Job.parallel_lock.release() return "" env['BUILDERS']['MakeTargets'] = Builder( generator = makeTargets, emitter = makeTargetsEmitter, )