Initial prebuilt support am: ce75d2c6a2
am: 2d9267aa6c
Change-Id: Ibbd81201441f7ada699ec3522d7020b95bf49a3e
This commit is contained in:
commit
6e240412aa
|
@ -72,6 +72,7 @@ bootstrap_go_package {
|
|||
"android/onceper.go",
|
||||
"android/package_ctx.go",
|
||||
"android/paths.go",
|
||||
"android/prebuilt.go",
|
||||
"android/register.go",
|
||||
"android/util.go",
|
||||
"android/variable.go",
|
||||
|
@ -81,6 +82,7 @@ bootstrap_go_package {
|
|||
],
|
||||
testSrcs: [
|
||||
"android/paths_test.go",
|
||||
"android/prebuilt_test.go",
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -126,6 +128,7 @@ bootstrap_go_package {
|
|||
"cc/check.go",
|
||||
"cc/gen.go",
|
||||
"cc/makevars.go",
|
||||
"cc/prebuilt.go",
|
||||
"cc/relocation_packer.go",
|
||||
"cc/sanitize.go",
|
||||
"cc/stl.go",
|
||||
|
|
|
@ -34,6 +34,7 @@ func init() {
|
|||
|
||||
type AndroidMkDataProvider interface {
|
||||
AndroidMk() (AndroidMkData, error)
|
||||
BaseModuleName() string
|
||||
}
|
||||
|
||||
type AndroidMkData struct {
|
||||
|
@ -142,13 +143,12 @@ func translateAndroidMk(ctx blueprint.SingletonContext, mkFile string, mods []Mo
|
|||
}
|
||||
|
||||
func translateAndroidMkModule(ctx blueprint.SingletonContext, w io.Writer, mod blueprint.Module) error {
|
||||
name := ctx.ModuleName(mod)
|
||||
|
||||
provider, ok := mod.(AndroidMkDataProvider)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
name := provider.BaseModuleName()
|
||||
amod := mod.(Module).base()
|
||||
data, err := provider.AndroidMk()
|
||||
if err != nil {
|
||||
|
@ -156,7 +156,11 @@ func translateAndroidMkModule(ctx blueprint.SingletonContext, w io.Writer, mod b
|
|||
}
|
||||
|
||||
if !amod.Enabled() {
|
||||
return err
|
||||
return nil
|
||||
}
|
||||
|
||||
if amod.commonProperties.SkipInstall {
|
||||
return nil
|
||||
}
|
||||
|
||||
if data.SubName != "" {
|
||||
|
|
|
@ -151,6 +151,11 @@ func saveToConfigFile(config jsonConfigurable, filename string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// TestConfig returns a Config object suitable for using for tests
|
||||
func TestConfig() Config {
|
||||
return Config{&config{}}
|
||||
}
|
||||
|
||||
// New creates a new Config object. The srcDir argument specifies the path to
|
||||
// the root source directory. It also loads the config file, if found.
|
||||
func NewConfig(srcDir, buildDir string) (Config, error) {
|
||||
|
|
|
@ -147,6 +147,8 @@ type commonProperties struct {
|
|||
// Set by InitAndroidModule
|
||||
HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"`
|
||||
ArchSpecific bool `blueprint:"mutated"`
|
||||
|
||||
SkipInstall bool `blueprint:"mutated"`
|
||||
}
|
||||
|
||||
type hostAndDeviceProperties struct {
|
||||
|
@ -277,10 +279,17 @@ type ModuleBase struct {
|
|||
hooks hooks
|
||||
}
|
||||
|
||||
// Name returns the name of the module. It may be overridden by individual module types, for
|
||||
// example prebuilts will prepend prebuilt_ to the name.
|
||||
func (a *ModuleBase) Name() string {
|
||||
return a.nameProperties.Name
|
||||
}
|
||||
|
||||
// BaseModuleName returns the name of the module as specified in the blueprints file.
|
||||
func (a *ModuleBase) BaseModuleName() string {
|
||||
return a.nameProperties.Name
|
||||
}
|
||||
|
||||
func (a *ModuleBase) base() *ModuleBase {
|
||||
return a
|
||||
}
|
||||
|
@ -348,6 +357,10 @@ func (a *ModuleBase) Enabled() bool {
|
|||
return *a.commonProperties.Enabled
|
||||
}
|
||||
|
||||
func (a *ModuleBase) SkipInstall() {
|
||||
a.commonProperties.SkipInstall = true
|
||||
}
|
||||
|
||||
func (a *ModuleBase) computeInstallDeps(
|
||||
ctx blueprint.ModuleContext) Paths {
|
||||
|
||||
|
@ -600,7 +613,9 @@ func (a *androidModuleContext) InstallFileName(installPath OutputPath, name stri
|
|||
fullInstallPath := installPath.Join(a, name)
|
||||
a.module.base().hooks.runInstallHooks(a, fullInstallPath, false)
|
||||
|
||||
if a.Host() || !a.AConfig().SkipDeviceInstall() {
|
||||
if !a.module.base().commonProperties.SkipInstall &&
|
||||
(a.Host() || !a.AConfig().SkipDeviceInstall()) {
|
||||
|
||||
deps = append(deps, a.installDeps...)
|
||||
|
||||
var implicitDeps, orderOnlyDeps Paths
|
||||
|
@ -636,7 +651,9 @@ func (a *androidModuleContext) InstallSymlink(installPath OutputPath, name strin
|
|||
fullInstallPath := installPath.Join(a, name)
|
||||
a.module.base().hooks.runInstallHooks(a, fullInstallPath, true)
|
||||
|
||||
if a.Host() || !a.AConfig().SkipDeviceInstall() {
|
||||
if !a.module.base().commonProperties.SkipInstall &&
|
||||
(a.Host() || !a.AConfig().SkipDeviceInstall()) {
|
||||
|
||||
a.ModuleBuild(pctx, ModuleBuildParams{
|
||||
Rule: Symlink,
|
||||
Output: fullInstallPath,
|
||||
|
|
|
@ -33,6 +33,7 @@ func registerMutators() {
|
|||
}
|
||||
|
||||
ctx.TopDown("load_hooks", loadHookMutator).Parallel()
|
||||
ctx.BottomUp("prebuilts", prebuiltMutator).Parallel()
|
||||
ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
|
||||
ctx.TopDown("defaults", defaultsMutator).Parallel()
|
||||
|
||||
|
@ -45,6 +46,9 @@ func registerMutators() {
|
|||
|
||||
ctx.BottomUp("deps", depsMutator).Parallel()
|
||||
|
||||
ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
|
||||
ctx.TopDown("prebuilt_disable", PrebuiltDisableMutator).Parallel()
|
||||
|
||||
register(postDeps)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
//
|
||||
// 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 "github.com/google/blueprint"
|
||||
|
||||
// This file implements common functionality for handling modules that may exist as prebuilts,
|
||||
// source, or both.
|
||||
|
||||
var prebuiltDependencyTag blueprint.BaseDependencyTag
|
||||
|
||||
func SourceModuleHasPrebuilt(ctx ModuleContext) OptionalPath {
|
||||
var path Path
|
||||
ctx.VisitDirectDeps(func(m blueprint.Module) {
|
||||
if ctx.OtherModuleDependencyTag(m) == prebuiltDependencyTag {
|
||||
p := m.(PrebuiltInterface).Prebuilt()
|
||||
if p.usePrebuilt(ctx) {
|
||||
path = p.Path(ctx)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return OptionalPathForPath(path)
|
||||
}
|
||||
|
||||
type Prebuilt struct {
|
||||
Properties struct {
|
||||
Srcs []string `android:"arch_variant"`
|
||||
// When prefer is set to true the prebuilt will be used instead of any source module with
|
||||
// a matching name.
|
||||
Prefer bool `android:"arch_variant"`
|
||||
|
||||
SourceExists bool `blueprint:"mutated"`
|
||||
}
|
||||
module Module
|
||||
}
|
||||
|
||||
func (p *Prebuilt) Name(name string) string {
|
||||
return "prebuilt_" + name
|
||||
}
|
||||
|
||||
func (p *Prebuilt) Path(ctx ModuleContext) Path {
|
||||
if len(p.Properties.Srcs) == 0 {
|
||||
ctx.PropertyErrorf("srcs", "missing prebuilt source file")
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(p.Properties.Srcs) > 1 {
|
||||
ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
|
||||
return nil
|
||||
}
|
||||
|
||||
return PathForModuleSrc(ctx, p.Properties.Srcs[0])
|
||||
}
|
||||
|
||||
type PrebuiltInterface interface {
|
||||
Module
|
||||
Prebuilt() *Prebuilt
|
||||
}
|
||||
|
||||
type PrebuiltSourceInterface interface {
|
||||
SkipInstall()
|
||||
}
|
||||
|
||||
// prebuiltMutator ensures that there is always a module with an undecorated name, and marks
|
||||
// prebuilt modules that have both a prebuilt and a source module.
|
||||
func prebuiltMutator(ctx BottomUpMutatorContext) {
|
||||
if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
|
||||
p := m.Prebuilt()
|
||||
name := m.base().BaseModuleName()
|
||||
if ctx.OtherModuleExists(name) {
|
||||
ctx.AddReverseDependency(ctx.Module(), prebuiltDependencyTag, name)
|
||||
p.Properties.SourceExists = true
|
||||
} else {
|
||||
ctx.Rename(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PrebuiltReplaceMutator replaces dependencies on the source module with dependencies on the prebuilt
|
||||
// when both modules exist and the prebuilt should be used.
|
||||
func PrebuiltReplaceMutator(ctx BottomUpMutatorContext) {
|
||||
if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
|
||||
p := m.Prebuilt()
|
||||
name := m.base().BaseModuleName()
|
||||
if p.Properties.SourceExists && p.usePrebuilt(ctx) {
|
||||
ctx.ReplaceDependencies(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PrebuiltDisableMutator disables source modules that have prebuilts that should be used instead.
|
||||
func PrebuiltDisableMutator(ctx TopDownMutatorContext) {
|
||||
if s, ok := ctx.Module().(PrebuiltSourceInterface); ok {
|
||||
ctx.VisitDirectDeps(func(m blueprint.Module) {
|
||||
if ctx.OtherModuleDependencyTag(m) == prebuiltDependencyTag {
|
||||
p := m.(PrebuiltInterface).Prebuilt()
|
||||
if p.usePrebuilt(ctx) {
|
||||
s.SkipInstall()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Prebuilt) usePrebuilt(ctx BaseContext) bool {
|
||||
// TODO: use p.Properties.Name and ctx.ModuleDir to override prefer
|
||||
return p.Properties.Prefer && len(p.Properties.Srcs) > 0
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
//
|
||||
// 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 (
|
||||
"testing"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
var prebuiltsTests = []struct {
|
||||
name string
|
||||
modules string
|
||||
prebuilt bool
|
||||
}{
|
||||
{
|
||||
name: "no prebuilt",
|
||||
modules: `
|
||||
source {
|
||||
name: "bar",
|
||||
}`,
|
||||
prebuilt: false,
|
||||
},
|
||||
{
|
||||
name: "no source prebuilt not preferred",
|
||||
modules: `
|
||||
prebuilt {
|
||||
name: "bar",
|
||||
prefer: false,
|
||||
srcs: ["prebuilt"],
|
||||
}`,
|
||||
prebuilt: true,
|
||||
},
|
||||
{
|
||||
name: "no source prebuilt preferred",
|
||||
modules: `
|
||||
prebuilt {
|
||||
name: "bar",
|
||||
prefer: true,
|
||||
srcs: ["prebuilt"],
|
||||
}`,
|
||||
prebuilt: true,
|
||||
},
|
||||
{
|
||||
name: "prebuilt not preferred",
|
||||
modules: `
|
||||
source {
|
||||
name: "bar",
|
||||
}
|
||||
|
||||
prebuilt {
|
||||
name: "bar",
|
||||
prefer: false,
|
||||
srcs: ["prebuilt"],
|
||||
}`,
|
||||
prebuilt: false,
|
||||
},
|
||||
{
|
||||
name: "prebuilt preferred",
|
||||
modules: `
|
||||
source {
|
||||
name: "bar",
|
||||
}
|
||||
|
||||
prebuilt {
|
||||
name: "bar",
|
||||
prefer: true,
|
||||
srcs: ["prebuilt"],
|
||||
}`,
|
||||
prebuilt: true,
|
||||
},
|
||||
}
|
||||
|
||||
func TestPrebuilts(t *testing.T) {
|
||||
for _, test := range prebuiltsTests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctx := NewContext()
|
||||
ctx.RegisterModuleType("prebuilt", newPrebuiltModule)
|
||||
ctx.RegisterModuleType("source", newSourceModule)
|
||||
ctx.MockFileSystem(map[string][]byte{
|
||||
"Blueprints": []byte(`
|
||||
source {
|
||||
name: "foo",
|
||||
deps: ["bar"],
|
||||
}
|
||||
` + test.modules),
|
||||
})
|
||||
|
||||
config := TestConfig()
|
||||
|
||||
_, errs := ctx.ParseBlueprintsFiles("Blueprints")
|
||||
fail(t, errs)
|
||||
_, errs = ctx.PrepareBuildActions(config)
|
||||
fail(t, errs)
|
||||
|
||||
foo := findModule(ctx, "foo")
|
||||
if foo == nil {
|
||||
t.Fatalf("failed to find module foo")
|
||||
}
|
||||
|
||||
if test.prebuilt {
|
||||
if !foo.(*sourceModule).dependsOnPrebuiltModule {
|
||||
t.Errorf("doesn't depend on prebuilt module")
|
||||
}
|
||||
|
||||
if foo.(*sourceModule).dependsOnSourceModule {
|
||||
t.Errorf("depends on source module")
|
||||
}
|
||||
} else {
|
||||
if foo.(*sourceModule).dependsOnPrebuiltModule {
|
||||
t.Errorf("depends on prebuilt module")
|
||||
}
|
||||
|
||||
if !foo.(*sourceModule).dependsOnSourceModule {
|
||||
t.Errorf("doens't depend on source module")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type prebuiltModule struct {
|
||||
ModuleBase
|
||||
prebuilt Prebuilt
|
||||
}
|
||||
|
||||
func newPrebuiltModule() (blueprint.Module, []interface{}) {
|
||||
m := &prebuiltModule{}
|
||||
return InitAndroidModule(m, &m.prebuilt.Properties)
|
||||
}
|
||||
|
||||
func (p *prebuiltModule) Name() string {
|
||||
return p.prebuilt.Name(p.ModuleBase.Name())
|
||||
}
|
||||
|
||||
func (p *prebuiltModule) DepsMutator(ctx BottomUpMutatorContext) {
|
||||
}
|
||||
|
||||
func (p *prebuiltModule) GenerateAndroidBuildActions(ModuleContext) {
|
||||
}
|
||||
|
||||
func (p *prebuiltModule) Prebuilt() *Prebuilt {
|
||||
return &p.prebuilt
|
||||
}
|
||||
|
||||
type sourceModule struct {
|
||||
ModuleBase
|
||||
properties struct {
|
||||
Deps []string
|
||||
}
|
||||
dependsOnSourceModule, dependsOnPrebuiltModule bool
|
||||
}
|
||||
|
||||
func newSourceModule() (blueprint.Module, []interface{}) {
|
||||
m := &sourceModule{}
|
||||
return InitAndroidModule(m, &m.properties)
|
||||
}
|
||||
|
||||
func (s *sourceModule) DepsMutator(ctx BottomUpMutatorContext) {
|
||||
for _, d := range s.properties.Deps {
|
||||
ctx.AddDependency(ctx.Module(), nil, d)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *sourceModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||
ctx.VisitDirectDeps(func(m blueprint.Module) {
|
||||
if _, ok := m.(*sourceModule); ok {
|
||||
s.dependsOnSourceModule = true
|
||||
}
|
||||
if _, ok := m.(*prebuiltModule); ok {
|
||||
s.dependsOnPrebuiltModule = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func findModule(ctx *blueprint.Context, name string) blueprint.Module {
|
||||
var ret blueprint.Module
|
||||
ctx.VisitAllModules(func(m blueprint.Module) {
|
||||
if ctx.ModuleName(m) == name {
|
||||
ret = m
|
||||
}
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
func fail(t *testing.T, errs []error) {
|
||||
if len(errs) > 0 {
|
||||
for _, err := range errs {
|
||||
t.Error(err)
|
||||
}
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ func (binary *binaryDecorator) linkerProps() []interface{} {
|
|||
}
|
||||
|
||||
func (binary *binaryDecorator) getStem(ctx BaseModuleContext) string {
|
||||
stem := ctx.ModuleName()
|
||||
stem := ctx.baseModuleName()
|
||||
if binary.Properties.Stem != "" {
|
||||
stem = binary.Properties.Stem
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) {
|
|||
}
|
||||
if ctx.TargetPrimary() {
|
||||
binary.baseInstaller.Properties.Symlinks = append(binary.baseInstaller.Properties.Symlinks,
|
||||
ctx.ModuleName())
|
||||
ctx.baseModuleName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
42
cc/cc.go
42
cc/cc.go
|
@ -19,7 +19,6 @@ package cc
|
|||
// is handled in builder.go
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
|
@ -146,6 +145,7 @@ type ModuleContextIntf interface {
|
|||
sdk() bool
|
||||
sdkVersion() string
|
||||
selectedStl() string
|
||||
baseModuleName() string
|
||||
}
|
||||
|
||||
type ModuleContext interface {
|
||||
|
@ -354,6 +354,10 @@ func (ctx *moduleContextImpl) selectedStl() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (ctx *moduleContextImpl) baseModuleName() string {
|
||||
return ctx.mod.ModuleBase.BaseModuleName()
|
||||
}
|
||||
|
||||
func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
|
||||
return &Module{
|
||||
hod: hod,
|
||||
|
@ -368,6 +372,21 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo
|
|||
return module
|
||||
}
|
||||
|
||||
func (c *Module) Prebuilt() *android.Prebuilt {
|
||||
if p, ok := c.linker.(prebuiltLinkerInterface); ok {
|
||||
return p.prebuilt()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Module) Name() string {
|
||||
name := c.ModuleBase.Name()
|
||||
if p, ok := c.linker.(prebuiltLinkerInterface); ok {
|
||||
name = p.Name(name)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
||||
ctx := &moduleContext{
|
||||
ModuleContext: actx,
|
||||
|
@ -434,12 +453,12 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
|
|||
return
|
||||
}
|
||||
c.outputFile = android.OptionalPathForPath(outputFile)
|
||||
}
|
||||
|
||||
if c.installer != nil && !c.Properties.PreventInstall {
|
||||
c.installer.install(ctx, outputFile)
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
if c.installer != nil && !c.Properties.PreventInstall && c.outputFile.Valid() {
|
||||
c.installer.install(ctx, c.outputFile.Path())
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -792,11 +811,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||
return
|
||||
}
|
||||
|
||||
if !cc.outputFile.Valid() {
|
||||
ctx.ModuleErrorf("module %q missing output file", name)
|
||||
return
|
||||
}
|
||||
|
||||
if tag == reuseObjTag {
|
||||
depPaths.ObjFiles = append(depPaths.ObjFiles,
|
||||
cc.compiler.(libraryInterface).reuseObjs()...)
|
||||
|
@ -861,11 +875,13 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||
depPaths.CrtBegin = linkFile
|
||||
case crtEndDepTag:
|
||||
depPaths.CrtEnd = linkFile
|
||||
default:
|
||||
panic(fmt.Errorf("unknown dependency tag: %s", tag))
|
||||
}
|
||||
|
||||
if ptr != nil {
|
||||
if !linkFile.Valid() {
|
||||
ctx.ModuleErrorf("module %q missing output file", name)
|
||||
return
|
||||
}
|
||||
*ptr = append(*ptr, linkFile.Path())
|
||||
}
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ type libraryInterface interface {
|
|||
func (library *libraryDecorator) getLibName(ctx ModuleContext) string {
|
||||
name := library.libName
|
||||
if name == "" {
|
||||
name = ctx.ModuleName()
|
||||
name = ctx.baseModuleName()
|
||||
}
|
||||
|
||||
if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
//
|
||||
// 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 cc
|
||||
|
||||
import (
|
||||
"android/soong/android"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
func init() {
|
||||
android.RegisterModuleType("cc_prebuilt_shared_library", prebuiltSharedLibraryFactory)
|
||||
}
|
||||
|
||||
type prebuiltLinkerInterface interface {
|
||||
Name(string) string
|
||||
prebuilt() *android.Prebuilt
|
||||
}
|
||||
|
||||
type prebuiltLibraryLinker struct {
|
||||
*libraryDecorator
|
||||
android.Prebuilt
|
||||
}
|
||||
|
||||
var _ prebuiltLinkerInterface = (*prebuiltLibraryLinker)(nil)
|
||||
|
||||
func (p *prebuiltLibraryLinker) prebuilt() *android.Prebuilt {
|
||||
return &p.Prebuilt
|
||||
}
|
||||
|
||||
func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
|
||||
props := p.libraryDecorator.linkerProps()
|
||||
return append(props, &p.Prebuilt.Properties)
|
||||
}
|
||||
|
||||
func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
|
||||
flags Flags, deps PathDeps, objFiles android.Paths) android.Path {
|
||||
// TODO(ccross): verify shared library dependencies
|
||||
if len(p.Prebuilt.Properties.Srcs) > 0 {
|
||||
p.libraryDecorator.exportIncludes(ctx, "-I")
|
||||
p.libraryDecorator.reexportFlags(deps.ReexportedFlags)
|
||||
p.libraryDecorator.reexportDeps(deps.ReexportedFlagsDeps)
|
||||
// TODO(ccross): .toc optimization, stripping, packing
|
||||
return p.Prebuilt.Path(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func prebuiltSharedLibraryFactory() (blueprint.Module, []interface{}) {
|
||||
module, library := NewLibrary(android.HostAndDeviceSupported, true, false)
|
||||
module.compiler = nil
|
||||
|
||||
prebuilt := &prebuiltLibraryLinker{
|
||||
libraryDecorator: library,
|
||||
}
|
||||
module.linker = prebuilt
|
||||
|
||||
return module.Init()
|
||||
}
|
Loading…
Reference in New Issue