Re: FYI: g++15 import std / import std.compat fails for use of FreeBSD /usr/include/fenv.h : needs external linkage usage instead
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