Skip to content

Failed to generate a static or dynamic Swift library called by C code #7257

Open
@oliviermartin

Description

@oliviermartin

Description

I am trying to generate a Swift library that can be called from a C binary.

Expected behavior

  1. Generate a static or dynamic library based on Swift code
  2. Include the C header linked to this swift library in my C source code
  3. Link the Swift based library with my C object
  4. Demonstrate my C binary can call my Swift function

Actual behavior

  1. Generate a static or dynamic library based on Swift code [OK]
  2. Include the C header linked to this swift library in my C source code [FAILED]
    The generated C header cannot be include because of error error: module 'MySwiftLib' requires feature 'objc'

Steps to reproduce

  1. 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();
}
  1. Build the static or dynamic (replace .static by .dynamic in Package.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.

  2. Build the C app. I use swift run and it seems to require objc:

/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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions