Example #1
0
  def __init__(self, name, source, dependencies=None, resources=None):
    InternalTarget.__init__(self, name, dependencies, is_meta=False)
    TargetWithSources.__init__(self, name)

    self.source = self._resolve_paths(self.target_base, [source]).pop()
    self.resources = self._resolve_paths(self.target_base, resources) if resources else []
    self._wikis = {}
Example #2
0
    def __init__(self,
                 name,
                 sources,
                 dependencies,
                 excludes=None,
                 buildflags=None,
                 is_meta=False,
                 configurations=None):
        InternalTarget.__init__(self, name, dependencies, is_meta)
        TargetWithSources.__init__(self, name, is_meta)

        self.declared_dependencies = set(dependencies or [])
        self.add_label('jvm')
        self.sources = self._resolve_paths(self.target_base, sources) or []
        for source in self.sources:
            rel_path = os.path.join(self.target_base, source)
            TargetWithSources.register_source(rel_path, self)
        self.excludes = excludes or []
        self.buildflags = buildflags or []

        custom_antxml = '%s.xml' % self.name
        buildfile = self.address.buildfile.full_path
        custom_antxml_path = os.path.join(os.path.dirname(buildfile),
                                          custom_antxml)
        self.custom_antxml_path = custom_antxml_path if os.path.exists(
            custom_antxml_path) else None

        self.configurations = configurations
Example #3
0
File: doc.py Project: avadh/commons
 def __init__(self, name, dependencies=(), sources=None, resources=None):
   InternalTarget.__init__(self, name, dependencies, None)
   TargetWithSources.__init__(self, name)
   if not sources:
     raise TargetDefinitionException(self, 'No sources specified')
   self.name = name
   self.sources = self._resolve_paths(self.target_base, sources)
   self.resources = self._resolve_paths(self.target_base, resources) if resources else []
Example #4
0
  def test_validation(self):
    with ParseContext.temp('InternalTargetTest/test_validation'):
      InternalTarget(name="valid", dependencies=None)
      self.assertRaises(TargetDefinitionException, InternalTarget,
                        name=1, dependencies=None)

      InternalTarget(name="valid2", dependencies=Target(name='mybird'))
      self.assertRaises(TargetDefinitionException, InternalTarget,
                        name='valid3', dependencies=1)
Example #5
0
 def __init__(self, name, dependencies=(), sources=None, resources=None):
     InternalTarget.__init__(self, name, dependencies, None)
     TargetWithSources.__init__(self, name)
     if not sources:
         raise TargetDefinitionException(self, 'No sources specified')
     self.name = name
     self.sources = self._resolve_paths(self.target_base, sources)
     self.resources = self._resolve_paths(self.target_base,
                                          resources) if resources else []
Example #6
0
    def __init__(self, name, source, dependencies=None, resources=None):
        InternalTarget.__init__(self, name, dependencies, is_meta=False)
        TargetWithSources.__init__(self, name)

        self.sources = self._resolve_paths(self.target_base, [source])
        self._source = self.sources.pop()

        self.resources = self._resolve_paths(self.target_base,
                                             resources) if resources else []
        self._wikis = {}
Example #7
0
  def testSort(self):
    a = MockTarget('a', [])
    b = MockTarget('b', [a])
    c = MockTarget('c', [b])
    d = MockTarget('d', [c, a])
    e = MockTarget('e', [d])

    self.assertEquals(InternalTarget.sort_targets([a,b,c,d,e]), [e,d,c,b,a])
    self.assertEquals(InternalTarget.sort_targets([b,d,a,e,c]), [e,d,c,b,a])
    self.assertEquals(InternalTarget.sort_targets([e,d,c,b,a]), [e,d,c,b,a])
Example #8
0
 def __init__(self, name, dependencies=None, num_sources=0, exclusives=None):
   with ParseContext.temp():
     InternalTarget.__init__(self, name, dependencies, exclusives=exclusives)
     TargetWithSources.__init__(self, name, exclusives=exclusives)
   self.num_sources = num_sources
   self.declared_exclusives = defaultdict(set)
   if exclusives is not None:
     for k in exclusives:
       self.declared_exclusives[k] = set([exclusives[k]])
   self.exclusives = None
Example #9
0
  def test_detect_cycle_direct(self):
    a = MockTarget('a')

    # no cycles yet
    InternalTarget.sort_targets([a])
    a.update_dependencies([a])
    try:
      InternalTarget.sort_targets([a])
      self.fail("Expected a cycle to be detected")
    except InternalTarget.CycleException:
      # expected
      pass
Example #10
0
  def __init__(self, name, sources, dependencies, excludes=None, buildflags=None, is_meta=False):
    InternalTarget.__init__(self, name, dependencies, is_meta)
    TargetWithSources.__init__(self, name, is_meta)

    self.sources = self._resolve_paths(self.target_base, sources) or []
    self.excludes = excludes or []
    self.buildflags = buildflags or []

    custom_antxml = '%s.xml' % self.name
    buildfile = self.address.buildfile.full_path
    custom_antxml_path = os.path.join(os.path.dirname(buildfile), custom_antxml)
    self.custom_antxml_path = custom_antxml_path if os.path.exists(custom_antxml_path) else None
Example #11
0
  def exported_targets(self):
    candidates = set()
    if self.transitive:
      candidates.update(self.context.targets())
    else:
      candidates.update(self.context.target_roots)

      def get_synthetic(lang, target):
        mappings = self.context.products.get(lang).get(target)
        if mappings:
          for generated in mappings.itervalues():
            for synthetic in generated:
              yield synthetic

      # Handle the case where a code gen target is in the listed roots and the thus the publishable
      # target is a synthetic twin generated by a code gen task upstream.
      for candidate in self.context.target_roots:
        candidates.update(get_synthetic('java', candidate))
        candidates.update(get_synthetic('scala', candidate))

    def exportable(tgt):
      return tgt in candidates and tgt.is_exported

    return OrderedSet(filter(exportable,
                             reversed(InternalTarget.sort_targets(filter(exportable, candidates)))))
Example #12
0
  def execute(self, targets):
    java_targets = filter(JavaCompile._is_java, reversed(InternalTarget.sort_targets(targets)))
    if java_targets:
      safe_mkdir(self._classes_dir)
      safe_mkdir(self._depfile_dir)

      with self.context.state('classpath', []) as cp:
        for conf in self._confs:
          cp.insert(0, (conf, self._resources_dir))
          cp.insert(0, (conf, self._classes_dir))

      if not self._flatten:
        for target in java_targets:
          self.execute_single_compilation([target], cp)
      else:
        self.execute_single_compilation(java_targets, cp)

      if self.context.products.isrequired('classes'):
        genmap = self.context.products.get('classes')

        # Map generated classes to the owning targets and sources.
        for target, classes_by_source in self._deps.findclasses(java_targets).items():
          for source, classes in classes_by_source.items():
            genmap.add(source, self._classes_dir, classes)
            genmap.add(target, self._classes_dir, classes)

        # TODO(John Sirois): Map target.resources in the same way
        # 'Map' (rewrite) annotation processor service info files to the owning targets.
        for target in java_targets:
          if is_apt(target) and target.processors:
            basedir = os.path.join(self._resources_dir, target.id)
            processor_info_file = os.path.join(basedir, _PROCESSOR_INFO_FILE)
            self.write_processor_info(processor_info_file, target.processors)
            genmap.add(target, basedir, [_PROCESSOR_INFO_FILE])
Example #13
0
def extract_target(java_targets, is_classpath):
  primary_target = InternalTarget.sort_targets(java_targets)[0]

  with ParseContext.temp(primary_target.target_base):
    internal_deps, jar_deps = _extract_target(java_targets, is_classpath)

    # TODO(John Sirois): make an empty source set work in ant/compile.xml
    sources = [ '__no_source__' ]

    all_deps = OrderedSet()
    all_deps.update(internal_deps)
    all_deps.update(jar_deps)

    if is_java(primary_target):
      return JavaLibrary('ide',
                         sources,
                         dependencies = all_deps,
                         is_meta = True)
    elif is_scala(primary_target):
      return ScalaLibrary('ide',
                          sources,
                          dependencies = all_deps,
                          is_meta = True)
    else:
      raise TypeError("Cannot generate IDE configuration for targets: %s" % java_targets)
Example #14
0
 def _order_target_list(self, targets):
     """Orders the targets topologically, from least to most dependent."""
     target_ids = set([x.id for x in targets])
     ordered_targets_and_deps = reversed(
         InternalTarget.sort_targets(targets))
     # Return just the ones that were originally in targets.
     return filter(lambda x: x.id in target_ids, ordered_targets_and_deps)
Example #15
0
  def exported_targets(self):
    candidates = set()
    if self.transitive:
      candidates.update(self.context.targets())
    else:
      candidates.update(self.context.target_roots)

      def get_synthetic(lang, target):
        mappings = self.context.products.get(lang).get(target)
        if mappings:
          for generated in mappings.itervalues():
            for synthetic in generated:
              yield synthetic

      # Handle the case where a code gen target is in the listed roots and the thus the publishable
      # target is a synthetic twin generated by a code gen task upstream.
      for candidate in self.context.target_roots:
        candidates.update(get_synthetic('java', candidate))
        candidates.update(get_synthetic('scala', candidate))

    def exportable(tgt):
      return tgt in candidates and tgt.is_exported

    return OrderedSet(filter(exportable,
                             reversed(InternalTarget.sort_targets(filter(exportable, candidates)))))
Example #16
0
    def _create_chunks(self):
        def discriminator(tgt):
            for group_member in self._group_members:
                if group_member.predicate(tgt):
                    return group_member.name
            return None

        # TODO(John Sirois): coalescing should be made available in another spot, InternalTarget is jvm
        # specific, and all we care is that the Targets have dependencies defined
        coalesced = InternalTarget.coalesce_targets(self._targets,
                                                    discriminator)
        coalesced = list(reversed(coalesced))

        chunks = []
        flavor = None
        chunk_start = 0
        for chunk_num, target in enumerate(coalesced):
            target_flavor = discriminator(target)
            if target_flavor != flavor and chunk_num > chunk_start:
                chunks.append(OrderedSet(coalesced[chunk_start:chunk_num]))
                chunk_start = chunk_num
            flavor = target_flavor
        if chunk_start < len(coalesced):
            chunks.append(OrderedSet(coalesced[chunk_start:]))
        return chunks
Example #17
0
  def execute(self, targets):
    if not self._flatten and len(targets) > 1:
      topologically_sorted_targets = filter(JavaCompile._is_java, reversed(InternalTarget.sort_targets(targets)))
      for target in topologically_sorted_targets:
        self.execute([target])
      return

    self.context.log.info('Compiling targets %s' % str(targets))

    java_targets = filter(JavaCompile._is_java, targets)
    if java_targets:
      with self.context.state('classpath', []) as cp:
        for conf in self._confs:
          cp.insert(0, (conf, self._resources_dir))
          cp.insert(0, (conf, self._classes_dir))

        with self.changed(java_targets, invalidate_dependants=True) as changed:
          sources_by_target, processors, fingerprint = self.calculate_sources(changed)
          if sources_by_target:
            sources = reduce(lambda all, sources: all.union(sources), sources_by_target.values())
            if not sources:
              self.context.log.warn('Skipping java compile for targets with no sources:\n  %s' %
                                    '\n  '.join(str(t) for t in sources_by_target.keys()))
            else:
              classpath = [jar for conf, jar in cp if conf in self._confs]
              result = self.compile(classpath, sources, fingerprint)
              if result != 0:
                default_message = 'Unexpected error - %s returned %d' % (_JMAKE_MAIN, result)
                raise TaskError(_JMAKE_ERROR_CODES.get(result, default_message))

            if processors:
              # Produce a monolithic apt processor service info file for further compilation rounds
              # and the unit test classpath.
              processor_info_file = os.path.join(self._classes_dir, _PROCESSOR_INFO_FILE)
              if os.path.exists(processor_info_file):
                with safe_open(processor_info_file, 'r') as f:
                  for processor in f:
                    processors.add(processor.strip())
              self.write_processor_info(processor_info_file, processors)

      if self.context.products.isrequired('classes'):
        genmap = self.context.products.get('classes')

        # Map generated classes to the owning targets and sources.
        dependencies = Dependencies(self._classes_dir, self._dependencies_file)
        for target, classes_by_source in dependencies.findclasses(targets).items():
          for source, classes in classes_by_source.items():
            genmap.add(source, self._classes_dir, classes)
            genmap.add(target, self._classes_dir, classes)

        # TODO(John Sirois): Map target.resources in the same way
        # 'Map' (rewrite) annotation processor service info files to the owning targets.
        for target in targets:
          if is_apt(target) and target.processors:
            basedir = os.path.join(self._resources_dir, target.id)
            processor_info_file = os.path.join(basedir, _PROCESSOR_INFO_FILE)
            self.write_processor_info(processor_info_file, target.processors)
            genmap.add(target, basedir, [_PROCESSOR_INFO_FILE])
Example #18
0
  def _order_target_list(self, targets):
    """Orders the targets topologically, from least to most dependent."""
    target_ids = set([x.id for x in targets])

    # Most to least dependent.
    reverse_ordered_targets_and_deps = InternalTarget.sort_targets(targets)
    # Least to most dependent. We must build in this order.
    ordered_targets_and_deps = reversed(reverse_ordered_targets_and_deps)
    # Return just the ones that were originally in targets.
    return filter(lambda x: x.id in target_ids, ordered_targets_and_deps)
Example #19
0
    def execute(self, targets):
        if not self._flatten and len(targets) > 1:
            topologically_sorted_targets = filter(
                is_scala, reversed(InternalTarget.sort_targets(targets)))
            for target in topologically_sorted_targets:
                self.execute([target])
            return

        self.context.log.info('Compiling targets %s' % str(targets))

        scala_targets = filter(is_scala, targets)
        if scala_targets:
            with self.context.state('classpath', []) as cp:
                for conf in self._confs:
                    cp.insert(0, (conf, self._resources_dir))
                    cp.insert(0, (conf, self._classes_dir))

            with self.changed(scala_targets,
                              invalidate_dependants=True) as changed_targets:
                sources_by_target = self.calculate_sources(changed_targets)
                if sources_by_target:
                    sources = reduce(lambda all, sources: all.union(sources),
                                     sources_by_target.values())
                    if not sources:
                        self.context.log.warn(
                            'Skipping scala compile for targets with no sources:\n  %s'
                            % '\n  '.join(
                                str(t) for t in sources_by_target.keys()))
                    else:
                        classpath = [
                            jar for conf, jar in cp if conf in self._confs
                        ]
                        result = self.compile(classpath, sources)
                        if result != 0:
                            raise TaskError('%s returned %d' %
                                            (self._main, result))

            if self.context.products.isrequired('classes'):
                genmap = self.context.products.get('classes')

                # Map generated classes to the owning targets and sources.
                dependencies = Dependencies(self._classes_dir, self._depfile)
                for target, classes_by_source in dependencies.findclasses(
                        targets).items():
                    for source, classes in classes_by_source.items():
                        genmap.add(source, self._classes_dir, classes)
                        genmap.add(target, self._classes_dir, classes)

                # TODO(John Sirois): Map target.resources in the same way
                # Create and Map scala plugin info files to the owning targets.
                for target in targets:
                    if is_scalac_plugin(target) and target.classname:
                        basedir = self.write_plugin_info(target)
                        genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
 def _compute_transitive_deps_by_target(self):
   """Map from target to all the targets it depends on, transitively."""
   # Sort from least to most dependent.
   sorted_targets = reversed(InternalTarget.sort_targets(self._context.targets()))
   transitive_deps_by_target = defaultdict(set)
   # Iterate in dep order, to accumulate the transitive deps for each target.
   for target in sorted_targets:
     transitive_deps = set()
     if hasattr(target, 'dependencies'):
       for dep in target.dependencies:
         transitive_deps.update(transitive_deps_by_target.get(dep, []))
         transitive_deps.add(dep)
       transitive_deps_by_target[target] = transitive_deps
   return transitive_deps_by_target
Example #21
0
 def _compute_transitive_deps_by_target(self):
     """Map from target to all the targets it depends on, transitively."""
     # Sort from least to most dependent.
     sorted_targets = reversed(
         InternalTarget.sort_targets(self._context.targets()))
     transitive_deps_by_target = defaultdict(set)
     # Iterate in dep order, to accumulate the transitive deps for each target.
     for target in sorted_targets:
         transitive_deps = set()
         if hasattr(target, 'dependencies'):
             for dep in target.dependencies:
                 transitive_deps.update(
                     transitive_deps_by_target.get(dep, []))
                 transitive_deps.add(dep)
             transitive_deps_by_target[target] = transitive_deps
     return transitive_deps_by_target
Example #22
0
  def execute(self, targets):
    if not self._flatten and len(targets) > 1:
      topologically_sorted_targets = filter(is_scala, reversed(InternalTarget.sort_targets(targets)))
      for target in topologically_sorted_targets:
        self.execute([target])
      return

    self.context.log.info('Compiling targets %s' % str(targets))

    scala_targets = filter(is_scala, targets)
    if scala_targets:
      with self.context.state('classpath', []) as cp:
        for conf in self._confs:
          cp.insert(0, (conf, self._resources_dir))
          cp.insert(0, (conf, self._classes_dir))

      with self.changed(scala_targets, invalidate_dependants=True) as changed_targets:
        sources_by_target = self.calculate_sources(changed_targets)
        if sources_by_target:
          sources = reduce(lambda all, sources: all.union(sources), sources_by_target.values())
          if not sources:
            self.context.log.warn('Skipping scala compile for targets with no sources:\n  %s' %
                                  '\n  '.join(str(t) for t in sources_by_target.keys()))
          else:
            classpath = [jar for conf, jar in cp if conf in self._confs]
            result = self.compile(classpath, sources)
            if result != 0:
              raise TaskError('%s returned %d' % (self._main, result))

      if self.context.products.isrequired('classes'):
        genmap = self.context.products.get('classes')

        # Map generated classes to the owning targets and sources.
        dependencies = Dependencies(self._classes_dir, self._depfile)
        for target, classes_by_source in dependencies.findclasses(targets).items():
          for source, classes in classes_by_source.items():
            genmap.add(source, self._classes_dir, classes)
            genmap.add(target, self._classes_dir, classes)

        # TODO(John Sirois): Map target.resources in the same way
        # Create and Map scala plugin info files to the owning targets.
        for target in targets:
          if is_scalac_plugin(target) and target.classname:
            basedir = self.write_plugin_info(target)
            genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
Example #23
0
  def execute(self, targets):
    scala_targets = filter(is_scala, reversed(InternalTarget.sort_targets(targets)))
    if scala_targets:
      safe_mkdir(self._classes_dir)
      safe_mkdir(self._depfile_dir)

      with self.context.state('classpath', []) as cp:
        for conf in self._confs:
          cp.insert(0, (conf, self._resources_dir))
          # If we're not flattening, we don't want the classes dir on the classpath yet, as we want zinc to
          # see only the per-compilation output dirs, so it can map them to analysis caches.
          if self._flatten:
            cp.insert(0, (conf, self._classes_dir))

      if not self._flatten:
        upstream_analysis_caches = OrderedDict()  # output dir -> analysis cache file for the classes in that dir.
        for target in scala_targets:
          self.execute_single_compilation([target], cp, upstream_analysis_caches)
      else:
        self.execute_single_compilation(scala_targets, cp, {})

      if not self._flatten:
        # Now we can add the global output dir, so that subsequent goals can see it.
        with self.context.state('classpath', []) as cp:
          for conf in self._confs:
            cp.insert(0, (conf, self._classes_dir))

      if self.context.products.isrequired('classes'):
        genmap = self.context.products.get('classes')

        # Map generated classes to the owning targets and sources.
        for target, classes_by_source in self._deps.findclasses(scala_targets).items():
          for source, classes in classes_by_source.items():
            genmap.add(source, self._classes_dir, classes)
            genmap.add(target, self._classes_dir, classes)

        # TODO(John Sirois): Map target.resources in the same way
        # Create and Map scala plugin info files to the owning targets.
        for target in scala_targets:
          if is_scalac_plugin(target) and target.classname:
            basedir = self.write_plugin_info(target)
            genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
Example #24
0
  def execute(self, targets):
    scala_targets = filter(is_scala, reversed(InternalTarget.sort_targets(targets)))
    if scala_targets:
      safe_mkdir(self._depfile_dir)
      safe_mkdir(self._analysis_cache_dir)

      # Map from output directory to { analysis_cache_dir, [ analysis_cache_file ]}
      upstream_analysis_caches = self.context.products.get('upstream')

      with self.context.state('classpath', []) as cp:
        for conf in self._confs:
          cp.insert(0, (conf, self._resources_dir))

      if self._flatten:
        self.execute_single_compilation(scala_targets, cp, upstream_analysis_caches)
      else:
        for target in scala_targets:
          self.execute_single_compilation([target], cp, upstream_analysis_caches)


      # Now we can add the global output dir, so that subsequent goals can see it.
      with self.context.state('classpath', []) as cp:
        for conf in self._confs:
          cp.insert(0, (conf, self._classes_dir))

      if self.context.products.isrequired('classes'):
        genmap = self.context.products.get('classes')

        # Map generated classes to the owning targets and sources.
        for target, classes_by_source in self._deps.findclasses(scala_targets).items():
          for source, classes in classes_by_source.items():
            genmap.add(source, self._classes_dir, classes)
            genmap.add(target, self._classes_dir, classes)

        # TODO(John Sirois): Map target.resources in the same way
        # Create and Map scala plugin info files to the owning targets.
        for target in scala_targets:
          if is_scalac_plugin(target) and target.classname:
            basedir = self.write_plugin_info(target)
            genmap.add(target, basedir, [_PLUGIN_INFO_FILE])
Example #25
0
  def _create_chunks(self):
    def discriminator(tgt):
      for group_member in self._group_members:
        if group_member.predicate(tgt):
          return group_member.name
      return None

    # TODO(John Sirois): coalescing should be made available in another spot, InternalTarget is jvm
    # specific, and all we care is that the Targets have dependencies defined
    coalesced = InternalTarget.coalesce_targets(self._targets, discriminator)
    coalesced = list(reversed(coalesced))

    chunks = []
    flavor = None
    chunk_start = 0
    for chunk_num, target in enumerate(coalesced):
      target_flavor = discriminator(target)
      if target_flavor != flavor and chunk_num > chunk_start:
        chunks.append(OrderedSet(coalesced[chunk_start:chunk_num]))
        chunk_start = chunk_num
      flavor = target_flavor
    if chunk_start < len(coalesced):
      chunks.append(OrderedSet(coalesced[chunk_start:]))
    return chunks
Example #26
0
 def _order_target_list(self, targets):
   """Orders the targets topologically, from least to most dependent."""
   targets = set(t for t in targets if isinstance(t, Target))
   return filter(targets.__contains__, reversed(InternalTarget.sort_targets(targets)))
 def _order_target_list(self, targets):
   """Orders the targets topologically, from least to most dependent."""
   targets = set(filter(has_sources, targets))
   return filter(targets.__contains__, reversed(InternalTarget.sort_targets(targets)))
Example #28
0
 def _order_target_list(self, targets):
     """Orders the targets topologically, from least to most dependent."""
     targets = set(filter(has_sources, targets))
     return filter(targets.__contains__,
                   reversed(InternalTarget.sort_targets(targets)))
Example #29
0
    def execute(self, targets):
        if not self._flatten and len(targets) > 1:
            topologically_sorted_targets = filter(
                JavaCompile._is_java,
                reversed(InternalTarget.sort_targets(targets)))
            for target in topologically_sorted_targets:
                self.execute([target])
            return

        self.context.log.info('Compiling targets %s' % str(targets))

        java_targets = filter(JavaCompile._is_java, targets)
        if java_targets:
            with self.context.state('classpath', []) as cp:
                for conf in self._confs:
                    cp.insert(0, (conf, self._resources_dir))
                    cp.insert(0, (conf, self._classes_dir))

                with self.changed(java_targets,
                                  invalidate_dependants=True) as changed:
                    sources_by_target, processors, fingerprint = self.calculate_sources(
                        changed)
                    if sources_by_target:
                        sources = reduce(
                            lambda all, sources: all.union(sources),
                            sources_by_target.values())
                        if not sources:
                            self.context.log.warn(
                                'Skipping java compile for targets with no sources:\n  %s'
                                % '\n  '.join(
                                    str(t) for t in sources_by_target.keys()))
                        else:
                            classpath = [
                                jar for conf, jar in cp if conf in self._confs
                            ]
                            result = self.compile(classpath, sources,
                                                  fingerprint)
                            if result != 0:
                                default_message = 'Unexpected error - %s returned %d' % (
                                    _JMAKE_MAIN, result)
                                raise TaskError(
                                    _JMAKE_ERROR_CODES.get(
                                        result, default_message))

                        if processors:
                            # Produce a monolithic apt processor service info file for further compilation rounds
                            # and the unit test classpath.
                            processor_info_file = os.path.join(
                                self._classes_dir, _PROCESSOR_INFO_FILE)
                            if os.path.exists(processor_info_file):
                                with safe_open(processor_info_file, 'r') as f:
                                    for processor in f:
                                        processors.add(processor.strip())
                            self.write_processor_info(processor_info_file,
                                                      processors)

            if self.context.products.isrequired('classes'):
                genmap = self.context.products.get('classes')

                # Map generated classes to the owning targets and sources.
                dependencies = Dependencies(self._classes_dir,
                                            self._dependencies_file)
                for target, classes_by_source in dependencies.findclasses(
                        targets).items():
                    for source, classes in classes_by_source.items():
                        genmap.add(source, self._classes_dir, classes)
                        genmap.add(target, self._classes_dir, classes)

                # TODO(John Sirois): Map target.resources in the same way
                # 'Map' (rewrite) annotation processor service info files to the owning targets.
                for target in targets:
                    if is_apt(target) and target.processors:
                        basedir = os.path.join(self._resources_dir, target.id)
                        processor_info_file = os.path.join(
                            basedir, _PROCESSOR_INFO_FILE)
                        self.write_processor_info(processor_info_file,
                                                  target.processors)
                        genmap.add(target, basedir, [_PROCESSOR_INFO_FILE])