/**
   * Registers actions required to build an application. This includes any {@link
   * BundleSupport#registerActions(ObjcProvider) bundle} and bundle merge actions, signing this
   * application if appropriate and combining several single-architecture binaries into one
   * multi-architecture binary.
   *
   * @return this application support
   * @throws InterruptedException
   */
  ReleaseBundlingSupport registerActions() throws InterruptedException {
    bundleSupport.registerActions(objcProvider);

    registerCombineArchitecturesAction();
    registerTransformAndCopyBreakpadFilesAction();
    registerSwiftStdlibActionsIfNecessary();

    AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
    Artifact ipaOutput = ruleContext.getImplicitOutputArtifact(IPA);

    Artifact maybeSignedIpa;
    if (appleConfiguration.getBundlingPlatform() == Platform.IOS_SIMULATOR) {
      maybeSignedIpa = ipaOutput;
    } else if (attributes.provisioningProfile() == null) {
      throw new IllegalStateException(DEVICE_NO_PROVISIONING_PROFILE);
    } else {
      maybeSignedIpa = registerBundleSigningActions(ipaOutput);
    }

    registerEmbedLabelPlistAction();
    registerEnvironmentPlistAction();
    registerAutomaticPlistAction();

    if (ObjcRuleClasses.useLaunchStoryboard(ruleContext)) {
      registerLaunchStoryboardPlistAction();
    }

    BundleMergeControlBytes bundleMergeControlBytes =
        new BundleMergeControlBytes(
            bundling, maybeSignedIpa, appleConfiguration, bundleSupport.targetDeviceFamilies());
    registerBundleMergeActions(
        maybeSignedIpa, bundling.getBundleContentArtifacts(), bundleMergeControlBytes);

    return this;
  }
Пример #2
0
    @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));
      }
    }
Пример #3
0
  /**
   * Returns the xcode version number corresponding to the {@code --xcode_version} flag, if there is
   * an available {@code xcode_version} target which recognizes the flag value as either an official
   * version or an alias. Returns null if no such target is found.
   */
  @Nullable
  private DottedVersion resolveExplicitlyDefinedVersion(RuleContext ruleContext) {
    AppleConfiguration configuration = ruleContext.getFragment(AppleConfiguration.class);
    Optional<DottedVersion> versionOverrideFlag = configuration.getXcodeVersionOverrideFlag();
    if (versionOverrideFlag.isPresent()) {
      // The version override flag is not necessarily an actual version - it may be a version
      // alias.
      DottedVersion explicitVerison =
          aliasesToVersionMap(ruleContext).get(versionOverrideFlag.get().toString());
      if (explicitVerison != null) {
        return explicitVerison;
      }
    } else { // No override specified. Use default.
      XcodeVersionProvider defaultProvider =
          ruleContext.getPrerequisite(
              XcodeConfigRule.DEFAULT_ATTR_NAME, Mode.TARGET, XcodeVersionProvider.class);

      if (defaultProvider != null) {
        return defaultProvider.getVersion();
      }
    }

    boolean requireDefinedVersions =
        ruleContext.attributes().get(XcodeConfigRule.REQUIRE_DEFINED_VERSIONS_ATTR_NAME, BOOLEAN);
    if (requireDefinedVersions) {
      ruleContext.ruleError(
          "xcode version config required an explicitly defined version, but none was available");
    }

    return null;
  }
  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));
  }
Пример #5
0
 /** Returns true iff code coverage is enabled for the given target. */
 private boolean isCodeCoverageEnabled() {
   if (configuration.isCodeCoverageEnabled()) {
     // If rule is matched by the instrumentation filter, enable instrumentation
     if (InstrumentedFilesCollector.shouldIncludeLocalSources(ruleContext)) {
       return true;
     }
     // At this point the rule itself is not matched by the instrumentation filter. However, we
     // might still want to instrument C++ rules if one of the targets listed in "deps" is
     // instrumented and, therefore, can supply header files that we would want to collect code
     // coverage for. For example, think about cc_test rule that tests functionality defined in a
     // header file that is supplied by the cc_library.
     //
     // Note that we only check direct prerequisites and not the transitive closure. This is done
     // for two reasons:
     // a) It is a good practice to declare libraries which you directly rely on. Including headers
     //    from a library hidden deep inside the transitive closure makes build dependencies less
     //    readable and can lead to unexpected breakage.
     // b) Traversing the transitive closure for each C++ compile action would require more complex
     //    implementation (with caching results of this method) to avoid O(N^2) slowdown.
     if (ruleContext.getRule().isAttrDefined("deps", BuildType.LABEL_LIST)) {
       for (TransitiveInfoCollection dep : ruleContext.getPrerequisites("deps", Mode.TARGET)) {
         if (dep.getProvider(CppCompilationContext.class) != null
             && InstrumentedFilesCollector.shouldIncludeLocalSources(configuration, dep)) {
           return true;
         }
       }
     }
   }
   return false;
 }
Пример #6
0
    @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));
        }
      }
    }
 private static Collection<Artifact> getTargetListAttribute(
     RuleContext ruleContext, String attributeName) {
   return (ruleContext.attributes().has(attributeName, BuildType.LABEL_LIST)
           && ruleContext.getAttributeMode(attributeName) == Mode.TARGET)
       ? ruleContext.getPrerequisiteArtifacts(attributeName, Mode.TARGET).list()
       : ImmutableList.<Artifact>of();
 }
  TestTargetExecutionSettings(
      RuleContext ruleContext,
      RunfilesSupport runfiles,
      Artifact executable,
      Artifact instrumentedFileManifest,
      int shards) {
    Preconditions.checkArgument(TargetUtils.isTestRule(ruleContext.getRule()));
    Preconditions.checkArgument(shards >= 0);
    BuildConfiguration config = ruleContext.getConfiguration();

    List<String> targetArgs = runfiles.getArgs();
    testArguments =
        targetArgs.isEmpty()
            ? config.getTestArguments()
            : ImmutableList.copyOf(Iterables.concat(targetArgs, config.getTestArguments()));

    totalShards = shards;
    runUnder = config.getRunUnder();
    runUnderExecutable = getRunUnderExecutable(ruleContext);

    this.testFilter = config.getTestFilter();
    this.executable = executable;
    this.runfilesManifest = runfiles.getRunfilesManifest();
    this.runfilesInputManifest = runfiles.getRunfilesInputManifest();
    this.instrumentedFileManifest = instrumentedFileManifest;
  }
 private static void validateManifest(RuleContext ruleContext) throws RuleErrorException {
   if (ruleContext.getPrerequisiteArtifact("manifest", Mode.TARGET) == null) {
     ruleContext.attributeError(
         "manifest", "manifest is required when resource_files or assets are defined.");
     throw new RuleErrorException();
   }
 }
Пример #10
0
    /**
     * Creates a middleman for the compilation prerequisites.
     *
     * @return the middleman or null if there are no prerequisites
     */
    private Artifact createMiddleman(ActionOwner owner, MiddlemanFactory middlemanFactory) {
      if (compilationPrerequisites.isEmpty()) {
        return null;
      }

      // Compilation prerequisites gathered in the compilationPrerequisites
      // must be generated prior to executing C++ compilation step that depends
      // on them (since these prerequisites include all potential header files, etc
      // that could be referenced during compilation). So there is a definite need
      // to ensure scheduling edge dependency. However, those prerequisites should
      // have no effect on the decision whether C++ compilation should happen in
      // the first place - only CppCompileAction outputs (*.o and *.d files) and
      // all files referenced by the *.d file should be used to make that decision.
      // If this action was never executed, then *.d file would be missing, forcing
      // compilation to occur. If *.d file is present and has not changed then the
      // only reason that would force us to re-compile would be change in one of
      // the files referenced by the *.d file, since no other files participated
      // in the compilation. We also need to propagate errors through this
      // dependency link. So we use an error propagating middleman.
      // Such middleman will be ignored by the dependency checker yet will still
      // represent an edge in the action dependency graph - forcing proper execution
      // order and error propagation.
      return middlemanFactory.createErrorPropagatingMiddleman(
          owner,
          ruleContext.getLabel().toString(),
          purpose,
          ImmutableList.copyOf(compilationPrerequisites),
          ruleContext
              .getConfiguration()
              .getMiddlemanDirectory(ruleContext.getRule().getRepository()));
    }
Пример #11
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);
  }
Пример #12
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);
  }
Пример #13
0
  private ImmutableList<Artifact> generatedOutputArtifacts(FileType newFileType) {
    ImmutableList.Builder<Artifact> builder = new ImmutableList.Builder<>();
    for (Artifact protoFile : getFilteredProtoSources()) {
      String protoFileName = FileSystemUtils.removeExtension(protoFile.getFilename());
      String generatedOutputName;
      if (attributes.outputsCpp()) {
        generatedOutputName = protoFileName;
      } else if (usesProtobufLibrary()) {
        // The protobuf library generates filenames with some slight modifications.
        generatedOutputName = generateProtobufFilename(protoFileName);
      } else {
        String lowerUnderscoreBaseName = protoFileName.replace('-', '_').toLowerCase();
        generatedOutputName = LOWER_UNDERSCORE.to(UPPER_CAMEL, lowerUnderscoreBaseName);
      }

      PathFragment generatedFilePath =
          new PathFragment(
              protoFile.getRootRelativePath().getParentDirectory(),
              new PathFragment(generatedOutputName));

      PathFragment outputFile =
          FileSystemUtils.appendExtension(generatedFilePath, newFileType.getExtensions().get(0));

      if (outputFile != null) {
        builder.add(
            ruleContext.getUniqueDirectoryArtifact(
                UNIQUE_DIRECTORY_NAME, outputFile, ruleContext.getBinOrGenfilesDirectory()));
      }
    }
    return builder.build();
  }
Пример #14
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;
  }
  /** 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));
  }
Пример #16
0
 public CppModel(RuleContext ruleContext, CppSemantics semantics) {
   this.ruleContext = Preconditions.checkNotNull(ruleContext);
   this.semantics = semantics;
   configuration = ruleContext.getConfiguration();
   cppConfiguration = ruleContext.getFragment(CppConfiguration.class);
   features = CppHelper.getToolchain(ruleContext).getFeatures();
 }
Пример #17
0
    /**
     * Validity-checks that no group has its environment referenced in both the "compatible with"
     * and restricted to" attributes. Returns true if all is good, returns false and reports
     * appropriate errors if there are any problems.
     */
    boolean validateEnvironmentSpecifications() {
      ImmutableCollection<EnvironmentGroup> restrictionGroups = restrictionEnvironments.getGroups();
      boolean hasErrors = false;

      for (EnvironmentGroup group : compatibilityEnvironments.getGroups()) {
        if (restrictionGroups.contains(group)) {
          // To avoid error-spamming the user, when we find a conflict we only report one example
          // environment from each attribute for that group.
          Label compatibilityEnv =
              compatibilityEnvironments.getEnvironments(group).iterator().next();
          Label restrictionEnv = restrictionEnvironments.getEnvironments(group).iterator().next();

          if (compatibilityEnv.equals(restrictionEnv)) {
            ruleContext.attributeError(
                compatibilityAttr,
                compatibilityEnv + " cannot appear both here and in " + restrictionAttr);
          } else {
            ruleContext.attributeError(
                compatibilityAttr,
                compatibilityEnv
                    + " and "
                    + restrictionEnv
                    + " belong to the same environment group. They should be declared "
                    + "together either here or in "
                    + restrictionAttr);
          }
          hasErrors = true;
        }
      }

      return !hasErrors;
    }
Пример #18
0
 /**
  * The artifact for the .o file that should be generated when compiling the {@code source}
  * artifact.
  */
 public Artifact objFile(Artifact source) {
   if (source.isTreeArtifact()) {
     PathFragment rootRelativePath = source.getRootRelativePath().replaceName("obj_files");
     return ruleContext.getTreeArtifact(rootRelativePath, ruleContext.getBinOrGenfilesDirectory());
   } else {
     return inUniqueObjsDir(source, ".o");
   }
 }
 private void registerAutomaticPlistAction() {
   ruleContext.registerAction(
       new FileWriteAction(
           ruleContext.getActionOwner(),
           getGeneratedAutomaticPlist(),
           automaticEntries().toASCIIPropertyList(),
           /*makeExecutable=*/ false));
 }
Пример #20
0
 /** Returns the options file, or null if it was not specified. */
 @Nullable
 Artifact getOptionsFile() {
   if (ruleContext.attributes().has(ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, LABEL)) {
     return ruleContext.getPrerequisiteArtifact(
         ObjcProtoLibraryRule.OPTIONS_FILE_ATTR, Mode.HOST);
   }
   return null;
 }
Пример #21
0
 private void registerProtoInputListFileAction() {
   ruleContext.registerAction(
       new FileWriteAction(
           ruleContext.getActionOwner(),
           getProtoInputListFile(),
           getProtoInputListFileContents(),
           false));
 }
Пример #22
0
 /**
  * Returns the list of proto files that were added directly into the deps attributes. This way
  * of specifying the protos is deprecated, and displays a warning when the target does so.
  */
 private ImmutableList<Artifact> getProtoDepsFiles() {
   PrerequisiteArtifacts prerequisiteArtifacts =
       ruleContext.getPrerequisiteArtifacts("deps", Mode.TARGET);
   ImmutableList<Artifact> protos = prerequisiteArtifacts.filter(FileType.of(".proto")).list();
   if (!protos.isEmpty()) {
     ruleContext.attributeWarning("deps", FILES_DEPRECATED_WARNING);
   }
   return protos;
 }
Пример #23
0
 @Nullable
 Artifact provisioningProfile() {
   Artifact explicitProvisioningProfile =
       ruleContext.getPrerequisiteArtifact("provisioning_profile", Mode.TARGET);
   if (explicitProvisioningProfile != null) {
     return explicitProvisioningProfile;
   }
   return ruleContext.getPrerequisiteArtifact(":default_provisioning_profile", Mode.TARGET);
 }
Пример #24
0
  private PathFragment getWorkspaceRelativeOutputDir() {
    // Generate sources in a package-and-rule-scoped directory; adds both the
    // package-and-rule-scoped directory and the header-containing-directory to the include path
    // of dependers.
    PathFragment rootRelativeOutputDir = ruleContext.getUniqueDirectory(UNIQUE_DIRECTORY_NAME);

    return new PathFragment(
        ruleContext.getBinOrGenfilesDirectory().getExecPath(), rootRelativeOutputDir);
  }
Пример #25
0
  private Artifact scopedArtifact(PathFragment scopeRelative, boolean inGenfiles) {
    Root root =
        inGenfiles
            ? buildConfiguration.getGenfilesDirectory(ruleContext.getRule().getRepository())
            : buildConfiguration.getBinDirectory(ruleContext.getRule().getRepository());

    // The path of this artifact will be RULE_PACKAGE/SCOPERELATIVE
    return ruleContext.getPackageRelativeArtifact(scopeRelative, root);
  }
 private static void validateAssetsAndAssetsDir(RuleContext ruleContext)
     throws RuleErrorException {
   if (ruleContext.attributes().isAttributeValueExplicitlySpecified("assets")
       ^ ruleContext.attributes().isAttributeValueExplicitlySpecified("assets_dir")) {
     ruleContext.ruleError(
         "'assets' and 'assets_dir' should be either both empty or both non-empty");
     throw new RuleErrorException();
   }
 }
Пример #27
0
 /**
  * Returns a derived artifact in the bin directory obtained by appending some extension to the
  * main label name; the result artifact is placed in a unique "entitlements" directory. For
  * example, if this artifact is for a target Foo with extension ".extension", the result artifact
  * will be located at {target_base_path}/entitlements/Foo.extension.
  */
 public Artifact appendExtensionForEntitlementArtifact(String extension) {
   PathFragment entitlementsDirectory = ruleContext.getUniqueDirectory("entitlements");
   Artifact artifact =
       ruleContext.getDerivedArtifact(
           entitlementsDirectory.replaceName(
               addOutputPrefix(entitlementsDirectory.getBaseName(), extension)),
           buildConfiguration.getBinDirectory(ruleContext.getRule().getRepository()));
   return artifact;
 }
Пример #28
0
  private TransitiveInfoCollection selectDep(
      RuleContext ruleContext, String attribute, Label label) {
    for (TransitiveInfoCollection dep : ruleContext.getPrerequisites(attribute, Mode.TARGET)) {
      if (dep.getLabel().equals(label)) {
        return dep;
      }
    }

    return ruleContext.getPrerequisites(attribute, Mode.TARGET).get(0);
  }
Пример #29
0
 private CppModuleMap createCrosstoolModuleMap(RuleContext ruleContext) {
   if (ruleContext.getPrerequisite("module_map", Mode.HOST) == null) {
     return null;
   }
   Artifact moduleMapArtifact = ruleContext.getPrerequisiteArtifact("module_map", Mode.HOST);
   if (moduleMapArtifact == null) {
     return null;
   }
   return new CppModuleMap(moduleMapArtifact, "crosstool");
 }
Пример #30
0
 /** Returns the list of portable proto filters. */
 ImmutableList<Artifact> getPortableProtoFilters() {
   if (ruleContext
       .attributes()
       .has(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR, LABEL_LIST)) {
     return ruleContext
         .getPrerequisiteArtifacts(ObjcProtoLibraryRule.PORTABLE_PROTO_FILTERS_ATTR, Mode.HOST)
         .list();
   }
   return ImmutableList.of();
 }