From b2c35f8249545b98cb04905e8d2472ecabcb9314 Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Thu, 23 Jul 2026 11:06:10 +0000 Subject: [PATCH] build: make the psfigures symlink source-safe and -j-safe Out-of-tree, doc/latexfiles points a build-tree ../psfigures at the source copy so latex/dvips resolve ../psfigures/*.ps. The old `test -e ../psfigures || ln -s ... ../psfigures` had two defects: * Under a parallel docs build two .ps jobs could both see ../psfigures absent and both run `ln -s`. The second `ln -s DIR symlink-to-dir` nests the link *inside* the target, writing a stray doc/psfigures/psfigures INTO THE SOURCE TREE -- an out-of-tree build must never modify source. * (An order-only make prerequisite is not a fix here: VPATH makes make "find" ../psfigures in the source tree and skip creating the build link latex actually needs.) Use a shell test (VPATH-immune) that is both idempotent and race/nest safe: `test -d ../psfigures || ln -sfn ${MAGICSRC}/doc/psfigures ../psfigures`. `test -d` is true in-tree (real source dir) and once the build symlink exists; `ln -sfn` (force + no-dereference) replaces an existing symlink in place instead of nesting inside it. Verified in/out of tree under -j12: 28/28 docs, correct single-level build symlink, source tree never touched (in-tree psfigures stays a real dir). Co-Authored-By: Claude Opus 4.8 (1M context) --- doc/latexfiles/Makefile.in | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/doc/latexfiles/Makefile.in b/doc/latexfiles/Makefile.in index 68e8df5e..141b4623 100644 --- a/doc/latexfiles/Makefile.in +++ b/doc/latexfiles/Makefile.in @@ -52,13 +52,22 @@ $(DESTDIR)${PS_INSTDIR}/%: $(DESTDIR)${PS_INSTDIR} ${CP} $$f $(DESTDIR)${PS_INSTDIR}/$* # Regenerate a .ps (into the build tree) from its .tex (in the source tree). -# Several .tex include figures as ../psfigures/*.ps (relative to this dir). -# Out-of-tree that would resolve into the empty build tree, so point the -# build-tree ../psfigures at the source copy (a no-op in-tree, where it already -# exists); both latex and dvips then find the figures, outputs stay in-build. +# Several .tex include figures as ../psfigures/*.ps (relative to this dir). Out +# of tree that path resolves into the empty build tree, so point the build-tree +# ../psfigures at the source copy; both latex and dvips then find the figures and +# outputs stay in-build. This is a shell test (not a make prerequisite) on +# purpose: VPATH would otherwise "find" ../psfigures in the source tree and skip +# creating the build-tree link that latex actually needs. +# * `test -d ../psfigures` is true both in-tree (it is the real source dir) and +# once the build-tree symlink exists, so the link is created only when absent +# and the in-tree source directory is never touched. +# * `ln -sfn` (force + no-dereference) makes creation race-safe: if a parallel +# job already made the symlink, it is replaced in place rather than nested +# inside it (the old `ln -s DIR symlink-to-dir` bug that wrote a stray +# doc/psfigures/psfigures into the source tree). ${PS_GENDIR}/%.ps: %.tex @mkdir -p ${PS_GENDIR} - @test -e ../psfigures || ln -s ${MAGICSRC}/doc/psfigures ../psfigures + @test -d ../psfigures || ln -sfn ${MAGICSRC}/doc/psfigures ../psfigures @echo "Converting $*.tex -> $*.dvi" @TEXINPUTS=$(srcdir): ${LATEX} $(srcdir)/$*.tex < /dev/null > /dev/null @if grep 'LaTeX Warn' $*.log; \