aboutsummaryrefslogtreecommitdiffstats
path: root/android/sdk.go
blob: 52c392f4d92101c6187faddff4065936cfcb3da9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright (C) 2019 The Android Open Source Project
//
// 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 android

import (
	"strings"

	"github.com/google/blueprint/proptools"
)

// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
// built with SDK
type SdkAware interface {
	Module
	sdkBase() *SdkBase
	MakeMemberOf(sdk SdkRef)
	IsInAnySdk() bool
	ContainingSdk() SdkRef
	MemberName() string
	BuildWithSdks(sdks SdkRefs)
	RequiredSdks() SdkRefs
}

// SdkRef refers to a version of an SDK
type SdkRef struct {
	Name    string
	Version string
}

const (
	// currentVersion refers to the in-development version of an SDK
	currentVersion = "current"
)

// IsCurrentVersion determines if the SdkRef is referencing to an in-development version of an SDK
func (s SdkRef) IsCurrentVersion() bool {
	return s.Version == currentVersion
}

// IsCurrentVersionOf determines if the SdkRef is referencing to an in-development version of the
// specified SDK
func (s SdkRef) IsCurrentVersionOf(name string) bool {
	return s.Name == name && s.IsCurrentVersion()
}

// ParseSdkRef parses a `name#version` style string into a corresponding SdkRef struct
func ParseSdkRef(ctx BaseModuleContext, str string, property string) SdkRef {
	tokens := strings.Split(str, "#")
	if len(tokens) < 1 || len(tokens) > 2 {
		ctx.PropertyErrorf(property, "%q does not follow name#version syntax", str)
		return SdkRef{Name: "invalid sdk name", Version: "invalid sdk version"}
	}

	name := tokens[0]

	version := currentVersion // If version is omitted, defaults to "current"
	if len(tokens) == 2 {
		version = tokens[1]
	}

	return SdkRef{Name: name, Version: version}
}

type SdkRefs []SdkRef

func (refs SdkRefs) Contains(s SdkRef) bool {
	for _, r := range refs {
		if r == s {
			return true
		}
	}
	return false
}

type sdkProperties struct {
	// The SDK that this module is a member of. nil if it is not a member of any SDK
	ContainingSdk *SdkRef `blueprint:"mutated"`

	// The list of SDK names and versions that are used to build this module
	RequiredSdks SdkRefs `blueprint:"mutated"`

	// Name of the module that this sdk member is representing
	Sdk_member_name *string
}

// SdkBase is a struct that is expected to be included in module types to implement the SdkAware
// interface. InitSdkAwareModule should be called to initialize this struct.
type SdkBase struct {
	properties sdkProperties
}

func (s *SdkBase) sdkBase() *SdkBase {
	return s
}

// MakeMemberof sets this module to be a member of a specific SDK
func (s *SdkBase) MakeMemberOf(sdk SdkRef) {
	s.properties.ContainingSdk = &sdk
}

// IsInAnySdk returns true if this module is a member of any SDK
func (s *SdkBase) IsInAnySdk() bool {
	return s.properties.ContainingSdk != nil
}

// ContainingSdk returns the SDK that this module is a member of
func (s *SdkBase) ContainingSdk() SdkRef {
	if s.properties.ContainingSdk != nil {
		return *s.properties.ContainingSdk
	}
	return SdkRef{Name: "", Version: currentVersion}
}

// Membername returns the name of the module that this SDK member is overriding
func (s *SdkBase) MemberName() string {
	return proptools.String(s.properties.Sdk_member_name)
}

// BuildWithSdks is used to mark that this module has to be built with the given SDK(s).
func (s *SdkBase) BuildWithSdks(sdks SdkRefs) {
	s.properties.RequiredSdks = sdks
}

// RequiredSdks returns the SDK(s) that this module has to be built with
func (s *SdkBase) RequiredSdks() SdkRefs {
	return s.properties.RequiredSdks
}

// InitSdkAwareModule initializes the SdkBase struct. This must be called by all modules including
// SdkBase.
func InitSdkAwareModule(m SdkAware) {
	base := m.sdkBase()
	m.AddProperties(&base.properties)
}