meta: replace cmake mono-build system with a custom build co-ordinator

every system component now has its own self-contained build system, and a
seed file describing the component and its build system and dependencies.

a new tool, meadow, collects and uses these seed files to build the
components into a full system. meadow also manages the target system root
and a host prefix where toolchain tools are installed to.

the build system has also been updated to use a new $ARCH-rosetta-gcc
compiler, and the patches files necessary to build it have been
added to toolchain/cross-compiler.
This commit is contained in:
2026-07-19 13:34:32 +01:00
parent 59034be9e6
commit 1ec33767ab
104 changed files with 7111 additions and 257 deletions
+156
View File
@@ -0,0 +1,156 @@
import os
class DependencyResolutionError(Exception):
pass
class DependencyItem:
def __init__(self):
self.__target = None
self.__dep_list = None
def name(self):
return None
def target(self):
return self.__target
def dependencies(self):
return None
def dependency_list(self):
return self.__dep_list
def publish(self):
return None
def reset_resolution(self):
self.__dep_list = None
def resolve(self, **kwargs):
if self.__dep_list is not None:
return self.__dep_list
ctx = None
dep_list = None
if 'ctx' in kwargs:
ctx = kwargs['ctx']
else:
ctx = {}
if 'dep_list' in kwargs:
dep_list = kwargs['dep_list']
else:
dep_list = []
if self.name() in ctx:
return
ctx[self.name()] = self
deps = self.dependencies()
if deps is None:
return
for d in deps.values():
d_value = d.resolve_self()
if d_value is not None:
d_value.resolve(ctx=ctx, dep_list=dep_list)
dep_list.append(self)
return dep_list
class Dependency:
def __init__(self, parent):
self.__parent = parent
def name(self, parent):
return None
def parent_name(self):
return self.__parent
def resolve_self(self):
return None
def is_resolved(self):
return False
class SeedDependency(Dependency):
def __init__(self, **kwargs):
self.__target_seed = None
if 'name' in kwargs:
self.__name = kwargs['name']
if 'parent' in kwargs:
super().__init__(kwargs['parent'])
def name(self):
return self.__name
def target(self):
return self.__target_seed
def resolve_self(self):
from seed import Seed
if self.__target_seed is not None:
return self.__target_seed
target = Seed.get(self.__name)
if target is None:
raise DependencyResolutionError(
'{} depends on seed "{}", but the required seed cannot be found'.format(self.parent_name(), self.__name))
self.__target_seed = target
return self.__target_seed
def is_resolved(self):
return self.__target_seed is not None
class ProgramDependency(Dependency):
def __init__(self, **kwargs):
if 'name' in kwargs:
self.__name = kwargs['name']
if 'parent' in kwargs:
super().__init__(kwargs['parent'])
def __is_exe(self, fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
def name(self):
return self.__name
def resolve_self(self):
if self.__is_exe(self.__name):
return None
path_string = os.environ['PATH']
path_list = path_string.split(':')
for d in path_list:
exe_path = os.path.join(d, self.__name)
if self.__is_exe(exe_path):
return None
raise DependencyResolutionError(f'{self.parent_name()} depends on command `{self.__name}`, but the command cannot be found. Make sure that the named command exists, the containing directory is in $PATH if necessary, and the executable file has the correct permissions.')