Re: FYI: g++15 import std / import std.compat fails for use of FreeBSD /usr/include/fenv.h : needs external linkage usage instead

From: Mark Millard <marklmi_at_yahoo.com>
Date: Fri, 23 May 2025 05:05:19 UTC
On May 22, 2025, at 21:36, Mark Millard <marklmi@yahoo.com> wrote:

> I do not know if clang++ would end up with analogous issues.

FreeBSD's system clang and devel/llvm20 do not
support building std.compat or std . See later.

> I happened to have started with g++15 for seeing if I could
> build the std std.compat module from the source for doing so.
> gcc got support for std.compat and std builds in 15.1 .
> 
> Note that I'm using a aarch64 context here and my lang/gcc15
> has the recent patch that that has been committed to
> lang/gcc15-devel that allows the toolchain to be built for
> aarch64. (I doubt that use of lang/gcc15-devel would be any
> different.)
> 
> 
> # g++15 -std=c++23 -O2 -fmodules -fsearch-include-path -fmodule-only -c bits/std.cc
> /usr/local/lib/gcc15/include/c++/bits/std.cc:3351:14: error: exporting 'int feclearexcept(int)' that does not have external linkage
> 3351 |   using std::feclearexcept;
>      |              ^~~~~~~~~~~~~
> In file included from /usr/local/lib/gcc15/include/c++/fenv.h:41,
>                 from /usr/local/lib/gcc15/include/c++/cfenv:43,
>                 from /usr/local/lib/gcc15/include/c++/aarch64-portbld-freebsd15.0/bits/stdc++.h:128,
>                 from /usr/local/lib/gcc15/include/c++/bits/std.cc:30:
> /usr/include/fenv.h:84:1: note: 'int feclearexcept(int)' declared here with internal linkage
>   84 | feclearexcept(int __excepts)
>      | ^~~~~~~~~~~~~
> /usr/local/lib/gcc15/include/c++/bits/std.cc:3352:14: error: exporting 'int fegetenv(fenv_t*)' that does not have external linkage
> 3352 |   using std::fegetenv;
>      |              ^~~~~~~~
> . . .
> 
> and so on for supporting building from (for example):
> 
> /usr/local/lib/gcc15/include/c++/bits/std.cc <http://std.cc/> :
> 
> . . .
> // 28.3 <cfenv>
> export C_LIB_NAMESPACE
> {
> #ifdef _GLIBCXX_USE_C99_FENV
>  using std::feclearexcept;
>  using std::fegetenv;
>  using std::fegetexceptflag;
>  using std::fegetround;
>  using std::feholdexcept;
>  using std::fenv_t;
>  using std::feraiseexcept;
>  using std::fesetenv;
>  using std::fesetexceptflag;
>  using std::fesetround;
>  using std::fetestexcept;
>  using std::feupdateenv;
>  using std::fexcept_t;
> #endif
> }
> . . .
> 
> g++15 has:
> 
> /usr/local/lib/gcc15/include/c++/cfenv :
> 
> . . .
> #include <bits/c++config.h>
> 
> #if _GLIBCXX_HAVE_FENV_H
> # include <fenv.h>
> #endif
> . . .
> 
> /usr/local/lib/gcc15/include/c++/fenv.h :
> 
> . . .
> #include <bits/c++config.h>
> #if _GLIBCXX_HAVE_FENV_H
> # include_next <fenv.h>
> #endif
> . . .
> 
> /usr/local/lib/gcc15/include/c++/aarch64-portbld-freebsd15.0/bits/c++config.h
> does have:
> 
> /* Define to 1 if you have the <fenv.h> header file. */
> #define _GLIBCXX_HAVE_FENV_H 1
> 
> 
> FreeBSD's (main) /usr/include/fenv.h is using code like:
> 
> . . .
> #ifndef __fenv_static
> #define __fenv_static   static
> #endif
> . . .
> __fenv_static __inline int
> feclearexcept(int __excepts)
> {
>        fexcept_t __r;
> 
>        __mrs_fpsr(__r);
>        __r &= ~__excepts;
>        __msr_fpsr(__r);
>        return (0);
> }
> . . .
> 
> that disallows setting up the exports in C++ modules.
> 
> FreeBSD has /usr/include/sys/cdefs.h :
> 
> . . .
> #if defined(__STDC__) || defined(__cplusplus)
> . . .
> #if defined(__cplusplus)
> #define __inline        inline          /* convert to C++ keyword */
> #else
> #if !(defined(__CC_SUPPORTS___INLINE))
> #define __inline                        /* delete GCC keyword */
> #endif /* ! __CC_SUPPORTS___INLINE */
> #endif /* !__cplusplus */
> 
> #else   /* !(__STDC__ || __cplusplus) */
> . . .
> 
> 
> And FreeBSD has /usr/include/_ctype.h :
> 
> . . .
> #include <sys/cdefs.h>
> . . .
> /*
> * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us
> * to generate code for extern versions of all our inline functions.
> */
> #ifdef _EXTERNALIZE_CTYPE_INLINES_
> #define _USE_CTYPE_INLINE_
> #define static
> #define __inline
> #endif
> . . .
> 
> 
> There is also:
> 
> /usr/include/arm/fenv.h :
> 
> . . .
> #ifndef __fenv_static
> #define __fenv_static   static
> #endif
> . . .
> #ifndef __ARM_PCS_VFP
> 
> int feclearexcept(int __excepts);
> . . .
> #endif
> 
> #else   /* __ARM_PCS_VFP */
> 
> #define vmrs_fpscr(__r) __asm __volatile("vmrs %0, fpscr" : "=&r"(__r))
> #define vmsr_fpscr(__r) __asm __volatile("vmsr fpscr, %0" : : "r"(__r))
> 
> #define _FPU_MASK_SHIFT 8
> 
> __fenv_static inline int
> feclearexcept(int __excepts)
> {
>        fexcept_t __fpsr;
> 
>        vmrs_fpscr(__fpsr);
>        __fpsr &= ~__excepts;
>        vmsr_fpscr(__fpsr);
>        return (0);
> }
> . . .
> 
> Without __ARM_PCS_VFP involved, this would again end
> up blocking the C++ exports in std and in std.compat .
> It also does not use __inline but just inline.

As for FreeBSD's system c++ and lang/llvm20's clang++
go (showing the llvm20 example):

# cat main_std_std_compat-build.sh
#! /bin/sh
mkdir -p build
cmake -G Ninja -S . -B build -DCMAKE_CXX_COMPILER=/usr/local/bin/clang++20 -DCMAKE_CXX_FLAGS=-stdlib=libc++
ninja -C build
build/main

# ./main_std_std_compat-build.sh
-- The CXX compiler identification is Clang 20.1.5
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/clang++20 - skipped
-- Detecting CXX compile features
CMake Warning (dev) at /usr/local/share/cmake/Modules/Compiler/CMakeCommonCompilerMacros.cmake:248 (cmake_language):
  CMake's support for `import std;` in C++23 and newer is experimental.  It
  is meant only for experimentation and feedback to CMake developers.
Call Stack (most recent call first):
  /usr/local/share/cmake/Modules/CMakeDetermineCompilerSupport.cmake:113 (cmake_create_cxx_import_std)
  /usr/local/share/cmake/Modules/CMakeTestCXXCompiler.cmake:83 (CMAKE_DETERMINE_COMPILER_SUPPORT)
  CMakeLists.txt:10 (project)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Detecting CXX compile features - done
-- Configuring done (1.4s)
CMake Error in CMakeLists.txt:
  The "CXX_MODULE_STD" property on the target "main_std_std_compat" requires
  that the "__CMAKE::CXX23" target exist, but it was not provided by the
  toolchain.  Reason:

    `libc++.modules.json` resource does not exist


-- Generating done (0.0s)
CMake Generate step failed.  Build files cannot be regenerated correctly.
ninja: Entering directory `build'
ninja: error: loading 'build.ninja': No such file or directory
./main_std_std_compat-build.sh: build/main: not found
aarch64-main-pbase aarch64 main-CA76-chroot-ports-local 1500043 1500043 # cmake -v

# cmake -version
cmake version 3.31.7

CMake suite maintained and supported by Kitware (kitware.com/cmake).


For reference:

# find -s / -name libc++.modules.json -print
# 


===
Mark Millard
marklmi at yahoo.com