Trouble creating Swift library package around system library

I'm trying to make a system library target. I successfully made an old-style system-module package, and was able to import that into an SPM executable, and call a function (you can see this here).

Now I want to wrap a Swifty library around this C-library (libSDL2.dylib), and so I'm trying to make the system library target as part of my SPM library. Here's what I've got so far:

When I try to swift build it, I get

…/SwiftSDL/Sources/SwiftSDL/SDLWindow.swift:1:8: error: no such module 'CSDL2'
import CSDL2
       ^
…/SwiftSDL/Sources/SwiftSDL/SDLWindow.swift:1:8: error: no such module 'CSDL2'
import CSDL2
       ^

(I don't know why the same error is displayed twice).

I don't think it's actually trying to compile the underlying module, as I introduced a syntax error into the shim header and it didn't complain. I also don't get the complaint about pkg-config providing a non-whitelisted flag -D_THREAD_SAFE, which I get in the old-style package above.

// swift-tools-version:5.0

import PackageDescription

let package = Package(
	name: "SwiftSDL",
	products: [
		.library(
			name: "SwiftSDL",
			targets: ["SwiftSDL"]),
	],
	dependencies: [
	],
	targets: [
		.target(
			name: "SwiftSDL",
			dependencies: []),
		.testTarget(
			name: "SwiftSDLTests",
			dependencies: ["SwiftSDL"]),
		.systemLibrary(
			name: "CSDL2",
			path: "Sources/CSDL2",
			pkgConfig: "sdl2",
			providers: [
				.brew(["sdl2"]),
				.apt(["libsdl2"])
			]),
	]
)

module.modulemap looks like this:

module CSDL2 [system]
{
	umbrella header "CSDL2.h"
	link "CSDL2"
	export *
}

I’ve tried it with and without [system], umbrella, export *.

I don’t really understand how the system library target is supposed to be used, but this seems like a reasonable way to use it. Any help is much appreciated. Thanks!

You need to add CSDL2 as a dependency to SwiftSDL target.

1 Like

Well, when you put it like that, it seems obvious. :flushed:

So, there are dependencies at the Package level, and at the Target level. How do those differ?

EDIT: I think I understand. That fetches additional packages, but the targets must depend on other targets.

Is there a way to export CSDL2 from SwiftSDL so that a client that depends on SwiftSDL can also call into CSDL2?

There is @_exported import SomeModule, which is used frequently within the Swift project, but is underscored because its spelling and some semantic details still aren’t finalized. You can use it safely as long as you don’t care about source compatibility with future releases of Swift.

1 Like
Terms of Service

Privacy Policy

Cookie Policy