\out do need something create "foo" somehow ...">

Adding system actions should change the history of the rules

I have a rule like this:

"foo" *> \out do
  need something
  create "foo" somehow

      

It's built correctly and doing the build twice won't create a target. Then I add system 'to this rule:

"foo" *> \out do
  ...
  system' something

      

Running shake now does not restore the target "foo" because no dependencies have changed. In any case, the rule has changed. So I expect that the action of the newly added system will change the history of the rule and, in turn, lead to the restoration of "foo", but this was not the case. Typically, on autoconf / automake systems, or even in non-trivial makefiles, the rules depend on the Makefile itself, so that whenever it changes, the project is rebuilt. In Shake, I expect it to work and be shallow.

In the source code of the system, "I don't see anything that adds an implicit dependency on the command being executed.

Am I doing something wrong? Is it intentional not to support such dependencies, or is it just not implemented?

+3


source to share


1 answer


The behavior you see is expected and ICFP 2012 Document S6.2 describes some strategies for dealing with it. It would be ideal if each output depended on the rule used to create it, but this requires some equality over the rules (which are just functions whose source code is not available at runtime). One day I hope Shake will work as you describe, but I don't think it is possible at the moment at GHC.

To minimize the number of build system changes, it is best to keep whatever you think will change on a regular basis from the build system. Any list of files (such as what files are needed to link the C executable) can be placed in the config files or depend on the correct use of the oracle engine.

Of course, the rules will still change from time to time, and there are two approaches you can take:

Restore everything if something changes



A simple conservative approach taken by many Makefiles is to rebuild everything if something changes. An easy way to implement this strategy is to hash the Shake scripts and use that as a field shakeVersion

. For projects that recover quickly enough, this may work well.

Rebuild with manual control

For large projects, the build system is often used on a daily basis, but most parts of the build system do not affect most of the rules. For some rules I would explicitly have need

some source files in the rule, for example if there is a large generator in the file, I would need

have that in the rule that creates the generated output. If you also use the writeFileChanged

generated file to write, then many modifications to the generator will result in a minimal rebuild.

If the changes are more invasive, I manually increase the shakeVersion field and force the full rebuild to complete. In a mature build system with proper dependency tracking, this event might only occur a few times a year.

+1


source







All Articles