Search in sources :

Example 1 with FilesToRunProvider

use of com.google.devtools.build.lib.analysis.FilesToRunProvider in project bazel by bazelbuild.

the class RunCommand method exec.

@Override
public ExitCode exec(CommandEnvironment env, OptionsProvider options) {
    RunOptions runOptions = options.getOptions(RunOptions.class);
    // This list should look like: ["//executable:target", "arg1", "arg2"]
    List<String> targetAndArgs = options.getResidue();
    // The user must at the least specify an executable target.
    if (targetAndArgs.isEmpty()) {
        env.getReporter().handle(Event.error("Must specify a target to run"));
        return ExitCode.COMMAND_LINE_ERROR;
    }
    String targetString = targetAndArgs.get(0);
    List<String> runTargetArgs = targetAndArgs.subList(1, targetAndArgs.size());
    RunUnder runUnder = options.getOptions(BuildConfiguration.Options.class).runUnder;
    OutErr outErr = env.getReporter().getOutErr();
    List<String> targets = (runUnder != null) && (runUnder.getLabel() != null) ? ImmutableList.of(targetString, runUnder.getLabel().toString()) : ImmutableList.of(targetString);
    BuildRequest request = BuildRequest.create(this.getClass().getAnnotation(Command.class).name(), options, env.getRuntime().getStartupOptionsProvider(), targets, outErr, env.getCommandId(), env.getCommandStartTime());
    currentRunUnder = runUnder;
    BuildResult result;
    try {
        result = processRequest(env, request);
    } finally {
        currentRunUnder = null;
    }
    if (!result.getSuccess()) {
        env.getReporter().handle(Event.error("Build failed. Not running target"));
        return result.getExitCondition();
    }
    // Make sure that we have exactly 1 built target (excluding --run_under),
    // and that it is executable.
    // These checks should only fail if keepGoing is true, because we already did
    // validation before the build began.  See {@link #validateTargets()}.
    Collection<ConfiguredTarget> targetsBuilt = result.getSuccessfulTargets();
    ConfiguredTarget targetToRun = null;
    ConfiguredTarget runUnderTarget = null;
    if (targetsBuilt != null) {
        int maxTargets = runUnder != null && runUnder.getLabel() != null ? 2 : 1;
        if (targetsBuilt.size() > maxTargets) {
            env.getReporter().handle(Event.error(SINGLE_TARGET_MESSAGE));
            return ExitCode.COMMAND_LINE_ERROR;
        }
        for (ConfiguredTarget target : targetsBuilt) {
            ExitCode targetValidation = fullyValidateTarget(env, target);
            if (!targetValidation.equals(ExitCode.SUCCESS)) {
                return targetValidation;
            }
            if (runUnder != null && target.getLabel().equals(runUnder.getLabel())) {
                if (runUnderTarget != null) {
                    env.getReporter().handle(Event.error(null, "Can't identify the run_under target from multiple options?"));
                    return ExitCode.COMMAND_LINE_ERROR;
                }
                runUnderTarget = target;
            } else if (targetToRun == null) {
                targetToRun = target;
            } else {
                env.getReporter().handle(Event.error(SINGLE_TARGET_MESSAGE));
                return ExitCode.COMMAND_LINE_ERROR;
            }
        }
    }
    // Handle target & run_under referring to the same target.
    if ((targetToRun == null) && (runUnderTarget != null)) {
        targetToRun = runUnderTarget;
    }
    if (targetToRun == null) {
        env.getReporter().handle(Event.error(NO_TARGET_MESSAGE));
        return ExitCode.COMMAND_LINE_ERROR;
    }
    Path executablePath = Preconditions.checkNotNull(targetToRun.getProvider(FilesToRunProvider.class).getExecutable().getPath());
    BuildConfiguration configuration = targetToRun.getConfiguration();
    if (configuration == null) {
        // The target may be an input file, which doesn't have a configuration. In that case, we
        // choose any target configuration.
        configuration = result.getBuildConfigurationCollection().getTargetConfigurations().get(0);
    }
    Path workingDir;
    try {
        workingDir = ensureRunfilesBuilt(env, targetToRun);
    } catch (CommandException e) {
        env.getReporter().handle(Event.error("Error creating runfiles: " + e.getMessage()));
        return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
    }
    List<String> args = runTargetArgs;
    FilesToRunProvider provider = targetToRun.getProvider(FilesToRunProvider.class);
    RunfilesSupport runfilesSupport = provider == null ? null : provider.getRunfilesSupport();
    if (runfilesSupport != null && runfilesSupport.getArgs() != null) {
        List<String> targetArgs = runfilesSupport.getArgs();
        if (!targetArgs.isEmpty()) {
            args = Lists.newArrayListWithCapacity(targetArgs.size() + runTargetArgs.size());
            args.addAll(targetArgs);
            args.addAll(runTargetArgs);
        }
    }
    String productName = env.getRuntime().getProductName();
    //
    // We now have a unique executable ready to be run.
    //
    // We build up two different versions of the command to run: one with an absolute path, which
    // we'll actually run, and a prettier one with the long absolute path to the executable
    // replaced with a shorter relative path that uses the symlinks in the workspace.
    PathFragment prettyExecutablePath = OutputDirectoryLinksUtils.getPrettyPath(executablePath, env.getWorkspaceName(), env.getWorkspace(), options.getOptions(BuildRequestOptions.class).getSymlinkPrefix(productName), productName);
    List<String> cmdLine = new ArrayList<>();
    if (runOptions.scriptPath == null) {
        PathFragment processWrapperPath = env.getBlazeWorkspace().getBinTools().getExecPath(PROCESS_WRAPPER);
        Preconditions.checkNotNull(processWrapperPath, PROCESS_WRAPPER + " not found in embedded tools");
        cmdLine.add(env.getExecRoot().getRelative(processWrapperPath).getPathString());
        cmdLine.add("-1");
        cmdLine.add("15");
        cmdLine.add("-");
        cmdLine.add("-");
    }
    List<String> prettyCmdLine = new ArrayList<>();
    // at the start of the command line.
    if (runUnder != null) {
        String runUnderValue = runUnder.getValue();
        if (runUnderTarget != null) {
            // --run_under specifies a target. Get the corresponding executable.
            // This must be an absolute path, because the run_under target is only
            // in the runfiles of test targets.
            runUnderValue = runUnderTarget.getProvider(FilesToRunProvider.class).getExecutable().getPath().getPathString();
            // If the run_under command contains any options, make sure to add them
            // to the command line as well.
            List<String> opts = runUnder.getOptions();
            if (!opts.isEmpty()) {
                runUnderValue += " " + ShellEscaper.escapeJoinAll(opts);
            }
        }
        cmdLine.add(configuration.getShellExecutable().getPathString());
        cmdLine.add("-c");
        cmdLine.add(runUnderValue + " " + executablePath.getPathString() + " " + ShellEscaper.escapeJoinAll(args));
        prettyCmdLine.add(configuration.getShellExecutable().getPathString());
        prettyCmdLine.add("-c");
        prettyCmdLine.add(runUnderValue + " " + prettyExecutablePath.getPathString() + " " + ShellEscaper.escapeJoinAll(args));
    } else {
        cmdLine.add(executablePath.getPathString());
        cmdLine.addAll(args);
        prettyCmdLine.add(prettyExecutablePath.getPathString());
        prettyCmdLine.addAll(args);
    }
    // Add a newline between the blaze output and the binary's output.
    outErr.printErrLn("");
    if (runOptions.scriptPath != null) {
        String unisolatedCommand = CommandFailureUtils.describeCommand(CommandDescriptionForm.COMPLETE_UNISOLATED, cmdLine, null, workingDir.getPathString());
        if (writeScript(env, runOptions.scriptPath, unisolatedCommand)) {
            return ExitCode.SUCCESS;
        } else {
            return ExitCode.RUN_FAILURE;
        }
    }
    env.getReporter().handle(Event.info(null, "Running command line: " + ShellEscaper.escapeJoinAll(prettyCmdLine)));
    com.google.devtools.build.lib.shell.Command command = new CommandBuilder().addArgs(cmdLine).setEnv(env.getClientEnv()).setWorkingDir(workingDir).build();
    try {
        // Restore a raw EventHandler if it is registered. This allows for blaze run to produce the
        // actual output of the command being run even if --color=no is specified.
        env.getReporter().switchToAnsiAllowingHandler();
        // The command API is a little strange in that the following statement
        // will return normally only if the program exits with exit code 0.
        // If it ends with any other code, we have to catch BadExitStatusException.
        command.execute(com.google.devtools.build.lib.shell.Command.NO_INPUT, com.google.devtools.build.lib.shell.Command.NO_OBSERVER, outErr.getOutputStream(), outErr.getErrorStream(), true).getTerminationStatus().getExitCode();
        return ExitCode.SUCCESS;
    } catch (BadExitStatusException e) {
        String message = "Non-zero return code '" + e.getResult().getTerminationStatus().getExitCode() + "' from command: " + e.getMessage();
        env.getReporter().handle(Event.error(message));
        return ExitCode.RUN_FAILURE;
    } catch (AbnormalTerminationException e) {
        // The process was likely terminated by a signal in this case.
        return ExitCode.INTERRUPTED;
    } catch (CommandException e) {
        env.getReporter().handle(Event.error("Error running program: " + e.getMessage()));
        return ExitCode.RUN_FAILURE;
    }
}
Also used : BuildRequestOptions(com.google.devtools.build.lib.buildtool.BuildRequest.BuildRequestOptions) RunUnder(com.google.devtools.build.lib.analysis.config.RunUnder) FilesToRunProvider(com.google.devtools.build.lib.analysis.FilesToRunProvider) ExitCode(com.google.devtools.build.lib.util.ExitCode) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) ArrayList(java.util.ArrayList) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) RunfilesSupport(com.google.devtools.build.lib.analysis.RunfilesSupport) AbnormalTerminationException(com.google.devtools.build.lib.shell.AbnormalTerminationException) BadExitStatusException(com.google.devtools.build.lib.shell.BadExitStatusException) Path(com.google.devtools.build.lib.vfs.Path) OutErr(com.google.devtools.build.lib.util.io.OutErr) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) CommandException(com.google.devtools.build.lib.shell.CommandException) BuildRequest(com.google.devtools.build.lib.buildtool.BuildRequest) BuildResult(com.google.devtools.build.lib.buildtool.BuildResult) CommandBuilder(com.google.devtools.build.lib.util.CommandBuilder)

Example 2 with FilesToRunProvider

use of com.google.devtools.build.lib.analysis.FilesToRunProvider in project bazel by bazelbuild.

the class ReleaseBundlingSupport method registerPostProcessAndSigningActions.

/**
   * Registers all actions necessary to create a processed and signed IPA from the initial merged
   * IPA.
   *
   * <p>Includes user-provided actions to process IPA contents (via {@code ipa_post_processor}),
   * and signing actions if the IPA is being built for device architectures. If signing is necessary
   * also includes entitlements generation and processing actions.
   *
   * <p>Note that multiple "actions" on the IPA contents may be run in a single blaze action to
   * avoid excessive zipping/unzipping of IPA contents.
   */
private void registerPostProcessAndSigningActions() {
    Artifact processedIpa = releaseBundling.getIpaArtifact();
    Artifact unprocessedIpa = intermediateArtifacts.unprocessedIpa();
    NestedSetBuilder<Artifact> inputs = NestedSetBuilder.<Artifact>stableOrder().add(unprocessedIpa);
    String actionCommandLine = "set -e && " + "t=$(mktemp -d \"${TMPDIR:-/tmp}/signing_intermediate.XXXXXX\") && " + "trap \"rm -rf ${t}\" EXIT && " + // Get an absolute path since we need to cd into the temp directory for zip.
    "signed_ipa=${PWD}/" + processedIpa.getShellEscapedExecPathString() + " && " + "/usr/bin/unzip -qq " + unprocessedIpa.getShellEscapedExecPathString() + " -d ${t} && ";
    FilesToRunProvider processor = attributes.ipaPostProcessor();
    if (processor != null) {
        actionCommandLine += processor.getExecutable().getShellEscapedExecPathString() + " ${t} && ";
    }
    if (platform.isDevice()) {
        actionCommandLine += deviceSigningCommandLine();
        registerEntitlementsActions();
        inputs.add(releaseBundling.getProvisioningProfile()).add(intermediateArtifacts.entitlements());
    } else {
        actionCommandLine += simulatorSigningCommandLine();
    }
    actionCommandLine += "cd ${t} && /usr/bin/zip -q -r \"${signed_ipa}\" .";
    AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
    SpawnAction.Builder processAction = ObjcRuleClasses.spawnBashOnDarwinActionBuilder(actionCommandLine).setEnvironment(ObjcRuleClasses.appleToolchainEnvironment(appleConfiguration, platform)).setMnemonic("ObjcProcessIpa").setProgressMessage("Processing iOS IPA: " + ruleContext.getLabel()).disableSandboxing().addTransitiveInputs(inputs.build()).addOutput(processedIpa);
    if (processor != null) {
        processAction.addTool(processor);
    }
    ruleContext.registerAction(processAction.build(ruleContext));
}
Also used : FilesToRunProvider(com.google.devtools.build.lib.analysis.FilesToRunProvider) SpawnAction(com.google.devtools.build.lib.analysis.actions.SpawnAction) AppleConfiguration(com.google.devtools.build.lib.rules.apple.AppleConfiguration) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 3 with FilesToRunProvider

use of com.google.devtools.build.lib.analysis.FilesToRunProvider in project bazel by bazelbuild.

the class ProguardHelper method applyProguardIfRequested.

/**
   * Creates an action to run Proguard to <i>output</i> the given {@code deployJar} artifact if
   * --java_optimization_mode calls for it from an assumed input artifact {@link
   * JavaSemantics#JAVA_BINARY_MERGED_JAR}. Returns the artifacts that Proguard will generate or
   * {@code null} if Proguard isn't used.
   *
   * <p>If this method returns artifacts then {@link
   * com.google.devtools.build.lib.rules.java.DeployArchiveBuilder} needs to write the assumed input
   * artifact (instead of the conventional deploy.jar, which now Proguard writes). Do not use this
   * method for binary rules that themselves declare {@link #PROGUARD_SPECS} attributes, which as of
   * includes 1/2016 {@code android_binary} and {@code android_test}.
   */
@Nullable
public ProguardOutput applyProguardIfRequested(RuleContext ruleContext, Artifact deployJar, ImmutableList<Artifact> bootclasspath, String mainClassName, JavaSemantics semantics) throws InterruptedException {
    JavaOptimizationMode optMode = getJavaOptimizationMode(ruleContext);
    if (optMode == JavaOptimizationMode.NOOP || optMode == JavaOptimizationMode.LEGACY) {
        // For simplicity do nothing in LEGACY mode
        return null;
    }
    Preconditions.checkArgument(!bootclasspath.isEmpty(), "Bootclasspath should not be empty");
    FilesToRunProvider proguard = findProguard(ruleContext);
    if (proguard == null) {
        ruleContext.ruleError("--proguard_top required for --java_optimization_mode=" + optMode);
        return null;
    }
    ImmutableList<Artifact> proguardSpecs = collectProguardSpecs(ruleContext, bootclasspath, mainClassName);
    Artifact singleJar = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_MERGED_JAR);
    // TODO(bazel-team): Verify that proguard spec files don't contain -printmapping directions
    // which this -printmapping command line flag will override.
    Artifact proguardOutputMap = null;
    if (genProguardMapping(ruleContext.attributes()) || optMode.alwaysGenerateOutputMapping()) {
        proguardOutputMap = ruleContext.getImplicitOutputArtifact(JavaSemantics.JAVA_BINARY_PROGUARD_MAP);
    }
    return createProguardAction(ruleContext, proguard, singleJar, proguardSpecs, /* proguardSeeds */
    (Artifact) null, /* proguardUsage */
    (Artifact) null, /* proguardMapping */
    (Artifact) null, bootclasspath, deployJar, semantics, /* optimizationPases */
    3, proguardOutputMap, /* useSingleJarForProguardLibraryJars */
    false);
}
Also used : JavaOptimizationMode(com.google.devtools.build.lib.rules.java.JavaConfiguration.JavaOptimizationMode) FilesToRunProvider(com.google.devtools.build.lib.analysis.FilesToRunProvider) Artifact(com.google.devtools.build.lib.actions.Artifact) Nullable(javax.annotation.Nullable)

Example 4 with FilesToRunProvider

use of com.google.devtools.build.lib.analysis.FilesToRunProvider in project bazel by bazelbuild.

the class ProguardLibrary method collectProguardSpecs.

/**
   * Collects the validated proguard specs exported by this rule and its dependencies through the
   * given attributes.
   */
public NestedSet<Artifact> collectProguardSpecs(Multimap<Mode, String> attributes) {
    NestedSetBuilder<Artifact> specsBuilder = NestedSetBuilder.naiveLinkOrder();
    for (Entry<Mode, String> attribute : attributes.entries()) {
        specsBuilder.addTransitive(collectProguardSpecsFromAttribute(attribute.getValue(), attribute.getKey()));
    }
    Collection<Artifact> localSpecs = collectLocalProguardSpecs();
    if (!localSpecs.isEmpty()) {
        // Pass our local proguard configs through the validator, which checks a whitelist.
        FilesToRunProvider proguardWhitelister = ruleContext.getExecutablePrerequisite("$proguard_whitelister", Mode.HOST);
        for (Artifact specToValidate : localSpecs) {
            specsBuilder.add(validateProguardSpec(proguardWhitelister, specToValidate));
        }
    }
    return specsBuilder.build();
}
Also used : FilesToRunProvider(com.google.devtools.build.lib.analysis.FilesToRunProvider) Mode(com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode) Artifact(com.google.devtools.build.lib.actions.Artifact)

Example 5 with FilesToRunProvider

use of com.google.devtools.build.lib.analysis.FilesToRunProvider in project bazel by bazelbuild.

the class PopulateTreeArtifactActionTest method createPopulateTreeArtifactAction.

private PopulateTreeArtifactAction createPopulateTreeArtifactAction() throws Exception {
    Artifact archive = getSourceArtifact("myArchive.zip");
    Artifact treeArtifactToPopulate = createTreeArtifact("test/archive_member");
    Artifact archiveManifest = getSourceArtifact("archiveManifest.txt");
    FilesToRunProvider unzip = FilesToRunProvider.fromSingleExecutableArtifact(getSourceArtifact("unzipBinary"));
    scratch.file("archiveManifest.txt", "archive_members/1.class", "archive_members/2.class", "archive_members/txt/text.txt");
    return new PopulateTreeArtifactAction(ActionsTestUtil.NULL_ACTION_OWNER, archive, archiveManifest, treeArtifactToPopulate, unzip);
}
Also used : FilesToRunProvider(com.google.devtools.build.lib.analysis.FilesToRunProvider) SpecialArtifact(com.google.devtools.build.lib.actions.Artifact.SpecialArtifact) Artifact(com.google.devtools.build.lib.actions.Artifact) TreeFileArtifact(com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)

Aggregations

FilesToRunProvider (com.google.devtools.build.lib.analysis.FilesToRunProvider)22 Artifact (com.google.devtools.build.lib.actions.Artifact)17 SpawnAction (com.google.devtools.build.lib.analysis.actions.SpawnAction)7 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)4 TransitiveInfoCollection (com.google.devtools.build.lib.analysis.TransitiveInfoCollection)4 ImmutableMap (com.google.common.collect.ImmutableMap)3 CustomCommandLine (com.google.devtools.build.lib.analysis.actions.CustomCommandLine)3 ArrayList (java.util.ArrayList)3 ImmutableList (com.google.common.collect.ImmutableList)2 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)2 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)2 RunfilesSupport (com.google.devtools.build.lib.analysis.RunfilesSupport)2 Builder (com.google.devtools.build.lib.analysis.actions.SpawnAction.Builder)2 Label (com.google.devtools.build.lib.cmdline.Label)2 NestedSetBuilder (com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder)2 Path (com.google.devtools.build.lib.vfs.Path)2 PathFragment (com.google.devtools.build.lib.vfs.PathFragment)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 Nullable (javax.annotation.Nullable)2