I have an open source Objective C framework, which I'd like to provide using Swift Package Manager as well.
Normally, I have public headers set in the Xcode project, which, when the framework is built, are copied under the framework bundle, and are discovered when linked to by Xcode.
I can't, however get it to work with SwiftPM.
I created a modulemap for my framework:
framework module LNPopupController {
umbrella header "LNPopupController.h"
export *
module * { export * }
}
and I define the library like so in the Package.swift:
let package = Package(
name: "LNPopupController",
platforms: [
.iOS(.v12),
.macOS(.v10_15)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "LNPopupController",
type: .dynamic,
targets: ["LNPopupController"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "LNPopupController",
dependencies: [],
path: "LNPopupController",
publicHeadersPath: ".",
cSettings: [
.headerSearchPath("."),
.headerSearchPath("Private"),
]),
]
)
When added as a project dependency in Xcode, the framework compiles just fine, but when the dependent target attempts to import LNPopupController
, an error is thrown: umbrella header 'LNPopupController.h' not found
Looking at the build folder, indeed, I see that Xcode has built a binary, but has not copied the public headers.
Any way to specify which headers are public, and make the build system copy them for import?
I eventually figured it out. This is what I did for LNPopupController:
I created a include/LNPopupController/
sub-directory tree, and put soft links to all public headers there.
In the package file, I added publicHeadersPath: "include"
.
You can see the final result here: https://github.com/LeoNatan/LNPopupController/blob/master/Package.swift
It might not be the most optimal way, but it works for all my ObjC projects which I have tried this method on.