Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • willsalmon/buildstream
  • CumHoleZH/buildstream
  • tchaik/buildstream
  • DCotyPortfolio/buildstream
  • jesusoctavioas/buildstream
  • patrickmmartin/buildstream
  • franred/buildstream
  • tintou/buildstream
  • alatiera/buildstream
  • martinblanchard/buildstream
  • neverdie22042524/buildstream
  • Mattlk13/buildstream
  • PServers/buildstream
  • phamnghia610909/buildstream
  • chiaratolentino/buildstream
  • eysz7-x-x/buildstream
  • kerrick1/buildstream
  • matthew-yates/buildstream
  • twofeathers/buildstream
  • mhadjimichael/buildstream
  • pointswaves/buildstream
  • Mr.JackWilson/buildstream
  • Tw3akG33k/buildstream
  • AlexFazakas/buildstream
  • eruidfkiy/buildstream
  • clamotion2/buildstream
  • nanonyme/buildstream
  • wickyjaaa/buildstream
  • nmanchev/buildstream
  • bojorquez.ja/buildstream
  • mostynb/buildstream
  • highpit74/buildstream
  • Demo112/buildstream
  • ba2014sheer/buildstream
  • tonimadrino/buildstream
  • usuario2o/buildstream
  • Angelika123456/buildstream
  • neo355/buildstream
  • corentin-ferlay/buildstream
  • coldtom/buildstream
  • wifitvbox81/buildstream
  • 358253885/buildstream
  • seanborg/buildstream
  • SotK/buildstream
  • DouglasWinship/buildstream
  • karansthr97/buildstream
  • louib/buildstream
  • bwh-ct/buildstream
  • robjh/buildstream
  • we88c0de/buildstream
  • zhengxian5555/buildstream
51 results
Show changes
Commits on Source (12)
Showing
with 253 additions and 125 deletions
......@@ -2,6 +2,12 @@
buildstream 1.3.1
=================
o `bst shell` learned to accept multiple elements for staging
provided the element's kind flags `BST_STAGE_INTEGRATES` as false.
As a side-effect it is no longer possible to intersperse options and flags
with arguments in the `bst shell` command-line.
o All elements must now be suffixed with `.bst`
Attempting to use an element that does not have the `.bst` extension,
will result in a warning.
......
......@@ -599,7 +599,7 @@ class App():
click.echo("\nDropping into an interactive shell in the failed build sandbox\n", err=True)
try:
prompt = self.shell_prompt(element)
self.stream.shell(element, Scope.BUILD, prompt, isolate=True)
self.stream.shell([(element, Scope.BUILD)], prompt, isolate=True)
except BstError as e:
click.echo("Error while attempting to create interactive shell: {}".format(e), err=True)
elif choice == 'log':
......
......@@ -573,7 +573,7 @@ def show(app, elements, deps, except_, order, format_):
##################################################################
@cli.command(short_help="Shell into an element's sandbox environment")
@click.option('--build', '-b', 'build_', is_flag=True, default=False,
help='Stage dependencies and sources to build')
help='Stage dependencies and sources to build the first element')
@click.option('--sysroot', '-s', default=None,
type=click.Path(exists=True, file_okay=False, readable=True),
help="An existing sysroot")
......@@ -582,11 +582,11 @@ def show(app, elements, deps, except_, order, format_):
help="Mount a file or directory into the sandbox")
@click.option('--isolate', is_flag=True, default=False,
help='Create an isolated build sandbox')
@click.argument('element',
type=click.Path(readable=False))
@click.argument('command', type=click.STRING, nargs=-1)
@click.argument('elements',
type=click.Path(readable=False), nargs=-1,
metavar="[ELEMENT]... [--] [COMMAND]...")
@click.pass_obj
def shell(app, element, sysroot, mount, isolate, build_, command):
def shell(app, elements, sysroot, mount, isolate, build_):
"""Run a command in the target element's sandbox environment
This will stage a temporary sysroot for running the target
......@@ -600,6 +600,15 @@ def shell(app, element, sysroot, mount, isolate, build_, command):
directory or with a checkout of the given target, in order
to use a specific sysroot.
Multiple element target names ending in .bst may be provided,
optionally followed by the command to run in the shell.
The first argument that doesn't end in .bst is assumed to be the beginning of COMMAND.
A -- argument may be used to disambiguate between element target names and command arguments
and should be used when being driven as part of a script, to prevent mis-parsing,
in addition to a -- before the element list.
If no COMMAND is specified, the default is to attempt
to run an interactive shell.
"""
......@@ -607,13 +616,22 @@ def shell(app, element, sysroot, mount, isolate, build_, command):
from .._project import HostMount
from .._pipeline import PipelineSelection
if build_:
scope = Scope.BUILD
else:
scope = Scope.RUN
targets = []
command = []
for i, arg in enumerate(elements):
if arg == '--':
command = elements[i + 1:]
break
if not arg.endswith('.bst'):
command = elements[i:]
break
targets.append(arg)
if not targets:
raise AppError('No elements specified to open a shell in')
with app.initialized():
dependencies = app.stream.load_selection((element,), selection=PipelineSelection.NONE)
dependencies = app.stream.load_selection(targets, selection=PipelineSelection.NONE)
element = dependencies[0]
prompt = app.shell_prompt(element)
mounts = [
......@@ -621,7 +639,9 @@ def shell(app, element, sysroot, mount, isolate, build_, command):
for host_path, path in mount
]
try:
exitcode = app.stream.shell(element, scope, prompt,
elements = tuple((e, Scope.BUILD if i == 0 and build_ else Scope.RUN)
for (i, e) in enumerate(dependencies))
exitcode = app.stream.shell(elements, prompt,
directory=sysroot,
mounts=mounts,
isolate=isolate,
......
......@@ -25,15 +25,17 @@ import stat
import shlex
import shutil
import tarfile
from contextlib import contextmanager
from contextlib import contextmanager, ExitStack
from tempfile import TemporaryDirectory
from ._exceptions import StreamError, ImplError, BstError, set_last_task_error
from ._message import Message, MessageType
from ._scheduler import Scheduler, SchedStatus, TrackQueue, FetchQueue, BuildQueue, PullQueue, PushQueue
from ._pipeline import Pipeline, PipelineSelection
from ._platform import Platform
from .sandbox._config import SandboxConfig
from ._scheduler import Scheduler, SchedStatus, TrackQueue, FetchQueue, BuildQueue, PullQueue, PushQueue
from . import utils, _yaml, _site
from . import Scope, Consistency
from . import SandboxFlags, Scope, Consistency
# Stream()
......@@ -117,8 +119,7 @@ class Stream():
# Run a shell
#
# Args:
# element (Element): An Element object to run the shell for
# scope (Scope): The scope for the shell (Scope.BUILD or Scope.RUN)
# elements (List of (Element, Scope) tuples): Elements to run the shell for and their dependency scopes.
# prompt (str): The prompt to display in the shell
# directory (str): A directory where an existing prestaged sysroot is expected, or None
# mounts (list of HostMount): Additional directories to mount into the sandbox
......@@ -128,7 +129,7 @@ class Stream():
# Returns:
# (int): The exit code of the launched shell
#
def shell(self, element, scope, prompt, *,
def shell(self, elements, prompt, *,
directory=None,
mounts=None,
isolate=False,
......@@ -138,16 +139,118 @@ class Stream():
# in which case we just blindly trust the directory, using the element
# definitions to control the execution environment only.
if directory is None:
missing_deps = [
dep._get_full_name()
for dep in self._pipeline.dependencies([element], scope)
if not dep._cached()
]
missing_deps = []
for element, scope in elements:
missing_deps.extend(
dep._get_full_name()
for dep in self._pipeline.dependencies((element,), scope)
if not dep._cached())
if missing_deps:
raise StreamError("Elements need to be built or downloaded before staging a shell environment",
detail="\n".join(missing_deps))
return element._shell(scope, directory, mounts=mounts, isolate=isolate, prompt=prompt, command=command)
# Assert we're not mixing virtual directory compatible
# and non-virtual directory compatible elements
if (any(e.BST_VIRTUAL_DIRECTORY for (e, _) in elements) and
not all(e.BST_VIRTUAL_DIRECTORY for (e, _) in elements)):
raise StreamError(
"Elements do not support multiple-element staging",
detail=("Multi-element staging is not supported" +
" because elements {} support BST_VIRTUAL_DIRECTORY and {} do not.").format(
', '.join(e.name for (e, _) in elements if e.BST_VIRTUAL_DIRECTORY),
', '.join(e.name for (e, _) in elements if not e.BST_VIRTUAL_DIRECTORY)))
with ExitStack() as stack:
# Creation logic duplicated from Element.__sandbox
# since most of it is creating the tmpdir
# and deciding whether to make a remote sandbox,
# which we don't want to.
if directory is None:
os.makedirs(self._context.builddir, exist_ok=True)
rootdir = stack.enter_context(TemporaryDirectory(dir=self._context.builddir))
else:
rootdir = directory
# SandboxConfig comes from project, element defaults and MetaElement sandbox config
# In the absence of it being exposed to other APIs and a merging strategy
# just make it from the project sandbox config.
sandbox_config = SandboxConfig(_yaml.node_get(self._project._sandbox, int, 'build-uid'),
_yaml.node_get(self._project._sandbox, int, 'build-gid'))
platform = Platform.get_platform()
sandbox = platform.create_sandbox(context=self._context,
project=self._project,
directory=rootdir,
stdout=None, stderr=None, config=sandbox_config,
bare_directory=directory is not None,
allow_real_directory=not any(e.BST_VIRTUAL_DIRECTORY
for (e, _) in elements))
# Configure the sandbox with the last element taking precedence for config.
for e, _ in elements:
e.configure_sandbox(sandbox)
# Stage contents if not passed --sysroot
if not directory:
if any(e.BST_STAGE_INTEGRATES for (e, _) in elements):
if len(elements) > 1:
raise StreamError(
"Elements do not support multiple-element staging",
detail=("Elements {} do not support multi-element staging " +
" because element kinds {} set BST_STAGE_INTEGRATES").format(
', '.join(e.name for (e, _) in elements if e.BST_STAGE_INTEGRATES),
', '.join(set(e.get_kind() for (e, _) in elements))))
elements[0][0].stage(sandbox)
else:
visited = {}
for e, scope in elements:
if scope is Scope.BUILD:
e.stage(sandbox, visited=visited)
else:
e.stage_dependency_artifacts(sandbox, scope, visited=visited)
visited = {}
for e, scope in elements:
e.integrate_dependency_artifacts(sandbox, scope, visited=visited)
environment = {}
for e, _ in elements:
environment.update(e.get_environment())
flags = SandboxFlags.INTERACTIVE | SandboxFlags.ROOT_READ_ONLY
shell_command, shell_environment, shell_host_files = self._project.get_shell_config()
environment['PS1'] = prompt
# Special configurations for non-isolated sandboxes
if not isolate:
# Open the network, and reuse calling uid/gid
#
flags |= SandboxFlags.NETWORK_ENABLED | SandboxFlags.INHERIT_UID
# Apply project defined environment vars to set for a shell
for key, value in _yaml.node_items(shell_environment):
environment[key] = value
# Setup any requested bind mounts
if mounts is None:
mounts = []
for mount in shell_host_files + mounts:
if not os.path.exists(mount.host_path):
if not mount.optional:
self._message(MessageType.WARN,
"Not mounting non-existing host file: {}".format(mount.host_path))
else:
sandbox.mark_directory(mount.path)
sandbox._set_mount_source(mount.path, mount.host_path)
if command:
argv = list(command)
else:
argv = shell_command
self._message(MessageType.STATUS, "Running command", detail=" ".join(argv))
# Run shells with network enabled and readonly root.
return sandbox.run(argv, flags, env=environment)
# build()
#
......
......@@ -211,17 +211,18 @@ class BuildElement(Element):
self.batch_prepare_assemble(SandboxFlags.ROOT_READ_ONLY,
collect=self.get_variable('install-root'))
def stage(self, sandbox):
def stage(self, sandbox, *, visited=None):
assert not self.BST_STAGE_INTEGRATES or visited is None
# Stage deps in the sandbox root
with self.timed_activity("Staging dependencies", silent_nested=True):
self.stage_dependency_artifacts(sandbox, Scope.BUILD)
self.stage_dependency_artifacts(sandbox, Scope.BUILD, visited=visited)
# Run any integration commands provided by the dependencies
# once they are all staged and ready
with sandbox.batch(SandboxFlags.NONE, label="Integrating sandbox"):
for dep in self.dependencies(Scope.BUILD):
dep.integrate(sandbox)
if self.BST_STAGE_INTEGRATES:
# Run any integration commands provided by the dependencies
# once they are all staged and ready
with self.timed_activity("Integrating sandbox"):
self.integrate_dependency_artifacts(sandbox, Scope.BUILD)
# Stage sources in the build root
self.stage_sources(sandbox, self.get_variable('build-root'))
......
......@@ -47,7 +47,7 @@ cache:
scheduler:
# Maximum number of simultaneous downloading tasks.
fetchers: 10
fetchers: 1
# Maximum number of simultaneous build tasks.
builders: 4
......
......@@ -75,7 +75,6 @@ Class Reference
import os
import re
import stat
import copy
from collections import OrderedDict
from collections.abc import Mapping
import contextlib
......@@ -176,6 +175,15 @@ class Element(Plugin):
*Since: 1.4*
"""
BST_STAGE_INTEGRATES = True
"""If True, Element.stage() is expected to run integration commands for its dependencies.
If False, Element.integrate_dependency_artifacts() is called after Element.stage().
If True then multi-element sandboxes can't include this element.
*Since: 1.4*
"""
def __init__(self, context, project, meta, plugin_conf):
self.__cache_key_dict = None # Dict for cache key calculation
......@@ -291,11 +299,12 @@ class Element(Plugin):
raise ImplError("element plugin '{kind}' does not implement configure_sandbox()".format(
kind=self.get_kind()))
def stage(self, sandbox):
def stage(self, sandbox, *, visited=None):
"""Stage inputs into the sandbox directories
Args:
sandbox (:class:`.Sandbox`): The build sandbox
visited (dict or None): Skip Elements included here and add any traversed
Raises:
(:class:`.ElementError`): When the element raises an error
......@@ -304,10 +313,42 @@ class Element(Plugin):
directory with data. This is done either by staging :class:`.Source`
objects, by staging the artifacts of the elements this element depends
on, or both.
The visited parameter does not need to be declared unless BST_STAGE_INTEGRATES is set to False.
If BST_STAGE_INTEGRATES is False then visited should be passed to calls to dependencies().
"""
raise ImplError("element plugin '{kind}' does not implement stage()".format(
kind=self.get_kind()))
def integrate_dependency_artifacts(self, sandbox, scope, *, visited=None):
"""Integrate element dependencies in scope
Args:
sandbox (:class:`.Sandbox`): The build sandbox
scope (:class:`.Scope`): The scope to stage dependencies in
visited (dict or None): Skip Elements included here and add any traversed
This is primarily a convenience wrapper around
:func:`Element.integrate() <buildstream.element.Element.stage_artifact>`
which takes care of integrating all the dependencies in `scope`.
This defaults to just calling integrate() on every dependency.
If an Element needs to defer, reorder or change the selection of which Elements
should have their integration commands run, then this should be overridden.
This method is not guaranteed to be called when BST_STAGE_INTEGRATES is True
when staging this Element in a build scope,
but implementations of `stage()` may opt to call it in these circumstances.
*Since: 1.4*
"""
if visited is None:
visited = {}
with sandbox.batch(SandboxFlags.NONE, label="Integrating sandbox"):
for dep in self.dependencies(scope, visited=visited):
dep.integrate(sandbox)
def prepare(self, sandbox):
"""Run one-off preparation commands.
......@@ -656,7 +697,7 @@ class Element(Plugin):
return link_result.combine(copy_result)
def stage_dependency_artifacts(self, sandbox, scope, *, path=None,
include=None, exclude=None, orphans=True):
include=None, exclude=None, orphans=True, visited=None):
"""Stage element dependencies in scope
This is primarily a convenience wrapper around
......@@ -671,6 +712,7 @@ class Element(Plugin):
include (list): An optional list of domains to include files from
exclude (list): An optional list of domains to exclude files from
orphans (bool): Whether to include files not spoken for by split domains
visited (dict or None): Skip Elements included here and add any traversed
Raises:
(:class:`.ElementError`): If any of the dependencies in `scope` have not
......@@ -686,7 +728,7 @@ class Element(Plugin):
if self.__can_build_incrementally() and workspace.last_successful:
old_dep_keys = self.__get_artifact_metadata_dependencies(workspace.last_successful)
for dep in self.dependencies(scope):
for dep in self.dependencies(scope, visited=visited):
# If we are workspaced, and we therefore perform an
# incremental build, we must ensure that we update the mtimes
# of any files created by our dependencies since the last
......@@ -1339,7 +1381,7 @@ class Element(Plugin):
# is used to stage things by the `bst checkout` codepath
#
@contextmanager
def _prepare_sandbox(self, scope, directory, shell=False, integrate=True):
def _prepare_sandbox(self, scope, directory, integrate=True):
# bst shell and bst checkout require a local sandbox.
bare_directory = True if directory else False
with self.__sandbox(directory, config=self.__sandbox_config, allow_remote=False,
......@@ -1350,19 +1392,15 @@ class Element(Plugin):
# Stage something if we need it
if not directory:
if shell and scope == Scope.BUILD:
self.stage(sandbox)
else:
# Stage deps in the sandbox root
with self.timed_activity("Staging dependencies", silent_nested=True):
self.stage_dependency_artifacts(sandbox, scope)
# Stage deps in the sandbox root
with self.timed_activity("Staging dependencies", silent_nested=True):
self.stage_dependency_artifacts(sandbox, scope)
# Run any integration commands provided by the dependencies
# once they are all staged and ready
if integrate:
with self.timed_activity("Integrating sandbox"):
for dep in self.dependencies(scope):
dep.integrate(sandbox)
# Run any integration commands provided by the dependencies
# once they are all staged and ready
if integrate:
with self.timed_activity("Integrating sandbox"):
self.integrate_dependency_artifacts(sandbox, scope)
yield sandbox
......@@ -1581,6 +1619,8 @@ class Element(Plugin):
self.__configure_sandbox(sandbox)
# Step 2 - Stage
self.stage(sandbox)
if not self.BST_STAGE_INTEGRATES:
self.integrate_dependency_artifacts(sandbox, Scope.BUILD)
if self.__batch_prepare_assemble:
cm = sandbox.batch(self.__batch_prepare_assemble_flags,
......@@ -1839,71 +1879,6 @@ class Element(Plugin):
# Notify successful upload
return True
# _shell():
#
# Connects the terminal with a shell running in a staged
# environment
#
# Args:
# scope (Scope): Either BUILD or RUN scopes are valid, or None
# directory (str): A directory to an existing sandbox, or None
# mounts (list): A list of (str, str) tuples, representing host/target paths to mount
# isolate (bool): Whether to isolate the environment like we do in builds
# prompt (str): A suitable prompt string for PS1
# command (list): An argv to launch in the sandbox
#
# Returns: Exit code
#
# If directory is not specified, one will be staged using scope
def _shell(self, scope=None, directory=None, *, mounts=None, isolate=False, prompt=None, command=None):
with self._prepare_sandbox(scope, directory, shell=True) as sandbox:
environment = self.get_environment()
environment = copy.copy(environment)
flags = SandboxFlags.INTERACTIVE | SandboxFlags.ROOT_READ_ONLY
# Fetch the main toplevel project, in case this is a junctioned
# subproject, we want to use the rules defined by the main one.
context = self._get_context()
project = context.get_toplevel_project()
shell_command, shell_environment, shell_host_files = project.get_shell_config()
if prompt is not None:
environment['PS1'] = prompt
# Special configurations for non-isolated sandboxes
if not isolate:
# Open the network, and reuse calling uid/gid
#
flags |= SandboxFlags.NETWORK_ENABLED | SandboxFlags.INHERIT_UID
# Apply project defined environment vars to set for a shell
for key, value in _yaml.node_items(shell_environment):
environment[key] = value
# Setup any requested bind mounts
if mounts is None:
mounts = []
for mount in shell_host_files + mounts:
if not os.path.exists(mount.host_path):
if not mount.optional:
self.warn("Not mounting non-existing host file: {}".format(mount.host_path))
else:
sandbox.mark_directory(mount.path)
sandbox._set_mount_source(mount.path, mount.host_path)
if command:
argv = [arg for arg in command]
else:
argv = shell_command
self.status("Running command", detail=" ".join(argv))
# Run shells with network enabled and readonly root.
return sandbox.run(argv, flags, env=environment)
# _open_workspace():
#
# "Open" a workspace for this element
......
......@@ -62,6 +62,8 @@ from buildstream import BuildElement
class AutotoolsElement(BuildElement):
# Supports virtual directories (required for remote execution)
BST_VIRTUAL_DIRECTORY = True
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -61,6 +61,8 @@ from buildstream import BuildElement
class CMakeElement(BuildElement):
# Supports virtual directories (required for remote execution)
BST_VIRTUAL_DIRECTORY = True
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -58,6 +58,9 @@ class ComposeElement(Element):
# This plugin has been modified to avoid the use of Sandbox.get_directory
BST_VIRTUAL_DIRECTORY = True
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
def configure(self, node):
self.node_validate(node, [
'integrate', 'include', 'exclude', 'include-orphans'
......@@ -86,7 +89,10 @@ class ComposeElement(Element):
def configure_sandbox(self, sandbox):
pass
def stage(self, sandbox):
def stage(self, sandbox, *, visited=None):
pass
def integrate_dependency_artifacts(self, sandbox, scope, *, visited=None):
pass
def assemble(self, sandbox):
......@@ -122,9 +128,7 @@ class ComposeElement(Element):
snapshot = set(vbasedir.list_relative_paths())
vbasedir.mark_unmodified()
with sandbox.batch(0):
for dep in self.dependencies(Scope.BUILD):
dep.integrate(sandbox)
super().integrate_dependency_artifacts(sandbox, Scope.BUILD)
if require_split:
# Calculate added, modified and removed files
......
......@@ -36,7 +36,8 @@ from buildstream import BuildElement
# Element implementation for the python 'distutils' kind.
class DistutilsElement(BuildElement):
pass
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -97,7 +97,7 @@ class FilterElement(Element):
def configure_sandbox(self, sandbox):
pass
def stage(self, sandbox):
def stage(self, sandbox, *, visited=None):
pass
def assemble(self, sandbox):
......
......@@ -43,6 +43,8 @@ class ImportElement(BuildElement):
# This plugin has been modified to avoid the use of Sandbox.get_directory
BST_VIRTUAL_DIRECTORY = True
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
def configure(self, node):
self.source = self.node_subst_member(node, 'source')
......@@ -64,7 +66,10 @@ class ImportElement(BuildElement):
def configure_sandbox(self, sandbox):
pass
def stage(self, sandbox):
def stage(self, sandbox, *, visited=None):
pass
def integrate_dependency_artifacts(self, sandbox, scope, *, visited=None):
pass
def assemble(self, sandbox):
......
......@@ -152,7 +152,7 @@ class JunctionElement(Element):
def configure_sandbox(self, sandbox):
raise PipelineError("Cannot build junction elements")
def stage(self, sandbox):
def stage(self, sandbox, *, visited=None):
raise PipelineError("Cannot stage junction elements")
def generate_script(self):
......
......@@ -43,6 +43,8 @@ from buildstream import BuildElement
class MakeElement(BuildElement):
# Supports virtual directories (required for remote execution)
BST_VIRTUAL_DIRECTORY = True
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -36,7 +36,8 @@ from buildstream import BuildElement
# Element implementation for the 'makemaker' kind.
class MakeMakerElement(BuildElement):
pass
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -38,6 +38,8 @@ from buildstream import BuildElement
class ManualElement(BuildElement):
# Supports virtual directories (required for remote execution)
BST_VIRTUAL_DIRECTORY = True
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -58,6 +58,8 @@ from buildstream import BuildElement
class MesonElement(BuildElement):
# Supports virtual directories (required for remote execution)
BST_VIRTUAL_DIRECTORY = True
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -36,7 +36,8 @@ from buildstream import BuildElement
# Element implementation for the 'modulebuild' kind.
class ModuleBuildElement(BuildElement):
pass
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......
......@@ -36,7 +36,8 @@ from buildstream import BuildElement
# Element implementation for the 'pip' kind.
class PipElement(BuildElement):
pass
# This plugin has been modified to permit calling integration after staging
BST_STAGE_INTEGRATES = False
# Plugin entry point
......