2023-01-28

Tools: redo (part 7) The N artefact problem, a minimal example

#software

Content

Part 0: Intro

Part 1: Hello, world!

Part 2: Automatic Recording of Dependencies on Header Files

Part 3: CFLAGS and friends, config.sh, compile.do

Part 4: CFLAGS and friends, env/VAR, default.run.do

Part 5: Auto-update BUILDDATE in version.h

Part 6: The yacc/bison problem: one call produces two artifacts

Part 7: Test: Generator for N source files

My code featured in this series can be found at

https://git.sr.ht/~ew/ew.redo/

I wanted to have something to simulate a call to a code generator, which will produce a number of artefacts, which in turn are needed to build a (generated) hello world executable. And I wanted to build this thing using redo. How hard can it be?

This was not overly complicated. The generator comes in at 71 lines of code. This comes in a bit smaller than the 73 lines of code I needed in all .do snippets together.

Generator

The generator creates N pairs of resource_#.c and resource_#.h files. These are generated at once. The number N is read from a separate file ENV.nmax. These files are generated in a subdirectory, whose name is stored in ENV.tmpdir. The call to the generator is issued by redo itself, just like a call to bison. The state of this affair is recorded in a virtual target file. This file is not used in the code, its content is stamped against redo, such that changes become detectable.

resource_#.c resource_#.h

The generated resources are all the same except for the _#number suffix used in filenames, variable names and strings.

hello.c

These resource files are then included into hello.c, which in turn is generated, too:

It should be easy to see, that all the generated resource files are going to be needed. Please note, that in order to build hello.o from hello.c all resource_#.h files must be generated at this point. This requires a separate hello.o.do file including some magic to record these dependencies:

Calling the generator from redo

The generator is called in a .do snippet called run.generator.do.

The script takes care of the wanted temporary directory, creating it as needed. It then calls the generator and records the state of affairs in its target run.generator. Using wildcards in the md5sum call might record leftover files, if Nmax is reduced. redo clean is your friend.

Copy on change

In order to avoid unneeded rebuilds, the source files consumed by the compiler are copied from the temporary directory. This allows redo to store individual state about every file and flag things as unchanged. There are two separate snippets to copy .c and .h files accordingly:

El Resto

The difference between hello.o.do and default.o.do is, that in hello.o.do a dependency to all resource_#.h files is explicitly listed. Otherwise these files do not exist before gcc is called.

The difference between hello.c.do and default.c.do is that there is no dependency on hello.h ($2.h).

Conclusion

This experiment confirmed, that I have gathered enough puzzle pieces to actually understand this sort of build.

Finally I would like to recommend the use of redo-dot. The resulting diagram has allowed me to clean out a number of leftovers from experimentation. If the diagram looks crook, even if you remove the dottet lines, then the build probably is crook, too.

/file/20230128-redo7-diagram.png

Cheers,

~ew

Home

Proxied content from gemini://ew.srht.site/en/2023/20230128-redo-7.gmi (external content)

Gemini request details:

Original URL
gemini://ew.srht.site/en/2023/20230128-redo-7.gmi
Status code
Success
Meta
text/gemini
Proxied by
kineto

Be advised that no attempt was made to verify the remote SSL certificate.