1// Copyright (C) 2016 The Android Open Source Project 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 art 16 17// This file implements the "codegen" property to apply different properties based on the currently 18// selected codegen arches, which defaults to all arches on the host and the primary and secondary 19// arches on the device. 20 21import ( 22 "sort" 23 "strings" 24 25 "android/soong/android" 26) 27 28type moduleType struct { 29 library bool 30 static bool 31 shared bool 32} 33 34var ( 35 staticLibrary = moduleType{true, true, false} 36 sharedLibrary = moduleType{true, false, true} 37 staticAndSharedLibrary = moduleType{true, true, true} 38 binary = moduleType{false, false, false} 39) 40 41func codegen(ctx android.LoadHookContext, c *codegenProperties, t moduleType) { 42 var hostArches, deviceArches []string 43 44 e := ctx.Config().Getenv("ART_HOST_CODEGEN_ARCHS") 45 if e == "" { 46 hostArches = supportedArches 47 } else { 48 hostArches = strings.Split(e, " ") 49 } 50 51 e = ctx.Config().Getenv("ART_TARGET_CODEGEN_ARCHS") 52 if e == "" { 53 deviceArches = defaultDeviceCodegenArches(ctx) 54 } else { 55 deviceArches = strings.Split(e, " ") 56 } 57 58 getCodegenArchProperties := func(archName string) *codegenArchProperties { 59 var arch *codegenArchProperties 60 switch archName { 61 case "arm": 62 arch = &c.Codegen.Arm 63 case "arm64": 64 arch = &c.Codegen.Arm64 65 case "riscv64": 66 arch = &c.Codegen.Riscv64 67 case "x86": 68 arch = &c.Codegen.X86 69 case "x86_64": 70 arch = &c.Codegen.X86_64 71 default: 72 ctx.ModuleErrorf("Unknown codegen architecture %q", archName) 73 } 74 return arch 75 } 76 77 appendCodegenSourceArchProperties := func(p *CodegenSourceArchProperties, archName string) { 78 arch := getCodegenArchProperties(archName) 79 p.Srcs = append(p.Srcs, arch.CodegenSourceArchProperties.Srcs...) 80 } 81 82 addCodegenSourceArchProperties := func(host bool, p *CodegenSourceArchProperties) { 83 type sourceProps struct { 84 Target struct { 85 Android *CodegenSourceArchProperties 86 Host *CodegenSourceArchProperties 87 } 88 } 89 90 sp := &sourceProps{} 91 if host { 92 sp.Target.Host = p 93 } else { 94 sp.Target.Android = p 95 } 96 ctx.AppendProperties(sp) 97 } 98 99 addCodegenArchProperties := func(host bool, archName string) { 100 type commonProps struct { 101 Target struct { 102 Android *CodegenCommonArchProperties 103 Host *CodegenCommonArchProperties 104 } 105 } 106 107 type libraryProps struct { 108 Target struct { 109 Android *CodegenLibraryArchProperties 110 Host *CodegenLibraryArchProperties 111 } 112 } 113 114 type sharedLibraryProps struct { 115 Target struct { 116 Android *CodegenLibraryArchSharedProperties 117 Host *CodegenLibraryArchSharedProperties 118 } 119 } 120 121 type staticLibraryProps struct { 122 Target struct { 123 Android *CodegenLibraryArchStaticProperties 124 Host *CodegenLibraryArchStaticProperties 125 } 126 } 127 128 arch := getCodegenArchProperties(archName) 129 130 cp := &commonProps{} 131 lp := &libraryProps{} 132 sharedLP := &sharedLibraryProps{} 133 staticLP := &staticLibraryProps{} 134 if host { 135 cp.Target.Host = &arch.CodegenCommonArchProperties 136 lp.Target.Host = &arch.CodegenLibraryArchProperties 137 sharedLP.Target.Host = &arch.CodegenLibraryArchSharedProperties 138 staticLP.Target.Host = &arch.CodegenLibraryArchStaticProperties 139 } else { 140 cp.Target.Android = &arch.CodegenCommonArchProperties 141 lp.Target.Android = &arch.CodegenLibraryArchProperties 142 sharedLP.Target.Android = &arch.CodegenLibraryArchSharedProperties 143 staticLP.Target.Android = &arch.CodegenLibraryArchStaticProperties 144 } 145 146 ctx.AppendProperties(cp) 147 if t.library { 148 ctx.AppendProperties(lp) 149 if t.static { 150 ctx.AppendProperties(staticLP) 151 } 152 if t.shared { 153 ctx.AppendProperties(sharedLP) 154 } 155 } 156 } 157 158 addCodegenProperties := func(host bool, arches []string) { 159 sourceProps := &CodegenSourceArchProperties{} 160 for _, arch := range arches { 161 appendCodegenSourceArchProperties(sourceProps, arch) 162 addCodegenArchProperties(host, arch) 163 } 164 sourceProps.Srcs = android.FirstUniqueStrings(sourceProps.Srcs) 165 addCodegenSourceArchProperties(host, sourceProps) 166 } 167 168 addCodegenProperties(false /* host */, deviceArches) 169 addCodegenProperties(true /* host */, hostArches) 170} 171 172// These properties are allowed to contain the same source file name in different architectures. 173// They we will be deduplicated automatically. 174type CodegenSourceArchProperties struct { 175 Srcs []string 176} 177 178type CodegenCommonArchProperties struct { 179 Cflags []string 180 Cppflags []string 181} 182 183type CodegenLibraryArchProperties struct { 184 Static_libs []string 185 Export_static_lib_headers []string 186} 187 188type CodegenLibraryArchStaticProperties struct { 189 Static struct { 190 Whole_static_libs []string 191 } 192} 193type CodegenLibraryArchSharedProperties struct { 194 Shared struct { 195 Shared_libs []string 196 Export_shared_lib_headers []string 197 } 198} 199 200type codegenArchProperties struct { 201 CodegenSourceArchProperties 202 CodegenCommonArchProperties 203 CodegenLibraryArchProperties 204 CodegenLibraryArchStaticProperties 205 CodegenLibraryArchSharedProperties 206} 207 208type codegenProperties struct { 209 Codegen struct { 210 Arm, Arm64, Riscv64, X86, X86_64 codegenArchProperties 211 } 212} 213 214func defaultDeviceCodegenArches(ctx android.LoadHookContext) []string { 215 arches := make(map[string]bool) 216 for _, a := range ctx.DeviceConfig().Arches() { 217 s := a.ArchType.String() 218 arches[s] = true 219 if s == "arm64" { 220 arches["arm"] = true 221 } else if s == "riscv64" { 222 arches["riscv64"] = true 223 } else if s == "x86_64" { 224 arches["x86"] = true 225 } 226 } 227 ret := make([]string, 0, len(arches)) 228 for a := range arches { 229 ret = append(ret, a) 230 } 231 sort.Strings(ret) 232 return ret 233} 234 235func installCodegenCustomizer(module android.Module, t moduleType) { 236 c := &codegenProperties{} 237 android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, t) }) 238 module.AddProperties(c) 239} 240