xref: /aosp_15_r20/build/soong/android/proto.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 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 android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"strings"
19*333d2b36SAndroid Build Coastguard Worker
20*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
21*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
22*333d2b36SAndroid Build Coastguard Worker)
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Workerconst (
25*333d2b36SAndroid Build Coastguard Worker	canonicalPathFromRootDefault = true
26*333d2b36SAndroid Build Coastguard Worker)
27*333d2b36SAndroid Build Coastguard Worker
28*333d2b36SAndroid Build Coastguard Worker// TODO(ccross): protos are often used to communicate between multiple modules.  If the only
29*333d2b36SAndroid Build Coastguard Worker// way to convert a proto to source is to reference it as a source file, and external modules cannot
30*333d2b36SAndroid Build Coastguard Worker// reference source files in other modules, then every module that owns a proto file will need to
31*333d2b36SAndroid Build Coastguard Worker// export a library for every type of external user (lite vs. full, c vs. c++ vs. java).  It would
32*333d2b36SAndroid Build Coastguard Worker// be better to support a proto module type that exported a proto file along with some include dirs,
33*333d2b36SAndroid Build Coastguard Worker// and then external modules could depend on the proto module but use their own settings to
34*333d2b36SAndroid Build Coastguard Worker// generate the source.
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard Workertype ProtoFlags struct {
37*333d2b36SAndroid Build Coastguard Worker	Flags                 []string
38*333d2b36SAndroid Build Coastguard Worker	CanonicalPathFromRoot bool
39*333d2b36SAndroid Build Coastguard Worker	Dir                   ModuleGenPath
40*333d2b36SAndroid Build Coastguard Worker	SubDir                ModuleGenPath
41*333d2b36SAndroid Build Coastguard Worker	OutTypeFlag           string
42*333d2b36SAndroid Build Coastguard Worker	OutParams             []string
43*333d2b36SAndroid Build Coastguard Worker	Deps                  Paths
44*333d2b36SAndroid Build Coastguard Worker}
45*333d2b36SAndroid Build Coastguard Worker
46*333d2b36SAndroid Build Coastguard Workertype protoDependencyTag struct {
47*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
48*333d2b36SAndroid Build Coastguard Worker	name string
49*333d2b36SAndroid Build Coastguard Worker}
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Workervar ProtoPluginDepTag = protoDependencyTag{name: "plugin"}
52*333d2b36SAndroid Build Coastguard Worker
53*333d2b36SAndroid Build Coastguard Workerfunc ProtoDeps(ctx BottomUpMutatorContext, p *ProtoProperties) {
54*333d2b36SAndroid Build Coastguard Worker	if String(p.Proto.Plugin) != "" && String(p.Proto.Type) != "" {
55*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("only one of proto.type and proto.plugin can be specified.")
56*333d2b36SAndroid Build Coastguard Worker	}
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker	if plugin := String(p.Proto.Plugin); plugin != "" {
59*333d2b36SAndroid Build Coastguard Worker		ctx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(),
60*333d2b36SAndroid Build Coastguard Worker			ProtoPluginDepTag, "protoc-gen-"+plugin)
61*333d2b36SAndroid Build Coastguard Worker	}
62*333d2b36SAndroid Build Coastguard Worker}
63*333d2b36SAndroid Build Coastguard Worker
64*333d2b36SAndroid Build Coastguard Workerfunc GetProtoFlags(ctx ModuleContext, p *ProtoProperties) ProtoFlags {
65*333d2b36SAndroid Build Coastguard Worker	var flags []string
66*333d2b36SAndroid Build Coastguard Worker	var deps Paths
67*333d2b36SAndroid Build Coastguard Worker
68*333d2b36SAndroid Build Coastguard Worker	if len(p.Proto.Local_include_dirs) > 0 {
69*333d2b36SAndroid Build Coastguard Worker		localProtoIncludeDirs := PathsForModuleSrc(ctx, p.Proto.Local_include_dirs)
70*333d2b36SAndroid Build Coastguard Worker		flags = append(flags, JoinWithPrefix(localProtoIncludeDirs.Strings(), "-I"))
71*333d2b36SAndroid Build Coastguard Worker	}
72*333d2b36SAndroid Build Coastguard Worker	if len(p.Proto.Include_dirs) > 0 {
73*333d2b36SAndroid Build Coastguard Worker		rootProtoIncludeDirs := PathsForSource(ctx, p.Proto.Include_dirs)
74*333d2b36SAndroid Build Coastguard Worker		flags = append(flags, JoinWithPrefix(rootProtoIncludeDirs.Strings(), "-I"))
75*333d2b36SAndroid Build Coastguard Worker	}
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsProxyWithTag(ProtoPluginDepTag, func(dep ModuleProxy) {
78*333d2b36SAndroid Build Coastguard Worker		if h, ok := OtherModuleProvider(ctx, dep, HostToolProviderKey); !ok || !h.HostToolPath.Valid() {
79*333d2b36SAndroid Build Coastguard Worker			ctx.PropertyErrorf("proto.plugin", "module %q is not a host tool provider",
80*333d2b36SAndroid Build Coastguard Worker				ctx.OtherModuleName(dep))
81*333d2b36SAndroid Build Coastguard Worker		} else {
82*333d2b36SAndroid Build Coastguard Worker			plugin := String(p.Proto.Plugin)
83*333d2b36SAndroid Build Coastguard Worker			deps = append(deps, h.HostToolPath.Path())
84*333d2b36SAndroid Build Coastguard Worker			flags = append(flags, "--plugin=protoc-gen-"+plugin+"="+h.HostToolPath.String())
85*333d2b36SAndroid Build Coastguard Worker		}
86*333d2b36SAndroid Build Coastguard Worker	})
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard Worker	var protoOutFlag string
89*333d2b36SAndroid Build Coastguard Worker	if plugin := String(p.Proto.Plugin); plugin != "" {
90*333d2b36SAndroid Build Coastguard Worker		protoOutFlag = "--" + plugin + "_out"
91*333d2b36SAndroid Build Coastguard Worker	}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Worker	return ProtoFlags{
94*333d2b36SAndroid Build Coastguard Worker		Flags:                 flags,
95*333d2b36SAndroid Build Coastguard Worker		Deps:                  deps,
96*333d2b36SAndroid Build Coastguard Worker		OutTypeFlag:           protoOutFlag,
97*333d2b36SAndroid Build Coastguard Worker		CanonicalPathFromRoot: proptools.BoolDefault(p.Proto.Canonical_path_from_root, canonicalPathFromRootDefault),
98*333d2b36SAndroid Build Coastguard Worker		Dir:                   PathForModuleGen(ctx, "proto"),
99*333d2b36SAndroid Build Coastguard Worker		SubDir:                PathForModuleGen(ctx, "proto", ctx.ModuleDir()),
100*333d2b36SAndroid Build Coastguard Worker	}
101*333d2b36SAndroid Build Coastguard Worker}
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Workertype ProtoProperties struct {
104*333d2b36SAndroid Build Coastguard Worker	Proto struct {
105*333d2b36SAndroid Build Coastguard Worker		// Proto generator type.  C++: full or lite.  Java: micro, nano, stream, or lite.
106*333d2b36SAndroid Build Coastguard Worker		Type *string `android:"arch_variant"`
107*333d2b36SAndroid Build Coastguard Worker
108*333d2b36SAndroid Build Coastguard Worker		// Proto plugin to use as the generator.  Must be a cc_binary_host module.
109*333d2b36SAndroid Build Coastguard Worker		Plugin *string `android:"arch_variant"`
110*333d2b36SAndroid Build Coastguard Worker
111*333d2b36SAndroid Build Coastguard Worker		// list of directories that will be added to the protoc include paths.
112*333d2b36SAndroid Build Coastguard Worker		Include_dirs []string
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Worker		// list of directories relative to the bp file that will
115*333d2b36SAndroid Build Coastguard Worker		// be added to the protoc include paths.
116*333d2b36SAndroid Build Coastguard Worker		Local_include_dirs []string
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Worker		// whether to identify the proto files from the root of the
119*333d2b36SAndroid Build Coastguard Worker		// source tree (the original method in Android, useful for
120*333d2b36SAndroid Build Coastguard Worker		// android-specific protos), or relative from where they were
121*333d2b36SAndroid Build Coastguard Worker		// specified (useful for external/third party protos).
122*333d2b36SAndroid Build Coastguard Worker		//
123*333d2b36SAndroid Build Coastguard Worker		// This defaults to true today, but is expected to default to
124*333d2b36SAndroid Build Coastguard Worker		// false in the future.
125*333d2b36SAndroid Build Coastguard Worker		Canonical_path_from_root *bool
126*333d2b36SAndroid Build Coastguard Worker	} `android:"arch_variant"`
127*333d2b36SAndroid Build Coastguard Worker}
128*333d2b36SAndroid Build Coastguard Worker
129*333d2b36SAndroid Build Coastguard Workerfunc ProtoRule(rule *RuleBuilder, protoFile Path, flags ProtoFlags, deps Paths,
130*333d2b36SAndroid Build Coastguard Worker	outDir WritablePath, depFile WritablePath, outputs WritablePaths) {
131*333d2b36SAndroid Build Coastguard Worker
132*333d2b36SAndroid Build Coastguard Worker	var protoBase string
133*333d2b36SAndroid Build Coastguard Worker	if flags.CanonicalPathFromRoot {
134*333d2b36SAndroid Build Coastguard Worker		protoBase = "."
135*333d2b36SAndroid Build Coastguard Worker	} else {
136*333d2b36SAndroid Build Coastguard Worker		rel := protoFile.Rel()
137*333d2b36SAndroid Build Coastguard Worker		protoBase = strings.TrimSuffix(protoFile.String(), rel)
138*333d2b36SAndroid Build Coastguard Worker	}
139*333d2b36SAndroid Build Coastguard Worker
140*333d2b36SAndroid Build Coastguard Worker	rule.Command().
141*333d2b36SAndroid Build Coastguard Worker		BuiltTool("aprotoc").
142*333d2b36SAndroid Build Coastguard Worker		FlagWithArg(flags.OutTypeFlag+"=", strings.Join(flags.OutParams, ",")+":"+outDir.String()).
143*333d2b36SAndroid Build Coastguard Worker		FlagWithDepFile("--dependency_out=", depFile).
144*333d2b36SAndroid Build Coastguard Worker		FlagWithArg("-I ", protoBase).
145*333d2b36SAndroid Build Coastguard Worker		Flags(flags.Flags).
146*333d2b36SAndroid Build Coastguard Worker		Input(protoFile).
147*333d2b36SAndroid Build Coastguard Worker		Implicits(deps).
148*333d2b36SAndroid Build Coastguard Worker		ImplicitOutputs(outputs)
149*333d2b36SAndroid Build Coastguard Worker
150*333d2b36SAndroid Build Coastguard Worker	rule.Command().
151*333d2b36SAndroid Build Coastguard Worker		BuiltTool("dep_fixer").Flag(depFile.String())
152*333d2b36SAndroid Build Coastguard Worker}
153