Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runfiles.go should look at os.Args[0] + ".runfiles" etc. #2359

Closed
phst opened this issue Feb 3, 2020 · 3 comments · Fixed by #3205
Closed

runfiles.go should look at os.Args[0] + ".runfiles" etc. #2359

phst opened this issue Feb 3, 2020 · 3 comments · Fixed by #3205
Labels

Comments

@phst
Copy link
Contributor

phst commented Feb 3, 2020

What version of rules_go are you using?

0.21.2

What version of gazelle are you using?

None

What version of Bazel are you using?

2.0.0

Does this issue reproduce with the latest releases of all the above?

Yes

What operating system and processor architecture are you using?

Debian GNU/Linux, x86-64

Any other potentially useful information about your toolchain?

No

What did you do?

I created the following workspace:

  • BUILD:
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")

go_binary(
    name = "test",
    srcs = ["test.go"],
    data = ["test.txt"],
    deps = ["@io_bazel_rules_go//go/tools/bazel:go_default_library"],
)

genrule(
    name = "genrule",
    outs = ["copy.txt"],
    cmd = "$(location :test) > $@",
    tools = [":test"],
)
  • test.go:
package main

import (
	"io"
	"log"
	"os"

	"github.com/bazelbuild/rules_go/go/tools/bazel"
)

func main() {
	filename, err := bazel.Runfile("test.txt")
	if err != nil {
		log.Fatal(err)
	}
	fd, err := os.Open(filename)
	if err != nil {
		log.Fatal(err)
	}
	defer fd.Close()
	if _, err := io.Copy(os.Stdout, fd); err != nil {
		log.Fatal(err)
	}
}
  • test.txt with arbitrary contents.

Then run bazel build :copy.txt.

What did you expect to see?

Command succeeds

What did you see instead?

could not locate runfiles directory
Target //:copy.txt failed to build

The issue is that Bazel actions don't pass runfiles environment variables, and the current directory is also incorrect. Rather, runfiles.go should look at os.Args[0] + ".runfiles", os.Args[0] + ".runfiles/MANIFEST", and os.Args[0] + ".runfiles_manifest". See the C++ code for comparison: https://github.com/bazelbuild/bazel/blob/master/tools/cpp/runfiles/runfiles_src.cc#L271-L280.

@jayconrod
Copy link
Contributor

It doesn't look like any runfile environment variables are passed to an executable when run by a genrule. The runfiles interface is pretty lightly documented, so I'm not sure if this is because actions are intentionally not supposed to read runfiles, or if they should look for .runfiles directories, or if this is a bug in Bazel or rules_go. Do you know for sure? I don't feel comfortable copying code from the C++ without knowing that's how it's supposed to work.

Because of the lack of any specification, and the fact runfiles work differently on different platforms and in different configurations, I'm hesitant to make changes here.

@phst
Copy link
Contributor Author

phst commented Feb 4, 2020

There's some documentation at https://docs.bazel.build/versions/2.0.0/output_directories.html. Specifically, the lines

                foo/bar/baz               <== foo/bar/baz might be the artifact generated by a cc_binary named
                                              //foo/bar:baz
                foo/bar/baz.runfiles/     <== The runfiles symlink farm for the //foo/bar:baz executable.

imply that the runfiles are at $0.runfiles (assuming nobody messes with $0).

https://docs.bazel.build/versions/2.0.0/skylark/rules.html#tools-with-runfiles also covers this and documents the location relatively well.

@jayconrod
Copy link
Contributor

Thanks, that's helpful. It's been a while since I read through https://docs.bazel.build/versions/2.0.0/skylark/rules.html, but it looks like runfiles are documented better now.

$0.runfiles should work. Marking this as a bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants