blob: 816e3c7318436cb620dab7c4dab96090548df60c [file] [log] [blame]
Chih-Hung Hsieha5f22ed2019-10-24 20:47:54 -07001// Copyright 2019 The Android Open Source Project
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 rust
16
17import (
18 "path/filepath"
19 "strings"
20
21 "android/soong/android"
22)
23
24// A test module is a binary module with extra --test compiler flag
25// and different default installation directory.
26// In golang, inheriance is written as a component.
27type testBinaryDecorator struct {
28 *binaryDecorator
29}
30
31func NewRustTest(hod android.HostOrDeviceSupported) (*Module, *testBinaryDecorator) {
32 module := newModule(hod, android.MultilibFirst)
33
34 test := &testBinaryDecorator{
35 binaryDecorator: &binaryDecorator{
36 // TODO(chh): set up dir64?
37 baseCompiler: NewBaseCompiler("testcases", ""),
38 },
39 }
40
41 module.compiler = test
42
43 return module, test
44}
45
46func (test *testBinaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
47 flags = test.binaryDecorator.compilerFlags(ctx, flags)
48 flags.RustFlags = append(flags.RustFlags, "--test")
49 return flags
50}
51
52func init() {
53 // Rust tests are binary files built with --test.
54 android.RegisterModuleType("rust_test", RustTestFactory)
55 android.RegisterModuleType("rust_test_host", RustTestHostFactory)
56}
57
58func RustTestFactory() android.Module {
59 module, _ := NewRustTest(android.HostAndDeviceSupported)
60 return module.Init()
61}
62
63func RustTestHostFactory() android.Module {
64 module, _ := NewRustTest(android.HostSupported)
65 return module.Init()
66}
67
68func (test *testBinaryDecorator) testPerSrc() bool {
69 return true
70}
71
72func (test *testBinaryDecorator) srcs() []string {
73 return test.Properties.Srcs
74}
75
76func (test *testBinaryDecorator) setSrc(name, src string) {
77 test.Properties.Srcs = []string{src}
78 test.baseCompiler.Properties.Stem = StringPtr(name)
79}
80
81func (test *testBinaryDecorator) unsetSrc() {
82 test.Properties.Srcs = nil
83 test.baseCompiler.Properties.Stem = StringPtr("")
84}
85
86type testPerSrc interface {
87 testPerSrc() bool
88 srcs() []string
89 setSrc(string, string)
90 unsetSrc()
91}
92
93var _ testPerSrc = (*testBinaryDecorator)(nil)
94
95func TestPerSrcMutator(mctx android.BottomUpMutatorContext) {
96 if m, ok := mctx.Module().(*Module); ok {
97 if test, ok := m.compiler.(testPerSrc); ok {
98 numTests := len(test.srcs())
99 if test.testPerSrc() && numTests > 0 {
100 if duplicate, found := android.CheckDuplicate(test.srcs()); found {
101 mctx.PropertyErrorf("srcs", "found a duplicate entry %q", duplicate)
102 return
103 }
104 testNames := make([]string, numTests)
105 for i, src := range test.srcs() {
106 testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
107 }
108 // TODO(chh): Add an "all tests" variation like cc/test.go?
109 tests := mctx.CreateLocalVariations(testNames...)
110 for i, src := range test.srcs() {
111 tests[i].(*Module).compiler.(testPerSrc).setSrc(testNames[i], src)
112 }
113 }
114 }
115 }
116}