// Copyright (C) 2016 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 art // This file implements the "codegen" property to apply different properties based on the currently // selected codegen arches, which defaults to all arches on the host and the primary and secondary // arches on the device. import ( "sort" "strings" "android/soong/android" ) type moduleType struct { library bool static bool shared bool } var ( staticLibrary = moduleType{true, true, false} sharedLibrary = moduleType{true, false, true} staticAndSharedLibrary = moduleType{true, true, true} binary = moduleType{false, false, false} ) func codegen(ctx android.LoadHookContext, c *codegenProperties, t moduleType) { var hostArches, deviceArches []string e := ctx.Config().Getenv("ART_HOST_CODEGEN_ARCHS") if e == "" { hostArches = supportedArches } else { hostArches = strings.Split(e, " ") } e = ctx.Config().Getenv("ART_TARGET_CODEGEN_ARCHS") if e == "" { deviceArches = defaultDeviceCodegenArches(ctx) } else { deviceArches = strings.Split(e, " ") } getCodegenArchProperties := func(archName string) *codegenArchProperties { var arch *codegenArchProperties switch archName { case "arm": arch = &c.Codegen.Arm case "arm64": arch = &c.Codegen.Arm64 case "riscv64": arch = &c.Codegen.Riscv64 case "x86": arch = &c.Codegen.X86 case "x86_64": arch = &c.Codegen.X86_64 default: ctx.ModuleErrorf("Unknown codegen architecture %q", archName) } return arch } appendCodegenSourceArchProperties := func(p *CodegenSourceArchProperties, archName string) { arch := getCodegenArchProperties(archName) p.Srcs = append(p.Srcs, arch.CodegenSourceArchProperties.Srcs...) } addCodegenSourceArchProperties := func(host bool, p *CodegenSourceArchProperties) { type sourceProps struct { Target struct { Android *CodegenSourceArchProperties Host *CodegenSourceArchProperties } } sp := &sourceProps{} if host { sp.Target.Host = p } else { sp.Target.Android = p } ctx.AppendProperties(sp) } addCodegenArchProperties := func(host bool, archName string) { type commonProps struct { Target struct { Android *CodegenCommonArchProperties Host *CodegenCommonArchProperties } } type libraryProps struct { Target struct { Android *CodegenLibraryArchProperties Host *CodegenLibraryArchProperties } } type sharedLibraryProps struct { Target struct { Android *CodegenLibraryArchSharedProperties Host *CodegenLibraryArchSharedProperties } } type staticLibraryProps struct { Target struct { Android *CodegenLibraryArchStaticProperties Host *CodegenLibraryArchStaticProperties } } arch := getCodegenArchProperties(archName) cp := &commonProps{} lp := &libraryProps{} sharedLP := &sharedLibraryProps{} staticLP := &staticLibraryProps{} if host { cp.Target.Host = &arch.CodegenCommonArchProperties lp.Target.Host = &arch.CodegenLibraryArchProperties sharedLP.Target.Host = &arch.CodegenLibraryArchSharedProperties staticLP.Target.Host = &arch.CodegenLibraryArchStaticProperties } else { cp.Target.Android = &arch.CodegenCommonArchProperties lp.Target.Android = &arch.CodegenLibraryArchProperties sharedLP.Target.Android = &arch.CodegenLibraryArchSharedProperties staticLP.Target.Android = &arch.CodegenLibraryArchStaticProperties } ctx.AppendProperties(cp) if t.library { ctx.AppendProperties(lp) if t.static { ctx.AppendProperties(staticLP) } if t.shared { ctx.AppendProperties(sharedLP) } } } addCodegenProperties := func(host bool, arches []string) { sourceProps := &CodegenSourceArchProperties{} for _, arch := range arches { appendCodegenSourceArchProperties(sourceProps, arch) addCodegenArchProperties(host, arch) } sourceProps.Srcs = android.FirstUniqueStrings(sourceProps.Srcs) addCodegenSourceArchProperties(host, sourceProps) } addCodegenProperties(false /* host */, deviceArches) addCodegenProperties(true /* host */, hostArches) } // These properties are allowed to contain the same source file name in different architectures. // They we will be deduplicated automatically. type CodegenSourceArchProperties struct { Srcs []string } type CodegenCommonArchProperties struct { Cflags []string Cppflags []string } type CodegenLibraryArchProperties struct { Static_libs []string Export_static_lib_headers []string } type CodegenLibraryArchStaticProperties struct { Static struct { Whole_static_libs []string } } type CodegenLibraryArchSharedProperties struct { Shared struct { Shared_libs []string Export_shared_lib_headers []string } } type codegenArchProperties struct { CodegenSourceArchProperties CodegenCommonArchProperties CodegenLibraryArchProperties CodegenLibraryArchStaticProperties CodegenLibraryArchSharedProperties } type codegenProperties struct { Codegen struct { Arm, Arm64, Riscv64, X86, X86_64 codegenArchProperties } } func defaultDeviceCodegenArches(ctx android.LoadHookContext) []string { arches := make(map[string]bool) for _, a := range ctx.DeviceConfig().Arches() { s := a.ArchType.String() arches[s] = true if s == "arm64" { arches["arm"] = true } else if s == "riscv64" { arches["riscv64"] = true } else if s == "x86_64" { arches["x86"] = true } } ret := make([]string, 0, len(arches)) for a := range arches { ret = append(ret, a) } sort.Strings(ret) return ret } func installCodegenCustomizer(module android.Module, t moduleType) { c := &codegenProperties{} android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, t) }) module.AddProperties(c) }