[Bug 263530] devel/elfutils: Fails to build with GCC 11: ebl_syscall_abi.c:37:64: error: argument 5 of type 'int *' declared as a pointer [-Werror=array-parameter=]

From: <bugzilla-noreply_at_freebsd.org>
Date: Wed, 27 Nov 2024 09:35:27 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263530

John Hein <jcfyecrayz@liamekaens.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bofh@freebsd.org

--- Comment #9 from John Hein <jcfyecrayz@liamekaens.com> ---
(In reply to Yuri Victorovich from comment #4)
"... the current version fails with gcc, even with gcc-10:
https://sourceware.org/bugzilla/show_bug.cgi?id=29158 ..."

TLDR; See [[1]]

Longer explanatory read...

That bug [(filed as a problem with elfutils) describes this build failure with
gcc11:

In file included from color.c:34:
/usr/local/share/gnulib/lib/argp.h:583:3: error: #error "Please include
config.h first."
  583 |  #error "Please include config.h first."
  .
  .

The underlying cause is that gcc11 (and gcc10 and gcc12) decide that despite
the "-I/usr/local/include -I/usr/local/share/gnulib/lib" args to the
compilation line, gcc decides to put /usr/local/share/gnulib/lib ahead of
/usr/local/include in the search path.

That bug was closed upstream because it was [paraphrasing] "not a elfutils
problem, so WONTFIX".  That seems to be true - the issue is due to a quirk of
gcc (to be fair to the upstream bug responder, it was not very clearly spelled
out in the bug thread that there are two argp.h files involved).

It seems to be the case that because gcc was built with --prefix /usr/local, it
decides that the include search of /usr/local/include should be searched AFTER
the builtin search path for system directories (or put another way, it sees
/usr/local/include as a system directory, so it ignores the
-I/usr/local/include specified by the user because it knows that
/usr/local/include will be searched as a system directory).  This is exposed if
you add "-v" to the build line:

========================
gcc11 -D_GNU_SOURCE -DHAVE_CONFIG_H '-DLOCALEDIR="/usr/local/share/locale"' -I.
-I.. -I. -I. -I../lib -I.. -I./../libelf '-std=gnu99' -Wall -Wshadow
'-Wformat=2' -Wold-style-definition -Wstrict-prototypes -Wtrampolines
-Wlogical-op -Wduplicated-cond -Wnull-dereference '-Wimplicit-fallthrough=5'
-Werror -Wunused -Wextra '-Wstack-usage=262144' -fPIC '-D_FORTIFY_SOURCE=3' -O2
-pipe -I/usr/local/include -I/usr/local/share/gnulib/lib -DFREEBSD_HAS_MEMPCPY
-Wno-error -Wno-format-nonliteral -Wno-null-dereference -Wno-unused-value
-fstack-protector-strong -fno-strict-aliasing -MT color.o -MD -MP -MF
.deps/color.Tpo -c -o color.o color.c -v
  .
  .
ignoring nonexistent directory
"/usr/local/lib/gcc11/gcc/x86_64-portbld-freebsd13.4/11.5.0/include-fixed"
ignoring nonexistent directory
"/usr/local/lib/gcc11/gcc/x86_64-portbld-freebsd13.4/11.5.0/../../../../../x86_64-portbld-freebsd13.4/include"
ignoring duplicate directory "."
ignoring duplicate directory "."
ignoring duplicate directory "../lib"
ignoring duplicate directory ".."
ignoring duplicate directory "/usr/local/include"
  as it is a non-system directory that duplicates a system directory
#include "..." search starts here:
#include <...> search starts here:
 .
 ..
 ./../libelf
 /usr/local/share/gnulib/lib
 /usr/local/lib/gcc11/gcc/x86_64-portbld-freebsd13.4/11.5.0/include
 /usr/local/include
 /usr/include
End of search list.
In file included from color.c:34:
/usr/local/share/gnulib/lib/argp.h:583:3: error: #error "Please include
config.h first."
  583 |  #error "Please include config.h first."
      |   ^~~~~
========================

Notice the message: 'ignoring duplicate directory "/usr/local/include"'

Because of that quirk, gcc11 includes /usr/local/share/gnulib/lib/argp.h (from
the gnulib port) instead of the desired /usr/local/lib/argp.h (from the
argp-standalone port)... despite the explicit ordering specified on the command
line.

This could be construed as a bug in gcc, although it's subtle. And maybe it is
documented to behave that way intentionally - the gcc.info "Options for
Directory Search" section has language that might indicate it treats
/usr/local/include as a "standard system directory" which could be interpreted
to explain this behavior as intentional.  I think that adding
-I/usr/local/include on the command line should be enough to tell gcc that the
user clearly wants that directory ahead of other -I directories.  That gcc.info
documentation says:

"However, you should not use this option [-I] to add directories that contain
vendor-supplied system header files; use ‘-isystem’ for that."

From that documentation, it's not clear what it will do if you DO use -I with
directories that gcc has been configured to understand as directories
containing system header files.  As it turns out, it currently removes that -I
directory as a duplicate - hardly a clear / expected implementation detail
given that documentation, nor (arguably) perhaps a particularly well conceived
one.  If one "should not use" -I in that way, then the result of doing so
should be spelled out clearly (and treated at run-time as a exceptional case
providing a clear warning of the usage violation at run-time).

clang does not alter the search path that is spelled out on the command line -
neither /usr/bin/clang nor /usr/local/bin/clang18.  output snippet from using
/usr/local/bin/clang18 shown here:

========================
  .
  .
ignoring duplicate directory "."
ignoring duplicate directory "."
ignoring duplicate directory "../lib"
ignoring duplicate directory ".."
#include "..." search starts here:
#include <...> search starts here:
 .
 ..
 ./../libelf
 /usr/local/include
 /usr/local/share/gnulib/lib
 /usr/local/llvm18/lib/clang/18/include
 /usr/include
End of search list.
========================


A workaround to allow this port to build with gcc is to use -isystem instead of
-I [[1]]:

========================
gcc11 -D_GNU_SOURCE -DHAVE_CONFIG_H '-DLOCALEDIR=/usr/local/share/locale' -I.
-I.. -I. -I. -I../lib -I.. -I./../libelf '-std=gnu99' -Wall -Wshadow
'-Wformat=2' -Wold-style-definition -Wstrict-prototypes -Wtrampolines
-Wlogical-op -Wduplicated-cond -Wnull-dereference '-Wimplicit-fallthrough=5'
-Werror -Wunused -Wextra '-Wstack-usage=262144' -fPIC '-D_FORTIFY_SOURCE=3' -O2
-pipe -I/usr/local/include -I/usr/local/share/gnulib/lib -DFREEBSD_HAS_MEMPCPY
-Wno-error -Wno-format-nonliteral -Wno-null-dereference -Wno-unused-value
-fstack-protector-strong -fno-strict-aliasing -MT color.o -MD -MP -MF
.deps/color.Tpo -c -o color.o color.c -v
  .
  .
ignoring duplicate directory "/usr/local/include"
ignoring nonexistent directory
"/usr/local/lib/gcc11/gcc/x86_64-portbld-freebsd13.4/11.5.0/include-fixed"
ignoring nonexistent directory
"/usr/local/lib/gcc11/gcc/x86_64-portbld-freebsd13.4/11.5.0/../../../../../x86_64-portbld-freeb
sd13.4/include"
ignoring duplicate directory "."
ignoring duplicate directory "."
ignoring duplicate directory "../lib"
ignoring duplicate directory ".."
#include "..." search starts here:
#include <...> search starts here:
 .
 ..
 ./../libelf
 /usr/local/include
 /usr/local/share/gnulib/lib
 /usr/local/lib/gcc11/gcc/x86_64-portbld-freebsd13.4/11.5.0/include
 /usr/include
End of search list.
========================

This include directory search path ordering subtlety also explain why ports
2b0e78b7b9cb84 reverted the addition of USES=localbase asserting "Somehow this
breaks the build" and added a comment saying the CFLAGS setting is "synonymous
to USES=localbase" (it's not quite so). Although the specific log of the
failure that was observed was not included in the commit log at that time, it
appears to be the same problem including the wrong argp.h.

In that case the compiler command line had include search path arguments like
so: '-I/usr/local/share/gnulib/lib -isystem /usr/local/include'.  In this case
the ordering problem is more clear (and any -I vs. -isystem distinction is not
as relevant), and it fails for both clang and gcc.  That committer is CC'd here
(mostly just for information than a request for any particular action... unless
desired).

[[1]] So here is a patch that works for CC=gcc11 or CC=clang:

========================
--- a/devel/elfutils/Makefile
+++ b/devel/elfutils/Makefile
@@ -22,10 +22,8 @@ BUILD_DEPENDS=       gnulib>=0:devel/gnulib

 PLIST_SUB=     VERSION=${PORTVERSION}

-# Although the following line is synonymous to USES=localbase
-# it breaks the build
-CFLAGS+=       -I${LOCALBASE}/include \
-               -I${LOCALBASE}/share/gnulib/lib \
+CFLAGS+=       -isystem${LOCALBASE}/include \
+               -isystem${LOCALBASE}/share/gnulib/lib \
                -DFREEBSD_HAS_MEMPCPY
 LDFLAGS+=      ${LOCALBASE}/lib/libargp.so \
                ${LOCALBASE}/lib/libintl.so
========================

-- 
You are receiving this mail because:
You are the assignee for the bug.