bash-5.3$ ninja -t deps | egrep -vw '(Cellar|Library)' | sort -u
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/args.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/base.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/chrono.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/color.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/compile.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/format-inl.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/format.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/os.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/ostream.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/printf.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/ranges.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/std.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/xchar.h
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/module/fmt.cppm
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/module/format.cc
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/module/os.cc
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/tests/header-only-test.cc
CMakeFiles/__cmake_cxx23.dir/std.pcm
CMakeFiles/fmt__fmt@synth_439f33eb51e5.dir/f6569b67b774.bmi: #deps 197, deps mtime 1765026197877701690 (VALID)
CMakeFiles/module_header-only-test.dir/Users/clausklein/Workspace/cpp/cxx20/fmt-module/tests/header-only-test.cc.o: #deps 1, deps mtime 1765026197925780567 (VALID)
bash-5.3$ cmake . -L
-- CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES=/usr/local/Cellar/llvm/21.1.6/include/c++/v1;/usr/local/Cellar/llvm/21.1.6/lib/clang/21/include;/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include
-- CMAKE_CXX_MODULE_STD=ON
-- CMAKE_CXX_COMPILER_IMPORT_STD=23;26
-- Module tests to be built: header-only-test
-- Configuring done (0.1s)
CMake Warning (dev) in CMakeLists.txt:
CMake's support for `import std;` in C++23 and newer is experimental. It
is meant only for experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Generating done (0.0s)
-- Build files have been written to: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/build/dev/tests/find-package-test
-- Cache values
CMAKE_BUILD_TYPE:STRING=Release
CMAKE_CXX_COMPILER_LAUNCHER:STRING=ccache
CMAKE_INSTALL_PREFIX:PATH=/Users/clausklein/.local
CMAKE_MAKE_PROGRAM:FILEPATH=/Users/clausklein/.local/bin/ninja
CMAKE_OSX_ARCHITECTURES:STRING=
CMAKE_OSX_DEPLOYMENT_TARGET:STRING=
CMAKE_OSX_SYSROOT:STRING=
fmt_DIR:PATH=/Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt
bash-5.3$ pwd
/Users/clausklein/Workspace/cpp/cxx20/fmt-module/build/dev/tests/find-package-test
bash-5.3$ ctest
Test project /Users/clausklein/Workspace/cpp/cxx20/fmt-module/build/dev/tests/find-package-test
Start 1: module_header-only-test
1/1 Test #1: module_header-only-test .......... Passed 0.00 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.01 sec
bash-5.3$ cd ../..
bash-5.3$ find . -name '*.pcm'
./CMakeFiles/fmt.dir/fmt.pcm
./CMakeFiles/__cmake_cxx23.dir/std.compat.pcm
./CMakeFiles/__cmake_cxx23.dir/std.pcm
./tests/find-package-test/CMakeFiles/__cmake_cxx23.dir/std.compat.pcm
./tests/find-package-test/CMakeFiles/__cmake_cxx23.dir/std.pcm
./_CPack_Packages/Darwin/TGZ/fmt-12.1.0-Darwin/lib/cmake/fmt/bmi-Clang_Release/fmt.pcm
bash-5.3$
bash-5.3$ ninja install
[0/2] Re-checking globbed directories...
[0/2] Install the project...
-- Install configuration: "Release"
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/args.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/base.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/chrono.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/color.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/compile.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/core.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/format-inl.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/format.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/os.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/ostream.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/printf.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/ranges.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/std.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/include/fmt/xchar.h
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/libfmt.a
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/module/fmt.cppm
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/bmi-Clang_Release/fmt.pcm <<<<<<<<
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/module/format.cc
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/module/os.cc
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/fmtConfig.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/fmtConfigVersion.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/fmtTargets.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/fmtTargets-release.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/./cxx-modules-fmtTargets.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/./cxx-modules-fmtTargets-Release.cmake
-- Installing: /Users/clausklein/Workspace/cpp/cxx20/fmt-module/stagedir/lib/cmake/fmt/./target-fmt-Release.cmake
bash-5.3$
There is currently no mechanism to determine if a prebuilt BMI file is suitable for consumption by a given TU and its command line. Once P2581 (or similar) is available, we can reuse installed BMIs. Note that CMake, today, currently assumes that all BMI usages are compatible. @vito.gamberini is working on fixing that assumption which will fix a number of filed issues.
install(TARGETS fmt-header-only EXPORT fmtTargets FILE_SET HEADERS)
if(FMT_USE_MODULES)
install(
TARGETS fmt
EXPORT fmtTargets
# XXX FILE_SET HEADERS
FILE_SET public_headers
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR} # Same as default, could be omitted
# XXX FILE_SET CXX_MODULES
FILE_SET public_modules DESTINATION ${FMT_INSTALL_CMAKEDIR}/module
# There's currently no convention for this location
CXX_MODULES_BMI
DESTINATION
${FMT_INSTALL_CMAKEDIR}/bmi-${CMAKE_CXX_COMPILER_ID}_$<CONFIG>
)
else()
install(TARGETS fmt EXPORT fmtTargets FILE_SET public_headers)
endif()
install(FILES module/fmt.cppm DESTINATION ${FMT_INSTALL_CMAKEDIR}/module)
install(FILES ${_fmt_all_sources} DESTINATION ${FMT_INSTALL_CMAKEDIR}/module)
Should the CXX_MODULES_BMI install the std.*.pcm files too?
No.
Sure, in the same sense it depends on the STL headers and the rest of the C++ stdlib.
We don’t install those either. We don’t install anything from your dependencies as part of your project. If you depend on fmt, we don’t install fmt alongside your project either.
The std.*pcm files are build 2 time!
First while building the fmt module.
And again, when build a program, the import the fmt module?
Yep, every project that uses import std; gets its own copy of the BMIs.
BMIs are basically PCHs, at least as far as this behavior is concerned. If you imagine every import std; as a PCH of the whole standard library, you’ll understand this behavior.
No, I do not understand!
My fmt.pcm seems to be reused, because there is only one?
What is the difference between the fmt.pcm and std.pcm?
Both are kind of PCH as you say, or not?
If in your project, you wrote code to generate a PCH of the whole standard library, what mechanism would you use to advertise that to other projects so they could re-use your PCH? (If they’re compatible with the options it was generated with)
That mechanism doesn’t exist. The STL is not a CMake project with a CMake configuration file pointing to “over here is my pre-built BMI”.
everything you say is true for the fmt module too.
Again, why is the fmt BMI file not generated 2 times?
fmt is a CMake package, it generates its own BMI, installs it alongside all the rest of its files when it is built and installed with the FMT_MODULE option (haven’t actually verified it installs BMIs, in principle it could).
The BMI fmt generates for itself is the canonical BMI, if your package is incompatible with that BMI (different language standard, etc) you would need to generate a new BMI for fmt to use it. There is no canonical source for the std BMI, so projects will always generate a new one.