# C++20 module seems to be broken (missing transitive usage) in a very specific case

**URL:** <https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537>\
**Category:** Code\
**Tags:** gen:ninja\
**Created:** [December 1, 2023, 8:06am UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537 "2023-12-01T08:06:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![cpplearner](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/c/3bc359/32.png) [@cpplearner](https://discourse.cmake.org/u/cpplearner)\
**Post date:** [December 1, 2023, 8:06am UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/1 "2023-12-01T08:06:09Z")

</div>

I am learning to use C++20 module with CMake 2.38.0-rc4, and I noticed a possible bug in CMake.

CMakeLists.txt:

```auto
cmake_minimum_required(VERSION 3.28.0)

project(MyLib LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)

add_library(my-lib)

target_sources(my-lib PRIVATE FILE_SET CXX_MODULES FILES
    mod1.cpp
    mod3.cpp # import mod2
    mod4.cpp # import mod2
    mod2.cpp # import mod1
    mod5.cpp # import mod4
    mod6.cpp # import mod5
)

```

All module units are empty except for the imports as indicated in the comments above.

When compiling this project against Clang, I got

```auto
[13/14] Building CXX object CMakeFiles/my-lib.dir/mod6.cpp.o
/mnt/d/test/test-module/mod6.cpp:2:1: warning: it is deprecated to read module 'mod1' implicitly; it is going to be removed in clang 18; consider to specify the dependencies explicitly [-Wread-modules-implicitly]
    2 | import mod5;
      | ^
1 warning generated.
warning: it is deprecated to read module 'mod1' implicitly; it is going to be removed in clang 18; consider to specify the dependencies explicitly [-Wread-modules-implicitly]
1 warning generated.

```

It seems that CMake forgets to tell Clang the location of `mod1.pcm` when compiling `mod6.cpp`.

Note that the order of files in `target_souces` is significant. The warning might not occur if the files are listed in a different order.

Does this sound like a bug of CMake? Is this a known bug?

> **For the reference, here are the contents of \`mod1.cpp\` through \`mod6.cpp\`**
>
> mod1.cpp:
> 
> ```auto
> export module mod1;
> 
> ```
> 
> mod2.cpp:
> 
> ```auto
> export module mod2;
> import mod1;
> 
> ```
> 
> mod3.cpp:
> 
> ```auto
> export module mod3;
> import mod2;
> 
> ```
> 
> mod4.cpp:
> 
> ```auto
> export module mod4;
> import mod2;
> 
> ```
> 
> mod5.cpp:
> 
> ```auto
> export module mod5;
> import mod4;
> 
> ```
> 
> mod6.cpp:
> 
> ```auto
> export module mod6;
> import mod5;
> 
> ```

---

<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 1, 2023, 11:35am UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/2 "2023-12-01T11:35:15Z")

</div>

> [@cpplearner](#):
>
> Does this sound like a bug of CMake? Is this a known bug?

It does sound like a bug; not known before.

> [@cpplearner](#):
>
> Note that the order of files in `target_souces` is significant.

I’m guessing that we need to do 2 full passes over the modules in order to support transitive module tracking properly. Thanks for the test case.

Thanks; do you mind [filing an issue](https://gitlab.kitware.com/cmake/cmake/-/issues) to track this?

---

<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:** [April 9, 2024, 8:53pm UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/3 "2024-04-09T20:53:08Z")

</div>

### With this example I see the same warning:

```cpp
module;

//XXX #include <fmt/core.h>
import fmt;

module algo;

void Algo::helloWorld()
{
  fmt::print("hello {}\n", m_name);
}

```

```bash
bash-5.2$ ninja Algo -j 1
[4/6] Building CXX object CMakeFiles/Algo.dir/algo-interface.cppm.o
warning: it is deprecated to read module 'fmt' implicitly; it is going to be removed in clang 18; consider to specify the dependencies explicitly [-Wread-modules-implicitly]
1 warning generated.
[5/6] Building CXX object CMakeFiles/Algo.dir/algo-impl.cpp.o
warning: the form '-fmodule-file=<BMI-path>' is deprecated for standard C++ named modules;consider to use '-fmodule-file=<module-name>=<BMI-path>' instead [-Weager-load-cxx-named-modules]
warning: the form '-fmodule-file=<BMI-path>' is deprecated for standard C++ named modules;consider to use '-fmodule-file=<module-name>=<BMI-path>' instead [-Weager-load-cxx-named-modules]
/Users/clausklein/Workspace/cpp/cxx20/cmake-init-modules/algo-impl.cpp:6:1: warning: it is deprecated to read module 'fmt' implicitly; it is going to be removed in clang 18; consider to specify the dependencies explicitly [-Wread-modules-implicitly]
    6 | module algo;
      | ^
3 warnings generated.
[6/6] Linking CXX shared library libAlgo.dylib
bash-5.2$ 

bash-5.2$ cmake --version
cmake version 3.29.20240409-g24f1e7c

CMake suite maintained and supported by Kitware (kitware.com/cmake).
bash-5.2$ clang --version
Homebrew clang version 17.0.6
Target: x86_64-apple-darwin23.4.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
bash-5.2$ 

```

I is the extended example from @craig.scott[C++20 Modules, CMake, And Shared Libraries](https://crascit.com/2024/04/04/cxx-modules-cmake-shared-libraries/)

---

<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:** [April 9, 2024, 11:46pm UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/4 "2024-04-09T23:46:49Z")

</div>

Can you please provide:

- `.ddi` file for `algo-interface.cppm` and `algo-impl.cpp`
- `.modmap` for `algo-interface.cppm.o` and `algo-impl.cpp.o`
- `CXX*.json` files for the `Algo` target
- `cmake --version`

One thing I see is that you’re importing in the global module fragment; this is certainly weird at least. Does this work instead?

```cxx
module algo;

import fmt;

// …

```

---

<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:** [April 10, 2024, 1:00pm UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/5 "2024-04-10T13:00:10Z")

</div>

> [@ben.boeckel](#):
>
> One thing I see is that you’re importing in the global module fragment; this is certainly weird at least. Does this work instead?

Yes, but now it fails with different error:

```bash
Executing workflow step 2 of 3: build preset "dev"

[19/27] Building CXX object CMakeFiles/Algo.dir/algo-impl.cpp.o
FAILED: CMakeFiles/Algo.dir/algo-impl.cpp.o 
/usr/local/opt/llvm/bin/clang++ -DAlgo_EXPORTS -DFMT_HEADER_ONLY=1 -I/Users/clausklein/Workspace/cpp/cxx20/cmake-init-modules/build/dev -isystem /Users/clausklein/.cache/CPM/fmt/c3ebf53335b44df838d9982d1a0e35afe190e34f/include -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wformat=2 -Wundef -Werror=float-equal -Wshadow -Wcast-align -Wunused -Wnull-dereference -Wdouble-promotion -Wimplicit-fallthrough -Wextra-semi -Woverloaded-virtual -Wnon-virtual-dtor -Wold-style-cast -g -std=c++20 -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.4.sdk -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -MD -MT CMakeFiles/Algo.dir/algo-impl.cpp.o -MF CMakeFiles/Algo.dir/algo-impl.cpp.o.d @CMakeFiles/Algo.dir/algo-impl.cpp.o.modmap -o CMakeFiles/Algo.dir/algo-impl.cpp.o -c /Users/clausklein/Workspace/cpp/cxx20/cmake-init-modules/algo-impl.cpp
/Users/clausklein/Workspace/cpp/cxx20/cmake-init-modules/algo-impl.cpp:8:8: fatal error: module 'fmt' not found
    8 | import fmt;
      | ~~~~~~~^~~
1 error generated.
[21/27] Linking CXX shared library _deps/fmt-build/libfmtd.10.2.1.dylib
ninja: build stopped: subcommand failed.
make: *** [all] Error 1
bash-5.2$ cd build/dev/
bash-5.2$ tree _deps/fmt-build/
_deps/fmt-build/
|-- CMakeFiles
| |-- Export
| | `-- b834597d9b1628ff12ae4314c3a2e4b8
| | |-- fmt-targets-debug.cmake
| | `-- fmt-targets.cmake
| `-- fmt.dir
|-- cmake_install.cmake
|-- fmt-config-version.cmake
|-- fmt-config.cmake
|-- fmt-targets.cmake
|-- fmt.o
|-- fmt.pc
|-- fmt.pcm
`-- libfmtd.10.2.1.dylib

5 directories, 10 files
bash-5.2$ 

```

---

<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:** [April 10, 2024, 1:23pm UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/6 "2024-04-10T13:23:54Z")

</div>

@DanielaE It seems, that the` fmt v10.2.1` **C++20 module** does not build to be usable?

---

<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:** [April 10, 2024, 1:43pm UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/7 "2024-04-10T13:43:03Z")

</div>

> [@ben.boeckel](#):
>
> Can you please provide:
> 
> - `.ddi` file for `algo-interface.cppm` and `algo-impl.cpp`
> - `.modmap` for `algo-interface.cppm.o` and `algo-impl.cpp.o`
> - `CXX*.json` files for the `Algo` target
> - `cmake --version`

you find the contents here [Use C++20 fmt module #3](https://github.com/ClausKlein/cmake-init-modules/pull/3/files#diff-86dd0a518024f456453abb5fcc81a4868dba024d43015d80f9f955c8b7cbc0c9)

---

<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:** [April 12, 2024, 5:25pm UTC](https://discourse.cmake.org/t/c-20-module-seems-to-be-broken-missing-transitive-usage-in-a-very-specific-case/9537/8 "2024-04-12T17:25:01Z")

</div>

I don’t see your build scanning the `fmt` module. You cannot use BMI files not compiled as part of the project. It seems that `fmt` is not being provided as an `IMPORTED` target with `CXX_MODULES`-typed `FILE_SET` sources to let CMake know about its modules.
