The LGPL text does not require dynamic linking. It's FUD.
What the LGPL requires is that the LGPL part can be replaced. That's possible with static linking, that's possible with other languages than the ones relying on a linker step, etc.
> That's possible with static linking, that's possible with other languages than the ones relying on a linker step, etc.
We are talking about Rust, not languages other than Rust. Could you walk us through how you would offer a Rust binary with a statically linked LGPL Rust crate that is replaceable according to the license requirements (v2.0, 2.1, 3.0, pick your poison), without also releasing the binary's source code? I think it's technically possible, but how would you do it? * Edit: keep in mind that .rlib files are not stable across compiler versions. AFAIK very little about the target/ folder is stable at all, except the final product location.
I see that rustc has a "--emit obj" option, from there surely any decent build system would allow enough customization to do what you want but there's enough raw capability to write a user guide that says "build your stuff with rustc --emit obj lgpl_lib_1.rs -o lgpl_lib_1.o and link with our proprietary .o with lld" ; and you'd be good to go.
> * Edit: keep in mind that .rlib files are not stable across compiler versions.
sure, that's not an issue, just say that you used compiler version x.y ? the LGPL does not require that things work with any compiler version, only that there is a way to patch / rebuild the LGPL parts. e.g. if I ship a C++20 proprietary library with C++20-specific types in the API which interoperates with a C++20 LGPL lib, of course things won't work with GCC 2.95 and everyone will be fine with that.
No, that is not how it works, like not at all.
Rust doesn't use the same concepts for building as C.
1. You don't build stuff with `rustc` in general. (You build it with cargo.)
2. You don't produce object files in general, sure rust can produce them and if you link something over the C-ABI it can make sense. What the compiler produces in general for linking libraries are rlibs.
3. rlibs are not just unstable in their format, they are more like a implementation details, don't expect to be able to link in a library as rlib. Like at all.
4. Rust widely uses generics similar to C++ templates this means part of the code which is not supposed to become public will leak if the libary interface involves templates/generics.
5. In rust (and somewhat in C) you normally don't link two "objects" to produce the final binary you build it with a number of "object" dependencies. But this doesn't work with what LGPL requires from you. It can be easy to make a public open-source skeleton you link in all LGPL libraries and your code then to make the linking magic work.
6. `rust --emit` is mainly meant for debugging, and some special use cases around embedding. Don't expect good integration with build tools.
And most important:
What is theoretically possible doesn't matter, what matters is what is practical. I.e. simple, and fast to setup and maintain.
Even for a C CI the requirements the static linking of a LGPL library puts up can make it easily not worth it.
> only that there is a way to patch
No, you need to be able to provide a non LGPL object which you can re-link with the LGPLed libary, so "just" binary patching isn't a legal option.
I do agree that that the concern is becoming much more orthogonal both to the FSF's goals and to the way software is built. But that doesn't change the fact that the license works the way it does, nor does it let you insert the words 'dynamic linking' in it.
But it does matter, it practice it matters more then what is legal if we are honest.
> It isn't the FSF's job to write Rust tooling
Yes, but it doesn't mean that it's not a bad license for the given use-case.
If it's impractical, then in practice there is not much difference to the license simply forbidding the usage (iff the company cares about what is legal).
Through the question is is it a bad license for the given use-case? I.e. does Sequoia provide a rust API or do they provide a C-API written in rust.
Licensing a rust "for-rust" library as LGPL is in practice so close to GPL, that you just could have made it GPL. But a rust C-ABI library/program (e.g. a system library) is a different matter and binding in a LGPL C-ABI library into a rust project still somewhat practical doable (but still quite annoying).
In many projects, ensuring the freedom to replace a copy of the library just isn’t worth all this trouble. If I make my code LGPL, I’m mostly shifting that burden onto other people who want to use it, not myself, and so there are presumably very few LGPL authors who are actually motivated to fix all these problems for someone else. Further, most corps will simply not use the LGPL software, because difficulty looks like license trouble. In that sense, this does look a bit like a job for the FSF, to be honest. At this rate, LGPL use will die out, and not in favour of GPL.
In another sense, a proprietary product choosing to embed my component would be a massive victory for the ecosystem it is built to support. I think that is also true for Sequoia. I just straight up don’t care about the ability to replace my component within another proprietary program. If they are using it at all, they will presumably update it themselves, it would be a pretty central dependency; if they don’t want to, they can just build their own version. I'm just hoping to get anyone to pull the trigger and drop their commercial alternative in favour of the open standard my component implements. So is Sequoia; their livelihood depends on it. Will they hack on rustc to make it easier to use? Somehow I think they will not! This makes no sense to me.
A lot of open source today cares less about LGPL-style replaceability and more about adoption of an open standard that is separate from the code itself. In this case it’s PGP-compatible encryption and signing, which has famously never really taken off and by some odd coincidence never had a project of Sequoia's quality with e.g. a BSD-style license that you could simply slap in a project and depend on. (Although much of the blame deservedly goes to GPG providing over a hundred intricate and one must presume deliberately hard-to-reproduce APIs.) In Kubernetes-land, the concept of being k8s-compatible and interoperable is arguably responsible for more freedom than the core software itself. This is simply true of so many things, and further you must admit: Sequoia as code is 100% replaceable by a motivated corporation, if only there were more demand for being compatible with PGP. If you’re still thinking in 2021 that if PGP were in demand the only reason Amazon would be shipping software without a user-serviceable Sequoia package is the LGPL, you haven’t seen how many hundreds of thousands of dev job ads they posted in the last month. Adoption of the open standard is just more important than anyone’s actual code, up until the codebase is so big it would be prohibitively difficult to replicate. If you think your code in particular is special, maybe you're right, or maybe it's just the rare piece of software whose existence is not entirely justified by an open standard.
The free software advocate's take: You say the toolchain from rust-lang.org makes this difficult? Granted—I'll take your word for it. Go fix that toolchain. (And as a side note, the fact that rust-lang.org chose LLVM is likely to do the opposite of cultivating sympathy.) It's a lot like the saying that goes something like, "poor planning on your end does not automatically make for an emergency on my end."
I'm saying it's a poor choice for a brand new library written in a language where the vast majority of the ecosystem utilizes static linking.
BTW, Rust's objects/rlibs may contain bitcode and a high-level form of generic/inlineable code, so they should be much easier to reverse/decompile than an optimized binary. If the goal was to keep the non-LGPL part closed, it won't work well.
So this is only an inconvenience for proprietary closed-source applications. Making the library conveniently usable by closed-source applications is outside the stated objective in the blog post.
But what does buildable mean, no-one but you has access to your CI (which also might likely not be public).
So do you need to provide another CI, a make-file you maintain additionally, etc.? Or is it good enough so that someone could run "the right CLI commands to build and link the project".
it's trivial in CMake which is the most used buildsystem in languages with a linker, just set -DBUILD_SHARED_LIBS=0 on the command line
> and deprives you of the ability to do certain post-build steps (such as signing the build)
why would it ? I build my app as a set of static libs linked together in the end and there's no trouble signing it... and it does not make sense for people who will build their own custom version of your app to sign it.
here's a guide inspired by instructions given by Cisco to rebuild one of their proprietary apps for instance on iOS:
https://github.com/freedesktop/gstreamer/blob/master/README....
Building or using static libraries isn't hard. Doing so in a way that doesn't violate the LGPL's replacement requirement is. The document you yourself linked says this about developing statically-linked libraries with the GPL:
> If you statically link against an LGPLed library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.
If you're distributing an object format, you need a .o that could be linked with the user's custom version of the LGPLed library. Building such a .o file cannot be done easily with tools, and that is what I'm referring to.
I.e. nothing in the LGPL requires you to sign the changed/re-linked binary as far as I known. Similar nothing requires you to sign the provided intermediate artifacts.
Still only relay viable for C, and maybe C++ if no/few templates where used around the interface. (Or scripting languages bundles with a runtime into a binary.)
Yes, but in practice it tend to not matter.
> (1) If you statically link against an LGPLed library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.
Now to get the "oh C objects" thing out of the way, GPLv3 defines:
> “Object code” means any non-source form of a work.
Still this means what you need is to distribute you application in a partial compiled state which can be relinked with the LGPL library (or a updated version) to re-produce the final application. (You also might need to provide the tools to do so if they are not freely available.)
Also let's not forgot the context, i.e. you don't want (or can't) provide the source code of the "main application" which links against the LGPL library.
Now if you program in C, providing a (set-of) pre-compiled pre-symbol stripped objects is feasible.
But most (new) programs are not in C anymore and most new languages do not have clear ABI boundaries at library level. Only clear API boundaries.
A good example are generics or template programming.
E.g. even in C++ if there is heavy use of template programming around the library boundary can make LGP infeasible for that use case. And we are still in C++ which is rather close to C in how it compiles stuff.
If we go a step further, e.g. into Rust it becomes even more of a mess. (It is possible, at least theoretically, with a lot of hacks and restrictions, but totally a nightmare not worth even considering. And again if generics are used a lot, all the generic code at the interface boundary leaks.)
Then there is the additional complexity this introduces to CI.
So possible yes, but for many projects not worth considering.
> What the LGPL requires is that the LGPL part can be replaced.
Not quite, they require you to provide intermediates which can be re-linked with a alternate version of the library.
Which means if you want to e.g. provide the functionality through binary patching it gets tricky, because you need to provide a binary without the LGPled library (1) which you then can "patch" the library into. Instead of being able to provide a binary with the LGPled library in it and allowing you to replace/update it. Which means various approaches around binary patching just became way more complex.
(1): The reason for it is that the object you provide falls itself under license terms.
So ya, no dynamic linking requirement. But for some modern languages still a major problem. And conceptually too closely bound to the concept of the C-compilation process IMHO.
... You think people haven't solved this problem for literal decades in c++ ?
If your LGPL lib uses a template :
If it gets inlined the license says that it's fine and not breaking LGPL that you won't be able to change the call sites. All c++ compilers will still produce a non-inline version of the symbol with weak linkage that can be replaced in the cases where inlining did not happen. Surely rust does the same in order to comply with LD_PRELOAD semantics ? (Even MSVC does that inline symbol exporting afaik).
Like, you think people who wrote the LGPL did not consider the case of macros in C for instance ?
> If we go a step further, e.g. into Rust it becomes even more of a mess. (It is possible, at least theoretically, with a lot of hacks and restrictions, but totally a nightmare not worth even considering. And again if generics are used a lot, all the generic code at the interface boundary leaks.)
If that's such a nightmare then don't depend on the work of people who wrote LGPL libs and find an alternative instead ?