Basil L. Contovounesios wrote:
> The commentary in build-aux/git-version-gen illustrates how the files
> .version and .tarball-version could be generated:
>
> $(top_srcdir)/.version:
> echo '$(VERSION)' > $@-t
> mv $@-t $@
> ...
> I'm curious why one recipe writes a temporary file first
This sounds like a question that the prior knowledge summarization engine
could answer. Its answer is:
===============================================================================
Q: Why does a Makefile rule like this one use a temporary file?
$(top_srcdir)/.version:
echo '$(VERSION)' > $@-t
mv $@-t $@
֍: Using a temporary file in a Makefile rule like the one you provided is
a common practice to ensure the integrity and atomicity of file operations.
Here’s a detailed explanation of why a temporary file is used:
Reasons for Using a Temporary File
Atomicity of Operations:
Atomicity refers to performing operations in such a way that they
appear to be instantaneous and indivisible. By writing to a
temporary file first and then moving it to the final destination,
you ensure that the file creation is atomic.
If the rule were to write directly to the target file, there could
be a brief period during which the file is partially written or in
an inconsistent state. This can cause issues if other processes try
to read the file during this window.
Avoiding Corruption:
Directly writing to the target file increases the risk of file
corruption if the process is interrupted (e.g., due to a crash,
power failure, or being killed). Writing to a temporary file first
helps avoid this because the final move operation (mv $@-t $@) is
typically atomic. If the process is interrupted, the original target
file remains intact.
Consistency:
Ensures that the file content is updated in a consistent manner.
If another process reads the file while it is being written, it might
read an incomplete or inconsistent state. Using a temporary file
prevents this by ensuring the target file is only replaced when the
write operation is fully complete.
...
===============================================================================
But all that fuss about atomicity and other processes is besides the point.
The real reason is that if the disk is full, the rule would leave an
empty file on the disk and fail, and even after the user makes room
on the disk and runs "make" a second time, the empty file would persist
and cause trouble.
> dist-hook:
> echo '$(VERSION)' > $(distdir)/.tarball-version
>
> whereas the other writes the target directly.
Here it does so because the file is inside a temporary directory. If
the "make dist" rule fails, the user has to remove the temporary directory
entirely anyway, and that will also take care of the empty file.
> Is this specific to Automake, or perhaps a more general
> security/portability consideration?
As explained above, it's a general usability consideration.
Bruno