Subject: compilation error: 'S_MAGIC_BCACHEFS' undeclared

From: Bruno Haible <[email-masked]>
Date: Mon, 04 Nov 2024 00:14:16 +0100

Hi,

Building coreutils from source, today, I encountered this compilation error:

  CC       src/stat.o
../src/stat.c: In function 'human_fstype':
../src/stat.c:304:10: error: 'S_MAGIC_BCACHEFS' undeclared (first use in this function); did you mean 'S_MAGIC_TRACEFS'?
  304 |     case S_MAGIC_BCACHEFS: /* 0xCA451A4E local */
      |          ^~~~~~~~~~~~~~~~
      |          S_MAGIC_TRACEFS
../src/stat.c:304:10: note: each undeclared identifier is reported only once for each function it appears in
../src/stat.c:378:10: error: 'S_MAGIC_FUSE' undeclared (first use in this function); did you mean 'S_MAGIC_UFS'?
  378 |     case S_MAGIC_FUSE: /* 0x65735546 remote */
      |          ^~~~~~~~~~~~
      |          S_MAGIC_UFS
../src/stat.c:463:10: error: 'S_MAGIC_PID_FS' undeclared (first use in this function); did you mean 'S_MAGIC_PRL_FS'?
  463 |     case S_MAGIC_PID_FS: /* 0x50494446 local */
      |          ^~~~~~~~~~~~~~
      |          S_MAGIC_PRL_FS
make[2]: *** [Makefile:12874: src/stat.o] Error 1

I understand that the list of S_* macros is meant to be defined in src/fs.h,
which is meant to be autogenerated from src/stat.c.

History:
- In July I had apparently built coreutils in this checkout.
- Now I did a 'git pull', 'make -k distclean', then
  built in a subdir 'build-64' (VPATH build).

The files that I have in this checkout at this point:

$ ls -l src/fs.h src/fs-is-local.h 
-r--r--r-- 1 bruno bruno 4755 Jul 21 18:15 src/fs.h
-r--r--r-- 1 bruno bruno 5157 Jul 21 18:15 src/fs-is-local.h
$ ls -l src/stat.c 
-rw-rw-r-- 1 bruno bruno 57973 Aug 14 14:38 src/stat.c

I tried this:

$ ./configure; make distclean
$ ls -l src/fs.h src/fs-is-local.h 
-r--r--r-- 1 bruno bruno 4755 Jul 21 18:15 src/fs.h
-r--r--r-- 1 bruno bruno 5157 Jul 21 18:15 src/fs-is-local.h

This is normal: since src/fs.h and src/fs-is-local.h are contained in the
tarball, "make distclean" does not remove them.

Now I try a non-VPATH build:

$ ./configure; make
$ ls -l src/fs.h src/fs-is-local.h 
-r--r--r-- 1 bruno bruno 4824 Nov  3 23:39 src/fs.h
-r--r--r-- 1 bruno bruno 5230 Nov  3 23:39 src/fs-is-local.h

This one succeeded, because src/fs.h was regenerated now.

The question thus is: Why was src/fs.h not regenerated in the VPATH build
earlier?

To reproduce this, I
  - remove the 3 entries from src/fs.h,
  - $ touch -d 'Jul 21 18:15' src/fs.h
  - $ mkdir build-64; cd build-64; ../configure; make

What I see is:

1) build-64/src/fs.h has been created, and it contains the 3 entries.

2) In the compilation command, -Isrc occurs before -I../src.

   gcc  -I. -I.. -I./lib  -Ilib -I../lib -Isrc -I../src -Wall   -g -O2 -c -o src/stat.o ../src/stat.c

   Use of option -E shows that despite this ordering of -I options,
   ../src/fs.h gets included. Apparently because it sits in the same
   directory as ../src/stat.c.

So the bug is that fs.h was created in the build directory, not in
the source directory. The GNU Coding Standards
<https://www.gnu.org/prep/standards/html_node/Makefile-Basics.html>
say that the file should be generated in the source directory:

  "GNU distributions usually contain some files which are not source
   files—for example, Info files, and the output from Autoconf, Automake,
   Bison or Flex. Since these files normally appear in the source
   directory, they should always appear in the source directory,
   not in the build directory. So Makefile rules to update them should
   put the updated files in the source directory."

The attached patch fixes this GCS violation and thus fixes the compilation
error.

>From a750d2b575520966e361753d9a0aebf9cc6809c8 Mon Sep 17 00:00:00 2001
From: Bruno Haible <[email-masked]>
Date: Mon, 4 Nov 2024 00:11:40 +0100
Subject: [PATCH] build: Regenerate distributed built files in $(top_srcdir)

* src/local.mk (src/dircolors.h, src/fs-is-local.h, src/fs.h): Generate
in $(top_srcdir).
---
 src/local.mk | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/local.mk b/src/local.mk
index 8133925ac..feea9a6c9 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -521,8 +521,8 @@ clean-local:
 	done

-BUILT_SOURCES += src/dircolors.h
-src/dircolors.h: src/dcgen src/dircolors.hin
+BUILT_SOURCES += $(top_srcdir)/src/dircolors.h
+$(top_srcdir)/src/dircolors.h: src/dcgen src/dircolors.hin
 	$(AM_V_GEN)rm -f $@ $@-t
 	$(AM_V_at)${MKDIR_P} src
 	$(AM_V_at)$(PERL) -w -- $(srcdir)/src/dcgen \
@@ -614,8 +614,8 @@ src/fs-kernel-magic: Makefile src/fs-latest-magic.h
 	  | $(ASSORT) -u						\
 	  > $@-t && mv $@-t $@
 
-BUILT_SOURCES += src/fs-is-local.h
-src/fs-is-local.h: src/stat.c src/extract-magic
+BUILT_SOURCES += $(top_srcdir)/src/fs-is-local.h
+$(top_srcdir)/src/fs-is-local.h: src/stat.c src/extract-magic
 	$(AM_V_GEN)rm -f $@
 	$(AM_V_at)${MKDIR_P} src
 	$(AM_V_at)$(PERL) $(srcdir)/src/extract-magic \
@@ -623,8 +623,8 @@ src/fs-is-local.h: src/stat.c src/extract-magic
 	$(AM_V_at)chmod a-w $@t
 	$(AM_V_at)mv $@t $@
 
-BUILT_SOURCES += src/fs.h
-src/fs.h: src/stat.c src/extract-magic
+BUILT_SOURCES += $(top_srcdir)/src/fs.h
+$(top_srcdir)/src/fs.h: src/stat.c src/extract-magic
 	$(AM_V_GEN)rm -f $@
 	$(AM_V_at)${MKDIR_P} src
 	$(AM_V_at)$(PERL) $(srcdir)/src/extract-magic \
-- 
2.34.1