• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2020 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 cc
16
17import (
18	"path/filepath"
19
20	"android/soong/android"
21
22	"github.com/google/blueprint"
23)
24
25func init() {
26	android.RegisterSdkMemberType(ccBinarySdkMemberType)
27}
28
29var ccBinarySdkMemberType = &binarySdkMemberType{
30	SdkMemberTypeBase: android.SdkMemberTypeBase{
31		PropertyName: "native_binaries",
32	},
33}
34
35type binarySdkMemberType struct {
36	android.SdkMemberTypeBase
37}
38
39func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
40	targets := mctx.MultiTargets()
41	for _, lib := range names {
42		for _, target := range targets {
43			name, version := StubsLibNameAndVersion(lib)
44			if version == "" {
45				version = LatestStubsVersionFor(mctx.Config(), name)
46			}
47			mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
48				{Mutator: "version", Variation: version},
49			}...), dependencyTag, name)
50		}
51	}
52}
53
54func (mt *binarySdkMemberType) IsInstance(module android.Module) bool {
55	// Check the module to see if it can be used with this module type.
56	if m, ok := module.(*Module); ok {
57		for _, allowableMemberType := range m.sdkMemberTypes {
58			if allowableMemberType == mt {
59				return true
60			}
61		}
62	}
63
64	return false
65}
66
67func (mt *binarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
68	return ctx.SnapshotBuilder().AddPrebuiltModule(member, "cc_prebuilt_binary")
69}
70
71func (mt *binarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
72	return &nativeBinaryInfoProperties{}
73}
74
75const (
76	nativeBinaryDir = "bin"
77)
78
79// path to the native binary. Relative to <sdk_root>/<api_dir>
80func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string {
81	return filepath.Join(lib.OsPrefix(), lib.archType,
82		nativeBinaryDir, lib.outputFile.Base())
83}
84
85// nativeBinaryInfoProperties represents properties of a native binary
86//
87// The exported (capitalized) fields will be examined and may be changed during common value extraction.
88// The unexported fields will be left untouched.
89type nativeBinaryInfoProperties struct {
90	android.SdkMemberPropertiesBase
91
92	// archType is not exported as if set (to a non default value) it is always arch specific.
93	// This is "" for common properties.
94	archType string
95
96	// outputFile is not exported as it is always arch specific.
97	outputFile android.Path
98
99	// The set of shared libraries
100	//
101	// This field is exported as its contents may not be arch specific.
102	SharedLibs []string
103
104	// The set of system shared libraries
105	//
106	// This field is exported as its contents may not be arch specific.
107	SystemSharedLibs []string
108}
109
110func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
111	ccModule := variant.(*Module)
112
113	p.archType = ccModule.Target().Arch.ArchType.String()
114	p.outputFile = getRequiredMemberOutputFile(ctx, ccModule)
115
116	if ccModule.linker != nil {
117		specifiedDeps := specifiedDeps{}
118		specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps)
119
120		p.SharedLibs = specifiedDeps.sharedLibs
121		p.SystemSharedLibs = specifiedDeps.systemSharedLibs
122	}
123}
124
125func (p *nativeBinaryInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
126	if p.Compile_multilib != "" {
127		propertySet.AddProperty("compile_multilib", p.Compile_multilib)
128	}
129
130	builder := ctx.SnapshotBuilder()
131	if p.outputFile != nil {
132		propertySet.AddProperty("srcs", []string{nativeBinaryPathFor(*p)})
133
134		builder.CopyToSnapshot(p.outputFile, nativeBinaryPathFor(*p))
135	}
136
137	if len(p.SharedLibs) > 0 {
138		propertySet.AddPropertyWithTag("shared_libs", p.SharedLibs, builder.SdkMemberReferencePropertyTag(false))
139	}
140
141	// SystemSharedLibs needs to be propagated if it's a list, even if it's empty,
142	// so check for non-nil instead of nonzero length.
143	if p.SystemSharedLibs != nil {
144		propertySet.AddPropertyWithTag("system_shared_libs", p.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false))
145	}
146}
147