import std does also not work with gcc-15
on ubuntu 25.04
!
builder@5b11ff1f2350:~/workdir$ cmake -S . -B build -G Ninja --fresh
-- The CXX compiler identification is GNU 15.0.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/g++-15 - skipped
-- Detecting CXX compile features
CMake Warning (dev) at /usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/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/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/CMakeDetermineCompilerSupport.cmake:113 (cmake_create_cxx_import_std)
/usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/CMakeTestCXXCompiler.cmake:83 (CMAKE_DETERMINE_COMPILER_SUPPORT)
CMakeLists.txt:36 (project)
This warning is for project developers. Use -Wno-dev to suppress it.
-- Detecting CXX compile features - done
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done (0.9s)
CMake Error at build/CMakeFiles/4.0.3/CMakeCXXCompiler.cmake:119 (target_sources):
Cannot find source file:
/usr/lib/gcc/x86_64-linux-gnu/include/c++/15/bits/std.cc
Call Stack (most recent call first):
/usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/CMakeTestCXXCompiler.cmake:91 (include)
CMakeLists.txt:36 (project)
CMake Error in CMakeLists.txt:
No SOURCES given to target: __CMAKE__CXX26@synth_228b59946540
CMake Generate step failed. Build files cannot be regenerated correctly.
builder@5b11ff1f2350:~/workdir$ find /usr -iname 'std.cc'
/usr/include/c++/15/bits/std.cc
builder@5b11ff1f2350:~/workdir$ uname -a
Linux 5b11ff1f2350 6.10.14-linuxkit #1 SMP PREEMPT_DYNAMIC Thu Mar 20 16:36:58 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
builder@5b11ff1f2350:~/workdir$ cat /etc/issue
Ubuntu 25.04 \n \l
builder@5b11ff1f2350:~/workdir$ cat /usr/lib/gcc/x86_64-linux-gnu/15/libstdc++.modules.json
{
"version": 1,
"revision": 1,
"modules": [
{
"logical-name": "std",
"source-path": "../include/c++/15/bits/std.cc",
"is-std-library": true
},
{
"logical-name": "std.compat",
"source-path": "../include/c++/15/bits/std.compat.cc",
"is-std-library": true
}
]
}
builder@5b11ff1f2350:~/workdir$
import std does also not work with clang-20
on ubuntu 25.04
!
builder@98757d772b6f:~/workdir$ CXX=clang++ cmake -S . -B build -G Ninja --fresh
-- The CXX compiler identification is Clang 20.1.2
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/clang++ - skipped
-- Detecting CXX compile features
CMake Warning (dev) at /usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/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/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/CMakeDetermineCompilerSupport.cmake:113 (cmake_create_cxx_import_std)
/usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/CMakeTestCXXCompiler.cmake:83 (CMAKE_DETERMINE_COMPILER_SUPPORT)
CMakeLists.txt:36 (project)
This warning is for project developers. Use -Wno-dev to suppress it.
-- Detecting CXX compile features - done
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
CMake Error at /home/builder/workdir/build/CMakeFiles/4.0.3/CMakeCXXCompiler.cmake:111 (target_sources):
Cannot find source file:
/usr/lib/gcc/x86_64-linux-gnu/include/c++/15/bits/std.cc
Call Stack (most recent call first):
/home/builder/workdir/build/CMakeFiles/CMakeScratch/TryCompile-u2A8qJ/CMakeLists.txt:2 (project)
CMake Error at /home/builder/workdir/build/CMakeFiles/4.0.3/CMakeCXXCompiler.cmake:103 (add_library):
No SOURCES given to target: __cmake_cxx23
Call Stack (most recent call first):
/home/builder/workdir/build/CMakeFiles/CMakeScratch/TryCompile-u2A8qJ/CMakeLists.txt:2 (project)
CMake Error at /home/builder/workdir/build/CMakeFiles/4.0.3/CMakeCXXCompiler.cmake:127 (add_library):
No SOURCES given to target: __cmake_cxx26
Call Stack (most recent call first):
/home/builder/workdir/build/CMakeFiles/CMakeScratch/TryCompile-u2A8qJ/CMakeLists.txt:2 (project)
CMake Error at /usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/Internal/CheckSourceCompiles.cmake:104 (try_compile):
Failed to generate test project build system.
Call Stack (most recent call first):
/usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/Internal/CheckCompilerFlag.cmake:18 (cmake_check_source_compiles)
/usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/CheckCompilerFlag.cmake:56 (cmake_check_compiler_flag)
/usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/GenerateExportHeader.cmake:244 (check_compiler_flag)
/usr/local/lib/python3.13/dist-packages/cmake/data/share/cmake-4.0/Modules/GenerateExportHeader.cmake:425 (_test_compiler_hidden_visibility)
CMakeLists.txt:50 (generate_export_header)
-- Configuring incomplete, errors occurred!
builder@98757d772b6f:~/workdir$ find /usr -name std.cppm
/usr/lib/llvm-20/share/libc++/v1/std.cppm
builder@98757d772b6f:~/workdir$ find /usr -name '*modules.json'
/usr/lib/gcc/x86_64-linux-gnu/15/libstdc++.modules.json
/usr/lib/llvm-20/lib/libc++.modules.json
builder@98757d772b6f:~/workdir$ cat /usr/lib/llvm-20/lib/libc++.modules.json
{
"version": 1,
"revision": 1,
"modules": [
{
"logical-name": "std",
"source-path": "../share/libc++/v1/std.cppm",
"is-std-library": true,
"local-arguments": {
"system-include-directories": [
"../share/libc++/v1"
]
}
},
{
"logical-name": "std.compat",
"source-path": "../share/libc++/v1/std.compat.cppm",
"is-std-library": true,
"local-arguments": {
"system-include-directories": [
"../share/libc++/v1"
]
}
}
]
}
builder@98757d772b6f:~/workdir$
ben.boeckel
(Ben Boeckel (Kitware))
June 16, 2025, 2:53pm
3
Looks like a packaging problem to me; the mentioned source files should be included in the -dev
package that provides the stdlib modules’ .json
file.
Or, perhaps, the paths are not correct? In any case, this is an Ubuntu issue based on the information provided.
For the gcc-15
case, I agree.
But in the clang-20
case, it seems a CMake
problem, the /usr/lib/llvm-20/lib/libc++.modules.json
is correct!
ben.boeckel
(Ben Boeckel (Kitware))
June 16, 2025, 5:28pm
5
Can you please trace the paths made in Clang-CXX-CXXImportStd.cmake
to see where CMake goes astray?
cmake.log (40.7 KB)
My CMakeLists.txt
:
cmake_minimum_required(VERSION 4.0)
if(APPLE)
set(CMAKE_CXX_COMPILER /usr/local/bin/g++-15)
# set(LLVM_ROOT /usr/local/Cellar/llvm/20.1.6)
# set(CMAKE_CXX_COMPILER ${LLVM_ROOT}/bin/clang++)
# add_link_options(-L${LLVM_ROOT}/lib/c++)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_compile_options(-stdlib=libc++)
add_link_options(-stdlib=libc++)
endif()
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_SKIP_TEST_ALL_DEPENDENCY FALSE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_VERSION VERSION_LESS 4.0.3)
# cmake v4.0.2:
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD a9e1cf81-9932-4810-974b-6eccaf14e457)
else()
# cmake release branch
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD d0edc3af-4c50-42ea-a356-e2862fe7a444)
endif()
set(CMAKE_CXX_MODULE_STD ON)
# Ensure non-empty default build type for single-config
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT isMultiConfig)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type")
endif()
set(CMAKE_DEBUG_POSTFIX _debug)
project(example-modules VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)
add_library(Algo SHARED)
target_sources(
Algo
PRIVATE algo-impl.cpp
PUBLIC FILE_SET CXX_MODULES FILES algo-interface.cppm
)
target_compile_features(Algo PUBLIC cxx_std_23)
include(GenerateExportHeader)
generate_export_header(Algo)
target_sources(
Algo
PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/algo_export.h
)
add_executable(algo-example algo-example.cpp)
target_link_libraries(algo-example PRIVATE Algo)
enable_testing()
add_test(NAME algo-example COMMAND algo-example)
include(GNUInstallDirs)
install(
TARGETS Algo
EXPORT Algo
FILE_SET HEADERS
FILE_SET CXX_MODULES
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/my_package/src
CXX_MODULES_BMI
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/my_package/bmi-$<CONFIG>
# Other things to install
)
install(
EXPORT Algo
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/my_package
FILE algo-targets.cmake
NAMESPACE Algo
CXX_MODULES_DIRECTORY
algo
)
ben.boeckel
(Ben Boeckel (Kitware))
June 16, 2025, 7:37pm
7
I don’t think these get used at all during compiler detection; I see no libc++
usage in the logs you’ve provided, so they’re both using the broken libstdc++.modules.json
file.
How may I control to use libc++ with clang++?
This is magic on linux
:
builder@3be174728abe:~/workdir$ /usr/bin/clang++-20 -print-file-name=libstdc++.modules.json
/usr/lib/gcc/x86_64-linux-gnu/15/libstdc++.modules.json
builder@3be174728abe:~/workdir$ /usr/bin/clang++-20 -print-file-name=libc++.modules.json
/usr/lib/llvm-20/bin/../lib/libc++.modules.json
builder@3be174728abe:~/workdir$
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
builder@3be174728abe:~/workdir$ g++-15 -print-file-name=libstdc++.modules.json
/usr/lib/gcc/x86_64-linux-gnu/15/libstdc++.modules.json
builder@3be174728abe:~/workdir$ g++-15 -print-file-name=libc++.modules.json
libc++.modules.json
builder@3be174728abe:~/workdir$
an other miracle on OSX
:
bash-5.2$ g++-15 -print-file-name=libc++.modules.json
libc++.modules.json
bash-5.2$ g++-15 -print-file-name=libstdc++.modules.json
/usr/local/Cellar/gcc/15.1.0/bin/../lib/gcc/current/gcc/x86_64-apple-darwin23/15/../../../libstdc++.modules.json
bash-5.2$ clang++ -print-file-name=libstdc++.modules.json
libstdc++.modules.json
bash-5.2$ clang++ -print-file-name=libc++.modules.json
libc++.modules.json
bash-5.2$ clang++ -print-file-name=c++/libc++.modules.json
/usr/local/Cellar/llvm/20.1.6/lib/clang/20/../../c++/libc++.modules.json
bash-5.2$
ben.boeckel
(Ben Boeckel (Kitware))
June 17, 2025, 5:01am
10
I used CXXFLAGS=-stdlib=libc++
in the environment.
1 Like
But the CMAKE_CXX_STANDARD_LIBRARY
is set in CMakeDetermineComilerId.cmake
:
set(CMAKE_${lang}_STANDARD_LIBRARY "")
if ("x${lang}" STREQUAL "xCXX" AND
EXISTS "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${lang}-DetectStdlib.h" AND
("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xClang" AND
"x${CMAKE_${lang}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU") OR
("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xGNU"))
# See #20851 for a proper abstraction for this.
execute_process(
COMMAND "${CMAKE_${lang}_COMPILER}"
${CMAKE_${lang}_COMPILER_ID_ARG1}
${CMAKE_CXX_COMPILER_ID_FLAGS_LIST}
-E
-x c++-header
"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${lang}-DetectStdlib.h"
-o - # Write to stdout.
OUTPUT_VARIABLE _lang_stdlib_out
ERROR_VARIABLE _lang_stdlib_err
RESULT_VARIABLE _lang_stdlib_res
ERROR_STRIP_TRAILING_WHITESPACE)
if (_lang_stdlib_res EQUAL 0)
string(REGEX REPLACE ".*CMAKE-STDLIB-DETECT: (.+)\n.*" "\\1" "CMAKE_${lang}_STANDARD_LIBRARY" "${_lang_stdlib_out}")
endif ()
endif ()
default set to:
Modules/CMakeDetermineCompilerId.cmake(434): set(CMAKE_CXX_STANDARD_LIBRARY libstdc++ PARENT_SCOPE )
But this helps:
CXX=clang++-20 CXXFLAGS=-stdlib=libc++ cmake -G Ninja -S . -B build --trace-expand --trace-source=CMakeDetermineCompilerId.cmake --fresh
So I have to set for clang-20
if($ENV{CXX} MATCHES "clang" OR CMAKE_CXX_COMPILER MATCHES "clang")
set(ENV{CXXFLAGS} -stdlib=libc++)
endif()
before project(...)
in my CMakeLists.txt
!
And for gcc-15
this workaround helps:
sudo mkdir -p /usr/lib/gcc/x86_64-linux-gnu/include/c++/15
cd /usr/lib/gcc/x86_64-linux-gnu/include/c++/15
sudo ln -s /usr/include/c++/15/bits .
So with this works with clang++-20
on ubuntu-25.04
out of the box
@ben.boeckel With g++15
it builds only with my workaround !
cmake_minimum_required(VERSION 4.0...4.1)
if(APPLE)
set(CMAKE_CXX_COMPILER /usr/local/bin/g++-15)
set(LLVM_ROOT /usr/local/Cellar/llvm/20.1.6)
# FIXME: NO usable! set(CMAKE_CXX_COMPILER ${LLVM_ROOT}/bin/clang++)
endif()
if($ENV{CXX} MATCHES "clang" OR CMAKE_CXX_COMPILER MATCHES "clang")
set(ENV{CXXFLAGS} -stdlib=libc++)
endif()
if(NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
endif()
set(CMAKE_SKIP_TEST_ALL_DEPENDENCY FALSE)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(CMAKE_VERSION VERSION_LESS 4.0.3)
# cmake v4.0.2:
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD a9e1cf81-9932-4810-974b-6eccaf14e457)
else()
# cmake release branch
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD d0edc3af-4c50-42ea-a356-e2862fe7a444)
endif()
unset(CMAKE_CXX_MODULE_STD)
# Ensure non-empty default build type for single-config
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT isMultiConfig)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type")
endif()
set(CMAKE_DEBUG_POSTFIX _debug)
####################################################
project(example-modules VERSION 0.1.0 LANGUAGES CXX)
####################################################
if(APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
add_link_options(-L${LLVM_ROOT}/lib/c++)
endif()
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)
add_library(Algo SHARED)
target_sources(
Algo
PRIVATE algo-impl.cpp
PUBLIC FILE_SET CXX_MODULES FILES algo-interface.cppm
)
target_compile_features(Algo PUBLIC cxx_std_23)
include(GenerateExportHeader)
generate_export_header(Algo)
target_sources(
Algo
PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/algo_export.h
)
add_executable(algo-example algo-example.cpp)
target_link_libraries(algo-example PRIVATE Algo)
enable_testing()
add_test(NAME algo-example COMMAND algo-example)
include(GNUInstallDirs)
install(
TARGETS Algo
EXPORT Algo
FILE_SET HEADERS
FILE_SET CXX_MODULES
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/my_package/src
CXX_MODULES_BMI
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/my_package/bmi-$<CONFIG>
# Other things to install
)
install(
EXPORT Algo
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/my_package
FILE algo-targets.cmake
NAMESPACE Algo
CXX_MODULES_DIRECTORY
algo
)
# Tell CMake that we explicitly want `import std`.
# This will initialize the property on all targets declared after this to 1
if(26 IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD)
set(CMAKE_CXX_MODULE_STD ON)
else()
return()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
return()
endif()
add_executable(import-std main.cpp)
add_test(NAME import-std COMMAND import-std)
add_library(demo)
target_compile_features(demo PUBLIC cxx_std_26)
target_sources(demo PUBLIC FILE_SET CXX_MODULES FILES demo.cppm)
add_executable(demo-example main2.cpp)
target_link_libraries(demo-example PRIVATE demo)
add_test(NAME demo-example COMMAND demo-example)
I believe these are broadly upstream and packaging bugs based on logs.
There’s nothing for CMake to do if the given compiler cannot provide a correct P3286 file describing the stdlib.
Whoever packaged the compiler.
If the packagers need support for their use case from the compiler, ex, they need to be able to tell the compiler “I’m going to put these files here” to make -print-file-name
work, then it is on the packagers to communicate that the various compiler upstreams.
The compiler upstreams can decide on a case-by-case basis if they want to support the packagers conventions, or if it is on the packagers to align themselves with the compiler’s expectations.
CMake’s involvement begins and ends at -print-file-name
. We 100% need better error messages if the path we get from -print-file-name
is invalid, or the P3286 file contains bogus metadata, but we can’t “fix” that.
Yep, that’s an example of a packager bug report, as Ubuntu is a packager of GCC.
For any packager who has a bugged compiler package, it’s on them to figure out how to fix their package.
Obviously we’re here to help anyone who needs it, but CMake can’t be arbitrarily re-arranging files in a given distro’s package.