Building Swift toolchain using gcc

Aloha-

As part of packaging Swift for Linux, I was asked by the reviewer (per https://bugzilla.redhat.com/show_bug.cgi?id=1536780) if there was any info about whether the Swift toolchain (at least up to the part where clang is used to build Swift itself) has ever been built, or even considered, with gcc. I have been making an honest attempt to try, and have found some minor differences (certain flags are not in gcc, gcc doesn't seem to like inferred directory paths). So far I've been able to get to within linking distance of llvm and no further.

I understand the strangeness of the question; I am doing this in good faith to conform as much as possible with the packaging guidelines. If there's any info about whether this is possible or not, I'd love to hear it.

Thanks,

Ron

2 Likes

Hi Ron,

You might be the first person to have tried this! We certainly would be happy to accept pull requests that help the Swift code-base build with GCC. If you get stuck, please post here with some of the error messages you're seeing (from GCC, the linker, whatever) and someone here will make suggestions.

Doug

4 Likes

Note that, although the compiler itself strives to be standard, portable C++11, the Swift runtime does rely on some extensions that are (at least currently) only implemented by the version of Clang that builds alongside the Swift compiler, in order to implement runtime functions with Swift calling conventions from C++ among other things.

Okay, so let me repeat what I think I understand: Setting aside GCC, the Swift toolchain is built using a system-installed clang, which as part of the build is a swift-specific clang that allows binaries to be built that allows for interoperability with C++, whereas the system clang presumably does not do that. With the system-installed clang, currently, I can build swift executables, but I haven't tried mixing and matching swift and c++, which, if I understand, won't work unless you use the swift-based clang executable.

So to facilitate this, I should make swift use the swift-specific clang, and not the system clang. On Linux a user may install clang and lldb independently of swift, so to make the swift-specific version of lldb available I patch where swift looks for lldb in swift/lib/Driver/ToolChains.cpp; do you know where swift looks for the clang executable? I've been looking and as far as I can tell, it expects to find it on the path but so far haven't identified the file where it explicitly calls it. I assumed it'd be in the same file (ToolChains.cpp) but haven't found it yet.

Thanks for any info,

Ron

As an update, I've been taking the approach of following MSVC support as it's a separate compiler being used to build everything, and I've gotten to the point where during linking of tools/clang/tools/c-index-test/CMakeFiles/c-index-test.dir/c-index-test.c I get a series of undefined references to all the libclang functions (e.g. clang_getCString()). Reading through the info on the llvm.org it's my understanding that these are internal clang functions that are used to work with clang itself, external of compiling code; GCC doesn't have these so the linking fails, okay, no problem. Where I'm lost is finding where MSVC gets around this problem at this stage; there are plenty of references to MSVC in the CMake files, but I haven't seen one that bypasses or otherwise 'solves' this particular issue.

It's also possible I'm completely wrong and am barking up the wrong tree. :crazy_face:

Ron

@Joe_Groff I've been looking at including the Swift-built version of Clang/Clang++ in my package, but while it's necessary to use this particular version for Swift/other language interoperability, it seems weird that it's not part of the final installation (i.e. in $SWIFT_BUILD/usr/bin) but is left in buildbot_linux/llvm-linux-x86_64/bin directory. Do you know if there's a setting in the build script to allow it to be installed alongside swift, or have an idea about why this isn't done?

The clang that's built alongside Swift is only necessary to build the runtime, and isn't otherwise of much use to users.

Oh, then I guess I misunderstood what that version of clang is for. I read your previous note as saying that the clang that is built as part of the Swift toolchain was necessary to allow Swift code to work with C/C++ code in the same binary. But, if I'm understanding you now (always a first time), the version of clang built as part of the Swift toolchain is just to facilitate building Swift, and once you have the swift binary, the system version of clang can be used and no Swift/C/C++ interoperability is lost?

Sorry for my confusion,

Ron

I should have been more clear too, I apologize. The Clang that's built alongside Swift has some extensions specifically to allow C++ functions to be defined with Swift-style calling conventions in order to implement some parts of the Swift runtime in C++. This isn't a general feature that's necessary for user-level Swift/C interop, though.

So the system-provided clang is sufficient for user-level Swift programming, regardless if there's any C/C++ interoperability (just confirming what I understand you're saying).

Yeah, or any C compiler that follows the target platform's standard ABI conventions.

Are the extensions required for building swift something that will be upstreamed in clang? How big is the delta between the clang built alongside Swift and the upstream release of clang it is base off of?

The calling-convention extensions used by Swift were upstreamed over a year ago, but we cannot count on the system C++ compiler not being much further out of date than that. Anyway, we find and fix bugs in those extensions every now and then, so building the runtime with the just-built Clang is a good idea regardless.

The Swift build process requires Clang to be built almost completely anyway (it's a core library dependency), it just doesn't technically need a Clang binary to be linked except to build the runtime.