220 lines
5.7 KiB
Python
220 lines
5.7 KiB
Python
import os
|
|
import sys
|
|
import tomli
|
|
from dependency import *
|
|
from cmake import CMakeBuildSystem
|
|
from publish import Publish
|
|
from build import UnknownBuildSystemError
|
|
from env import Environment
|
|
from source_only import SourceOnlyBuildSystem
|
|
from generic import GenericBuildSystem
|
|
|
|
|
|
all_seeds = {}
|
|
|
|
|
|
class SeedParseError(Exception):
|
|
pass
|
|
|
|
|
|
class Seed(DependencyItem):
|
|
def all_seeds():
|
|
return all_seeds
|
|
|
|
|
|
def get(name):
|
|
if name in all_seeds:
|
|
return all_seeds[name]
|
|
|
|
return None
|
|
|
|
|
|
def load_file(self, path):
|
|
with open(path, mode='rb') as f:
|
|
self.__data = tomli.load(f)
|
|
|
|
|
|
def __init_dependencies(self):
|
|
self.__dependencies = {}
|
|
|
|
if 'dependency' not in self.__data:
|
|
return
|
|
|
|
dependency = self.__data['dependency']
|
|
if 'seeds' in dependency:
|
|
seeds = dependency['seeds']
|
|
self.__dependencies = {}
|
|
for s in seeds:
|
|
self.__dependencies[s] = SeedDependency(parent=self.name(), name=s)
|
|
|
|
|
|
def __init_build_system(self):
|
|
self.__build_system = None
|
|
if 'build' not in self.__data:
|
|
return
|
|
|
|
build = self.__data['build']
|
|
if 'build_system' not in build:
|
|
return
|
|
|
|
source_dir = os.path.dirname(self.__seed_path)
|
|
bin_dir = os.path.join(Environment.build_root(), self.name())
|
|
install = self.__data.get('install', None)
|
|
|
|
if 'source_dir' in build:
|
|
source_dir = build['source_dir']
|
|
|
|
match build['build_system']:
|
|
case 'none':
|
|
self.__build_system = None
|
|
case 'cmake':
|
|
self.__build_system = CMakeBuildSystem(
|
|
parent=self,
|
|
name=self.name(),
|
|
source_dir=source_dir,
|
|
bin_dir=bin_dir,
|
|
install=install,
|
|
data=build)
|
|
case 'source-only':
|
|
self.__build_system = SourceOnlyBuildSystem(
|
|
parent=self,
|
|
name=self.name(),
|
|
source_dir=source_dir,
|
|
bin_dir=bin_dir,
|
|
install=install,
|
|
data=build)
|
|
case 'generic':
|
|
self.__build_system = GenericBuildSystem(
|
|
parent=self,
|
|
name=self.name(),
|
|
source_dir=source_dir,
|
|
bin_dir=bin_dir,
|
|
install=install,
|
|
data=build)
|
|
case _:
|
|
raise UnknownBuildSystemError(
|
|
'Seed {} has unrecognised build system "{}"'.format(self.name(), build['build_system']))
|
|
|
|
|
|
def __init_publish(self):
|
|
install_path = Environment.system_root()
|
|
if 'build' in self.__data and 'build_for' in self.__data['build']:
|
|
build_for = self.__data['build']['build_for']
|
|
if build_for == 'host':
|
|
install_path = Environment.native_root()
|
|
|
|
self.__publish = None
|
|
if 'publish' not in self.__data:
|
|
return
|
|
|
|
self.__publish = Publish(install_path=install_path, data=self.__data['publish'])
|
|
|
|
|
|
def add_dependency(self, name, dep):
|
|
self.__dependencies[name] = dep
|
|
|
|
|
|
def collect_dependencies(self, **kwargs):
|
|
ctx = None
|
|
if 'ctx' in kwargs:
|
|
ctx = kwargs['ctx']
|
|
else:
|
|
ctx = {}
|
|
|
|
for k, d in self.__dependencies.items():
|
|
if k in ctx:
|
|
continue
|
|
|
|
ctx[d.name()] = d.target()
|
|
if isinstance(d.target(), Seed):
|
|
d.target().collect_dependencies(ctx=ctx)
|
|
|
|
return list(ctx.values())
|
|
|
|
|
|
def __init__(self, **kwargs):
|
|
super().__init__()
|
|
|
|
if not 'path' in kwargs:
|
|
return
|
|
|
|
self.__seed_path = kwargs['path']
|
|
self.load_file(kwargs['path'])
|
|
self.__init_dependencies()
|
|
self.__init_build_system()
|
|
self.__init_publish()
|
|
|
|
|
|
def seed_path(self):
|
|
return self.__seed_path
|
|
|
|
|
|
def name(self):
|
|
if not 'seed' in self.__data:
|
|
return None
|
|
|
|
s = self.__data['seed']
|
|
if 'name' in s:
|
|
return s['name']
|
|
return None
|
|
|
|
|
|
def type(self):
|
|
if not 'seed' in self.__data:
|
|
return None
|
|
|
|
s = self.__data['seed']
|
|
if 'type' in s:
|
|
return s['type']
|
|
return 'component'
|
|
|
|
|
|
def dependencies(self):
|
|
return self.__dependencies
|
|
|
|
|
|
def publish(self):
|
|
return self.__publish
|
|
|
|
|
|
def install(self):
|
|
return self.__data.get('install', None)
|
|
|
|
|
|
def should_include_standard_dependencies(self):
|
|
if 'dependency' not in self.__data:
|
|
return True
|
|
|
|
s = self.__data['dependency']
|
|
if 'no_standard_dependencies' in s:
|
|
return not s['no_standard_dependencies']
|
|
|
|
return True
|
|
|
|
|
|
def build_system(self):
|
|
return self.__build_system
|
|
|
|
|
|
def scan_directory(paths):
|
|
for p in paths:
|
|
for root, dirs, files in os.walk(p):
|
|
for f in files:
|
|
if not f.endswith('.seed'):
|
|
continue
|
|
seed_path = os.path.join(root, f)
|
|
seed = None
|
|
try:
|
|
seed = Seed(path=seed_path)
|
|
except tomli.TOMLDecodeError as e:
|
|
raise SeedParseError('Err: Failed to parse seed file {}: {}'.format(seed_path, e))
|
|
|
|
all_seeds[seed.name()] = seed
|
|
|
|
|
|
def resolve_all():
|
|
for s in all_seeds.values():
|
|
deps = s.dependencies()
|
|
for k, v in deps.items():
|
|
v.resolve()
|