Пример #1
0
 // This test rule just executes the test bundle, so we need it available locally.
 @Override
 public ImmutableSortedSet<BuildRule> getRuntimeDeps() {
   return ImmutableSortedSet.<BuildRule>naturalOrder()
       .add(testBundle)
       .addAll(getResolver().filterBuildRuleInputs(xctool.asSet()))
       .addAll(testHostApp.asSet())
       .build();
 }
Пример #2
0
    @Override
    public Optional<ImmutableSet<PreemptionVictim>> filterPreemptionVictims(
        ITaskConfig pendingTask,
        Iterable<PreemptionVictim> possibleVictims,
        AttributeAggregate jobState,
        Optional<HostOffer> offer,
        StoreProvider storeProvider) {

      // This enforces the precondition that all of the resources are from the same host. We need to
      // get the host for the schedulingFilter.
      Set<String> hosts =
          ImmutableSet.<String>builder()
              .addAll(Iterables.transform(possibleVictims, VICTIM_TO_HOST))
              .addAll(Iterables.transform(offer.asSet(), OFFER_TO_HOST))
              .build();

      ResourceSlot slackResources = sum(Iterables.transform(offer.asSet(), OFFER_TO_RESOURCE_SLOT));

      FluentIterable<PreemptionVictim> preemptableTasks =
          FluentIterable.from(possibleVictims).filter(preemptionFilter(pendingTask));

      if (preemptableTasks.isEmpty()) {
        return Optional.absent();
      }

      Set<PreemptionVictim> toPreemptTasks = Sets.newHashSet();

      Iterable<PreemptionVictim> sortedVictims =
          resourceOrder.immutableSortedCopy(preemptableTasks);

      Optional<IHostAttributes> attributes =
          storeProvider.getAttributeStore().getHostAttributes(Iterables.getOnlyElement(hosts));

      if (!attributes.isPresent()) {
        metrics.recordMissingAttributes();
        return Optional.absent();
      }

      for (PreemptionVictim victim : sortedVictims) {
        toPreemptTasks.add(victim);

        ResourceSlot totalResource =
            sum(Iterables.transform(toPreemptTasks, victimToResources)).add(slackResources);

        Set<Veto> vetoes =
            schedulingFilter.filter(
                new UnusedResource(totalResource, attributes.get()),
                new ResourceRequest(pendingTask, jobState));

        if (vetoes.isEmpty()) {
          return Optional.of(ImmutableSet.copyOf(toPreemptTasks));
        }
      }
      return Optional.absent();
    }
  /**
   * Finds the build file responsible for the given {@link Path} and invalidates all of the cached
   * rules dependent on it.
   *
   * @param path A {@link Path}, relative to the project root and "contained" within the build file
   *     to find and invalidate.
   */
  private synchronized void invalidateContainingBuildFile(
      Cell cell, BuildFileTree buildFiles, Path path) {
    Set<Path> packageBuildFiles = new HashSet<>();

    // Find the closest ancestor package for the input path.  We'll definitely need to invalidate
    // that.
    Optional<Path> packageBuildFile = buildFiles.getBasePathOfAncestorTarget(path);
    packageBuildFiles.addAll(
        packageBuildFile.transform(cell.getFilesystem().getAbsolutifier()).asSet());

    // If we're *not* enforcing package boundary checks, it's possible for multiple ancestor
    // packages to reference the same file
    if (!cell.isEnforcingBuckPackageBoundaries()) {
      while (packageBuildFile.isPresent() && packageBuildFile.get().getParent() != null) {
        packageBuildFile =
            buildFiles.getBasePathOfAncestorTarget(packageBuildFile.get().getParent());
        packageBuildFiles.addAll(packageBuildFile.asSet());
      }
    }

    // Invalidate all the packages we found.
    for (Path buildFile : packageBuildFiles) {
      invalidatePath(cell, buildFile.resolve(cell.getBuildFileName()));
    }
  }
Пример #4
0
 private void collectProviders(Set<XcodeProvider> allProviders) {
   if (allProviders.add(this)) {
     for (XcodeProvider dependency :
         Iterables.concat(propagatedDependencies, nonPropagatedDependencies)) {
       dependency.collectProviders(allProviders);
     }
     for (XcodeProvider justTestHost : testHost.asSet()) {
       justTestHost.collectProviders(allProviders);
     }
     for (XcodeProvider extension : extensions) {
       extension.collectProviders(allProviders);
     }
   }
 }
Пример #5
0
  /** Constructs an {@link ObjcCommon} instance based on the attributes. */
  private ObjcCommon common(RuleContext ruleContext, Optional<ObjcProvider> protosObjcProvider) {
    CompilationArtifacts compilationArtifacts =
        CompilationSupport.compilationArtifacts(ruleContext);

    ObjcCommon.Builder builder =
        new ObjcCommon.Builder(ruleContext)
            .setCompilationAttributes(
                CompilationAttributes.Builder.fromRuleContext(ruleContext).build())
            .setCompilationArtifacts(compilationArtifacts)
            .setResourceAttributes(new ResourceAttributes(ruleContext))
            .addDefines(ruleContext.getTokenizedStringListAttr("defines"))
            .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
            .addRuntimeDeps(ruleContext.getPrerequisites("runtime_deps", Mode.TARGET))
            .addDeps(ruleContext.getPrerequisites("bundles", Mode.TARGET))
            .addDepObjcProviders(protosObjcProvider.asSet())
            .addNonPropagatedDepObjcProviders(
                ruleContext.getPrerequisites(
                    "non_propagated_deps", Mode.TARGET, ObjcProvider.class))
            .setIntermediateArtifacts(ObjcRuleClasses.intermediateArtifacts(ruleContext))
            .setHasModuleMap();

    if (isXcTest(ruleContext)) {
      builder
          .addExtraSdkFrameworks(AUTOMATIC_SDK_FRAMEWORKS_FOR_XCTEST)
          .addDepObjcProviders(ImmutableList.of(xcTestAppProvider(ruleContext).getObjcProvider()));
    }

    // Add the memleaks library if the --ios_memleaks flag is true.  The library pauses the test
    // after all tests have been executed so that leaks can be run.
    ObjcConfiguration config = ruleContext.getFragment(ObjcConfiguration.class);
    if (config.runMemleaks()) {
      builder.addDepObjcProviders(
          ruleContext.getPrerequisites(MEMLEAKS_DEP_ATTR, Mode.TARGET, ObjcProvider.class));
    }

    return builder.build();
  }
Пример #6
0
  @Override
  public <A extends Arg> AppleBundle createBuildRule(
      TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, A args) {
    AppleCxxPlatform appleCxxPlatform = getAppleCxxPlatformForBuildTarget(params.getBuildTarget());
    AppleBundleDestinations destinations =
        AppleBundleDestinations.platformDestinations(
            appleCxxPlatform.getAppleSdk().getApplePlatform());

    ImmutableSet.Builder<SourcePath> bundleDirsBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<SourcePath> dirsContainingResourceDirsBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<SourcePath> bundleFilesBuilder = ImmutableSet.builder();
    ImmutableSet.Builder<SourcePath> bundleVariantFilesBuilder = ImmutableSet.builder();
    AppleResources.collectResourceDirsAndFiles(
        targetGraph,
        Preconditions.checkNotNull(targetGraph.get(params.getBuildTarget())),
        bundleDirsBuilder,
        dirsContainingResourceDirsBuilder,
        bundleFilesBuilder,
        bundleVariantFilesBuilder);
    ImmutableSet<SourcePath> bundleDirs = bundleDirsBuilder.build();
    ImmutableSet<SourcePath> dirsContainingResourceDirs = dirsContainingResourceDirsBuilder.build();
    ImmutableSet<SourcePath> bundleFiles = bundleFilesBuilder.build();
    ImmutableSet<SourcePath> bundleVariantFiles = bundleVariantFilesBuilder.build();

    SourcePathResolver sourcePathResolver = new SourcePathResolver(resolver);

    Optional<AppleAssetCatalog> assetCatalog =
        AppleDescriptions.createBuildRuleForTransitiveAssetCatalogDependencies(
            targetGraph,
            params,
            sourcePathResolver,
            appleCxxPlatform.getAppleSdk().getApplePlatform(),
            appleCxxPlatform.getActool());

    // TODO(user): Sort through the changes needed to make project generation work with
    // binary being optional.
    BuildRule flavoredBinaryRule = getFlavoredBinaryRule(targetGraph, params, resolver, args);
    BuildRuleParams bundleParamsWithFlavoredBinaryDep =
        getBundleParamsWithUpdatedDeps(
            params,
            args.binary,
            ImmutableSet.<BuildRule>builder()
                .add(flavoredBinaryRule)
                .addAll(assetCatalog.asSet())
                .addAll(
                    BuildRules.toBuildRulesFor(
                        params.getBuildTarget(),
                        resolver,
                        SourcePaths.filterBuildTargetSourcePaths(
                            Iterables.concat(
                                bundleFiles,
                                bundleDirs,
                                dirsContainingResourceDirs,
                                bundleVariantFiles))))
                .build());

    ImmutableMap<SourcePath, String> extensionBundlePaths =
        collectFirstLevelAppleDependencyBundles(params.getDeps(), destinations);

    return new AppleBundle(
        bundleParamsWithFlavoredBinaryDep,
        sourcePathResolver,
        args.extension,
        args.productName,
        args.infoPlist,
        args.infoPlistSubstitutions.get(),
        Optional.of(flavoredBinaryRule),
        destinations,
        bundleDirs,
        bundleFiles,
        dirsContainingResourceDirs,
        extensionBundlePaths,
        Optional.of(bundleVariantFiles),
        appleCxxPlatform.getIbtool(),
        appleCxxPlatform.getDsymutil(),
        appleCxxPlatform.getCxxPlatform().getStrip(),
        assetCatalog,
        args.getTests(),
        appleCxxPlatform.getAppleSdk(),
        codeSignIdentityStore,
        provisioningProfileStore,
        AppleBundle.DebugInfoFormat.DSYM);
  }
 public static Function<String, String> from(Optional<DeclaringType> optional) {
   return new ImportsTypeStringResolver(optional.asSet());
 }
Пример #8
0
  /**
   * {@inheritDoc}
   *
   * <p>Creates a target, including registering actions, just as {@link #create(RuleContext)} does.
   * The difference between {@link #create(RuleContext)} and this method is that this method does
   * only what is needed to support tests on the environment besides generate the Xcodeproj file and
   * build the app and test {@code .ipa}s. The {@link #create(RuleContext)} method delegates to this
   * method.
   */
  @Override
  public final ConfiguredTarget create(RuleContext ruleContext)
      throws InterruptedException, RuleErrorException {
    ProtobufSupport protoSupport =
        new ProtobufSupport(ruleContext).registerGenerationActions().registerCompilationActions();
    Optional<ObjcProvider> protosObjcProvider = protoSupport.getObjcProvider();
    Optional<XcodeProvider> protosXcodeProvider = protoSupport.getXcodeProvider();

    ObjcCommon common = common(ruleContext, protosObjcProvider);

    if (!common.getCompilationArtifacts().get().getArchive().isPresent()) {
      ruleContext.ruleError(REQUIRES_SOURCE_ERROR);
    }

    if (!ruleContext.getFragment(AppleConfiguration.class).getIosMultiCpus().isEmpty()) {
      ruleContext.ruleError(NO_MULTI_CPUS_ERROR);
    }

    XcodeProvider.Builder xcodeProviderBuilder =
        new XcodeProvider.Builder().addPropagatedDependencies(protosXcodeProvider.asSet());

    NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.stableOrder();
    addResourceFilesToBuild(ruleContext, common.getObjcProvider(), filesToBuild);

    XcodeProductType productType = getProductType(ruleContext);
    ExtraLinkArgs extraLinkArgs;
    Iterable<Artifact> extraLinkInputs;
    String bundleFormat;
    if (!isXcTest(ruleContext)) {
      extraLinkArgs = new ExtraLinkArgs();
      extraLinkInputs = ImmutableList.of();
      bundleFormat = ReleaseBundlingSupport.APP_BUNDLE_DIR_FORMAT;
    } else {
      XcodeProvider appIpaXcodeProvider =
          ruleContext.getPrerequisite(XCTEST_APP_ATTR, Mode.TARGET, XcodeProvider.class);
      xcodeProviderBuilder.setTestHost(appIpaXcodeProvider).setProductType(productType);

      XcTestAppProvider testApp = xcTestAppProvider(ruleContext);
      Artifact bundleLoader = testApp.getBundleLoader();

      // -bundle causes this binary to be linked as a bundle and not require an entry point
      // (i.e. main())
      // -bundle_loader causes the code in this test to have access to the symbols in the test rig,
      // or more specifically, the flag causes ld to consider the given binary when checking for
      // missing symbols.
      // -rpath @loader_path/Frameworks allows test bundles to load dylibs from the app's
      // Frameworks directory.
      extraLinkArgs =
          new ExtraLinkArgs(
              "-bundle",
              "-bundle_loader",
              bundleLoader.getExecPathString(),
              "-Xlinker",
              "-rpath",
              "-Xlinker",
              "@loader_path/Frameworks");

      extraLinkInputs = ImmutableList.of(bundleLoader);
      bundleFormat = ReleaseBundlingSupport.XCTEST_BUNDLE_DIR_FORMAT;

      filesToBuild.add(testApp.getIpa());
    }

    J2ObjcMappingFileProvider j2ObjcMappingFileProvider =
        J2ObjcMappingFileProvider.union(
            ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcMappingFileProvider.class));
    J2ObjcEntryClassProvider j2ObjcEntryClassProvider =
        new J2ObjcEntryClassProvider.Builder()
            .addTransitive(
                ruleContext.getPrerequisites("deps", Mode.TARGET, J2ObjcEntryClassProvider.class))
            .build();

    new CompilationSupport(ruleContext)
        .registerLinkActions(
            common.getObjcProvider(),
            j2ObjcMappingFileProvider,
            j2ObjcEntryClassProvider,
            extraLinkArgs,
            extraLinkInputs,
            DsymOutputType.TEST)
        .registerCompileAndArchiveActions(common)
        .registerFullyLinkAction(
            common.getObjcProvider(),
            ruleContext.getImplicitOutputArtifact(CompilationSupport.FULLY_LINKED_LIB))
        .addXcodeSettings(xcodeProviderBuilder, common)
        .validateAttributes();

    AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
    new ReleaseBundlingSupport(
            ruleContext,
            common.getObjcProvider(),
            LinkedBinary.LOCAL_AND_DEPENDENCIES,
            bundleFormat,
            appleConfiguration.getMinimumOsForPlatformType(PlatformType.IOS),
            appleConfiguration.getMultiArchPlatform(PlatformType.IOS))
        .registerActions(DsymOutputType.TEST)
        .addXcodeSettings(xcodeProviderBuilder)
        .addFilesToBuild(filesToBuild, Optional.of(DsymOutputType.TEST))
        .validateResources()
        .validateAttributes();

    new ResourceSupport(ruleContext).validateAttributes().addXcodeSettings(xcodeProviderBuilder);

    new XcodeSupport(ruleContext)
        .addXcodeSettings(xcodeProviderBuilder, common.getObjcProvider(), productType)
        .addDependencies(xcodeProviderBuilder, new Attribute("bundles", Mode.TARGET))
        .addDependencies(xcodeProviderBuilder, new Attribute("deps", Mode.TARGET))
        .addNonPropagatedDependencies(
            xcodeProviderBuilder, new Attribute("non_propagated_deps", Mode.TARGET))
        .addFilesToBuild(filesToBuild)
        .registerActions(xcodeProviderBuilder.build());

    XcodeProvider xcodeProvider = xcodeProviderBuilder.build();
    NestedSet<Artifact> filesToBuildSet = filesToBuild.build();

    Runfiles.Builder runfilesBuilder =
        new Runfiles.Builder(
                ruleContext.getWorkspaceName(),
                ruleContext.getConfiguration().legacyExternalRunfiles())
            .addRunfiles(ruleContext, RunfilesProvider.DEFAULT_RUNFILES);

    NestedSetBuilder<Artifact> filesToBuildBuilder =
        NestedSetBuilder.<Artifact>stableOrder().addTransitive(filesToBuildSet);

    InstrumentedFilesProvider instrumentedFilesProvider =
        new CompilationSupport(ruleContext).getInstrumentedFilesProvider(common);

    TestSupport testSupport =
        new TestSupport(ruleContext)
            .registerTestRunnerActions()
            .addRunfiles(runfilesBuilder, instrumentedFilesProvider)
            .addFilesToBuild(filesToBuildBuilder);

    Artifact executable = testSupport.generatedTestScript();

    Runfiles runfiles = runfilesBuilder.build();
    RunfilesSupport runfilesSupport =
        RunfilesSupport.withExecutable(ruleContext, runfiles, executable);

    ImmutableMap.Builder<String, String> execInfoMapBuilder = new ImmutableMap.Builder<>();
    execInfoMapBuilder.put(ExecutionRequirements.REQUIRES_DARWIN, "");
    if (ruleContext.getFragment(ObjcConfiguration.class).runMemleaks()) {
      execInfoMapBuilder.put("nosandbox", "");
    }

    return new RuleConfiguredTargetBuilder(ruleContext)
        .setFilesToBuild(filesToBuildBuilder.build())
        .addProvider(xcodeProvider)
        .addProvider(RunfilesProvider.simple(runfiles))
        .addProvider(new ExecutionInfoProvider(execInfoMapBuilder.build()))
        .addProvider(InstrumentedFilesProvider.class, instrumentedFilesProvider)
        .addProviders(testSupport.getExtraProviders())
        .setRunfilesSupport(runfilesSupport, executable)
        .build();
  }
Пример #9
0
 @Override
 public Set<ClassName> referencedClasses() {
   return FluentIterable.from(
           Iterables.concat(ImmutableList.of(returnType), parameterWriters.values(), body.asSet()))
       .transformAndConcat(
           new Function<HasClassReferences, Set<ClassName>>() {
             @Override
             public Set<ClassName> apply(HasClassReferences input) {
               return input.referencedClasses();
             }
           })
       .toSet();
 }
Пример #10
0
  private TargetControl targetControl() {
    String buildFilePath = label.getPackageFragment().getSafePathString() + "/BUILD";
    NestedSet<String> userHeaderSearchPaths =
        NestedSetBuilder.<String>linkOrder()
            .addTransitive(propagatedUserHeaderSearchPaths)
            .addTransitive(nonPropagatedUserHeaderSearchPaths)
            .build();
    NestedSet<String> headerSearchPaths =
        NestedSetBuilder.<String>linkOrder()
            .addTransitive(propagatedHeaderSearchPaths)
            .addTransitive(nonPropagatedHeaderSearchPaths)
            .build();

    // TODO(bazel-team): Add provisioning profile information when Xcodegen supports it.
    TargetControl.Builder targetControl =
        TargetControl.newBuilder()
            .setName(label.getName())
            .setLabel(xcodeTargetName(label))
            .setProductType(productType.getIdentifier())
            .addSupportFile(buildFilePath)
            .addAllImportedLibrary(Artifact.toExecPaths(objcProvider.get(IMPORTED_LIBRARY)))
            .addAllImportedLibrary(Artifact.toExecPaths(ccLibraries(objcProvider)))
            .addAllUserHeaderSearchPath(userHeaderSearchPaths)
            .addAllHeaderSearchPath(headerSearchPaths)
            .addAllSupportFile(Artifact.toExecPaths(headers))
            .addAllCopt(compilationModeCopts)
            .addAllCopt(CompilationSupport.DEFAULT_COMPILER_FLAGS)
            .addAllCopt(Interspersing.prependEach("-D", objcProvider.get(DEFINE)))
            .addAllCopt(copts)
            .addAllLinkopt(
                Interspersing.beforeEach("-force_load", objcProvider.get(FORCE_LOAD_FOR_XCODEGEN)))
            .addAllLinkopt(CompilationSupport.DEFAULT_LINKER_FLAGS)
            .addAllLinkopt(
                Interspersing.beforeEach(
                    "-weak_framework", SdkFramework.names(objcProvider.get(WEAK_SDK_FRAMEWORK))))
            .addAllBuildSetting(xcodeprojBuildSettings)
            .addAllBuildSetting(AppleToolchain.defaultWarningsForXcode())
            .addAllSdkFramework(SdkFramework.names(objcProvider.get(SDK_FRAMEWORK)))
            .addAllFramework(PathFragment.safePathStrings(objcProvider.get(FRAMEWORK_DIR)))
            .addAllFrameworkSearchPathOnly(
                PathFragment.safePathStrings(objcProvider.get(FRAMEWORK_SEARCH_PATH_ONLY)))
            .addAllXcassetsDir(PathFragment.safePathStrings(objcProvider.get(XCASSETS_DIR)))
            .addAllXcdatamodel(
                PathFragment.safePathStrings(
                    Xcdatamodels.datamodelDirs(objcProvider.get(XCDATAMODEL))))
            .addAllBundleImport(PathFragment.safePathStrings(objcProvider.get(BUNDLE_IMPORT_DIR)))
            .addAllSdkDylib(objcProvider.get(SDK_DYLIB))
            .addAllGeneralResourceFile(
                Artifact.toExecPaths(objcProvider.get(GENERAL_RESOURCE_FILE)))
            .addAllGeneralResourceFile(
                PathFragment.safePathStrings(objcProvider.get(GENERAL_RESOURCE_DIR)));

    if (CAN_LINK_PRODUCT_TYPES.contains(productType)) {
      // For builds with --ios_multi_cpus set, we may have several copies of some XCodeProviders
      // in the dependencies (one per cpu architecture). We deduplicate the corresponding
      // xcode target names with a LinkedHashSet before adding to the TargetControl.
      Set<String> jreTargetNames = new HashSet<>();
      for (XcodeProvider jreDependency : jreDependencies) {
        jreTargetNames.add(jreDependency.dependencyXcodeTargetName());
      }
      Set<DependencyControl> dependencySet = new LinkedHashSet<>();
      Set<DependencyControl> jreDependencySet = new LinkedHashSet<>();
      for (XcodeProvider dependency : propagatedDependencies) {
        // Only add a library target to a binary's dependencies if it has source files to compile
        // and it is not from the "non_propagated_deps" attribute. Xcode cannot build targets
        // without a source file in the PBXSourceFilesBuildPhase, so if such a target is present in
        // the control file, it is only to get Xcodegen to put headers and resources not used by the
        // final binary in the Project Navigator.
        //
        // The exceptions to this rule are objc_bundle_library and ios_extension targets. Bundles
        // are generally used for resources and can lack a PBXSourceFilesBuildPhase in the project
        // file and still be considered valid by Xcode.
        //
        // ios_extension targets are an exception because they have no CompilationArtifact object
        // but do have a dummy source file to make Xcode happy.
        boolean hasSources =
            dependency.compilationArtifacts.isPresent()
                && dependency.compilationArtifacts.get().getArchive().isPresent();
        if (hasSources
            || (dependency.productType == XcodeProductType.BUNDLE
                || (dependency.productType == XcodeProductType.WATCH_OS1_APPLICATION))) {
          String dependencyXcodeTargetName = dependency.dependencyXcodeTargetName();
          Set<DependencyControl> set =
              jreTargetNames.contains(dependencyXcodeTargetName) ? jreDependencySet : dependencySet;
          set.add(DependencyControl.newBuilder().setTargetLabel(dependencyXcodeTargetName).build());
        }
      }

      for (DependencyControl dependencyControl : dependencySet) {
        targetControl.addDependency(dependencyControl);
      }
      // Make sure that JRE dependencies are ordered after other propagated dependencies.
      for (DependencyControl dependencyControl : jreDependencySet) {
        targetControl.addDependency(dependencyControl);
      }
    }
    for (XcodeProvider justTestHost : testHost.asSet()) {
      targetControl.addDependency(
          DependencyControl.newBuilder()
              .setTargetLabel(xcodeTargetName(justTestHost.label))
              .setTestHost(true)
              .build());
    }
    for (XcodeProvider extension : extensions) {
      targetControl.addDependency(
          DependencyControl.newBuilder().setTargetLabel(xcodeTargetName(extension.label)).build());
    }

    if (bundleInfoplist.isPresent()) {
      targetControl.setInfoplist(bundleInfoplist.get().getExecPathString());
    }
    for (CompilationArtifacts artifacts : compilationArtifacts.asSet()) {
      targetControl
          .addAllSourceFile(Artifact.toExecPaths(artifacts.getSrcs()))
          .addAllSupportFile(Artifact.toExecPaths(artifacts.getAdditionalHdrs()))
          .addAllSupportFile(Artifact.toExecPaths(artifacts.getPrivateHdrs()))
          .addAllNonArcSourceFile(Artifact.toExecPaths(artifacts.getNonArcSrcs()));

      for (Artifact pchFile : artifacts.getPchFile().asSet()) {
        targetControl
            .setPchPath(pchFile.getExecPathString())
            .addSupportFile(pchFile.getExecPathString());
      }
    }

    for (Artifact artifact : additionalSources) {
      targetControl.addSourceFile(artifact.getExecPathString());
    }

    if (objcProvider.is(Flag.USES_CPP)) {
      targetControl.addSdkDylib("libc++");
    }

    return targetControl.build();
  }