123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- // Copyright 2015 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 cc
- import (
- "path/filepath"
- "strings"
- "android/soong/bazel"
- "github.com/google/blueprint"
- "android/soong/android"
- )
- func init() {
- pctx.SourcePathVariable("lexCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/flex")
- pctx.SourcePathVariable("m4Cmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/m4")
- pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
- pctx.HostBinToolVariable("syspropCmd", "sysprop_cpp")
- }
- var (
- lex = pctx.AndroidStaticRule("lex",
- blueprint.RuleParams{
- Command: "M4=$m4Cmd $lexCmd $flags -o$out $in",
- CommandDeps: []string{"$lexCmd", "$m4Cmd"},
- }, "flags")
- sysprop = pctx.AndroidStaticRule("sysprop",
- blueprint.RuleParams{
- Command: "$syspropCmd --header-dir=$headerOutDir --public-header-dir=$publicOutDir " +
- "--source-dir=$srcOutDir --include-name=$includeName $in",
- CommandDeps: []string{"$syspropCmd"},
- },
- "headerOutDir", "publicOutDir", "srcOutDir", "includeName")
- )
- type YaccProperties struct {
- // list of module-specific flags that will be used for .y and .yy compiles
- Flags []string
- // whether the yacc files will produce a location.hh file
- Gen_location_hh *bool
- // whether the yacc files will product a position.hh file
- Gen_position_hh *bool
- }
- func genYacc(ctx android.ModuleContext, rule *android.RuleBuilder, yaccFile android.Path,
- outFile android.ModuleGenPath, props *YaccProperties) (headerFiles android.Paths) {
- outDir := android.PathForModuleGen(ctx, "yacc")
- headerFile := android.GenPathWithExt(ctx, "yacc", yaccFile, "h")
- ret := android.Paths{headerFile}
- cmd := rule.Command()
- // Fix up #line markers to not use the sbox temporary directory
- // android.sboxPathForOutput(outDir, outDir) returns the sbox placeholder for the out
- // directory itself, without any filename appended.
- sboxOutDir := cmd.PathForOutput(outDir)
- sedCmd := "sed -i.bak 's#" + sboxOutDir + "#" + outDir.String() + "#'"
- rule.Command().Text(sedCmd).Input(outFile)
- rule.Command().Text(sedCmd).Input(headerFile)
- var flags []string
- if props != nil {
- flags = props.Flags
- if Bool(props.Gen_location_hh) {
- locationHeader := outFile.InSameDir(ctx, "location.hh")
- ret = append(ret, locationHeader)
- cmd.ImplicitOutput(locationHeader)
- rule.Command().Text(sedCmd).Input(locationHeader)
- }
- if Bool(props.Gen_position_hh) {
- positionHeader := outFile.InSameDir(ctx, "position.hh")
- ret = append(ret, positionHeader)
- cmd.ImplicitOutput(positionHeader)
- rule.Command().Text(sedCmd).Input(positionHeader)
- }
- }
- cmd.Text("BISON_PKGDATADIR=prebuilts/build-tools/common/bison").
- FlagWithInput("M4=", ctx.Config().PrebuiltBuildTool(ctx, "m4")).
- PrebuiltBuildTool(ctx, "bison").
- Flag("-d").
- Flags(flags).
- FlagWithOutput("--defines=", headerFile).
- Flag("-o").Output(outFile).Input(yaccFile)
- return ret
- }
- func genAidl(ctx android.ModuleContext, rule *android.RuleBuilder, aidlFile android.Path, aidlFlags string) (cppFile android.OutputPath, headerFiles android.Paths) {
- aidlPackage := strings.TrimSuffix(aidlFile.Rel(), aidlFile.Base())
- baseName := strings.TrimSuffix(aidlFile.Base(), aidlFile.Ext())
- shortName := baseName
- // TODO(b/111362593): aidl_to_cpp_common.cpp uses heuristics to figure out if
- // an interface name has a leading I. Those same heuristics have been
- // moved here.
- if len(baseName) >= 2 && baseName[0] == 'I' &&
- strings.ToUpper(baseName)[1] == baseName[1] {
- shortName = strings.TrimPrefix(baseName, "I")
- }
- outDir := android.PathForModuleGen(ctx, "aidl")
- cppFile = outDir.Join(ctx, aidlPackage, baseName+".cpp")
- depFile := outDir.Join(ctx, aidlPackage, baseName+".cpp.d")
- headerI := outDir.Join(ctx, aidlPackage, baseName+".h")
- headerBn := outDir.Join(ctx, aidlPackage, "Bn"+shortName+".h")
- headerBp := outDir.Join(ctx, aidlPackage, "Bp"+shortName+".h")
- baseDir := strings.TrimSuffix(aidlFile.String(), aidlFile.Rel())
- if baseDir != "" {
- aidlFlags += " -I" + baseDir
- }
- cmd := rule.Command()
- cmd.BuiltTool("aidl-cpp").
- FlagWithDepFile("-d", depFile).
- Flag("--ninja").
- Flag(aidlFlags).
- Input(aidlFile).
- OutputDir().
- Output(cppFile).
- ImplicitOutputs(android.WritablePaths{
- headerI,
- headerBn,
- headerBp,
- })
- return cppFile, android.Paths{
- headerI,
- headerBn,
- headerBp,
- }
- }
- type LexProperties struct {
- // list of module-specific flags that will be used for .l and .ll compiles
- Flags []string
- }
- func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.ModuleGenPath, props *LexProperties) {
- var flags []string
- if props != nil {
- flags = props.Flags
- }
- flagsString := strings.Join(flags[:], " ")
- ctx.Build(pctx, android.BuildParams{
- Rule: lex,
- Description: "lex " + lexFile.Rel(),
- Output: outFile,
- Input: lexFile,
- Args: map[string]string{"flags": flagsString},
- })
- }
- type LexAttrs struct {
- Srcs bazel.LabelListAttribute
- Lexopts bazel.StringListAttribute
- }
- type LexNames struct {
- cSrcName bazel.LabelAttribute
- srcName bazel.LabelAttribute
- }
- func bp2BuildLex(ctx android.Bp2buildMutatorContext, moduleName string, ca compilerAttributes) LexNames {
- names := LexNames{}
- if !ca.lSrcs.IsEmpty() {
- names.cSrcName = createLexTargetModule(ctx, moduleName+"_genlex_l", ca.lSrcs, ca.lexopts)
- }
- if !ca.llSrcs.IsEmpty() {
- names.srcName = createLexTargetModule(ctx, moduleName+"_genlex_ll", ca.llSrcs, ca.lexopts)
- }
- return names
- }
- func createLexTargetModule(ctx android.Bp2buildMutatorContext, name string, srcs bazel.LabelListAttribute, opts bazel.StringListAttribute) bazel.LabelAttribute {
- ctx.CreateBazelTargetModule(
- bazel.BazelTargetModuleProperties{
- Rule_class: "genlex",
- Bzl_load_location: "//build/bazel/rules/cc:flex.bzl",
- },
- android.CommonAttributes{Name: name},
- &LexAttrs{
- Srcs: srcs,
- Lexopts: opts,
- })
- return bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + name}}
- }
- func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Paths) {
- headerFile := android.PathForModuleGen(ctx, "sysprop", "include", syspropFile.Rel()+".h")
- publicHeaderFile := android.PathForModuleGen(ctx, "sysprop/public", "include", syspropFile.Rel()+".h")
- cppFile := android.PathForModuleGen(ctx, "sysprop", syspropFile.Rel()+".cpp")
- headers := android.WritablePaths{headerFile, publicHeaderFile}
- ctx.Build(pctx, android.BuildParams{
- Rule: sysprop,
- Description: "sysprop " + syspropFile.Rel(),
- Output: cppFile,
- ImplicitOutputs: headers,
- Input: syspropFile,
- Args: map[string]string{
- "headerOutDir": filepath.Dir(headerFile.String()),
- "publicOutDir": filepath.Dir(publicHeaderFile.String()),
- "srcOutDir": filepath.Dir(cppFile.String()),
- "includeName": syspropFile.Rel() + ".h",
- },
- })
- return cppFile, headers.Paths()
- }
- func bp2buildCcSysprop(ctx android.Bp2buildMutatorContext, moduleName string, minSdkVersion *string, srcs bazel.LabelListAttribute) *bazel.LabelAttribute {
- labels := SyspropLibraryLabels{
- SyspropLibraryLabel: moduleName + "_sysprop_library",
- StaticLibraryLabel: moduleName + "_cc_sysprop_library_static",
- }
- Bp2buildSysprop(ctx, labels, srcs, minSdkVersion)
- return createLabelAttributeCorrespondingToSrcs(":"+labels.StaticLibraryLabel, srcs)
- }
- // Creates a LabelAttribute for a given label where the value is only set for
- // the same config values that have values in a given LabelListAttribute
- func createLabelAttributeCorrespondingToSrcs(baseLabelName string, srcs bazel.LabelListAttribute) *bazel.LabelAttribute {
- baseLabel := bazel.Label{Label: baseLabelName}
- label := bazel.LabelAttribute{}
- if !srcs.Value.IsNil() && !srcs.Value.IsEmpty() {
- label.Value = &baseLabel
- return &label
- }
- for axis, configToSrcs := range srcs.ConfigurableValues {
- for config, val := range configToSrcs {
- if !val.IsNil() && !val.IsEmpty() {
- label.SetSelectValue(axis, config, baseLabel)
- }
- }
- }
- return &label
- }
- // Used to communicate information from the genSources method back to the library code that uses
- // it.
- type generatedSourceInfo struct {
- // The headers created from .proto files
- protoHeaders android.Paths
- // The files that can be used as order only dependencies in order to ensure that the proto header
- // files are up to date.
- protoOrderOnlyDeps android.Paths
- // The headers created from .aidl files
- aidlHeaders android.Paths
- // The files that can be used as order only dependencies in order to ensure that the aidl header
- // files are up to date.
- aidlOrderOnlyDeps android.Paths
- // The headers created from .sysprop files
- syspropHeaders android.Paths
- // The files that can be used as order only dependencies in order to ensure that the sysprop
- // header files are up to date.
- syspropOrderOnlyDeps android.Paths
- }
- func genSources(ctx android.ModuleContext, srcFiles android.Paths,
- buildFlags builderFlags) (android.Paths, android.Paths, generatedSourceInfo) {
- var info generatedSourceInfo
- var deps android.Paths
- var rsFiles android.Paths
- var aidlRule *android.RuleBuilder
- var yaccRule_ *android.RuleBuilder
- yaccRule := func() *android.RuleBuilder {
- if yaccRule_ == nil {
- yaccRule_ = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "yacc"),
- android.PathForModuleGen(ctx, "yacc.sbox.textproto"))
- }
- return yaccRule_
- }
- for i, srcFile := range srcFiles {
- switch srcFile.Ext() {
- case ".y":
- cFile := android.GenPathWithExt(ctx, "yacc", srcFile, "c")
- srcFiles[i] = cFile
- deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cFile, buildFlags.yacc)...)
- case ".yy":
- cppFile := android.GenPathWithExt(ctx, "yacc", srcFile, "cpp")
- srcFiles[i] = cppFile
- deps = append(deps, genYacc(ctx, yaccRule(), srcFile, cppFile, buildFlags.yacc)...)
- case ".l":
- cFile := android.GenPathWithExt(ctx, "lex", srcFile, "c")
- srcFiles[i] = cFile
- genLex(ctx, srcFile, cFile, buildFlags.lex)
- case ".ll":
- cppFile := android.GenPathWithExt(ctx, "lex", srcFile, "cpp")
- srcFiles[i] = cppFile
- genLex(ctx, srcFile, cppFile, buildFlags.lex)
- case ".proto":
- ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
- srcFiles[i] = ccFile
- info.protoHeaders = append(info.protoHeaders, headerFile)
- // Use the generated header as an order only dep to ensure that it is up to date when needed.
- info.protoOrderOnlyDeps = append(info.protoOrderOnlyDeps, headerFile)
- case ".aidl":
- if aidlRule == nil {
- aidlRule = android.NewRuleBuilder(pctx, ctx).Sbox(android.PathForModuleGen(ctx, "aidl"),
- android.PathForModuleGen(ctx, "aidl.sbox.textproto"))
- }
- cppFile, aidlHeaders := genAidl(ctx, aidlRule, srcFile, buildFlags.aidlFlags)
- srcFiles[i] = cppFile
- info.aidlHeaders = append(info.aidlHeaders, aidlHeaders...)
- // Use the generated headers as order only deps to ensure that they are up to date when
- // needed.
- // TODO: Reduce the size of the ninja file by using one order only dep for the whole rule
- info.aidlOrderOnlyDeps = append(info.aidlOrderOnlyDeps, aidlHeaders...)
- case ".rscript", ".fs":
- cppFile := rsGeneratedCppFile(ctx, srcFile)
- rsFiles = append(rsFiles, srcFiles[i])
- srcFiles[i] = cppFile
- case ".sysprop":
- cppFile, headerFiles := genSysprop(ctx, srcFile)
- srcFiles[i] = cppFile
- info.syspropHeaders = append(info.syspropHeaders, headerFiles...)
- // Use the generated headers as order only deps to ensure that they are up to date when
- // needed.
- info.syspropOrderOnlyDeps = append(info.syspropOrderOnlyDeps, headerFiles...)
- }
- }
- if aidlRule != nil {
- aidlRule.Build("aidl", "gen aidl")
- }
- if yaccRule_ != nil {
- yaccRule_.Build("yacc", "gen yacc")
- }
- deps = append(deps, info.protoOrderOnlyDeps...)
- deps = append(deps, info.aidlOrderOnlyDeps...)
- deps = append(deps, info.syspropOrderOnlyDeps...)
- if len(rsFiles) > 0 {
- deps = append(deps, rsGenerateCpp(ctx, rsFiles, buildFlags.rsFlags)...)
- }
- return srcFiles, deps, info
- }
|