C++20 modules and Objective-C++ (.mm) files?

I’ve the got the latest Clang and CMake and I’m trying to move my C++ project to use modules. It was working for pure C++ stuff but then I hit a problem with a .mm file. I can’t import My.Module from a .mm file.

That module is defined in a .cc file. Before, when using #include instead of import, there was a .h and .cc file, as usual, and it all worked – I could include the .h file from the .mm file.

Will this work with modules?

The error:

error: Objective-C was disabled in PCH file but is currently enabled

error: module file AppleInterop/CMakeFiles/AppleInterop.dir/AppleInterop.Strings.pcm cannot be loaded due to a configuration mismatch with the current compilation [-Wmodule-file-config-mismatch]
In file included from /Users/rob/Workspace/MonoRepo/AppleInterop/AppleInterop/UserDefaults.mm:7:
1 Like

Will this work with modules?

There are discussion about if we should support Standard C++ Modules with Traditional Clang Modules at the same time since it may be hard to support the compatible modes. And we don’t get the final consensus yet. And the status quo is that they may be workable together but nobody every actually tests it.

Then for your current problem, you can workaround the error message by adding -Xclang -fno-validate-pch to avoid the check.

1 Like

Thanks, that seems to work. I get another error now, but it may be unrelated to Objective-C. I have a #include <iostream> in a global module fragment, and also in a normal non-module c++ file, and they seem to conflict…

/llvm-project/build/bin/../include/c++/v1/__compare/synth_three_way.h:28:45: error: redefinition of '__synth_three_way' as different kind of symbol
_LIBCPP_HIDE_FROM_ABI inline constexpr auto __synth_three_way =

/llvm-project/build/bin/../include/c++/v1/__utility/pair.h:13:10: note: '/Users/rob/Dev/llvm-project/build/bin/../include/c++/v1/__compare/synth_three_way.h' included multiple times, additional include site in header from module 'AppleInterop.Strings.<global>'
#include <__compare/synth_three_way.h>

C++ Standard library and C++20 modules have not shipped yet. They are still working on it: ⚙ D144994 [Draft][libc++][modules] Adds std module..

But I should still be able to #include <iostream> it from a module, no? I’m not trying to do import std.

You can describe this formally with a reproducer in the Github issues: Issues · llvm/llvm-project · GitHub

Done. Using import and #include causes redeclaration errors · Issue #61329 · llvm/llvm-project · GitHub

Those flags seemed to work for some files, but on others I get errors like the ones below, which I don’t understand. They seem to be related to the Objective-C++ again, because if I change the file to .cc (and strip about enough function bodies to get rid of Obj-C syntax), then the error goes away.

Maybe I need to use the C API to Obj-C (objc_msgSend, etc), which won’t require these .mm files with Obj-C syntax. That will take some work for things like creating Obj-C subclasses.

In module 'Common.Range' imported from /Users/rob/Workspace/MonoRepo/AppleInterop/AppleInterop/CoreText.h:17:
/Users/rob/Dev/llvm-project/build/bin/../include/c++/v1/string_view:329:5: error: 'std::basic_string_view<char>::basic_string_view' from module 'Common.Range.<global>' is not present in definition of 'std::string_view' provided earlier
    basic_string_view(_Range&& __r) : __data_(ranges::data(__r)), __size_(ranges::size(__r)) {}
    ^
/Users/rob/Dev/llvm-project/build/bin/../include/c++/v1/string_view:289:5: note: declaration of 'basic_string_view' does not match
    basic_string_view() _NOEXCEPT : __data_(nullptr), __size_(0) {}
...