Linking C++ with Swift

I'm having a little trouble getting some C++ code to link with my Swift code.
I'm not currently using any package. FWIW the main function is in the C++ code.

My makefile looks like this:

swiftc -v -Xlinker --verbose -o foo -import-objc-header bridge.h\
 MyCppThing.o someCcode.o MySwiftClass.swift \
-L/usr/lib/aarch64-linux-gnu/ -lvariousStuff -lpthread -lstdc++

The error I get after much successful compiling is:

(unknown):51: error: undefined reference to 'vtable for MyCppThing'
/usr/bin/ the vtable symbol may be undefined because the class is missing its key function

As you can see I'm trying to elicit some verbosity in the linker output but that's not happening. I'm just getting a cryptic error about a missing vtable. In my C++ class, everything is accounted for. All defined methods are implemented.

Anyone know what could be going on? My binaries are:

Swift version 5.9-dev (LLVM 726983520b3cae8, Swift a3ac122d046f663)
Target: aarch64-unknown-linux-gnu
1 Like

Hmm. That could easily be a bug in C++ interop if the v-table needs to be emitted lazily. There’s a walk we do over imported inline function bodies to mark the lazy definitions they use, but it’s easy to imagine that it might not consider v-tables. @egor.zhdan, is this in your space?

The simplest workaround would be to define whatever constructor or destructor that you’re calling on that C++ class in an implementation file. Either that or give the class a key function by defining at least one of its virtual functions in an implementation file.


I've currently got the C++ constructor and destructor in the .cpp file.
There aren't any virtual functions that I've defined but when I set the destructor to virtual I get the same output.

If the the class doesn't declare any virtual functions, it must be inheriting them, or else it wouldn't have a v-table at all. Regardless, as long as it's not a template class, you can give it a key function and anchor the v-table to a file by declaring at least one virtual function in the class and then defining it non-inline in a .cpp file.

The constructor and destructor are usually the only functions that directly reference the v-table, so if those aren't defined inline in the header, I don't know why the Swift translation unit would reference it. Are you sure your C++ code links without Swift being involved?

This is difficult to debug without being able to look at source.

It turns out that was the question that led me to fix the problem. There was an object file missing.
Thanks :slight_smile:

1 Like