genrule cmd with multiline string

2,187 views
Skip to first unread message

Hu David

unread,
Oct 11, 2015, 10:52:55 PM10/11/15
to bazel-discuss
Hi,

I would like to have multiline string in genrule's cmd.
I tried many but cannot find the correct way to do this.

genrule(
  .....
  cmd = """ echo 123 &&
                  echo abc &&
                  echo def """,
)

Any ideas? Thanks.

David

Kamal Marhubi

unread,
Oct 11, 2015, 11:02:18 PM10/11/15
to Hu David, bazel-discuss

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/fd0cf718-b29a-4a27-a8b6-cabd4cf8ff3c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kamal Marhubi

unread,
Oct 11, 2015, 11:03:11 PM10/11/15
to Hu David, bazel-discuss
(Alternatively, take it all and put it in a script, which you include in the tools attribute.)

Brian Silverman

unread,
Oct 11, 2015, 11:08:53 PM10/11/15
to Kamal Marhubi, Hu David, bazel-discuss
I think you need to get rid of the '&&'s. The whole string (including the '\n's in the middle) gets passed into the shell at once, which means each line is actually a separate line.

In general, I've found '\n'.join([
  'echo 123',
  'echo %s' % 'abc',
]) to be the nicest approach, both for specifying the command directly and as the contents to put into a file if it gets too big.

Hu David

unread,
Oct 12, 2015, 1:03:13 AM10/12/15
to bazel-discuss, ka...@marhubi.com, chi...@gmail.com
Thanks. I'll try both.

Hu David

unread,
Oct 12, 2015, 3:34:24 AM10/12/15
to bazel-discuss, chi...@gmail.com
Kamal Marhubi,

I checked your genrule, what is the purpose of having the parenthesis in Line 23?

If I remove the parenthesis, the copy command next to it will fail. Why is it?

Thanks.

Kamal Marhubi

unread,
Oct 12, 2015, 8:44:07 AM10/12/15
to Hu David, bazel-discuss
David—the parens run that command in a subshell, and that way the change of directory doesn't affect the rest of the command. Without the parens, the cp is running in the wrong directory. I hadn't looked at this before since I was just porting it from the makefile, so thanks for pointing it out! :-)

-Kamal

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.

Alex Humesky

unread,
Oct 13, 2015, 11:40:01 AM10/13/15
to Kamal Marhubi, Hu David, bazel-discuss
Multiline strings should work in the genrule:

genrule(
  name = "gen_txt",
  outs = ["text.txt"],
  cmd = """
echo "hello world" > $@ && \
echo "hello world" >> $@
""")

then:

$ bazel build :gen_txt
INFO: Found 1 target...
Target //:gen_txt up-to-date:
  bazel-genfiles/text.txt
INFO: Elapsed time: 0.418s, Critical Path: 0.06s
$ cat bazel-genfiles/text.txt 
hello world
hello world

You may have been missing the backslash to escape the new lines for the shell, although this also worked for me:

  cmd = """
echo "hello world" > $@
echo "hello world" >> $@
"""

Alex Humesky

unread,
Oct 13, 2015, 11:43:50 AM10/13/15
to Kamal Marhubi, Hu David, bazel-discuss
If your error was "not all outputs were created" or similar, then you just needed to write the output to the outs file or files. If there is one output file, you can use $@ as in the above example. See http://bazel.io/docs/build-encyclopedia.html#genrule.cmd for more details.

Kamal Marhubi

unread,
Oct 13, 2015, 2:15:32 PM10/13/15
to Alex Humesky, Hu David, bazel-discuss

Alex Humesky

unread,
Oct 13, 2015, 2:46:53 PM10/13/15
to Kamal Marhubi, Hu David, bazel-discuss
Note if the command to the genrule gets complicated enough, it may make sense to move the command into a .sh file, write a sh_binary rule, include the sh_binary in the tools attribute of the genrule, and then execute the binary in the genrule command. (py_binary, java_binary, etc, will also work). Then you don't have to have all the ampersands and escaping

Hu David

unread,
Oct 14, 2015, 5:03:15 AM10/14/15
to bazel-discuss, ka...@marhubi.com, chi...@gmail.com
Alex,

I found that my BUILD files were \r\n line break thus I cannot use the following:

cmd = """
echo "hello world" > $@
echo "hello world" >> $@
"""

I fix this by transform the line break to the unix style.
Now, I can use this clean syntax. Thanks.

Kamal Marhubi

unread,
Oct 14, 2015, 12:45:45 PM10/14/15
to Alex Humesky, Hu David, bazel-discuss
On Tue, Oct 13, 2015 at 2:46 PM Alex Humesky <ahum...@google.com> wrote:
Note if the command to the genrule gets complicated enough, it may make sense to move the command into a .sh file, write a sh_binary rule, include the sh_binary in the tools attribute of the genrule

I would probably do this, except that build files for new external repositories cannot refer to targets inside the main repo (yet?).

For now the multiline string is a huge improvement. For some reason I thought they weren't available in the strange Python subset that is the BUILD language.

Lukács T. Berki

unread,
Oct 19, 2015, 4:40:10 AM10/19/15
to Kamal Marhubi, Alex Humesky, Hu David, bazel-discuss
On Wed, Oct 14, 2015 at 6:45 PM, Kamal Marhubi <ka...@marhubi.com> wrote:
On Tue, Oct 13, 2015 at 2:46 PM Alex Humesky <ahum...@google.com> wrote:
Note if the command to the genrule gets complicated enough, it may make sense to move the command into a .sh file, write a sh_binary rule, include the sh_binary in the tools attribute of the genrule

I would probably do this, except that build files for new external repositories cannot refer to targets inside the main repo (yet?).
Now the can :) The corresponding label syntax is "@//foo:bar" . 

For now the multiline string is a huge improvement. For some reason I thought they weren't available in the strange Python subset that is the BUILD language.

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Lukács T. Berki | Software Engineer | lbe...@google.com | 

Google Germany GmbH | Maximillianstr. 11-15 | 80539 München | Germany | Geschäftsführer: Matthew Scott Sucherman, Paul Terence Manicle | Registergericht und -nummer: Hamburg, HRB 86891

Kamal Marhubi

unread,
Oct 19, 2015, 2:35:54 PM10/19/15
to Lukács T. Berki, Alex Humesky, Hu David, bazel-discuss
Oh interesting! Now I just need to think about where it makes sense to put the BUILD files and any other scripts. Probably makes sense under third_party.
Reply all
Reply to author
Forward
0 new messages