• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 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 xml
16
17import (
18	"android/soong/android"
19
20	"github.com/google/blueprint"
21	"github.com/google/blueprint/proptools"
22)
23
24// prebuilt_etc_xml installs an xml file under <partition>/etc/<subdir>.
25// It also optionally validates the xml file against the schema.
26
27var (
28	pctx = android.NewPackageContext("android/soong/xml")
29
30	xmllintDtd = pctx.AndroidStaticRule("xmllint-dtd",
31		blueprint.RuleParams{
32			Command:     `$XmlLintCmd --dtdvalid $dtd $in > /dev/null && touch -a $out`,
33			CommandDeps: []string{"$XmlLintCmd"},
34			Restat:      true,
35		},
36		"dtd")
37
38	xmllintXsd = pctx.AndroidStaticRule("xmllint-xsd",
39		blueprint.RuleParams{
40			Command:     `$XmlLintCmd --schema $xsd $in > /dev/null && touch -a $out`,
41			CommandDeps: []string{"$XmlLintCmd"},
42			Restat:      true,
43		},
44		"xsd")
45
46	xmllintMinimal = pctx.AndroidStaticRule("xmllint-minimal",
47		blueprint.RuleParams{
48			Command:     `$XmlLintCmd $in > /dev/null && touch -a $out`,
49			CommandDeps: []string{"$XmlLintCmd"},
50			Restat:      true,
51		})
52)
53
54func init() {
55	android.RegisterModuleType("prebuilt_etc_xml", PrebuiltEtcXmlFactory)
56	pctx.HostBinToolVariable("XmlLintCmd", "xmllint")
57}
58
59type prebuiltEtcXmlProperties struct {
60	// Optional DTD that will be used to validate the xml file.
61	Schema *string `android:"path"`
62}
63
64type prebuiltEtcXml struct {
65	android.PrebuiltEtc
66
67	properties prebuiltEtcXmlProperties
68}
69
70func (p *prebuiltEtcXml) timestampFilePath(ctx android.ModuleContext) android.WritablePath {
71	return android.PathForModuleOut(ctx, p.PrebuiltEtc.SourceFilePath(ctx).Base()+"-timestamp")
72}
73
74func (p *prebuiltEtcXml) DepsMutator(ctx android.BottomUpMutatorContext) {
75	p.PrebuiltEtc.DepsMutator(ctx)
76}
77
78func (p *prebuiltEtcXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
79	p.PrebuiltEtc.GenerateAndroidBuildActions(ctx)
80
81	if p.properties.Schema != nil {
82		schema := android.PathForModuleSrc(ctx, proptools.String(p.properties.Schema))
83
84		switch schema.Ext() {
85		case ".dtd":
86			ctx.Build(pctx, android.BuildParams{
87				Rule:        xmllintDtd,
88				Description: "xmllint-dtd",
89				Input:       p.PrebuiltEtc.SourceFilePath(ctx),
90				Output:      p.timestampFilePath(ctx),
91				Implicit:    schema,
92				Args: map[string]string{
93					"dtd": schema.String(),
94				},
95			})
96			break
97		case ".xsd":
98			ctx.Build(pctx, android.BuildParams{
99				Rule:        xmllintXsd,
100				Description: "xmllint-xsd",
101				Input:       p.PrebuiltEtc.SourceFilePath(ctx),
102				Output:      p.timestampFilePath(ctx),
103				Implicit:    schema,
104				Args: map[string]string{
105					"xsd": schema.String(),
106				},
107			})
108			break
109		default:
110			ctx.PropertyErrorf("schema", "not supported extension: %q", schema.Ext())
111		}
112	} else {
113		// when schema is not specified, just check if the xml is well-formed
114		ctx.Build(pctx, android.BuildParams{
115			Rule:        xmllintMinimal,
116			Description: "xmllint-minimal",
117			Input:       p.PrebuiltEtc.SourceFilePath(ctx),
118			Output:      p.timestampFilePath(ctx),
119		})
120	}
121
122	p.SetAdditionalDependencies([]android.Path{p.timestampFilePath(ctx)})
123}
124
125func PrebuiltEtcXmlFactory() android.Module {
126	module := &prebuiltEtcXml{}
127	module.AddProperties(&module.properties)
128
129	android.InitPrebuiltEtcModule(&module.PrebuiltEtc)
130	// This module is device-only
131	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
132	return module
133}
134