Move from target logic to steps logic.

This is the big change !!!!

Instead of handling target as primary object and prepare/build targets,
we are handling build steps.

A build step may be a source (preparation) or a build (of the source).
Actualy, a step is a tuple (context, Builder or Source).

The context define the context of the step. It can be :
- 'source', for a Source step
- 'neutral' or the name of a platform for Build step.

Target becomes a "Class only" class.
This commit is contained in:
Matthieu Gautier
2018-05-28 15:42:30 +02:00
parent 754df8df1d
commit 041826d0e8
17 changed files with 393 additions and 233 deletions

View File

@ -3,8 +3,14 @@ import sys
from collections import OrderedDict
from .buildenv import *
from .platforms import PlatformInfo
from .utils import remove_duplicates, StopBuild
from .dependencies import Dependency
from ._global import (
neutralEnv,
add_target_step, get_target_step, target_steps,
add_plt_step, get_plt_step, plt_steps)
from . import _global
class Builder:
def __init__(self, options):
@ -15,78 +21,115 @@ class Builder:
'Select another target platform, or change your host system.'
).format(options.target_platform, self.distname))
sys.exit(-1)
self.targets = OrderedDict()
self.platform = platform = platformClass(self.targets)
self.platform = platform = platformClass()
_targets = {}
targetDef = options.targets
targetDef = (options.target_platform, options.targets)
self.add_targets(targetDef, _targets)
dependencies = self.order_dependencies(_targets, targetDef)
dependencies = list(remove_duplicates(dependencies))
if options.build_nodeps:
self.targets[targetDef] = _targets[targetDef]
add_target_step(targetDef, _targets[targetDef])
else:
for dep in dependencies:
if self.options.build_deps_only and dep == targetDef:
continue
self.targets[dep] = _targets[dep]
add_target_step(dep, _targets[dep])
def add_targets(self, targetName, targets):
if targetName in targets:
def add_targets(self, targetDef, targets):
if targetDef in targets:
return
targetPlatformName, targetName = targetDef
targetPlatform = PlatformInfo.all_platforms[targetPlatformName]
targetClass = Dependency.all_deps[targetName]
target = targetClass(self.platform.buildEnv)
targets[targetName] = target
for dep in target.builder.get_dependencies(self.platform):
self.add_targets(dep, targets)
targets[('source', targetName)] = targetClass.Source
targets[targetDef] = targetClass.Builder
for dep in targetClass.Builder.get_dependencies(targetPlatform):
try:
depPlatform, depName = dep
except ValueError:
depPlatform, depName = targetPlatformName, dep
self.add_targets((depPlatform, depName), targets)
def order_dependencies(self, _targets, targetName):
target = _targets[targetName]
for depName in target.builder.dependencies(self.platform):
yield from self.order_dependencies(_targets, depName)
yield targetName
def order_dependencies(self, _targets, targetDef):
targetPlatformName, targetName = targetDef
if targetPlatformName == 'source':
# Do not try to order sources, they will be added as dep by the
# build step two lines later.
return
target = _targets[targetDef]
targetPlatform = PlatformInfo.all_platforms[targetPlatformName]
yield ('source', targetName)
for dep in target.get_dependencies(targetPlatform):
try:
depPlatform, depName = dep
except ValueError:
depPlatform, depName = targetPlatformName, dep
yield from self.order_dependencies(_targets, (depPlatform, depName))
yield targetDef
def prepare_toolchain_sources(self):
tlsourceDefs = (tlDef for tlDef in plt_steps() if tlDef[0]=='source')
for tlsourceDef in tlsourceDefs:
print("prepare sources for toolchain {} :".format(tlsourceDef[1]))
toolchainClass = Toolchain.all_toolchains[tlsourceDef[1]]
source = get_plt_step(tlsourceDef)(toolchainClass)
add_plt_step(tlsourceDef, source)
source.prepare()
def prepare_sources(self):
if self.options.skip_source_prepare:
print("SKIP")
return
toolchain_sources = (tlc.source for tlc in self.platform.buildEnv.toolchains if tlc.source)
for toolchain_source in toolchain_sources:
print("prepare sources for toolchain {} :".format(toolchain_source.name))
toolchain_source.prepare()
sourceDefs = remove_duplicates(tDef for tDef in target_steps() if tDef[0]=='source')
for sourceDef in sourceDefs:
sources = (dep.source for dep in self.targets.values() if not dep.skip)
sources = remove_duplicates(sources, lambda s: s.__class__)
for source in sources:
print("prepare sources {} :".format(source.name))
print("prepare sources {} :".format(sourceDef[1]))
depClass = Dependency.all_deps[sourceDef[1]]
source = get_target_step(sourceDef)(depClass)
add_target_step(sourceDef, source)
source.prepare()
def build(self):
toolchain_builders = (tlc.builder for tlc in self.platform.buildEnv.toolchains if tlc.builder)
for toolchain_builder in toolchain_builders:
print("build toolchain {} :".format(toolchain_builder.name))
toolchain_builder.build()
builders = (dep.builder for dep in self.targets.values() if (dep.builder and not dep.skip))
for builder in builders:
if self.options.make_dist and builder.name == self.options.targets:
continue
print("build {} :".format(builder.name))
def build_toolchains(self):
tlbuilderDefs = (tlDef for tlDef in plt_steps() if tlDef[0] != 'source')
for tlbuilderDef in tlbuilderDefs:
print("build toolchain {} :".format(tlbuilderDef[1]))
toolchainClass = Toolchain.all_toolchains[tlbuilderDef[1]]
source = get_plt_step(tlbuilderDef[1], 'source')
if tlbuilderDef[0] == 'neutral':
env = _global._neutralEnv
else:
env = PlatformInfo.all_running_platforms[tlbuilderDef[0]].buildEnv
builder = get_plt_step(tlbuilderDef)(toolchainClass, source, env)
add_plt_step(tlbuilderDef, builder)
builder.build()
def build(self):
builderDefs = (tDef for tDef in target_steps() if tDef[0] != 'source')
for builderDef in builderDefs:
depClass = Dependency.all_deps[builderDef[1]]
source = get_target_step(builderDef[1], 'source')
env = PlatformInfo.all_running_platforms[builderDef[0]].buildEnv
builder = get_target_step(builderDef)(depClass, source, env)
if self.options.make_dist and builderDef[1] == self.options.targets:
print("make dist {}:".format(builder.name))
builder.make_dist()
continue
print("build {} ({}):".format(builder.name, builderDef[0]))
add_target_step(builderDef, builder)
builder.build()
if self.options.make_dist:
dep = self.targets[self.options.targets]
builder = dep.builder
print("make dist {}:".format(builder.name))
builder.make_dist()
def run(self):
try:
print("[SETUP PLATFORMS]")
self.prepare_toolchain_sources()
self.build_toolchains()
self.platform.finalize_setup()
print("[INSTALL PACKAGES]")
self.platform.install_packages()
self.platform.finalize_setup()
print("[PREPARE]")
self.prepare_sources()
print("[BUILD]")