Description
Description
I am trying to generate a Swift library that can be called from a C binary.
Expected behavior
- Generate a static or dynamic library based on Swift code
- Include the C header linked to this swift library in my C source code
- Link the Swift based library with my C object
- Demonstrate my C binary can call my Swift function
Actual behavior
- Generate a static or dynamic library based on Swift code [OK]
- Include the C header linked to this swift library in my C source code [FAILED]
The generated C header cannot be include because of errorerror: module 'MySwiftLib' requires feature 'objc'
Steps to reproduce
- Create sample project:
Package.swift
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "TestApp",
platforms: [.macOS(.v14), .iOS(.v13), .watchOS(.v6)],
products: [
.executable(name: "MyApp", targets: ["MyApp"]),
.library(name: "MySwiftLib", type: .static, targets: ["MySwiftLib"])
],
targets: [
.executableTarget(name: "MyApp",
cSettings: [
.headerSearchPath("../../.build/x86_64-apple-macosx/debug/MySwiftLib.build")
]/*,
linkerSettings: [
.unsafeFlags(["-Xlinker", "-rpath", "-Xlinker", "../../.build/x86_64-apple-macosx/debug/"]),
.linkedLibrary("MySwiftLib")
]*/
),
.target(name: "MySwiftLib",
swiftSettings: [
.interoperabilityMode(.C)
]
)
]
)
Sources/MySwiftLib/MySwiftLib.swift
@_cdecl("mySwiftFunc")
public func mySwiftFunc() {
print("Hello from Swift")
}
Sources/MyApp/main.c
#include <stdio.h>
#include "MySwiftLib-Swift.h"
void main() {
puts("Hello World from C!");
mySwiftFunc();
}
-
Build the static or dynamic (replace
.static
by.dynamic
inPackage.swift
) library with:swift build --product MySwiftLib
It produces./.build/x86_64-apple-macosx/debug/libMySwiftLib.a
and./.build/x86_64-apple-macosx/debug/MySwiftLib.build/MySwiftLib-Swift.h
when building a static library - and./.build/x86_64-apple-macosx/debug/libMySwiftLib.dylib
and./.build/x86_64-apple-macosx/debug/MySwiftLib.build/MySwiftLib-Swift.h
when building a dynamic library. -
Build the C app. I use
swift run
and it seems to requireobjc
:
/Users/olivier/dev/test_swift_lib/.build/x86_64-apple-macosx/debug/MySwiftLib.build/module.modulemap:1:8: error: module 'MySwiftLib' requires feature 'objc'
module MySwiftLib {
^
/Users/olivier/dev/test_swift_lib/Sources/MyApp/main.c:3:10: note: submodule of top-level module 'MySwiftLib' implicitly imported here
#include "MySwiftLib-Swift.h"
^
/Users/olivier/dev/test_swift_lib/Sources/MyApp/main.c:7:5: error: call to undeclared function 'mySwiftFunc'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
mySwiftFunc();
^
2 errors generated.
[0/2] Compiling MyApp main.c
Swift Package Manager version/commit hash
swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.50)
Swift & OS version (output of swift --version ; uname -a
)
swift-driver version: 1.87.3 Apple Swift version 5.9.2 (swiftlang-5.9.2.2.56 clang-1500.1.0.2.50
Target: x86_64-apple-macosx14.0
Darwin 23.2.0 Darwin Kernel Version 23.2.0; Wed Nov 15 21:54:10 PST 2023; root:xnu-10002.61.3~2/RELEASE_X86_64 x86_64
XCode 15.2 (15C500b)