Home » Swift » xcrun swift on command line generate <unknown>:0: error: could not load shared library

xcrun swift on command line generate <unknown>:0: error: could not load shared library

Posted by: admin January 9, 2018 Leave a comment

Questions:

My goal is to try run my Swift program like a script. If the whole program is self-contained, you can run it like:

% xcrun swift hello.swift

where hello.swift is

import Cocoa
println("hello")

However, I want to go one step beyond this, and include swift module, where I can import other classes, funcs, etc.

So lets say we have a really good class we want to use in GoodClass.swift

public class GoodClass {
    public init() {}
    public func sayHello() {
        println("hello")
    }
}

I now like to import this goodie into my hello.swift:

import Cocoa
import GoodClass

let myGoodClass = GoodClass()
myGoodClass.sayHello()

I first generate the .o, lib<>.a, .swiftmodule by running these:

% xcrun swiftc -emit-library -emit-object GoodClass.swift -sdk $(xcrun --show-sdk-path --sdk macosx) -module-name GoodClass
% ar rcs libGoodClass.a GoodClass.o
% xcrun swiftc -emit-module GoodClass.swift -sdk $(xcrun --show-sdk-path --sdk macosx) -module-name GoodClass

Then finally, I am readying to run my hello.swift (as if it’s a script):

% xcrun swift -I "./" -L "./" -lGoodClass -sdk $(xcrun --show-sdk-path --sdk macosx) hello.swift 

But I got this error:

< unknown >:0: error: could not load shared library ‘libGoodClass’

What does this mean? What am I missing. If I go ahead, and do the link/compile thing similar to what you do for C/C++:

% xcrun swiftc -o hello -I "./" -L "./" -lGoodClass -sdk $(xcrun --show-sdk-path --sdk macosx) hello.swift
% ./hello

Then everything is happy. I think I could live with that but still want to understand that shared library error.

Answers:

Here is a reformatted, simplified bash script to build your project. Your use of -emit-object and the subsequent conversion isn’t necessary. Your command doesn’t result in a libGoodClass.dylib file being generated, which is what the linker needed for your -lGoodClass parameter when you run xcrun swift -I "./" -L "./" -lGoodClass -sdk $(xcrun --show-sdk-path --sdk macosx) hello.swift. You also didn’t specify the module to link against with -module-link-name.

This works for me:

#!/bin/bash

xcrun swiftc \
    -emit-library \
    -module-name GoodClass \
    -emit-module GoodClass.swift \
    -sdk $(xcrun --show-sdk-path --sdk macosx)

xcrun swift -I "." -L "." \
    -lGoodClass \
    -module-link-name GoodClass \
    -sdk $(xcrun --show-sdk-path --sdk macosx) hello.swift