1*333d2b36SAndroid Build Coastguard Worker// Copyright 2024 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 Worker// Package golang wraps the blueprint blueprint_go_binary and bootstrap_go_binary module types in versions 16*333d2b36SAndroid Build Coastguard Worker// that implement android.Module that are used when building in Soong. This simplifies the code in Soong 17*333d2b36SAndroid Build Coastguard Worker// so it can always assume modules are an android.Module. 18*333d2b36SAndroid Build Coastguard Worker// The original blueprint blueprint_go_binary and bootstrap_go_binary module types are still used during 19*333d2b36SAndroid Build Coastguard Worker// bootstrapping, so the Android.bp entries for these module types must be compatible with both the 20*333d2b36SAndroid Build Coastguard Worker// original blueprint module types and these wrapped module types. 21*333d2b36SAndroid Build Coastguard Workerpackage golang 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Workerimport ( 24*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 25*333d2b36SAndroid Build Coastguard Worker 26*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 27*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/bootstrap" 28*333d2b36SAndroid Build Coastguard Worker) 29*333d2b36SAndroid Build Coastguard Worker 30*333d2b36SAndroid Build Coastguard Workerfunc init() { 31*333d2b36SAndroid Build Coastguard Worker // Wrap the blueprint Go module types with Soong ones that interoperate with the rest of the Soong modules. 32*333d2b36SAndroid Build Coastguard Worker bootstrap.GoModuleTypesAreWrapped() 33*333d2b36SAndroid Build Coastguard Worker RegisterGoModuleTypes(android.InitRegistrationContext) 34*333d2b36SAndroid Build Coastguard Worker} 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Workerfunc RegisterGoModuleTypes(ctx android.RegistrationContext) { 37*333d2b36SAndroid Build Coastguard Worker ctx.RegisterModuleType("bootstrap_go_package", goPackageModuleFactory) 38*333d2b36SAndroid Build Coastguard Worker ctx.RegisterModuleType("blueprint_go_binary", goBinaryModuleFactory) 39*333d2b36SAndroid Build Coastguard Worker} 40*333d2b36SAndroid Build Coastguard Worker 41*333d2b36SAndroid Build Coastguard Worker// A GoPackage is a module for building Go packages. 42*333d2b36SAndroid Build Coastguard Workertype GoPackage struct { 43*333d2b36SAndroid Build Coastguard Worker android.ModuleBase 44*333d2b36SAndroid Build Coastguard Worker bootstrap.GoPackage 45*333d2b36SAndroid Build Coastguard Worker} 46*333d2b36SAndroid Build Coastguard Worker 47*333d2b36SAndroid Build Coastguard Workerfunc goPackageModuleFactory() android.Module { 48*333d2b36SAndroid Build Coastguard Worker module := &GoPackage{} 49*333d2b36SAndroid Build Coastguard Worker module.AddProperties(module.Properties()...) 50*333d2b36SAndroid Build Coastguard Worker android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) 51*333d2b36SAndroid Build Coastguard Worker return module 52*333d2b36SAndroid Build Coastguard Worker} 53*333d2b36SAndroid Build Coastguard Worker 54*333d2b36SAndroid Build Coastguard Workerfunc (g *GoPackage) GenerateBuildActions(ctx blueprint.ModuleContext) { 55*333d2b36SAndroid Build Coastguard Worker // The embedded ModuleBase and bootstrap.GoPackage each implement GenerateBuildActions, 56*333d2b36SAndroid Build Coastguard Worker // the delegation has to be implemented manually to disambiguate. Call ModuleBase's 57*333d2b36SAndroid Build Coastguard Worker // GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call 58*333d2b36SAndroid Build Coastguard Worker // bootstrap.GoPackage.GenerateBuildActions. 59*333d2b36SAndroid Build Coastguard Worker g.ModuleBase.GenerateBuildActions(ctx) 60*333d2b36SAndroid Build Coastguard Worker} 61*333d2b36SAndroid Build Coastguard Worker 62*333d2b36SAndroid Build Coastguard Workerfunc (g *GoPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) { 63*333d2b36SAndroid Build Coastguard Worker g.GoPackage.GenerateBuildActions(ctx.BlueprintModuleContext()) 64*333d2b36SAndroid Build Coastguard Worker} 65*333d2b36SAndroid Build Coastguard Worker 66*333d2b36SAndroid Build Coastguard Worker// A GoBinary is a module for building executable binaries from Go sources. 67*333d2b36SAndroid Build Coastguard Workertype GoBinary struct { 68*333d2b36SAndroid Build Coastguard Worker android.ModuleBase 69*333d2b36SAndroid Build Coastguard Worker bootstrap.GoBinary 70*333d2b36SAndroid Build Coastguard Worker 71*333d2b36SAndroid Build Coastguard Worker outputFile android.Path 72*333d2b36SAndroid Build Coastguard Worker} 73*333d2b36SAndroid Build Coastguard Worker 74*333d2b36SAndroid Build Coastguard Workerfunc goBinaryModuleFactory() android.Module { 75*333d2b36SAndroid Build Coastguard Worker module := &GoBinary{} 76*333d2b36SAndroid Build Coastguard Worker module.AddProperties(module.Properties()...) 77*333d2b36SAndroid Build Coastguard Worker android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) 78*333d2b36SAndroid Build Coastguard Worker return module 79*333d2b36SAndroid Build Coastguard Worker} 80*333d2b36SAndroid Build Coastguard Worker 81*333d2b36SAndroid Build Coastguard Workerfunc (g *GoBinary) GenerateBuildActions(ctx blueprint.ModuleContext) { 82*333d2b36SAndroid Build Coastguard Worker // The embedded ModuleBase and bootstrap.GoBinary each implement GenerateBuildActions, 83*333d2b36SAndroid Build Coastguard Worker // the delegation has to be implemented manually to disambiguate. Call ModuleBase's 84*333d2b36SAndroid Build Coastguard Worker // GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call 85*333d2b36SAndroid Build Coastguard Worker // bootstrap.GoBinary.GenerateBuildActions. 86*333d2b36SAndroid Build Coastguard Worker g.ModuleBase.GenerateBuildActions(ctx) 87*333d2b36SAndroid Build Coastguard Worker} 88*333d2b36SAndroid Build Coastguard Worker 89*333d2b36SAndroid Build Coastguard Workerfunc (g *GoBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 90*333d2b36SAndroid Build Coastguard Worker // Install the file in Soong instead of blueprint so that Soong knows about the install rules. 91*333d2b36SAndroid Build Coastguard Worker g.GoBinary.SetSkipInstall() 92*333d2b36SAndroid Build Coastguard Worker 93*333d2b36SAndroid Build Coastguard Worker // Run the build actions from the wrapped blueprint bootstrap module. 94*333d2b36SAndroid Build Coastguard Worker g.GoBinary.GenerateBuildActions(ctx.BlueprintModuleContext()) 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker // Translate the bootstrap module's string path into a Path 97*333d2b36SAndroid Build Coastguard Worker outputFile := android.PathForArbitraryOutput(ctx, android.Rel(ctx, ctx.Config().OutDir(), g.IntermediateFile())).WithoutRel() 98*333d2b36SAndroid Build Coastguard Worker g.outputFile = outputFile 99*333d2b36SAndroid Build Coastguard Worker 100*333d2b36SAndroid Build Coastguard Worker // Don't create install rules for modules used by bootstrap, the install command line will differ from 101*333d2b36SAndroid Build Coastguard Worker // what was used during bootstrap, which will cause ninja to rebuild the module on the next run, 102*333d2b36SAndroid Build Coastguard Worker // triggering reanalysis. 103*333d2b36SAndroid Build Coastguard Worker if !usedByBootstrap(ctx.ModuleName()) { 104*333d2b36SAndroid Build Coastguard Worker installPath := ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), outputFile) 105*333d2b36SAndroid Build Coastguard Worker 106*333d2b36SAndroid Build Coastguard Worker // Modules in an unexported namespace have no install rule, only add modules in the exported namespaces 107*333d2b36SAndroid Build Coastguard Worker // to the blueprint_tools phony rules. 108*333d2b36SAndroid Build Coastguard Worker if !ctx.Config().KatiEnabled() || g.ExportedToMake() { 109*333d2b36SAndroid Build Coastguard Worker ctx.Phony("blueprint_tools", installPath) 110*333d2b36SAndroid Build Coastguard Worker } 111*333d2b36SAndroid Build Coastguard Worker } 112*333d2b36SAndroid Build Coastguard Worker 113*333d2b36SAndroid Build Coastguard Worker ctx.SetOutputFiles(android.Paths{outputFile}, "") 114*333d2b36SAndroid Build Coastguard Worker} 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Workerfunc usedByBootstrap(name string) bool { 117*333d2b36SAndroid Build Coastguard Worker switch name { 118*333d2b36SAndroid Build Coastguard Worker case "loadplugins", "soong_build": 119*333d2b36SAndroid Build Coastguard Worker return true 120*333d2b36SAndroid Build Coastguard Worker default: 121*333d2b36SAndroid Build Coastguard Worker return false 122*333d2b36SAndroid Build Coastguard Worker } 123*333d2b36SAndroid Build Coastguard Worker} 124*333d2b36SAndroid Build Coastguard Worker 125*333d2b36SAndroid Build Coastguard Workerfunc (g *GoBinary) HostToolPath() android.OptionalPath { 126*333d2b36SAndroid Build Coastguard Worker return android.OptionalPathForPath(g.outputFile) 127*333d2b36SAndroid Build Coastguard Worker} 128*333d2b36SAndroid Build Coastguard Worker 129*333d2b36SAndroid Build Coastguard Workerfunc (g *GoBinary) AndroidMkEntries() []android.AndroidMkEntries { 130*333d2b36SAndroid Build Coastguard Worker return []android.AndroidMkEntries{ 131*333d2b36SAndroid Build Coastguard Worker { 132*333d2b36SAndroid Build Coastguard Worker Class: "EXECUTABLES", 133*333d2b36SAndroid Build Coastguard Worker OutputFile: android.OptionalPathForPath(g.outputFile), 134*333d2b36SAndroid Build Coastguard Worker Include: "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", 135*333d2b36SAndroid Build Coastguard Worker }, 136*333d2b36SAndroid Build Coastguard Worker } 137*333d2b36SAndroid Build Coastguard Worker} 138