Dear Recipient,

This is to inform you that the bug that you reported, bug#39666, has been resolved. The patch is attached for your convenience. Thank you for reporting.

https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39666

-------- Forwarded Message --------
From: "Jannick" <thirdedition <at> gmx.net>
To: <bug-automake <at> gnu.org>
Subject: distcheck for VPATH build: #line directives of generated YACC and LEX
 c-files in tarballs
Date: Tue, 18 Feb 2020 10:59:43 +0100

$ automake --version
automake (GNU automake) 1.16.1

For c-files generated by LEX and YACC in the build process the script ylwrap
takes care, among other things, that the relative file paths in #line
directives are correct.  The generated files are part of distribution
tarballs, where they sit next to their corresponding source YACC or LEX
file; it appears that their #line directives are the same as in the build
process.  This causes an issue when 'make distcheck' is run in a (strict)
VPATH build: In the distribution tarball the relative #line directives
pointing to the source YACC or LEX file are incorrect.

So my question is under the premise of a VPATH build:  Is there a remedy for
the incorrect paths in these #line directives (OTHER THAN running configure
and make in the top src dir)?  Or this is rather a bug in automake to be
fixed?  The documentation appears to be silent about that (or am I missing
something here?)

The attached minimal sample package demonstrates the issue.  Sources sit in
the src subdir. The package was created by 'make distcheck' for a VPATH
build, i.e.:  mkdir bld && cd bld && ../configure  && make && make distcheck
Please check the #line directives in parse.c and scan.c. (I did not have
automake generate corresponding header files.)


Separately, when distcleancheck fails for an elaborate package I find the
part of the error message a bit misleading (sample below).  It could be
interpreted in the way that './share/info/dir' should be uninstalled, too,
which supposedly it should NOT be, since the check passes regardless of the
dir file.  So, it would be great if the dir file could be dropped in the
currently prompted error message. (Of course, it is technically correct to
say that the dir file is left after uninstall.)

ERROR: files left after uninstall:
./path/to/file/forgotten/to/uninstall
./share/info/dir


Many thanks for your insights,
J.

PS: Please cc me in replies. Thanks!

-------- Forwarded Message --------
Subject: [automake-commit] branch master updated: lib/am/distdir.am: strip VPATH srcdir from #line in distributed yacc/lex outputs
Date: Tue, 20 Oct 2026 03:17:39 -0400
From: Kamila Szewczyk <[email protected]>
Reply-To: [email protected], Kamila Szewczyk <[email protected]>
To: [email protected]

This is an automated email from the git hooks/post-receive script.

iczelia pushed a commit to branch master
in repository automake.

View the commit online:
https://git.savannah.gnu.org/gitweb/?p=automake.git;a=commitdiff;h=0631d8b1590db78bcf17568ed34ef05ee08aa64b

The following commit(s) were added to refs/heads/master by this push:
new 0631d8b15 lib/am/distdir.am: strip VPATH srcdir from #line in distributed yacc/lex outputs
0631d8b15 is described below

commit 0631d8b1590db78bcf17568ed34ef05ee08aa64b
Author: Kamila Szewczyk <[email protected]>
AuthorDate: Tue Oct 20 09:17:01 2026 +0200

lib/am/distdir.am: strip VPATH srcdir from #line in distributed yacc/lex outputs * bin/automake.in (%ylwrap_dist_files): New. (lang_yacc_target_hook, lang_lex_target_hook): Record distributed outputs and headers. (handle_dist): Define am__ylwrap_dist_files and YLWRAP-DIST. * lib/am/distdir.am (distdir-am): Strip the $(srcdir)/ prefix from "#line" directives of those files taken from the build directory, preserving their timestamps.
    * t/yacc-lex-vpath-dist-line.sh: New test.
    * t/list-of-tests.mk: Add it.
    * doc/automake.texi (Yacc and Lex): Document it.
    * NEWS: Mention it.
---
 NEWS                          |   5 ++
 bin/automake.in               |  19 ++++-
 doc/automake.texi             |   6 +-
 lib/am/distdir.am             |  15 ++++
 t/list-of-tests.mk            |   1 +
t/yacc-lex-vpath-dist-line.sh | 163 ++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 206 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index e6ff5b66d..1c7e152cd 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,11 @@ New in 1.20 (????-??-??):
   - distcheck now detects symbolic links left in the installation tree
     after uninstall, including dangling links.
 +  - Yacc and lex outputs distributed from a VPATH build no longer carry
+    "#line" directives pointing to their sources through the build-time
+    srcdir, e.g. "../src/parse.y"; the distributed copies now refer to
+    the sources next to them.  (bug#39666)
+
   - dist-zstd now honors numeric ZSTD_CLEVEL values, such as 3, instead
     of treating them as input filenames.  This fixes failed or incorrect
     distribution archives when ZSTD_CLEVEL is set.
diff --git a/bin/automake.in b/bin/automake.in
index d8e37c383..8130a8a93 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -563,6 +563,8 @@ my @dist_common_cond;
 # in some conditions, as [$DISJCONDITIONS, $FILE] pairs.
 my @dist_common_if_present;
 +my %ylwrap_dist_files;
+
 # This is set when 'handle_dist' has finished.  Once this happens,
 # we should no longer push on dist_common.
 my $handle_dist_run;
@@ -663,6 +665,7 @@ sub initialize_per_input ()
     @dist_common = ();
     @dist_common_cond = ();
     @dist_common_if_present = ();
+    %ylwrap_dist_files = ();
     $handle_dist_run = 0;
      @proglist = ();
@@ -4058,6 +4061,11 @@ sub handle_dist ()
     if @if_present;
   $transform{'DIST-IF-PRESENT'} = !!@if_present;
 +  define_pretty_variable ('am__ylwrap_dist_files', TRUE, INTERNAL,
+                         sort keys %ylwrap_dist_files)
+    if %ylwrap_dist_files;
+  $transform{'YLWRAP-DIST'} = !!%ylwrap_dist_files;
+
   # $(am__DIST_COMMON): files to be distributed automatically.  Will be
   # appended to $(DIST_COMMON) in the generated Makefile.
   # Use 'sort' so that the expansion of $(DIST_COMMON) in the generated
@@ -6156,8 +6164,11 @@ sub lang_yacc_target_hook
        # Distribute the generated file, unless its .y source was
        # listed in a nodist_ variable.  (handle_source_transform()
        # will set DIST_SOURCE.)
-       push_dist_common ($header)
-         if $transform{'DIST_SOURCE'};
+       if ($transform{'DIST_SOURCE'})
+         {
+           push_dist_common ($header);
+           $ylwrap_dist_files{$header} = 1;
+         }
        # The GNU rules say that yacc/lex output files should be removed
        # by maintainer-clean.  However, if the files are not distributed,
@@ -6167,6 +6178,8 @@ sub lang_yacc_target_hook
       }
     # See the comment above for $HEADER.
$clean_files{$output} = $transform{'DIST_SOURCE'} ? MAINTAINER_CLEAN : CLEAN;
+    $ylwrap_dist_files{$output} = 1
+      if $transform{'DIST_SOURCE'};
 }
  # This is a lex helper which is called whenever we have decided to
@@ -6179,6 +6192,8 @@ sub lang_lex_target_hook
     # then we want to remove them with "make clean"; otherwise,
     # "make distcheck" will fail.
$clean_files{$output} = $transform{'DIST_SOURCE'} ? MAINTAINER_CLEAN : CLEAN;
+    $ylwrap_dist_files{$output} = 1
+      if $transform{'DIST_SOURCE'};
 }
  # This is a helper for both lex and yacc.
diff --git a/doc/automake.texi b/doc/automake.texi
index e4bcff208..c55334d58 100644
--- a/doc/automake.texi
+++ b/doc/automake.texi
@@ -6542,7 +6542,11 @@ only list the source file.
  The intermediate files generated by @command{yacc} (or @command{lex})
 will be included in any distribution that is made.  That way the user
-doesn't need to have @command{yacc} or @command{lex}.
+doesn't need to have @command{yacc} or @command{lex}.  When these files
+are generated in a VPATH build, their @samp{#line} directives refer to
+the sources through @code{$(srcdir)}; @samp{make dist} removes this
+prefix from the distributed copies, so that they refer to the sources
+next to them.
  If a Yacc source file is seen, then your @file{configure.ac} must
 define the variable @code{YACC}.  This is most easily done by invoking
diff --git a/lib/am/distdir.am b/lib/am/distdir.am
index 76c886f6e..50e36122c 100644
--- a/lib/am/distdir.am
+++ b/lib/am/distdir.am
@@ -230,6 +230,21 @@ if %?DIST-IF-PRESENT%
          || exit 1; \
        done
 endif %?DIST-IF-PRESENT%
+if %?YLWRAP-DIST%
+       @if test "$(srcdir)" != .; then \
+         srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+         list='$(am__ylwrap_dist_files)'; for file in $$list; do \
+           case $$file in "$(srcdir)"/*) continue;; esac; \
+           test -f $$file && test -f "$(distdir)/$$file" || continue; \
+           rm -f "$(distdir)/$$file" \
+           && sed -e "/^#/!b" \
+ -e "s|^\(#[ ]*\(line[ ][ ]*\)\{0,1\}[0-9][0-9]*[ ][ ]*\"\)$$srcdirstrip/|\1|" \
+             $$file >"$(distdir)/$$file" \
+           && touch -r $$file "$(distdir)/$$file" \
+           || exit 1; \
+         done; \
+       fi
+endif %?YLWRAP-DIST%
 ##
 ## Test for directory existence here because a previous automake
 ## invocation might have created some directories.  Note that we
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index 5f4d9313b..9b7bdcb72 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -1357,6 +1357,7 @@ t/yacc-dry.sh \
 t/yacc-grepping.sh \
 t/yacc-grepping2.sh \
 t/yacc-headers-and-dist-pr47.sh \
+t/yacc-lex-vpath-dist-line.sh \
 t/yacc-line.sh \
 t/yacc-misc.sh \
 t/yacc-mix-c-cxx.sh \
diff --git a/t/yacc-lex-vpath-dist-line.sh b/t/yacc-lex-vpath-dist-line.sh
new file mode 100755
index 000000000..1aebcb6fa
--- /dev/null
+++ b/t/yacc-lex-vpath-dist-line.sh
@@ -0,0 +1,163 @@
+#! /bin/sh
+# Copyright (C) 2026 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+# Yacc and lex outputs generated in a VPATH build must not carry
+# "#line" directives pointing through the srcdir into the distribution
+# (automake bug#39666).  The build tree copies must keep them.
+# See also 'yacc-line.sh' and 'lex-line.sh'.
+
+required='cc yacc lex'
+. test-init.sh
+
+cat >> configure.ac << 'END'
+AC_CONFIG_FILES([sub/Makefile])
+AC_PROG_CC
+AC_PROG_YACC
+AC_PROG_LEX
+AC_OUTPUT
+END
+
+mkdir dir sub sub/dir
+
+cat > Makefile.am << 'END'
+AM_LFLAGS = --never-interactive
+SUBDIRS = sub
+noinst_PROGRAMS = foo bar baz
+AM_YFLAGS = -d
+bar_YFLAGS =
+foo_SOURCES = parse.y
+bar_SOURCES = dir/quux.y
+baz_SOURCES = scan.l
+LDADD = $(LEXLIB)
+## Avoid spurious failures with Solaris make.
+parse.@OBJEXT@: parse.c
+bar-quux.@OBJEXT@: bar-quux.c
+END
+
+cat > sub/Makefile.am << 'END'
+AUTOMAKE_OPTIONS = subdir-objects
+AM_LFLAGS = --never-interactive
+noinst_PROGRAMS = foo
+foo_SOURCES = dir/parse.y dir/scan.l
+LDADD = $(LEXLIB)
+## Avoid spurious failures with Solaris make.
+dir/parse.@OBJEXT@: dir/parse.c
+dir/scan.@OBJEXT@: dir/scan.c
+END
+
+cat > parse.y << 'END'
+%{
+int yylex (void) { return 0; }
+void yyerror (const char *s) {}
+%}
+%%
+x : 'x' {};
+%%
+int main (void)
+{
+  return yyparse ();
+}
+END
+
+cp parse.y dir/quux.y
+sed 's/main/sub_main/;s/^int yylex (void).*/int yylex (void);/' parse.y \
+  > sub/dir/parse.y
+echo 'int main (void) { return sub_main (); }' >> sub/dir/parse.y
+
+cat > scan.l << 'END'
+%%
+"END"  return EOF;
+.
+%%
+int main (void)
+{
+  return 0;
+}
+int yywrap (void)
+{
+  return 1;
+}
+END
+
+cat > sub/dir/scan.l << 'END'
+%%
+"END"  return 0;
+.
+%%
+int yywrap (void)
+{
+  return 1;
+}
+END
+
+outputs='parse.c parse.h bar-quux.c scan.c sub/dir/parse.c sub/dir/scan.c'
+
+$ACLOCAL
+$AUTOCONF
+# FIXME: stop disabling the warnings in the 'unsupported' category
+# FIXME: once the 'subdir-objects' option has been mandatory.
+$AUTOMAKE -a -Wno-unsupported
+
+grep '^am__ylwrap_dist_files' Makefile.in sub/Makefile.in
+
+check_dist ()
+{
+  srcdir=$1
+
+  $srcdir/configure
+  $MAKE
+  $MAKE distdir
+  ls -l $distdir $distdir/dir $distdir/sub/dir
+
+  # For debugging.
+  for f in $outputs; do
+    grep '^#.*line' $distdir/$f || :
+  done
+
+  # The build tree copies still point to the srcdir.
+  grep '^#.*line.*"\.\./\.\./sub/dir/parse\.y"' sub/dir/parse.c \
+    || grep "^#.*line.*\"$srcdir/sub/dir/parse\\.y\"" sub/dir/parse.c
+
+  # The distributed copies do not.
+  for f in $outputs; do
+    $EGREP '^#.*line.*"(\.\./|/)' $distdir/$f && exit 1
+  done
+  grep '^#.*line.*"parse\.y"' $distdir/parse.c
+  grep '^#.*line.*"dir/quux\.y"' $distdir/bar-quux.c
+  grep '^#.*line.*"scan\.l"' $distdir/scan.c
+  grep '^#.*line.*"dir/parse\.y"' $distdir/sub/dir/parse.c
+  grep '^#.*line.*"dir/scan\.l"' $distdir/sub/dir/scan.c
+
+  # The header must not be older than its parser.
+  test -z "$(find $distdir/parse.c -newer $distdir/parse.h)"
+
+  $MAKE distcheck
+}
+
+# Relative srcdir.
+mkdir build
+cd build
+check_dist ..
+cd ..
+rm -rf build
+
+# Absolute srcdir.
+mkdir build
+cd build
+check_dist "$(cd .. && pwd)"
+cd ..
+
+:

Attachment: OpenPGP_0xC868F0B6DE38409D.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

Reply via email to