blob: 66faa20accc4150c48f624cd90a15d626fc529da [file] [log] [blame]
Colin Cross38f794e2017-09-07 10:53:07 -07001// Copyright 2017 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
15package android
16
Colin Cross19878da2019-03-28 14:45:07 -070017import (
18 "strings"
Yu Liu2d136142022-08-18 14:46:13 -070019
Colin Crossfe17f6f2019-03-28 19:30:56 -070020 "github.com/google/blueprint"
Colin Cross19878da2019-03-28 14:45:07 -070021 "github.com/google/blueprint/proptools"
22)
23
Liz Kammer12615db2021-09-28 09:19:17 -040024const (
25 canonicalPathFromRootDefault = true
26)
27
Colin Cross38f794e2017-09-07 10:53:07 -070028// TODO(ccross): protos are often used to communicate between multiple modules. If the only
29// way to convert a proto to source is to reference it as a source file, and external modules cannot
30// reference source files in other modules, then every module that owns a proto file will need to
31// export a library for every type of external user (lite vs. full, c vs. c++ vs. java). It would
32// be better to support a proto module type that exported a proto file along with some include dirs,
33// and then external modules could depend on the proto module but use their own settings to
34// generate the source.
35
Colin Cross19878da2019-03-28 14:45:07 -070036type ProtoFlags struct {
37 Flags []string
38 CanonicalPathFromRoot bool
39 Dir ModuleGenPath
40 SubDir ModuleGenPath
41 OutTypeFlag string
42 OutParams []string
Colin Crossfe17f6f2019-03-28 19:30:56 -070043 Deps Paths
44}
45
46type protoDependencyTag struct {
47 blueprint.BaseDependencyTag
48 name string
49}
50
51var ProtoPluginDepTag = protoDependencyTag{name: "plugin"}
52
53func ProtoDeps(ctx BottomUpMutatorContext, p *ProtoProperties) {
54 if String(p.Proto.Plugin) != "" && String(p.Proto.Type) != "" {
55 ctx.ModuleErrorf("only one of proto.type and proto.plugin can be specified.")
56 }
57
58 if plugin := String(p.Proto.Plugin); plugin != "" {
Colin Cross0f7d2ef2019-10-16 11:03:10 -070059 ctx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(),
60 ProtoPluginDepTag, "protoc-gen-"+plugin)
Colin Crossfe17f6f2019-03-28 19:30:56 -070061 }
Colin Cross19878da2019-03-28 14:45:07 -070062}
Colin Crossa3b25002017-12-15 13:41:30 -080063
Colin Cross19878da2019-03-28 14:45:07 -070064func GetProtoFlags(ctx ModuleContext, p *ProtoProperties) ProtoFlags {
Colin Crossfe17f6f2019-03-28 19:30:56 -070065 var flags []string
66 var deps Paths
67
Colin Cross38f794e2017-09-07 10:53:07 -070068 if len(p.Proto.Local_include_dirs) > 0 {
69 localProtoIncludeDirs := PathsForModuleSrc(ctx, p.Proto.Local_include_dirs)
Colin Crossfe17f6f2019-03-28 19:30:56 -070070 flags = append(flags, JoinWithPrefix(localProtoIncludeDirs.Strings(), "-I"))
Colin Cross38f794e2017-09-07 10:53:07 -070071 }
72 if len(p.Proto.Include_dirs) > 0 {
73 rootProtoIncludeDirs := PathsForSource(ctx, p.Proto.Include_dirs)
Colin Crossfe17f6f2019-03-28 19:30:56 -070074 flags = append(flags, JoinWithPrefix(rootProtoIncludeDirs.Strings(), "-I"))
75 }
76
Yu Liud2a95952024-10-10 00:15:26 +000077 ctx.VisitDirectDepsProxyWithTag(ProtoPluginDepTag, func(dep ModuleProxy) {
78 if h, ok := OtherModuleProvider(ctx, dep, HostToolProviderKey); !ok || !h.HostToolPath.Valid() {
Colin Crossfe17f6f2019-03-28 19:30:56 -070079 ctx.PropertyErrorf("proto.plugin", "module %q is not a host tool provider",
80 ctx.OtherModuleName(dep))
81 } else {
82 plugin := String(p.Proto.Plugin)
Yu Liud2a95952024-10-10 00:15:26 +000083 deps = append(deps, h.HostToolPath.Path())
84 flags = append(flags, "--plugin=protoc-gen-"+plugin+"="+h.HostToolPath.String())
Colin Crossfe17f6f2019-03-28 19:30:56 -070085 }
86 })
87
88 var protoOutFlag string
89 if plugin := String(p.Proto.Plugin); plugin != "" {
90 protoOutFlag = "--" + plugin + "_out"
Colin Cross38f794e2017-09-07 10:53:07 -070091 }
92
Colin Cross19878da2019-03-28 14:45:07 -070093 return ProtoFlags{
Colin Crossfe17f6f2019-03-28 19:30:56 -070094 Flags: flags,
95 Deps: deps,
96 OutTypeFlag: protoOutFlag,
Liz Kammer12615db2021-09-28 09:19:17 -040097 CanonicalPathFromRoot: proptools.BoolDefault(p.Proto.Canonical_path_from_root, canonicalPathFromRootDefault),
Colin Cross19878da2019-03-28 14:45:07 -070098 Dir: PathForModuleGen(ctx, "proto"),
99 SubDir: PathForModuleGen(ctx, "proto", ctx.ModuleDir()),
Dan Willemsenab9f4262018-02-14 13:58:34 -0800100 }
Colin Cross38f794e2017-09-07 10:53:07 -0700101}
102
103type ProtoProperties struct {
104 Proto struct {
105 // Proto generator type. C++: full or lite. Java: micro, nano, stream, or lite.
106 Type *string `android:"arch_variant"`
107
Colin Crossfe17f6f2019-03-28 19:30:56 -0700108 // Proto plugin to use as the generator. Must be a cc_binary_host module.
109 Plugin *string `android:"arch_variant"`
110
Colin Cross38f794e2017-09-07 10:53:07 -0700111 // list of directories that will be added to the protoc include paths.
112 Include_dirs []string
113
114 // list of directories relative to the bp file that will
115 // be added to the protoc include paths.
116 Local_include_dirs []string
Dan Willemsenab9f4262018-02-14 13:58:34 -0800117
118 // whether to identify the proto files from the root of the
119 // source tree (the original method in Android, useful for
120 // android-specific protos), or relative from where they were
121 // specified (useful for external/third party protos).
122 //
123 // This defaults to true today, but is expected to default to
124 // false in the future.
125 Canonical_path_from_root *bool
Colin Cross38f794e2017-09-07 10:53:07 -0700126 } `android:"arch_variant"`
127}
Colin Cross19878da2019-03-28 14:45:07 -0700128
Colin Crossf1a035e2020-11-16 17:32:30 -0800129func ProtoRule(rule *RuleBuilder, protoFile Path, flags ProtoFlags, deps Paths,
Colin Cross19878da2019-03-28 14:45:07 -0700130 outDir WritablePath, depFile WritablePath, outputs WritablePaths) {
131
132 var protoBase string
133 if flags.CanonicalPathFromRoot {
134 protoBase = "."
135 } else {
136 rel := protoFile.Rel()
137 protoBase = strings.TrimSuffix(protoFile.String(), rel)
138 }
139
140 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800141 BuiltTool("aprotoc").
Colin Cross19878da2019-03-28 14:45:07 -0700142 FlagWithArg(flags.OutTypeFlag+"=", strings.Join(flags.OutParams, ",")+":"+outDir.String()).
143 FlagWithDepFile("--dependency_out=", depFile).
144 FlagWithArg("-I ", protoBase).
145 Flags(flags.Flags).
146 Input(protoFile).
147 Implicits(deps).
148 ImplicitOutputs(outputs)
149
150 rule.Command().
Colin Crossf1a035e2020-11-16 17:32:30 -0800151 BuiltTool("dep_fixer").Flag(depFile.String())
Colin Cross19878da2019-03-28 14:45:07 -0700152}