new file mode 100755
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import apt_pkg
+import apt.progress.base
+
+sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '/bitbake/lib')
+
+import bb.tinfoil
+
+class IsarBuilder:
+ def __init__(self):
+ self.tinfoil = bb.tinfoil.Tinfoil()
+ self.tinfoil.prepare()
+
+ def create_apt_rootfs(self, rootfs):
+ repo_isar_dir = '%s/tmp/deploy/isar-apt/%s-%s/apt' % (os.path.abspath(os.getcwd()), self.distro, self.arch)
+ mirror = 'file://%s/%s' % (repo_isar_dir, self.distro)
+ codename = 'isar'
+
+ if not os.path.exists(rootfs + '/var/lib/dpkg'):
+ os.makedirs(rootfs + '/var/lib/dpkg')
+ open(rootfs + '/var/lib/dpkg/status', 'w').close()
+
+ if not os.path.exists(rootfs + '/etc/apt/preferences.d'):
+ os.makedirs(rootfs + '/etc/apt/preferences.d')
+ with open(rootfs + '/etc/apt/sources.list', 'w') as f:
+ f.write('deb [arch=%s] %s %s main\n' % (self.arch, mirror, codename))
+ f.write('deb-src [arch=%s] %s %s main\n' % (self.arch, mirror, codename))
+
+ if not os.path.exists(rootfs + '/var/cache/apt/archives/partial'):
+ os.makedirs(rootfs + '/var/cache/apt/archives/partial')
+
+ def apt_config(self):
+ apt_pkg.init()
+
+ rootfs = os.path.abspath(os.getcwd()) + '/tmp/deps_poc_rootfs/%s-%s' % (self.distro, self.arch)
+
+ if not os.path.isdir(rootfs):
+ self.create_apt_rootfs(rootfs)
+
+ apt_pkg.config.set('APT::Architecture', self.arch)
+ apt_pkg.config.set('Dir', rootfs)
+ apt_pkg.config.set('Dir::Cache', rootfs + '/var/cache/apt')
+ apt_pkg.config.set('Dir::State::status', rootfs + '/var/lib/dpkg/status')
+
+ apt_pkg.config.set("Acquire::AllowInsecureRepositories", "1")
+
+ def isar_apt_update(self):
+ sources = apt_pkg.SourceList()
+ sources.read_main_list()
+
+ progress = apt.progress.text.AcquireProgress()
+
+ self.cache = apt_pkg.Cache()
+ self.cache.update(progress, sources)
+ self.cache = apt_pkg.Cache()
+
+ def srcpackage_lookup(self, pkg):
+ if pkg in self.cache:
+ return
+ if self.tinfoil.find_best_provider(pkg)[3] is None:
+ return
+ if pkg not in self.target_deps:
+ self.need_deb.append(pkg)
+ self.sr.restart()
+ if self.sr.lookup(pkg) is None:
+ self.need_source.append(pkg)
+ return
+ if 'Build-Depends' not in self.sr.build_depends:
+ return
+ for dep in self.sr.build_depends['Build-Depends']:
+ child = str(dep[0][0])
+ if child not in self.checkdeps:
+ self.checkdeps.append(child)
+ self.srcpackage_lookup(child)
+
+ def bitbake(self, mc, targets, task='', justbuild=[]):
+ targets = [targets] if isinstance(targets, str) else targets
+ target_str = ''
+ for pn in targets:
+ target_str += 'mc:%s:%s ' % (mc, pn if not task else ':'.join([pn, task]))
+ targets.clear()
+ for pn in justbuild:
+ target_str += 'mc:%s:%s ' % (mc, pn)
+ justbuild.clear()
+ if target_str != '':
+ print('Building %s' % target_str)
+ self.tinfoil.build_targets(target_str)
+
+ def build(self, mc, target):
+ d = self.tinfoil.parse_recipe('multiconfig:%s:%s' % (mc, target))
+ self.distro = d.getVar('DISTRO', expand=True)
+ self.arch = d.getVar('DISTRO_ARCH', expand=True)
+
+ recipecache = self.tinfoil.cooker.recipecaches[mc]
+ provider = self.tinfoil.find_best_provider('multiconfig:%s:%s' % (mc, target))
+ self.target_deps = recipecache.deps[provider[3]]
+
+ kernel_image = d.getVar('KERNEL_IMAGE_PKG', expand=True) or ''
+ if kernel_image in self.target_deps:
+ kernel = self.tinfoil.find_best_provider('multiconfig:%s:%s' % (mc, kernel_image))
+ if kernel[3].endswith('linux-distro.bb'):
+ self.target_deps.remove(kernel_image)
+ print('Remove %s from checking' % kernel_image)
+
+ self.need_source = self.target_deps.copy()
+ self.need_deb = []
+
+ self.apt_config()
+
+ maxdepth = 3
+ while maxdepth > 0:
+ maxdepth -= 1
+
+ self.bitbake(mc, self.need_source, 'do_deploy_source', self.need_deb)
+
+ self.isar_apt_update()
+ self.sr = apt_pkg.SourceRecords()
+
+ self.checkdeps = []
+ for dep in self.target_deps:
+ if dep not in self.checkdeps:
+ self.checkdeps.append(dep)
+ self.srcpackage_lookup(dep)
+
+ if not self.need_source:
+ break
+
+ if self.need_source:
+ print('Following packages still left unchecked: ' + str(self.need_source))
+
+ if self.need_deb:
+ print('Additional Debian dependencies found:' + str(self.need_deb))
+ self.bitbake(mc, self.need_deb)
+
+ # start final build
+ self.bitbake(mc, target)
+
+ib = IsarBuilder()
+ib.build('qemuamd64-bullseye', 'isar-image-base')
Build Isar with external tool to parce all Debian package dependencies. Support only one target build for now, mc:qemuamd64-bullseye:isar-image-base is used by default. Usage (inside build dir): $ ../isar_builder.py Signed-off-by: Anton Mikanovich <amikan@ilbers.de> --- isar_builder.py | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100755 isar_builder.py