diff mbox series

[RFC] libxfs: compile with a C++ compiler

Message ID 20240827234533.GE1977952@frogsfrogsfrogs (mailing list archive)
State Not Applicable, archived
Headers show
Series [RFC] libxfs: compile with a C++ compiler | expand

Commit Message

Darrick J. Wong Aug. 27, 2024, 11:45 p.m. UTC
From: Darrick J. Wong <djwong@kernel.org>

Apparently C++ compilers don't like the implicit void* casts that go on
in the system headers.  Compile a dummy program with the C++ compiler to
make sure this works, so Darrick has /some/ chance of figuring these
things out before the users do.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
 configure.ac         |    1 +
 include/builddefs.in |    7 +++++++
 libxfs/Makefile      |    8 +++++++-
 libxfs/dummy.cpp     |   15 +++++++++++++++
 4 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 libxfs/dummy.cpp

Comments

Sam James Aug. 28, 2024, 12:01 a.m. UTC | #1
"Darrick J. Wong" <djwong@kernel.org> writes:

> From: Darrick J. Wong <djwong@kernel.org>
>
> Apparently C++ compilers don't like the implicit void* casts that go on
> in the system headers.  Compile a dummy program with the C++ compiler to
> make sure this works, so Darrick has /some/ chance of figuring these
> things out before the users do.

Thanks, this is a good idea. Double thanks for the quick fix.

1) yes, it finds the breakage:
Tested-by: Sam James <sam@gentoo.org>

2) with the fix below (CC -> CXX):
Reviewed-by: Sam James <sam@gentoo.org>

3) another thing to think about is:
* -pedantic?
* maybe do one for a bunch of standards? (I think systemd does every
possible value [1])
* doing the above for C as well

I know that sounds a bit like overkill, but systemd
does it and it's cheap to do it versus the blowup if something goes
wrong. I don't have a strong opinion on this or how far you want to go
with it.

[1] https://github.com/systemd/systemd/blob/3317aedff0901e08a8efc8346ad76b184d5d40ea/src/systemd/meson.build#L60

>
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>  configure.ac         |    1 +
>  include/builddefs.in |    7 +++++++
>  libxfs/Makefile      |    8 +++++++-
>  libxfs/dummy.cpp     |   15 +++++++++++++++
>  4 files changed, 30 insertions(+), 1 deletion(-)
>  create mode 100644 libxfs/dummy.cpp
>
> diff --git a/configure.ac b/configure.ac
> index 0ffe2e5dfc53..04544f85395b 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -9,6 +9,7 @@ AC_PROG_INSTALL
>  LT_INIT
>  
>  AC_PROG_CC
> +AC_PROG_CXX
>  AC_ARG_VAR(BUILD_CC, [C compiler for build tools])
>  if test "${BUILD_CC+set}" != "set"; then
>    if test $cross_compiling = no; then
> diff --git a/include/builddefs.in b/include/builddefs.in
> index 44f95234d21b..0f312b8b88fe 100644
> --- a/include/builddefs.in
> +++ b/include/builddefs.in
> @@ -14,6 +14,7 @@ MALLOCLIB = @malloc_lib@
>  LOADERFLAGS = @LDFLAGS@
>  LTLDFLAGS = @LDFLAGS@
>  CFLAGS = @CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
> +CXXFLAGS = @CXXFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
>  BUILD_CFLAGS = @BUILD_CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
>  
>  # make sure we don't pick up whacky LDFLAGS from the make environment and
> @@ -234,9 +235,15 @@ ifeq ($(ENABLE_GETTEXT),yes)
>  GCFLAGS += -DENABLE_GETTEXT
>  endif
>  
> +# Override these if C++ needs other options
> +SANITIZER_CXXFLAGS = $(SANITIZER_CFLAGS)
> +GCXXFLAGS = $(GCFLAGS)
> +PCXXFLAGS = $(PCFLAGS)
> +
>  BUILD_CFLAGS += $(GCFLAGS) $(PCFLAGS)
>  # First, Sanitizer, Global, Platform, Local CFLAGS
>  CFLAGS += $(FCFLAGS) $(SANITIZER_CFLAGS) $(OPTIMIZER) $(GCFLAGS) $(PCFLAGS) $(LCFLAGS)
> +CXXFLAGS += $(FCXXFLAGS) $(SANITIZER_CXXFLAGS) $(OPTIMIZER) $(GCXXFLAGS) $(PCXXFLAGS) $(LCXXFLAGS)
>  
>  include $(TOPDIR)/include/buildmacros
>  
> diff --git a/libxfs/Makefile b/libxfs/Makefile
> index 1185a5e6cb26..bb851ab74204 100644
> --- a/libxfs/Makefile
> +++ b/libxfs/Makefile
> @@ -125,6 +125,8 @@ CFILES = buf_mem.c \
>  	xfs_trans_space.c \
>  	xfs_types.c
>  
> +LDIRT += dummy.o
> +
>  #
>  # Tracing flags:
>  # -DMEM_DEBUG		all zone memory use
> @@ -144,7 +146,11 @@ LTLIBS = $(LIBPTHREAD) $(LIBRT)
>  # don't try linking xfs_repair with a debug libxfs.
>  DEBUG = -DNDEBUG
>  
> -default: ltdepend $(LTLIBRARY)
> +default: ltdepend $(LTLIBRARY) dummy.o
> +
> +dummy.o: dummy.cpp
> +	@echo "    [CXX]    $@"
> +	$(Q)$(CC) $(CXXFLAGS) -c $<

$(CXX) ;)

>  
>  # set up include/xfs header directory
>  include $(BUILDRULES)
> diff --git a/libxfs/dummy.cpp b/libxfs/dummy.cpp
> new file mode 100644
> index 000000000000..a872c00ad84b
> --- /dev/null
> +++ b/libxfs/dummy.cpp
> @@ -0,0 +1,15 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2024 Oracle.  All Rights Reserved.
> + * Author: Darrick J. Wong <djwong@kernel.org>
> + */
> +#include "include/xfs.h"
> +#include "include/handle.h"
> +#include "include/jdm.h"
> +
> +/* Dummy program to test C++ compilation of user-exported xfs headers */
> +
> +int main(int argc, char *argv[])
> +{
> +	return 0;
> +}

cheers,
sam
Sam James Aug. 28, 2024, 12:10 a.m. UTC | #2
Sam James <sam@gentoo.org> writes:

> "Darrick J. Wong" <djwong@kernel.org> writes:
>
>> From: Darrick J. Wong <djwong@kernel.org>
>>
>> Apparently C++ compilers don't like the implicit void* casts that go on
>> in the system headers.  Compile a dummy program with the C++ compiler to
>> make sure this works, so Darrick has /some/ chance of figuring these
>> things out before the users do.
>
> Thanks, this is a good idea. Double thanks for the quick fix.
>
> 1) yes, it finds the breakage:
> Tested-by: Sam James <sam@gentoo.org>
>
> 2) with the fix below (CC -> CXX):
> Reviewed-by: Sam James <sam@gentoo.org>
>
> 3) another thing to think about is:
> * -pedantic?
> * maybe do one for a bunch of standards? (I think systemd does every
> possible value [1])
> * doing the above for C as well
>
> I know that sounds a bit like overkill, but systemd
> does it and it's cheap to do it versus the blowup if something goes
> wrong. I don't have a strong opinion on this or how far you want to go
> with it.

... thinking about this, it could've helped us with
https://lore.kernel.org/linux-xfs/a216140e-1c8a-4d04-ba46-670646498622@redhat.com/

>
> [1] https://github.com/systemd/systemd/blob/3317aedff0901e08a8efc8346ad76b184d5d40ea/src/systemd/meson.build#L60
>
>>
>> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
>> ---
>>  configure.ac         |    1 +
>>  include/builddefs.in |    7 +++++++
>>  libxfs/Makefile      |    8 +++++++-
>>  libxfs/dummy.cpp     |   15 +++++++++++++++
>>  4 files changed, 30 insertions(+), 1 deletion(-)
>>  create mode 100644 libxfs/dummy.cpp
>>
>> diff --git a/configure.ac b/configure.ac
>> index 0ffe2e5dfc53..04544f85395b 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -9,6 +9,7 @@ AC_PROG_INSTALL
>>  LT_INIT
>>  
>>  AC_PROG_CC
>> +AC_PROG_CXX
>>  AC_ARG_VAR(BUILD_CC, [C compiler for build tools])
>>  if test "${BUILD_CC+set}" != "set"; then
>>    if test $cross_compiling = no; then
>> diff --git a/include/builddefs.in b/include/builddefs.in
>> index 44f95234d21b..0f312b8b88fe 100644
>> --- a/include/builddefs.in
>> +++ b/include/builddefs.in
>> @@ -14,6 +14,7 @@ MALLOCLIB = @malloc_lib@
>>  LOADERFLAGS = @LDFLAGS@
>>  LTLDFLAGS = @LDFLAGS@
>>  CFLAGS = @CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
>> +CXXFLAGS = @CXXFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
>>  BUILD_CFLAGS = @BUILD_CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
>>  
>>  # make sure we don't pick up whacky LDFLAGS from the make environment and
>> @@ -234,9 +235,15 @@ ifeq ($(ENABLE_GETTEXT),yes)
>>  GCFLAGS += -DENABLE_GETTEXT
>>  endif
>>  
>> +# Override these if C++ needs other options
>> +SANITIZER_CXXFLAGS = $(SANITIZER_CFLAGS)
>> +GCXXFLAGS = $(GCFLAGS)
>> +PCXXFLAGS = $(PCFLAGS)
>> +
>>  BUILD_CFLAGS += $(GCFLAGS) $(PCFLAGS)
>>  # First, Sanitizer, Global, Platform, Local CFLAGS
>>  CFLAGS += $(FCFLAGS) $(SANITIZER_CFLAGS) $(OPTIMIZER) $(GCFLAGS) $(PCFLAGS) $(LCFLAGS)
>> +CXXFLAGS += $(FCXXFLAGS) $(SANITIZER_CXXFLAGS) $(OPTIMIZER) $(GCXXFLAGS) $(PCXXFLAGS) $(LCXXFLAGS)
>>  
>>  include $(TOPDIR)/include/buildmacros
>>  
>> diff --git a/libxfs/Makefile b/libxfs/Makefile
>> index 1185a5e6cb26..bb851ab74204 100644
>> --- a/libxfs/Makefile
>> +++ b/libxfs/Makefile
>> @@ -125,6 +125,8 @@ CFILES = buf_mem.c \
>>  	xfs_trans_space.c \
>>  	xfs_types.c
>>  
>> +LDIRT += dummy.o
>> +
>>  #
>>  # Tracing flags:
>>  # -DMEM_DEBUG		all zone memory use
>> @@ -144,7 +146,11 @@ LTLIBS = $(LIBPTHREAD) $(LIBRT)
>>  # don't try linking xfs_repair with a debug libxfs.
>>  DEBUG = -DNDEBUG
>>  
>> -default: ltdepend $(LTLIBRARY)
>> +default: ltdepend $(LTLIBRARY) dummy.o
>> +
>> +dummy.o: dummy.cpp
>> +	@echo "    [CXX]    $@"
>> +	$(Q)$(CC) $(CXXFLAGS) -c $<
>
> $(CXX) ;)
>
>>  
>>  # set up include/xfs header directory
>>  include $(BUILDRULES)
>> diff --git a/libxfs/dummy.cpp b/libxfs/dummy.cpp
>> new file mode 100644
>> index 000000000000..a872c00ad84b
>> --- /dev/null
>> +++ b/libxfs/dummy.cpp
>> @@ -0,0 +1,15 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2024 Oracle.  All Rights Reserved.
>> + * Author: Darrick J. Wong <djwong@kernel.org>
>> + */
>> +#include "include/xfs.h"
>> +#include "include/handle.h"
>> +#include "include/jdm.h"
>> +
>> +/* Dummy program to test C++ compilation of user-exported xfs headers */
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +	return 0;
>> +}
>
> cheers,
> sam
Christoph Hellwig Aug. 28, 2024, 4:25 a.m. UTC | #3
On Tue, Aug 27, 2024 at 04:45:33PM -0700, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Apparently C++ compilers don't like the implicit void* casts that go on
> in the system headers.  Compile a dummy program with the C++ compiler to
> make sure this works, so Darrick has /some/ chance of figuring these
> things out before the users do.

I guess if we want to support C++ users of our system headers we'll have
to do something, so ACK.
Darrick J. Wong Aug. 28, 2024, 11:53 p.m. UTC | #4
On Wed, Aug 28, 2024 at 01:01:31AM +0100, Sam James wrote:
> "Darrick J. Wong" <djwong@kernel.org> writes:
> 
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > Apparently C++ compilers don't like the implicit void* casts that go on
> > in the system headers.  Compile a dummy program with the C++ compiler to
> > make sure this works, so Darrick has /some/ chance of figuring these
> > things out before the users do.
> 
> Thanks, this is a good idea. Double thanks for the quick fix.
> 
> 1) yes, it finds the breakage:
> Tested-by: Sam James <sam@gentoo.org>
> 
> 2) with the fix below (CC -> CXX):
> Reviewed-by: Sam James <sam@gentoo.org>
> 
> 3) another thing to think about is:
> * -pedantic?

-pedantic won't build because C++ doesn't support flexarrays:

In file included from ../include/xfs.h:61:
../include/xfs/xfs_fs.h:523:33: error: ISO C++ forbids flexible array member ‘bulkstat’ [-Werror=pedantic]
  523 |         struct xfs_bulkstat     bulkstat[];
      |                                 ^~~~~~~~

even if you wrap it in extern "C" { ... };

> * maybe do one for a bunch of standards? (I think systemd does every
> possible value [1])

That might be overkill since xfsprogs' build system doesn't have a good
mechanism for detecting if a compiler supports a particular standard.
I'm not even sure there's a good "reference" C++ standard to pick here,
since the kernel doesn't require a C++ compiler.

> * doing the above for C as well

Hmm, that's a good idea.

I think the only relevant standard here is C11 (well really gnu11),
because that's what the kernel compiles with since 5.18.  xfsprogs
doesn't specify any particular version of C, but perhaps we should match
the kernel every time they bump that up?

IOWs, should we build xfsprogs with -std=gnu11?  The commit changing the
kernel to gnu11 (e8c07082a810) remarks that gcc 5.1 supports it just
fine.  IIRC RHEL 7 only has 4.8.5 but it's now in extended support so
... who cares?  The oldest supported Debian stable has gcc 8.

--D

> I know that sounds a bit like overkill, but systemd
> does it and it's cheap to do it versus the blowup if something goes
> wrong. I don't have a strong opinion on this or how far you want to go
> with it.
> 
> [1] https://github.com/systemd/systemd/blob/3317aedff0901e08a8efc8346ad76b184d5d40ea/src/systemd/meson.build#L60
> 
> >
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > ---
> >  configure.ac         |    1 +
> >  include/builddefs.in |    7 +++++++
> >  libxfs/Makefile      |    8 +++++++-
> >  libxfs/dummy.cpp     |   15 +++++++++++++++
> >  4 files changed, 30 insertions(+), 1 deletion(-)
> >  create mode 100644 libxfs/dummy.cpp
> >
> > diff --git a/configure.ac b/configure.ac
> > index 0ffe2e5dfc53..04544f85395b 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -9,6 +9,7 @@ AC_PROG_INSTALL
> >  LT_INIT
> >  
> >  AC_PROG_CC
> > +AC_PROG_CXX
> >  AC_ARG_VAR(BUILD_CC, [C compiler for build tools])
> >  if test "${BUILD_CC+set}" != "set"; then
> >    if test $cross_compiling = no; then
> > diff --git a/include/builddefs.in b/include/builddefs.in
> > index 44f95234d21b..0f312b8b88fe 100644
> > --- a/include/builddefs.in
> > +++ b/include/builddefs.in
> > @@ -14,6 +14,7 @@ MALLOCLIB = @malloc_lib@
> >  LOADERFLAGS = @LDFLAGS@
> >  LTLDFLAGS = @LDFLAGS@
> >  CFLAGS = @CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
> > +CXXFLAGS = @CXXFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
> >  BUILD_CFLAGS = @BUILD_CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
> >  
> >  # make sure we don't pick up whacky LDFLAGS from the make environment and
> > @@ -234,9 +235,15 @@ ifeq ($(ENABLE_GETTEXT),yes)
> >  GCFLAGS += -DENABLE_GETTEXT
> >  endif
> >  
> > +# Override these if C++ needs other options
> > +SANITIZER_CXXFLAGS = $(SANITIZER_CFLAGS)
> > +GCXXFLAGS = $(GCFLAGS)
> > +PCXXFLAGS = $(PCFLAGS)
> > +
> >  BUILD_CFLAGS += $(GCFLAGS) $(PCFLAGS)
> >  # First, Sanitizer, Global, Platform, Local CFLAGS
> >  CFLAGS += $(FCFLAGS) $(SANITIZER_CFLAGS) $(OPTIMIZER) $(GCFLAGS) $(PCFLAGS) $(LCFLAGS)
> > +CXXFLAGS += $(FCXXFLAGS) $(SANITIZER_CXXFLAGS) $(OPTIMIZER) $(GCXXFLAGS) $(PCXXFLAGS) $(LCXXFLAGS)
> >  
> >  include $(TOPDIR)/include/buildmacros
> >  
> > diff --git a/libxfs/Makefile b/libxfs/Makefile
> > index 1185a5e6cb26..bb851ab74204 100644
> > --- a/libxfs/Makefile
> > +++ b/libxfs/Makefile
> > @@ -125,6 +125,8 @@ CFILES = buf_mem.c \
> >  	xfs_trans_space.c \
> >  	xfs_types.c
> >  
> > +LDIRT += dummy.o
> > +
> >  #
> >  # Tracing flags:
> >  # -DMEM_DEBUG		all zone memory use
> > @@ -144,7 +146,11 @@ LTLIBS = $(LIBPTHREAD) $(LIBRT)
> >  # don't try linking xfs_repair with a debug libxfs.
> >  DEBUG = -DNDEBUG
> >  
> > -default: ltdepend $(LTLIBRARY)
> > +default: ltdepend $(LTLIBRARY) dummy.o
> > +
> > +dummy.o: dummy.cpp
> > +	@echo "    [CXX]    $@"
> > +	$(Q)$(CC) $(CXXFLAGS) -c $<
> 
> $(CXX) ;)
> 
> >  
> >  # set up include/xfs header directory
> >  include $(BUILDRULES)
> > diff --git a/libxfs/dummy.cpp b/libxfs/dummy.cpp
> > new file mode 100644
> > index 000000000000..a872c00ad84b
> > --- /dev/null
> > +++ b/libxfs/dummy.cpp
> > @@ -0,0 +1,15 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2024 Oracle.  All Rights Reserved.
> > + * Author: Darrick J. Wong <djwong@kernel.org>
> > + */
> > +#include "include/xfs.h"
> > +#include "include/handle.h"
> > +#include "include/jdm.h"
> > +
> > +/* Dummy program to test C++ compilation of user-exported xfs headers */
> > +
> > +int main(int argc, char *argv[])
> > +{
> > +	return 0;
> > +}
> 
> cheers,
> sam
Sam James Aug. 29, 2024, 12:17 a.m. UTC | #5
"Darrick J. Wong" <djwong@kernel.org> writes:

> On Wed, Aug 28, 2024 at 01:01:31AM +0100, Sam James wrote:
>> "Darrick J. Wong" <djwong@kernel.org> writes:
>> 
>> > From: Darrick J. Wong <djwong@kernel.org>
>> >
>> > Apparently C++ compilers don't like the implicit void* casts that go on
>> > in the system headers.  Compile a dummy program with the C++ compiler to
>> > make sure this works, so Darrick has /some/ chance of figuring these
>> > things out before the users do.
>> 
>> Thanks, this is a good idea. Double thanks for the quick fix.
>> 
>> 1) yes, it finds the breakage:
>> Tested-by: Sam James <sam@gentoo.org>
>> 
>> 2) with the fix below (CC -> CXX):
>> Reviewed-by: Sam James <sam@gentoo.org>
>> 
>> 3) another thing to think about is:
>> * -pedantic?
>
> -pedantic won't build because C++ doesn't support flexarrays:
>
> In file included from ../include/xfs.h:61:
> ../include/xfs/xfs_fs.h:523:33: error: ISO C++ forbids flexible array member ‘bulkstat’ [-Werror=pedantic]
>   523 |         struct xfs_bulkstat     bulkstat[];
>       |                                 ^~~~~~~~
>
> even if you wrap it in extern "C" { ... };

Doh. So the ship has kind of sailed already anyway.

>
>> * maybe do one for a bunch of standards? (I think systemd does every
>> possible value [1])
>
> That might be overkill since xfsprogs' build system doesn't have a good
> mechanism for detecting if a compiler supports a particular standard.
> I'm not even sure there's a good "reference" C++ standard to pick here,
> since the kernel doesn't require a C++ compiler.
>
>> * doing the above for C as well
>
> Hmm, that's a good idea.
>
> I think the only relevant standard here is C11 (well really gnu11),
> because that's what the kernel compiles with since 5.18.  xfsprogs
> doesn't specify any particular version of C, but perhaps we should match
> the kernel every time they bump that up?

Projects are often (IMO far too) conservative with the features they use
in their headers and I don't think it's unreasonable to match the kernel
here.

>
> IOWs, should we build xfsprogs with -std=gnu11?  The commit changing the
> kernel to gnu11 (e8c07082a810) remarks that gcc 5.1 supports it just
> fine.  IIRC RHEL 7 only has 4.8.5 but it's now in extended support so
> ... who cares?  The oldest supported Debian stable has gcc 8.

so, I think we should match whatever linux-headers / the uapi rules are,
and given I've seen flexible array members in there, it's at least C99.

I did some quick greps and am not sure if we're using any C11 features
in uapi at least.

Just don't blame me if someone yells ;)

(kees, any idea if I'm talking rubbish?)

tl;dr: let's try gnu11?

> [...]

sam
Kees Cook Aug. 29, 2024, 1:30 a.m. UTC | #6
On Thu, Aug 29, 2024 at 01:17:53AM +0100, Sam James wrote:
> "Darrick J. Wong" <djwong@kernel.org> writes:
> 
> > On Wed, Aug 28, 2024 at 01:01:31AM +0100, Sam James wrote:
> >> "Darrick J. Wong" <djwong@kernel.org> writes:
> >> 
> >> > From: Darrick J. Wong <djwong@kernel.org>
> >> >
> >> > Apparently C++ compilers don't like the implicit void* casts that go on
> >> > in the system headers.  Compile a dummy program with the C++ compiler to
> >> > make sure this works, so Darrick has /some/ chance of figuring these
> >> > things out before the users do.
> >> 
> >> Thanks, this is a good idea. Double thanks for the quick fix.
> >> 
> >> 1) yes, it finds the breakage:
> >> Tested-by: Sam James <sam@gentoo.org>
> >> 
> >> 2) with the fix below (CC -> CXX):
> >> Reviewed-by: Sam James <sam@gentoo.org>
> >> 
> >> 3) another thing to think about is:
> >> * -pedantic?
> >
> > -pedantic won't build because C++ doesn't support flexarrays:
> >
> > In file included from ../include/xfs.h:61:
> > ../include/xfs/xfs_fs.h:523:33: error: ISO C++ forbids flexible array member ‘bulkstat’ [-Werror=pedantic]
> >   523 |         struct xfs_bulkstat     bulkstat[];
> >       |                                 ^~~~~~~~
> >
> > even if you wrap it in extern "C" { ... };
> 
> Doh. So the ship has kind of sailed already anyway.
> 
> >
> >> * maybe do one for a bunch of standards? (I think systemd does every
> >> possible value [1])
> >
> > That might be overkill since xfsprogs' build system doesn't have a good
> > mechanism for detecting if a compiler supports a particular standard.
> > I'm not even sure there's a good "reference" C++ standard to pick here,
> > since the kernel doesn't require a C++ compiler.
> >
> >> * doing the above for C as well
> >
> > Hmm, that's a good idea.
> >
> > I think the only relevant standard here is C11 (well really gnu11),
> > because that's what the kernel compiles with since 5.18.  xfsprogs
> > doesn't specify any particular version of C, but perhaps we should match
> > the kernel every time they bump that up?
> 
> Projects are often (IMO far too) conservative with the features they use
> in their headers and I don't think it's unreasonable to match the kernel
> here.
> 
> >
> > IOWs, should we build xfsprogs with -std=gnu11?  The commit changing the
> > kernel to gnu11 (e8c07082a810) remarks that gcc 5.1 supports it just
> > fine.  IIRC RHEL 7 only has 4.8.5 but it's now in extended support so
> > ... who cares?  The oldest supported Debian stable has gcc 8.
> 
> so, I think we should match whatever linux-headers / the uapi rules are,
> and given I've seen flexible array members in there, it's at least C99.
> 
> I did some quick greps and am not sure if we're using any C11 features
> in uapi at least.

-std=gnu11 seems like the correct choice, yes.

> Just don't blame me if someone yells ;)
> 
> (kees, any idea if I'm talking rubbish?)
> 
> tl;dr: let's try gnu11?
> 
> > [...]
> 
> sam

In really ugly cases (i.e. MSVC importing headers into a C++ project in
ACPICA) we did things like:

#if defined(__cplusplus)
# define __FLEX_SIZE	0
#else
# define __FLEX_SIZE	/**/
#endif

...
struct ... {
	...
	struct xfs_bulkstat     bulkstat[__FLEX_SIZE];
	...
};
diff mbox series

Patch

diff --git a/configure.ac b/configure.ac
index 0ffe2e5dfc53..04544f85395b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,6 +9,7 @@  AC_PROG_INSTALL
 LT_INIT
 
 AC_PROG_CC
+AC_PROG_CXX
 AC_ARG_VAR(BUILD_CC, [C compiler for build tools])
 if test "${BUILD_CC+set}" != "set"; then
   if test $cross_compiling = no; then
diff --git a/include/builddefs.in b/include/builddefs.in
index 44f95234d21b..0f312b8b88fe 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -14,6 +14,7 @@  MALLOCLIB = @malloc_lib@
 LOADERFLAGS = @LDFLAGS@
 LTLDFLAGS = @LDFLAGS@
 CFLAGS = @CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
+CXXFLAGS = @CXXFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 -Wno-address-of-packed-member
 BUILD_CFLAGS = @BUILD_CFLAGS@ -D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64
 
 # make sure we don't pick up whacky LDFLAGS from the make environment and
@@ -234,9 +235,15 @@  ifeq ($(ENABLE_GETTEXT),yes)
 GCFLAGS += -DENABLE_GETTEXT
 endif
 
+# Override these if C++ needs other options
+SANITIZER_CXXFLAGS = $(SANITIZER_CFLAGS)
+GCXXFLAGS = $(GCFLAGS)
+PCXXFLAGS = $(PCFLAGS)
+
 BUILD_CFLAGS += $(GCFLAGS) $(PCFLAGS)
 # First, Sanitizer, Global, Platform, Local CFLAGS
 CFLAGS += $(FCFLAGS) $(SANITIZER_CFLAGS) $(OPTIMIZER) $(GCFLAGS) $(PCFLAGS) $(LCFLAGS)
+CXXFLAGS += $(FCXXFLAGS) $(SANITIZER_CXXFLAGS) $(OPTIMIZER) $(GCXXFLAGS) $(PCXXFLAGS) $(LCXXFLAGS)
 
 include $(TOPDIR)/include/buildmacros
 
diff --git a/libxfs/Makefile b/libxfs/Makefile
index 1185a5e6cb26..bb851ab74204 100644
--- a/libxfs/Makefile
+++ b/libxfs/Makefile
@@ -125,6 +125,8 @@  CFILES = buf_mem.c \
 	xfs_trans_space.c \
 	xfs_types.c
 
+LDIRT += dummy.o
+
 #
 # Tracing flags:
 # -DMEM_DEBUG		all zone memory use
@@ -144,7 +146,11 @@  LTLIBS = $(LIBPTHREAD) $(LIBRT)
 # don't try linking xfs_repair with a debug libxfs.
 DEBUG = -DNDEBUG
 
-default: ltdepend $(LTLIBRARY)
+default: ltdepend $(LTLIBRARY) dummy.o
+
+dummy.o: dummy.cpp
+	@echo "    [CXX]    $@"
+	$(Q)$(CC) $(CXXFLAGS) -c $<
 
 # set up include/xfs header directory
 include $(BUILDRULES)
diff --git a/libxfs/dummy.cpp b/libxfs/dummy.cpp
new file mode 100644
index 000000000000..a872c00ad84b
--- /dev/null
+++ b/libxfs/dummy.cpp
@@ -0,0 +1,15 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Oracle.  All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#include "include/xfs.h"
+#include "include/handle.h"
+#include "include/jdm.h"
+
+/* Dummy program to test C++ compilation of user-exported xfs headers */
+
+int main(int argc, char *argv[])
+{
+	return 0;
+}