blob: a5b85c8c272a91b4b25845895d7098560ce50350 [file] [log] [blame]
Colin Crossce75d2c2016-10-06 16:12:58 -07001// Copyright 2016 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
17import (
Colin Cross41955e82019-05-29 14:40:35 -070018 "fmt"
Colin Cross0d614dd2016-10-14 15:38:43 -070019 "io/ioutil"
20 "os"
Colin Crossce75d2c2016-10-06 16:12:58 -070021 "testing"
22
23 "github.com/google/blueprint"
24)
25
26var prebuiltsTests = []struct {
27 name string
28 modules string
29 prebuilt bool
30}{
31 {
32 name: "no prebuilt",
33 modules: `
34 source {
35 name: "bar",
36 }`,
37 prebuilt: false,
38 },
39 {
40 name: "no source prebuilt not preferred",
41 modules: `
42 prebuilt {
43 name: "bar",
44 prefer: false,
Jiyong Parkd4671112019-04-19 17:23:04 +090045 srcs: ["prebuilt_file"],
Colin Crossce75d2c2016-10-06 16:12:58 -070046 }`,
47 prebuilt: true,
48 },
49 {
50 name: "no source prebuilt preferred",
51 modules: `
52 prebuilt {
53 name: "bar",
54 prefer: true,
Jiyong Parkd4671112019-04-19 17:23:04 +090055 srcs: ["prebuilt_file"],
Colin Crossce75d2c2016-10-06 16:12:58 -070056 }`,
57 prebuilt: true,
58 },
59 {
60 name: "prebuilt not preferred",
61 modules: `
62 source {
63 name: "bar",
64 }
65
66 prebuilt {
67 name: "bar",
68 prefer: false,
Jiyong Parkd4671112019-04-19 17:23:04 +090069 srcs: ["prebuilt_file"],
Colin Crossce75d2c2016-10-06 16:12:58 -070070 }`,
71 prebuilt: false,
72 },
73 {
74 name: "prebuilt preferred",
75 modules: `
76 source {
77 name: "bar",
78 }
79
80 prebuilt {
81 name: "bar",
82 prefer: true,
Jiyong Parkd4671112019-04-19 17:23:04 +090083 srcs: ["prebuilt_file"],
Colin Crossce75d2c2016-10-06 16:12:58 -070084 }`,
85 prebuilt: true,
86 },
Colin Cross0d614dd2016-10-14 15:38:43 -070087 {
88 name: "prebuilt no file not preferred",
89 modules: `
90 source {
91 name: "bar",
92 }
93
94 prebuilt {
95 name: "bar",
96 prefer: false,
97 }`,
98 prebuilt: false,
99 },
100 {
101 name: "prebuilt no file preferred",
102 modules: `
103 source {
104 name: "bar",
105 }
106
107 prebuilt {
108 name: "bar",
109 prefer: true,
110 }`,
111 prebuilt: false,
112 },
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700113 {
114 name: "prebuilt file from filegroup preferred",
115 modules: `
116 filegroup {
117 name: "fg",
Jiyong Parkd4671112019-04-19 17:23:04 +0900118 srcs: ["prebuilt_file"],
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700119 }
120 prebuilt {
121 name: "bar",
122 prefer: true,
123 srcs: [":fg"],
124 }`,
125 prebuilt: true,
126 },
Colin Crossce75d2c2016-10-06 16:12:58 -0700127}
128
129func TestPrebuilts(t *testing.T) {
Colin Cross0d614dd2016-10-14 15:38:43 -0700130 buildDir, err := ioutil.TempDir("", "soong_prebuilt_test")
131 if err != nil {
132 t.Fatal(err)
133 }
134 defer os.RemoveAll(buildDir)
135
Colin Cross6ccbc912017-10-10 23:07:38 -0700136 config := TestConfig(buildDir, nil)
Colin Cross0d614dd2016-10-14 15:38:43 -0700137
Colin Crossce75d2c2016-10-06 16:12:58 -0700138 for _, test := range prebuiltsTests {
139 t.Run(test.name, func(t *testing.T) {
Colin Crosscec81712017-07-13 14:43:27 -0700140 ctx := NewTestContext()
Colin Cross5ea9bcc2017-07-27 15:41:32 -0700141 ctx.PreArchMutators(RegisterPrebuiltsPreArchMutators)
142 ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
Pirama Arumuga Nainar955dc492018-04-17 14:58:42 -0700143 ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
Colin Cross36242852017-06-23 15:06:31 -0700144 ctx.RegisterModuleType("prebuilt", ModuleFactoryAdaptor(newPrebuiltModule))
145 ctx.RegisterModuleType("source", ModuleFactoryAdaptor(newSourceModule))
Colin Crosscec81712017-07-13 14:43:27 -0700146 ctx.Register()
Colin Crossce75d2c2016-10-06 16:12:58 -0700147 ctx.MockFileSystem(map[string][]byte{
Jiyong Parkd4671112019-04-19 17:23:04 +0900148 "prebuilt_file": nil,
149 "source_file": nil,
Colin Crossce75d2c2016-10-06 16:12:58 -0700150 "Blueprints": []byte(`
151 source {
152 name: "foo",
Jiyong Parkd4671112019-04-19 17:23:04 +0900153 deps: [":bar"],
Colin Crossce75d2c2016-10-06 16:12:58 -0700154 }
155 ` + test.modules),
156 })
157
Colin Crossce75d2c2016-10-06 16:12:58 -0700158 _, errs := ctx.ParseBlueprintsFiles("Blueprints")
Logan Chien42039712018-03-12 16:29:17 +0800159 FailIfErrored(t, errs)
Colin Crossce75d2c2016-10-06 16:12:58 -0700160 _, errs = ctx.PrepareBuildActions(config)
Logan Chien42039712018-03-12 16:29:17 +0800161 FailIfErrored(t, errs)
Colin Crossce75d2c2016-10-06 16:12:58 -0700162
Colin Crosscec81712017-07-13 14:43:27 -0700163 foo := ctx.ModuleForTests("foo", "")
Colin Crossce75d2c2016-10-06 16:12:58 -0700164
Colin Crossc3e7fa62017-03-17 13:14:32 -0700165 var dependsOnSourceModule, dependsOnPrebuiltModule bool
Colin Crosscec81712017-07-13 14:43:27 -0700166 ctx.VisitDirectDeps(foo.Module(), func(m blueprint.Module) {
Colin Crossc3e7fa62017-03-17 13:14:32 -0700167 if _, ok := m.(*sourceModule); ok {
168 dependsOnSourceModule = true
169 }
170 if p, ok := m.(*prebuiltModule); ok {
171 dependsOnPrebuiltModule = true
Colin Cross74d73e22017-08-02 11:05:49 -0700172 if !p.Prebuilt().properties.UsePrebuilt {
Colin Crossc3e7fa62017-03-17 13:14:32 -0700173 t.Errorf("dependency on prebuilt module not marked used")
174 }
175 }
176 })
177
Jiyong Parkd4671112019-04-19 17:23:04 +0900178 deps := foo.Module().(*sourceModule).deps
179 if deps == nil || len(deps) != 1 {
180 t.Errorf("deps does not have single path, but is %v", deps)
181 }
182 var usingSourceFile, usingPrebuiltFile bool
183 if deps[0].String() == "source_file" {
184 usingSourceFile = true
185 }
186 if deps[0].String() == "prebuilt_file" {
187 usingPrebuiltFile = true
188 }
189
Colin Crossce75d2c2016-10-06 16:12:58 -0700190 if test.prebuilt {
Colin Crossc3e7fa62017-03-17 13:14:32 -0700191 if !dependsOnPrebuiltModule {
Colin Crossce75d2c2016-10-06 16:12:58 -0700192 t.Errorf("doesn't depend on prebuilt module")
193 }
Jiyong Parkd4671112019-04-19 17:23:04 +0900194 if !usingPrebuiltFile {
195 t.Errorf("doesn't use prebuilt_file")
196 }
Colin Crossce75d2c2016-10-06 16:12:58 -0700197
Colin Crossc3e7fa62017-03-17 13:14:32 -0700198 if dependsOnSourceModule {
Colin Crossce75d2c2016-10-06 16:12:58 -0700199 t.Errorf("depends on source module")
200 }
Jiyong Parkd4671112019-04-19 17:23:04 +0900201 if usingSourceFile {
202 t.Errorf("using source_file")
203 }
Colin Crossce75d2c2016-10-06 16:12:58 -0700204 } else {
Colin Crossc3e7fa62017-03-17 13:14:32 -0700205 if dependsOnPrebuiltModule {
Colin Crossce75d2c2016-10-06 16:12:58 -0700206 t.Errorf("depends on prebuilt module")
207 }
Jiyong Parkd4671112019-04-19 17:23:04 +0900208 if usingPrebuiltFile {
209 t.Errorf("using prebuilt_file")
210 }
Colin Crossce75d2c2016-10-06 16:12:58 -0700211
Colin Crossc3e7fa62017-03-17 13:14:32 -0700212 if !dependsOnSourceModule {
Jiyong Parkd4671112019-04-19 17:23:04 +0900213 t.Errorf("doesn't depend on source module")
214 }
215 if !usingSourceFile {
216 t.Errorf("doesn't use source_file")
Colin Crossce75d2c2016-10-06 16:12:58 -0700217 }
218 }
219 })
220 }
Colin Crossce75d2c2016-10-06 16:12:58 -0700221}
222
223type prebuiltModule struct {
224 ModuleBase
Colin Cross74d73e22017-08-02 11:05:49 -0700225 prebuilt Prebuilt
226 properties struct {
Colin Cross27b922f2019-03-04 22:35:41 -0800227 Srcs []string `android:"path"`
Colin Cross74d73e22017-08-02 11:05:49 -0700228 }
Jiyong Parkd4671112019-04-19 17:23:04 +0900229 src Path
Colin Crossce75d2c2016-10-06 16:12:58 -0700230}
231
Colin Cross36242852017-06-23 15:06:31 -0700232func newPrebuiltModule() Module {
Colin Crossce75d2c2016-10-06 16:12:58 -0700233 m := &prebuiltModule{}
Colin Cross74d73e22017-08-02 11:05:49 -0700234 m.AddProperties(&m.properties)
235 InitPrebuiltModule(m, &m.properties.Srcs)
Colin Cross36242852017-06-23 15:06:31 -0700236 InitAndroidModule(m)
237 return m
Colin Crossce75d2c2016-10-06 16:12:58 -0700238}
239
240func (p *prebuiltModule) Name() string {
241 return p.prebuilt.Name(p.ModuleBase.Name())
242}
243
Jiyong Parkd4671112019-04-19 17:23:04 +0900244func (p *prebuiltModule) GenerateAndroidBuildActions(ctx ModuleContext) {
245 if len(p.properties.Srcs) >= 1 {
246 p.src = p.prebuilt.SingleSourcePath(ctx)
247 }
Colin Crossce75d2c2016-10-06 16:12:58 -0700248}
249
250func (p *prebuiltModule) Prebuilt() *Prebuilt {
251 return &p.prebuilt
252}
253
Colin Cross41955e82019-05-29 14:40:35 -0700254func (p *prebuiltModule) OutputFiles(tag string) (Paths, error) {
255 switch tag {
256 case "":
257 return Paths{p.src}, nil
258 default:
259 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
260 }
Jiyong Parkd4671112019-04-19 17:23:04 +0900261}
262
Colin Crossce75d2c2016-10-06 16:12:58 -0700263type sourceModule struct {
264 ModuleBase
265 properties struct {
Jiyong Parkd4671112019-04-19 17:23:04 +0900266 Deps []string `android:"path"`
Colin Crossce75d2c2016-10-06 16:12:58 -0700267 }
268 dependsOnSourceModule, dependsOnPrebuiltModule bool
Jiyong Parkd4671112019-04-19 17:23:04 +0900269 deps Paths
270 src Path
Colin Crossce75d2c2016-10-06 16:12:58 -0700271}
272
Colin Cross36242852017-06-23 15:06:31 -0700273func newSourceModule() Module {
Colin Crossce75d2c2016-10-06 16:12:58 -0700274 m := &sourceModule{}
Colin Cross36242852017-06-23 15:06:31 -0700275 m.AddProperties(&m.properties)
276 InitAndroidModule(m)
277 return m
Colin Crossce75d2c2016-10-06 16:12:58 -0700278}
279
280func (s *sourceModule) DepsMutator(ctx BottomUpMutatorContext) {
Jiyong Parkd4671112019-04-19 17:23:04 +0900281 // s.properties.Deps are annotated with android:path, so they are
282 // automatically added to the dependency by pathDeps mutator
Colin Crossce75d2c2016-10-06 16:12:58 -0700283}
284
285func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
Jiyong Parkd4671112019-04-19 17:23:04 +0900286 s.deps = PathsForModuleSrc(ctx, s.properties.Deps)
287 s.src = PathForModuleSrc(ctx, "source_file")
288}
289
290func (s *sourceModule) Srcs() Paths {
291 return Paths{s.src}
Colin Crossce75d2c2016-10-06 16:12:58 -0700292}