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