LLVM fails to build with modules

I'm trying build a recent LLVM main as a reference for my work integrating Swift's C++ interop with MLIR. As I understand it, C++ interop requires clang modules be enabled via LLVM_ENABLE_MODULES (though I've noticed there is no mention of this here: GitHub - apple/swift-llvm-bindings: Swift Bindings for LLVM Project APIs)). When I try to build check-llvm I now run into a large number of errors similar to the following:

[build] /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/unique_ptr.h:37:10: note: '/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/tuple' included multiple times, additional include site in header from module 'LLVM_Utils.ADT.Any'

Has anyone else run into this? Am I missing something?

are you using libstdc++? Libstdc++ is not modularized, so that's probably why you're hitting this.

1 Like

I don't think this is required. Swift always enables clang modules when importing C/C++ headers, however, when building C/C++, you don't necessarily have to use modules. For example, we don't enable modules when building LLVM or Swift, but we're still able to use LLVM & Swift headers in SwiftCompilerSources.

@Alex_L is right, the error that you're seeing is caused by libstdc++ not being modularized. The Swift compiler works around this by injecting a modulemap into libstdc++ when importing C++ headers.

1 Like

Hmm… so this has been failing for me on recent nightlies, even if I turn LLVM_ENABLE_MODULES to OFF. Would there be some reason the Swift compiler fails to inject this modulemap? Is there a way I can diagnose this?

One of the first errors I'm running into is:

/workspaces/llvm-workspace/llvm-project/llvm/include/llvm/ADT/StringRef.h:96:43: error: no type named 'string_view' in namespace 'std'
     /*implicit*/ constexpr StringRef(std::string_view Str)

Could this be an issue with the modulemap for std used by the Swift compiler?

UPDATE It looks like this may be a C++ 17 issue... I'm not sure where this is being misinterpreted though.

Is there a flag I can pass to swiftc to enable C++17 mode?

-Xfrontend -Xcc -Xfrontend -std=gnu++17

1 Like

I also get away with -Xcc -std=c++17

2 Likes

Thanks! I forgot that -std was different from -stdlib=libc++.

I'm running into some different errors, both with gnu++17 and c++17, the most salient of which seems to be:

/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/functional:54:10: note: in file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/functional:54:
#include <tuple>
         ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/tuple:1849:27: error: redefinition of '__unpack_std_tuple<_Trait, _Tp, const tuple<_Up...> &>'
    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>

This looks like a modularization issue with libstdc++. I think I know a solution, I submitted a patch to fix this error.

Thanks @egor.zhdan!

@egor.zhdan I have a new issue after trying with an updated compiler version that I think may be the same problem:

/workspaces/llvm-workspace/llvm-project/llvm/include/llvm/Support/MathExtras.h:313:22: error: no template named 'is_same_v' in namespace 'std'; did you mean 'is_same'?
if constexpr (std::is_same_v<T, uint64_t>)

I'd wager this won't be the last one. Any chance we could add a flag to the Swift compiler to specify a modulemap for libstdc++ at compile time? At least as a development aid?

This doesn't look like a modularization issue: both std::is_same and std::is_same_v are defined in the same header (type_traits) so it's likely that the header got its module assigned correctly.

I think this might be a result of wrong C++ standard version being passed to clang. Could you please try passing -Xcc -std=c++20 to the Swift compiler?

1 Like

Ah right, sorry I seem to have lost this flag in between git branches.

1 Like