microsoft / vcpkg

C++ Library Manager for Windows, Linux, and MacOS
MIT License
23.19k stars 6.39k forks source link

vcpkg should have a mechanism for warning when a copyleft license is used for a closed platform target #31820

Open walbourn opened 1 year ago

walbourn commented 1 year ago

Describe the bug For the xbox triplets (as well as iOS and other closed platforms), use of open source with a 'copyleft' license is potentially problematic in meeting the developer agreement needed to ship on the platform. The concern is not just the primary usage, but usage through the 'dependency cone'.

Therefore, it would be helpful to have some mechanism for the vcpkg tool to evaluate the license SPDX values and emit an informative notice or warning if the license is GPL, LGPL, or other "copyleft" variant when used for xbox or similar triplets.

To Reproduce

Example ports that should emit this notice when building with the xbox triplets:

ableton  
ableton-link  
alpaka  
argtable2  
argumentum  
cdt  
check  
chmlib  
comms  
cunit  
eigen3  
faad2  
fann  
fftw3  
fluidlite  
fuzzylite  
geos  
getopt-win32  
gsl  
jack2  
libdatrie  
libexif  
libgme  
libical  
libjuice  
libkeyfinder  
libmt32emu  
libnoise  
libplist  
librttopo  
libsbsms  
libsigcpp  
libsmacker  
libusb  
libusbmuxd  
mp3lame  
mpir  
ngspice  
readosm  
sdl1  
shiftmedia-libgcrypt  
shiftmedia-libgpg-error  
spectra  
taglib  
treehh  
uchardet  
unicorn  
vcglib  
wildmidi  
wolfmqtt  
wolfssl  
zziplib  
FrankXie05 commented 1 year ago

@walbourn Thanks for your investigation. 👍 But as Osyotr said, we need a detection mechanism instead of submitting a bloated PR. Maybe we should add a CI inspection? cc @BillyONeal https://github.com/microsoft/vcpkg/pull/31770#issuecomment-1573251883

autoantwort commented 1 year ago

Maybe introduce a triplet variable that is a list of "forbidden" licenses. For example: xbox.cmake triplet:

set(VCPKG_FORBIDDEN_LICENSES "gpl;lgpl")

Then the vcpkg tool could then evaluate the license expressions of the ports and emit warnings/errors.

walbourn commented 1 year ago

The SPDX list for "copyleft" licenses is a bit longer than seems reasonable to list directly in each triplet.

MS-RL

GPL-1.0
GPL-1.0-only
GPL-1.0+
GPL-1.0-or-later
GPL-2.0                                            
GPL-2.0-only
GPL-2.0+
GPL-2.0-or-later
GPL-2.0-with-autoconf-exception
GPL-2.0-with-bison-exception
GPL-2.0-with-classpath-exception
GPL-2.0-with-font-exception
GPL-2.0-with-GCC-exception
GPL-3.0
GPL-3.0-only
GPL-3.0+
GPL-3.0-or-later
GPL-3.0-with-autoconf-exception
GPL-3.0-with-GCC-exception

LGPL-2.0
LGPL-2.0-only
LGPL-2.0+
LGPL-2.0-or-later
LGPL-2.1
LGPL-2.1-only
LGPL-2.1+
LGPL-2.1-or-later
LGPL-3.0
LGPL-3.0-only
LGPL-3.0+
LGPL-3.0-or-later

AGPL-1.0-only
AGPL-1.0-or-later
AGPL-3.0-only
AGPL-3.0-or-later

CC-BY-SA-1.0
CC-BY-SA-2.0
CC-BY-SA-2.5
CC-BY-SA-3.0
CC-BY-SA-4.0
CC-BY-NC-SA-1.0
CC-BY-NC-SA-2.0
CC-BY-NC-SA-2.5
CC-BY-NC-SA-3.0
CC-BY-NC-SA-4.0

CPL-1.0

MPL-1.0
MPL-1.1
MPL-2.0
MPL-2.0-no-copyleft-exception

EPL-1.0
EPL-2.0

Also, there are a number of "OR" and "AND" scenarios the expression evaluation would need to support as some license terms are "copyleft-style OR permissive-style" expressions so wouldn't be a problem. For example, libopnmidi has:

"license": "LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR MIT"

There's also a case of some complex AND/OR with parenthesis. See range-v3:

"license": "BSL-1.0 AND MIT AND (NCSA OR MIT)"
Neumann-A commented 1 year ago

As said in https://github.com/microsoft/vcpkg/pull/31770#issuecomment-1573236385 and by @autoantwort a triplet variable is the way to go (also i prefer DISALLOWED over FORBIDDEN ). It should support list of SPDX identifiers + maybe pattern matching to simplyfy the setup. Complex OR/AND should be ignored for now and rightout simply apply the restrion no matter what. Exceptions can be created by per port customization which can also deal with the null case on a per port basis.

dg0yt commented 1 year ago

deal with the null case on a per port basis.

In some cases, it will depend on features. (ffmpeg, gstreamer, x264 seem to be the obvious cases.)

Neumann-A commented 1 year ago

In some cases, it will depend on features. (ffmpeg, gstreamer, x264 seem to be the obvious cases.)

Even that can be dealt with with per port customization inspecting the FEATURES variable.

autoantwort commented 1 year ago

Complex OR/AND should be ignored for now

The code for that is already there. Platform expressions with AND and OR instead of & and |. So evaluating expressions should be no problem.

JoergAtGithub commented 1 year ago

Such a logic should not be coded to target only one particular license issue. There are many more incomptible licenses. For example, if I develop a GPLv2 application with VCPKG dependecies, I would like to know if one of these library doesn't have a GPLv2 compatible license. First step, before such a logic can be implemented, should be, to store the SPDX license information in proper structures:

autoantwort commented 1 year ago

Allow to store multiple SPDX codes per port (see hidapi with 3 alternative licences for example)

Is there anything that prevents you from using an OR?

BurningEnlightenment commented 1 year ago

Maybe introduce a triplet variable that is a list of "forbidden" licenses.

If you distribute software you will need to read all dependency licenses anyway in order to ensure compliance. I think it is much safer and therefore sensible to whitelist licenses.

(It would also be nice if there was a vcpkg command for printing a license summary of the install tree)

autoantwort commented 1 year ago
  • Allow to store SPDX codes per feature (see the GPL feature of ffmpeg for example)

I have created https://github.com/microsoft/vcpkg-tool/pull/1096 for that.

JoergAtGithub commented 1 year ago

Allow to store multiple SPDX codes per port (see hidapi with 3 alternative licences for example)

Is there anything that prevents you from using an OR?

After reading the SPDX spec, OR should do the job for standard licenses. Thanks for pointing this out! But there remains a gap for application specific licenses using the SPDX LicenseRef keyword: https://reuse.software/faq/#custom-license

In case of the hidapi example, 2 standard licenses with official SPDX code are used, and a third custom license with the license text in an attached file: https://github.com/libusb/hidapi/blob/master/LICENSE-orig.txt

walbourn commented 1 year ago

In case of the hidapi example, 2 standard licenses with official SPDX code are used, and a third custom license with the license text in an attached file: https://github.com/libusb/hidapi/blob/master/LICENSE-orig.txt

Seems like null is the right choice for a license option this complex.

github-actions[bot] commented 11 months ago

This is an automated message. Per our repo policy, stale issues get closed if there has been no activity in the past 180 days. The issue will be automatically closed in 14 days. If you wish to keep this issue open, please add a new comment.

BurningEnlightenment commented 11 months ago

I think this is still useful.

github-actions[bot] commented 4 months ago

This is an automated message. Per our repo policy, stale issues get closed if there has been no activity in the past 180 days. The issue will be automatically closed in 14 days. If you wish to keep this issue open, please add a new comment.

BurningEnlightenment commented 4 months ago

🪄 unstale

bansan85 commented 4 months ago

Maybe a solution is to create a LICENSE CMake variable based on the portfile ? Like the PORT CMake variable ?

And customize the triplet based on the documentation:

set(VCPKG_LIBRARY_LINKAGE static)
if(${LICENSE} MATCHES "LGPL")
    set(VCPKG_LIBRARY_LINKAGE dynamic)
endif()
dg0yt commented 4 months ago

The original request is related to entire platforms, not linkage.

Maybe a solution is to create a LICENSE CMake variable based on the portfile ? Like the PORT CMake variable ?

There is no single license. There is AND, there is OR, there are exceptions. Features may add additional licenses. And there is null.

And customize the triplet based on the documentation:

AFAIU (L)GPL isn't incompatible with static linkage. It just needs a different way to support relinking.

What you can do already now is to customize the triplet per port name.

What might work as well (at least technically) is to make the triplet file read the general license field in the manifest, at least when CURRENT_PORT_DIR is defined.

bansan85 commented 4 months ago

My code was only shown as an example. It could have been:

if(${LICENSE} MATCHES "LGPL")
    message(FATAL_ERROR "Wrong license")
endif()

Thanks for the tip about CURRENT_PORT_DIR variable and the idea about reading portfile.cmake. I will try it.