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 sharedLibraryProps struct { 106 Target struct { 107 Android *CodegenLibraryArchSharedProperties 108 Host *CodegenLibraryArchSharedProperties 109 } 110 } 111 112 type staticLibraryProps struct { 113 Target struct { 114 Android *CodegenLibraryArchStaticProperties 115 Host *CodegenLibraryArchStaticProperties 116 } 117 } 118 119 arch := getCodegenArchProperties(archName) 120 121 cp := &commonProps{} 122 sharedLP := &sharedLibraryProps{} 123 staticLP := &staticLibraryProps{} 124 if host { 125 cp.Target.Host = &arch.CodegenCommonArchProperties 126 sharedLP.Target.Host = &arch.CodegenLibraryArchSharedProperties 127 staticLP.Target.Host = &arch.CodegenLibraryArchStaticProperties 128 } else { 129 cp.Target.Android = &arch.CodegenCommonArchProperties 130 sharedLP.Target.Android = &arch.CodegenLibraryArchSharedProperties 131 staticLP.Target.Android = &arch.CodegenLibraryArchStaticProperties 132 } 133 134 ctx.AppendProperties(cp) 135 if t.library { 136 if t.static { 137 ctx.AppendProperties(staticLP) 138 } 139 if t.shared { 140 ctx.AppendProperties(sharedLP) 141 } 142 } 143 } 144 145 addCodegenProperties := func(host bool, arches []string) { 146 sourceProps := &CodegenSourceArchProperties{} 147 for _, arch := range arches { 148 appendCodegenSourceArchProperties(sourceProps, arch) 149 addCodegenArchProperties(host, arch) 150 } 151 sourceProps.Srcs = android.FirstUniqueStrings(sourceProps.Srcs) 152 addCodegenSourceArchProperties(host, sourceProps) 153 } 154 155 addCodegenProperties(false /* host */, deviceArches) 156 addCodegenProperties(true /* host */, hostArches) 157} 158 159// These properties are allowed to contain the same source file name in different architectures. 160// They we will be deduplicated automatically. 161type CodegenSourceArchProperties struct { 162 Srcs []string 163} 164 165type CodegenCommonArchProperties struct { 166 Cflags []string 167 Cppflags []string 168} 169 170type CodegenLibraryArchStaticProperties struct { 171 Static struct { 172 Whole_static_libs []string 173 } 174} 175type CodegenLibraryArchSharedProperties struct { 176 Shared struct { 177 Shared_libs []string 178 Export_shared_lib_headers []string 179 } 180} 181 182type codegenArchProperties struct { 183 CodegenSourceArchProperties 184 CodegenCommonArchProperties 185 CodegenLibraryArchStaticProperties 186 CodegenLibraryArchSharedProperties 187} 188 189type codegenProperties struct { 190 Codegen struct { 191 Arm, Arm64, X86, X86_64 codegenArchProperties 192 } 193} 194 195func defaultDeviceCodegenArches(ctx android.LoadHookContext) []string { 196 arches := make(map[string]bool) 197 for _, a := range ctx.DeviceConfig().Arches() { 198 s := a.ArchType.String() 199 arches[s] = true 200 if s == "arm64" { 201 arches["arm"] = true 202 } else if s == "x86_64" { 203 arches["x86"] = true 204 } 205 } 206 ret := make([]string, 0, len(arches)) 207 for a := range arches { 208 ret = append(ret, a) 209 } 210 sort.Strings(ret) 211 return ret 212} 213 214func installCodegenCustomizer(module android.Module, t moduleType) { 215 c := &codegenProperties{} 216 android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, t) }) 217 module.AddProperties(c) 218} 219