facebook / buck2

Build system, successor to Buck

Home Page:https://buck2.build/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: how to pass dependencies that change state forward across a non-output-changing rule

vindard opened this issue · comments

Description

We've come across an interesting challenge where we have the following situation:

  • Rule A: Has source files as its dependencies and rebuild whenever a source file changes
  • Rule B: Has Rule A as an input and outputs a bin file that never changes even if outputs of Rule A change. It rebuilds, but always with the same output.
  • Rule C: Has Rule B as an input and never rebuilds since the output of Rule B never changes even if Rule A's dependencies changes and it rebuilds

How can we get Rule C to rebuild if Rule A's dependencies change and both Rule A and Rule B correctly rebuild?

Two approaches we've explored:

  1. (Non buck-native approach) Take a hash of Rule A's dependencies and include it in the output of Rule B so that it changes from build to build and re-triggers Rule C
    -> see GaloyMoney/blink#4169

  2. (Buck-native approach) Pass the dependencies of Rule A into Rule C as well to trigger rebuild in a non-Rule-B-dependent way
    -> see GaloyMoney/blink#4172

We've decided to go with the first approach for now since it more accurately reflects the inter-relationship between the rules, but ideally we'd like to figure out if there is some buck-native way to accomplish this without having to hack a changing dependency state in as we've done.

What’s the point of rebuilding B if it’s just going to generate the same output every time?

What’s the point of rebuilding B if it’s just going to generate the same output every time?

It technically doesn't need to be rebuilt after its first build. But it needs to signal to other rules it's an input of, that its own dependencies have changed.

What inputs actually influence the output of B? If it really never changes, then I think you should upload the bin file somewhere, and download it with http_archive(). It sounds like B should not have a dependency on anything, since nothing influences the nature of its output, and instead C should have a direct dependency on A as well as a dependency on B.

It sounds like B should not have a dependency on anything, since nothing influences the nature of its output, and instead C should have a direct dependency on A as well as a dependency on B.

Yup this is the approach we sort of took in GaloyMoney/blink#4172 and now I'm thinking it's probably the correct one for best representing what we have. Closing for now based on this, thanks!