bazelbuild / rules_scala

Scala rules for Bazel
Apache License 2.0
363 stars 275 forks source link

Can't run a bazel executable within bazel on Windows #1540

Closed Atridas closed 8 months ago

Atridas commented 8 months ago

I'm not sure if this is a Bazel issue or a rules_scala issue.

This is how we're calling the run action

ctx.actions.run(
        executable = ctx.files.generator[1],
        outputs = [ output, ],
        inputs = ctx.files.generator,
        arguments = [ args ],
        toolchain = None,
    )

generator comes from a label to a scala_binary and it's files are the .jar and .exe. This works when I first invoke the binary generation and then the run rule, but if I do it the other way around it fails because it can't get the runfiles on windows. I've tracked it down to Bazel not writing the executablename.exe.runfiles_manifest in the later case, and I have no idea how to force it to do.

I whould have two questions: is there a "more correct" way to invoke a scala executable during the build steps than this? If not, how can I force Bazel to write all the necessary files for it to run this way?

tjgq commented 8 months ago

Does your binary use a runfiles library to resolve runfile paths, or is it trying to access the runfile symlinks directly? The symlinks aren't created by default on Windows (see https://bazel.build/configure/windows#symlink).

tjgq commented 8 months ago

Also, you must write executable = ctx.executable.generator to ensure the runfiles are inputs to the action (irrespective of whether symlinks are enabled or not).

Atridas commented 8 months ago

Enabling symlinks run into the same problem, executable = ctx.executable.generator will fail with the following message:

Error in run: in call to run(), parameter 'executable' got value of type 'list', want 'File, string, or FilesToRunProvider'

tjgq commented 8 months ago

Can you share a complete example? It's hard for me to reconcile the error message with what you're doing; my suspicion is that you might be using an attr.label_list instead of an attr.label(cfg = "exec", executable = True) as expected by ctx.executable, but I'm not sure.

Atridas commented 8 months ago

This is the bazel script I had:


def _verilog_generate_impl(ctx):

    output = ctx.actions.declare_file(ctx.attr.output)

    # Build arguments
    args = ctx.actions.args()
    args.add("--verilog")
    args.add("-o")
    args.add(output.dirname)

    ctx.actions.run(
        executable = ctx.files.generator[1],
        outputs = [ output, ],
        inputs = ctx.files.generator,
        arguments = [ args ],
        toolchain = None,
    )
    return [DefaultInfo(files = depset([ output ]))]

verilog_generate = rule(
    implementation = _verilog_generate_impl,
    attrs = {
        "generator": attr.label(mandatory=True, allow_files=True),
        "output": attr.string(mandatory=True),
        },
)

and the BUILD file I'm using:

load("@io_bazel_rules_scala//scala:scala.bzl", "scala_binary")
load("//toolchains:plugins.bzl", "SPINAL_HDL_PLUGINS")

scala_binary(
    name = "spinaltest",
    main_class = "spinaltest.CarryAdderProject",
    srcs = [
        "hw/spinal/spinaltest/Config.scala",
        "hw/spinal/spinaltest/CarryAdder.scala",
        ],
    plugins = SPINAL_HDL_PLUGINS,
)

load("//toolchains:verilog_generate.bzl", "verilog_generate")

verilog_generate(
  name="generate_verilog",
  output="CarryAdder.v",
  generator=":spinaltest",
)

the rest of the setup is pretty much copied from the readme on this repo.

I just tried to change

ctx.actions.run(
        executable = ctx.files.generator,
        outputs = [ output, ],
        inputs = ctx.files.generator,
        arguments = [ args ],
        toolchain = None,
    )
attrs = {
        "generator": attr.label(mandatory=True, cfg = "exec", executable = True),
        "output": attr.string(mandatory=True),
        },

but then I'm getting this error: Error in run: in call to run(), parameter 'executable' got value of type 'list', want 'File, string, or FilesToRunProvider' getting the list access back yields

ERROR: C:/work/bazel-scala/BUILD.bazel:18:17: Action CarryAdder.v failed: (Exit -1): spinaltest.jar failed: error executing command (from target //:generate_verilog) bazel-out\x64_windows-opt-exec-2B5CBBC6\bin\spinaltest.jar --verilog -o bazel-out/x64_windows-fastbuild/bin
Action failed to execute: java.io.IOException: ERROR: src/main/native/windows/process.cc(202): CreateProcessW("C:\work\bazel-scala\build-output\execroot\__main__\bazel-out\x64_windows-opt-exec-2B5CBBC6\bin\spinaltest.jar" --verilog -o bazel-out/x64_windows-fastbuild/bin): %1 is not a valid Win32 application.
tjgq commented 8 months ago

Declare the generator attribute as attr.label(cfg = "exec", executable = True, mandatory = True); that should make ctx.executable.generator work. You should also delete the inputs = ctx.files.generator argument to ctx.actions.run (there's no need to specify inputs that are already implied by the executable).

Atridas commented 8 months ago

I tried to do that (see the later part of my previous post) and then bazel is trying to run the .jar file instead of the .exe file

tjgq commented 8 months ago

Does your example work on a Unix platform? i.e., is this a Windows-specific issue, or a more general issue with using a scala_binary as a build tool?

At this point I'm afraid I can't be of further help; someone more familiar with the scala_binary implementation will have to chime in.

Atridas commented 8 months ago

I can't test it on a unix right now, I'll wait until someone else chimes in, thanks for the help anyway @tjgq

Atridas commented 8 months ago

Dumb me, I was still passing ctx.files.generator instead of ctx.executable.generator to the executable field on ctx.actions.run. It all work now. Thank you very much.,