Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use static C library with Swift package manager

I'd like to use the Swift package manager to include a static C library in my build. Apple's documentation shows the process with shared libraries but I'm hoping there's a way to use static. I am able to link against static libraries using swiftc, so it seems reasonable to hope that I should be able to do so using swift build.

I have a small example problem which uses a static C library containing a function for multiplying two numbers together. (Note: I'm running Swift 3 Preview 1 on Linux)

The directory structure that looks like this:

example/
    Package.swift
    main.swift
    .git/

CMult/
    Package.swift
    module.modulemap
    mult.h
    libmult.a
    .git/

Contents of example/Package.swift:

import PackageDescription

let package = Package(
    name: "example",
    dependencies: [
        .Package(url: "../CMult", majorVersion: 1)
    ]
)

Contents of example/main.swift:

import CMult

let n: Int32 = mult2(3, 5) // "int mult2(int,int)" is in mult.h and libmult.a
print("Result = \(n)")

Contents of CMult/Package.swift:

import PackageDescription

let package = Package(
    name: "CMult"
)

Contents of CMult/module.modulemap:

module CMult [system] {
    header "./mult.h"
    link "mult"
    export *
}

Now the problem is when I run example$ swift build, the linker complains with the error, "/usr/bin/ld: cannot find -lmult", which isn't surprising since it's not there and I haven't told it where else to look. What I'd like is some way to specify the -L flag in the module map, specifying where to look for the .a file (this is how I linked against my .a with swiftc). A less desirable but acceptable solution seemed to be to set the LD_LIBRARY_PATH environment variable to look in CMult/ but that didn't change the error.

Any ideas? Thanks.

like image 509
Philip Avatar asked Jul 21 '16 23:07

Philip


1 Answers

I'm not aware of a way to specify library locations in a module map, but here is what worked for me:

example$ swift build -Xlinker -L../CMult

You can find some other useful options by running

swift build --help

As for LD_LIBRARY_PATH, that's for searching shared libraries. For static it would be LIBRARY_PATH, but that one didn't work with swift build when I tried it. It does work with gcc, though.

like image 158
Anatoli P Avatar answered Sep 21 '22 03:09

Anatoli P