blob: 8aa696bf1b43a764bd5b31cda921314fe9ea243e [file] [log] [blame]
Joe Onorato37f900c2023-07-18 16:58:16 -07001// Copyright 2023 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 aconfig
16
17import (
18 "android/soong/android"
Yu Liu855cfc22023-09-14 15:10:03 -070019 "android/soong/bazel"
Joe Onorato37f900c2023-07-18 16:58:16 -070020 "android/soong/cc"
Dennis Shenc5e39f52023-09-14 18:52:49 +000021
Joe Onorato37f900c2023-07-18 16:58:16 -070022 "github.com/google/blueprint"
Dennis Shenc5e39f52023-09-14 18:52:49 +000023 "github.com/google/blueprint/proptools"
Joe Onorato37f900c2023-07-18 16:58:16 -070024
25 "fmt"
26 "strings"
27)
28
29type ccDeclarationsTagType struct {
30 blueprint.BaseDependencyTag
31}
32
33var ccDeclarationsTag = ccDeclarationsTagType{}
34
Yu Liu855cfc22023-09-14 15:10:03 -070035const baseLibDep = "server_configurable_flags"
36
Joe Onorato37f900c2023-07-18 16:58:16 -070037type CcAconfigLibraryProperties struct {
38 // name of the aconfig_declarations module to generate a library for
39 Aconfig_declarations string
Dennis Shenc5e39f52023-09-14 18:52:49 +000040
41 // whether to generate test mode version of the library
Zi Wang275f6542023-11-09 14:59:31 -080042 // TODO: remove "Test" property when "Mode" can be used in all the branches
Dennis Shenc5e39f52023-09-14 18:52:49 +000043 Test *bool
Zi Wang275f6542023-11-09 14:59:31 -080044
45 // default mode is "production", the other accepted modes are:
46 // "test": to generate test mode version of the library
47 // "exported": to generate exported mode version of the library
48 // an error will be thrown if the mode is not supported
49 Mode *string
Joe Onorato37f900c2023-07-18 16:58:16 -070050}
51
52type CcAconfigLibraryCallbacks struct {
53 properties *CcAconfigLibraryProperties
54
55 generatedDir android.WritablePath
56 headerDir android.WritablePath
57 generatedCpp android.WritablePath
58 generatedH android.WritablePath
59}
60
61func CcAconfigLibraryFactory() android.Module {
62 callbacks := &CcAconfigLibraryCallbacks{
63 properties: &CcAconfigLibraryProperties{},
64 }
65 return cc.GeneratedCcLibraryModuleFactory("cc_aconfig_library", callbacks)
66}
67
68func (this *CcAconfigLibraryCallbacks) GeneratorInit(ctx cc.BaseModuleContext) {
69}
70
71func (this *CcAconfigLibraryCallbacks) GeneratorProps() []interface{} {
72 return []interface{}{this.properties}
73}
74
75func (this *CcAconfigLibraryCallbacks) GeneratorDeps(ctx cc.DepsContext, deps cc.Deps) cc.Deps {
76 // Add a dependency for the declarations module
77 declarations := this.properties.Aconfig_declarations
78 if len(declarations) == 0 {
79 ctx.PropertyErrorf("aconfig_declarations", "aconfig_declarations property required")
80 } else {
81 ctx.AddDependency(ctx.Module(), ccDeclarationsTag, declarations)
82 }
83
84 // Add a dependency for the aconfig flags base library
Yu Liu855cfc22023-09-14 15:10:03 -070085 deps.SharedLibs = append(deps.SharedLibs, baseLibDep)
Joe Onorato37f900c2023-07-18 16:58:16 -070086 // TODO: It'd be really nice if we could reexport this library and not make everyone do it.
87
88 return deps
89}
90
91func (this *CcAconfigLibraryCallbacks) GeneratorSources(ctx cc.ModuleContext) cc.GeneratedSource {
92 result := cc.GeneratedSource{}
93
94 // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
95 declarationsModules := ctx.GetDirectDepsWithTag(ccDeclarationsTag)
96 if len(declarationsModules) != 1 {
97 panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
98 }
99 declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
100
101 // Figure out the generated file paths. This has to match aconfig's codegen_cpp.rs.
102 this.generatedDir = android.PathForModuleGen(ctx)
103
104 this.headerDir = android.PathForModuleGen(ctx, "include")
105 result.IncludeDirs = []android.Path{this.headerDir}
106 result.ReexportedDirs = []android.Path{this.headerDir}
107
108 basename := strings.ReplaceAll(declarations.Package, ".", "_")
109
110 this.generatedCpp = android.PathForModuleGen(ctx, basename+".cc")
111 result.Sources = []android.Path{this.generatedCpp}
112
113 this.generatedH = android.PathForModuleGen(ctx, "include", basename+".h")
114 result.Headers = []android.Path{this.generatedH}
115
116 return result
117}
118
119func (this *CcAconfigLibraryCallbacks) GeneratorFlags(ctx cc.ModuleContext, flags cc.Flags, deps cc.PathDeps) cc.Flags {
120 return flags
121}
122
123func (this *CcAconfigLibraryCallbacks) GeneratorBuildActions(ctx cc.ModuleContext, flags cc.Flags, deps cc.PathDeps) {
124 // Get the values that came from the global RELEASE_ACONFIG_VALUE_SETS flag
125 declarationsModules := ctx.GetDirectDepsWithTag(ccDeclarationsTag)
126 if len(declarationsModules) != 1 {
127 panic(fmt.Errorf("Exactly one aconfig_declarations property required"))
128 }
129 declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
130
Zi Wang275f6542023-11-09 14:59:31 -0800131 if this.properties.Mode != nil && this.properties.Test != nil {
132 ctx.PropertyErrorf("test", "test prop should not be specified when mode prop is set")
133 }
134 mode := proptools.StringDefault(this.properties.Mode, "production")
135 if !isModeSupported(mode) {
136 ctx.PropertyErrorf("mode", "%q is not a supported mode", mode)
137 }
138 // TODO: remove "Test" property
Dennis Shenc5e39f52023-09-14 18:52:49 +0000139 if proptools.Bool(this.properties.Test) {
140 mode = "test"
Dennis Shenc5e39f52023-09-14 18:52:49 +0000141 }
Joe Onorato37f900c2023-07-18 16:58:16 -0700142 ctx.Build(pctx, android.BuildParams{
143 Rule: cppRule,
144 Input: declarations.IntermediatePath,
145 Outputs: []android.WritablePath{
146 this.generatedCpp,
147 this.generatedH,
148 },
149 Description: "cc_aconfig_library",
150 Args: map[string]string{
151 "gendir": this.generatedDir.String(),
Dennis Shenc5e39f52023-09-14 18:52:49 +0000152 "mode": mode,
Joe Onorato37f900c2023-07-18 16:58:16 -0700153 },
154 })
155}
Yu Liu855cfc22023-09-14 15:10:03 -0700156
157type bazelCcAconfigLibraryAttributes struct {
Yu Liuf11b7c32023-10-20 19:15:51 +0000158 cc.SdkAttributes
Yu Liu855cfc22023-09-14 15:10:03 -0700159 Aconfig_declarations bazel.LabelAttribute
160 Dynamic_deps bazel.LabelListAttribute
161}
162
163// Convert the cc_aconfig_library module to bazel.
164//
165// This method is called from cc.ConvertWithBp2build to actually convert the
166// cc_aconfig_library module. This is necessary since the factory method of this
167// module type returns a cc library and the bp2build conversion is called on the
168// cc library type.
169
Yu Liuf11b7c32023-10-20 19:15:51 +0000170func (this *CcAconfigLibraryCallbacks) GeneratorBp2build(ctx android.Bp2buildMutatorContext, module *cc.Module) bool {
Yu Liu855cfc22023-09-14 15:10:03 -0700171 if ctx.ModuleType() != "cc_aconfig_library" {
172 return false
173 }
174
175 attrs := bazelCcAconfigLibraryAttributes{
Yu Liuf11b7c32023-10-20 19:15:51 +0000176 SdkAttributes: cc.Bp2BuildParseSdkAttributes(module),
Yu Liu855cfc22023-09-14 15:10:03 -0700177 Aconfig_declarations: *bazel.MakeLabelAttribute(android.BazelLabelForModuleDepSingle(ctx, this.properties.Aconfig_declarations).Label),
178 Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, []string{baseLibDep})),
179 }
180 props := bazel.BazelTargetModuleProperties{
181 Rule_class: "cc_aconfig_library",
182 Bzl_load_location: "//build/bazel/rules/cc:cc_aconfig_library.bzl",
183 }
184
Yu Liuf11b7c32023-10-20 19:15:51 +0000185 ctx.CreateBazelTargetModule(
186 props,
187 android.CommonAttributes{
188 Name: ctx.ModuleName(),
189 Tags: android.ApexAvailableTagsWithoutTestApexes(ctx, module),
190 },
191 &attrs)
Yu Liu855cfc22023-09-14 15:10:03 -0700192 return true
193}