diff options
Diffstat (limited to 'golang/golang.go')
| -rw-r--r-- | golang/golang.go | 136 | 
1 files changed, 136 insertions, 0 deletions
| diff --git a/golang/golang.go b/golang/golang.go new file mode 100644 index 000000000..618a0852b --- /dev/null +++ b/golang/golang.go @@ -0,0 +1,136 @@ +// Copyright 2024 Google Inc. All rights reserved. +// +// 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 golang wraps the blueprint blueprint_go_binary and bootstrap_go_binary module types in versions +// that implement android.Module that are used when building in Soong.  This simplifies the code in Soong +// so it can always assume modules are an android.Module. +// The original blueprint blueprint_go_binary and bootstrap_go_binary module types are still used during +// bootstrapping, so the Android.bp entries for these module types must be compatible with both the +// original blueprint module types and these wrapped module types. +package golang + +import ( +	"android/soong/android" +	"github.com/google/blueprint" +	"github.com/google/blueprint/bootstrap" +) + +func init() { +	// Wrap the blueprint Go module types with Soong ones that interoperate with the rest of the Soong modules. +	bootstrap.GoModuleTypesAreWrapped() +	RegisterGoModuleTypes(android.InitRegistrationContext) +} + +func RegisterGoModuleTypes(ctx android.RegistrationContext) { +	ctx.RegisterModuleType("bootstrap_go_package", goPackageModuleFactory) +	ctx.RegisterModuleType("blueprint_go_binary", goBinaryModuleFactory) +} + +// A GoPackage is a module for building Go packages. +type GoPackage struct { +	android.ModuleBase +	bootstrap.GoPackage +} + +func goPackageModuleFactory() android.Module { +	module := &GoPackage{} +	module.AddProperties(module.Properties()...) +	android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) +	return module +} + +func (g *GoPackage) GenerateBuildActions(ctx blueprint.ModuleContext) { +	// The embedded ModuleBase and bootstrap.GoPackage each implement GenerateBuildActions, +	// the delegation has to be implemented manually to disambiguate.  Call ModuleBase's +	// GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call +	// bootstrap.GoPackage.GenerateBuildActions. +	g.ModuleBase.GenerateBuildActions(ctx) +} + +func (g *GoPackage) GenerateAndroidBuildActions(ctx android.ModuleContext) { +	g.GoPackage.GenerateBuildActions(ctx.BlueprintModuleContext()) +} + +// A GoBinary is a module for building executable binaries from Go sources. +type GoBinary struct { +	android.ModuleBase +	bootstrap.GoBinary + +	outputFile android.Path +} + +func goBinaryModuleFactory() android.Module { +	module := &GoBinary{} +	module.AddProperties(module.Properties()...) +	android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst) +	return module +} + +func (g *GoBinary) GenerateBuildActions(ctx blueprint.ModuleContext) { +	// The embedded ModuleBase and bootstrap.GoBinary each implement GenerateBuildActions, +	// the delegation has to be implemented manually to disambiguate.  Call ModuleBase's +	// GenerateBuildActions, which will call GenerateAndroidBuildActions, which will call +	// bootstrap.GoBinary.GenerateBuildActions. +	g.ModuleBase.GenerateBuildActions(ctx) +} + +func (g *GoBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { +	// Install the file in Soong instead of blueprint so that Soong knows about the install rules. +	g.GoBinary.SetSkipInstall() + +	// Run the build actions from the wrapped blueprint bootstrap module. +	g.GoBinary.GenerateBuildActions(ctx.BlueprintModuleContext()) + +	// Translate the bootstrap module's string path into a Path +	outputFile := android.PathForArbitraryOutput(ctx, android.Rel(ctx, ctx.Config().OutDir(), g.IntermediateFile())).WithoutRel() +	g.outputFile = outputFile + +	// Don't create install rules for modules used by bootstrap, the install command line will differ from +	// what was used during bootstrap, which will cause ninja to rebuild the module on the next run, +	// triggering reanalysis. +	if !usedByBootstrap(ctx.ModuleName()) { +		installPath := ctx.InstallFile(android.PathForModuleInstall(ctx, "bin"), ctx.ModuleName(), outputFile) + +		// Modules in an unexported namespace have no install rule, only add modules in the exported namespaces +		// to the blueprint_tools phony rules. +		if !ctx.Config().KatiEnabled() || g.ExportedToMake() { +			ctx.Phony("blueprint_tools", installPath) +		} +	} + +	ctx.SetOutputFiles(android.Paths{outputFile}, "") +} + +func usedByBootstrap(name string) bool { +	switch name { +	case "loadplugins", "soong_build": +		return true +	default: +		return false +	} +} + +func (g *GoBinary) HostToolPath() android.OptionalPath { +	return android.OptionalPathForPath(g.outputFile) +} + +func (g *GoBinary) AndroidMkEntries() []android.AndroidMkEntries { +	return []android.AndroidMkEntries{ +		{ +			Class:      "EXECUTABLES", +			OutputFile: android.OptionalPathForPath(g.outputFile), +			Include:    "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk", +		}, +	} +} |