Merge "Phony target to report all library names." am: f2a0110d36

Original change: https://android-review.googlesource.com/c/platform/build/+/2002324

Change-Id: I236cdbe7b5723e0b2c54075bca83fb471346d2cc
This commit is contained in:
Treehugger Robot 2022-03-04 02:50:26 +00:00 committed by Automerger Merge Worker
commit 578d7b2492
5 changed files with 209 additions and 81 deletions

View file

@ -874,6 +874,34 @@ reportmissinglicenses:
endef
###########################################################
# Returns the unique list of built license metadata files.
###########################################################
define all-license-metadata
$(sort \
$(foreach t,$(ALL_NON_MODULES),$(if $(filter 0p,$(ALL_TARGETS.$(t).META_LIC)),, $(ALL_TARGETS.$(t).META_LIC))) \
$(foreach m,$(ALL_MODULES), $(ALL_MODULES.$(m).META_LIC)) \
)
endef
###########################################################
# Declares the rule to report all library names used in any notice files.
###########################################################
define report-all-notice-library-names-rule
$(strip $(eval _all := $(call all-license-metadata)))
.PHONY: reportallnoticelibrarynames
reportallnoticelibrarynames: PRIVATE_LIST_FILE := $(call license-metadata-dir)/filelist
reportallnoticelibrarynames: | $(COMPLIANCENOTICE_SHIPPEDLIBS)
reportallnoticelibrarynames: $(_all)
@echo Reporting notice library names for at least $$(words $(_all)) license metadata files
$(hide) rm -f $$(PRIVATE_LIST_FILE)
$(hide) mkdir -p $$(dir $$(PRIVATE_LIST_FILE))
$(hide) find out -name '*meta_lic' -type f -printf '"%p"\n' >$$(PRIVATE_LIST_FILE)
$(COMPLIANCENOTICE_SHIPPEDLIBS) @$$(PRIVATE_LIST_FILE)
endef
###########################################################
## Declares a license metadata build rule for ALL_MODULES
###########################################################
@ -888,7 +916,8 @@ $(strip \
) \
$(foreach t,$(sort $(ALL_NON_MODULES)),$(eval $(call non-module-license-metadata-rule,$(t)))) \
$(foreach m,$(sort $(ALL_MODULES)),$(eval $(call license-metadata-rule,$(m)))) \
$(eval $(call report-missing-licenses-rule)))
$(eval $(call report-missing-licenses-rule)) \
$(eval $(call report-all-notice-library-names-rule)))
endef
###########################################################

View file

@ -11,10 +11,6 @@ endif
ifneq (,$(strip $(LOCAL_LICENSE_PACKAGE_NAME)))
license_package_name:=$(strip $(LOCAL_LICENSE_PACKAGE_NAME))
else ifdef my_register_name
license_package_name:=$(my_register_name)
else
license_package_name:=$(strip $(LOCAL_MODULE))
endif
ifneq (,$(strip $(LOCAL_LICENSE_INSTALL_MAP)))

View file

@ -18,17 +18,27 @@ package {
}
blueprint_go_binary {
name: "bom",
name: "checkshare",
srcs: ["cmd/checkshare/checkshare.go"],
deps: ["compliance-module"],
testSrcs: ["cmd/checkshare/checkshare_test.go"],
}
blueprint_go_binary {
name: "compliancenotice_bom",
srcs: ["cmd/bom/bom.go"],
deps: ["compliance-module"],
testSrcs: ["cmd/bom/bom_test.go"],
}
blueprint_go_binary {
name: "checkshare",
srcs: ["cmd/checkshare/checkshare.go"],
deps: ["compliance-module"],
testSrcs: ["cmd/checkshare/checkshare_test.go"],
name: "compliancenotice_shippedlibs",
srcs: ["cmd/shippedlibs/shippedlibs.go"],
deps: [
"compliance-module",
"soong-response",
],
testSrcs: ["cmd/shippedlibs/shippedlibs_test.go"],
}
blueprint_go_binary {
@ -69,13 +79,6 @@ blueprint_go_binary {
testSrcs: ["cmd/rtrace/rtrace_test.go"],
}
blueprint_go_binary {
name: "shippedlibs",
srcs: ["cmd/shippedlibs/shippedlibs.go"],
deps: ["compliance-module"],
testSrcs: ["cmd/shippedlibs/shippedlibs_test.go"],
}
blueprint_go_binary {
name: "textnotice",
srcs: ["cmd/textnotice/textnotice.go"],

View file

@ -22,13 +22,13 @@ import (
"io/fs"
"os"
"path/filepath"
"strings"
"android/soong/response"
"android/soong/tools/compliance"
)
var (
outputFile = flag.String("o", "-", "Where to write the library list. (default stdout)")
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoLicenses = fmt.Errorf("No licenses found")
)
@ -40,28 +40,58 @@ type context struct {
}
func init() {
flag.Usage = func() {
}
func main() {
var expandedArgs []string
for _, arg := range os.Args[1:] {
if strings.HasPrefix(arg, "@") {
f, err := os.Open(strings.TrimPrefix(arg, "@"))
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
respArgs, err := response.ReadRspFile(f)
f.Close()
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
expandedArgs = append(expandedArgs, respArgs...)
} else {
expandedArgs = append(expandedArgs, arg)
}
}
flags := flag.NewFlagSet("flags", flag.ExitOnError)
outputFile := flags.String("o", "-", "Where to write the library list. (default stdout)")
flags.Usage = func() {
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
Outputs a list of libraries used in the shipped images.
Options:
`, filepath.Base(os.Args[0]))
flag.PrintDefaults()
flags.PrintDefaults()
}
}
func main() {
flag.Parse()
err := flags.Parse(expandedArgs)
if err != nil {
flags.Usage()
fmt.Fprintf(os.Stderr, "%v\n", err)
}
// Must specify at least one root target.
if flag.NArg() == 0 {
flag.Usage()
if flags.NArg() == 0 {
flags.Usage()
os.Exit(2)
}
if len(*outputFile) == 0 {
flag.Usage()
flags.Usage()
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
os.Exit(2)
} else {
@ -89,10 +119,10 @@ func main() {
ctx := &context{ofile, os.Stderr, os.DirFS(".")}
err := shippedLibs(ctx, flag.Args()...)
err = shippedLibs(ctx, flags.Args()...)
if err != nil {
if err == failNoneRequested {
flag.Usage()
flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)

View file

@ -311,6 +311,13 @@ func (ni *NoticeIndex) HashText(h hash) []byte {
func (ni *NoticeIndex) getLibName(noticeFor *TargetNode, h hash) string {
for _, text := range noticeFor.LicenseTexts() {
if !strings.Contains(text, ":") {
if ni.hash[text].key != h.key {
continue
}
ln := ni.checkMetadataForLicenseText(noticeFor, text)
if len(ln) > 0 {
return ln
}
continue
}
@ -342,6 +349,17 @@ func (ni *NoticeIndex) getLibName(noticeFor *TargetNode, h hash) string {
if !strings.HasPrefix(licenseText, "prebuilts/") {
continue
}
if !strings.Contains(licenseText, ":") {
if ni.hash[licenseText].key != h.key {
continue
}
} else {
fields := strings.SplitN(licenseText, ":", 2)
fname := fields[0]
if ni.hash[fname].key != h.key {
continue
}
}
for r, prefix := range SafePrebuiltPrefixes {
match := r.FindString(licenseText)
if len(match) == 0 {
@ -389,6 +407,10 @@ func (ni *NoticeIndex) getLibName(noticeFor *TargetNode, h hash) string {
if li > 0 {
n = n[li+1:]
}
fi := strings.Index(n, "@")
if fi > 0 {
n = n[:fi]
}
return n
}
@ -401,67 +423,115 @@ func (ni *NoticeIndex) checkMetadata(noticeFor *TargetNode) string {
}
return name
}
f, err := ni.rootFS.Open(filepath.Join(p, "METADATA"))
name, err := ni.checkMetadataFile(filepath.Join(p, "METADATA"))
if err != nil {
ni.projectName[p] = noProjectName
continue
}
name := ""
description := ""
version := ""
s := bufio.NewScanner(f)
for s.Scan() {
line := s.Text()
m := nameRegexp.FindStringSubmatch(line)
if m != nil {
if 1 < len(m) && m[1] != "" {
name = m[1]
}
if version != "" {
break
}
continue
}
m = versionRegexp.FindStringSubmatch(line)
if m != nil {
if 1 < len(m) && m[1] != "" {
version = m[1]
}
if name != "" {
break
}
continue
}
m = descRegexp.FindStringSubmatch(line)
if m != nil {
if 1 < len(m) && m[1] != "" {
description = m[1]
}
}
if len(name) == 0 {
ni.projectName[p] = noProjectName
continue
}
_ = s.Err()
_ = f.Close()
if name != "" {
if version != "" {
if version[0] == 'v' || version[0] == 'V' {
ni.projectName[p] = name + "_" + version
} else {
ni.projectName[p] = name + "_v_" + version
}
} else {
ni.projectName[p] = name
}
return ni.projectName[p]
}
if description != "" {
ni.projectName[p] = description
return ni.projectName[p]
}
ni.projectName[p] = noProjectName
ni.projectName[p] = name
return name
}
return ""
}
// checkMetadataForLicenseText
func (ni *NoticeIndex) checkMetadataForLicenseText(noticeFor *TargetNode, licenseText string) string {
p := ""
for _, proj := range noticeFor.Projects() {
if strings.HasPrefix(licenseText, proj) {
p = proj
}
}
if len(p) == 0 {
p = filepath.Dir(licenseText)
for {
fi, err := fs.Stat(ni.rootFS, filepath.Join(p, ".git"))
if err == nil && fi.IsDir() {
break
}
if strings.Contains(p, "/") && p != "/" {
p = filepath.Dir(p)
continue
}
return ""
}
}
if name, ok := ni.projectName[p]; ok {
if name == noProjectName {
return ""
}
return name
}
name, err := ni.checkMetadataFile(filepath.Join(p, "METADATA"))
if err == nil && len(name) > 0 {
ni.projectName[p] = name
return name
}
ni.projectName[p] = noProjectName
return ""
}
// checkMetadataFile tries to look up a library name from a METADATA file at `path`.
func (ni *NoticeIndex) checkMetadataFile(path string) (string, error) {
f, err := ni.rootFS.Open(path)
if err != nil {
return "", err
}
name := ""
description := ""
version := ""
s := bufio.NewScanner(f)
for s.Scan() {
line := s.Text()
m := nameRegexp.FindStringSubmatch(line)
if m != nil {
if 1 < len(m) && m[1] != "" {
name = m[1]
}
if version != "" {
break
}
continue
}
m = versionRegexp.FindStringSubmatch(line)
if m != nil {
if 1 < len(m) && m[1] != "" {
version = m[1]
}
if name != "" {
break
}
continue
}
m = descRegexp.FindStringSubmatch(line)
if m != nil {
if 1 < len(m) && m[1] != "" {
description = m[1]
}
}
}
_ = s.Err()
_ = f.Close()
if name != "" {
if version != "" {
if version[0] == 'v' || version[0] == 'V' {
return name + "_" + version, nil
} else {
return name + "_v_" + version, nil
}
}
return name, nil
}
if description != "" {
return description, nil
}
return "", nil
}
// addText reads and indexes the content of a license text file.
func (ni *NoticeIndex) addText(file string) error {
f, err := ni.rootFS.Open(filepath.Clean(file))