androidbp: Implement static/shared property copying
During mutation, make deep copies of the blueprint modules, then start modifying the property lists to apply the static/shared properties. Change-Id: Idc7063f4d1cf7d173ae10418e3437f3e2b914f59
This commit is contained in:
parent
2ef08f4458
commit
2701212d05
|
@ -193,6 +193,7 @@ bootstrap_go_binary {
|
||||||
srcs: [
|
srcs: [
|
||||||
"androidbp/cmd/androidbp.go",
|
"androidbp/cmd/androidbp.go",
|
||||||
"androidbp/cmd/soong.go",
|
"androidbp/cmd/soong.go",
|
||||||
|
"androidbp/cmd/module.go",
|
||||||
],
|
],
|
||||||
testSrcs: [
|
testSrcs: [
|
||||||
"androidbp/cmd/androidbp_test.go",
|
"androidbp/cmd/androidbp_test.go",
|
||||||
|
|
|
@ -18,43 +18,6 @@ import (
|
||||||
|
|
||||||
var recursiveSubdirRegex *regexp.Regexp = regexp.MustCompile("(.+)/\\*\\*/(.+)")
|
var recursiveSubdirRegex *regexp.Regexp = regexp.MustCompile("(.+)/\\*\\*/(.+)")
|
||||||
|
|
||||||
type Module struct {
|
|
||||||
bpmod *bpparser.Module
|
|
||||||
bpname string
|
|
||||||
mkname string
|
|
||||||
isHostRule bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func newModule(mod *bpparser.Module) *Module {
|
|
||||||
return &Module{
|
|
||||||
bpmod: mod,
|
|
||||||
bpname: mod.Type.Name,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Module) translateRuleName() error {
|
|
||||||
var name string
|
|
||||||
if translation, ok := moduleTypeToRule[m.bpname]; ok {
|
|
||||||
name = translation
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("Unknown module type %q", m.bpname)
|
|
||||||
}
|
|
||||||
|
|
||||||
if m.isHostRule {
|
|
||||||
if trans, ok := targetToHostModuleRule[name]; ok {
|
|
||||||
name = trans
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("No corresponding host rule for %q", name)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m.isHostRule = strings.Contains(name, "HOST")
|
|
||||||
}
|
|
||||||
|
|
||||||
m.mkname = name
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type androidMkWriter struct {
|
type androidMkWriter struct {
|
||||||
io.Writer
|
io.Writer
|
||||||
|
|
||||||
|
@ -85,6 +48,22 @@ func valueToString(value bpparser.Value) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func appendValueToValue(dest bpparser.Value, src bpparser.Value) (bpparser.Value, error) {
|
||||||
|
if src.Type != dest.Type {
|
||||||
|
return bpparser.Value{}, fmt.Errorf("ERROR: source and destination types don't match")
|
||||||
|
}
|
||||||
|
switch dest.Type {
|
||||||
|
case bpparser.List:
|
||||||
|
dest.ListValue = append(dest.ListValue, src.ListValue...)
|
||||||
|
return dest, nil
|
||||||
|
case bpparser.String:
|
||||||
|
dest.StringValue += src.StringValue
|
||||||
|
return dest, nil
|
||||||
|
default:
|
||||||
|
return bpparser.Value{}, fmt.Errorf("ERROR: unsupported append with type %s", dest.Type.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getTopOfAndroidTree(wd string) (string, error) {
|
func getTopOfAndroidTree(wd string) (string, error) {
|
||||||
if !filepath.IsAbs(wd) {
|
if !filepath.IsAbs(wd) {
|
||||||
return "", errors.New("path must be absolute: " + wd)
|
return "", errors.New("path must be absolute: " + wd)
|
||||||
|
@ -257,15 +236,6 @@ func prependLocalModule(name string, prop *bpparser.Property, suffix *string) ([
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func modulePropBool(module *bpparser.Module, name string) bool {
|
|
||||||
for _, prop := range module.Properties {
|
|
||||||
if name == prop.Name.Name {
|
|
||||||
return prop.Value.BoolValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *androidMkWriter) writeModule(moduleRule string, props []string,
|
func (w *androidMkWriter) writeModule(moduleRule string, props []string,
|
||||||
disabledBuilds map[string]bool, isHostRule bool) {
|
disabledBuilds map[string]bool, isHostRule bool) {
|
||||||
disabledConditionals := disabledTargetConditionals
|
disabledConditionals := disabledTargetConditionals
|
||||||
|
@ -331,8 +301,41 @@ func (w *androidMkWriter) mutateModule(module *Module) (modules []*Module, err e
|
||||||
newModule(module.bpmod),
|
newModule(module.bpmod),
|
||||||
newModule(module.bpmod),
|
newModule(module.bpmod),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccLinkageCopy := func(props Properties, prop *bpparser.Property) error {
|
||||||
|
for _, p := range prop.Value.MapValue {
|
||||||
|
err := props.AppendToProp(p.Name.Name, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
props.DeleteProp(prop.Name.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ccLinkageDelete := func(props Properties, prop *bpparser.Property) error {
|
||||||
|
props.DeleteProp(prop.Name.Name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
modules[0].bpname = "cc_library_shared"
|
modules[0].bpname = "cc_library_shared"
|
||||||
|
err := modules[0].IterateArchPropertiesWithName("shared", ccLinkageCopy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = modules[0].IterateArchPropertiesWithName("static", ccLinkageDelete)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
modules[1].bpname = "cc_library_static"
|
modules[1].bpname = "cc_library_static"
|
||||||
|
err = modules[1].IterateArchPropertiesWithName("shared", ccLinkageDelete)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = modules[1].IterateArchPropertiesWithName("static", ccLinkageCopy)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, mod := range modules {
|
for _, mod := range modules {
|
||||||
|
@ -340,7 +343,7 @@ func (w *androidMkWriter) mutateModule(module *Module) (modules []*Module, err e
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if mod.isHostRule || !modulePropBool(mod.bpmod, "host_supported") {
|
if mod.isHostRule || !mod.PropBool("host_supported") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,33 @@ var moduleTestCases = []struct {
|
||||||
LOCAL_MODULE := test
|
LOCAL_MODULE := test
|
||||||
include $(BUILD_HOST_STATIC_LIBRARY)`,
|
include $(BUILD_HOST_STATIC_LIBRARY)`,
|
||||||
},
|
},
|
||||||
|
// Static and Shared properties
|
||||||
|
{
|
||||||
|
blueprint: `cc_library {
|
||||||
|
name: "test",
|
||||||
|
srcs: ["a"],
|
||||||
|
static: { srcs: ["c"], static_libs: ["l"], },
|
||||||
|
shared: { srcs: ["b"], },
|
||||||
|
multilib: { lib32: { shared: { cflags: ["f"], }, }, },
|
||||||
|
}`,
|
||||||
|
androidmk: `include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := test
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
a \
|
||||||
|
b
|
||||||
|
LOCAL_CFLAGS_32 := \
|
||||||
|
f
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := test
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
a \
|
||||||
|
c
|
||||||
|
LOCAL_STATIC_LIBRARIES := \
|
||||||
|
l
|
||||||
|
include $(BUILD_STATIC_LIBRARY)`,
|
||||||
|
},
|
||||||
// Manual translation
|
// Manual translation
|
||||||
{
|
{
|
||||||
blueprint: `/* Android.mk:start
|
blueprint: `/* Android.mk:start
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
bpparser "github.com/google/blueprint/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Module struct {
|
||||||
|
bpmod *bpparser.Module
|
||||||
|
bpname string
|
||||||
|
mkname string
|
||||||
|
isHostRule bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newModule(mod *bpparser.Module) *Module {
|
||||||
|
return &Module{
|
||||||
|
bpmod: mod.Copy(),
|
||||||
|
bpname: mod.Type.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) translateRuleName() error {
|
||||||
|
var name string
|
||||||
|
if translation, ok := moduleTypeToRule[m.bpname]; ok {
|
||||||
|
name = translation
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Unknown module type %q", m.bpname)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.isHostRule {
|
||||||
|
if trans, ok := targetToHostModuleRule[name]; ok {
|
||||||
|
name = trans
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("No corresponding host rule for %q", name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m.isHostRule = strings.Contains(name, "HOST")
|
||||||
|
}
|
||||||
|
|
||||||
|
m.mkname = name
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) Properties() Properties {
|
||||||
|
return Properties{&m.bpmod.Properties}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) PropBool(name string) bool {
|
||||||
|
if prop, ok := m.Properties().Prop(name); ok {
|
||||||
|
return prop.Value.BoolValue
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Module) IterateArchPropertiesWithName(name string, f func(Properties, *bpparser.Property) error) error {
|
||||||
|
if p, ok := m.Properties().Prop(name); ok {
|
||||||
|
err := f(m.Properties(), p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, prop := range m.bpmod.Properties {
|
||||||
|
switch prop.Name.Name {
|
||||||
|
case "arch", "multilib", "target":
|
||||||
|
for _, sub := range prop.Value.MapValue {
|
||||||
|
props := Properties{&sub.Value.MapValue}
|
||||||
|
if p, ok := props.Prop(name); ok {
|
||||||
|
err := f(props, p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Properties struct {
|
||||||
|
props *[]*bpparser.Property
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Properties) Prop(name string) (*bpparser.Property, bool) {
|
||||||
|
for _, prop := range *p.props {
|
||||||
|
if name == prop.Name.Name {
|
||||||
|
return prop, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Properties) AppendToProp(name string, src *bpparser.Property) error {
|
||||||
|
if d, ok := p.Prop(name); ok {
|
||||||
|
val, err := appendValueToValue(d.Value, src.Value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Value = val
|
||||||
|
} else {
|
||||||
|
prop := src.Copy()
|
||||||
|
prop.Name.Name = name
|
||||||
|
*p.props = append(*p.props, prop)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Properties) DeleteProp(name string) {
|
||||||
|
for i, prop := range *p.props {
|
||||||
|
if prop.Name.Name == name {
|
||||||
|
*p.props = append((*p.props)[0:i], (*p.props)[i+1:]...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,6 +68,7 @@ rule g.bootstrap.test
|
||||||
build .bootstrap/androidbp/test/androidbp.a: g.bootstrap.gc $
|
build .bootstrap/androidbp/test/androidbp.a: g.bootstrap.gc $
|
||||||
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp.go $
|
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp.go $
|
||||||
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/soong.go $
|
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/soong.go $
|
||||||
|
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/module.go $
|
||||||
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp_test.go | $
|
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp_test.go | $
|
||||||
${g.bootstrap.gcCmd} $
|
${g.bootstrap.gcCmd} $
|
||||||
.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
||||||
|
@ -104,7 +105,8 @@ default .bootstrap/androidbp/test/test.passed
|
||||||
|
|
||||||
build .bootstrap/androidbp/obj/androidbp.a: g.bootstrap.gc $
|
build .bootstrap/androidbp/obj/androidbp.a: g.bootstrap.gc $
|
||||||
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp.go $
|
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/androidbp.go $
|
||||||
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/soong.go | $
|
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/soong.go $
|
||||||
|
${g.bootstrap.srcDir}/build/soong/androidbp/cmd/module.go | $
|
||||||
${g.bootstrap.gcCmd} $
|
${g.bootstrap.gcCmd} $
|
||||||
.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
.bootstrap/blueprint-parser/pkg/github.com/google/blueprint/parser.a $
|
||||||
.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
|
.bootstrap/blueprint-pathtools/pkg/github.com/google/blueprint/pathtools.a $
|
||||||
|
|
Loading…
Reference in New Issue