コード例 #1
0
ファイル: ApkActionsBuilder.java プロジェクト: mrdomino/bazel
    @Override
    public void registerActions(RuleContext ruleContext, AndroidSemantics semantics) {
      Preconditions.checkNotNull(
          apkName, "APK name must be set to create progress messages for APK actions.");

      if (signedApk != null) {
        Artifact intermediateUnsignedApk = unsignedApk;
        if (intermediateUnsignedApk == null) {
          // If the caller did not request an unsigned APK, we still need to construct one so that
          // we can sign it. So we make up an intermediate artifact.
          intermediateUnsignedApk =
              AndroidBinary.getDxArtifact(ruleContext, "unsigned_" + signedApk.getFilename());
        }
        ruleContext.registerAction(
            buildApk(ruleContext, intermediateUnsignedApk, null, "Generating unsigned " + apkName));

        Artifact apkToSign = intermediateUnsignedApk;
        if (zipalignApk) {
          apkToSign =
              AndroidBinary.getDxArtifact(ruleContext, "zipaligned_" + signedApk.getFilename());
          ruleContext.registerAction(zipalignApk(ruleContext, intermediateUnsignedApk, apkToSign));
        }

        ruleContext.registerAction(
            signApk(
                ruleContext, semantics.getApkDebugSigningKey(ruleContext), apkToSign, signedApk));
      } else if (unsignedApk != null) {
        ruleContext.registerAction(
            buildApk(ruleContext, unsignedApk, null, "Generating unsigned " + apkName));
      }
    }
コード例 #2
0
ファイル: ApkActionsBuilder.java プロジェクト: mrdomino/bazel
    @Override
    public void registerActions(RuleContext ruleContext, AndroidSemantics semantics) {
      Preconditions.checkNotNull(
          apkName, "APK name must be set to create progress messages for APK actions.");

      if (unsignedApk != null) {
        ruleContext.registerAction(
            buildApk(ruleContext, unsignedApk, null, "Generating unsigned " + apkName));
      }

      if (signedApk != null) {
        // Legacy signing destroys zip aligning, so if zip aligning is requested we build an
        // intermediate APK that is signed but not zip aligned then zip align it. If zip aligning
        // is not requested then the output of the buildApk step is the final apk.
        Artifact intermediateSignedApk;
        if (zipalignApk) {
          intermediateSignedApk =
              AndroidBinary.getDxArtifact(ruleContext, "signed_" + signedApk.getFilename());
        } else {
          intermediateSignedApk = signedApk;
        }

        ruleContext.registerAction(
            buildApk(
                ruleContext,
                intermediateSignedApk,
                semantics.getApkDebugSigningKey(ruleContext),
                "Generating signed " + apkName));

        if (zipalignApk) {
          ruleContext.registerAction(zipalignApk(ruleContext, intermediateSignedApk, signedApk));
        }
      }
    }
コード例 #3
0
  private void registerBundleMergeActions(
      Artifact ipaUnsigned,
      NestedSet<Artifact> bundleContentArtifacts,
      BundleMergeControlBytes controlBytes) {
    Artifact bundleMergeControlArtifact =
        ObjcRuleClasses.artifactByAppendingToBaseName(ruleContext, ".ipa-control");

    ruleContext.registerAction(
        new BinaryFileWriteAction(
            ruleContext.getActionOwner(),
            bundleMergeControlArtifact,
            controlBytes,
            /*makeExecutable=*/ false));

    ruleContext.registerAction(
        new SpawnAction.Builder()
            .setMnemonic("IosBundle")
            .setProgressMessage("Bundling iOS application: " + ruleContext.getLabel())
            .setExecutable(attributes.bundleMergeExecutable())
            .addInputArgument(bundleMergeControlArtifact)
            .addTransitiveInputs(bundleContentArtifacts)
            .addOutput(ipaUnsigned)
            .setVerboseFailuresAndSubcommandsInEnv()
            .build(ruleContext));
  }
コード例 #4
0
ファイル: CppModel.java プロジェクト: XClouded/bazel
  /** Create the actions for "--save_temps". */
  private ImmutableList<Artifact> createTempsActions(
      Artifact source,
      String outputName,
      CppCompileActionBuilder builder,
      boolean usePic,
      boolean generateDotd,
      PathFragment ccRelativeName) {
    if (!cppConfiguration.getSaveTemps()) {
      return ImmutableList.of();
    }

    String path = source.getFilename();
    boolean isCFile = CppFileTypes.C_SOURCE.matches(path);
    boolean isCppFile = CppFileTypes.CPP_SOURCE.matches(path);

    if (!isCFile && !isCppFile) {
      return ImmutableList.of();
    }

    ArtifactCategory category =
        isCFile ? ArtifactCategory.PREPROCESSED_C_SOURCE : ArtifactCategory.PREPROCESSED_CPP_SOURCE;

    String outputArtifactNameBase = getOutputNameBaseWith(outputName, usePic);

    CppCompileActionBuilder dBuilder = new CppCompileActionBuilder(builder);
    dBuilder.setOutputs(category, outputArtifactNameBase, generateDotd);
    setupCompileBuildVariables(
        dBuilder,
        usePic,
        ccRelativeName,
        source.getExecPath(),
        null,
        null,
        ImmutableMap.<String, String>of());
    semantics.finalizeCompileActionBuilder(ruleContext, dBuilder);
    CppCompileAction dAction = dBuilder.build();
    ruleContext.registerAction(dAction);

    CppCompileActionBuilder sdBuilder = new CppCompileActionBuilder(builder);
    sdBuilder.setOutputs(ArtifactCategory.GENERATED_ASSEMBLY, outputArtifactNameBase, generateDotd);
    setupCompileBuildVariables(
        sdBuilder,
        usePic,
        ccRelativeName,
        source.getExecPath(),
        null,
        null,
        ImmutableMap.<String, String>of());
    semantics.finalizeCompileActionBuilder(ruleContext, sdBuilder);
    CppCompileAction sdAction = sdBuilder.build();
    ruleContext.registerAction(sdAction);

    return ImmutableList.of(dAction.getOutputFile(), sdAction.getOutputFile());
  }
コード例 #5
0
  /** Registers an action to copy Swift standard library dylibs into app bundle. */
  private void registerSwiftStdlibActionsIfNecessary() {
    if (!objcProvider.is(USES_SWIFT)) {
      return;
    }

    ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);

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

    ruleContext.registerAction(
        ObjcRuleClasses.spawnOnDarwinActionBuilder(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));
  }
コード例 #6
0
  private void registerEntitlementsVariableSubstitutionAction(
      Artifact in, Artifact out, Artifact prefix) {
    String escapedBundleId = ShellUtils.shellEscape(attributes.bundleId());
    String shellCommand =
        "set -e && "
            + "PREFIX=\"$(cat "
            + prefix.getShellEscapedExecPathString()
            + ")\" && "
            + "sed "
            // Replace .* from default entitlements file with bundle ID where suitable.
            + "-e \"s#${PREFIX}\\.\\*#${PREFIX}."
            + escapedBundleId
            + "#g\" "

            // Replace some variables that people put in their own entitlements files
            + "-e \"s#\\$(AppIdentifierPrefix)#${PREFIX}.#g\" "
            + "-e \"s#\\$(CFBundleIdentifier)#"
            + escapedBundleId
            + "#g\" "
            + in.getShellEscapedExecPathString()
            + " "
            + "> "
            + out.getShellEscapedExecPathString();
    ruleContext.registerAction(
        new SpawnAction.Builder()
            .setMnemonic("SubstituteIosEntitlements")
            .setShellCommand(shellCommand)
            .addInput(in)
            .addInput(prefix)
            .addOutput(out)
            .build(ruleContext));
  }
コード例 #7
0
ファイル: CppModel.java プロジェクト: XClouded/bazel
  /**
   * Returns the linked artifact resulting from a linking of the given type. Consults the feature
   * configuration to obtain an action_config that provides the artifact. If the feature
   * configuration provides no artifact, uses a default.
   *
   * <p>We cannot assume that the feature configuration contains an action_config for the link
   * action, because the linux link action depends on hardcoded values in
   * LinkCommandLine.getRawLinkArgv(), which are applied on the condition that an action_config is
   * not present. TODO(b/30393154): Assert that the given link action has an action_config.
   *
   * @throws RuleErrorException
   */
  private Artifact getLinkedArtifact(LinkTargetType linkTargetType) throws RuleErrorException {
    Artifact result = null;
    Artifact linuxDefault = CppHelper.getLinuxLinkedArtifact(ruleContext, linkTargetType);

    try {
      String templatedName =
          features.getArtifactNameForCategory(
              linkTargetType.getLinkerOutput(), ruleContext, ImmutableMap.<String, String>of());
      PathFragment artifactFragment =
          new PathFragment(ruleContext.getLabel().getName())
              .getParentDirectory()
              .getRelative(templatedName);
      result =
          ruleContext.getPackageRelativeArtifact(
              artifactFragment, ruleContext.getConfiguration().getBinDirectory());
    } catch (ExpansionException e) {
      ruleContext.throwWithRuleError(e.getMessage());
    }

    // If the linked artifact is not the linux default, then a FailAction is generated for the
    // linux default to satisfy the requirement of the implicit output.
    // TODO(b/30132703): Remove the implicit outputs of cc_library.
    if (!result.equals(linuxDefault)) {
      ruleContext.registerAction(
          new FailAction(
              ruleContext.getActionOwner(),
              ImmutableList.of(linuxDefault),
              String.format(
                  "the given toolchain supports creation of %s instead of %s",
                  linuxDefault.getExecPathString(), result.getExecPathString())));
    }

    return result;
  }
コード例 #8
0
  /** Registers an action to generate a runner script based on a template. */
  ReleaseBundlingSupport registerGenerateRunnerScriptAction(
      Artifact runnerScript, Artifact ipaInput) {
    ObjcConfiguration objcConfiguration = ObjcRuleClasses.objcConfiguration(ruleContext);
    String escapedSimDevice = ShellUtils.shellEscape(objcConfiguration.getIosSimulatorDevice());
    String escapedSdkVersion = ShellUtils.shellEscape(objcConfiguration.getIosSimulatorVersion());
    ImmutableList<Substitution> substitutions =
        ImmutableList.of(
            Substitution.of("%app_name%", ruleContext.getLabel().getName()),
            Substitution.of("%ipa_file%", ipaInput.getRootRelativePath().getPathString()),
            Substitution.of("%sim_device%", escapedSimDevice),
            Substitution.of("%sdk_version%", escapedSdkVersion),
            Substitution.of("%iossim%", attributes.iossim().getRootRelativePath().getPathString()),
            Substitution.of(
                "%std_redirect_dylib_path%",
                attributes.stdRedirectDylib().getRootRelativePath().getPathString()));

    ruleContext.registerAction(
        new TemplateExpansionAction(
            ruleContext.getActionOwner(),
            attributes.runnerScriptTemplate(),
            runnerScript,
            substitutions,
            true));
    return this;
  }
コード例 #9
0
  public ApplicationManifest createSplitManifest(
      RuleContext ruleContext, String splitName, boolean hasCode) {
    // aapt insists that manifests be called AndroidManifest.xml, even though they have to be
    // explicitly designated as manifests on the command line
    Artifact result =
        AndroidBinary.getDxArtifact(ruleContext, "split_" + splitName + "/AndroidManifest.xml");
    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .setExecutable(
                ruleContext.getExecutablePrerequisite("$build_split_manifest", Mode.HOST))
            .setProgressMessage("Creating manifest for split " + splitName)
            .setMnemonic("AndroidBuildSplitManifest")
            .addArgument("--main_manifest")
            .addInputArgument(manifest)
            .addArgument("--split_manifest")
            .addOutputArgument(result)
            .addArgument("--split")
            .addArgument(splitName)
            .addArgument(hasCode ? "--hascode" : "--nohascode");

    String overridePackage = getOverridePackage(ruleContext);
    if (overridePackage != null) {
      builder.addArgument("--override_package").addArgument(overridePackage);
    }

    ruleContext.registerAction(builder.build(ruleContext));
    return new ApplicationManifest(result);
  }
コード例 #10
0
  public ApplicationManifest addStubApplication(RuleContext ruleContext) {

    Artifact stubManifest =
        ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.STUB_APPLICATON_MANIFEST);

    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .setExecutable(ruleContext.getExecutablePrerequisite("$stubify_manifest", Mode.HOST))
            .setProgressMessage("Injecting stub application")
            .setMnemonic("InjectStubApplication")
            .addArgument("--input_manifest")
            .addInputArgument(manifest)
            .addArgument("--output_manifest")
            .addOutputArgument(stubManifest)
            .addArgument("--output_datafile")
            .addOutputArgument(
                ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.STUB_APPLICATION_DATA));

    String overridePackage = getOverridePackage(ruleContext);
    if (overridePackage != null) {
      builder.addArgument("--override_package");
      builder.addArgument(overridePackage);
    }

    ruleContext.registerAction(builder.build(ruleContext));

    return new ApplicationManifest(stubManifest);
  }
コード例 #11
0
ファイル: ProtoSupport.java プロジェクト: dslomov/bazel
 private void registerProtoInputListFileAction() {
   ruleContext.registerAction(
       new FileWriteAction(
           ruleContext.getActionOwner(),
           getProtoInputListFile(),
           getProtoInputListFileContents(),
           false));
 }
コード例 #12
0
 private void registerAutomaticPlistAction() {
   ruleContext.registerAction(
       new FileWriteAction(
           ruleContext.getActionOwner(),
           getGeneratedAutomaticPlist(),
           automaticEntries().toASCIIPropertyList(),
           /*makeExecutable=*/ false));
 }
コード例 #13
0
ファイル: ProtoSupport.java プロジェクト: dslomov/bazel
 private void registerGenerateProtoFilesAction() {
   ruleContext.registerAction(
       ObjcRuleClasses.spawnOnDarwinActionBuilder()
           .setMnemonic("GenObjcProtos")
           .addInputs(getGenerateActionInputs())
           .addOutputs(getGenerateActionOutputs())
           .setExecutable(new PathFragment("/usr/bin/python"))
           .setCommandLine(getGenerateCommandLine())
           .build(ruleContext));
 }
コード例 #14
0
ファイル: AndroidCommon.java プロジェクト: morimekta/bazel
  private void createJarJarActions(
      JavaTargetAttributes.Builder attributes,
      ImmutableList.Builder<Artifact> jarsProducedForRuntime,
      Iterable<ResourceContainer> resourceContainers,
      String originalPackage,
      Artifact binaryResourcesJar) {
    // Now use jarjar for the rest of the resources. We need to make a copy
    // of the final generated resources for each of the targets included in
    // the transitive closure of this binary.
    for (ResourceContainer otherContainer : resourceContainers) {
      if (otherContainer.getLabel().equals(ruleContext.getLabel())) {
        continue;
      }

      Artifact resourcesJar = createResourceJarArtifact(ruleContext, otherContainer, ".jar");
      // combined resource constants copy needs to come before library classes that may contain
      // their local resource constants
      attributes.addRuntimeClassPathEntry(resourcesJar);

      Artifact jarJarRuleFile =
          createResourceJarArtifact(ruleContext, otherContainer, ".jar_jarjar_rules.txt");

      String jarJarRule =
          String.format("rule %s.* %s.@1", originalPackage, otherContainer.getJavaPackage());
      ruleContext.registerAction(
          new FileWriteAction(ruleContext.getActionOwner(), jarJarRuleFile, jarJarRule, false));

      FilesToRunProvider jarjar = ruleContext.getExecutablePrerequisite("$jarjar_bin", Mode.HOST);

      ruleContext.registerAction(
          new SpawnAction.Builder()
              .setExecutable(jarjar)
              .addArgument("process")
              .addInputArgument(jarJarRuleFile)
              .addInputArgument(binaryResourcesJar)
              .addOutputArgument(resourcesJar)
              .setProgressMessage("Repackaging jar")
              .setMnemonic("AndroidRepackageJar")
              .build(ruleContext));
      jarsProducedForRuntime.add(resourcesJar);
    }
  }
コード例 #15
0
ファイル: XcodeSupport.java プロジェクト: godouxm/bazel
  private void registerXcodegenActions(XcodeProvider.Project project) {
    Artifact controlFile =
        ObjcRuleClasses.intermediateArtifacts(ruleContext).pbxprojControlArtifact();

    ruleContext.registerAction(
        new BinaryFileWriteAction(
            ruleContext.getActionOwner(),
            controlFile,
            xcodegenControlFileBytes(project),
            /*makeExecutable=*/ false));

    ruleContext.registerAction(
        new SpawnAction.Builder()
            .setMnemonic("GenerateXcodeproj")
            .setExecutable(ruleContext.getExecutablePrerequisite("$xcodegen", Mode.HOST))
            .addArgument("--control")
            .addInputArgument(controlFile)
            .addOutput(ruleContext.getImplicitOutputArtifact(XcodeSupport.PBXPROJ))
            .addTransitiveInputs(project.getInputsToXcodegen())
            .build(ruleContext));
  }
コード例 #16
0
ファイル: TestSupport.java プロジェクト: ahirreddy/bazel
  private void registerTestScriptSubstitutionAction() throws InterruptedException {
    // testIpa is the app actually containing the tests
    Artifact testIpa = testIpa();

    String runMemleaks =
        ruleContext.getFragment(ObjcConfiguration.class).runMemleaks() ? "true" : "false";

    Map<String, String> testEnv = ruleContext.getConfiguration().getTestEnv();

    // The substitutions below are common for simulator and lab device.
    ImmutableList.Builder<Substitution> substitutions =
        new ImmutableList.Builder<Substitution>()
            .add(Substitution.of("%(memleaks)s", runMemleaks))
            .add(Substitution.of("%(test_app_ipa)s", testIpa.getRootRelativePathString()))
            .add(Substitution.of("%(test_app_name)s", baseNameWithoutIpa(testIpa)))
            .add(
                Substitution.of("%(plugin_jars)s", Artifact.joinRootRelativePaths(":", plugins())));

    substitutions.add(Substitution.ofSpaceSeparatedMap("%(test_env)s", testEnv));

    // xctestIpa is the app bundle being tested
    Optional<Artifact> xctestIpa = xctestIpa();
    if (xctestIpa.isPresent()) {
      substitutions
          .add(Substitution.of("%(xctest_app_ipa)s", xctestIpa.get().getRootRelativePathString()))
          .add(Substitution.of("%(xctest_app_name)s", baseNameWithoutIpa(xctestIpa.get())));
    } else {
      substitutions
          .add(Substitution.of("%(xctest_app_ipa)s", ""))
          .add(Substitution.of("%(xctest_app_name)s", ""));
    }

    Artifact template;
    if (!runWithLabDevice()) {
      substitutions.addAll(substitutionsForSimulator());
      template = ruleContext.getPrerequisiteArtifact("$test_template", Mode.TARGET);
    } else {
      substitutions.addAll(substitutionsForLabDevice());
      template = testTemplateForLabDevice();
    }

    ruleContext.registerAction(
        new TemplateExpansionAction(
            ruleContext.getActionOwner(),
            template,
            generatedTestScript(),
            substitutions.build(),
            /*executable=*/ true));
  }
コード例 #17
0
  private ReleaseBundlingSupport registerSignBundleAction(
      Artifact entitlements, Artifact ipaOutput, Artifact ipaUnsigned) {
    // TODO(bazel-team): Support variable substitution

    ImmutableList.Builder<String> dirsToSign = new ImmutableList.Builder<>();

    // Explicitly sign Swift dylibs. Unfortunately --deep option on codesign doesn't do this
    // automatically.
    // The order here is important. The innermost code must singed first.
    String bundleDir = ShellUtils.shellEscape(bundling.getBundleDir());
    if (objcProvider.is(USES_SWIFT)) {
      dirsToSign.add(bundleDir + "/Frameworks/*");
    }
    dirsToSign.add(bundleDir);

    StringBuilder codesignCommandLineBuilder = new StringBuilder();
    for (String dir : dirsToSign.build()) {
      codesignCommandLineBuilder
          .append(codesignCommand(entitlements, "${t}/" + dir))
          .append(" && ");
    }

    // TODO(bazel-team): Support nested code signing.
    String shellCommand =
        "set -e && "
            + "t=$(mktemp -d -t signing_intermediate) && "
            + "trap \"rm -rf ${t}\" EXIT && "
            // Get an absolute path since we need to cd into the temp directory for zip.
            + "signed_ipa=${PWD}/"
            + ipaOutput.getShellEscapedExecPathString()
            + " && "
            + "/usr/bin/unzip -qq "
            + ipaUnsigned.getShellEscapedExecPathString()
            + " -d ${t} && "
            + codesignCommandLineBuilder.toString()
            // Using zip since we need to preserve permissions
            + "cd ${t} && /usr/bin/zip -q -r \"${signed_ipa}\" .";
    ruleContext.registerAction(
        ObjcRuleClasses.spawnBashOnDarwinActionBuilder(ruleContext, shellCommand)
            .setMnemonic("IosSignBundle")
            .setProgressMessage("Signing iOS bundle: " + ruleContext.getLabel())
            .addInput(ipaUnsigned)
            .addInput(attributes.provisioningProfile())
            .addInput(entitlements)
            .addOutput(ipaOutput)
            .build(ruleContext));

    return this;
  }
コード例 #18
0
ファイル: AndroidCommon.java プロジェクト: morimekta/bazel
  /**
   * Creates an action that converts {@code jarToDex} to a dex file. The output will be stored in
   * the {@link com.google.devtools.build.lib.actions.Artifact} {@code dxJar}.
   */
  public static void createDexAction(
      RuleContext ruleContext,
      Artifact jarToDex,
      Artifact classesDex,
      List<String> dexOptions,
      boolean multidex,
      Artifact mainDexList) {
    List<String> args = new ArrayList<>();
    args.add("--dex");
    // Add --no-locals to coverage builds.  Older coverage tools don't correctly preserve local
    // variable information in stack frame maps that are required since Java 7, so to avoid runtime
    // errors we just don't add local variable info in the first place.  This may no longer be
    // necessary, however, as long as we use a coverage tool that generates stack frame maps.
    if (ruleContext.getConfiguration().isCodeCoverageEnabled()) {
      args.add("--no-locals"); // TODO(bazel-team): Is this still needed?
    }

    // Multithreaded dex does not work when using --multi-dex.
    if (!multidex) {
      // Multithreaded dex tends to run faster, but only up to about 5 threads (at which point the
      // law of diminishing returns kicks in). This was determined experimentally, with 5-thread dex
      // performing about 25% faster than 1-thread dex.
      args.add("--num-threads=5");
    }

    args.addAll(dexOptions);
    if (multidex) {
      args.add("--multi-dex");
      if (mainDexList != null) {
        args.add("--main-dex-list=" + mainDexList.getExecPathString());
      }
    }
    args.add("--output=" + classesDex.getExecPathString());
    args.add(jarToDex.getExecPathString());

    SpawnAction.Builder builder =
        new SpawnAction.Builder()
            .setExecutable(AndroidSdkProvider.fromRuleContext(ruleContext).getDx())
            .addInput(jarToDex)
            .addOutput(classesDex)
            .addArguments(args)
            .setProgressMessage("Converting " + jarToDex.getExecPathString() + " to dex format")
            .setMnemonic("AndroidDexer")
            .setResources(ResourceSet.createWithRamCpuIo(4096.0, 5.0, 0.0));
    if (mainDexList != null) {
      builder.addInput(mainDexList);
    }
    ruleContext.registerAction(builder.build(ruleContext));
  }
コード例 #19
0
 private void registerExtractTeamPrefixAction(Artifact teamPrefixFile) {
   String shellCommand =
       "set -e && "
           + "PLIST=$(mktemp -t teamprefix.plist) && trap \"rm ${PLIST}\" EXIT && "
           + extractPlistCommand(attributes.provisioningProfile())
           + " > ${PLIST} && "
           + "/usr/libexec/PlistBuddy -c 'Print ApplicationIdentifierPrefix:0' ${PLIST} > "
           + teamPrefixFile.getShellEscapedExecPathString();
   ruleContext.registerAction(
       ObjcRuleClasses.spawnBashOnDarwinActionBuilder(ruleContext, shellCommand)
           .setMnemonic("ExtractIosTeamPrefix")
           .addInput(attributes.provisioningProfile())
           .addOutput(teamPrefixFile)
           .build(ruleContext));
 }
コード例 #20
0
 private void registerEmbedLabelPlistAction() {
   Artifact buildInfo =
       Iterables.getOnlyElement(ruleContext.getBuildInfo(ObjcBuildInfoFactory.KEY));
   String generatedVersionPlistPath = getGeneratedVersionPlist().getShellEscapedExecPathString();
   String shellCommand =
       "VERSION=\"$("
           + "grep \"^"
           + BuildInfo.BUILD_EMBED_LABEL
           + "\" "
           + buildInfo.getShellEscapedExecPathString()
           + " | cut -d' ' -f2- | sed -e '"
           + EXTRACT_VERSION_NUMBER_SED_COMMAND
           + "' | "
           + "sed -e 's#\"#\\\"#g')\" && "
           + "cat >"
           + generatedVersionPlistPath
           + " <<EOF\n"
           + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
           + "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
           + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
           + "<plist version=\"1.0\">\n"
           + "<dict>\n"
           + "EOF\n"
           + "if [[ -n \"${VERSION}\" ]]; then\n"
           + "  for KEY in CFBundleVersion CFBundleShortVersionString; do\n"
           + "    echo \"  <key>${KEY}</key>\n\" >> "
           + generatedVersionPlistPath
           + "\n"
           + "    echo \"  <string>${VERSION}</string>\n\" >> "
           + generatedVersionPlistPath
           + "\n"
           + "  done\n"
           + "fi\n"
           + "cat >>"
           + generatedVersionPlistPath
           + " <<EOF\n"
           + "</dict>\n"
           + "</plist>\n"
           + "EOF\n";
   ruleContext.registerAction(
       new SpawnAction.Builder()
           .setMnemonic("ObjcVersionPlist")
           .setShellCommand(shellCommand)
           .addInput(buildInfo)
           .addOutput(getGeneratedVersionPlist())
           .build(ruleContext));
 }
コード例 #21
0
  private void registerCombineArchitecturesAction() {
    Artifact resultingLinkedBinary = intermediateArtifacts.combinedArchitectureBinary();
    NestedSet<Artifact> linkedBinaries = linkedBinaries();

    ruleContext.registerAction(
        ObjcRuleClasses.spawnOnDarwinActionBuilder(ruleContext)
            .setMnemonic("ObjcCombiningArchitectures")
            .addTransitiveInputs(linkedBinaries)
            .addOutput(resultingLinkedBinary)
            .setExecutable(CompilationSupport.xcrunwrapper(ruleContext))
            .setCommandLine(
                CustomCommandLine.builder()
                    .add(ObjcRuleClasses.LIPO)
                    .addExecPaths("-create", linkedBinaries)
                    .addExecPath("-o", resultingLinkedBinary)
                    .build())
            .build(ruleContext));
  }
コード例 #22
0
 /**
  * Registers the actions that transform and copy the breakpad files from the CPU-specific binaries
  * that are part of this application. There are two steps involved: 1) The breakpad files have to
  * be renamed to include their corresponding CPU architecture as a suffix. 2) The first line of
  * the breakpad file has to be rewritten, as it has to include the name of the application instead
  * of the name of the binary artifact.
  *
  * <p>Example:<br>
  * The ios_application "PrenotCalculator" is specified to use "PrenotCalculatorBinary" as its
  * binary. Assuming that the application is built for armv7 and arm64 CPUs, in the build process
  * two binaries with a corresponding breakpad file each will be built:
  *
  * <pre>blaze-out/xyz-crosstool-ios-arm64/.../PrenotCalculatorBinary_bin
  * blaze-out/xyz-crosstool-ios-arm64/.../PrenotCalculatorBinary.breakpad
  * blaze-out/xyz-crosstool-ios-armv7/.../PrenotCalculatorBinary_bin
  * blaze-out/xyz-crosstool-ios-armv7/.../PrenotCalculatorBinary.breakpad</pre>
  *
  * <p>The first line of the breakpad files will look like this:
  *
  * <pre>MODULE mac arm64 8A7A2DDD28E83E27B339E63631ADBEF30 PrenotCalculatorBinary_bin</pre>
  *
  * <p>For our application, we have to transform & copy these breakpad files like this:
  *
  * <pre>$ head -n1 blaze-bin/.../PrenotCalculator_arm64.breakpad
  * MODULE mac arm64 8A7A2DDD28E83E27B339E63631ADBEF30 PrenotCalculator</pre>
  */
 private void registerTransformAndCopyBreakpadFilesAction() {
   for (Entry<Artifact, Artifact> breakpadFiles : getBreakpadFiles().entrySet()) {
     ruleContext.registerAction(
         new SpawnAction.Builder()
             .setMnemonic("CopyBreakpadFile")
             .setShellCommand(
                 String.format(
                     // This sed command replaces the last word of the first line with the
                     // application
                     // name.
                     "sed \"1 s/^\\(MODULE \\w* \\w* \\w*\\).*$/\\1 %s/\" < %s > %s",
                     ruleContext.getLabel().getName(),
                     breakpadFiles.getKey().getExecPathString(),
                     breakpadFiles.getValue().getExecPathString()))
             .addInput(breakpadFiles.getKey())
             .addOutput(breakpadFiles.getValue())
             .build(ruleContext));
   }
 }
コード例 #23
0
  private void registerLaunchStoryboardPlistAction() {
    String launchStoryboard = attributes.launchStoryboard().getFilename();
    String launchStoryboardName = launchStoryboard.substring(0, launchStoryboard.lastIndexOf('.'));
    String contents =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            + "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
            + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
            + "<plist version=\"1.0\">\n"
            + "<dict>\n"
            + "  <key>UILaunchStoryboardName</key>\n"
            + "  <string>"
            + launchStoryboardName
            + "</string>\n"
            + "</dict>\n"
            + "</plist>\n";

    ruleContext.registerAction(
        new FileWriteAction(
            ruleContext.getActionOwner(), getLaunchStoryboardPlist(), contents, false));
  }
コード例 #24
0
  protected void createActions(
      ConfiguredTarget base,
      RuleContext ruleContext,
      Iterable<Artifact> protoSources,
      NestedSet<Artifact> transitiveProtoSources,
      Iterable<Artifact> headerMappingFiles,
      Iterable<Artifact> classMappingFiles,
      J2ObjcSource j2ObjcSource) {
    String genDir = ruleContext.getConfiguration().getGenfilesDirectory().getExecPathString();
    Artifact compiler = ruleContext.getPrerequisiteArtifact("$protoc_darwin", Mode.HOST);
    Artifact j2objcPlugin = ruleContext.getPrerequisiteArtifact("$j2objc_plugin", Mode.HOST);

    ruleContext.registerAction(
        new SpawnAction.Builder()
            .setMnemonic("TranslatingJ2ObjcProtos")
            .addInput(compiler)
            .addInput(j2objcPlugin)
            .addInputs(
                ruleContext.getPrerequisiteArtifacts("$protoc_support_darwin", Mode.HOST).list())
            .addInputs(protoSources)
            .addTransitiveInputs(transitiveProtoSources)
            .addOutputs(j2ObjcSource.getObjcSrcs())
            .addOutputs(j2ObjcSource.getObjcHdrs())
            .addOutputs(headerMappingFiles)
            .addOutputs(classMappingFiles)
            .setExecutable(new PathFragment("/usr/bin/python"))
            .setCommandLine(
                new CustomCommandLine.Builder()
                    .add(compiler.getPath().toString())
                    .add("-w")
                    .add(compiler.getRoot().getPath().toString())
                    .add("--generate-j2objc")
                    .add("--generator-param=file_dir_mapping")
                    .add("--generator-param=generate_class_mappings")
                    .add("--j2objc-plugin=" + j2objcPlugin.getExecPathString())
                    .add("--output-dir=" + genDir)
                    .addExecPaths(protoSources)
                    .build())
            .setExecutionInfo(ImmutableMap.of(ExecutionRequirements.REQUIRES_DARWIN, ""))
            .build(ruleContext));
  }
コード例 #25
0
 private void registerEnvironmentPlistAction() {
   ObjcConfiguration configuration = ObjcRuleClasses.objcConfiguration(ruleContext);
   // Generates a .plist that contains environment values (such as the SDK used to build, the Xcode
   // version, etc), which are parsed from various .plist files of the OS, namely Xcodes' and
   // Platforms' plists.
   // The resulting file is meant to be merged with the final bundle.
   String platformWithVersion =
       String.format(
           "%s%s",
           configuration.getBundlingPlatform().getLowerCaseNameInPlist(),
           Strings.nullToEmpty(configuration.getIosSdkVersion()));
   ruleContext.registerAction(
       ObjcRuleClasses.spawnOnDarwinActionBuilder(ruleContext)
           .setMnemonic("EnvironmentPlist")
           .addInput(attributes.environmentPlistScript())
           .setExecutable(attributes.environmentPlistScript())
           .addArguments("--platform", platformWithVersion)
           .addArguments("--output", getGeneratedEnvironmentPlist().getExecPathString())
           .addOutput(getGeneratedEnvironmentPlist())
           .build(ruleContext));
 }
コード例 #26
0
  private ReleaseBundlingSupport registerExtractEntitlementsAction(Artifact entitlements) {
    // See Apple Glossary (http://goo.gl/EkhXOb)
    // An Application Identifier is constructed as: TeamID.BundleID
    // TeamID is extracted from the provisioning profile.
    // BundleID consists of a reverse-DNS string to identify the app, where the last component
    // is the application name, and is specified as an attribute.
    String shellCommand =
        "set -e && "
            + "PLIST=$(mktemp -t entitlements.plist) && trap \"rm ${PLIST}\" EXIT && "
            + extractPlistCommand(attributes.provisioningProfile())
            + " > ${PLIST} && "
            + "/usr/libexec/PlistBuddy -x -c 'Print Entitlements' ${PLIST} > "
            + entitlements.getShellEscapedExecPathString();
    ruleContext.registerAction(
        ObjcRuleClasses.spawnBashOnDarwinActionBuilder(ruleContext, shellCommand)
            .setMnemonic("ExtractIosEntitlements")
            .setProgressMessage("Extracting entitlements: " + ruleContext.getLabel())
            .addInput(attributes.provisioningProfile())
            .addOutput(entitlements)
            .build(ruleContext));

    return this;
  }
コード例 #27
0
  private AndroidStudioInfoFilesProvider createIdeBuildArtifact(
      ConfiguredTarget base,
      RuleContext ruleContext,
      Kind ruleKind,
      DependenciesResult dependenciesResult,
      AndroidStudioInfoFilesProvider.Builder providerBuilder) {

    Artifact ideInfoFile = derivedArtifact(base, ruleContext, ASWB_BUILD_SUFFIX);
    Artifact ideInfoTextFile = derivedArtifact(base, ruleContext, ASWB_BUILD_TEXT_SUFFIX);
    providerBuilder.ideInfoFilesBuilder().add(ideInfoFile);
    providerBuilder.ideInfoTextFilesBuilder().add(ideInfoTextFile);
    NestedSetBuilder<Artifact> ideResolveArtifacts = providerBuilder.ideResolveFilesBuilder();

    RuleIdeInfo.Builder outputBuilder = RuleIdeInfo.newBuilder();

    outputBuilder.setLabel(base.getLabel().toString());

    outputBuilder.setBuildFile(
        ruleContext.getRule().getPackage().getBuildFile().getPath().toString());

    outputBuilder.setBuildFileArtifactLocation(
        makeArtifactLocation(ruleContext.getRule().getPackage()));

    if (ruleKind != Kind.UNRECOGNIZED) {
      outputBuilder.setKind(ruleKind);
    }
    outputBuilder.setKindString(ruleContext.getRule().getRuleClass());

    // Java rules
    JavaRuleOutputJarsProvider outputJarsProvider =
        base.getProvider(JavaRuleOutputJarsProvider.class);
    if (outputJarsProvider != null) {
      Artifact packageManifest = createPackageManifest(base, ruleContext);
      if (packageManifest != null) {
        providerBuilder.ideInfoFilesBuilder().add(packageManifest);
        ruleContext.registerAction(
            makePackageManifestAction(ruleContext, packageManifest, getJavaSources(ruleContext)));
      }

      JavaRuleIdeInfo javaRuleIdeInfo =
          makeJavaRuleIdeInfo(
              base, ruleContext, outputJarsProvider, ideResolveArtifacts, packageManifest);
      outputBuilder.setJavaRuleIdeInfo(javaRuleIdeInfo);
    }

    // C rules
    CppCompilationContext cppCompilationContext = base.getProvider(CppCompilationContext.class);
    if (cppCompilationContext != null) {
      CRuleIdeInfo cRuleIdeInfo = makeCRuleIdeInfo(base, ruleContext, cppCompilationContext);
      outputBuilder.setCRuleIdeInfo(cRuleIdeInfo);
    }

    // CCToolchain rule
    CppConfiguration cppConfiguration = getCppConfiguration(base);
    if (cppConfiguration != null) {
      CToolchainIdeInfo cToolchainIdeInfo = makeCToolchainIdeInfo(ruleContext, cppConfiguration);
      if (cToolchainIdeInfo != null) {
        outputBuilder.setCToolchainIdeInfo(cToolchainIdeInfo);
      }
    }

    // Android rules
    AndroidIdeInfoProvider androidIdeInfoProvider = base.getProvider(AndroidIdeInfoProvider.class);
    if (androidIdeInfoProvider != null) {
      outputBuilder.setAndroidRuleIdeInfo(
          makeAndroidRuleIdeInfo(
              base, androidIdeInfoProvider, dependenciesResult, ideResolveArtifacts));
    }

    AndroidStudioInfoFilesProvider provider = providerBuilder.build();

    outputBuilder.addAllDependencies(transform(dependenciesResult.deps, LABEL_TO_STRING));
    outputBuilder.addAllRuntimeDeps(transform(dependenciesResult.runtimeDeps, LABEL_TO_STRING));
    outputBuilder.addAllTags(base.getTarget().getAssociatedRule().getRuleTags());

    final RuleIdeInfo ruleIdeInfo = outputBuilder.build();

    ruleContext.registerAction(
        makeProtoWriteAction(ruleContext.getActionOwner(), ruleIdeInfo, ideInfoFile));
    ruleContext.registerAction(
        makeProtoTextWriteAction(ruleContext.getActionOwner(), ruleIdeInfo, ideInfoTextFile));

    return provider;
  }
コード例 #28
0
  /** Builds the action as configured. */
  public void build() throws InterruptedException {
    ImmutableList<Artifact> classpathResources = attributes.getClassPathResources();
    Set<String> classPathResourceNames = new HashSet<>();
    for (Artifact artifact : classpathResources) {
      String name = artifact.getExecPath().getBaseName();
      if (!classPathResourceNames.add(name)) {
        ruleContext.attributeError(
            "classpath_resources",
            "entries must have different file names (duplicate: " + name + ")");
        return;
      }
    }

    IterablesChain<Artifact> runtimeJars = runtimeJarsBuilder.build();

    // TODO(kmb): Consider not using getArchiveInputs, specifically because we don't want/need to
    // transform anything but the runtimeClasspath and b/c we currently do it twice here and below
    IterablesChain.Builder<Artifact> inputs = IterablesChain.builder();
    inputs.add(getArchiveInputs(attributes, derivedJars));

    inputs.add(ImmutableList.copyOf(Iterables.transform(runtimeJars, derivedJars)));
    if (runfilesMiddleman != null) {
      inputs.addElement(runfilesMiddleman);
    }

    ImmutableList<Artifact> buildInfoArtifacts = ruleContext.getBuildInfo(JavaBuildInfoFactory.KEY);
    inputs.add(buildInfoArtifacts);

    Iterable<Artifact> runtimeClasspath =
        Iterables.transform(
            Iterables.concat(runtimeJars, attributes.getRuntimeClassPathForArchive()), derivedJars);

    if (launcher != null) {
      inputs.addElement(launcher);
    }

    CommandLine commandLine =
        semantics.buildSingleJarCommandLine(
            ruleContext.getConfiguration(),
            outputJar,
            javaStartClass,
            deployManifestLines,
            buildInfoArtifacts,
            classpathResources,
            runtimeClasspath,
            includeBuildData,
            compression,
            launcher);

    List<String> jvmArgs = ImmutableList.of("-client", SINGLEJAR_MAX_MEMORY);
    ResourceSet resourceSet =
        ResourceSet.createWithRamCpuIo(/*memoryMb = */ 200.0, /*cpuUsage = */ .2, /*ioUsage=*/ .2);

    // If singlejar's name ends with .jar, it is Java application, otherwise it is native.
    // TODO(asmundak): once b/28640279 is fixed (that is, the native singlejar is released),
    // eliminate this check, allowing only native singlejar.
    Artifact singlejar = getSingleJar(ruleContext);
    if (singlejar.getFilename().endsWith(".jar")) {
      ruleContext.registerAction(
          new SpawnAction.Builder()
              .addInputs(inputs.build())
              .addTransitiveInputs(JavaHelper.getHostJavabaseInputs(ruleContext))
              .addOutput(outputJar)
              .setResources(resourceSet)
              .setJarExecutable(
                  ruleContext.getHostConfiguration().getFragment(Jvm.class).getJavaExecutable(),
                  singlejar,
                  jvmArgs)
              .setCommandLine(commandLine)
              .alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED)
              .setProgressMessage("Building deploy jar " + outputJar.prettyPrint())
              .setMnemonic("JavaDeployJar")
              .setExecutionInfo(ImmutableMap.of("supports-workers", "1"))
              .build(ruleContext));
    } else {
      ruleContext.registerAction(
          new SpawnAction.Builder()
              .addInputs(inputs.build())
              .addTransitiveInputs(JavaHelper.getHostJavabaseInputs(ruleContext))
              .addOutput(outputJar)
              .setResources(resourceSet)
              .setExecutable(singlejar)
              .setCommandLine(commandLine)
              .alwaysUseParameterFile(ParameterFileType.SHELL_QUOTED)
              .setProgressMessage("Building deploy jar " + outputJar.prettyPrint())
              .setMnemonic("JavaDeployJar")
              .build(ruleContext));
    }
  }
コード例 #29
0
  /** Create context for cc compile action from generated inputs. */
  private CppCompilationContext initializeCppCompilationContext(CppModel model) {
    CppCompilationContext.Builder contextBuilder = new CppCompilationContext.Builder(ruleContext);

    // Setup the include path; local include directories come before those inherited from deps or
    // from the toolchain; in case of aliasing (same include file found on different entries),
    // prefer the local include rather than the inherited one.

    // Add in the roots for well-formed include names for source files and
    // generated files. It is important that the execRoot (EMPTY_FRAGMENT) comes
    // before the genfilesFragment to preferably pick up source files. Otherwise
    // we might pick up stale generated files.
    PathFragment repositoryPath =
        ruleContext.getLabel().getPackageIdentifier().getRepository().getPathFragment();
    contextBuilder.addQuoteIncludeDir(repositoryPath);
    contextBuilder.addQuoteIncludeDir(
        ruleContext.getConfiguration().getGenfilesFragment().getRelative(repositoryPath));

    for (PathFragment systemIncludeDir : systemIncludeDirs) {
      contextBuilder.addSystemIncludeDir(systemIncludeDir);
    }
    for (PathFragment includeDir : includeDirs) {
      contextBuilder.addIncludeDir(includeDir);
    }

    contextBuilder.mergeDependentContexts(
        AnalysisUtils.getProviders(deps, CppCompilationContext.class));
    CppHelper.mergeToolchainDependentContext(ruleContext, contextBuilder);

    // But defines come after those inherited from deps.
    contextBuilder.addDefines(defines);

    // There are no ordering constraints for declared include dirs/srcs, or the pregrepped headers.
    contextBuilder.addDeclaredIncludeSrcs(publicHeaders);
    contextBuilder.addDeclaredIncludeSrcs(publicTextualHeaders);
    contextBuilder.addDeclaredIncludeSrcs(privateHeaders);
    contextBuilder.addPregreppedHeaderMap(
        CppHelper.createExtractInclusions(ruleContext, semantics, publicHeaders));
    contextBuilder.addPregreppedHeaderMap(
        CppHelper.createExtractInclusions(ruleContext, semantics, publicTextualHeaders));
    contextBuilder.addPregreppedHeaderMap(
        CppHelper.createExtractInclusions(ruleContext, semantics, privateHeaders));
    contextBuilder.addCompilationPrerequisites(prerequisites);

    // Add this package's dir to declaredIncludeDirs, & this rule's headers to declaredIncludeSrcs
    // Note: no include dir for STRICT mode.
    if (headersCheckingMode == HeadersCheckingMode.WARN) {
      contextBuilder.addDeclaredIncludeWarnDir(ruleContext.getLabel().getPackageFragment());
      for (PathFragment looseIncludeDir : looseIncludeDirs) {
        contextBuilder.addDeclaredIncludeWarnDir(looseIncludeDir);
      }
    } else if (headersCheckingMode == HeadersCheckingMode.LOOSE) {
      contextBuilder.addDeclaredIncludeDir(ruleContext.getLabel().getPackageFragment());
      for (PathFragment looseIncludeDir : looseIncludeDirs) {
        contextBuilder.addDeclaredIncludeDir(looseIncludeDir);
      }
    }

    if (featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAPS)) {
      CppModuleMap cppModuleMap = CppHelper.addCppModuleMapToContext(ruleContext, contextBuilder);
      // TODO(bazel-team): addCppModuleMapToContext second-guesses whether module maps should
      // actually be enabled, so we need to double-check here. Who would write code like this?
      if (cppModuleMap != null) {
        CppModuleMapAction action =
            new CppModuleMapAction(
                ruleContext.getActionOwner(),
                cppModuleMap,
                privateHeaders,
                publicHeaders,
                collectModuleMaps(),
                additionalExportedHeaders,
                featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULES),
                featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAP_HOME_CWD),
                featureConfiguration.isEnabled(CppRuleClasses.GENERATE_SUBMODULES),
                !featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAP_WITHOUT_EXTERN_MODULE));
        ruleContext.registerAction(action);
      }
      if (model.getGeneratesPicHeaderModule()) {
        contextBuilder.setPicHeaderModule(model.getPicHeaderModule(cppModuleMap.getArtifact()));
      }
      if (model.getGeneratesNoPicHeaderModule()) {
        contextBuilder.setHeaderModule(model.getHeaderModule(cppModuleMap.getArtifact()));
      }
      if (featureConfiguration.isEnabled(CppRuleClasses.USE_HEADER_MODULES)
          && featureConfiguration.isEnabled(CppRuleClasses.TRANSITIVE_MODULE_MAPS)) {
        contextBuilder.setProvideTransitiveModuleMaps(true);
      }
    }

    semantics.setupCompilationContext(ruleContext, contextBuilder);
    return contextBuilder.build();
  }