Support cross-compiling GN for other targets
This change extends the recipe used by builders with support for
cross-compiling GN to different platforms beyond the host one, and
sets up cross compilation for Linux as an example.
Change-Id: I0d9aa1a104b14842c875d1a8d9082b6949e47e14
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/3760
Reviewed-by: Scott Graham <scottmg@chromium.org>
Reviewed-by: Dirk Pranke <dpranke@google.com>
Commit-Queue: Petr Hosek <phosek@google.com>
diff --git a/infra/recipe_modules/target/__init__.py b/infra/recipe_modules/target/__init__.py
new file mode 100644
index 0000000..1239fd2
--- /dev/null
+++ b/infra/recipe_modules/target/__init__.py
@@ -0,0 +1,7 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+DEPS = [
+ 'recipe_engine/platform',
+]
diff --git a/infra/recipe_modules/target/api.py b/infra/recipe_modules/target/api.py
new file mode 100644
index 0000000..f128707
--- /dev/null
+++ b/infra/recipe_modules/target/api.py
@@ -0,0 +1,98 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from recipe_engine import recipe_api
+
+
+PLATFORM_TO_TRIPLE = {
+ 'fuchsia-amd64': 'x86_64-fuchsia',
+ 'fuchsia-arm64': 'aarch64-fuchsia',
+ 'linux-amd64': 'x86_64-linux-gnu',
+ 'linux-arm64': 'aarch64-linux-gnu',
+ 'mac-amd64': 'x86_64-apple-darwin',
+ 'mac-arm64': 'aarch64-apple-darwin',
+}
+PLATFORMS = PLATFORM_TO_TRIPLE.keys()
+
+
+class Target(object):
+
+ def __init__(self, api, os, arch):
+ self.m = api
+ self._os = os
+ self._arch = arch
+
+ @property
+ def is_win(self):
+ """Returns True iff the target platform is Windows."""
+ return self.os == 'windows'
+
+ @property
+ def is_mac(self):
+ """Returns True iff the target platform is macOS."""
+ return self.os == 'mac'
+
+ @property
+ def is_linux(self):
+ """Returns True iff the target platform is Linux."""
+ return self.os == 'linux'
+
+ @property
+ def is_host(self):
+ """Returns True iff the target platform is host."""
+ return self == self.m.host
+
+ @property
+ def os(self):
+ """Returns the target os name which will be in:
+ * windows
+ * mac
+ * linux
+ """
+ return self._os
+
+ @property
+ def arch(self):
+ """Returns the current CPU architecture."""
+ return self._arch
+
+ @property
+ def platform(self):
+ """Returns the target platform in the <os>-<arch> format."""
+ return '%s-%s' % (self.os, self.arch)
+
+ @property
+ def triple(self):
+ """Returns the target triple."""
+ return PLATFORM_TO_TRIPLE[self.platform]
+
+ def __str__(self):
+ return self.platform
+
+ def __eq__(self, other):
+ if isinstance(other, Target):
+ return self._os == other._os and self._arch == other._arch
+ return False
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+
+class TargetApi(recipe_api.RecipeApi):
+
+ def __call__(self, platform):
+ return Target(self, *platform.split('-', 2))
+
+ @property
+ def host(self):
+ return Target(self, self.m.platform.name.replace('win', 'windows'), {
+ 'intel': {
+ 32: '386',
+ 64: 'amd64',
+ },
+ 'arm': {
+ 32: 'armv6',
+ 64: 'arm64',
+ },
+ }[self.m.platform.arch][self.m.platform.bits])
diff --git a/infra/recipe_modules/target/examples/full.expected/linux.json b/infra/recipe_modules/target/examples/full.expected/linux.json
new file mode 100644
index 0000000..947f5d2
--- /dev/null
+++ b/infra/recipe_modules/target/examples/full.expected/linux.json
@@ -0,0 +1,22 @@
+[
+ {
+ "cmd": [],
+ "name": "platform things",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@name@fuchsia@@@",
+ "@@@STEP_LOG_END@name@@@",
+ "@@@STEP_LOG_LINE@arch@arm64@@@",
+ "@@@STEP_LOG_END@arch@@@",
+ "@@@STEP_LOG_LINE@platform@fuchsia-arm64@@@",
+ "@@@STEP_LOG_END@platform@@@",
+ "@@@STEP_LOG_LINE@triple@aarch64-fuchsia@@@",
+ "@@@STEP_LOG_END@triple@@@",
+ "@@@STEP_LOG_LINE@string@fuchsia-arm64@@@",
+ "@@@STEP_LOG_END@string@@@"
+ ]
+ },
+ {
+ "jsonResult": null,
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/infra/recipe_modules/target/examples/full.expected/mac.json b/infra/recipe_modules/target/examples/full.expected/mac.json
new file mode 100644
index 0000000..947f5d2
--- /dev/null
+++ b/infra/recipe_modules/target/examples/full.expected/mac.json
@@ -0,0 +1,22 @@
+[
+ {
+ "cmd": [],
+ "name": "platform things",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@name@fuchsia@@@",
+ "@@@STEP_LOG_END@name@@@",
+ "@@@STEP_LOG_LINE@arch@arm64@@@",
+ "@@@STEP_LOG_END@arch@@@",
+ "@@@STEP_LOG_LINE@platform@fuchsia-arm64@@@",
+ "@@@STEP_LOG_END@platform@@@",
+ "@@@STEP_LOG_LINE@triple@aarch64-fuchsia@@@",
+ "@@@STEP_LOG_END@triple@@@",
+ "@@@STEP_LOG_LINE@string@fuchsia-arm64@@@",
+ "@@@STEP_LOG_END@string@@@"
+ ]
+ },
+ {
+ "jsonResult": null,
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/infra/recipe_modules/target/examples/full.expected/win.json b/infra/recipe_modules/target/examples/full.expected/win.json
new file mode 100644
index 0000000..947f5d2
--- /dev/null
+++ b/infra/recipe_modules/target/examples/full.expected/win.json
@@ -0,0 +1,22 @@
+[
+ {
+ "cmd": [],
+ "name": "platform things",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@name@fuchsia@@@",
+ "@@@STEP_LOG_END@name@@@",
+ "@@@STEP_LOG_LINE@arch@arm64@@@",
+ "@@@STEP_LOG_END@arch@@@",
+ "@@@STEP_LOG_LINE@platform@fuchsia-arm64@@@",
+ "@@@STEP_LOG_END@platform@@@",
+ "@@@STEP_LOG_LINE@triple@aarch64-fuchsia@@@",
+ "@@@STEP_LOG_END@triple@@@",
+ "@@@STEP_LOG_LINE@string@fuchsia-arm64@@@",
+ "@@@STEP_LOG_END@string@@@"
+ ]
+ },
+ {
+ "jsonResult": null,
+ "name": "$result"
+ }
+]
\ No newline at end of file
diff --git a/infra/recipe_modules/target/examples/full.py b/infra/recipe_modules/target/examples/full.py
new file mode 100644
index 0000000..c47c86a
--- /dev/null
+++ b/infra/recipe_modules/target/examples/full.py
@@ -0,0 +1,31 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+DEPS = [
+ 'target',
+ 'recipe_engine/platform',
+ 'recipe_engine/properties',
+ 'recipe_engine/step',
+]
+
+
+def RunSteps(api):
+ target = api.target('fuchsia-arm64')
+ assert not target.is_win
+ assert not target.is_linux
+ assert not target.is_mac
+ assert api.target.host.is_host
+ assert target != api.target.host
+ assert target != 'foo'
+ step_result = api.step('platform things', cmd=None)
+ step_result.presentation.logs['name'] = [target.os]
+ step_result.presentation.logs['arch'] = [target.arch]
+ step_result.presentation.logs['platform'] = [target.platform]
+ step_result.presentation.logs['triple'] = [target.triple]
+ step_result.presentation.logs['string'] = [str(target)]
+
+
+def GenTests(api):
+ for platform in ('linux', 'mac', 'win'):
+ yield api.test(platform) + api.platform.name(platform)