Search code examples
c++boostclangc++20c++-modules

clang++ error: () from module () is not present in definition of () in module ()


Clang and libc++ version: 15.0.7

Source

as.cppm:

export module as;
import <boost/asio.hpp>;
// import <iostream>;
export int main() {
}

Compile

(needs boost library)

clang++ -std=c++20 -stdlib=libc++ --precompile -xc++-system-header boost/asio.hpp
#Produces `asio.pcm`
clang++ -std=c++20 -stdlib=libc++ --precompile as.cppm -fmodule-file=asio.pcm
#Produces `as.pcm`

Everything works well

But if I uncomment line 3

Source:

as.cppm:

export module as;
import <boost/asio.hpp>;
import <iostream>;
export int main() {
}

Compile

(needs boost library)

clang++ -std=c++20 -stdlib=libc++ --precompile -xc++-system-header boost/asio.hpp
#Produces `asio.pcm`
clang++ -std=c++20 -stdlib=libc++ --precompile -xc++-system-header iostream
#Produces `iostream.pcm`
clang++ -std=c++20 -stdlib=libc++ --precompile as.cppm -fmodule-file=asio.pcm -fmodule-file=iostream.pcm
#Error

Error

pastebin

Why is it producing such error messages? I cannot find similar ones across google.

g++ 12.2 produces internal compiler error on the same code


Solution

  • I've encountered a similar problem to yours.

    In my case, I imported <format> and <iostream> together.

    $ clang++-18 -std=c++26 -x c++-system-header format iostream -stdlib=libc++
    # Produces `format.pcm` and `iostream.pcm`
    
    $ clang++-18 -std=c++26 -fmodule-file=format.pcm -fmodule-file=iostream.pcm -x c++ - -stdlib=libc++
    import <format>;
    import <iostream>;
    int main() { std::cout << std::format("clang {}\n", __clang_major__); }
    # Many errors like this:
    /usr/lib/llvm-18/bin/../include/c++/v1/string_view:344:5: error: 'std::basic_string_view<char>::basic_string_view' from module '/usr/lib/llvm-18/bin/../include/c++/v1/iostream' is not present in definition of 'std::string_view' in module '/usr/lib/llvm-18/bin/../include/c++/v1/format'
    

    The culprit is <string_view> in this case. Since both <format> and <iostream> include <string_view> directly or indirectly, generating format.pcm and iostream.pcm separately might mess up dependencies, leading to problems in the ODR Checking and declarations merging when parsing import <format>; and import <iostream>;. (See the official document)

    A temporary workaround might be generating string_view.pcm first and then generating format.pcm and iostream.pcm based on string_view.pcm.

    $ clang++-18 -std=c++26 -x c++-system-header string_view -stdlib=libc++
    # Produces `string_view.pcm`
    
    $ clang++-18 -std=c++26 -fmodule-file=string_view.pcm -x c++-system-header format iostream -stdlib=libc++
    # Produces `format.pcm` and `iostream.pcm` (with the same `string_view.pcm` dependency)
    
    $ clang++-18 -std=c++26 -fmodule-file=format.pcm -fmodule-file=iostream.pcm -x c++ - -stdlib=libc++
    import <format>;
    import <iostream>;
    int main() { std::cout << std::format("clang {}\n", __clang_major__); }
    # Produces `a.out`
    
    $ ./a.out
    clang 18
    

    In your case, you might generate stdexcept.pcm first and then generate asio.pcm and iostream.pcm based on stdexcept.pcm.

    Remember not to use this feature in a production environment until the compiler has stable support for it. You might also try the Standard Library Modules feature, which is much more convenient - only an import std; statement is needed.