Building distributable executable using SwiftPM

Hello!

I've been using SPM for my local development, and now I'd like to distribute my command line tool which is binary target in my SPM project. I've noticed when I build it using swift build, the linked binary contains LC_LOAD_DYLIB load command which loads libSwiftPM.dylib, and it's path is an absolute value (/Users/beefon/.../debug/libSwiftPM.dylib). Is there an option so it can override and look for this dylib in the current folder, e.g. use "@executable_path/libSwiftPN.dylib"?

Looks like it is controlled by LC_ID_DYLIB value in libSwiftPM.dylib (I took SwiftPM lib as an example; technically this can be applied to any library you are depending on).
So I can see this value can be set by passing -install_name name linker flag. But there is no way to pass this flag to swift build MyBinary invocation as it will be appended to every linker invocation, and the value must be different per library.

Unfortunately, it is not possible to control these with SwiftPM currently. I think this will be covered by the install and deployment support in future.

If you want to distribute your executable, would it be preferable to statically link all dependencies (including the Swift runtime), so you can really distribute just a single binary and avoid the whole problem?

I don't know whether that is something SwiftPM supports right now, though.

2 Likes

Statically linking all dependencies is nice but that might not be always possible or desirable. SwiftPM can statically link the Swift stdlib on macOS using swift build --static-swift-stdlib.

Thank you for your replies.

While I can statically link core libraries by using the mentioned flag, apparently I cannot force my deps to be statically linked into my binary as the linkage type is defined per Packager.swift rather than on the importer side. Unless there is an option to override the dependency's type: .dynamic, is there one? Specifically, SwiftPM library has this link type hardcoded in it's Package.swift

Oh, I've just discovered SwiftPM exposes Utility library which does not have enforced linkage type, so this unblocks me. But the questions about making distributable binary and overriding link type on user side are still open. Are there corresponding tasks I can follow?

1 Like

Ok, just to clarify: It is not possible to build a binary using SPM that I can move to a different machine?

We recommend packages to not specify the link type unless they really need to. But there is no way to override if they do specify it.

It is but you have to make sure everything is setup correctly, which may involve linking the stdlib statically, setting up rpaths etc. In future, SwiftPM should do all this for you.

@Nicole_Jacque please move this thread to "Using Swift" section

Does "in the future" mean in Swift 4.2 already? :slight_smile: (Sry for that stupid question, but it begged to be asked)

I had the same question. This is needed asap

I doubt it, we need proposal work here.

That is unfortunate as it seems to be such a fundamental issue. :cry:

3 Likes

@Aciid, what's the need for SwiftPM library to be dynamic? How can I understand when should the library specify to be dynamic vs not specify at all?

Prefer not specifying the linkage type as SwiftPM can figure out the linkage for you. Dynamic libraries have their specific use-cases that you may sometimes need (e.g. a plugin system). If you're interested in knowing more, I recommend searching for resources on static vs dynamic library.