[swift-build-dev] importing a *local* native dependency

Drew Crawford drew at sealedabstract.com
Fri Dec 25 02:19:19 CST 2015

I'm trying to package a Swift library.  This Swift library is tightly coupled to a native library.  By "tightly coupled" here I really mean that only half the library is written in Swift, and the other half, as an implementation detail, is in some other language.

You *probably* do not have a build environment for this other language just lying around, so my plan (actually, my current practice) is to distribute binaries of the non-Swift part, just checked into source control, and then link against them with a module map.  Yes, I realize this isn't portable, but neither is anything else in this project, so I'll save that particular surprise for another day.

The trouble is, swiftpm wants there to be some "other" repo called `CFoo` containing only a modulemap with paths that point to... /usr/local I guess? <https://github.com/apple/swift-package-manager/blob/master/Documentation/SystemModules.md>  But 

1.  There is no other repo
2.  You have not installed the non-Swift half of my library to /usr/local
3.  You do not want to link against "some" version of the binary blob you have lying around from times past.  You want to link against exactly the one I give you, because the work is versioned as a whole.

I see two solutions to this problem.

# Non-URL dependencies

Behind this door, I can write a Package.swift like this:

let package = Package(
    name: "Foo",
    dependencies: [
        .Package(path: "CFoo"),

The semantic of this is that Foo depends on a package CFoo that is merely a folder in the current repository (e.g., we do not need to clone it from somewhere else).

In my case CFoo would contain a module.map and a binary blob, but in the general case it is any arbitrary kind of package.

This solves my three problems since 1) There's only one repo, 2) The binary is located with repo-based paths, 3) You're linking against the particular CFoo distributed in the repository.

# Custom include paths

Another possibility goes like this:

let package = Package(
    name: "Foo",
    extraIncludePaths: ["CFoo"]

The semantic of this is that we pass `-I CFoo` to swiftc (e.g. that is emitted into `other-args` of llbuild.yaml)

In my case CFoo contains a module.map and a binary blob, but in the general case it contains any kind of header path that a package may want to import.

There are certainly other possibilities besides these two, I'm just suggesting them because they seem straightforward based on my poking around in the sourcecode today.

I am happy to contrib either of these (or something else proposed) but would like to achieve consensus on a design instead of PRing by surprise.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-build-dev/attachments/20151225/66a1e576/attachment.html>

More information about the swift-build-dev mailing list