Cargo build certain dependencies as dylibs


#1

I have been working on some project and started using crates, which is awesome, however all those crates each have some kind of license. Some are MIT, some are MPL, some are GPL, some are Apache, and so on.

The thing is, I might plan to sell my software at some point, so I want to distribute binary blobs. That’s OK, if I only use MIT and BSD type of licenses. As you might guess, GPL-like licenses are a completely different matter. They require me to share my source code if I distribute them in binary form. Bad. Really bad.

So, correct me if I am wrong, but what I think I have to do is compile them and distribute them separately in binary form and just link my executable to the dylibs. That way, the OSS binary files (dylibs) will remain 100% open-source, while I do not have to share the source of my executable application.

How can I go and tell Cargo to build certain dependencies as dylibs? I’d prefer to do so centrally and automatically, if possible. If not, how can I tell Cargo to build a separate crate as dylib and link to the dylib later on?

I already know about crate-type, but I would rather not edit all dependencies individually. That feels hacky and like a lot of trouble!

Thank you for any pointers and corrections!


#2

No I don’t think you could circumvent the GPL by dynamic linking, as your application builds upon that library, hence a derivative work. LGPL-licensed libraries allow dynamic linking though, IIRC. Best practice is to avoid GPL when developing closed-source applications, it’s unfortunate but this is how GPL works.


#3

@xen0n thank you for the information. I am currently still trying to make sense of all the separate licenses, so I might have confused GPL and LGPL.

You don’t happen to know how linking such dependencies in a useful way works?


#4

If you base your application in any way on GPL’ed software, you have to license your entire application as GPL. This is just how it works (and I’d just read the full license text, it’s quite easy to read: https://www.gnu.org/licenses/gpl-3.0.en.html). There are no “clever” technical “tricks” you can use to get around this. Judges don’t care about the distinction between static and dynamic linking, they only care if your work is "based on” the GPL’ed work as described in the license text.


#5

Anyways, it’s not really about linking. Basically, the LGPL requires that the user be able to modify, replace, and redistribute all LGPL licensed components. Dynamic linking satisfies this requirement because the user can just drop-in a replacement dynamic library.

Alternatively, you could probably (IANAL) just distribute pre-link rlibs along with your program as long as the user can replace the LGPL licensed rlibs and link everything back together. However, that may leak information as rlibs often contain a lot of additional information about your code (for inlining, generics, etc.).


#6

Rust dynamic linking does not count as LGPL compatible dynamic linking because of how much code gets inlined and monomorphized so the code isn’t entirely in the dynamic library, and you cannot swap out the dylib for a modified version. The lack of a stable Rust ABI really doesn’t help.

This also isn’t going to happen any time soon.

Basically don’t use Rust code that is LGPL or GPL, or if you really have to, either license your own project as GPL or never distribute binaries.


#7

Rust dynamic linking

Sorry, I was talking about C shared libraries. I don’t know much about rust dynamic linking.

as long as the user can replace the LGPL licensed rlibs

This also isn’t going to happen any time soon.

You can do this but, after thinking about it, it would be a pain. You can’t replace an rlib dependency but you can replace an rlib sibling so you’d have to put all your IP in one crate, your LGPL stuff in another, and glue them together with an “open source” (but restrictively licensed) top-level crate.

If you don’t have any IP (proprietary algorithms, secrets, etc.), you could also just “open source” your entire project under a restrictive (all rights reserved) license. From a legal perspective, there’s really no reason to keep the source closed.


You could also use a C FFI and write your own rust facade (rust -> c -> rust) but that’s not very fun (and won’t work in many cases).


But yeah, choosing a non LGPL library is probably your best bet for now.