# Why are the build and installed BMI files not used?

**URL:** https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367
**Category:** Development
**Tags:** os:macos, gen:ninja
**Created:** [December 6, 2025, 1:18pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367 "2025-12-06T13:18:10Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [December 6, 2025, 1:18pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/1 "2025-12-06T13:18:10Z")

</div>

```bash
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$

```

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 6, 2025, 1:28pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/2 "2025-12-06T13:28:56Z")

</div>

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](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2581r2.pdf) (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.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [December 6, 2025, 1:42pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/3 "2025-12-06T13:42:34Z")

</div>

```cmake
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?

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [December 6, 2025, 9:02pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/4 "2025-12-06T21:02:54Z")

</div>

> [@ClausKlein](#):
>
> Should the `CXX_MODULES_BMI` install the `std.*.pcm` files too?

No.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [December 6, 2025, 9:20pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/5 "2025-12-06T21:20:05Z")

</div>

### But the installed project libray and its `BMI` depends on it, or not?

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [December 6, 2025, 9:22pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/6 "2025-12-06T21:22:51Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [December 6, 2025, 9:30pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/7 "2025-12-06T21:30:23Z")

</div>

> [@ClausKlein](#):
>
> ```auto
> 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$
> 
> ```

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?

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [December 6, 2025, 9:34pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/8 "2025-12-06T21:34:27Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [December 6, 2025, 9:43pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/9 "2025-12-06T21:43:57Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [December 6, 2025, 10:00pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/10 "2025-12-06T22:00:44Z")

</div>

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”.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [December 6, 2025, 10:06pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/11 "2025-12-06T22:06:53Z")

</div>

everything you say is true for the `fmt module` too.

Again, why is the fmt BMI file not generated 2 times?

---

<div class="post-metadata">

### Author: ![vito.gamberini](https://discourse.cmake.org/user_avatar/discourse.cmake.org/vito.gamberini/32/4376_2.png) [@vito.gamberini](https://discourse.cmake.org/u/vito.gamberini)
#### Post date: [December 6, 2025, 10:12pm UTC](https://discourse.cmake.org/t/why-are-the-build-and-installed-bmi-files-not-used/15367/12 "2025-12-06T22:12:05Z")

</div>

`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.
