From 4afa2e26828abf484f8d8e8355bc8eb1a30db2ae Mon Sep 17 00:00:00 2001 From: Jiyong Park Date: Mon, 13 Jul 2020 15:43:45 +0900 Subject: [PATCH] LinuxBionic supports arm64 LinuxBionic now supports arm64 architecture in addition to the existing x86_64 arch. This is to make it possible to build host tools like adb, fastboot, crosvm, etc. for Linux/ARM on regular Linux/x86 machines. The arm64 target can be selected in various ways in Android.bp files: - target.host (because this is still considered as a host target) - target.linux (provided that the module is also enabled for host) - target.linux_bionic (use the OS name directly) - target.linux_bionic_arm64 (OS name + arch combo) - target.linux_arm64 (provided that the module is also for host) - target.not_windows - arch.arm64 The toolchain for the new target is almost the same as the toolchain config for Android/ARM64. One notable difference is that the clang triple is aarch64-linux instead of aarch64-linux-android, so that __ANDROID__ is not defined for the new OS type. Bug: 134795810 Test: HOST_CROSS_OS=linux_bionic HOST_CROSS_ARCH=arm64 m nothing Change-Id: If4300583edfb6d75bd4d984b38f73b6a406b4447 --- android/arch.go | 2 +- cc/config/Android.bp | 2 + cc/config/arm64_linux_host.go | 94 +++++++++++++++++++++++++++++++++ rust/config/Android.bp | 1 + rust/config/arm64_device.go | 9 +++- rust/config/arm64_linux_host.go | 24 +++++++++ 6 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 cc/config/arm64_linux_host.go create mode 100644 rust/config/arm64_linux_host.go diff --git a/android/arch.go b/android/arch.go index 66edf7eae..aeaa9bbd7 100644 --- a/android/arch.go +++ b/android/arch.go @@ -578,7 +578,7 @@ var ( osArchTypeMap = map[OsType][]ArchType{ Linux: []ArchType{X86, X86_64}, - LinuxBionic: []ArchType{X86_64}, + LinuxBionic: []ArchType{Arm64, X86_64}, Darwin: []ArchType{X86_64}, Windows: []ArchType{X86, X86_64}, Android: []ArchType{Arm, Arm64, X86, X86_64}, diff --git a/cc/config/Android.bp b/cc/config/Android.bp index 6275064f5..ce4bdfb50 100644 --- a/cc/config/Android.bp +++ b/cc/config/Android.bp @@ -23,6 +23,8 @@ bootstrap_go_package { "x86_linux_host.go", "x86_linux_bionic_host.go", "x86_windows_host.go", + + "arm64_linux_host.go", ], testSrcs: [ "tidy_test.go", diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go new file mode 100644 index 000000000..74642c2cf --- /dev/null +++ b/cc/config/arm64_linux_host.go @@ -0,0 +1,94 @@ +// Copyright 2020 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "android/soong/android" + "strings" +) + +var ( + // This is a host toolchain but flags for device toolchain are required + // as the flags are actually for Bionic-based builds. + linuxCrossCflags = ClangFilterUnknownCflags(append(deviceGlobalCflags, + // clang by default enables PIC when the clang triple is set to *-android. + // See toolchain/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp#920. + // However, for this host target, we don't set "-android" to avoid __ANDROID__ macro + // which stands for "Android device target". Keeping PIC on is required because + // many modules we have (e.g. Bionic) assume PIC. + "-fpic", + )) + + linuxCrossLdflags = ClangFilterUnknownCflags([]string{ + "-Wl,-z,noexecstack", + "-Wl,-z,relro", + "-Wl,-z,now", + "-Wl,--build-id=md5", + "-Wl,--warn-shared-textrel", + "-Wl,--fatal-warnings", + "-Wl,--hash-style=gnu", + "-Wl,--no-undefined-version", + }) +) + +func init() { + pctx.StaticVariable("LinuxBionicArm64Cflags", strings.Join(linuxCrossCflags, " ")) + pctx.StaticVariable("LinuxBionicArm64Ldflags", strings.Join(linuxCrossLdflags, " ")) +} + +// toolchain config for ARM64 Linux CrossHost. Almost everything is the same as the ARM64 Android +// target. The overridden methods below show the differences. +type toolchainLinuxArm64 struct { + toolchainArm64 +} + +func (toolchainLinuxArm64) ClangTriple() string { + // Note the absence of "-android" suffix. The compiler won't define __ANDROID__ + return "aarch64-linux" +} + +func (toolchainLinuxArm64) ClangCflags() string { + // The inherited flags + extra flags + return "${config.Arm64ClangCflags} ${config.LinuxBionicArm64Cflags}" +} + +func linuxArm64ToolchainFactory(arch android.Arch) Toolchain { + archVariant := "armv8-a" // for host, default to armv8-a + toolchainClangCflags := []string{arm64ClangArchVariantCflagsVar[archVariant]} + + // We don't specify CPU architecture for host. Conservatively assume + // the host CPU needs the fix + extraLdflags := "-Wl,--fix-cortex-a53-843419" + + ret := toolchainLinuxArm64{} + + // add the extra ld and lld flags + ret.toolchainArm64.ldflags = strings.Join([]string{ + "${config.Arm64Ldflags}", + "${config.LinuxBionicArm64Ldflags}", + extraLdflags, + }, " ") + ret.toolchainArm64.lldflags = strings.Join([]string{ + "${config.Arm64Lldflags}", + "${config.LinuxBionicArm64Ldflags}", + extraLdflags, + }, " ") + ret.toolchainArm64.toolchainClangCflags = strings.Join(toolchainClangCflags, " ") + return &ret +} + +func init() { + registerToolchainFactory(android.LinuxBionic, android.Arm64, linuxArm64ToolchainFactory) +} diff --git a/rust/config/Android.bp b/rust/config/Android.bp index bcfac7c06..e0cc4ce07 100644 --- a/rust/config/Android.bp +++ b/rust/config/Android.bp @@ -16,5 +16,6 @@ bootstrap_go_package { "x86_linux_host.go", "x86_device.go", "x86_64_device.go", + "arm64_linux_host.go", ], } diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go index 180fd8ba0..b1f1f169a 100644 --- a/rust/config/arm64_device.go +++ b/rust/config/arm64_device.go @@ -75,9 +75,16 @@ func (t *toolchainArm64) Supported() bool { } func Arm64ToolchainFactory(arch android.Arch) Toolchain { + archVariant := arch.ArchVariant + if archVariant == "" { + // arch variants defaults to armv8-a. This is mostly for + // the host target which borrows toolchain configs from here. + archVariant = "armv8-a" + } + toolchainRustFlags := []string{ "${config.Arm64ToolchainRustFlags}", - "${config.Arm64" + arch.ArchVariant + "VariantRustFlags}", + "${config.Arm64" + archVariant + "VariantRustFlags}", } toolchainRustFlags = append(toolchainRustFlags, deviceGlobalRustFlags...) diff --git a/rust/config/arm64_linux_host.go b/rust/config/arm64_linux_host.go new file mode 100644 index 000000000..baf9cf836 --- /dev/null +++ b/rust/config/arm64_linux_host.go @@ -0,0 +1,24 @@ +// Copyright 2019 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "android/soong/android" +) + +func init() { + // Linux_cross-arm64 uses the same rust toolchain as the Android-arm64 + registerToolchainFactory(android.LinuxBionic, android.Arm64, Arm64ToolchainFactory) +}