1*333d2b36SAndroid Build Coastguard Worker// Copyright 2020 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage cc 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 19*333d2b36SAndroid Build Coastguard Worker "android/soong/genrule" 20*333d2b36SAndroid Build Coastguard Worker) 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker// sdkTransitionMutator creates a platform and an SDK variant for modules 23*333d2b36SAndroid Build Coastguard Worker// that set sdk_version, and ignores sdk_version for the platform 24*333d2b36SAndroid Build Coastguard Worker// variant. The SDK variant will be used for embedding in APKs 25*333d2b36SAndroid Build Coastguard Worker// that may be installed on older platforms. Apexes use their own 26*333d2b36SAndroid Build Coastguard Worker// variants that enforce backwards compatibility. 27*333d2b36SAndroid Build Coastguard Workertype sdkTransitionMutator struct{} 28*333d2b36SAndroid Build Coastguard Worker 29*333d2b36SAndroid Build Coastguard Workerfunc (sdkTransitionMutator) Split(ctx android.BaseModuleContext) []string { 30*333d2b36SAndroid Build Coastguard Worker if ctx.Os() != android.Android { 31*333d2b36SAndroid Build Coastguard Worker return []string{""} 32*333d2b36SAndroid Build Coastguard Worker } 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Worker switch m := ctx.Module().(type) { 35*333d2b36SAndroid Build Coastguard Worker case LinkableInterface: 36*333d2b36SAndroid Build Coastguard Worker if m.AlwaysSdk() { 37*333d2b36SAndroid Build Coastguard Worker if !m.UseSdk() && !m.SplitPerApiLevel() { 38*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("UseSdk() must return true when AlwaysSdk is set, did the factory forget to set Sdk_version?") 39*333d2b36SAndroid Build Coastguard Worker } 40*333d2b36SAndroid Build Coastguard Worker return []string{"sdk"} 41*333d2b36SAndroid Build Coastguard Worker } else if m.UseSdk() || m.SplitPerApiLevel() { 42*333d2b36SAndroid Build Coastguard Worker return []string{"", "sdk"} 43*333d2b36SAndroid Build Coastguard Worker } else { 44*333d2b36SAndroid Build Coastguard Worker return []string{""} 45*333d2b36SAndroid Build Coastguard Worker } 46*333d2b36SAndroid Build Coastguard Worker case *genrule.Module: 47*333d2b36SAndroid Build Coastguard Worker if p, ok := m.Extra.(*GenruleExtraProperties); ok { 48*333d2b36SAndroid Build Coastguard Worker if String(p.Sdk_version) != "" { 49*333d2b36SAndroid Build Coastguard Worker return []string{"", "sdk"} 50*333d2b36SAndroid Build Coastguard Worker } else { 51*333d2b36SAndroid Build Coastguard Worker return []string{""} 52*333d2b36SAndroid Build Coastguard Worker } 53*333d2b36SAndroid Build Coastguard Worker } 54*333d2b36SAndroid Build Coastguard Worker } 55*333d2b36SAndroid Build Coastguard Worker 56*333d2b36SAndroid Build Coastguard Worker return []string{""} 57*333d2b36SAndroid Build Coastguard Worker} 58*333d2b36SAndroid Build Coastguard Worker 59*333d2b36SAndroid Build Coastguard Workerfunc (sdkTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string { 60*333d2b36SAndroid Build Coastguard Worker return sourceVariation 61*333d2b36SAndroid Build Coastguard Worker} 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Workerfunc (sdkTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string { 64*333d2b36SAndroid Build Coastguard Worker if ctx.Os() != android.Android { 65*333d2b36SAndroid Build Coastguard Worker return "" 66*333d2b36SAndroid Build Coastguard Worker } 67*333d2b36SAndroid Build Coastguard Worker switch m := ctx.Module().(type) { 68*333d2b36SAndroid Build Coastguard Worker case LinkableInterface: 69*333d2b36SAndroid Build Coastguard Worker if m.AlwaysSdk() { 70*333d2b36SAndroid Build Coastguard Worker return "sdk" 71*333d2b36SAndroid Build Coastguard Worker } else if m.UseSdk() || m.SplitPerApiLevel() { 72*333d2b36SAndroid Build Coastguard Worker return incomingVariation 73*333d2b36SAndroid Build Coastguard Worker } 74*333d2b36SAndroid Build Coastguard Worker case *genrule.Module: 75*333d2b36SAndroid Build Coastguard Worker if p, ok := m.Extra.(*GenruleExtraProperties); ok { 76*333d2b36SAndroid Build Coastguard Worker if String(p.Sdk_version) != "" { 77*333d2b36SAndroid Build Coastguard Worker return incomingVariation 78*333d2b36SAndroid Build Coastguard Worker } 79*333d2b36SAndroid Build Coastguard Worker } 80*333d2b36SAndroid Build Coastguard Worker } 81*333d2b36SAndroid Build Coastguard Worker 82*333d2b36SAndroid Build Coastguard Worker if ctx.IsAddingDependency() { 83*333d2b36SAndroid Build Coastguard Worker return incomingVariation 84*333d2b36SAndroid Build Coastguard Worker } else { 85*333d2b36SAndroid Build Coastguard Worker return "" 86*333d2b36SAndroid Build Coastguard Worker } 87*333d2b36SAndroid Build Coastguard Worker} 88*333d2b36SAndroid Build Coastguard Worker 89*333d2b36SAndroid Build Coastguard Workerfunc (sdkTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) { 90*333d2b36SAndroid Build Coastguard Worker if ctx.Os() != android.Android { 91*333d2b36SAndroid Build Coastguard Worker return 92*333d2b36SAndroid Build Coastguard Worker } 93*333d2b36SAndroid Build Coastguard Worker 94*333d2b36SAndroid Build Coastguard Worker switch m := ctx.Module().(type) { 95*333d2b36SAndroid Build Coastguard Worker case LinkableInterface: 96*333d2b36SAndroid Build Coastguard Worker ccModule, isCcModule := ctx.Module().(*Module) 97*333d2b36SAndroid Build Coastguard Worker if m.AlwaysSdk() { 98*333d2b36SAndroid Build Coastguard Worker if variation != "sdk" { 99*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("tried to create variation %q for module with AlwaysSdk set, expected \"sdk\"", variation) 100*333d2b36SAndroid Build Coastguard Worker } 101*333d2b36SAndroid Build Coastguard Worker 102*333d2b36SAndroid Build Coastguard Worker ccModule.Properties.IsSdkVariant = true 103*333d2b36SAndroid Build Coastguard Worker } else if m.UseSdk() || m.SplitPerApiLevel() { 104*333d2b36SAndroid Build Coastguard Worker if variation == "" { 105*333d2b36SAndroid Build Coastguard Worker // Clear the sdk_version property for the platform (non-SDK) variant so later code 106*333d2b36SAndroid Build Coastguard Worker // doesn't get confused by it. 107*333d2b36SAndroid Build Coastguard Worker ccModule.Properties.Sdk_version = nil 108*333d2b36SAndroid Build Coastguard Worker } else { 109*333d2b36SAndroid Build Coastguard Worker // Mark the SDK variant. 110*333d2b36SAndroid Build Coastguard Worker ccModule.Properties.IsSdkVariant = true 111*333d2b36SAndroid Build Coastguard Worker 112*333d2b36SAndroid Build Coastguard Worker // SDK variant never gets installed because the variant is to be embedded in 113*333d2b36SAndroid Build Coastguard Worker // APKs, not to be installed to the platform. 114*333d2b36SAndroid Build Coastguard Worker ccModule.Properties.PreventInstall = true 115*333d2b36SAndroid Build Coastguard Worker } 116*333d2b36SAndroid Build Coastguard Worker 117*333d2b36SAndroid Build Coastguard Worker if ctx.Config().UnbundledBuildApps() { 118*333d2b36SAndroid Build Coastguard Worker if variation == "" { 119*333d2b36SAndroid Build Coastguard Worker // For an unbundled apps build, hide the platform variant from Make 120*333d2b36SAndroid Build Coastguard Worker // so that other Make modules don't link against it, but against the 121*333d2b36SAndroid Build Coastguard Worker // SDK variant. 122*333d2b36SAndroid Build Coastguard Worker ccModule.Properties.HideFromMake = true 123*333d2b36SAndroid Build Coastguard Worker } 124*333d2b36SAndroid Build Coastguard Worker } else { 125*333d2b36SAndroid Build Coastguard Worker if variation == "sdk" { 126*333d2b36SAndroid Build Coastguard Worker // For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when 127*333d2b36SAndroid Build Coastguard Worker // exposed to Make. 128*333d2b36SAndroid Build Coastguard Worker ccModule.Properties.SdkAndPlatformVariantVisibleToMake = true 129*333d2b36SAndroid Build Coastguard Worker } 130*333d2b36SAndroid Build Coastguard Worker } 131*333d2b36SAndroid Build Coastguard Worker } else { 132*333d2b36SAndroid Build Coastguard Worker if isCcModule { 133*333d2b36SAndroid Build Coastguard Worker // Clear the sdk_version property for modules that don't have an SDK variant so 134*333d2b36SAndroid Build Coastguard Worker // later code doesn't get confused by it. 135*333d2b36SAndroid Build Coastguard Worker ccModule.Properties.Sdk_version = nil 136*333d2b36SAndroid Build Coastguard Worker } 137*333d2b36SAndroid Build Coastguard Worker } 138*333d2b36SAndroid Build Coastguard Worker } 139*333d2b36SAndroid Build Coastguard Worker} 140