/** Registers an action to copy Swift standard library dylibs into app bundle. */
  private void registerSwiftStdlibActionsIfNecessary() {
    if (!objcProvider.is(USES_SWIFT)) {
      return;
    }

    AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);

    CustomCommandLine.Builder commandLine =
        CustomCommandLine.builder()
            .addPath(intermediateArtifacts.swiftFrameworksFileZip().getExecPath())
            .add("--platform")
            .add(AppleToolchain.swiftPlatform(appleConfiguration))
            .addExecPath("--scan-executable", intermediateArtifacts.combinedArchitectureBinary());

    ruleContext.registerAction(
        ObjcRuleClasses.spawnXcrunActionBuilder(ruleContext)
            .setMnemonic("SwiftStdlibCopy")
            .setExecutable(attributes.swiftStdlibToolWrapper())
            .setCommandLine(commandLine.build())
            .addOutput(intermediateArtifacts.swiftFrameworksFileZip())
            .addInput(intermediateArtifacts.combinedArchitectureBinary())
            // TODO(dmaclach): Adding realpath and xcrunwrapper should not be required once
            // https://github.com/google/bazel/issues/285 is fixed.
            .addInput(attributes.realpath())
            .addInput(CompilationSupport.xcrunwrapper(ruleContext).getExecutable())
            .build(ruleContext));
  }
Beispiel #2
0
 private TargetControl companionLibTargetControl(TargetControl mainTargetControl) {
   return TargetControl.newBuilder()
       .mergeFrom(mainTargetControl)
       .setName(label.getName() + COMPANION_LIB_TARGET_LABEL_SUFFIX)
       .setLabel(xcodeCompanionLibTargetName(label))
       .setProductType(LIBRARY_STATIC.getIdentifier())
       .clearInfoplist()
       .clearDependency()
       .clearBuildSetting()
       .addAllBuildSetting(companionTargetXcodeprojBuildSettings)
       .addAllBuildSetting(AppleToolchain.defaultWarningsForXcode())
       .build();
 }
Beispiel #3
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();
  }