Collect modules' info to create IDE project file.
- Register a singleton and implement GenerateBuildActions func in java/jdeps.go. - Declare a interface and a struct to collect info in android/module.go. - Implement IDEInfo for Library & Import module in java/jdeps.go. - Implement IDEInfo for Genrule module in genrule/genrule.go. - Implement IDEInfo for fileGroup module in android/filegroup.go. - Test codes for jdeps.go in java/jdeps_test.go. Bug: 111044346 Test: export SOONG_COLLECT_JAVA_DEPS=1;mmm packages/apps/Settings out/soong/module_bp_java_deps.json will be generated Change-Id: If61da77b4d7614c2c5da438b6af4c725ceccc5c3
This commit is contained in:
parent
cfbea98a57
commit
5d45c6f6f8
|
@ -235,6 +235,7 @@ bootstrap_go_package {
|
|||
"java/genrule.go",
|
||||
"java/jacoco.go",
|
||||
"java/java.go",
|
||||
"java/jdeps.go",
|
||||
"java/java_resources.go",
|
||||
"java/prebuilt_apis.go",
|
||||
"java/proto.go",
|
||||
|
@ -245,6 +246,7 @@ bootstrap_go_package {
|
|||
testSrcs: [
|
||||
"java/app_test.go",
|
||||
"java/java_test.go",
|
||||
"java/jdeps_test.go",
|
||||
],
|
||||
pluginFor: ["soong_build"],
|
||||
}
|
||||
|
|
|
@ -1547,3 +1547,27 @@ func (s AndroidModulesByName) Less(i, j int) bool {
|
|||
}
|
||||
}
|
||||
func (s AndroidModulesByName) Swap(i, j int) { s.slice[i], s.slice[j] = s.slice[j], s.slice[i] }
|
||||
|
||||
// Collect information for opening IDE project files in java/jdeps.go.
|
||||
type IDEInfo interface {
|
||||
IDEInfo(ideInfo *IdeInfo)
|
||||
BaseModuleName() string
|
||||
}
|
||||
|
||||
// Extract the base module name from the Import name.
|
||||
// Often the Import name has a prefix "prebuilt_".
|
||||
// Remove the prefix explicitly if needed
|
||||
// until we find a better solution to get the Import name.
|
||||
type IDECustomizedModuleName interface {
|
||||
IDECustomizedModuleName() string
|
||||
}
|
||||
|
||||
type IdeInfo struct {
|
||||
Deps []string `json:"dependencies,omitempty"`
|
||||
Srcs []string `json:"srcs,omitempty"`
|
||||
Aidl_include_dirs []string `json:"aidl_include_dirs,omitempty"`
|
||||
Jarjar_rules []string `json:"jarjar_rules,omitempty"`
|
||||
Jars []string `json:"jars,omitempty"`
|
||||
Classes []string `json:"class,omitempty"`
|
||||
Installed_paths []string `json:"installed,omitempty"`
|
||||
}
|
||||
|
|
|
@ -344,6 +344,17 @@ func (g *Module) generateSourceFile(ctx android.ModuleContext, task generateTask
|
|||
g.outputDeps = append(g.outputDeps, task.out[0])
|
||||
}
|
||||
|
||||
// Collect information for opening IDE project files in java/jdeps.go.
|
||||
func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
|
||||
dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...)
|
||||
for _, src := range g.properties.Srcs {
|
||||
if strings.HasPrefix(src, ":") {
|
||||
src = strings.Trim(src, ":")
|
||||
dpInfo.Deps = append(dpInfo.Deps, src)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func generatorFactory(taskGenerator taskFunc, props ...interface{}) *Module {
|
||||
module := &Module{
|
||||
taskGenerator: taskGenerator,
|
||||
|
|
45
java/java.go
45
java/java.go
|
@ -311,6 +311,10 @@ type Module struct {
|
|||
|
||||
// list of SDK lib names that this java moudule is exporting
|
||||
exportedSdkLibs []string
|
||||
|
||||
// list of source files, collected from compiledJavaSrcs and compiledSrcJars
|
||||
// filter out Exclude_srcs, will be used by android.IDEInfo struct
|
||||
expandIDEInfoCompiledSrcs []string
|
||||
}
|
||||
|
||||
func (j *Module) Srcs() android.Paths {
|
||||
|
@ -1010,6 +1014,10 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path
|
|||
srcJars = append(srcJars, deps.srcJars...)
|
||||
srcJars = append(srcJars, extraSrcJars...)
|
||||
|
||||
// Collect source files from compiledJavaSrcs, compiledSrcJars and filter out Exclude_srcs
|
||||
// that IDEInfo struct will use
|
||||
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.Strings()...)
|
||||
|
||||
jarName := ctx.ModuleName() + ".jar"
|
||||
|
||||
javaSrcFiles := srcFiles.FilterByExt(".java")
|
||||
|
@ -1362,6 +1370,23 @@ func (j *Module) logtags() android.Paths {
|
|||
return j.logtagsSrcs
|
||||
}
|
||||
|
||||
// Collect information for opening IDE project files in java/jdeps.go.
|
||||
func (j *Module) IDEInfo(dpInfo *android.IdeInfo) {
|
||||
dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...)
|
||||
dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...)
|
||||
dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...)
|
||||
if j.properties.Jarjar_rules != nil {
|
||||
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, *j.properties.Jarjar_rules)
|
||||
}
|
||||
}
|
||||
|
||||
func (j *Module) CompilerDeps() []string {
|
||||
jdeps := []string{}
|
||||
jdeps = append(jdeps, j.properties.Libs...)
|
||||
jdeps = append(jdeps, j.properties.Static_libs...)
|
||||
return jdeps
|
||||
}
|
||||
|
||||
//
|
||||
// Java libraries (.jar file)
|
||||
//
|
||||
|
@ -1691,6 +1716,26 @@ func (j *Import) ExportedSdkLibs() []string {
|
|||
return j.exportedSdkLibs
|
||||
}
|
||||
|
||||
// Collect information for opening IDE project files in java/jdeps.go.
|
||||
const (
|
||||
removedPrefix = "prebuilt_"
|
||||
)
|
||||
|
||||
func (j *Import) IDEInfo(dpInfo *android.IdeInfo) {
|
||||
dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...)
|
||||
}
|
||||
|
||||
func (j *Import) IDECustomizedModuleName() string {
|
||||
// TODO(b/113562217): Extract the base module name from the Import name, often the Import name
|
||||
// has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better
|
||||
// solution to get the Import name.
|
||||
name := j.Name()
|
||||
if strings.HasPrefix(name, removedPrefix) {
|
||||
name = strings.Trim(name, removedPrefix)
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
var _ android.PrebuiltInterface = (*Import)(nil)
|
||||
|
||||
func ImportFactory() android.Module {
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
// Copyright 2018 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 java
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
// This singleton generates android java dependency into to a json file. It does so for each
|
||||
// blueprint Android.bp resulting in a java.Module when either make, mm, mma, mmm or mmma is
|
||||
// called. Dependency info file is generated in $OUT/module_bp_java_depend.json.
|
||||
|
||||
func init() {
|
||||
android.RegisterSingletonType("jdeps_generator", jDepsGeneratorSingleton)
|
||||
}
|
||||
|
||||
func jDepsGeneratorSingleton() android.Singleton {
|
||||
return &jdepsGeneratorSingleton{}
|
||||
}
|
||||
|
||||
type jdepsGeneratorSingleton struct {
|
||||
}
|
||||
|
||||
const (
|
||||
// Environment variables used to modify behavior of this singleton.
|
||||
envVariableCollectJavaDeps = "SOONG_COLLECT_JAVA_DEPS"
|
||||
jdepsJsonFileName = "module_bp_java_deps.json"
|
||||
)
|
||||
|
||||
func (j *jdepsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
if !ctx.Config().IsEnvTrue(envVariableCollectJavaDeps) {
|
||||
return
|
||||
}
|
||||
|
||||
moduleInfos := make(map[string]android.IdeInfo)
|
||||
|
||||
ctx.VisitAllModules(func(module android.Module) {
|
||||
ideInfoProvider, ok := module.(android.IDEInfo)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
name := ideInfoProvider.BaseModuleName()
|
||||
ideModuleNameProvider, ok := module.(android.IDECustomizedModuleName)
|
||||
if ok {
|
||||
name = ideModuleNameProvider.IDECustomizedModuleName()
|
||||
}
|
||||
|
||||
dpInfo := moduleInfos[name]
|
||||
ideInfoProvider.IDEInfo(&dpInfo)
|
||||
dpInfo.Deps = android.FirstUniqueStrings(dpInfo.Deps)
|
||||
dpInfo.Srcs = android.FirstUniqueStrings(dpInfo.Srcs)
|
||||
dpInfo.Aidl_include_dirs = android.FirstUniqueStrings(dpInfo.Aidl_include_dirs)
|
||||
dpInfo.Jarjar_rules = android.FirstUniqueStrings(dpInfo.Jarjar_rules)
|
||||
dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
|
||||
moduleInfos[name] = dpInfo
|
||||
|
||||
mkProvider, ok := module.(android.AndroidMkDataProvider)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
data := mkProvider.AndroidMk()
|
||||
if data.Class != "" {
|
||||
dpInfo.Classes = append(dpInfo.Classes, data.Class)
|
||||
}
|
||||
out := data.OutputFile.String()
|
||||
if out != "" {
|
||||
dpInfo.Installed_paths = append(dpInfo.Installed_paths, out)
|
||||
}
|
||||
dpInfo.Classes = android.FirstUniqueStrings(dpInfo.Classes)
|
||||
dpInfo.Installed_paths = android.FirstUniqueStrings(dpInfo.Installed_paths)
|
||||
moduleInfos[name] = dpInfo
|
||||
})
|
||||
|
||||
jfpath := android.PathForOutput(ctx, jdepsJsonFileName).String()
|
||||
err := createJsonFile(moduleInfos, jfpath)
|
||||
if err != nil {
|
||||
ctx.Errorf(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func createJsonFile(moduleInfos map[string]android.IdeInfo, jfpath string) error {
|
||||
file, err := os.Create(jfpath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create file: %s, relative: %v", jdepsJsonFileName, err)
|
||||
}
|
||||
defer file.Close()
|
||||
buf, err := json.MarshalIndent(moduleInfos, "", "\t")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Write file failed: %s, relative: %v", jdepsJsonFileName, err)
|
||||
}
|
||||
fmt.Fprintf(file, string(buf))
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2018 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 java
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
func TestCollectJavaLibraryPropertiesAddLibsDeps(t *testing.T) {
|
||||
expected := []string{"Foo", "Bar"}
|
||||
module := LibraryFactory().(*Library)
|
||||
module.properties.Libs = append(module.properties.Libs, expected...)
|
||||
dpInfo := &android.IdeInfo{}
|
||||
|
||||
module.IDEInfo(dpInfo)
|
||||
|
||||
if !reflect.DeepEqual(dpInfo.Deps, expected) {
|
||||
t.Errorf("Library.IDEInfo() Deps = %v, want %v", dpInfo.Deps, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectJavaLibraryPropertiesAddStaticLibsDeps(t *testing.T) {
|
||||
expected := []string{"Foo", "Bar"}
|
||||
module := LibraryFactory().(*Library)
|
||||
module.properties.Static_libs = append(module.properties.Static_libs, expected...)
|
||||
dpInfo := &android.IdeInfo{}
|
||||
|
||||
module.IDEInfo(dpInfo)
|
||||
|
||||
if !reflect.DeepEqual(dpInfo.Deps, expected) {
|
||||
t.Errorf("Library.IDEInfo() Deps = %v, want %v", dpInfo.Deps, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectJavaLibraryPropertiesAddScrs(t *testing.T) {
|
||||
expected := []string{"Foo", "Bar"}
|
||||
module := LibraryFactory().(*Library)
|
||||
module.expandIDEInfoCompiledSrcs = append(module.expandIDEInfoCompiledSrcs, expected...)
|
||||
dpInfo := &android.IdeInfo{}
|
||||
|
||||
module.IDEInfo(dpInfo)
|
||||
|
||||
if !reflect.DeepEqual(dpInfo.Srcs, expected) {
|
||||
t.Errorf("Library.IDEInfo() Srcs = %v, want %v", dpInfo.Srcs, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) {
|
||||
expected := []string{"Foo", "Bar"}
|
||||
module := LibraryFactory().(*Library)
|
||||
module.deviceProperties.Aidl.Include_dirs = append(module.deviceProperties.Aidl.Include_dirs, expected...)
|
||||
dpInfo := &android.IdeInfo{}
|
||||
|
||||
module.IDEInfo(dpInfo)
|
||||
|
||||
if !reflect.DeepEqual(dpInfo.Aidl_include_dirs, expected) {
|
||||
t.Errorf("Library.IDEInfo() Aidl_include_dirs = %v, want %v", dpInfo.Aidl_include_dirs, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectJavaLibraryPropertiesAddJarjarRules(t *testing.T) {
|
||||
expected := "Jarjar_rules.txt"
|
||||
module := LibraryFactory().(*Library)
|
||||
module.properties.Jarjar_rules = &expected
|
||||
dpInfo := &android.IdeInfo{}
|
||||
|
||||
module.IDEInfo(dpInfo)
|
||||
|
||||
if dpInfo.Jarjar_rules[0] != expected {
|
||||
t.Errorf("Library.IDEInfo() Jarjar_rules = %v, want %v", dpInfo.Jarjar_rules[0], expected)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue