aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-11 15:24:34 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-06-11 16:19:15 +0000
commit4684c41fbac950686b0107111c1d03197265cb96 (patch)
tree4f4975caac41fce5747359116a1e8d4d30536663
parentdf4fde205b5085e716192c6a2c15bb633300e328 (diff)
parent52a972709d4f2525255f611cf8b24e7cd0fa1e30 (diff)
downloadbuild-4684c41fbac950686b0107111c1d03197265cb96.tar.gz
Make change and version bump to t_frc_art_330439000 for mainline module file: None
Change-Id: Iff0ad6aa01d865acba914bbea25ae10fa3dfb649
-rw-r--r--core/Makefile30
-rw-r--r--core/android_soong_config_vars.mk47
-rw-r--r--core/build_id.mk2
-rw-r--r--core/definitions.mk137
-rw-r--r--core/distdir.mk108
-rw-r--r--core/main.mk4
-rw-r--r--core/notice_files.mk2
-rw-r--r--core/tasks/tools/package-modules.mk2
-rw-r--r--target/product/base_system.mk1
-rw-r--r--target/product/sdk.mk7
-rw-r--r--tools/compliance/Android.bp33
-rw-r--r--tools/compliance/cmd/bom/bom.go68
-rw-r--r--tools/compliance/cmd/checkshare/checkshare.go109
-rw-r--r--tools/compliance/cmd/dumpgraph/dumpgraph.go112
-rw-r--r--tools/compliance/cmd/dumpresolutions/dumpresolutions.go114
-rw-r--r--tools/compliance/cmd/htmlnotice/htmlnotice.go78
-rw-r--r--tools/compliance/cmd/listshare/listshare.go91
-rw-r--r--tools/compliance/cmd/rtrace/rtrace.go120
-rw-r--r--tools/compliance/cmd/shippedlibs/shippedlibs.go3
-rw-r--r--tools/compliance/cmd/textnotice/textnotice.go74
-rw-r--r--tools/compliance/cmd/xmlnotice/xmlnotice.go76
21 files changed, 934 insertions, 284 deletions
diff --git a/core/Makefile b/core/Makefile
index 93b3e03af7..de9fd52c12 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -842,10 +842,6 @@ $(INSTALLED_FILES_FILE_ROOT) : $(INTERNAL_ROOT_FILES) $(FILESLIST) $(FILESLIST_U
$(call declare-0p-target,$(INSTALLED_FILES_FILE_ROOT))
$(call declare-0p-target,$(INSTALLED_FILES_JSON_ROOT))
-ifeq ($(HOST_OS),linux)
-$(call dist-for-goals, sdk sdk_addon, $(INSTALLED_FILES_FILE_ROOT))
-endif
-
#------------------------------------------------------------------
# dtb
ifdef BOARD_INCLUDE_DTB_IN_BOOTIMG
@@ -877,9 +873,6 @@ $(INSTALLED_FILES_FILE_RAMDISK) : $(INTERNAL_RAMDISK_FILES) $(FILESLIST) $(FILES
$(eval $(call declare-0p-target,$(INSTALLED_FILES_FILE_RAMDISK)))
$(eval $(call declare-0p-target,$(INSTALLED_FILES_JSON_RAMDISK)))
-ifeq ($(HOST_OS),linux)
-$(call dist-for-goals, sdk sdk_addon, $(INSTALLED_FILES_FILE_RAMDISK))
-endif
BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img
ifeq ($(BOARD_RAMDISK_USE_LZ4),true)
@@ -1571,7 +1564,6 @@ ifndef TARGET_BUILD_APPS
# TODO These intermediate NOTICE.txt/NOTICE.html files should go into
# TARGET_OUT_NOTICE_FILES now that the notice files are gathered from
# the src subdirectory.
-target_notice_file_txt := $(TARGET_OUT_INTERMEDIATES)/NOTICE.txt
kernel_notice_file := $(TARGET_OUT_NOTICE_FILES)/src/kernel.txt
winpthreads_notice_file := $(TARGET_OUT_NOTICE_FILES)/src/winpthreads.txt
@@ -3109,10 +3101,6 @@ $(eval $(call declare-0p-target,$(INSTALLED_FILES_JSON)))
.PHONY: installed-file-list
installed-file-list: $(INSTALLED_FILES_FILE)
-ifeq ($(HOST_OS),linux)
-$(call dist-for-goals, sdk sdk_addon, $(INSTALLED_FILES_FILE))
-endif
-
systemimage_intermediates := \
$(call intermediates-dir-for,PACKAGING,systemimage)
BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img
@@ -6799,8 +6787,6 @@ ATREE_FILES :=
# if we don't have a real list, then use "everything"
ifeq ($(strip $(ATREE_FILES)),)
ATREE_FILES := \
- $(ALL_DEFAULT_INSTALLED_MODULES) \
- $(INSTALLED_RAMDISK_TARGET) \
$(ALL_DOCS) \
$(ALL_SDK_FILES)
endif
@@ -6825,21 +6811,9 @@ sdk_atree_files += $(atree_dir)/sdk.atree
endif
deps := \
- $(target_notice_file_txt) \
$(OUT_DOCS)/offline-sdk-timestamp \
$(SDK_METADATA_FILES) \
- $(SYMBOLS_ZIP) \
- $(COVERAGE_ZIP) \
- $(APPCOMPAT_ZIP) \
- $(INSTALLED_SYSTEMIMAGE_TARGET) \
- $(INSTALLED_QEMU_SYSTEMIMAGE) \
- $(INSTALLED_QEMU_RAMDISKIMAGE) \
- $(INSTALLED_QEMU_VENDORIMAGE) \
- $(QEMU_VERIFIED_BOOT_PARAMS) \
- $(INSTALLED_USERDATAIMAGE_TARGET) \
- $(INSTALLED_RAMDISK_TARGET) \
- $(INSTALLED_SDK_BUILD_PROP_TARGET) \
- $(INSTALLED_BUILD_PROP_TARGET) \
+ $(INSTALLED_SDK_BUILD_PROP_TARGET) \
$(ATREE_FILES) \
$(sdk_atree_files) \
$(HOST_OUT_EXECUTABLES)/atree \
@@ -6882,8 +6856,6 @@ $(INTERNAL_SDK_TARGET): $(deps)
-v "TARGET_CPU_ABI=$(TARGET_CPU_ABI)" \
-v "DLL_EXTENSION=$(HOST_SHLIB_SUFFIX)" \
-o $(PRIVATE_DIR) && \
- cp -f $(target_notice_file_txt) \
- $(PRIVATE_DIR)/system-images/android-$(PLATFORM_VERSION)/$(TARGET_CPU_ABI)/NOTICE.txt && \
HOST_OUT_EXECUTABLES=$(HOST_OUT_EXECUTABLES) HOST_OS=$(HOST_OS) \
development/build/tools/sdk_clean.sh $(PRIVATE_DIR) && \
chmod -R ug+rwX $(PRIVATE_DIR) && \
diff --git a/core/android_soong_config_vars.mk b/core/android_soong_config_vars.mk
index 144edd088e..28181ebfae 100644
--- a/core/android_soong_config_vars.mk
+++ b/core/android_soong_config_vars.mk
@@ -39,13 +39,56 @@ $(call add_soong_config_var,ANDROID,PRODUCT_INSTALL_DEBUG_POLICY_TO_SYSTEM_EXT)
# Default behavior for the tree wrt building modules or using prebuilts. This
# can always be overridden by setting the environment variable
# MODULE_BUILD_FROM_SOURCE.
+BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := false
+
ifneq ($(SANITIZE_TARGET)$(EMMA_INSTRUMENT_FRAMEWORK),)
# Always use sources when building the framework with Java coverage or
# sanitized builds as they both require purpose built prebuilts which we do
# not provide.
BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
-else
- BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := false
+endif
+
+ifneq ($(CLANG_COVERAGE)$(NATIVE_COVERAGE_PATHS),)
+ # Always use sources when building with clang coverage and native coverage.
+ # It is possible that there are certain situations when building with coverage
+ # would work with prebuilts, e.g. when the coverage is not being applied to
+ # modules for which we provide prebuilts. Unfortunately, determining that
+ # would require embedding knowledge of which coverage paths affect which
+ # modules here. That would duplicate a lot of information, add yet another
+ # location module authors have to update and complicate the logic here.
+ # For nowe we will just always build from sources when doing coverage builds.
+ BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# TODO(b/172063604): Remove once products no longer use dex2oat(d)s.
+# If the product uses dex2oats and/or dex2oatds then build from sources as
+# ART does not currently provide prebuilts of those tools.
+ifneq (,$(filter dex2oats dex2oatds,$(PRODUCT_HOST_PACKAGES)))
+ BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# ART does not provide linux_bionic variants needed for products that
+# set HOST_CROSS_OS=linux_bionic.
+ifeq (linux_bionic,${HOST_CROSS_OS})
+ BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# ART does not provide host side arm64 variants needed for products that
+# set HOST_CROSS_ARCH=arm64.
+ifeq (arm64,${HOST_CROSS_ARCH})
+ BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# TV based devices do not seem to work with prebuilts, so build from source
+# for now and fix in a follow up.
+ifneq (,$(filter tv,$(subst $(comma),$(space),${PRODUCT_CHARACTERISTICS})))
+ BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
+endif
+
+# ATV based devices do not seem to work with prebuilts, so build from source
+# for now and fix in a follow up.
+ifneq (,${PRODUCT_IS_ATV})
+ BRANCH_DEFAULT_MODULE_BUILD_FROM_SOURCE := true
endif
ifneq (,$(MODULE_BUILD_FROM_SOURCE))
diff --git a/core/build_id.mk b/core/build_id.mk
index a4897887a2..6f73faf673 100644
--- a/core/build_id.mk
+++ b/core/build_id.mk
@@ -18,4 +18,4 @@
# (like "CRB01"). It must be a single word, and is
# capitalized by convention.
-BUILD_ID=TM
+BUILD_ID=330439000
diff --git a/core/definitions.mk b/core/definitions.mk
index 0c46de9fc6..84860f9fa4 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -570,16 +570,21 @@ define license-metadata-dir
$(call generated-sources-dir-for,META,lic,)
endef
+TARGETS_MISSING_LICENSE_METADATA:=
+
###########################################################
# License metadata targets corresponding to targets in $(1)
###########################################################
define corresponding-license-metadata
-$(strip $(foreach target, $(sort $(1)), \
+$(strip $(filter-out 0p,$(foreach target, $(sort $(1)), \
$(if $(strip $(ALL_MODULES.$(target).META_LIC)), \
$(ALL_MODULES.$(target).META_LIC), \
$(if $(strip $(ALL_TARGETS.$(target).META_LIC)), \
$(ALL_TARGETS.$(target).META_LIC), \
- $(call append-path,$(call license-metadata-dir),$(patsubst $(OUT_DIR)%,out%,$(target).meta_lic))))))
+ $(eval TARGETS_MISSING_LICENSE_METADATA += $(target)) \
+ ) \
+ ) \
+)))
endef
###########################################################
@@ -705,6 +710,60 @@ $(_meta) : $(foreach d,$(_deps),$(call word-colon,1,$(d))) $(foreach n,$(_notice
endef
###########################################################
+## Record missing dependencies for non-module target $(1)
+###########################################################
+define record-missing-non-module-dependencies
+$(strip $(eval _tgt := $(strip $(1))))
+$(strip $(foreach d,$(strip $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES)), \
+ $(if $(strip $(ALL_TARGETS.$(d).META_LIC)), \
+ , \
+ $(eval NON_MODULES_WITHOUT_LICENSE_METADATA += $(d))) \
+))
+endef
+
+###########################################################
+## License metadata build rule for copied target $(1)
+###########################################################
+define copied-target-license-metadata-rule
+$(if $(strip $(ALL_TARGETS.$(1).META_LIC)),,$(call _copied-target-license-metadata-rule,$(1)))
+endef
+
+define _copied-target-license-metadata-rule
+$(strip $(eval _dir := $(call license-metadata-dir)))
+$(strip $(eval _meta := $(call append-path,$(_dir),$(patsubst $(OUT_DIR)%,out%,$(1).meta_lic))))
+$(strip $(eval ALL_TARGETS.$(1).META_LIC:=$(_meta)))
+$(strip $(eval _dep:=))
+$(strip $(foreach s,$(ALL_COPIED_TARGETS.$(1).SOURCES),\
+ $(eval _dmeta:=$(ALL_TARGETS.$(s).META_LIC))\
+ $(if $(filter 0p,$(_dmeta)),\
+ $(if $(filter-out 0p,$(_dep)),,$(eval ALL_TARGETS.$(1).META_LIC:=0p)),\
+ $(if $(_dep),\
+ $(if $(filter-out $(_dep),$(_dmeta)),$(error cannot copy target from multiple modules: $(1) from $(_dep) and $(_dmeta))),
+ $(eval _dep:=$(_dmeta))))))
+$(strip $(if $(strip $(_dep)),,$(error cannot copy target from unknown module: $(1) from $(ALL_COPIED_TARGETS.$(1).SOURCES))))
+
+ifneq (0p,$(ALL_TARGETS.$(1).META_LIC))
+$(_meta): PRIVATE_DEST_TARGET := $(1)
+$(_meta): PRIVATE_SOURCE_TARGETS := $(ALL_COPIED_TARGETS.$(1).SOURCES)
+$(_meta): PRIVATE_SOURCE_METADATA := $(_dep)
+$(_meta): PRIVATE_ARGUMENT_FILE := $(call intermediates-dir-for,PACKAGING,copynotice)/$(_meta)/arguments
+$(_meta) : $(_dep) $(COPY_LICENSE_METADATA)
+ rm -f $$@
+ mkdir -p $$(dir $$@)
+ mkdir -p $$(dir $$(PRIVATE_ARGUMENT_FILE))
+ $$(call dump-words-to-file,\
+ $$(addprefix -i ,$$(PRIVATE_DEST_TARGET))\
+ $$(addprefix -s ,$$(PRIVATE_SOURCE_TARGETS))\
+ $$(addprefix -d ,$$(PRIVATE_SOURCE_METADATA)),\
+ $$(PRIVATE_ARGUMENT_FILE))
+ OUT_DIR=$(OUT_DIR) $(COPY_LICENSE_METADATA) \
+ @$$(PRIVATE_ARGUMENT_FILE) \
+ -o $$@
+
+endif
+endef
+
+###########################################################
## Declare the license metadata for non-module target $(1).
##
## $(2) -- license kinds e.g. SPDX-license-identifier-Apache-2.0
@@ -717,6 +776,7 @@ define declare-license-metadata
$(strip \
$(eval _tgt := $(subst //,/,$(strip $(1)))) \
$(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_TARGETS.$(_tgt).META_LIC := $(call license-metadata-dir)/$(patsubst $(OUT_DIR)%,out%,$(_tgt)).meta_lic) \
$(eval ALL_NON_MODULES.$(_tgt).LICENSE_KINDS := $(strip $(2))) \
$(eval ALL_NON_MODULES.$(_tgt).LICENSE_CONDITIONS := $(strip $(3))) \
$(eval ALL_NON_MODULES.$(_tgt).NOTICES := $(strip $(4))) \
@@ -757,6 +817,7 @@ define declare-container-license-metadata
$(strip \
$(eval _tgt := $(subst //,/,$(strip $(1)))) \
$(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_TARGETS.$(_tgt).META_LIC := $(call license-metadata-dir)/$(patsubst $(OUT_DIR)%,out%,$(_tgt)).meta_lic) \
$(eval ALL_NON_MODULES.$(_tgt).LICENSE_KINDS := $(strip $(2))) \
$(eval ALL_NON_MODULES.$(_tgt).LICENSE_CONDITIONS := $(strip $(3))) \
$(eval ALL_NON_MODULES.$(_tgt).NOTICES := $(strip $(4))) \
@@ -829,6 +890,7 @@ define declare-license-deps
$(strip \
$(eval _tgt := $(strip $(1))) \
$(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_TARGETS.$(_tgt).META_LIC := $(call license-metadata-dir)/$(patsubst $(OUT_DIR)%,out%,$(_tgt)).meta_lic) \
$(eval ALL_NON_MODULES.$(_tgt).DEPENDENCIES := $(strip $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES) $(2))) \
)
endef
@@ -845,6 +907,7 @@ define declare-container-license-deps
$(strip \
$(eval _tgt := $(strip $(1))) \
$(eval ALL_NON_MODULES += $(_tgt)) \
+ $(eval ALL_TARGETS.$(_tgt).META_LIC := $(call license-metadata-dir)/$(patsubst $(OUT_DIR)%,out%,$(_tgt)).meta_lic) \
$(eval ALL_NON_MODULES.$(_tgt).DEPENDENCIES := $(strip $(ALL_NON_MODULES.$(_tgt).DEPENDENCIES) $(2))) \
$(eval ALL_NON_MODULES.$(_tgt).IS_CONTAINER := true) \
$(eval ALL_NON_MODULES.$(_tgt).ROOT_MAPPINGS := $(strip $(ALL_NON_MODULES.$(_tgt).ROOT_MAPPINGS) $(3))) \
@@ -856,12 +919,14 @@ endef
###########################################################
define report-missing-licenses-rule
.PHONY: reportmissinglicenses
-reportmissinglicenses: PRIVATE_NON_MODULES:=$(sort $(NON_MODULES_WITHOUT_LICENSE_METADATA))
-reportmissinglicenses: PRIVATE_COPIED_FILES:=$(sort $(filter $(NON_MODULES_WITHOUT_LICENSE_METADATA),$(foreach _pair,$(PRODUCT_COPY_FILES), $(PRODUCT_OUT)/$(call word-colon,2,$(_pair)))))
+reportmissinglicenses: PRIVATE_NON_MODULES:=$(sort $(NON_MODULES_WITHOUT_LICENSE_METADATA) $(TARGETS_MISSING_LICENSE_METADATA))
+reportmissinglicenses: PRIVATE_COPIED_FILES:=$(sort $(filter $(NON_MODULES_WITHOUT_LICENSE_METADATA) $(TARGETS_MISSING_LICENSE_METADATA),\
+ $(foreach _pair,$(PRODUCT_COPY_FILES), $(PRODUCT_OUT)/$(call word-colon,2,$(_pair)))))
reportmissinglicenses:
@echo Reporting $$(words $$(PRIVATE_NON_MODULES)) targets without license metadata
$$(foreach t,$$(PRIVATE_NON_MODULES),if ! [ -h $$(t) ]; then echo No license metadata for $$(t) >&2; fi;)
$$(foreach t,$$(PRIVATE_COPIED_FILES),if ! [ -h $$(t) ]; then echo No license metadata for copied file $$(t) >&2; fi;)
+ echo $$(words $$(PRIVATE_NON_MODULES)) targets missing license metadata >&2
endef
@@ -914,13 +979,9 @@ $(strip \
$(foreach t,$(sort $(ALL_0P_TARGETS)), \
$(eval ALL_TARGETS.$(t).META_LIC := 0p) \
) \
- $(foreach t,$(sort $(ALL_NON_MODULES)), \
- $(eval ALL_TARGETS.$(t).META_LIC := $(call append-path,$(_dir),$(patsubst $(OUT_DIR)%,out%,$(t).meta_lic))) \
- ) \
$(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-all-notice-library-names-rule)) \
+ $(foreach t,$(sort $(ALL_COPIED_TARGETS)),$(eval $(call copied-target-license-metadata-rule,$(t)))) \
$(eval $(call build-all-license-metadata-rule)))
endef
@@ -992,6 +1053,22 @@ $(strip \
)
endef
+# Uses LOCAL_MODULE_CLASS, LOCAL_MODULE, and LOCAL_IS_HOST_MODULE
+# to determine the intermediates directory.
+#
+# $(1): if non-empty, force the intermediates to be COMMON
+# $(2): if non-empty, force the intermediates to be for the 2nd arch
+# $(3): if non-empty, force the intermediates to be for the host cross os
+define local-meta-intermediates-dir
+$(strip \
+ $(if $(strip $(LOCAL_MODULE_CLASS)),, \
+ $(error $(LOCAL_PATH): LOCAL_MODULE_CLASS not defined before call to local-meta-intermediates-dir)) \
+ $(if $(strip $(LOCAL_MODULE)),, \
+ $(error $(LOCAL_PATH): LOCAL_MODULE not defined before call to local-meta-intermediates-dir)) \
+ $(call intermediates-dir-for,META$(LOCAL_MODULE_CLASS),$(LOCAL_MODULE),$(if $(strip $(LOCAL_IS_HOST_MODULE)),HOST),$(1),$(2),$(3)) \
+)
+endef
+
###########################################################
## The generated sources directory. Placing generated
## source files directly in the intermediates directory
@@ -2411,7 +2488,47 @@ define dump-words-to-file
@$(call emit-line,$(wordlist 38001,38500,$(1)),$(2))
@$(call emit-line,$(wordlist 38501,39000,$(1)),$(2))
@$(call emit-line,$(wordlist 39001,39500,$(1)),$(2))
- @$(if $(wordlist 39501,39502,$(1)),$(error Too many words ($(words $(1)))))
+ @$(call emit-line,$(wordlist 39501,40000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 40001,40500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 40501,41000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 41001,41500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 41501,42000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 42001,42500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 42501,43000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 43001,43500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 43501,44000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 44001,44500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 44501,45000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 45001,45500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 45501,46000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 46001,46500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 46501,47000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 47001,47500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 47501,48000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 48001,48500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 48501,49000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 49001,49500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 49501,50000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 50001,50500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 50501,51000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 51001,51500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 51501,52000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 52001,52500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 52501,53000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 53001,53500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 53501,54000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 54001,54500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 54501,55000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 55001,55500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 55501,56000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 56001,56500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 56501,57000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 57001,57500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 57501,58000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 58001,58500,$(1)),$(2))
+ @$(call emit-line,$(wordlist 58501,59000,$(1)),$(2))
+ @$(call emit-line,$(wordlist 59001,59500,$(1)),$(2))
+ @$(if $(wordlist 59501,59502,$(1)),$(error Too many words ($(words $(1)))))
endef
# Return jar arguments to compress files in a given directory
# $(1): directory
diff --git a/core/distdir.mk b/core/distdir.mk
index aad8ff3d65..3d48a484a5 100644
--- a/core/distdir.mk
+++ b/core/distdir.mk
@@ -45,6 +45,105 @@ $(foreach file,$(2), \
$(eval _all_dist_goal_output_pairs += $$(goal):$$(dst))))
endef
+.PHONY: shareprojects
+
+define __share-projects-rule
+$(1) : PRIVATE_TARGETS := $(2)
+$(1) : PRIVATE_ARGUMENT_FILE := $(call intermediates-dir-for,METAPACKAGING,codesharing)/$(1)/arguments
+$(1): $(2) $(COMPLIANCE_LISTSHARE)
+ $(hide) rm -f $$@
+ mkdir -p $$(dir $$@)
+ mkdir -p $$(dir $$(PRIVATE_ARGUMENT_FILE))
+ $$(if $$(strip $$(PRIVATE_TARGETS)),$$(call dump-words-to-file,$$(PRIVATE_TARGETS),$$(PRIVATE_ARGUMENT_FILE)))
+ $$(if $$(strip $$(PRIVATE_TARGETS)),OUT_DIR=$(OUT_DIR) $(COMPLIANCE_LISTSHARE) -o $$@ @$$(PRIVATE_ARGUMENT_FILE),touch $$@)
+endef
+
+# build list of projects to share in $(1) for dist targets in $(2)
+#
+# $(1): the intermediate project sharing file
+# $(2): the dist files to base the sharing on
+define _share-projects-rule
+$(eval $(call __share-projects-rule,$(1),$(call corresponding-license-metadata,$(2))))
+endef
+
+# Add a build dependency
+#
+# $(1): the goal phony target
+# $(2): the intermediate shareprojects file
+define _share-projects-dep
+$(1): $(2)
+endef
+
+.PHONY: alllicensetexts
+
+define __license-texts-rule
+$(2) : PRIVATE_GOAL := $(1)
+$(2) : PRIVATE_TARGETS := $(3)
+$(2) : PRIVATE_ROOTS := $(4)
+$(2) : PRIVATE_ARGUMENT_FILE := $(call intermediates-dir-for,METAPACKAGING,licensetexts)/$(2)/arguments
+$(2): $(3) $(TEXTNOTICE)
+ $(hide) rm -f $$@
+ mkdir -p $$(dir $$@)
+ mkdir -p $$(dir $$(PRIVATE_ARGUMENT_FILE))
+ $$(if $$(strip $$(PRIVATE_TARGETS)),$$(call dump-words-to-file,\
+ -product="$$(PRIVATE_GOAL)" -title="$$(PRIVATE_GOAL)" \
+ $$(addprefix -strip_prefix ,$$(PRIVATE_ROOTS)) \
+ -strip_prefix=$(PRODUCT_OUT)/ -strip_prefix=$(HOST_OUT)/\
+ $$(PRIVATE_TARGETS),\
+ $$(PRIVATE_ARGUMENT_FILE)))
+ $$(if $$(strip $$(PRIVATE_TARGETS)),OUT_DIR=$(OUT_DIR) $(TEXTNOTICE) -o $$@ @$$(PRIVATE_ARGUMENT_FILE),touch $$@)
+endef
+
+# build list of projects to share in $(2) for dist targets in $(3) for dist goal $(1)
+#
+# $(1): the name of the dist goal
+# $(2): the intermediate project sharing file
+# $(3): the dist files to base the sharing on
+define _license-texts-rule
+$(eval $(call __license-texts-rule,$(1),$(2),$(call corresponding-license-metadata,$(3)),$(sort $(dir $(3)))))
+endef
+
+# Add a build dependency
+#
+# $(1): the goal phony target
+# $(2): the intermediate shareprojects file
+define _license-texts-dep
+$(1): $(2)
+endef
+
+define _add_projects_to_share
+$(strip $(eval _idir := $(call intermediates-dir-for,METAPACKAGING,shareprojects))) \
+$(strip $(eval _tdir := $(call intermediates-dir-for,METAPACKAGING,licensetexts))) \
+$(strip $(eval _goals := $(sort $(_all_dist_goals)))) \
+$(strip $(eval _opairs := $(sort $(_all_dist_goal_output_pairs)))) \
+$(strip $(eval _dpairs := $(sort $(_all_dist_src_dst_pairs)))) \
+$(strip $(eval _allt :=)) \
+$(foreach goal,$(_goals), \
+ $(eval _f := $(_idir)/$(goal).shareprojects) \
+ $(eval _n := $(_tdir)/$(goal).txt) \
+ $(call dist-for-goals,$(goal),$(_f):shareprojects/$(basename $(notdir $(_f)))) \
+ $(call dist-for-goals,$(goal),$(_n):licensetexts/$(basename $(notdir $(_n)))) \
+ $(eval _targets :=) \
+ $(foreach op,$(filter $(goal):%,$(_opairs)),$(foreach p,$(filter %:$(call word-colon,2,$(op)),$(_dpairs)),$(eval _targets += $(call word-colon,1,$(p))))) \
+ $(eval _allt += $(_targets)) \
+ $(eval $(call _share-projects-rule,$(_f),$(_targets))) \
+ $(eval $(call _license-texts-rule,$(goal),$(_n),$(_targets))) \
+)\
+$(eval _f := $(_idir)/all.shareprojects)\
+$(eval _n := $(_tdir)/all.txt)\
+$(eval _idir :=)\
+$(eval _tdir :=)\
+$(eval $(call _share-projects-dep,shareprojects,$(_f))) \
+$(eval $(call _license-texts-dep,alllicensetexts,$(_n))) \
+$(call dist-for-goals,droid shareprojects,$(_f):shareprojects/all)\
+$(call dist-for-goals,droid alllicensetexts,$(_n):licensetexts/all)\
+$(eval _allt := $(sort $(_allt)))\
+$(eval $(call _share-projects-rule,$(_f),$(_allt)))\
+$(eval $(call _license-texts-rule,droid,$(_n),$(_allt)))\
+$(eval _f :=)\
+$(evan _n :=)
+endef
+
#------------------------------------------------------------------
# To be used at the end of the build to collect all the uses of
# dist-for-goals, and write them into a file for the packaging step to use.
@@ -52,6 +151,15 @@ endef
# $(1): The file to write
define dist-write-file
$(strip \
+ $(call _add_projects_to_share)\
+ $(if $(strip $(ANDROID_REQUIRE_LICENSE_METADATA)),\
+ $(foreach target,$(sort $(TARGETS_MISSING_LICENSE_METADATA)),$(warning target $(target) missing license metadata))\
+ $(if $(strip $(TARGETS_MISSING_LICENSE_METADATA)),\
+ $(if $(filter true error,$(ANDROID_REQUIRE_LICENSE_METADATA)),\
+ $(error $(words $(sort $(TARGETS_MISSING_LICENSE_METADATA))) targets need license metadata))))\
+ $(foreach t,$(sort $(ALL_NON_MODULES)),$(call record-missing-non-module-dependencies,$(t))) \
+ $(eval $(call report-missing-licenses-rule)) \
+ $(eval $(call report-all-notice-library-names-rule)) \
$(KATI_obsolete_var dist-for-goals,Cannot be used after dist-write-file) \
$(foreach goal,$(sort $(_all_dist_goals)), \
$(eval $$(goal): _dist_$$(goal))) \
diff --git a/core/main.mk b/core/main.mk
index e0efdad61e..c63c6dfde9 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1936,10 +1936,6 @@ ALL_SDK_TARGETS := $(INTERNAL_SDK_TARGET)
sdk: $(ALL_SDK_TARGETS)
$(call dist-for-goals,sdk, \
$(ALL_SDK_TARGETS) \
- $(SYMBOLS_ZIP) \
- $(SYMBOLS_MAPPING) \
- $(COVERAGE_ZIP) \
- $(APPCOMPAT_ZIP) \
$(INSTALLED_BUILD_PROP_TARGET) \
)
endif
diff --git a/core/notice_files.mk b/core/notice_files.mk
index c05d4ea0be..4b67404fd2 100644
--- a/core/notice_files.mk
+++ b/core/notice_files.mk
@@ -125,7 +125,7 @@ local_path := $(LOCAL_PATH)
module_license_metadata :=
ifdef my_register_name
- module_license_metadata := $(call local-intermediates-dir)/$(my_register_name).meta_lic
+ module_license_metadata := $(call local-meta-intermediates-dir)/$(my_register_name).meta_lic
$(foreach target,$(ALL_MODULES.$(my_register_name).BUILT) $(ALL_MODULES.$(my_register_name).INSTALLED) $(my_test_data) $(my_test_config),\
$(eval ALL_TARGETS.$(target).META_LIC := $(module_license_metadata)))
diff --git a/core/tasks/tools/package-modules.mk b/core/tasks/tools/package-modules.mk
index 20a1694682..f89d51eea0 100644
--- a/core/tasks/tools/package-modules.mk
+++ b/core/tasks/tools/package-modules.mk
@@ -21,6 +21,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := $(my_package_name)
LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
LOCAL_LICENSE_CONDITIONS := notice
+LOCAL_LICENSE_PACKAGE_NAME := Android
+LOCAL_NOTICE_FILE := build/soong/licenses/LICENSE
LOCAL_MODULE_CLASS := PACKAGING
LOCAL_MODULE_STEM := $(my_package_name).zip
LOCAL_UNINSTALLABLE_MODULE := true
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 998327e9a0..6f6cd79214 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -120,7 +120,6 @@ PRODUCT_PACKAGES += \
init_system \
input \
installd \
- IntentResolver \
ip \
iptables \
ip-up-vpn \
diff --git a/target/product/sdk.mk b/target/product/sdk.mk
index 96d8cc94e1..fa7e1ad381 100644
--- a/target/product/sdk.mk
+++ b/target/product/sdk.mk
@@ -14,8 +14,11 @@
# limitations under the License.
#
-# Don't modify this file - It's just an alias!
+# This is a simple product that uses configures the minimum amount
+# needed to build the SDK (without the emulator).
-$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk_phone_armv7.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_default.mk)
PRODUCT_NAME := sdk
+PRODUCT_BRAND := Android
+PRODUCT_DEVICE := mainline_x86
diff --git a/tools/compliance/Android.bp b/tools/compliance/Android.bp
index 7a6c4ba4c0..225f3a578b 100644
--- a/tools/compliance/Android.bp
+++ b/tools/compliance/Android.bp
@@ -20,14 +20,20 @@ package {
blueprint_go_binary {
name: "compliance_checkshare",
srcs: ["cmd/checkshare/checkshare.go"],
- deps: ["compliance-module"],
+ deps: [
+ "compliance-module",
+ "soong-response",
+ ],
testSrcs: ["cmd/checkshare/checkshare_test.go"],
}
blueprint_go_binary {
name: "compliancenotice_bom",
srcs: ["cmd/bom/bom.go"],
- deps: ["compliance-module"],
+ deps: [
+ "compliance-module",
+ "soong-response",
+ ],
testSrcs: ["cmd/bom/bom_test.go"],
}
@@ -44,21 +50,30 @@ blueprint_go_binary {
blueprint_go_binary {
name: "compliance_listshare",
srcs: ["cmd/listshare/listshare.go"],
- deps: ["compliance-module"],
+ deps: [
+ "compliance-module",
+ "soong-response",
+ ],
testSrcs: ["cmd/listshare/listshare_test.go"],
}
blueprint_go_binary {
name: "compliance_dumpgraph",
srcs: ["cmd/dumpgraph/dumpgraph.go"],
- deps: ["compliance-module"],
+ deps: [
+ "compliance-module",
+ "soong-response",
+ ],
testSrcs: ["cmd/dumpgraph/dumpgraph_test.go"],
}
blueprint_go_binary {
name: "compliance_dumpresolutions",
srcs: ["cmd/dumpresolutions/dumpresolutions.go"],
- deps: ["compliance-module"],
+ deps: [
+ "compliance-module",
+ "soong-response",
+ ],
testSrcs: ["cmd/dumpresolutions/dumpresolutions_test.go"],
}
@@ -68,6 +83,7 @@ blueprint_go_binary {
deps: [
"compliance-module",
"blueprint-deptools",
+ "soong-response",
],
testSrcs: ["cmd/htmlnotice/htmlnotice_test.go"],
}
@@ -75,7 +91,10 @@ blueprint_go_binary {
blueprint_go_binary {
name: "compliance_rtrace",
srcs: ["cmd/rtrace/rtrace.go"],
- deps: ["compliance-module"],
+ deps: [
+ "compliance-module",
+ "soong-response",
+ ],
testSrcs: ["cmd/rtrace/rtrace_test.go"],
}
@@ -85,6 +104,7 @@ blueprint_go_binary {
deps: [
"compliance-module",
"blueprint-deptools",
+ "soong-response",
],
testSrcs: ["cmd/textnotice/textnotice_test.go"],
}
@@ -95,6 +115,7 @@ blueprint_go_binary {
deps: [
"compliance-module",
"blueprint-deptools",
+ "soong-response",
],
testSrcs: ["cmd/xmlnotice/xmlnotice_test.go"],
}
diff --git a/tools/compliance/cmd/bom/bom.go b/tools/compliance/cmd/bom/bom.go
index b613a1f9ff..187f828057 100644
--- a/tools/compliance/cmd/bom/bom.go
+++ b/tools/compliance/cmd/bom/bom.go
@@ -24,13 +24,11 @@ import (
"path/filepath"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
)
var (
- outputFile = flag.String("o", "-", "Where to write the bill of materials. (default stdout)")
- stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoLicenses = fmt.Errorf("No licenses found")
)
@@ -55,22 +53,10 @@ func (ctx context) strip(installPath string) string {
return installPath
}
-func init() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
-
-Outputs a bill of materials. i.e. the list of installed paths.
-
-Options:
-`, filepath.Base(os.Args[0]))
- flag.PrintDefaults()
- }
-}
-
// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(name, usage string) *multiString {
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
var f multiString
- flag.Var(&f, name, usage)
+ flags.Var(&f, name, usage)
return &f
}
@@ -81,16 +67,52 @@ func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
func main() {
- flag.Parse()
+ 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)
+
+ flags.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
+
+Outputs a bill of materials. i.e. the list of installed paths.
+
+Options:
+`, filepath.Base(os.Args[0]))
+ flags.PrintDefaults()
+ }
+
+ outputFile := flags.String("o", "-", "Where to write the bill of materials. (default stdout)")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
+
+ flags.Parse(expandedArgs)
// 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 {
@@ -118,10 +140,10 @@ func main() {
ctx := &context{ofile, os.Stderr, compliance.FS, *stripPrefix}
- err := billOfMaterials(ctx, flag.Args()...)
+ err := billOfMaterials(ctx, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)
diff --git a/tools/compliance/cmd/checkshare/checkshare.go b/tools/compliance/cmd/checkshare/checkshare.go
index 73bdcb5679..f7b4cd2e39 100644
--- a/tools/compliance/cmd/checkshare/checkshare.go
+++ b/tools/compliance/cmd/checkshare/checkshare.go
@@ -15,6 +15,7 @@
package main
import (
+ "bytes"
"flag"
"fmt"
"io"
@@ -22,13 +23,51 @@ import (
"os"
"path/filepath"
"sort"
+ "strings"
+ "android/soong/response"
"android/soong/tools/compliance"
)
-func init() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s file.meta_lic {file.meta_lic...}
+var (
+ failConflicts = fmt.Errorf("conflicts")
+ failNoneRequested = fmt.Errorf("\nNo metadata files requested")
+ failNoLicenses = fmt.Errorf("No licenses")
+)
+
+// byError orders conflicts by error string
+type byError []compliance.SourceSharePrivacyConflict
+
+func (l byError) Len() int { return len(l) }
+func (l byError) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
+func (l byError) Less(i, j int) bool { return l[i].Error() < l[j].Error() }
+
+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)
+
+ flags.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s {-o outfile} file.meta_lic {file.meta_lic...}
Reports on stderr any targets where policy says that the source both
must and must not be shared. The error report indicates the target, the
@@ -44,41 +83,65 @@ outputs "PASS" to stdout and exits with status 0.
If policy says any source must both be shared and not be shared,
outputs "FAIL" to stdout and exits with status 1.
`, filepath.Base(os.Args[0]))
+ flags.PrintDefaults()
}
-}
-var (
- failConflicts = fmt.Errorf("conflicts")
- failNoneRequested = fmt.Errorf("\nNo metadata files requested")
- failNoLicenses = fmt.Errorf("No licenses")
-)
-
-// byError orders conflicts by error string
-type byError []compliance.SourceSharePrivacyConflict
-
-func (l byError) Len() int { return len(l) }
-func (l byError) Swap(i, j int) { l[i], l[j] = l[j], l[i] }
-func (l byError) Less(i, j int) bool { return l[i].Error() < l[j].Error() }
+ outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
-func main() {
- flag.Parse()
+ flags.Parse(expandedArgs)
// Must specify at least one root target.
- if flag.NArg() == 0 {
- flag.Usage()
+ if flags.NArg() == 0 {
+ flags.Usage()
os.Exit(2)
}
- err := checkShare(os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
+ if len(*outputFile) == 0 {
+ flags.Usage()
+ fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
+ os.Exit(2)
+ } else {
+ dir, err := filepath.Abs(filepath.Dir(*outputFile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
+ os.Exit(1)
+ }
+ fi, err := os.Stat(dir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
+ os.Exit(1)
+ }
+ if !fi.IsDir() {
+ fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
+ os.Exit(1)
+ }
+ }
+
+ var ofile io.Writer
+ ofile = os.Stdout
+ var obuf *bytes.Buffer
+ if *outputFile != "-" {
+ obuf = &bytes.Buffer{}
+ ofile = obuf
+ }
+
+ err := checkShare(ofile, os.Stderr, compliance.FS, flags.Args()...)
if err != nil {
if err != failConflicts {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
}
os.Exit(1)
}
+ if *outputFile != "-" {
+ err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not write output to %q from %q: %s\n", *outputFile, os.Getenv("PWD"), err)
+ os.Exit(1)
+ }
+ }
os.Exit(0)
}
@@ -92,7 +155,7 @@ func checkShare(stdout, stderr io.Writer, rootFS fs.FS, files ...string) error {
// Read the license graph from the license metadata files (*.meta_lic).
licenseGraph, err := compliance.ReadLicenseGraph(rootFS, stderr, files)
if err != nil {
- return fmt.Errorf("Unable to read license metadata file(s) %q: %w\n", files, err)
+ return fmt.Errorf("Unable to read license metadata file(s) %q from %q: %w\n", files, os.Getenv("PWD"), err)
}
if licenseGraph == nil {
return failNoLicenses
diff --git a/tools/compliance/cmd/dumpgraph/dumpgraph.go b/tools/compliance/cmd/dumpgraph/dumpgraph.go
index 32a3fc44cf..56257794a4 100644
--- a/tools/compliance/cmd/dumpgraph/dumpgraph.go
+++ b/tools/compliance/cmd/dumpgraph/dumpgraph.go
@@ -15,6 +15,7 @@
package main
import (
+ "bytes"
"flag"
"fmt"
"io"
@@ -24,14 +25,11 @@ import (
"sort"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
)
var (
- graphViz = flag.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
- labelConditions = flag.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
- stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoLicenses = fmt.Errorf("No licenses found")
)
@@ -55,8 +53,44 @@ func (ctx context) strip(installPath string) string {
return installPath
}
-func init() {
- flag.Usage = func() {
+// newMultiString creates a flag that allows multiple values in an array.
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
+ var f multiString
+ flags.Var(&f, name, usage)
+ return &f
+}
+
+// multiString implements the flag `Value` interface for multiple strings.
+type multiString []string
+
+func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
+func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
+
+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)
+
+ flags.Usage = func() {
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
Outputs space-separated Target Dependency Annotations tuples for each
@@ -70,42 +104,68 @@ target:condition1:condition2 etc.
Options:
`, filepath.Base(os.Args[0]))
- flag.PrintDefaults()
+ flags.PrintDefaults()
}
-}
-// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(name, usage string) *multiString {
- var f multiString
- flag.Var(&f, name, usage)
- return &f
-}
+ graphViz := flags.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
+ labelConditions := flags.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
+ outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-// multiString implements the flag `Value` interface for multiple strings.
-type multiString []string
-
-func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
-func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
-
-func main() {
- flag.Parse()
+ flags.Parse(expandedArgs)
// 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 {
+ flags.Usage()
+ fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
+ os.Exit(2)
+ } else {
+ dir, err := filepath.Abs(filepath.Dir(*outputFile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
+ os.Exit(1)
+ }
+ fi, err := os.Stat(dir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
+ os.Exit(1)
+ }
+ if !fi.IsDir() {
+ fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
+ os.Exit(1)
+ }
+ }
+
+ var ofile io.Writer
+ ofile = os.Stdout
+ var obuf *bytes.Buffer
+ if *outputFile != "-" {
+ obuf = &bytes.Buffer{}
+ ofile = obuf
+ }
+
ctx := &context{*graphViz, *labelConditions, *stripPrefix}
- err := dumpGraph(ctx, os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
+ err := dumpGraph(ctx, ofile, os.Stderr, compliance.FS, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)
}
+ if *outputFile != "-" {
+ err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not write output to %q from %q: %s\n", *outputFile, os.Getenv("PWD"), err)
+ os.Exit(1)
+ }
+ }
os.Exit(0)
}
diff --git a/tools/compliance/cmd/dumpresolutions/dumpresolutions.go b/tools/compliance/cmd/dumpresolutions/dumpresolutions.go
index d02c238846..dc0cf884f5 100644
--- a/tools/compliance/cmd/dumpresolutions/dumpresolutions.go
+++ b/tools/compliance/cmd/dumpresolutions/dumpresolutions.go
@@ -15,6 +15,7 @@
package main
import (
+ "bytes"
"flag"
"fmt"
"io"
@@ -24,15 +25,11 @@ import (
"sort"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
)
var (
- conditions = newMultiString("c", "License condition to resolve. (may be given multiple times)")
- graphViz = flag.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
- labelConditions = flag.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
- stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoLicenses = fmt.Errorf("No licenses found")
)
@@ -57,8 +54,44 @@ func (ctx context) strip(installPath string) string {
return installPath
}
-func init() {
- flag.Usage = func() {
+// newMultiString creates a flag that allows multiple values in an array.
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
+ var f multiString
+ flags.Var(&f, name, usage)
+ return &f
+}
+
+// multiString implements the flag `Value` interface for multiple strings.
+type multiString []string
+
+func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
+func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
+
+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)
+
+ flags.Usage = func() {
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
Outputs a space-separated Target ActsOn Origin Condition tuple for each
@@ -75,32 +108,52 @@ i.e. target:condition1:condition2 etc.
Options:
`, filepath.Base(os.Args[0]))
- flag.PrintDefaults()
+ flags.PrintDefaults()
}
-}
-// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(name, usage string) *multiString {
- var f multiString
- flag.Var(&f, name, usage)
- return &f
-}
+ conditions := newMultiString(flags, "c", "License condition to resolve. (may be given multiple times)")
+ graphViz := flags.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
+ labelConditions := flags.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
+ outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-// multiString implements the flag `Value` interface for multiple strings.
-type multiString []string
-
-func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
-func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
-
-func main() {
- flag.Parse()
+ flags.Parse(expandedArgs)
// 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 {
+ flags.Usage()
+ fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
+ os.Exit(2)
+ } else {
+ dir, err := filepath.Abs(filepath.Dir(*outputFile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
+ os.Exit(1)
+ }
+ fi, err := os.Stat(dir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
+ os.Exit(1)
+ }
+ if !fi.IsDir() {
+ fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
+ os.Exit(1)
+ }
+ }
+
+ var ofile io.Writer
+ ofile = os.Stdout
+ var obuf *bytes.Buffer
+ if *outputFile != "-" {
+ obuf = &bytes.Buffer{}
+ ofile = obuf
+ }
+
lcs := make([]compliance.LicenseCondition, 0, len(*conditions))
for _, name := range *conditions {
lcs = append(lcs, compliance.RecognizedConditionNames[name])
@@ -111,14 +164,21 @@ func main() {
labelConditions: *labelConditions,
stripPrefix: *stripPrefix,
}
- _, err := dumpResolutions(ctx, os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
+ _, err := dumpResolutions(ctx, ofile, os.Stderr, compliance.FS, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)
}
+ if *outputFile != "-" {
+ err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not write output to %q from %q: %s\n", *outputFile, os.Getenv("PWD"), err)
+ os.Exit(1)
+ }
+ }
os.Exit(0)
}
diff --git a/tools/compliance/cmd/htmlnotice/htmlnotice.go b/tools/compliance/cmd/htmlnotice/htmlnotice.go
index e98b27222a..1a4961020e 100644
--- a/tools/compliance/cmd/htmlnotice/htmlnotice.go
+++ b/tools/compliance/cmd/htmlnotice/htmlnotice.go
@@ -26,19 +26,13 @@ import (
"path/filepath"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
"github.com/google/blueprint/deptools"
)
var (
- outputFile = flag.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
- depsFile = flag.String("d", "", "Where to write the deps file")
- includeTOC = flag.Bool("toc", true, "Whether to include a table of contents.")
- product = flag.String("product", "", "The name of the product for which the notice is generated.")
- stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
- title = flag.String("title", "", "The title of the notice file.")
-
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoLicenses = fmt.Errorf("No licenses found")
)
@@ -70,23 +64,10 @@ func (ctx context) strip(installPath string) string {
return installPath
}
-func init() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
-
-Outputs an html NOTICE.html or gzipped NOTICE.html.gz file if the -o filename
-ends with ".gz".
-
-Options:
-`, filepath.Base(os.Args[0]))
- flag.PrintDefaults()
- }
-}
-
// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(name, usage string) *multiString {
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
var f multiString
- flag.Var(&f, name, usage)
+ flags.Var(&f, name, usage)
return &f
}
@@ -97,16 +78,57 @@ func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
func main() {
- flag.Parse()
+ 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)
+
+ flags.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
+
+Outputs an html NOTICE.html or gzipped NOTICE.html.gz file if the -o filename
+ends with ".gz".
+
+Options:
+`, filepath.Base(os.Args[0]))
+ flags.PrintDefaults()
+ }
+
+ outputFile := flags.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
+ depsFile := flags.String("d", "", "Where to write the deps file")
+ includeTOC := flags.Bool("toc", true, "Whether to include a table of contents.")
+ product := flags.String("product", "", "The name of the product for which the notice is generated.")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
+ title := flags.String("title", "", "The title of the notice file.")
+
+ flags.Parse(expandedArgs)
// 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 {
@@ -143,10 +165,10 @@ func main() {
ctx := &context{ofile, os.Stderr, compliance.FS, *includeTOC, *product, *stripPrefix, *title, &deps}
- err := htmlNotice(ctx, flag.Args()...)
+ err := htmlNotice(ctx, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)
diff --git a/tools/compliance/cmd/listshare/listshare.go b/tools/compliance/cmd/listshare/listshare.go
index 7f4038b6c5..31bd1b22ac 100644
--- a/tools/compliance/cmd/listshare/listshare.go
+++ b/tools/compliance/cmd/listshare/listshare.go
@@ -15,6 +15,7 @@
package main
import (
+ "bytes"
"flag"
"fmt"
"io"
@@ -24,12 +25,41 @@ import (
"sort"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
)
-func init() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s file.meta_lic {file.meta_lic...}
+var (
+ failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
+ failNoLicenses = fmt.Errorf("No licenses found")
+)
+
+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)
+
+ flags.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s {-o outfile} file.meta_lic {file.meta_lic...}
Outputs a csv file with 1 project per line in the first field followed
by target:condition pairs describing why the project must be shared.
@@ -39,30 +69,61 @@ Soong module or Make target, and the license condition is either
restricted (e.g. GPL) or reciprocal (e.g. MPL).
`, filepath.Base(os.Args[0]))
}
-}
-var (
- failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
- failNoLicenses = fmt.Errorf("No licenses found")
-)
+ outputFile := flags.String("o", "-", "Where to write the list of projects to share. (default stdout)")
-func main() {
- flag.Parse()
+ flags.Parse(expandedArgs)
// Must specify at least one root target.
- if flag.NArg() == 0 {
- flag.Usage()
+ if flags.NArg() == 0 {
+ flags.Usage()
os.Exit(2)
}
- err := listShare(os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
+ if len(*outputFile) == 0 {
+ flags.Usage()
+ fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
+ os.Exit(2)
+ } else {
+ dir, err := filepath.Abs(filepath.Dir(*outputFile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
+ os.Exit(1)
+ }
+ fi, err := os.Stat(dir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
+ os.Exit(1)
+ }
+ if !fi.IsDir() {
+ fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
+ os.Exit(1)
+ }
+ }
+
+ var ofile io.Writer
+ ofile = os.Stdout
+ var obuf *bytes.Buffer
+ if *outputFile != "-" {
+ obuf = &bytes.Buffer{}
+ ofile = obuf
+ }
+
+ err := listShare(ofile, os.Stderr, compliance.FS, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)
}
+ if *outputFile != "-" {
+ err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not write output to %q from %q: %s\n", *outputFile, os.Getenv("PWD"), err)
+ os.Exit(1)
+ }
+ }
os.Exit(0)
}
@@ -76,7 +137,7 @@ func listShare(stdout, stderr io.Writer, rootFS fs.FS, files ...string) error {
// Read the license graph from the license metadata files (*.meta_lic).
licenseGraph, err := compliance.ReadLicenseGraph(rootFS, stderr, files)
if err != nil {
- return fmt.Errorf("Unable to read license metadata file(s) %q: %v\n", files, err)
+ return fmt.Errorf("Unable to read license metadata file(s) %q from %q: %v\n", files, os.Getenv("PWD"), err)
}
if licenseGraph == nil {
return failNoLicenses
diff --git a/tools/compliance/cmd/rtrace/rtrace.go b/tools/compliance/cmd/rtrace/rtrace.go
index 91171c42e7..667cdcea87 100644
--- a/tools/compliance/cmd/rtrace/rtrace.go
+++ b/tools/compliance/cmd/rtrace/rtrace.go
@@ -15,6 +15,7 @@
package main
import (
+ "bytes"
"flag"
"fmt"
"io"
@@ -24,21 +25,19 @@ import (
"sort"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
)
var (
- sources = newMultiString("rtrace", "Projects or metadata files to trace back from. (required; multiple allowed)")
- stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoSources = fmt.Errorf("\nNo projects or metadata files to trace back from")
failNoLicenses = fmt.Errorf("No licenses found")
)
type context struct {
- sources []string
- stripPrefix []string
+ sources []string
+ stripPrefix []string
}
func (ctx context) strip(installPath string) string {
@@ -54,8 +53,44 @@ func (ctx context) strip(installPath string) string {
return installPath
}
-func init() {
- flag.Usage = func() {
+// newMultiString creates a flag that allows multiple values in an array.
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
+ var f multiString
+ flags.Var(&f, name, usage)
+ return &f
+}
+
+// multiString implements the flag `Value` interface for multiple strings.
+type multiString []string
+
+func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
+func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
+
+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)
+
+ flags.Usage = func() {
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
Outputs a space-separated Target ActsOn Origin Condition tuple for each
@@ -72,50 +107,75 @@ i.e. target:condition1:condition2 etc.
Options:
`, filepath.Base(os.Args[0]))
- flag.PrintDefaults()
+ flags.PrintDefaults()
}
-}
-// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(name, usage string) *multiString {
- var f multiString
- flag.Var(&f, name, usage)
- return &f
-}
+ outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
+ sources := newMultiString(flags, "rtrace", "Projects or metadata files to trace back from. (required; multiple allowed)")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
-// multiString implements the flag `Value` interface for multiple strings.
-type multiString []string
-
-func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
-func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
-
-func main() {
- flag.Parse()
+ flags.Parse(expandedArgs)
// Must specify at least one root target.
- if flag.NArg() == 0 {
- flag.Usage()
+ if flags.NArg() == 0 {
+ flags.Usage()
os.Exit(2)
}
if len(*sources) == 0 {
- flag.Usage()
+ flags.Usage()
fmt.Fprintf(os.Stderr, "\nMust specify at least 1 --rtrace source.\n")
os.Exit(2)
}
+ if len(*outputFile) == 0 {
+ flags.Usage()
+ fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
+ os.Exit(2)
+ } else {
+ dir, err := filepath.Abs(filepath.Dir(*outputFile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
+ os.Exit(1)
+ }
+ fi, err := os.Stat(dir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
+ os.Exit(1)
+ }
+ if !fi.IsDir() {
+ fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
+ os.Exit(1)
+ }
+ }
+
+ var ofile io.Writer
+ ofile = os.Stdout
+ var obuf *bytes.Buffer
+ if *outputFile != "-" {
+ obuf = &bytes.Buffer{}
+ ofile = obuf
+ }
+
ctx := &context{
- sources: *sources,
- stripPrefix: *stripPrefix,
+ sources: *sources,
+ stripPrefix: *stripPrefix,
}
- _, err := traceRestricted(ctx, os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
+ _, err := traceRestricted(ctx, ofile, os.Stderr, compliance.FS, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)
}
+ if *outputFile != "-" {
+ err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "could not write output to %q from %q: %s\n", *outputFile, os.Getenv("PWD"), err)
+ os.Exit(1)
+ }
+ }
os.Exit(0)
}
diff --git a/tools/compliance/cmd/shippedlibs/shippedlibs.go b/tools/compliance/cmd/shippedlibs/shippedlibs.go
index 9d25dd3de9..add6dd63e8 100644
--- a/tools/compliance/cmd/shippedlibs/shippedlibs.go
+++ b/tools/compliance/cmd/shippedlibs/shippedlibs.go
@@ -39,9 +39,6 @@ type context struct {
rootFS fs.FS
}
-func init() {
-}
-
func main() {
var expandedArgs []string
for _, arg := range os.Args[1:] {
diff --git a/tools/compliance/cmd/textnotice/textnotice.go b/tools/compliance/cmd/textnotice/textnotice.go
index cfa0859a2a..9beaf58ad1 100644
--- a/tools/compliance/cmd/textnotice/textnotice.go
+++ b/tools/compliance/cmd/textnotice/textnotice.go
@@ -25,18 +25,13 @@ import (
"path/filepath"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
"github.com/google/blueprint/deptools"
)
var (
- outputFile = flag.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
- depsFile = flag.String("d", "", "Where to write the deps file")
- product = flag.String("product", "", "The name of the product for which the notice is generated.")
- stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
- title = flag.String("title", "", "The title of the notice file.")
-
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoLicenses = fmt.Errorf("No licenses found")
)
@@ -67,22 +62,10 @@ func (ctx context) strip(installPath string) string {
return installPath
}
-func init() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
-
-Outputs a text NOTICE file.
-
-Options:
-`, filepath.Base(os.Args[0]))
- flag.PrintDefaults()
- }
-}
-
// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(name, usage string) *multiString {
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
var f multiString
- flag.Var(&f, name, usage)
+ flags.Var(&f, name, usage)
return &f
}
@@ -93,16 +76,55 @@ func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
func main() {
- flag.Parse()
+ 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)
+
+ flags.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
+
+Outputs a text NOTICE file.
+
+Options:
+`, filepath.Base(os.Args[0]))
+ flags.PrintDefaults()
+ }
+
+ outputFile := flags.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
+ depsFile := flags.String("d", "", "Where to write the deps file")
+ product := flags.String("product", "", "The name of the product for which the notice is generated.")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
+ title := flags.String("title", "", "The title of the notice file.")
+
+ flags.Parse(expandedArgs)
// 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 {
@@ -139,10 +161,10 @@ func main() {
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, *title, &deps}
- err := textNotice(ctx, flag.Args()...)
+ err := textNotice(ctx, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)
diff --git a/tools/compliance/cmd/xmlnotice/xmlnotice.go b/tools/compliance/cmd/xmlnotice/xmlnotice.go
index 84859d738a..2097b7c5e1 100644
--- a/tools/compliance/cmd/xmlnotice/xmlnotice.go
+++ b/tools/compliance/cmd/xmlnotice/xmlnotice.go
@@ -26,18 +26,13 @@ import (
"path/filepath"
"strings"
+ "android/soong/response"
"android/soong/tools/compliance"
"github.com/google/blueprint/deptools"
)
var (
- outputFile = flag.String("o", "-", "Where to write the NOTICE xml or xml.gz file. (default stdout)")
- depsFile = flag.String("d", "", "Where to write the deps file")
- product = flag.String("product", "", "The name of the product for which the notice is generated.")
- stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
- title = flag.String("title", "", "The title of the notice file.")
-
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
failNoLicenses = fmt.Errorf("No licenses found")
)
@@ -68,23 +63,10 @@ func (ctx context) strip(installPath string) string {
return installPath
}
-func init() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
-
-Outputs an xml NOTICE.xml or gzipped NOTICE.xml.gz file if the -o filename ends
-with ".gz".
-
-Options:
-`, filepath.Base(os.Args[0]))
- flag.PrintDefaults()
- }
-}
-
// newMultiString creates a flag that allows multiple values in an array.
-func newMultiString(name, usage string) *multiString {
+func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
var f multiString
- flag.Var(&f, name, usage)
+ flags.Var(&f, name, usage)
return &f
}
@@ -95,16 +77,56 @@ func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
func main() {
- flag.Parse()
+ 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)
+
+ flags.Usage = func() {
+ fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
+
+Outputs an xml NOTICE.xml or gzipped NOTICE.xml.gz file if the -o filename ends
+with ".gz".
+
+Options:
+`, filepath.Base(os.Args[0]))
+ flags.PrintDefaults()
+ }
+
+ outputFile := flags.String("o", "-", "Where to write the NOTICE xml or xml.gz file. (default stdout)")
+ depsFile := flags.String("d", "", "Where to write the deps file")
+ product := flags.String("product", "", "The name of the product for which the notice is generated.")
+ stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
+ title := flags.String("title", "", "The title of the notice file.")
+
+ flags.Parse(expandedArgs)
// 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 {
@@ -141,10 +163,10 @@ func main() {
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, *title, &deps}
- err := xmlNotice(ctx, flag.Args()...)
+ err := xmlNotice(ctx, flags.Args()...)
if err != nil {
if err == failNoneRequested {
- flag.Usage()
+ flags.Usage()
}
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
os.Exit(1)