summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2019-01-10 13:34:56 +0000
committerJürg Billeter <j@bitron.ch>2019-01-10 13:34:56 +0000
commitf86bc760fb4b39d36b3d34dc8fbd8310cc25801d (patch)
tree32f5eeefea167e399b9e4b6297dee7812b756515
parentc8f3616d69c4ff58698532750207587936a6e78e (diff)
parent0c2a66b3b76a5d06a1ca61210ed24bf4a54e0f4a (diff)
downloadbuildstream-f86bc760fb4b39d36b3d34dc8fbd8310cc25801d.tar.gz
Merge branch 'juerg/arch' into 'master'
Accept architecture aliases See merge request BuildStream/buildstream!1034
-rw-r--r--buildstream/_options/optionarch.py31
-rw-r--r--buildstream/_platform/platform.py42
-rw-r--r--buildstream/element.py8
-rw-r--r--tests/format/option-arch-alias/element.bst8
-rw-r--r--tests/format/option-arch-alias/project.conf9
-rw-r--r--tests/format/option-arch-unknown/element.bst10
-rw-r--r--tests/format/option-arch-unknown/project.conf10
-rw-r--r--tests/format/optionarch.py44
8 files changed, 146 insertions, 16 deletions
diff --git a/buildstream/_options/optionarch.py b/buildstream/_options/optionarch.py
index 1d8509cf2..0e2963c84 100644
--- a/buildstream/_options/optionarch.py
+++ b/buildstream/_options/optionarch.py
@@ -17,6 +17,8 @@
# Authors:
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
+from .. import _yaml
+from .._exceptions import LoadError, LoadErrorReason, PlatformError
from .._platform import Platform
from .optionenum import OptionEnum
@@ -41,7 +43,34 @@ class OptionArch(OptionEnum):
super(OptionArch, self).load(node, allow_default_definition=False)
def load_default_value(self, node):
- return Platform.get_host_arch()
+ arch = Platform.get_host_arch()
+
+ default_value = None
+
+ for index, value in enumerate(self.values):
+ try:
+ canonical_value = Platform.canonicalize_arch(value)
+ if default_value is None and canonical_value == arch:
+ default_value = value
+ # Do not terminate the loop early to ensure we validate
+ # all values in the list.
+ except PlatformError as e:
+ provenance = _yaml.node_get_provenance(node, key='values', indices=[index])
+ prefix = ""
+ if provenance:
+ prefix = "{}: ".format(provenance)
+ raise LoadError(LoadErrorReason.INVALID_DATA,
+ "{}Invalid value for {} option '{}': {}"
+ .format(prefix, self.OPTION_TYPE, self.name, e))
+
+ if default_value is None:
+ # Host architecture is not supported by the project.
+ # Do not raise an error here as the user may override it.
+ # If the user does not override it, an error will be raised
+ # by resolve()/validate().
+ default_value = arch
+
+ return default_value
def resolve(self):
diff --git a/buildstream/_platform/platform.py b/buildstream/_platform/platform.py
index 42b360ff8..73ed571fe 100644
--- a/buildstream/_platform/platform.py
+++ b/buildstream/_platform/platform.py
@@ -77,20 +77,17 @@ class Platform():
def get_host_os():
return os.uname()[0]
- # get_host_arch():
+ # canonicalize_arch():
#
- # This returns the architecture of the host machine. The possible values
- # map from uname -m in order to be a OS independent list.
+ # This returns the canonical, OS-independent architecture name
+ # or raises a PlatformError if the architecture is unknown.
#
- # Returns:
- # (string): String representing the architecture
@staticmethod
- def get_host_arch():
- # get the hardware identifier from uname
- uname_machine = os.uname()[4]
- uname_to_arch = {
+ def canonicalize_arch(arch):
+ aliases = {
+ "aarch32": "aarch32",
"aarch64": "aarch64",
- "aarch64_be": "aarch64-be",
+ "aarch64-be": "aarch64-be",
"amd64": "x86-64",
"arm": "aarch32",
"armv8l": "aarch64",
@@ -99,17 +96,34 @@ class Platform():
"i486": "x86-32",
"i586": "x86-32",
"i686": "x86-32",
+ "power-isa-be": "power-isa-be",
+ "power-isa-le": "power-isa-le",
"ppc64": "power-isa-be",
"ppc64le": "power-isa-le",
"sparc": "sparc-v9",
"sparc64": "sparc-v9",
- "x86_64": "x86-64"
+ "sparc-v9": "sparc-v9",
+ "x86-32": "x86-32",
+ "x86-64": "x86-64"
}
+
try:
- return uname_to_arch[uname_machine]
+ return aliases[arch.replace('_', '-')]
except KeyError:
- raise PlatformError("uname gave unsupported machine architecture: {}"
- .format(uname_machine))
+ raise PlatformError("Unknown architecture: {}".format(arch))
+
+ # get_host_arch():
+ #
+ # This returns the architecture of the host machine. The possible values
+ # map from uname -m in order to be a OS independent list.
+ #
+ # Returns:
+ # (string): String representing the architecture
+ @staticmethod
+ def get_host_arch():
+ # get the hardware identifier from uname
+ uname_machine = os.uname()[4]
+ return Platform.canonicalize_arch(uname_machine)
##################################################################
# Sandbox functions #
diff --git a/buildstream/element.py b/buildstream/element.py
index 3bfe62275..c5fbf772c 100644
--- a/buildstream/element.py
+++ b/buildstream/element.py
@@ -2441,11 +2441,17 @@ class Element(Plugin):
# Sandbox config, unlike others, has fixed members so we should validate them
_yaml.node_validate(sandbox_config, ['build-uid', 'build-gid', 'build-os', 'build-arch'])
+ build_arch = self.node_get_member(sandbox_config, str, 'build-arch', default=None)
+ if build_arch:
+ build_arch = Platform.canonicalize_arch(build_arch)
+ else:
+ build_arch = host_arch
+
return SandboxConfig(
self.node_get_member(sandbox_config, int, 'build-uid'),
self.node_get_member(sandbox_config, int, 'build-gid'),
self.node_get_member(sandbox_config, str, 'build-os', default=host_os),
- self.node_get_member(sandbox_config, str, 'build-arch', default=host_arch))
+ build_arch)
# This makes a special exception for the split rules, which
# elements may extend but whos defaults are defined in the project.
diff --git a/tests/format/option-arch-alias/element.bst b/tests/format/option-arch-alias/element.bst
new file mode 100644
index 000000000..92ebfb134
--- /dev/null
+++ b/tests/format/option-arch-alias/element.bst
@@ -0,0 +1,8 @@
+kind: autotools
+variables:
+ result: "Nothing"
+ (?):
+ - machine_arch == "arm":
+ result: "Army"
+ - machine_arch == "x86_64":
+ result: "X86-64y"
diff --git a/tests/format/option-arch-alias/project.conf b/tests/format/option-arch-alias/project.conf
new file mode 100644
index 000000000..47f0945c9
--- /dev/null
+++ b/tests/format/option-arch-alias/project.conf
@@ -0,0 +1,9 @@
+name: test
+
+options:
+ machine_arch:
+ type: arch
+ description: The machine architecture
+ values:
+ - arm
+ - x86_64
diff --git a/tests/format/option-arch-unknown/element.bst b/tests/format/option-arch-unknown/element.bst
new file mode 100644
index 000000000..c4376715b
--- /dev/null
+++ b/tests/format/option-arch-unknown/element.bst
@@ -0,0 +1,10 @@
+kind: autotools
+variables:
+ result: "Nothing"
+ (?):
+ - machine_arch == "aarch32":
+ result: "Army"
+ - machine_arch == "aarch64":
+ result: "Aarchy"
+ - machine_arch == "x86-128":
+ result: "X86-128y"
diff --git a/tests/format/option-arch-unknown/project.conf b/tests/format/option-arch-unknown/project.conf
new file mode 100644
index 000000000..0827ec387
--- /dev/null
+++ b/tests/format/option-arch-unknown/project.conf
@@ -0,0 +1,10 @@
+name: test
+
+options:
+ machine_arch:
+ type: arch
+ description: The machine architecture
+ values:
+ - aarch32
+ - aarch64
+ - x86-128
diff --git a/tests/format/optionarch.py b/tests/format/optionarch.py
index 901b6e2da..09f9c07c9 100644
--- a/tests/format/optionarch.py
+++ b/tests/format/optionarch.py
@@ -75,3 +75,47 @@ def test_unsupported_arch(cli, datafiles):
])
result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_alias(cli, datafiles):
+
+ with override_uname_arch("arm"):
+ project = os.path.join(datafiles.dirname, datafiles.basename, 'option-arch-alias')
+ result = cli.run(project=project, silent=True, args=[
+ 'show',
+ '--deps', 'none',
+ '--format', '%{vars}',
+ 'element.bst'
+ ])
+
+ result.assert_success()
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_unknown_host_arch(cli, datafiles):
+
+ with override_uname_arch("x86_128"):
+ project = os.path.join(datafiles.dirname, datafiles.basename, 'option-arch')
+ result = cli.run(project=project, silent=True, args=[
+ 'show',
+ '--deps', 'none',
+ '--format', '%{vars}',
+ 'element.bst'
+ ])
+
+ result.assert_main_error(ErrorDomain.PLATFORM, None)
+
+
+@pytest.mark.datafiles(DATA_DIR)
+def test_unknown_project_arch(cli, datafiles):
+
+ project = os.path.join(datafiles.dirname, datafiles.basename, 'option-arch-unknown')
+ result = cli.run(project=project, silent=True, args=[
+ 'show',
+ '--deps', 'none',
+ '--format', '%{vars}',
+ 'element.bst'
+ ])
+
+ result.assert_main_error(ErrorDomain.LOAD, LoadErrorReason.INVALID_DATA)