I have a pure Swift package that I built with the Swift Package Manager. My Package.Swift
looks like this:
// File: Package.swift
// swift-tools-version:5.2
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "SwiftPackage",
products: [
.library(
name: "SwiftPackage",
type: .static,
targets: ["SwiftPackage"]),
],
dependencies: [
],
targets: [
.target(
name: "SwiftPackage",
dependencies: []),
.testTarget(
name: "SwiftPackageTests",
dependencies: ["SwiftPackage"]),
]
)
This Swift code I'm building contains a public function that I want to call from my C++ code:
// File: SwiftPackage.swift
public func StartWatcher() {
// code ...
}
I created a header file SwiftPackage.hh
where I define the StartWatcher
function like so:
// File: SwiftPackage.hh
void (*StartWatcher)();
Now I have my main.cc
file where I include the SwiftPackage.hh
and call the StartWatcher
function:
// File: main.cc
#include <SwiftPackage.hh>
int main() {
StartWatcher();
return 0;
}
However, when I run the built executable I'm getting the following error
./swift_package' terminated by signal SIGSEGV (Address boundary error)
Building
My build process is following:
- First, I build the Swift package by running
swift build --package-path SwiftPackage
. This creates thelibSwiftPackage.a
library. - Second, I build the C++ project where I link the
libSwiftPackage.a
library that was created in the previous step:
g++ -std=c++11 -L./SwiftPackage/.build/debug/ main.cc -lSwiftPackage -o swift_package
What am I doing wrong? I suspect that the Swift library isn't properly linked.
Edit
Based on the @Acorn's answer I did two things:
- Added my
StartWatcher
declarition in anextern "C"
block - Added an attribute
@_cdecl("StartWatcher")
to myStartWatcher
Swift function which should make sure that the name isn't mangled in the library.
Now I get a different output which is a bunch of messages like this:
Undefined symbols for architecture x86_64:
"static Foundation.Notification._unconditionallyBridgeFromObjectiveC(__C.NSNotification?) -> Foundation.Notification", referenced from:
@objc SwiftPackage.AppDelegate.applicationDidFinishLaunching(Foundation.Notification) -> () in libSwiftPackage.a(AppDelegate.swift.o)
@objc SwiftPackage.AppDelegate.applicationWillTerminate(Foundation.Notification) -> () in libSwiftPackage.a(AppDelegate.swift.o)
It seems to me that the there is some kind of problem accessing other libraries that are used in the Swift package?