1// Copyright 2020 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package config
16
17import (
18	"android/soong/android"
19	"strings"
20)
21
22var (
23	// This is a host toolchain but flags for device toolchain are required
24	// as the flags are actually for Bionic-based builds.
25	linuxCrossCflags = ClangFilterUnknownCflags(append(deviceGlobalCflags,
26		// clang by default enables PIC when the clang triple is set to *-android.
27		// See toolchain/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp#920.
28		// However, for this host target, we don't set "-android" to avoid __ANDROID__ macro
29		// which stands for "Android device target". Keeping PIC on is required because
30		// many modules we have (e.g. Bionic) assume PIC.
31		"-fpic",
32
33		// This is normally in ClangExtraTargetCflags, but that's for device and we need
34		// the same for host
35		"-nostdlibinc",
36	))
37
38	linuxCrossLdflags = ClangFilterUnknownCflags([]string{
39		"-Wl,-z,noexecstack",
40		"-Wl,-z,relro",
41		"-Wl,-z,now",
42		"-Wl,--build-id=md5",
43		"-Wl,--warn-shared-textrel",
44		"-Wl,--fatal-warnings",
45		"-Wl,--hash-style=gnu",
46		"-Wl,--no-undefined-version",
47	})
48)
49
50func init() {
51	pctx.StaticVariable("LinuxBionicArm64Cflags", strings.Join(linuxCrossCflags, " "))
52	pctx.StaticVariable("LinuxBionicArm64Ldflags", strings.Join(linuxCrossLdflags, " "))
53}
54
55// toolchain config for ARM64 Linux CrossHost. Almost everything is the same as the ARM64 Android
56// target. The overridden methods below show the differences.
57type toolchainLinuxArm64 struct {
58	toolchainArm64
59}
60
61func (toolchainLinuxArm64) ClangTriple() string {
62	// Note the absence of "-android" suffix. The compiler won't define __ANDROID__
63	return "aarch64-linux"
64}
65
66func (toolchainLinuxArm64) ClangCflags() string {
67	// The inherited flags + extra flags
68	return "${config.Arm64ClangCflags} ${config.LinuxBionicArm64Cflags}"
69}
70
71func linuxArm64ToolchainFactory(arch android.Arch) Toolchain {
72	archVariant := "armv8-a" // for host, default to armv8-a
73	toolchainClangCflags := []string{arm64ClangArchVariantCflagsVar[archVariant]}
74
75	// We don't specify CPU architecture for host. Conservatively assume
76	// the host CPU needs the fix
77	extraLdflags := "-Wl,--fix-cortex-a53-843419"
78
79	ret := toolchainLinuxArm64{}
80
81	// add the extra ld and lld flags
82	ret.toolchainArm64.ldflags = strings.Join([]string{
83		"${config.Arm64Ldflags}",
84		"${config.LinuxBionicArm64Ldflags}",
85		extraLdflags,
86	}, " ")
87	ret.toolchainArm64.lldflags = strings.Join([]string{
88		"${config.Arm64Lldflags}",
89		"${config.LinuxBionicArm64Ldflags}",
90		extraLdflags,
91	}, " ")
92	ret.toolchainArm64.toolchainClangCflags = strings.Join(toolchainClangCflags, " ")
93	return &ret
94}
95
96func init() {
97	registerToolchainFactory(android.LinuxBionic, android.Arm64, linuxArm64ToolchainFactory)
98}
99