Make bazel always rebuild a target indiscriminately

3,782 views
Skip to first unread message

Chris Brown

unread,
Dec 9, 2016, 4:12:13 PM12/9/16
to bazel-discuss
Does bazel have an equivalent to make's `PHONY` functionality? I'd like to be able to create a dependency that is always rebuilt regardless of the cache status. The reason I'd like to do this is the target is a genrule that needs to be rebuilt only when some hard-to-detect environment conditions change. I can't put these dependency conditions into the bazel target, and the target is fast to build, so the easiest thing to do is just tell Bazel that the target is always out of date. Is this possible?

Justine Tunney

unread,
Dec 9, 2016, 4:44:24 PM12/9/16
to Chris Brown, bazel-discuss
Out of curiosity, what environmental conditions does your genrule depend on?

On Fri, Dec 9, 2016 at 1:12 PM, Chris Brown <chris...@zoox.com> wrote:
Does bazel have an equivalent to make's `PHONY` functionality? I'd like to be able to create a dependency that is always rebuilt regardless of the cache status. The reason I'd like to do this is the target is a genrule that needs to be rebuilt only when some hard-to-detect environment conditions change. I can't put these dependency conditions into the bazel target, and the target is fast to build, so the easiest thing to do is just tell Bazel that the target is always out of date. Is this possible?

--
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-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/4471b6db-e9f4-4ffb-872b-c891143097c0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chris Brown

unread,
Dec 9, 2016, 5:28:31 PM12/9/16
to bazel-discuss

Well, to give a bit more details of the real problem:

I have a codegen step that extracts information from git - for example, the working tree status, git sha, etc. Other targets can then depend on the output and get some codegen'd const variables that they can embed in their executables.

The true semantics of the build dependency are "Rebuild this target if the output of the shell command `git diff-index --quiet HEAD` is not zero". (It's actually slightly more complicated because this won't catch untracked files, but this catches most changes in the git working tree). As far as I know there is no way to use a command output as a dependency though. I could make a genrule that outputs the command to a file and then depend on that file, but then I'm back where I started needing the new genrule to run every time. Can I do what I want here?

On Friday, December 9, 2016 at 1:44:24 PM UTC-8, Justine Tunney wrote:
Out of curiosity, what environmental conditions does your genrule depend on?
On Fri, Dec 9, 2016 at 1:12 PM, Chris Brown <chris...@zoox.com> wrote:
Does bazel have an equivalent to make's `PHONY` functionality? I'd like to be able to create a dependency that is always rebuilt regardless of the cache status. The reason I'd like to do this is the target is a genrule that needs to be rebuilt only when some hard-to-detect environment conditions change. I can't put these dependency conditions into the bazel target, and the target is fast to build, so the easiest thing to do is just tell Bazel that the target is always out of date. Is this possible?

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

Brian Silverman

unread,
Dec 9, 2016, 5:51:39 PM12/9/16
to Chris Brown, bazel-discuss
tags = ['external'] sounds like what you're asking for.

However, for adding repository status information, have you looked at Bazel's stamping support? It automatically handles rebuilding dependent rules with the newest information only when they're being rebuilt anyways. It also helpfully defaults to not stamping tests to minimize recompilation. I find it works well for recording the git revision and whether the tree has been modified or not. Recording the hostname code was built on can come in handy for tracking down git revisions that never make it into master.

If you're interested in the builtin stamping, tools/buildstamp/get_workspace_status in bazel's source tree is a good starting point. --workspace_status_command=tools/buildstamp/get_workspace_status will use it, and I think you have to pass --stamp=yes too. genrules need to be marked stamp = True explicitly and then they can read bazel-out/volatile-status.txt and bazel-out/stable-status.txt. For C/C++ a file listed in the linkstamp attr of a cc_library will have BUILD_SCM_REVISION, BUILD_SCM_STATUS, etc defined when it's compiled. There's something with .properties files for Java rules too, but I've never used it.

To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/94c624a1-b303-4068-ad51-dfc38eeb3b34%40googlegroups.com.

Justine Tunney

unread,
Dec 11, 2016, 1:03:01 AM12/11/16
to Chris Brown, bazel-discuss
Have you considered having files like ".git/HEAD" be srcs for your genrule?

The true semantics of the build dependency are "Rebuild this target if the output of the shell command `git diff-index --quiet HEAD` is not zero". 

If you need to rely on the git object graph to invalidate your bazel build graph, you might be working around the fact that your bazel build is not hermetically sealed.

To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/94c624a1-b303-4068-ad51-dfc38eeb3b34%40googlegroups.com.

Brian Silverman

unread,
Dec 11, 2016, 1:43:58 AM12/11/16
to Justine Tunney, Chris Brown, bazel-discuss
On Sun, Dec 11, 2016 at 1:02 AM, 'Justine Tunney' via bazel-discuss <bazel-...@googlegroups.com> wrote:
Have you considered having files like ".git/HEAD" be srcs for your genrule?

To (hopefully) save somebody else some trouble: from past experience (before I started using stamping), it's way more complicated than that. .git/HEAD for most people always says "ref: refs/heads/master" or something, before and after you make a new commit. glob(['.git/refs/**']) gets closer, but then you run into packed-refs once you repository gets old enough for an auto-gc. Even including all of glob(['.git/**']) or something, which gets really slow, it still misses changing a source file, which affects the output of diffs against the working tree. glob(['**']) is annoying to work with too; it likes recursing into all kinds of places it shouldn't, among them the convenience symlinks.
Reply all
Reply to author
Forward
0 new messages