Search code examples
c++c++20clang++macos-montereyc++-modules

Apple Clang 13 C++20 Module Support Missing


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.


Solution

  • Cause

    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.

    Solution

    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
    

    Working Example

    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'