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




Reply via email to