Reputation: 37105
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
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