Using a dynamically linked C library (.dylib) from SPM

I have compiled some C code and built a .dylib. I also have a C header for this .dylib.

I want to create a target for it in Swift Package Manager. I would then like to use that target as a dependency in a Swift only (source) package, so I can write/test a nicer way to do the C interop in Swift.

There are a lot of examples for system libraries, but I haven't found a single one for using a .dylib/C Header that I've created. Or they all are based on having the C source. I've searched for hours and am close to just giving up and opening a TSI.

If an example isn't available, answers to the following will help me move forward I think:

  • Does SPM support bridging headers?
  • Are system libraries the only way to use a .dylib?
  • Does SPM support embedding a .dylib this way?
  • To embed a .dylib, do I just add it as a .copy resource in the "C" package?
  • Do I need to add a cSettings flag for the dylib?
  • Do I need a module map?

I should note I can't just drop the source in (of which there are some examples for) because this is actually a Ziglang project, that I am compiling to a .dylib and using the C ABI. I was able to use my .dylib and C header in a test macOS app, but can't seem to figure out how to access the code using SPM. So I don't think it's a problem with my Zig code.

I'm not a C programmer, so please forgive any incorrect terms/ideas. I'd love to make this work!

Thanks!

Here's what I currently have in my Package.Swift file (ZigTools is the Swift Source package, ZigSyntaxChecker is where I'm trying to link the dylib and use the header file):

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
  name: "ZigTools",
  products: [
    .library(
      name: "ZigTools",
      targets: ["ZigSyntaxChecker", "ZigTools"]),
  ],
  dependencies: [],
  targets: [
    .target(
      name: "ZigTools",
      dependencies: ["ZigSyntaxChecker"],
      path: "Sources/ZigTools")
    ,
    .target(
      name: "ZigSyntaxChecker",
      dependencies: [],
      path: "Sources/ZigSyntaxChecker",
      exclude: [
        "src/",
        "README.md",
        "build.zig"
      ],
      resources: [
        Resource.copy("libZigSyntaxChecker.dylib"),
      ],
      publicHeadersPath: "include",
      cSettings: [
        .headerSearchPath("include/ZigSyntaxChecker.h")
      ]
    ),
    .testTarget(
      name: "ZigToolsTests",
      dependencies: ["ZigTools"]
    ),
  ]
)

My package file tree:

This currently gives the following error on the ZigToolsTests target:

Build input file cannot be found: 
'/Users/rudedogg/Library/Developer/Xcode/DerivedData/ZigTools-.../Build/Products/Debug/ZigSyntaxChecker.o'.

I assume this is just a sign of larger issues in my Package.swift configuration.

Terms of Service

Privacy Policy

Cookie Policy