105 lines
5.6 KiB
Python
105 lines
5.6 KiB
Python
"""Assemble THIRD_PARTY_LICENSES.txt for a build: every bundled component, its version, license, source URL
|
|
and full license text. Texts come from the installed wheels or from tools/licenses/ (copies of the texts at the
|
|
URLs listed in tools/licenses/SOURCES.txt, so the build needs no network).
|
|
|
|
python tools/collect_licenses.py OUT_FILE
|
|
"""
|
|
import importlib.metadata as md
|
|
import os
|
|
import sys
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
LICENSES = os.path.join(ROOT, "tools", "licenses")
|
|
|
|
|
|
def license_text(name):
|
|
return open(os.path.join(LICENSES, name), encoding="utf-8", errors="replace").read()
|
|
|
|
|
|
def dist_file(dist, *names):
|
|
try:
|
|
files = md.distribution(dist).files or []
|
|
except md.PackageNotFoundError:
|
|
return ""
|
|
for f in files:
|
|
if os.path.basename(str(f)) in names:
|
|
return open(f.locate(), encoding="utf-8", errors="replace").read()
|
|
return ""
|
|
|
|
|
|
def ver(dist):
|
|
try:
|
|
return md.version(dist)
|
|
except md.PackageNotFoundError:
|
|
return "?"
|
|
|
|
|
|
def site_file(*parts):
|
|
import soundfile
|
|
p = os.path.join(os.path.dirname(soundfile.__file__), *parts)
|
|
return open(p, encoding="utf-8", errors="replace").read() if os.path.exists(p) else ""
|
|
|
|
|
|
def components():
|
|
import soundfile
|
|
py_lic = os.path.join(sys.base_prefix, "LICENSE.txt")
|
|
return [
|
|
("Python", sys.version.split()[0], "PSF-2.0", "https://www.python.org/downloads/source/",
|
|
open(py_lic, encoding="utf-8", errors="replace").read() if os.path.exists(py_lic) else ""),
|
|
("Qt for Python (PySide6, Shiboken6) and the Qt libraries it bundles", ver("PySide6-Essentials"),
|
|
"LGPL-3.0-only (used under LGPL: dynamically linked, unmodified shared libraries)",
|
|
"https://code.qt.io/cgit/pyside/pyside-setup.git/ ; Qt sources: https://download.qt.io/official_releases/qt/",
|
|
license_text("lgpl-3.0.txt") + "\n\n" + license_text("gpl-3.0.txt")),
|
|
("FFmpeg libraries bundled inside Qt Multimedia (PySide6-Addons)", ver("PySide6-Addons"), "LGPL-2.1-or-later",
|
|
"https://download.qt.io/official_releases/qt/ (qtmultimedia FFmpeg build), https://ffmpeg.org/download.html",
|
|
site_file("_soundfile_data", "COPYING")),
|
|
("libsndfile (in soundfile, %s)" % soundfile.__libsndfile_version__, soundfile.__libsndfile_version__,
|
|
"LGPL-2.1-or-later", "https://github.com/libsndfile/libsndfile", site_file("_soundfile_data", "COPYING")),
|
|
("mpg123 (MP3 decoding, statically in libsndfile)", "bundled", "LGPL-2.1",
|
|
"https://www.mpg123.de/download.shtml", "(see the LGPL-2.1 text of libsndfile above)"),
|
|
("LAME (MP3 encoding, statically in libsndfile; not used by this app)", "bundled", "LGPL-2.0",
|
|
"https://lame.sourceforge.io/download.php", license_text("lgpl-2.0.txt")),
|
|
("libvorbis (statically in libsndfile)", "1.3.7", "BSD-3-Clause", "https://github.com/xiph/vorbis",
|
|
license_text("libvorbis-COPYING")),
|
|
("libogg (statically in libsndfile)", "1.3.5", "BSD-3-Clause", "https://github.com/xiph/ogg",
|
|
license_text("libogg-COPYING")),
|
|
("FLAC (statically in libsndfile)", "1.4.x", "BSD-3-Clause", "https://github.com/xiph/flac",
|
|
license_text("flac-COPYING.Xiph")),
|
|
("Opus (statically in libsndfile)", "1.4", "BSD-3-Clause", "https://github.com/xiph/opus", license_text("opus-COPYING")),
|
|
("python-soundfile", ver("soundfile"), "BSD-3-Clause", "https://github.com/bastibe/python-soundfile",
|
|
dist_file("soundfile", "LICENSE")),
|
|
("python-soxr and libsoxr", ver("soxr"), "LGPL-2.1-or-later", "https://github.com/dofuuz/python-soxr",
|
|
dist_file("soxr", "COPYING.LGPL") + "\n\n" + dist_file("soxr", "LICENSE-libsoxr.txt") + "\n\n" +
|
|
dist_file("soxr", "LICENSE-PFFFT.txt")),
|
|
("NumPy (incl. bundled OpenBLAS / runtime libraries)", ver("numpy"), "BSD-3-Clause and others (see text)",
|
|
"https://github.com/numpy/numpy", dist_file("numpy", "LICENSE.txt")),
|
|
("Pedalboard (incl. JUCE and the Rubber Band library, statically linked)", ver("pedalboard"), "GPL-3.0",
|
|
"https://github.com/spotify/pedalboard", dist_file("pedalboard", "LICENSE") + "\n\n" +
|
|
dist_file("pedalboard", "NOTICE")),
|
|
("cffi", ver("cffi"), "MIT-0", "https://github.com/python-cffi/cffi", dist_file("cffi", "LICENSE")),
|
|
("pycparser", ver("pycparser"), "BSD-3-Clause", "https://github.com/eliben/pycparser",
|
|
dist_file("pycparser", "LICENSE")),
|
|
("PyInstaller bootloader", ver("pyinstaller"), "GPL-2.0-or-later with bootloader exception",
|
|
"https://github.com/pyinstaller/pyinstaller", dist_file("pyinstaller", "COPYING.txt")),
|
|
("Wwise codebook data (ackit/data/game_codebooks.bin)", "-", "derived from libvorbis codebooks (BSD-3-Clause)",
|
|
"https://github.com/xiph/vorbis", "(see libvorbis above)"),
|
|
]
|
|
|
|
|
|
def main(out):
|
|
parts = ["THIRD-PARTY SOFTWARE in Unheard City\n" + "=" * 60 + "\n"
|
|
"This program bundles the components below. LGPL components are dynamically linked shared libraries\n"
|
|
"that you may replace; their source code is available at the URLs given.\n"]
|
|
comps = components()
|
|
for name, v, lic, url, _ in comps:
|
|
parts.append("- %s %s\n License: %s\n Source: %s" % (name, v, lic, url))
|
|
for name, v, lic, url, text in comps:
|
|
if text.strip():
|
|
parts.append("\n\n" + "=" * 78 + "\n%s %s (%s)\n" % (name, v, lic) + "=" * 78 + "\n" + text)
|
|
open(out, "w", encoding="utf-8").write("\n".join(parts))
|
|
print("wrote %s (%d components)" % (out, len(comps)))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv[1] if len(sys.argv) > 1 else "THIRD_PARTY_LICENSES.txt")
|