According to official documentation, Clang 13 supports C++20 Modules thru the use of a -fmodules
command-line parameter.
I cannot even get a basic module to compile using Clang 13 (macOS Monterey) either on an Intel or M1 based macs.
Assuming the following text contents of file module.cpp
:
export module a;
export int f(int a, int b) {
return a + b;
}
Running the following:
$ clang++ --version
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: x86_64-apple-darwin21.1.0
$ clang++ -std=c++20 -stdlib=libc++ -fmodules -fbuiltin-module-map -c module.cpp
module.cpp:1:8: error: expected template
export module a;
^
module.cpp:1:8: error: unknown type name 'module'
module.cpp:3:8: error: expected template
export int f(int a, int b) {
^
3 errors generated.
Tested with identical results on an ARM M1 chip:
$ clang++ --version
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: arm64-apple-darwin21.1.0
Is there another way to get modules working OR is there some undocumented C++20 modules limitation with Apple Clang 13?
Note: compiling with the experimental -fmodules-ts
flag works.
Thanks for the comments - the errors above are an indication of a Clang version that was built without module support. This is what Xcode comes with, i.e. by running xcode-select --install
in a terminal.
As suggested the solution has been to install Clang thru HomeBrew which is done as follows (tested on macOS Monterey):
brew install llvm
Clang gets installed to /opt/homebrew/opt/llvm/bin/clang++
. Confirm the running version as shown below:
% /opt/homebrew/opt/llvm/bin/clang++ --version
Homebrew clang version 13.0.0
Target: arm64-apple-darwin21.1.0
Thread model: posix
InstalledDir: /opt/homebrew/opt/llvm/bin
Which is a different build from the Xcode system-wide default version:
% clang++ --version
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: arm64-apple-darwin21.1.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Steps to see working example loosely based on repo posted by @alexpanter:
main.cpp
import <iostream>;
import mathlib;
using namespace std;
int main() {
cout << "Modules, baby!" << endl;
cout << "2 plus 3 makes " << add(2, 3) << " says module 'mathlib'" << endl;
}
mathlib.cpp
export module mathlib;
export int add(int a, int b)
{
return a + b;
}
Build by runnning in a terminal in same directory as files above:
/opt/homebrew/opt/llvm/bin/clang++ -std=c++20 -c -Xclang -emit-module-interface mathlib.cpp -o mathlib.pcm
/opt/homebrew/opt/llvm/bin/clang++ -std=c++20 -fmodules -c -fprebuilt-module-path=. main.cpp -o main.o
/opt/homebrew/opt/llvm/bin/clang++ -std=c++2a -fmodules -o main main.o *.pcm
Test module-based executable:
./main
Expected output:
Modules, baby!
2 plus 3 makes 5 says module 'mathlib'