sdgfsdh
sdgfsdh

Reputation: 37105

Bazel Make variable substitution for the package root?

Suppose I have a Bazel project like this:

tree .
.
├── foo
│   ├── BUILD.bazel
│   └── foo.txt
└── WORKSPACE

1 directory, 3 files

foo/BUILD.bazel:

genrule(
  name = "bar",
  srcs = [
    "foo.txt",
  ],
  cmd = "cp foo.txt $@",
  outs = [
    "bar.txt",
  ],
)

I cannot build bazel build //foo:bar:

bazel build //foo:bar

...

cp: cannot stat 'foo.txt': No such file or directory

It appears that paths in cmd must be relative to the WORKSPACE root, rather than the BUILD root.

This works:

genrule(
  name = "bar",
  srcs = [
    "foo.txt",
  ],
  # cmd = "cp foo.txt $@",
  cmd = "cp foo/foo.txt $@",
  outs = [
    "bar.txt",
  ],
)

It's inconvenient to have to specify the full path, particularly when BUILD files might be moved around.

It is also nice to be able to write scripts as if they run from their location in the source-tree (of course they are actually run in the sandbox!)

Is there a Make variable substitution that would allow me to specify this more cleanly?

For example:

genrule(
  name = "bar",
  srcs = [
    "foo.txt",
  ],
  cmd = "cd $(SRCDIR) && cp foo.txt $@",
  outs = [
    "bar.txt",
  ],
)

Here $(SRCDIR) could expand to ./foo.

Note that this is a contrived example. I cannot use $(SRCS) since I need to use the input files in different ways. I also cannot use $< since I have more than once srcs.

Upvotes: 1

Views: 4943

Answers (1)

Ray
Ray

Reputation: 986

Yes, there are such Make variables. In this particular case $< is the most convenient, so the rule declaration will look like this:

    genrule(
      name = "bar",
      srcs = ["foo.txt"],
      outs = ["bar.txt"],
      cmd = "cp $< $@",
    )

$< can be used if there is only one file in srcs. If there are more of them, then consider using $(SRCS) which will expand in space-separated inputs from srcs.

Also, there are predefined path substitutions, such as $(execpath) and $(rootpath) which expand labels to their full paths. So, the snippet mentioned above will look similar to this:

    genrule(
      name = "bar",
      srcs = ["foo.txt"],
      outs = ["bar.txt"],
      cmd = "cp $(execpath foo.txt) $@",
    )

And there is $(location) expansion which is synonym for either execpath or rootpath (depending on the context) but it's legacy and using it is not recommended.

Here you can check the official docs on Make variables in Bazel: https://docs.bazel.build/versions/2.0.0/be/make-variables.html

Upvotes: 1

Related Questions