Is it possible to run a shell command in BUILD file?

12,769 views
Skip to first unread message

linux...@gmail.com

unread,
May 19, 2016, 9:40:37 AM5/19/16
to bazel-discuss
Hi, all

I have a may-be-weird request for bazel to generate a binary with a build timestamp baked in.

In my Go program I can define a variable named "buildTime" and when compiling I can pass

-X main.buildTime=`date -u '+%Y%m%d-%I%M%S%Z'`

it then bake the current system time into the binary.

I know go_library doesn't support the X flag at right now (I can add the feature easily). But what's the best way to specify the time in a BUILD file? What I am looking for looks like:

go_binary(
name = "my_bin",
srcs = glob(["main.go"]),
x-def = [
"main.buildTime=$(date -u '+%Y%m%d-%I%M%S%Z')",
"main.commitID=$(git rev-parse --short HEAD)",
],
)

Is it possible?

Thanks!

Justine Tunney

unread,
May 19, 2016, 10:55:17 AM5/19/16
to linux...@gmail.com, bazel-discuss
You can run shell commands using genrule.

genrule(
    name = "hello_gen",
    outs = ["hello.txt"],
    cmd = "echo hello world >$@",
)

But you almost certainly do not want to add a timestamp to any files or binaries that you generate. That would introduce nondeterminism. Bazel is written under the assumption that for a given set of inputs, a specific set of outputs will always be created. If that assumption is broken, Bazel could have unexpected behavior.

Do ensure that tools run by a genrule are deterministic and hermetic. They should not write timestamps to their output, and they should use stable ordering for sets and maps, as well as write only relative file paths to the output, no absolute paths. Not following this rule will lead to unexpected build behavior (Bazel not rebuilding a genrule you thought it would) and degrade cache performance. http://bazel.io/docs/be/general.html


--
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/310527b4-fd21-4b49-8e7a-2cbfa26ab302%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

linux...@gmail.com

unread,
May 19, 2016, 11:53:05 AM5/19/16
to bazel-discuss, linux...@gmail.com
Thank you for the reply, Justine.

I fully understand and appreciate bazel's design principle on deterministic and hermetic. But, there are still use cases a build-time dependant value is useful. Above all, even bazel command itself supports "bazel version" which contains a build timestamp, right?

Justine Tunney

unread,
May 19, 2016, 12:19:02 PM5/19/16
to linux...@gmail.com, bazel-discuss
One feature of java_binary(name = "foo") is that you can build a special jar using bazel build //:foo_deploy.jar which puts all transitive jars into a single jar with a build-data.properties file containing the timestamp. That's what bazel version uses. As far as I know rules_go doesn't have that functionality, so you might want to file a feature request.

On Thu, May 19, 2016 at 11:53 AM, <linux...@gmail.com> wrote:
Thank you for the reply, Justine.

I fully understand and appreciate bazel's design principle on deterministic and hermetic. But, there are still use cases a build-time dependant value is useful. Above all, even bazel command itself supports "bazel version" which contains a build timestamp, right?
--
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.

linux...@gmail.com

unread,
May 19, 2016, 12:21:54 PM5/19/16
to bazel-discuss, linux...@gmail.com
Will do. Thank you!

Austin Schuh

unread,
May 19, 2016, 12:23:59 PM5/19/16
to Justine Tunney, linux...@gmail.com, bazel-discuss
Bazel uses stamping to add timestamps and machine specific information to a build.  This stamping is disabled for tests, for example, to make them easier to cache.  This information is treated carefully, and is linked in at the end.

Austin

linux...@gmail.com

unread,
May 19, 2016, 12:28:11 PM5/19/16
to bazel-discuss, ja...@google.com, linux...@gmail.com
rules_go has an unused attr "stamp": https://github.com/bazelbuild/rules_go/blob/master/go/def.bzl#L511

Is it intended for the same purpose?

Justine Tunney

unread,
May 19, 2016, 12:30:58 PM5/19/16
to Zhong Wang, bazel-discuss
As a workaround, you could use a genrule() to mutate the Go binary once it's been created. For example, it might be possible to define a string in your program like "XX:XX:XXTXX:XX:XXZ" (which is a template for an ISO-8601 zulu timestamp) and then say:

genrule(
    name = "app_deploy",
    srcs = ["app"],
    outs = ["app_deploy"],
    cmd = "sed -e s/
XX:XX:XXTXX:XX:XXZ
/$(TZ=UTC date +%Y-%m-%dT%H:%M:%SZ)/ <$< >$@",
    executable = True,
)

Even though it introduces nondeterminism, it probably wouldn't be so bad, since no other rules would be depending on :app_deploy

On Thu, May 19, 2016 at 12:21 PM, <linux...@gmail.com> wrote:
Will do. Thank you!


--
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.

Justine Tunney

unread,
May 19, 2016, 12:31:35 PM5/19/16
to Zhong Wang, bazel-discuss
Correction: $$(TZ=...

Austin Schuh

unread,
May 19, 2016, 12:33:32 PM5/19/16
to linux...@gmail.com, bazel-discuss, ja...@google.com
I'm not the author of the rules_go rules, but that matches the stamp pattern implemented by all the other bazel rules and was likely the intent.

On Thu, May 19, 2016 at 9:28 AM <linux...@gmail.com> wrote:
rules_go has an unused attr "stamp": https://github.com/bazelbuild/rules_go/blob/master/go/def.bzl#L511

Is it intended for the same purpose?

--
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.

linux...@gmail.com

unread,
May 19, 2016, 12:39:15 PM5/19/16
to bazel-discuss, linux...@gmail.com, ja...@google.com
Thank you guys, it's so helpful.

Ross Light

unread,
May 23, 2016, 3:40:24 PM5/23/16
to bazel-discuss
If someone were to add stamp support to the go_binary rules, they should use the -X flag to `go tool link`. docs

linux...@gmail.com

unread,
May 23, 2016, 4:51:30 PM5/23/16
to bazel-discuss
On Monday, May 23, 2016 at 12:40:24 PM UTC-7, Ross Light wrote:
> If someone were to add stamp support to the go_binary rules, they should use the -X flag to `go tool link`. docs

Yes, we are on it: https://github.com/bazelbuild/rules_go/pull/27

Marc Guilera

unread,
Jan 19, 2019, 4:29:44 PM1/19/19
to bazel-discuss

Hey! How can i run a bash script to integrate with other build systems? 

For example: The serverless framework CLI. 
Reply all
Reply to author
Forward
0 new messages