Switching license conditionally based on manifest feature

I wish switching package.license field by its dependencies. I thought it's useful if we touch library (such as *-sys) which is licensed under copy-lefts that require "license propagation." (especially /A?GPL/) I have tried to make it happen with following manifests:

# ./local1/Cargo.toml
[package]
name = "local1"
version = "0.1.0"
edition = "2021"

[target.'cfg(not(feature = "2"))'.package]
license = "MIT"

[target.'cfg(feature = "2")'.package]
license = "GPL-3.0-or-later"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
local2_gpl = { path = "../local2_gpl", optional = true }

[features]
2 = ["dep:local2_gpl"]
[package]
name = "local2_gpl"
version = "0.1.0"
edition = "2021"
license = "GPL-3.0-or-later"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

However, cargo-metadata -F 2 on workspace root does not recognize target.cfg(...).package section. It reports no license is tied with local1 package.

How can I achieve this? Thank you.

It's not possible to change the package license in the metadata on the basis of configuration. It's a fixed metadata field.

Current best practices I've seen involve documenting the dependency license in the README and making sure the dependency license is GPL-3.0-or-later, and relying on people to run tools like cargo-deny that check licenses recursively.

3 Likes

This only applies to binaries built from the sources together. The sources at-rest can be licensed under any license which is compatible with re-distribution under the copy-left license. (This is why the standard Rust license is Apache-2.0 OR MIT, the MIT license is compatible to be re-distributed under the GPL-3.0 license after becoming part of a combined work, Apache-2.0 on its own is not).

EDIT: To expand a little bit more, it's my understanding that usage of the GPL-3.0 copyrighted interface from the MIT licensed code falls under fair use, so it does not affect what license your code must be under. Only once you link in the implementation do you have to start complying with the GPL-3.0 license for that combined work. Largely based on the outcome of Google LLC v. Oracle America, Inc..

1 Like

Not to derail the thread, but Google v. Oracle was about whether APIs are inherently copyrightable. In this case, the "structure and organization" of APIs was insufficient for copyright in the first place. It's a narrow ruling and would need more cases to find "boundaries" one could use in the wild. Copyright flows through "derivative work" regardless of linking status or the like (but linking can be an indicator of whether something is such a derivative work).

Basically, my recommendations are the same: license your code as you see fit (provided it does not cause conflicting requirements), but your binaries are subject to your dependency's terms as well since they are included.

You can conditionally include dependencies. Having the code licensed differently as a dependency declaring its license in its own package should be enough.

Tools that scan dependencies need to scan everything recursively anyway.

The combined product will need to obey sum of all licenses, but you’re free to license your own code however you like.

3 Likes