git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] Don't write directly to a make target ($@).

From
Jim Meyering <jim@meyering.net>
Date
May 25, 2006, 16:52 UTC
Message-ID
<87veru3v4e.fsf@rho.meyering.net>
In-Reply-To
<7vejyixe5g.fsf@assigned-by-dhcp.cox.net>
Junio C Hamano <junkio@cox.net> wrote:
Show 28 quoted lines
> Jim Meyering <jim@meyering.net> writes:
>
>> Otherwise, if make is suspended, or killed with prejudice, or if the
>> system crashes, you could be left with an up-to-date, yet corrupt,
>> generated file.
>
> Thanks.  Maybe you would want a "make clean" target for them too
> if you do this.  I often use $@+ instead of t$@ so that I can
> say "rm -f *+" there.
>
>> @@ -496,37 +496,43 @@ builtin-help.o: common-cmds.h
>>  	rm -f $@ && ln git$X $@
>>
>>  common-cmds.h: Documentation/git-*.txt
>> -	./generate-cmdlist.sh > $@
>> +	./generate-cmdlist.sh > t$@
>> +	mv t$@ $@
>>
>
> IOW, like this:
>
> common-cmds.h: Documentation/git-*.txt
> 	rm -f $@+ $@
>         ./generate-cmdlist.sh > $@+
>         mv $@+ $@
>
> clean::
> 	rm -f *+
I've included a revised patch below.

I left off the `clean' addition, because I believe "make clean" should not remove wildcard patterns like "*+", on the off-chance that someone uses names like that for files they care about. Besides, in practice, those temporary files are left behind so rarely that they're not a bother, and they're removed again as part of the next build.

---------
Subject: [PATCH] Don't write directly to a make target ($@).  Update atomically.

Otherwise, if make is killed with prejudice, or if the system crashes, you could be left with an up-to-date, yet corrupt generated file.

---
 Makefile |   34 ++++++++++++++++++++--------------
 1 files changed, 20 insertions(+), 14 deletions(-)
620173525c5075f2056af107a85881d0d50d3a89
diff --git a/Makefile b/Makefile
index dbf19c6..04536f6 100644
--- a/Makefile
+++ b/Makefile
@@ -496,37 +496,43 @@ builtin-help.o: common-cmds.h
 	rm -f $@ && ln git$X $@
 
 common-cmds.h: Documentation/git-*.txt
-	./generate-cmdlist.sh > $@
+	./generate-cmdlist.sh > $@+
+	mv $@+ $@
 
 $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
-	rm -f $@
+	rm -f $@ $@+
 	sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
 	    -e 's/@@NO_CURL@@/$(NO_CURL)/g' \
 	    -e 's/@@NO_PYTHON@@/$(NO_PYTHON)/g' \
-	    $@.sh >$@
-	chmod +x $@
+	    $@.sh >$@+
+	chmod +x $@+
+	mv $@+ $@
 
 $(patsubst %.perl,%,$(SCRIPT_PERL)) : % : %.perl
-	rm -f $@
+	rm -f $@ $@+
 	sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-	    $@.perl >$@
-	chmod +x $@
+	    $@.perl >$@+
+	chmod +x $@+
+	mv $@+ $@
 
 $(patsubst %.py,%,$(SCRIPT_PYTHON)) : % : %.py
-	rm -f $@
+	rm -f $@ $@+
 	sed -e '1s|#!.*python|#!$(PYTHON_PATH_SQ)|' \
 	    -e 's|@@GIT_PYTHON_PATH@@|$(GIT_PYTHON_DIR_SQ)|g' \
 	    -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
-	    $@.py >$@
-	chmod +x $@
+	    $@.py >$@+
+	chmod +x $@+
+	mv $@+ $@
 
 git-cherry-pick: git-revert
-	cp $< $@
+	cp $< $@+
+	mv $@+ $@
 
 git-status: git-commit
-	cp $< $@
+	cp $< $@+
+	mv $@+ $@
 
 # These can record GIT_VERSION
 git$X git.spec \
@@ -653,7 +659,8 @@ install-doc:
 ### Maintainer's dist rules
 
 git.spec: git.spec.in
-	sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@
+	sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@+
+	mv $@+ $@
 
 GIT_TARNAME=git-$(GIT_VERSION)
 dist: git.spec git-tar-tree
@@ -724,4 +731,3 @@ check-docs::
 		*) echo "no link: $$v";; \
 		esac ; \
 	done | sort
-
-- 
1.3.2
Previous: Jim Meyering
Message 6 of 6 in “Don't write directly to a make target ($@).”
  1. Don't write directly to a make target ($@).Jim Meyering, May 25, 2006
  2. Junio C HamanoMay 25, 2006
  3. Timo HirvonenMay 25, 2006
  4. Jim MeyeringMay 25, 2006
  5. Jim MeyeringMay 25, 2006
  6. Jim MeyeringMay 25, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.