diff --git a/module_ctx.go b/module_ctx.go index a43deed..ed03789 100644 --- a/module_ctx.go +++ b/module_ctx.go @@ -139,6 +139,14 @@ type EarlyModuleContext interface { // Context.RegisterModuleType(). ModuleType() string + // ModuleTags returns the tags for this module that should be passed to + // ninja for analysis. For example: + // [ + // "module_name": "libfoo", + // "module_type": "cc_library", + // ] + ModuleTags() map[string]string + // BlueprintsFile returns the name of the blueprint file that contains the definition of this // module. BlueprintsFile() string @@ -406,6 +414,13 @@ func (d *baseModuleContext) ModuleType() string { return d.module.typeName } +func (d *baseModuleContext) ModuleTags() map[string]string { + return map[string]string{ + "module_name": d.ModuleName(), + "module_type": d.ModuleType(), + } +} + func (d *baseModuleContext) ContainsProperty(name string) bool { _, ok := d.module.propertyPos[name] return ok @@ -796,7 +811,7 @@ func (m *moduleContext) Rule(pctx PackageContext, name string, func (m *moduleContext) Build(pctx PackageContext, params BuildParams) { m.scope.ReparentTo(pctx) - def, err := parseBuildParams(m.scope, ¶ms) + def, err := parseBuildParams(m.scope, ¶ms, m.ModuleTags()) if err != nil { panic(err) } diff --git a/ninja_defs.go b/ninja_defs.go index 4915fdf..482c80c 100644 --- a/ninja_defs.go +++ b/ninja_defs.go @@ -275,8 +275,25 @@ type buildDef struct { Optional bool } -func parseBuildParams(scope scope, params *BuildParams) (*buildDef, - error) { +func formatTags(tags map[string]string, rule Rule) string { + // Maps in golang do not have a guaranteed iteration order, nor is there an + // ordered map type in the stdlib, but we need to deterministically generate + // the ninja file. + keys := make([]string, 0, len(tags)) + for k := range tags { + keys = append(keys, k) + } + sort.Strings(keys) + pairs := make([]string, 0, len(keys)) + for _, k := range keys { + pairs = append(pairs, k+"="+tags[k]) + } + pairs = append(pairs, "rule_name="+rule.name()) + return strings.Join(pairs, ";") +} + +func parseBuildParams(scope scope, params *BuildParams, + tags map[string]string) (*buildDef, error) { comment := params.Comment rule := params.Rule @@ -360,6 +377,10 @@ func parseBuildParams(scope scope, params *BuildParams) (*buildDef, simpleNinjaString(strings.Join(params.SymlinkOutputs, " "))) } + if len(tags) > 0 { + setVariable("tags", simpleNinjaString(formatTags(tags, rule))) + } + argNameScope := rule.scope() if len(params.Args) > 0 { diff --git a/ninja_strings.go b/ninja_strings.go index c3b070e..0e565e2 100644 --- a/ninja_strings.go +++ b/ninja_strings.go @@ -394,6 +394,10 @@ func validateArgName(argName string) error { return fmt.Errorf("%q contains a '.' character", argName) } + if argName == "tags" { + return fmt.Errorf("\"tags\" is a reserved argument name") + } + for _, builtin := range builtinRuleArgs { if argName == builtin { return fmt.Errorf("%q conflicts with Ninja built-in", argName) diff --git a/singleton_ctx.go b/singleton_ctx.go index d579b8e..95c29c4 100644 --- a/singleton_ctx.go +++ b/singleton_ctx.go @@ -265,7 +265,10 @@ func (s *singletonContext) Rule(pctx PackageContext, name string, func (s *singletonContext) Build(pctx PackageContext, params BuildParams) { s.scope.ReparentTo(pctx) - def, err := parseBuildParams(s.scope, ¶ms) + def, err := parseBuildParams(s.scope, ¶ms, map[string]string{ + "module_name": s.name, + "module_type": "singleton", + }) if err != nil { panic(err) }