summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Thursfield <sam.thursfield@codethink.co.uk>2017-06-09 18:57:01 +0100
committerTristan Van Berkom <tristan.vanberkom@codethink.co.uk>2017-07-06 21:08:10 +0900
commit039062218957bdae6473b482adc8800fd9be7ed3 (patch)
tree122e15ab36ea8aa2a2928040f6f159006f42fe10
parentae59134a32cf7c28d8d0b4ccb5518a2a0c18b97b (diff)
downloadbuildstream-039062218957bdae6473b482adc8800fd9be7ed3.tar.gz
Add --host-arch and --target-arch, and 'host-arches' conditional
This command adds initial cross-compilation support to BuildStream. It has been tested against a converted version of the Baserock compiler bootstrap and used to cross build sysroots for armv8l64 and ppc64l from an x86_64 host. For example, to build a sysroot for ARM v8 64-bit you can do this: bst build --target-arch=armv8b64 gnu-toolchain/stage2.bst This would cause the adapted Baserock definitions to produce a stage1 simple cross compiler that runs on the native architecture and produces armv8b64 binaries, and then cross build a stage2 sysroot that executes on armv8b64. Currently the --host-arch option does nothing of use. It will one day enable host-incompatible builds using a QEMU-powered cross sandbox. The `--arch=` option is now shorthand for `--host-arch= --target-arch=`. Elements have 2 new variables available, %{bst-host-arch} and %{bst-target-arch}. The 'arches' conditional now follows %{bst-target-arch}, while the new 'host-arches' conditional follows %{bst-host-arch}. All of --arch, --host-arch and --target-arch default to the output of `uname -a`. There's no magic here that would make all BuildStream elements suddenly able to cross compile. It is up to an individual element to support this by honouring %{bst-target-arch} in whatever way makes sense.
-rw-r--r--buildstream/_frontend/main.py91
-rw-r--r--buildstream/_frontend/widget.py3
-rw-r--r--buildstream/_loader.py32
-rw-r--r--buildstream/_pipeline.py3
-rw-r--r--buildstream/context.py15
-rw-r--r--buildstream/project.py22
-rw-r--r--doc/source/format.rst3
-rw-r--r--tests/context/context.py2
-rw-r--r--tests/loader/arches.py76
-rw-r--r--tests/loader/arches/elements/host-arch-conditional.bst20
-rw-r--r--tests/loader/basics.py10
-rw-r--r--tests/loader/dependencies.py18
-rw-r--r--tests/loader/variants.py32
-rw-r--r--tests/sources/fixture.py2
14 files changed, 232 insertions, 97 deletions
diff --git a/buildstream/_frontend/main.py b/buildstream/_frontend/main.py
index 0224ce50e..fa8ea12a6 100644
--- a/buildstream/_frontend/main.py
+++ b/buildstream/_frontend/main.py
@@ -98,15 +98,20 @@ def cli(context, **kwargs):
@click.option('--track', default=False, is_flag=True,
help="Track new source references before building (implies --all)")
@click.option('--arch', '-a', default=host_machine,
- help="The target architecture (default: %s)" % host_machine)
+ help="Architecture of the machine running the build (default: %s)" % host_machine)
+@click.option('--host-arch',
+ help="Run as a native build for the given architecture (defaults to --arch)")
+@click.option('--target-arch',
+ help="Produce elements that execute on this architecture (defaults to --arch)")
@click.option('--variant',
help='A variant of the specified target')
@click.argument('target')
@click.pass_obj
-def build(app, target, arch, variant, all, track):
+def build(app, target, arch, host_arch, target_arch, variant, all, track):
"""Build elements in a pipeline"""
- app.initialize(target, arch, variant, rewritable=track, inconsistent=track)
+ app.initialize(target, host_arch or arch, target_arch or arch, variant,
+ rewritable=track, inconsistent=track)
app.print_heading()
try:
app.pipeline.build(app.scheduler, all, track)
@@ -128,12 +133,16 @@ def build(app, target, arch, variant, all, track):
@click.option('--track', default=False, is_flag=True,
help="Track new source references before fetching")
@click.option('--arch', '-a', default=host_machine,
- help="The target architecture (default: %s)" % host_machine)
+ help="Architecture of the machine running the build (default: %s)" % host_machine)
+@click.option('--host-arch',
+ help="Run as a native build for the given architecture (defaults to --arch)")
+@click.option('--target-arch',
+ help="Produce elements that execute on this architecture (defaults to --arch)")
@click.option('--variant',
help='A variant of the specified target')
@click.argument('target')
@click.pass_obj
-def fetch(app, target, arch, variant, deps, track, except_):
+def fetch(app, target, arch, host_arch, target_arch, variant, deps, track, except_):
"""Fetch sources required to build the pipeline
By default this will only try to fetch sources which are
@@ -148,7 +157,8 @@ def fetch(app, target, arch, variant, deps, track, except_):
plan: Only dependencies required for the build plan
all: All dependencies
"""
- app.initialize(target, arch, variant, rewritable=track, inconsistent=track)
+ app.initialize(target, host_arch or arch, target_arch or arch, variant,
+ rewritable=track, inconsistent=track)
try:
dependencies = app.pipeline.deps_elements(deps, except_)
app.print_heading(deps=dependencies)
@@ -169,12 +179,16 @@ def fetch(app, target, arch, variant, deps, track, except_):
type=click.Choice(['none', 'all']),
help='The dependencies to track (default: none)')
@click.option('--arch', '-a', default=host_machine,
- help="The target architecture (default: %s)" % host_machine)
+ help="Architecture of the machine running the build (default: %s)" % host_machine)
+@click.option('--host-arch',
+ help="Run as a native build for the given architecture (defaults to --arch)")
+@click.option('--target-arch',
+ help="Produce elements that execute on this architecture (defaults to --arch)")
@click.option('--variant',
help='A variant of the specified target')
@click.argument('target')
@click.pass_obj
-def track(app, target, arch, variant, deps, except_):
+def track(app, target, arch, host_arch, target_arch, variant, deps, except_):
"""Consults the specified tracking branches for new versions available
to build and updates the project with any newly available references.
@@ -187,7 +201,8 @@ def track(app, target, arch, variant, deps, except_):
none: No dependencies, just the element itself
all: All dependencies
"""
- app.initialize(target, arch, variant, rewritable=True, inconsistent=True)
+ app.initialize(target, host_arch or arch, target_arch or arch, variant,
+ rewritable=True, inconsistent=True)
try:
dependencies = app.pipeline.deps_elements(deps, except_)
app.print_heading(deps=dependencies)
@@ -214,12 +229,16 @@ def track(app, target, arch, variant, deps, except_):
type=click.STRING,
help='Format string for each element')
@click.option('--arch', '-a', default=host_machine,
- help="The target architecture (default: %s)" % host_machine)
+ help="Architecture of the machine running the build (default: %s)" % host_machine)
+@click.option('--host-arch',
+ help="Run as a native build for the given architecture (defaults to --arch)")
+@click.option('--target-arch',
+ help="Produce elements that execute on this architecture (defaults to --arch)")
@click.option('--variant',
help='A variant of the specified target')
@click.argument('target')
@click.pass_obj
-def show(app, target, arch, variant, deps, except_, order, format):
+def show(app, target, arch, host_arch, target_arch, variant, deps, except_, order, format):
"""Show elements in the pipeline
By default this will show all of the dependencies of the
@@ -264,7 +283,7 @@ def show(app, target, arch, variant, deps, except_, order, format):
bst show target.bst --format \\
$'---------- %{name} ----------\\n%{vars}'
"""
- app.initialize(target, arch, variant)
+ app.initialize(target, host_arch or arch, target_arch or arch, variant)
try:
dependencies = app.pipeline.deps_elements(deps, except_)
except PipelineError as e:
@@ -289,12 +308,16 @@ def show(app, target, arch, variant, deps, except_, order, format):
type=click.Choice(['build', 'run']),
help='Specify element scope to stage')
@click.option('--arch', '-a', default=host_machine,
- help="The target architecture (default: %s)" % host_machine)
+ help="Architecture of the machine running the build (default: %s)" % host_machine)
+@click.option('--host-arch',
+ help="Run as a native build for the given architecture (defaults to --arch)")
+@click.option('--target-arch',
+ help="Produce elements that execute on this architecture (defaults to --arch)")
@click.option('--variant',
help='A variant of the specified target')
@click.argument('target')
@click.pass_obj
-def shell(app, target, arch, variant, builddir, scope):
+def shell(app, target, arch, host_arch, target_arch, variant, builddir, scope):
"""Shell into an element's sandbox environment
This can be used either to debug building or to launch
@@ -313,7 +336,7 @@ def shell(app, target, arch, variant, builddir, scope):
elif scope == "build":
scope = Scope.BUILD
- app.initialize(target, arch, variant)
+ app.initialize(target, host_arch or arch, target_arch or arch, variant)
# Assert we have everything we need built.
missing_deps = []
@@ -346,16 +369,20 @@ def shell(app, target, arch, variant, builddir, scope):
@click.option('--force', '-f', default=False, is_flag=True,
help="Overwrite files existing in checkout directory")
@click.option('--arch', '-a', default=host_machine,
- help="The target architecture (default: %s)" % host_machine)
+ help="Architecture of the machine running the build (default: %s)" % host_machine)
+@click.option('--host-arch',
+ help="Run as a native build for the given architecture (defaults to --arch)")
+@click.option('--target-arch',
+ help="Produce elements that execute on this architecture (defaults to --arch)")
@click.option('--variant',
help='A variant of the specified target')
@click.argument('target')
@click.argument('directory')
@click.pass_obj
-def checkout(app, target, arch, variant, directory, force):
+def checkout(app, target, arch, host_arch, target_arch, variant, directory, force):
"""Checkout a built artifact to the specified directory
"""
- app.initialize(target, arch, variant)
+ app.initialize(target, host_arch or arch, target_arch or arch, variant)
try:
app.pipeline.checkout(directory, force)
click.echo("")
@@ -380,7 +407,11 @@ def checkout(app, target, arch, variant, directory, force):
@click.option('--track', default=False, is_flag=True,
help="Track new source references before building")
@click.option('--arch', '-a', default=host_machine,
- help="The target architecture (default: %s)" % host_machine)
+ help="Architecture of the machine running the build (default: %s)" % host_machine)
+@click.option('--host-arch',
+ help="Run as a native build for the given architecture (defaults to --arch)")
+@click.option('--target-arch',
+ help="Produce elements that execute on this architecture (defaults to --arch)")
@click.option('--variant',
help='A variant of the specified target')
@click.option('--force', '-f', default=False, is_flag=True,
@@ -389,7 +420,7 @@ def checkout(app, target, arch, variant, directory, force):
help="The directory to write the tarball to")
@click.argument('target')
@click.pass_obj
-def source_bundle(app, target, arch, variant, force, directory,
+def source_bundle(app, target, arch, host_arch, target_arch, variant, force, directory,
track, deps, compression, except_):
"""Produce a build bundle to be manually executed
@@ -400,7 +431,8 @@ def source_bundle(app, target, arch, variant, force, directory,
run: Runtime dependencies, including the element itself
build: Build time dependencies, excluding the element itself
"""
- app.initialize(target, arch, variant, rewritable=track, inconsistent=track)
+ app.initialize(target, host_arch or arch, target_arch or arch, variant,
+ rewritable=track, inconsistent=track)
try:
dependencies = app.pipeline.deps_elements(deps, except_)
app.print_heading(dependencies)
@@ -425,7 +457,8 @@ class App():
self.logger = None
self.status = None
self.target = None
- self.arch = None
+ self.host_arch = None
+ self.target_arch = None
self.variant = None
# Main asset handles
@@ -473,18 +506,20 @@ class App():
#
# Initialize the main pipeline
#
- def initialize(self, target, arch, variant, rewritable=False, inconsistent=False):
+ def initialize(self, target, host_arch, target_arch, variant,
+ rewritable=False, inconsistent=False):
self.target = target
- self.arch = arch
+ self.host_arch = host_arch
+ self.target_arch = target_arch
self.variant = variant
- profile_start(Topics.LOAD_PIPELINE, target.replace(os.sep, '-') + '-' + arch)
+ profile_start(Topics.LOAD_PIPELINE, target.replace(os.sep, '-') + '-' + host_arch + '-' + target_arch)
directory = self.main_options['directory']
config = self.main_options['config']
try:
- self.context = Context(arch)
+ self.context = Context(host_arch, target_arch)
self.context.load(config)
except _BstError as e:
click.echo("Error loading user configuration: %s" % str(e))
@@ -534,7 +569,7 @@ class App():
self.context._set_message_handler(self.message_handler)
try:
- self.project = Project(directory, arch)
+ self.project = Project(directory, host_arch, target_arch)
except _BstError as e:
click.echo("Error loading project: %s" % str(e))
sys.exit(1)
@@ -559,7 +594,7 @@ class App():
self.logger.size_request(self.pipeline)
self.messaging_enabled = True
- profile_end(Topics.LOAD_PIPELINE, target.replace(os.sep, '-') + '-' + arch)
+ profile_end(Topics.LOAD_PIPELINE, target.replace(os.sep, '-') + '-' + host_arch + '-' + target_arch)
#
# Render the status area, conditional on some internal state
diff --git a/buildstream/_frontend/widget.py b/buildstream/_frontend/widget.py
index a9f574d32..760a40b6a 100644
--- a/buildstream/_frontend/widget.py
+++ b/buildstream/_frontend/widget.py
@@ -426,7 +426,8 @@ class LogLine(Widget):
values["Session Start"] = starttime.strftime('%A, %d-%m-%Y at %H:%M:%S')
values["Project"] = "{} ({})".format(project.name, project.directory)
values["Target"] = pipeline.target.name
- values["Machine Architecture"] = context.arch
+ values["Host Architecture"] = context.host_arch
+ values["Target Architecture"] = context.target_arch
values["Variant"] = variant
text += self.format_values(values)
diff --git a/buildstream/_loader.py b/buildstream/_loader.py
index f8196ed8e..fd2eef655 100644
--- a/buildstream/_loader.py
+++ b/buildstream/_loader.py
@@ -45,6 +45,7 @@ class Symbol():
VARIANT = "variant"
VARIANTS = "variants"
ARCHES = "arches"
+ HOST_ARCHES = "host-arches"
SOURCES = "sources"
CONFIG = "config"
VARIABLES = "variables"
@@ -117,9 +118,11 @@ class VariantError(Exception):
# the arches dict from the data node afterwards, this is shared
# with project.py
#
-def resolve_arch(data, active_arch):
+def resolve_arch(data, host_arch, target_arch=None):
+
+ def resolve_single_arch_conditional(symbol, active_arch):
+ arches = _yaml.node_get(data, Mapping, symbol, default_value={})
- arches = _yaml.node_get(data, Mapping, Symbol.ARCHES, default_value={})
arch = {}
if arches:
arch = _yaml.node_get(arches, Mapping, active_arch, default_value={})
@@ -133,12 +136,16 @@ def resolve_arch(data, active_arch):
provenance = _yaml.node_get_provenance(arch, key=active_arch)
raise LoadError(LoadErrorReason.ILLEGAL_COMPOSITE,
"%s: Arch %s specifies type '%s' for path '%s', expected '%s'" %
- (str(provenance), active_arch,
+ (str(provenance),
+ active_arch,
e.actual_type.__name__,
e.path,
e.expected_type.__name__)) from e
- del data[Symbol.ARCHES]
+ del data[symbol]
+
+ resolve_single_arch_conditional(Symbol.HOST_ARCHES, active_arch=host_arch)
+ resolve_single_arch_conditional(Symbol.ARCHES, active_arch=target_arch or host_arch)
# A transient object breaking down what is loaded
@@ -147,11 +154,12 @@ def resolve_arch(data, active_arch):
#
class LoadElement():
- def __init__(self, data, filename, basedir, arch, elements):
+ def __init__(self, data, filename, basedir, host_arch, target_arch, elements):
self.filename = filename
self.data = data
- self.arch = arch
+ self.host_arch = host_arch
+ self.target_arch = target_arch
self.name = filename
self.elements = elements
@@ -159,7 +167,7 @@ class LoadElement():
self.basedir = basedir
# Process arch conditionals
- resolve_arch(self.data, self.arch)
+ resolve_arch(self.data, self.host_arch, self.target_arch)
# Dependency objects after resolving variants
self.variant_name = None
@@ -178,7 +186,7 @@ class LoadElement():
variant = Variant(self.name, variant_node)
# Process arch conditionals on individual variants
- resolve_arch(variant.data, self.arch)
+ resolve_arch(variant.data, self.host_arch, self.target_arch)
self.variants.append(variant)
if len(self.variants) == 1:
@@ -356,7 +364,7 @@ def extract_depends_from_node(owner, data):
#
class Loader():
- def __init__(self, basedir, filename, variant, arch):
+ def __init__(self, basedir, filename, variant, host_arch, target_arch):
# Ensure we have an absolute path for the base directory
#
@@ -381,8 +389,8 @@ class Loader():
# Optional variant
self.target_variant = variant
- # Build architecture
- self.arch = arch
+ self.host_arch = host_arch
+ self.target_arch = target_arch
self.loaded_files = {} # Table of files we've already loaded
self.meta_elements = {} # Dict of resolved meta elements by name
@@ -465,7 +473,7 @@ class Loader():
# Load the element and track it in our elements table
data = _yaml.load(fullpath, shortname=filename, copy_tree=rewritable)
- element = LoadElement(data, filename, self.basedir, self.arch, self.elements)
+ element = LoadElement(data, filename, self.basedir, self.host_arch, self.target_arch, self.elements)
self.elements[filename] = element
diff --git a/buildstream/_pipeline.py b/buildstream/_pipeline.py
index f931a0e83..c1eb3a863 100644
--- a/buildstream/_pipeline.py
+++ b/buildstream/_pipeline.py
@@ -140,7 +140,8 @@ class Pipeline():
self.element_factory = ElementFactory(pluginbase, project._plugin_element_paths)
self.source_factory = SourceFactory(pluginbase, project._plugin_source_paths)
- loader = Loader(self.project.element_path, target, target_variant, context.arch)
+ loader = Loader(self.project.element_path, target, target_variant,
+ context.host_arch, context.target_arch)
meta_element = loader.load(rewritable, load_ticker)
if load_ticker:
load_ticker(None)
diff --git a/buildstream/context.py b/buildstream/context.py
index 33aae86ae..0ad894d96 100644
--- a/buildstream/context.py
+++ b/buildstream/context.py
@@ -45,15 +45,19 @@ class Context():
"""Context of how BuildStream was invoked
Args:
- arch (string): The target architecture to build for
+ host_arch (string): The desired architecture on which to run the build
+ target_arch (string): The machine on which the results of the build should execute
"""
- def __init__(self, arch):
+ def __init__(self, host_arch, target_arch=None):
self.config_origin = None
"""Filename indicating which configuration file was used, or None for the defaults"""
- self.arch = arch
- """The target architecture to build for"""
+ self.host_arch = host_arch
+ """The desired architecture on which to run the build"""
+
+ self.target_arch = target_arch or host_arch
+ """The machine on which the results of the build should execute"""
self.sourcedir = None
"""The directory where various sources are stored"""
@@ -205,7 +209,8 @@ class Context():
# Anything that alters the build goes into the unique key
self._cache_key = utils._generate_key({
- 'arch': self.arch
+ 'host-arch': self.host_arch,
+ 'target-arch': self.target_arch
})
return self._cache_key
diff --git a/buildstream/project.py b/buildstream/project.py
index 6af6657f5..6ec270857 100644
--- a/buildstream/project.py
+++ b/buildstream/project.py
@@ -44,12 +44,16 @@ class Project():
Args:
directory (str): The project directory
- arch (str): Symbolic machine architecture name
+ host_arch (str): Symbolic host machine architecture name
+ target_arch (str): Symbolic target machine architecture name
Raises:
:class:`.LoadError`
"""
- def __init__(self, directory, arch):
+ def __init__(self, directory, host_arch, target_arch=None):
+
+ host_arch = host_arch
+ target_arch = target_arch or host_arch
self.name = None
"""str: The project name"""
@@ -69,7 +73,7 @@ class Project():
self._cache_key = None
profile_start(Topics.LOAD_PROJECT, self.directory.replace(os.sep, '-'))
- self._load(arch)
+ self._load(host_arch, target_arch)
profile_end(Topics.LOAD_PROJECT, self.directory.replace(os.sep, '-'))
def translate_url(self, url):
@@ -101,7 +105,7 @@ class Project():
#
# Raises: LoadError if there was a problem with the project.conf
#
- def _load(self, arch):
+ def _load(self, host_arch, target_arch):
# Load builtin default
projectfile = os.path.join(self.directory, "project.conf")
@@ -111,14 +115,20 @@ class Project():
# be processed here before compositing any overrides
variables = _yaml.node_get(config, Mapping, 'variables')
variables['max-jobs'] = multiprocessing.cpu_count()
- variables['bst-arch'] = arch
+
+ variables['bst-host-arch'] = host_arch
+ variables['bst-target-arch'] = target_arch
+
+ # This is kept around for compatibility with existing definitions,
+ # but we should probably remove it due to being ambiguous.
+ variables['bst-arch'] = host_arch
# Load project local config and override the builtin
project_conf = _yaml.load(projectfile)
_yaml.composite(config, project_conf, typesafe=True)
# Resolve arches keyword, project may have arch conditionals
- _loader.resolve_arch(config, arch)
+ _loader.resolve_arch(config, host_arch, target_arch)
# The project name
self.name = _yaml.node_get(config, str, 'name')
diff --git a/doc/source/format.rst b/doc/source/format.rst
index f77f3a368..ebe8e2636 100644
--- a/doc/source/format.rst
+++ b/doc/source/format.rst
@@ -453,6 +453,9 @@ The ``arches`` attribute, if provided, overrides the element for a given archite
name. It is not considered an error if the element does not provide an architecture
clause for the specific architecture BuildStream was launched to build for.
+There is also a ``host-arches`` attribute, which operates in the same manner but
+follows the *host* architecture rather than the *target* architecture.
+
In the above example we demonstrate that a given ``config`` attribute can be overridden
by an architecture conditional, this can however be done for any segment of the
element such as ``depends``, ``sources`` and ``public`` as well. It is however illegal
diff --git a/tests/context/context.py b/tests/context/context.py
index c09643b75..65f6f51fd 100644
--- a/tests/context/context.py
+++ b/tests/context/context.py
@@ -30,7 +30,7 @@ def context_fixture():
def test_context_create(context_fixture):
context = context_fixture['context']
assert(isinstance(context, Context))
- assert(context.arch == 'x86_64')
+ assert(context.host_arch == 'x86_64')
#######################################
diff --git a/tests/loader/arches.py b/tests/loader/arches.py
index 99602d181..bc69d5b8f 100644
--- a/tests/loader/arches.py
+++ b/tests/loader/arches.py
@@ -19,7 +19,7 @@ def test_simple_conditional_nomatch(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-conditional.bst', None, 'arm')
+ basedir, 'elements/simple-conditional.bst', None, 'arm', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -34,7 +34,7 @@ def test_simple_conditional_x86_64(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-conditional.bst', None, 'x86_64')
+ basedir, 'elements/simple-conditional.bst', None, 'x86_64', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -49,7 +49,7 @@ def test_simple_conditional_x86_32(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-conditional.bst', None, 'x86_32')
+ basedir, 'elements/simple-conditional.bst', None, 'x86_32', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -60,6 +60,58 @@ def test_simple_conditional_x86_32(datafiles):
##############################################################
+# Test Arch and Host-Arch Conditionals #
+##############################################################
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_host_arch_conditional_armv8(datafiles):
+
+ basedir = os.path.join(datafiles.dirname, datafiles.basename)
+ loader = Loader(
+ basedir, 'elements/host-arch-conditional.bst', None, 'armv8', None)
+
+ element = loader.load()
+ assert(isinstance(element, MetaElement))
+ number = element.config.get('number')
+
+ # armv8 host-arch overrides the number to 88
+ assert(number == 88)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_host_arch_conditional_ignores_target_arch(datafiles):
+
+ basedir = os.path.join(datafiles.dirname, datafiles.basename)
+ loader = Loader(
+ basedir, 'elements/host-arch-conditional.bst', None, 'armv8', 'x86_32')
+
+ element = loader.load()
+ assert(isinstance(element, MetaElement))
+ number = element.config.get('number')
+
+ # The setting a target-arch has no effect on host-arches: the number is
+ # still 88
+ assert(number == 88)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_host_arch_conditional_overridden(datafiles):
+
+ basedir = os.path.join(datafiles.dirname, datafiles.basename)
+ loader = Loader(
+ basedir, 'elements/host-arch-conditional.bst', None, 'armv8', 'x86_64')
+
+ element = loader.load()
+ assert(isinstance(element, MetaElement))
+ number = element.config.get('number')
+
+ # The 'arches' conditional follows the target architecture, and overrides
+ # anything specified in 'host-arches'.
+ assert(number == 6)
+
+
+##############################################################
# Test Arch Conditionals inside Variants #
##############################################################
@pytest.mark.datafiles(DATA_DIR)
@@ -67,7 +119,7 @@ def test_variant_arch_default(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', None, 'arm')
+ basedir, 'elements/variant-arch-conditional.bst', None, 'arm', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -82,7 +134,7 @@ def test_variant_arch_default_x86_64(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', None, 'x86_64')
+ basedir, 'elements/variant-arch-conditional.bst', None, 'x86_64', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -96,7 +148,7 @@ def test_variant_arch_default_x86_32(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', None, 'x86_32')
+ basedir, 'elements/variant-arch-conditional.bst', None, 'x86_32', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -110,7 +162,7 @@ def test_variant_arch_pink_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', 'pink', 'arm')
+ basedir, 'elements/variant-arch-conditional.bst', 'pink', 'arm', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -125,7 +177,7 @@ def test_variant_arch_pink_pony_x86_64(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', 'pink', 'x86_64')
+ basedir, 'elements/variant-arch-conditional.bst', 'pink', 'x86_64', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -139,7 +191,7 @@ def test_variant_arch_pink_pony_x86_32(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', 'pink', 'x86_32')
+ basedir, 'elements/variant-arch-conditional.bst', 'pink', 'x86_32', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -153,7 +205,7 @@ def test_variant_arch_blue_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', 'blue', 'arm')
+ basedir, 'elements/variant-arch-conditional.bst', 'blue', 'arm', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -168,7 +220,7 @@ def test_variant_arch_blue_pony_x86_64(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', 'blue', 'x86_64')
+ basedir, 'elements/variant-arch-conditional.bst', 'blue', 'x86_64', None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -182,7 +234,7 @@ def test_variant_arch_blue_pony_x86_32(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-arch-conditional.bst', 'blue', 'x86_32')
+ basedir, 'elements/variant-arch-conditional.bst', 'blue', 'x86_32', None)
element = loader.load()
assert(isinstance(element, MetaElement))
diff --git a/tests/loader/arches/elements/host-arch-conditional.bst b/tests/loader/arches/elements/host-arch-conditional.bst
new file mode 100644
index 000000000..4c9272feb
--- /dev/null
+++ b/tests/loader/arches/elements/host-arch-conditional.bst
@@ -0,0 +1,20 @@
+kind: pony
+description: |
+ An element with host-arches and arches conditionals.
+
+ The 'arches' conditional follows --target-arch if specified, while the
+ 'host-arches' conditional does not. The 'arches' conditional overrides
+ 'host-arches' if both for some reason try to override the same thing.
+config:
+ number: 5
+arches:
+ x86_64:
+ config:
+ number: 6
+host-arches:
+ x86_64:
+ config:
+ number: 66
+ armv8:
+ config:
+ number: 88
diff --git a/tests/loader/basics.py b/tests/loader/basics.py
index f706d06ec..d7f85b0fe 100644
--- a/tests/loader/basics.py
+++ b/tests/loader/basics.py
@@ -18,7 +18,7 @@ DATA_DIR = os.path.join(
def test_one_file(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/onefile.bst', None, None)
+ loader = Loader(basedir, 'elements/onefile.bst', None, None, None)
element = loader.load()
@@ -30,7 +30,7 @@ def test_one_file(datafiles):
def test_missing_file(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/missing.bst', None, None)
+ loader = Loader(basedir, 'elements/missing.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -42,7 +42,7 @@ def test_missing_file(datafiles):
def test_invalid_reference(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/badreference.bst', None, None)
+ loader = Loader(basedir, 'elements/badreference.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -54,7 +54,7 @@ def test_invalid_reference(datafiles):
def test_invalid_yaml(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/badfile.bst', None, None)
+ loader = Loader(basedir, 'elements/badfile.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -69,6 +69,6 @@ def test_fail_fullpath_target(datafiles):
fullpath = os.path.join(basedir, 'elements', 'onefile.bst')
with pytest.raises(LoadError) as exc:
- loader = Loader(basedir, fullpath, None, None)
+ loader = Loader(basedir, fullpath, None, None, None)
assert (exc.value.reason == LoadErrorReason.INVALID_DATA)
diff --git a/tests/loader/dependencies.py b/tests/loader/dependencies.py
index 8a88bcaf8..a701d4723 100644
--- a/tests/loader/dependencies.py
+++ b/tests/loader/dependencies.py
@@ -18,7 +18,7 @@ DATA_DIR = os.path.join(
def test_two_files(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/target.bst', None, None)
+ loader = Loader(basedir, 'elements/target.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -34,7 +34,7 @@ def test_two_files(datafiles):
def test_shared_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/shareddeptarget.bst', None, None)
+ loader = Loader(basedir, 'elements/shareddeptarget.bst', None, None, None)
element = loader.load()
# Toplevel is 'pony' with 2 dependencies
@@ -77,7 +77,7 @@ def test_shared_dependency(datafiles):
def test_dependency_dict(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/target-depdict.bst', None, None)
+ loader = Loader(basedir, 'elements/target-depdict.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -92,7 +92,7 @@ def test_dependency_dict(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_invalid_dependency_declaration(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/invaliddep.bst', None, None)
+ loader = Loader(basedir, 'elements/invaliddep.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -103,7 +103,7 @@ def test_invalid_dependency_declaration(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_circular_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/circulartarget.bst', None, None)
+ loader = Loader(basedir, 'elements/circulartarget.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -114,7 +114,7 @@ def test_circular_dependency(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_invalid_dependency_type(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/invaliddeptype.bst', None, None)
+ loader = Loader(basedir, 'elements/invaliddeptype.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -125,7 +125,7 @@ def test_invalid_dependency_type(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_build_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/builddep.bst', None, None)
+ loader = Loader(basedir, 'elements/builddep.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -141,7 +141,7 @@ def test_build_dependency(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_runtime_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/runtimedep.bst', None, None)
+ loader = Loader(basedir, 'elements/runtimedep.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -157,7 +157,7 @@ def test_runtime_dependency(datafiles):
@pytest.mark.datafiles(DATA_DIR)
def test_build_runtime_dependency(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/target.bst', None, None)
+ loader = Loader(basedir, 'elements/target.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
diff --git a/tests/loader/variants.py b/tests/loader/variants.py
index 0e20faf93..865ffa268 100644
--- a/tests/loader/variants.py
+++ b/tests/loader/variants.py
@@ -18,7 +18,7 @@ DATA_DIR = os.path.join(
def test_variant_not_list(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/variants-not-list.bst', None, None)
+ loader = Loader(basedir, 'elements/variants-not-list.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -30,7 +30,7 @@ def test_variant_not_list(datafiles):
def test_variant_unnamed(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/unnamed-variant.bst', None, None)
+ loader = Loader(basedir, 'elements/unnamed-variant.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -42,7 +42,7 @@ def test_variant_unnamed(datafiles):
def test_variant_bad_name(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/variant-bad-name.bst', None, None)
+ loader = Loader(basedir, 'elements/variant-bad-name.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -54,7 +54,7 @@ def test_variant_bad_name(datafiles):
def test_variant_only_one(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/only-one-variant.bst', None, None)
+ loader = Loader(basedir, 'elements/only-one-variant.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -67,7 +67,7 @@ def test_variant_illegal_composite(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/variant-illegal-composite.bst', None, None)
+ basedir, 'elements/variant-illegal-composite.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
@@ -83,7 +83,7 @@ def test_variant_simple_composite_default(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-variant-compositing.bst', None, None)
+ basedir, 'elements/simple-variant-compositing.bst', None, None, None)
element = loader.load()
@@ -100,7 +100,7 @@ def test_variant_simple_composite_pink_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-variant-compositing.bst', 'pink', None)
+ basedir, 'elements/simple-variant-compositing.bst', 'pink', None, None)
element = loader.load()
@@ -117,7 +117,7 @@ def test_variant_simple_composite_blue_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-variant-compositing.bst', 'blue', None)
+ basedir, 'elements/simple-variant-compositing.bst', 'blue', None, None)
element = loader.load()
@@ -155,7 +155,7 @@ def test_variant_simple_dependency_default(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-dependency-variants.bst', None, None)
+ basedir, 'elements/simple-dependency-variants.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -170,7 +170,7 @@ def test_variant_simple_dependency_pink_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-dependency-variants.bst', 'pink', None)
+ basedir, 'elements/simple-dependency-variants.bst', 'pink', None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -185,7 +185,7 @@ def test_variant_simple_dependency_blue_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/simple-dependency-variants.bst', 'blue', None)
+ basedir, 'elements/simple-dependency-variants.bst', 'blue', None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -200,7 +200,7 @@ def test_variant_indirect_dependency_default(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/indirect-dependency-variants.bst', None, None)
+ basedir, 'elements/indirect-dependency-variants.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -219,7 +219,7 @@ def test_variant_indirect_dependency_blue_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/indirect-dependency-variants.bst', 'blue', None)
+ basedir, 'elements/indirect-dependency-variants.bst', 'blue', None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -238,7 +238,7 @@ def test_variant_indirect_dependency_pink_pony(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
loader = Loader(
- basedir, 'elements/indirect-dependency-variants.bst', 'pink', None)
+ basedir, 'elements/indirect-dependency-variants.bst', 'pink', None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -256,7 +256,7 @@ def test_variant_indirect_dependency_pink_pony(datafiles):
def test_engine_resolve_agreement(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/tricky.bst', None, None)
+ loader = Loader(basedir, 'elements/tricky.bst', None, None, None)
element = loader.load()
assert(isinstance(element, MetaElement))
@@ -271,7 +271,7 @@ def test_engine_resolve_agreement(datafiles):
def test_engine_disagreement(datafiles):
basedir = os.path.join(datafiles.dirname, datafiles.basename)
- loader = Loader(basedir, 'elements/disagreement.bst', None, None)
+ loader = Loader(basedir, 'elements/disagreement.bst', None, None, None)
with pytest.raises(LoadError) as exc:
element = loader.load()
diff --git a/tests/sources/fixture.py b/tests/sources/fixture.py
index a9ba94e1d..c7b3a8fe6 100644
--- a/tests/sources/fixture.py
+++ b/tests/sources/fixture.py
@@ -39,7 +39,7 @@ class Setup():
if not os.path.exists(self.context.builddir):
os.mkdir(self.context.builddir)
- loader = Loader(directory, target, None, None)
+ loader = Loader(directory, target, None, None, None)
element = loader.load()
assert(len(element.sources) == 1)
self.meta_source = element.sources[0]