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 "x86": 66 arch = &c.Codegen.X86 67 case "x86_64": 68 arch = &c.Codegen.X86_64 69 default: 70 ctx.ModuleErrorf("Unknown codegen architecture %q", archName) 71 } 72 return arch 73 } 74 75 appendCodegenSourceArchProperties := func(p *CodegenSourceArchProperties, archName string) { 76 arch := getCodegenArchProperties(archName) 77 p.Srcs = append(p.Srcs, arch.CodegenSourceArchProperties.Srcs...) 78 } 79 80 addCodegenSourceArchProperties := func(host bool, p *CodegenSourceArchProperties) { 81 type sourceProps struct { 82 Target struct { 83 Android *CodegenSourceArchProperties 84 Host *CodegenSourceArchProperties 85 } 86 } 87 88 sp := &sourceProps{} 89 if host { 90 sp.Target.Host = p 91 } else { 92 sp.Target.Android = p 93 } 94 ctx.AppendProperties(sp) 95 } 96 97 addCodegenArchProperties := func(host bool, archName string) { 98 type commonProps struct { 99 Target struct { 100 Android *CodegenCommonArchProperties 101 Host *CodegenCommonArchProperties 102 } 103 } 104 105 type libraryProps struct { 106 Target struct { 107 Android *CodegenLibraryArchProperties 108 Host *CodegenLibraryArchProperties 109 } 110 } 111 112 type sharedLibraryProps struct { 113 Target struct { 114 Android *CodegenLibraryArchSharedProperties 115 Host *CodegenLibraryArchSharedProperties 116 } 117 } 118 119 type staticLibraryProps struct { 120 Target struct { 121 Android *CodegenLibraryArchStaticProperties 122 Host *CodegenLibraryArchStaticProperties 123 } 124 } 125 126 arch := getCodegenArchProperties(archName) 127 128 cp := &commonProps{} 129 lp := &libraryProps{} 130 sharedLP := &sharedLibraryProps{} 131 staticLP := &staticLibraryProps{} 132 if host { 133 cp.Target.Host = &arch.CodegenCommonArchProperties 134 lp.Target.Host = &arch.CodegenLibraryArchProperties 135 sharedLP.Target.Host = &arch.CodegenLibraryArchSharedProperties 136 staticLP.Target.Host = &arch.CodegenLibraryArchStaticProperties 137 } else { 138 cp.Target.Android = &arch.CodegenCommonArchProperties 139 lp.Target.Android = &arch.CodegenLibraryArchProperties 140 sharedLP.Target.Android = &arch.CodegenLibraryArchSharedProperties 141 staticLP.Target.Android = &arch.CodegenLibraryArchStaticProperties 142 } 143 144 ctx.AppendProperties(cp) 145 if t.library { 146 ctx.AppendProperties(lp) 147 if t.static { 148 ctx.AppendProperties(staticLP) 149 } 150 if t.shared { 151 ctx.AppendProperties(sharedLP) 152 } 153 } 154 } 155 156 addCodegenProperties := func(host bool, arches []string) { 157 sourceProps := &CodegenSourceArchProperties{} 158 for _, arch := range arches { 159 appendCodegenSourceArchProperties(sourceProps, arch) 160 addCodegenArchProperties(host, arch) 161 } 162 sourceProps.Srcs = android.FirstUniqueStrings(sourceProps.Srcs) 163 addCodegenSourceArchProperties(host, sourceProps) 164 } 165 166 addCodegenProperties(false /* host */, deviceArches) 167 addCodegenProperties(true /* host */, hostArches) 168} 169 170// These properties are allowed to contain the same source file name in different architectures. 171// They we will be deduplicated automatically. 172type CodegenSourceArchProperties struct { 173 Srcs []string 174} 175 176type CodegenCommonArchProperties struct { 177 Cflags []string 178 Cppflags []string 179} 180 181type CodegenLibraryArchProperties struct { 182 Static_libs []string 183 Export_static_lib_headers []string 184} 185 186type CodegenLibraryArchStaticProperties struct { 187 Static struct { 188 Whole_static_libs []string 189 } 190} 191type CodegenLibraryArchSharedProperties struct { 192 Shared struct { 193 Shared_libs []string 194 Export_shared_lib_headers []string 195 } 196} 197 198type codegenArchProperties struct { 199 CodegenSourceArchProperties 200 CodegenCommonArchProperties 201 CodegenLibraryArchProperties 202 CodegenLibraryArchStaticProperties 203 CodegenLibraryArchSharedProperties 204} 205 206type codegenProperties struct { 207 Codegen struct { 208 Arm, Arm64, X86, X86_64 codegenArchProperties 209 } 210} 211 212func defaultDeviceCodegenArches(ctx android.LoadHookContext) []string { 213 arches := make(map[string]bool) 214 for _, a := range ctx.DeviceConfig().Arches() { 215 s := a.ArchType.String() 216 arches[s] = true 217 if s == "arm64" { 218 arches["arm"] = true 219 } else if s == "x86_64" { 220 arches["x86"] = true 221 } 222 } 223 ret := make([]string, 0, len(arches)) 224 for a := range arches { 225 ret = append(ret, a) 226 } 227 sort.Strings(ret) 228 return ret 229} 230 231func installCodegenCustomizer(module android.Module, t moduleType) { 232 c := &codegenProperties{} 233 android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, t) }) 234 module.AddProperties(c) 235} 236