Source: firmware-nonfree Version: 20230210-5 Severity: wishlist Tags: patch
Hello. The source package builds with the attached changes (2 to 10), and debdiff finds no difference in the resulting debs for firmware-{linux,linux-nonfree,qcom-media} (testing do_extra in gencontrol.py) firmware-realtek (testing an example of do_main in gencontrol.py) Commit 2 to 9 are cosmetic. Commit 10 simplifies the build system in my opinion, and may improve the handling of spaces in file names (1#1035505). This is a complex package and I miss context, so I may of course split 10 in separate commits or revert parts of it depending on your answer.
>From 798e5b247db70dc24ce6736a4eba7b5ae17ca41d Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Fri, 23 Feb 2024 17:10:17 +0100 Subject: [PATCH 02/10] d/README.Debian: typo --- debian/README.source | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/README.source b/debian/README.source index 15c11bf..43e897a 100644 --- a/debian/README.source +++ b/debian/README.source @@ -85,7 +85,7 @@ Optional per-file metadata: [<filename>_base] desc: One-line description for this file, used in package description -[<filename>_base] version: Verson number for this file, used in package +[<filename>_base] version: Version number for this file, used in package description To re-generate debian/control (and other files) based on these -- 2.39.2
>From c525da983a782b3d58e7ba4f793930e197fc05d7 Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Fri, 23 Feb 2024 17:11:31 +0100 Subject: [PATCH 03/10] d/clean: instead of complexity in d/rules --- debian/clean | 2 ++ debian/rules | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 debian/clean diff --git a/debian/clean b/debian/clean new file mode 100644 index 0000000..b0bff90 --- /dev/null +++ b/debian/clean @@ -0,0 +1,2 @@ +debian/build/ +debian/lib/python/__pycache__/ diff --git a/debian/rules b/debian/rules index 5867d9f..ccd41a7 100755 --- a/debian/rules +++ b/debian/rules @@ -15,7 +15,6 @@ build-indep build-arch build: debian/control clean: debian/control dh_testdir - rm -rf debian/build debian/lib/python/__pycache__ dh_clean binary-indep: build-indep -- 2.39.2
>From d193cb90f02e2c669c1ad2fb91759f4d9c3591e8 Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Fri, 23 Feb 2024 17:28:04 +0100 Subject: [PATCH 04/10] d/rules: use dpkg pkg-info.mk snippet instead of reinventing it --- debian/rules | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/debian/rules b/debian/rules index ccd41a7..d9a2d38 100755 --- a/debian/rules +++ b/debian/rules @@ -1,10 +1,9 @@ #!/usr/bin/make -f SHELL := sh -e -SOURCE := $(shell dpkg-parsechangelog -SSource) -VERSION := $(shell dpkg-parsechangelog -SVersion) -VERSION_UPSTREAM := $(shell echo "$(VERSION)" | sed -e 's,-[^-]*$$,,') -VERSION_BINNMU := $(shell echo "$(VERSION)" | sed -rne 's,.*\+b([0-9]+)$$,\1,p') -VERSION_SOURCE := $(patsubst %+b$(VERSION_BINNMU),%,$(VERSION)) + +include /usr/share/dpkg/pkg-info.mk +VERSION_BINNMU := $(shell echo "$(DEB_VERSION)" | sed -rne 's,.*\+b([0-9]+)$$,\1,p') +VERSION_SOURCE := $(patsubst %+b$(VERSION_BINNMU),%,$(DEB_VERSION)) include debian/rules.defs @@ -35,7 +34,7 @@ CONTROL_FILES += debian/bin/gencontrol.py debian/config/defines $(wildcard debia # in the checksum. debian/build/version-info: debian/changelog mkdir -p $(@D) - printf >$@ 'Source: %s\nVersion: %s\n' $(SOURCE) $(VERSION_SOURCE) + printf >$@ 'Source: %s\nVersion: %s\n' $(DEB_SOURCE) $(VERSION_SOURCE) debian/control debian/rules.gen: $(GENCONTROL) $(CONTROL_FILES) ifeq ($(wildcard debian/control.md5sum),) @@ -59,8 +58,8 @@ debian/control-real: $(GENCONTROL) $(CONTROL_FILES) @echo exit 1 -DIR_ORIG = ../orig/$(SOURCE)-$(VERSION_UPSTREAM) -TAR_ORIG_NAME = $(SOURCE)_$(VERSION_UPSTREAM).orig.tar.xz +DIR_ORIG = ../orig/$(DEB_SOURCE)-$(DEB_VERSION_UPSTREAM) +TAR_ORIG_NAME = $(DEB_SOURCE)_$(DEB_VERSION_UPSTREAM).orig.tar.xz TAR_ORIG = $(firstword $(wildcard ../$(TAR_ORIG_NAME)) $(wildcard ../orig/$(TAR_ORIG_NAME))) orig: $(DIR_ORIG) -- 2.39.2
>From 1327a9f8e15b602e7f3df768758f478b548dbd50 Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Fri, 23 Feb 2024 17:28:38 +0100 Subject: [PATCH 05/10] d/rules: expand GENCONTROL instead of duplicating its contents --- debian/rules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/rules b/debian/rules index d9a2d38..f455e5e 100755 --- a/debian/rules +++ b/debian/rules @@ -26,9 +26,9 @@ binary-arch: build-arch binary: binary-indep binary-arch CONTROL_FILES = debian/build/version-info $(wildcard debian/templates/*.in) -CONTROL_FILES += debian/bin/gencontrol.py debian/config/defines $(wildcard debian/config/*/defines) debian/modinfo.json +CONTROL_FILES += $(GENCONTROL) debian/config/defines $(wildcard debian/config/*/defines) debian/modinfo.json -# debian/bin/gencontrol.py uses debian/changelog as input, but the +# GENCONTROL uses debian/changelog as input, but the # output only depends on the source name and version. To avoid # frequent changes to debian/control.md5sum, include only those fields # in the checksum. -- 2.39.2
>From 568294221c5a8ba01a92952744ea96b6eda464db Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Fri, 23 Feb 2024 17:36:45 +0100 Subject: [PATCH 06/10] d/watch: update format to version 4, add spaces for readability --- debian/watch | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/debian/watch b/debian/watch index f09afbf..1e4102e 100644 --- a/debian/watch +++ b/debian/watch @@ -1,4 +1,10 @@ -version=3 -opts="mode=git, gitmode=shallow, pgpmode=gittag" \ +version=4 + +opts="\ + mode=git,\ + gitmode=shallow,\ + pgpmode=gittag,\ +" \ https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git \ -refs/tags/(.*) debian +refs/tags/(.*) \ +debian -- 2.39.2
>From 94edbc25117933a9e71db715333f29be54f110bf Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Fri, 23 Feb 2024 17:22:19 +0100 Subject: [PATCH 07/10] gencontrol.py: open files with context managers --- debian/bin/gencontrol.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 293432b..11249d0 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -258,18 +258,21 @@ class GenControl(debian_linux.gencontrol.Gencontrol): if 'initramfs-tools' in config_entry.get('support', []): postinst = self.templates.get('postinst.initramfs-tools') - open("debian/firmware-%s.postinst" % package, 'w').write(self.substitute(postinst, vars)) + with open(f'debian/firmware-{package}.postinst', 'w') as postint_f: + postint_f.write(self.substitute(postinst, vars)) if 'license-accept' in config_entry: - license = open("%s/LICENSE.install" % package_dir, 'r').read() + with open(f'{package_dir}/LICENSE.install', 'r') as license_f: + license = license_f.read() preinst = self.templates.get('preinst.license') preinst_filename = "debian/firmware-%s.preinst" % package - open(preinst_filename, 'w').write(self.substitute(preinst, vars)) + with open(preinst_filename, 'w') as preinst_f: + preinst_f.write(self.substitute(preinst, vars)) templates = self.templates.get_templates_control('templates.license', vars) templates[0]['Description'].append(re.sub('\n\n', '\n.\n', license)) templates_filename = "debian/firmware-%s.templates" % package - self.write_rfc822(open(templates_filename, 'w'), templates) + self.write_rfc822(templates_filename, templates) desc = packages_binary[0]['Description'] desc.append( @@ -290,7 +293,8 @@ You must agree to the terms of this license before it is installed.""" vars['longdesc-metainfo'] = re.sub(r'\s+', ' ', vars['longdesc']) package_meta_temp = self.templates.get("metainfo.xml", {}) # XXX Might need to escape some characters - open("debian/firmware-%s.metainfo.xml" % package, 'w').write(self.substitute(package_meta_temp, vars)) + with open(f'debian/firmware-{package}.metainfo.xml', 'w') as meta_f: + meta_f.write(self.substitute(package_meta_temp, vars)) def process_template(self, in_entry, vars): e = Template() @@ -324,18 +328,18 @@ You must agree to the terms of this license before it is installed.""" self.write_makefile(makefile) def write_control(self, list): - self.write_rfc822(open("debian/control", 'w'), list) + self.write_rfc822('debian/control', list) def write_makefile(self, makefile): - f = open("debian/rules.gen", 'w') - makefile.write(f) - f.close() - - def write_rfc822(self, f, list): - for entry in list: - for key, value in entry.items(): - f.write("%s: %s\n" % (key, value)) - f.write('\n') + with open('debian/rules.gen', 'w') as f: + makefile.write(f) + + def write_rfc822(self, path, list): + with open(path, 'w') as f: + for entry in list: + for key, value in entry.items(): + f.write("%s: %s\n" % (key, value)) + f.write('\n') if __name__ == '__main__': GenControl()() -- 2.39.2
>From ab600a244f3ca4b12c124c01c04f775a77adc699 Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Sun, 25 Feb 2024 01:07:44 +0100 Subject: [PATCH 08/10] gencontrol.py: import standard library before local modules --- debian/bin/gencontrol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 11249d0..1f5b574 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +from collections import OrderedDict import io import json import locale @@ -18,7 +19,6 @@ import debian_linux.gencontrol from debian_linux.gencontrol import Makefile, MakeFlags, PackagesList from debian_linux.utils import TextWrapper from debian_linux.utils import Templates as TemplatesBase -from collections import OrderedDict class PackageDescription(PackageDescriptionBase): __slots__ = () -- 2.39.2
>From fdadbaf724a06a554ee19da02bf8d6434aa516d6 Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Sun, 25 Feb 2024 01:16:09 +0100 Subject: [PATCH 09/10] gencontrol.py: remove unused process_template methods --- debian/bin/gencontrol.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index 1f5b574..fdaaf6b 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -296,23 +296,6 @@ You must agree to the terms of this license before it is installed.""" with open(f'debian/firmware-{package}.metainfo.xml', 'w') as meta_f: meta_f.write(self.substitute(package_meta_temp, vars)) - def process_template(self, in_entry, vars): - e = Template() - for key, value in in_entry.items(): - if isinstance(value, PackageDescription): - e[key] = self.process_description(value, vars) - elif key[:2] == 'X-': - pass - else: - e[key] = self.substitute(value, vars) - return e - - def process_templates(self, in_entries, vars): - entries = [] - for i in in_entries: - entries.append(self.process_template(i, vars)) - return entries - def substitute(self, s, vars): if isinstance(s, (list, tuple)): return [self.substitute(i, vars) for i in s] -- 2.39.2
>From e9ac0ac9976f9c05206f492c3cfcece7981887b9 Mon Sep 17 00:00:00 2001 From: Nicolas Boulenguez <nico...@debian.org> Date: Sun, 25 Feb 2024 01:26:35 +0100 Subject: [PATCH 10/10] Simplify gencontrol.py and its interaction with debian/rules Before: d/bin/gencontrol.py encodes a list of files and links to install as Make variables generates d/rules.gen as a Makefile running d/rules.real d/rules invokes 'make -f d/rules.gen' recursively d/rules.real installs things (and displays its actions) runs debhelper tools After: d/bin/gencontrol.py generates d/rules.gen as a shell script installing files and links d/rules: uses the dh driver and debhelper overrides in the usual way (displays and) executes d/rules.gen In gencontrol.py * remove the GenControl class. The ancestor class was unused, and the attributes are more explicit as parameters in procedure calls. * Move modinfo and firmware_modules from main() to the more specific do_main(). * Rename the templates local variable to avoid a clash with the argument. * Add a append_to_rules_gen procedure in charge of the generation. --- debian/bin/gencontrol.py | 469 +++++++++++++++++++-------------------- debian/rules | 29 ++- debian/rules.real | 45 ---- 3 files changed, 251 insertions(+), 292 deletions(-) delete mode 100644 debian/rules.real diff --git a/debian/bin/gencontrol.py b/debian/bin/gencontrol.py index fdaaf6b..162ae9a 100755 --- a/debian/bin/gencontrol.py +++ b/debian/bin/gencontrol.py @@ -15,8 +15,7 @@ locale.setlocale(locale.LC_CTYPE, "C.UTF-8") from config import Config from debian_linux.debian import BinaryPackage, PackageRelation, _ControlFileDict from debian_linux.debian import PackageDescription as PackageDescriptionBase -import debian_linux.gencontrol -from debian_linux.gencontrol import Makefile, MakeFlags, PackagesList +from debian_linux.gencontrol import PackagesList from debian_linux.utils import TextWrapper from debian_linux.utils import Templates as TemplatesBase @@ -70,259 +69,259 @@ class Templates(TemplatesBase): return Template.read_rfc822(io.StringIO(self.get(key, context))) -class GenControl(debian_linux.gencontrol.Gencontrol): - def __init__(self): - self.config = Config() - self.templates = Templates() +def main(): + config = Config() + templates = Templates() + packages = PackagesList() + do_source(templates, packages) + do_extra(config, templates, packages) + do_main(config, templates, packages) + write_rfc822('debian/control', packages.values()) - with open('debian/modinfo.json', 'r') as f: - self.modinfo = json.load(f) - # Make another dict keyed by firmware names - self.firmware_modules = {} - for name, info in self.modinfo.items(): - for firmware_filename in info['firmware']: - self.firmware_modules.setdefault(firmware_filename, []) \ - .append(name) +def do_source(templates, packages): + packages['source'] = templates.get_source_control("control.source", {})[0] - def __call__(self): - packages = PackagesList() - makefile = Makefile() - self.do_source(packages) - self.do_extra(packages, makefile) - self.do_main(packages, makefile) +def do_extra(config, templates, packages): + config_entry = config['base',] + vars = {} + vars.update(config_entry) - self.write(packages, makefile) + for package_binary in templates.get_control("control.extra", {}): + assert package_binary['Package'].startswith('firmware-') - def do_source(self, packages): - packages['source'] = self.templates.get_source_control("control.source", {})[0] + packages.append(package_binary) - def do_extra(self, packages, makefile): - config_entry = self.config['base',] - vars = {} - vars.update(config_entry) - for package_binary in self.templates.get_control("control.extra", {}): - assert package_binary['Package'].startswith('firmware-') - package = package_binary['Package'].replace('firmware-', '') +def do_main(config, templates, packages): - makeflags = MakeFlags() - makeflags['FILES'] = '' - makeflags['PACKAGE'] = package - makefile.add_cmds('binary-indep', ["$(MAKE) -f debian/rules.real binary-indep %s" % makeflags]) + with open('debian/modinfo.json', 'r') as f: + modinfo: dict[str, dict[str, list[str]]] = json.load(f) - packages.append(package_binary) + # Make another dict keyed by firmware names + firmware_modules: dict[str, list[str]] = {} + for name, info in modinfo.items(): + for firmware_filename in info['firmware']: + firmware_modules.setdefault(firmware_filename, []) \ + .append(name) - def do_main(self, packages, makefile): - config_entry = self.config['base',] - vars = {} - vars.update(config_entry) - - makeflags = MakeFlags() - - for i in ('build', 'binary-arch', 'setup'): - makefile.add_cmds("%s_%%" % i, ["@true"]) + config_entry = config['base',] + vars = {} + vars.update(config_entry) + with open('debian/rules.gen', 'w') as rules_gen: for package in config_entry['packages']: - self.do_package(packages, makefile, package, vars.copy(), makeflags.copy()) - - def do_package(self, packages, makefile, package, vars, makeflags): - config_entry = self.config['base', package] - vars.update(config_entry) - vars['package'] = package - vars['package-env-prefix'] = 'FIRMWARE_' + package.upper().replace('-', '_') - - makeflags['PACKAGE'] = package - - # Those might be absent, set them to empty string for replacement to work: - empty_list = ['replaces', 'conflicts', 'breaks', 'provides', 'recommends'] - for optional in ['replaces', 'conflicts', 'breaks', 'provides', 'recommends']: - if optional not in vars: - vars[optional] = '' - - package_dir = "debian/config/%s" % package - + do_package(config, templates, modinfo, firmware_modules, + packages, rules_gen, package, vars.copy()) + + +def do_package(config, templates, modinfo, firmware_modules, + packages, rules_gen, package, vars): + config_entry = config['base', package] + vars.update(config_entry) + vars['package'] = package + vars['package-env-prefix'] = 'FIRMWARE_' + package.upper().replace('-', '_') + + # Those might be absent, set them to empty string for replacement to work: + for optional in ['replaces', 'conflicts', 'breaks', 'provides', 'recommends']: + if optional not in vars: + vars[optional] = '' + + package_dir = "debian/config/%s" % package + + try: + os.unlink('debian/firmware-%s.bug-presubj' % package) + except OSError: + pass + os.symlink('bug-presubj', 'debian/firmware-%s.bug-presubj' % package) + + files_orig = config_entry['files'] + files_real = {} + files_unused = [] + links = {} + links_rev = {} + + # Look for additional and replacement files in binary package config + for root, dirs, files in os.walk(package_dir): try: - os.unlink('debian/firmware-%s.bug-presubj' % package) - except OSError: + dirs.remove('.svn') + except ValueError: pass - os.symlink('bug-presubj', 'debian/firmware-%s.bug-presubj' % package) - - files_orig = config_entry['files'] - files_real = {} - files_unused = [] - links = {} - links_rev = {} - - # Look for additional and replacement files in binary package config - for root, dirs, files in os.walk(package_dir): - try: - dirs.remove('.svn') - except ValueError: - pass - for f in files: - cur_path = root + '/' + f - if root != package_dir: - f = root[len(package_dir) + 1 : ] + '/' + f - if os.path.islink(cur_path): - if f in files_orig: - links[f] = os.readlink(cur_path) - continue - f1 = f.rsplit('-', 1) + for f in files: + cur_path = root + '/' + f + if root != package_dir: + f = root[len(package_dir) + 1 : ] + '/' + f + if os.path.islink(cur_path): if f in files_orig: - files_real[f] = f, cur_path, None - continue - if len(f1) > 1: - f_base, f_version = f1 - if f_base in files_orig: - if f_base in files_real: - raise RuntimeError("Multiple files for %s" % f_base) - files_real[f_base] = f_base, package_dir + '/' + f, \ - f_version - continue - # Whitelist files not expected to be installed as firmware - if f in ['defines', 'LICENSE.install', - 'update.py', 'update.sh']: + links[f] = os.readlink(cur_path) + continue + f1 = f.rsplit('-', 1) + if f in files_orig: + files_real[f] = f, cur_path, None + continue + if len(f1) > 1: + f_base, f_version = f1 + if f_base in files_orig: + if f_base in files_real: + raise RuntimeError("Multiple files for %s" % f_base) + files_real[f_base] = f_base, package_dir + '/' + f, \ + f_version continue - files_unused.append(f) - - # Take all the other files from upstream - for f in files_orig: - if f not in files_real and f not in links: - f_upstream = os.path.join('debian/build/install', f) - if os.path.islink(f_upstream): - links[f] = os.readlink(f_upstream) - elif os.path.isfile(f_upstream): - files_real[f] = f, f_upstream, None - - for f in links: - link_target = os.path.normpath(os.path.join(f, '..', links[f])) - links_rev.setdefault(link_target, []).append(f) - - if files_unused: - print('W: %s: unused files:' % package, ' '.join(files_unused), - file=sys.stderr) - - makeflags['FILES'] = ' '.join(["%s:%s" % (i[1], i[0]) for i in sorted(files_real.values())]) - vars['files_real'] = ' '.join(["/lib/firmware/%s" % i for i in config_entry['files']]) - - makeflags['LINKS'] = ' '.join(["%s:%s" % (link, target) - for link, target in sorted(links.items())]) - - files_desc = ["Contents:"] - firmware_meta_temp = self.templates.get("metainfo.xml.firmware") - firmware_meta_list = [] - module_names = set() - - wrap = TextWrapper(width = 71, fix_sentence_endings = True, - initial_indent = ' * ', - subsequent_indent = ' ').wrap - for f in config_entry['files']: - firmware_meta_list.append(self.substitute(firmware_meta_temp, - {'filename': f})) - for module_name in self.firmware_modules.get(f, []): - module_names.add(module_name) - if f in links: + # Whitelist files not expected to be installed as firmware + if f in ['defines', 'LICENSE.install', + 'update.py', 'update.sh']: continue - f, f_real, version = files_real[f] - c = self.config.get(('base', package, f), {}) - desc = c.get('desc') - if version is None: - version = c.get('version') - try: - f = f + ', ' + ', '.join(sorted(links_rev[f])) - except KeyError: - pass - if desc and version: - desc = "%s, version %s (%s)" % (desc, version, f) - elif desc: - desc = "%s (%s)" % (desc, f) - else: - desc = "%s" % f - files_desc.extend(wrap(desc)) - - modaliases = set() - for module_name in module_names: - for modalias in self.modinfo[module_name]['alias']: - modaliases.add(modalias) - modalias_meta_list = [ - self.substitute(self.templates.get("metainfo.xml.modalias"), - {'alias': alias}) - for alias in sorted(list(modaliases)) - ] - - packages_binary = self.templates.get_control("control.binary", vars) - - packages_binary[0]['Description'].append_pre(files_desc) - - if 'initramfs-tools' in config_entry.get('support', []): - postinst = self.templates.get('postinst.initramfs-tools') - with open(f'debian/firmware-{package}.postinst', 'w') as postint_f: - postint_f.write(self.substitute(postinst, vars)) - - if 'license-accept' in config_entry: - with open(f'{package_dir}/LICENSE.install', 'r') as license_f: - license = license_f.read() - preinst = self.templates.get('preinst.license') - preinst_filename = "debian/firmware-%s.preinst" % package - with open(preinst_filename, 'w') as preinst_f: - preinst_f.write(self.substitute(preinst, vars)) - - templates = self.templates.get_templates_control('templates.license', vars) - templates[0]['Description'].append(re.sub('\n\n', '\n.\n', license)) - templates_filename = "debian/firmware-%s.templates" % package - self.write_rfc822(templates_filename, templates) - - desc = packages_binary[0]['Description'] - desc.append( + files_unused.append(f) + + # Take all the other files from upstream + for f in files_orig: + if f not in files_real and f not in links: + f_upstream = os.path.join('debian/build/install', f) + if os.path.islink(f_upstream): + links[f] = os.readlink(f_upstream) + elif os.path.isfile(f_upstream): + files_real[f] = f, f_upstream, None + + for f in links: + link_target = os.path.normpath(os.path.join(f, '..', links[f])) + links_rev.setdefault(link_target, []).append(f) + + if files_unused: + print('W: %s: unused files:' % package, ' '.join(files_unused), + file=sys.stderr) + + vars['files_real'] = ' '.join(["/lib/firmware/%s" % i for i in config_entry['files']]) + + append_to_rules_gen(rules_gen, package, files_real, links) + + files_desc = ["Contents:"] + firmware_meta_temp = templates.get("metainfo.xml.firmware") + firmware_meta_list = [] + module_names = set() + + wrap = TextWrapper(width = 71, fix_sentence_endings = True, + initial_indent = ' * ', + subsequent_indent = ' ').wrap + for f in config_entry['files']: + firmware_meta_list.append(substitute(firmware_meta_temp, + {'filename': f})) + for module_name in firmware_modules.get(f, []): + module_names.add(module_name) + if f in links: + continue + f, f_real, version = files_real[f] + c = config.get(('base', package, f), {}) + desc = c.get('desc') + if version is None: + version = c.get('version') + try: + f = f + ', ' + ', '.join(sorted(links_rev[f])) + except KeyError: + pass + if desc and version: + desc = "%s, version %s (%s)" % (desc, version, f) + elif desc: + desc = "%s (%s)" % (desc, f) + else: + desc = "%s" % f + files_desc.extend(wrap(desc)) + + modaliases = set() + for module_name in module_names: + for modalias in modinfo[module_name]['alias']: + modaliases.add(modalias) + modalias_meta_list = [ + substitute(templates.get("metainfo.xml.modalias"), + {'alias': alias}) + for alias in sorted(list(modaliases)) + ] + + packages_binary = templates.get_control("control.binary", vars) + + packages_binary[0]['Description'].append_pre(files_desc) + + if 'initramfs-tools' in config_entry.get('support', []): + postinst = templates.get('postinst.initramfs-tools') + with open(f'debian/firmware-{package}.postinst', 'w') as postint_f: + postint_f.write(substitute(postinst, vars)) + + if 'license-accept' in config_entry: + with open(f'{package_dir}/LICENSE.install', 'r') as license_f: + license = license_f.read() + preinst = templates.get('preinst.license') + preinst_filename = "debian/firmware-%s.preinst" % package + with open(preinst_filename, 'w') as preinst_f: + preinst_f.write(substitute(preinst, vars)) + + templates_license = templates.get_templates_control('templates.license', vars) + templates_license[0]['Description'].append(re.sub('\n\n', '\n.\n', license)) + templates_filename = "debian/firmware-%s.templates" % package + write_rfc822(templates_filename, templates_license) + + desc = packages_binary[0]['Description'] + desc.append( """This firmware is covered by the %s. You must agree to the terms of this license before it is installed.""" % vars['license-title']) - packages_binary[0]['Pre-Depends'] = PackageRelation('debconf | debconf-2.0') - - packages.extend(packages_binary) - - makefile.add_cmds('binary-indep', ["$(MAKE) -f debian/rules.real binary-indep %s" % makeflags]) - - vars['firmware-list'] = ''.join(firmware_meta_list) - vars['modalias-list'] = ''.join(modalias_meta_list) - # Underscores are preferred to hyphens - vars['package-metainfo'] = package.replace('-', '_') - # Summary must not contain line breaks - vars['longdesc-metainfo'] = re.sub(r'\s+', ' ', vars['longdesc']) - package_meta_temp = self.templates.get("metainfo.xml", {}) - # XXX Might need to escape some characters - with open(f'debian/firmware-{package}.metainfo.xml', 'w') as meta_f: - meta_f.write(self.substitute(package_meta_temp, vars)) - - def substitute(self, s, vars): - if isinstance(s, (list, tuple)): - return [self.substitute(i, vars) for i in s] - def subst(match): - if match.group(1): - return vars.get(match.group(2), '') - else: - return vars[match.group(2)] - return re.sub(r'@(\??)([-_a-z]+)@', subst, str(s)) - - def write(self, packages, makefile): - self.write_control(packages.values()) - self.write_makefile(makefile) - - def write_control(self, list): - self.write_rfc822('debian/control', list) - - def write_makefile(self, makefile): - with open('debian/rules.gen', 'w') as f: - makefile.write(f) - - def write_rfc822(self, path, list): - with open(path, 'w') as f: - for entry in list: - for key, value in entry.items(): - f.write("%s: %s\n" % (key, value)) - f.write('\n') + packages_binary[0]['Pre-Depends'] = PackageRelation('debconf | debconf-2.0') + + packages.extend(packages_binary) + + vars['firmware-list'] = ''.join(firmware_meta_list) + vars['modalias-list'] = ''.join(modalias_meta_list) + # Underscores are preferred to hyphens + vars['package-metainfo'] = package.replace('-', '_') + # Summary must not contain line breaks + vars['longdesc-metainfo'] = re.sub(r'\s+', ' ', vars['longdesc']) + package_meta_temp = templates.get("metainfo.xml", {}) + # XXX Might need to escape some characters + with open(f'debian/firmware-{package}.metainfo.xml', 'w') as meta_f: + meta_f.write(substitute(package_meta_temp, vars)) + + +def append_to_rules_gen(rules_gen, package, files_real, links): + deb_pkg = f'firmware-{package}' + pkg_dir = f'debian/{deb_pkg}' + firmware_dir = f'{pkg_dir}/lib/firmware' + + for dst, src, _vsn in files_real.values(): + rules_gen.write(f"install -m644 -D '{src}' '{firmware_dir}/{dst}'\n") + + # Avoid flooding the build log with redundant 'install -d'. + seen_dirnames = set() + for link, target in links.items(): + link_path = f'{firmware_dir}/{link}' + link_dirname = os.path.dirname(link_path) + + if link_dirname not in seen_dirnames: + seen_dirnames.add(link_dirname) + rules_gen.write(f"install -d '{link_dirname}'\n") + + rules_gen.write(f"ln -s '{target}' '{link_path}'\n") + + rules_gen.write( + f'dh_install -p{deb_pkg} {pkg_dir}.metainfo.xml usr/share/metainfo\n') + + +def substitute(s, vars): + if isinstance(s, (list, tuple)): + return [substitute(i, vars) for i in s] + def subst(match): + if match.group(1): + return vars.get(match.group(2), '') + else: + return vars[match.group(2)] + return re.sub(r'@(\??)([-_a-z]+)@', subst, str(s)) + + +def write_rfc822(path, list): + with open(path, 'w') as f: + for entry in list: + for key, value in entry.items(): + f.write("%s: %s\n" % (key, value)) + f.write('\n') + if __name__ == '__main__': - GenControl()() + main() diff --git a/debian/rules b/debian/rules index f455e5e..503d6b6 100755 --- a/debian/rules +++ b/debian/rules @@ -9,21 +9,26 @@ include debian/rules.defs GENCONTROL = debian/bin/gencontrol.py -# Nothing to build -build-indep build-arch build: debian/control - -clean: debian/control - dh_testdir - dh_clean - -binary-indep: build-indep - dh_testdir +binary binary-arch binary-indep build build-arch build-indep clean: \ + debian/control + dh $@ + +# Tell debhelper to ignore ./configure and Makefile. +override_dh_auto_configure: +override_dh_auto_build: +override_dh_auto_install: ./copy-firmware.sh -v debian/build/install - $(MAKE) -f debian/rules.gen binary-indep +override_dh_auto_test: + +execute_before_dh_install: debian/rules.gen + cat $< + sh -e $< -binary-arch: build-arch +override_dh_installdocs: + dh_installdocs -XTODO -binary: binary-indep binary-arch +execute_after_dh_installdeb: + if command -v dh_movetousr >/dev/null; then dh_movetousr; fi CONTROL_FILES = debian/build/version-info $(wildcard debian/templates/*.in) CONTROL_FILES += $(GENCONTROL) debian/config/defines $(wildcard debian/config/*/defines) debian/modinfo.json diff --git a/debian/rules.real b/debian/rules.real deleted file mode 100644 index 3fa602f..0000000 --- a/debian/rules.real +++ /dev/null @@ -1,45 +0,0 @@ -SHELL := sh -e - -export DH_OPTIONS - -# -# Targets -# -binary-indep: install - -install: PACKAGE_NAME = firmware-$(PACKAGE) -install: DH_OPTIONS = -p$(PACKAGE_NAME) -install: - dh_testdir - dh_testroot - dh_prep - @for i in $(FILES); do \ - s="$${i%:*}"; \ - d=/lib/firmware/"$${i#*:}"; \ - echo install -m644 -D "$$s" debian/$(PACKAGE_NAME)"$$d"; \ - install -m644 -D "$$s" debian/$(PACKAGE_NAME)"$$d"; \ - done - @for i in $(LINKS); do \ - link=debian/$(PACKAGE_NAME)/lib/firmware/"$${i%:*}"; \ - target="$${i#*:}"; \ - install -d "$${link%/*}"; \ - echo ln -s "$$target" "$$link"; \ - ln -s "$$target" "$$link"; \ - done -ifneq ($(FILES),) - dh_installdirs /usr/share/metainfo - dh_install debian/$(PACKAGE_NAME).metainfo.xml /usr/share/metainfo -endif - dh_bugfiles - dh_installchangelogs - dh_installdocs -XTODO - dh_installdebconf - dh_lintian - dh_link - dh_compress - dh_fixperms - dh_installdeb - if command -v dh_movetousr >/dev/null; then dh_movetousr; fi - dh_gencontrol - dh_md5sums - dh_builddeb -- 2.39.2