Merge "Remove unit tests jar from suites"
diff --git a/core/Makefile b/core/Makefile
index d85bd76..30a41d1 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -40,6 +40,10 @@
)
endef
+# Phony target to check PRODUCT_COPY_FILES copy pairs don't contain ELF files
+.PHONY: check-elf-prebuilt-product-copy-files
+check-elf-prebuilt-product-copy-files:
+
check_elf_prebuilt_product_copy_files := true
ifneq (,$(filter true,$(BUILD_BROKEN_ELF_PREBUILT_PRODUCT_COPY_FILES)))
check_elf_prebuilt_product_copy_files :=
@@ -1666,16 +1670,15 @@
INSTALLED_FILES_FILE_RECOVERY := $(PRODUCT_OUT)/installed-files-recovery.txt
INSTALLED_FILES_JSON_RECOVERY := $(INSTALLED_FILES_FILE_RECOVERY:.txt=.json)
+ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
+INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET)
+endif
+
# TODO(b/30414428): Can't depend on INTERNAL_RECOVERYIMAGE_FILES alone like other
# INSTALLED_FILES_FILE_* rules. Because currently there're cp/rsync/rm commands in
# build-recoveryimage-target, which would touch the files under TARGET_RECOVERY_OUT and race with
# the call to FILELIST.
-ifeq ($(BOARD_USES_RECOVERY_AS_BOOT),true)
-INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET)
-$(INSTALLED_FILES_FILE_RECOVERY): $(INSTALLED_BOOTIMAGE_TARGET)
-else
-$(INSTALLED_FILES_FILE_RECOVERY): $(INSTALLED_RECOVERYIMAGE_TARGET)
-endif
+$(INSTALLED_FILES_FILE_RECOVERY): $(INTERNAL_RECOVERY_RAMDISK_FILES_TIMESTAMP)
$(INSTALLED_FILES_FILE_RECOVERY): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_RECOVERY)
$(INSTALLED_FILES_FILE_RECOVERY): $(INTERNAL_RECOVERYIMAGE_FILES) $(FILESLIST) $(FILESLIST_UTIL)
@@ -2467,6 +2470,15 @@
# -----------------------------------------------------------------
ifdef BUILDING_SYSTEM_IMAGE
+# Install system linker configuration
+# Collect all available stub libraries installed in system and install with predefined linker configuration
+SYSTEM_LINKER_CONFIG := $(TARGET_OUT)/etc/linker.config.pb
+$(SYSTEM_LINKER_CONFIG) : $(INTERNAL_SYSTEMIMAGE_FILES) $(LINKER_CONFIG_PATH_system_linker_config) | conv_linker_config
+ $(HOST_OUT_EXECUTABLES)/conv_linker_config systemprovide --source $(LINKER_CONFIG_PATH_system_linker_config)\
+ --output $@ --value "$(STUB_LIBRARIES)" --system "$(TARGET_OUT)"
+
+FULL_SYSTEMIMAGE_DEPS += $(SYSTEM_LINKER_CONFIG)
+
# installed file list
# Depending on anything that $(BUILT_SYSTEMIMAGE) depends on.
# We put installed-files.txt ahead of image itself in the dependency graph
@@ -3951,6 +3963,7 @@
fec \
fs_config \
generate_verity_key \
+ host_init_verifier \
img2simg \
img_from_target_files \
imgdiff \
diff --git a/core/definitions.mk b/core/definitions.mk
index 8219f82..0230340 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -2493,15 +2493,25 @@
# $(2): destination file
# $(3): message to print on error
define copy-non-elf-file-checked
-$(2): $(1) $(LLVM_READOBJ)
- @echo "Copy non-ELF: $$@"
+$(eval check_non_elf_file_timestamp := \
+ $(call intermediates-dir-for,FAKE,check-non-elf-file-timestamps)/$(2).timestamp)
+$(check_non_elf_file_timestamp): $(1) $(LLVM_READOBJ)
+ @echo "Check non-ELF: $$<"
+ $(hide) mkdir -p "$$(dir $$@)"
+ $(hide) rm -f "$$@"
$(hide) \
- if $(LLVM_READOBJ) -h $$< >/dev/null 2>&1; then \
- $(call echo-error,$$@,$(3)); \
- $(call echo-error,$$@,found ELF file: $$<); \
+ if $(LLVM_READOBJ) -h "$$<" >/dev/null 2>&1; then \
+ $(call echo-error,$(2),$(3)); \
+ $(call echo-error,$(2),found ELF file: $$<); \
false; \
fi
+ $(hide) touch "$$@"
+
+$(2): $(1) $(check_non_elf_file_timestamp)
+ @echo "Copy non-ELF: $$@"
$$(copy-file-to-target)
+
+check-elf-prebuilt-product-copy-files: $(check_non_elf_file_timestamp)
endef
# The -t option to acp and the -p option to cp is
diff --git a/core/soong_config.mk b/core/soong_config.mk
index 06b5555..250efb2 100644
--- a/core/soong_config.mk
+++ b/core/soong_config.mk
@@ -210,6 +210,9 @@
$(call add_json_bool, EnforceProductPartitionInterface, $(PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE))
$(call add_json_str, DeviceCurrentApiLevelForVendorModules, $(BOARD_CURRENT_API_LEVEL_FOR_VENDOR_MODULES))
+$(call add_json_bool, EnforceInterPartitionJavaSdkLibrary, $(PRODUCT_ENFORCE_INTER_PARTITION_JAVA_SDK_LIBRARY))
+$(call add_json_list, InterPartitionJavaLibraryAllowList, $(PRODUCT_INTER_PARTITION_JAVA_LIBRARY_ALLOWLIST))
+
$(call add_json_bool, InstallExtraFlattenedApexes, $(PRODUCT_INSTALL_EXTRA_FLATTENED_APEXES))
$(call add_json_bool, BoardUsesRecoveryAsBoot, $(BOARD_USES_RECOVERY_AS_BOOT))
diff --git a/core/tasks/mts.mk b/core/tasks/mts.mk
index e800505..e084856 100644
--- a/core/tasks/mts.mk
+++ b/core/tasks/mts.mk
@@ -13,13 +13,20 @@
# limitations under the License.
ifneq ($(wildcard test/mts/README.md),)
-test_suite_name := mts
-test_suite_tradefed := mts-tradefed
-test_suite_readme := test/mts/README.md
-include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk
+mts_test_suites :=
+mts_test_suites += mts
-.PHONY: mts
-mts: $(compatibility_zip)
-$(call dist-for-goals, mts, $(compatibility_zip))
+$(foreach module, $(mts_modules), $(eval mts_test_suites += mts-$(module)))
+
+$(foreach suite, $(mts_test_suites), \
+ $(eval test_suite_name := $(suite)) \
+ $(eval test_suite_tradefed := mts-tradefed) \
+ $(eval test_suite_readme := test/mts/README.md) \
+ $(eval include $(BUILD_SYSTEM)/tasks/tools/compatibility.mk) \
+ $(eval .PHONY: $(suite)) \
+ $(eval $(suite): $(compatibility_zip)) \
+ $(eval $(call dist-for-goals, $(suite), $(compatibility_zip))) \
+)
+
endif
diff --git a/rbesetup.sh b/rbesetup.sh
index 410ed86..ec39e6e 100644
--- a/rbesetup.sh
+++ b/rbesetup.sh
@@ -65,7 +65,10 @@
function _set_rbe_vars() {
unset USE_GOMA
export USE_RBE="true"
- export RBE_CXX_EXEC_STRATEGY="remote_local_fallback"
+ export RBE_CXX_EXEC_STRATEGY="racing"
+ export RBE_JAVAC_EXEC_STRATEGY="racing"
+ export RBE_R8_EXEC_STRATEGY="racing"
+ export RBE_D8_EXEC_STRATEGY="racing"
export RBE_use_unified_cas_ops="true"
export RBE_JAVAC=1
export RBE_R8=1
diff --git a/target/product/base_system.mk b/target/product/base_system.mk
index 4d92db7..1b4c8d9 100644
--- a/target/product/base_system.mk
+++ b/target/product/base_system.mk
@@ -323,45 +323,12 @@
tz_version_host \
tz_version_host_tzdata_apex \
-ifeq ($(ART_APEX_JARS),)
-$(error ART_APEX_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
-endif
-
-# The order matters for runtime class lookup performance.
-PRODUCT_BOOT_JARS := \
- $(ART_APEX_JARS) \
- framework-minus-apex \
- ext \
- com.android.i18n:core-icu4j \
- telephony-common \
- voip-common \
- ims-common
-
-PRODUCT_UPDATABLE_BOOT_JARS := \
- com.android.conscrypt:conscrypt \
- com.android.media:updatable-media \
- com.android.mediaprovider:framework-mediaprovider \
- com.android.os.statsd:framework-statsd \
- com.android.permission:framework-permission \
- com.android.sdkext:framework-sdkextensions \
- com.android.wifi:framework-wifi \
- com.android.tethering:framework-tethering
PRODUCT_COPY_FILES += \
system/core/rootdir/init.usb.rc:system/etc/init/hw/init.usb.rc \
system/core/rootdir/init.usb.configfs.rc:system/etc/init/hw/init.usb.configfs.rc \
system/core/rootdir/etc/hosts:system/etc/hosts
-# Add the compatibility library that is needed when android.test.base
-# is removed from the bootclasspath.
-# Default to excluding android.test.base from the bootclasspath.
-ifneq ($(REMOVE_ATB_FROM_BCP),false)
-PRODUCT_PACKAGES += framework-atb-backward-compatibility
-PRODUCT_BOOT_JARS += framework-atb-backward-compatibility
-else
-PRODUCT_BOOT_JARS += android.test.base
-endif
-
PRODUCT_COPY_FILES += system/core/rootdir/init.zygote32.rc:system/etc/init/hw/init.zygote32.rc
PRODUCT_SYSTEM_PROPERTIES += ro.zygote?=zygote32
@@ -422,4 +389,5 @@
PRODUCT_COPY_FILES += $(call add-to-product-copy-files-if-exists,\
frameworks/base/config/dirty-image-objects:system/etc/dirty-image-objects)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/bootclasspath.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/runtime_libart.mk)
diff --git a/target/product/bootclasspath.mk b/target/product/bootclasspath.mk
new file mode 100644
index 0000000..60dd071
--- /dev/null
+++ b/target/product/bootclasspath.mk
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2020 The Android Open Source Project
+#
+# 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.
+#
+
+ifeq ($(ART_APEX_JARS),)
+ $(error ART_APEX_JARS is empty; cannot initialize PRODUCT_BOOT_JARS variable)
+endif
+
+# The order matters for runtime class lookup performance.
+PRODUCT_BOOT_JARS := \
+ $(ART_APEX_JARS) \
+ framework-minus-apex \
+ ext \
+ com.android.i18n:core-icu4j \
+ telephony-common \
+ voip-common \
+ ims-common
+
+PRODUCT_UPDATABLE_BOOT_JARS := \
+ com.android.conscrypt:conscrypt \
+ com.android.media:updatable-media \
+ com.android.mediaprovider:framework-mediaprovider \
+ com.android.os.statsd:framework-statsd \
+ com.android.permission:framework-permission \
+ com.android.sdkext:framework-sdkextensions \
+ com.android.wifi:framework-wifi \
+ com.android.tethering:framework-tethering
+
+# Add the compatibility library that is needed when android.test.base
+# is removed from the bootclasspath.
+# Default to excluding android.test.base from the bootclasspath.
+ifneq ($(REMOVE_ATB_FROM_BCP),false)
+ PRODUCT_PACKAGES += framework-atb-backward-compatibility
+ PRODUCT_BOOT_JARS += framework-atb-backward-compatibility
+else
+ PRODUCT_BOOT_JARS += android.test.base
+endif
diff --git a/target/product/virtual_ab_ota/README.md b/target/product/virtual_ab_ota/README.md
index c1d0d7d..2d40c03 100644
--- a/target/product/virtual_ab_ota/README.md
+++ b/target/product/virtual_ab_ota/README.md
@@ -8,6 +8,8 @@
launch.mk
|- retrofit.mk
|- plus_non_ab.mk
+
+launch_with_vendor_ramdisk.mk
|- compression.mk
compression_retrofit.mk
diff --git a/target/product/virtual_ab_ota/compression.mk b/target/product/virtual_ab_ota/compression.mk
index 2251187..1dd8643 100644
--- a/target/product/virtual_ab_ota/compression.mk
+++ b/target/product/virtual_ab_ota/compression.mk
@@ -14,7 +14,7 @@
# limitations under the License.
#
-$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/launch.mk)
+$(call inherit-product, $(SRC_TARGET_DIR)/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk)
PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.compression.enabled=true
diff --git a/target/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk b/target/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk
new file mode 100644
index 0000000..bc81b33
--- /dev/null
+++ b/target/product/virtual_ab_ota/launch_with_vendor_ramdisk.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2020 The Android Open-Source Project
+#
+# 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.
+#
+
+# Devices launching with Virtual A/B and has a vendor_boot partition is
+# preferred to inherit from this makefile instead of launch.mk.
+
+PRODUCT_VIRTUAL_AB_OTA := true
+
+PRODUCT_VENDOR_PROPERTIES += ro.virtual_ab.enabled=true
+
+PRODUCT_PACKAGES += \
+ linker.vendor_ramdisk \
+ e2fsck.vendor_ramdisk \
diff --git a/tools/fs_config/fs_config.go b/tools/fs_config/fs_config.go
index 16bcefa..4c324fb 100644
--- a/tools/fs_config/fs_config.go
+++ b/tools/fs_config/fs_config.go
@@ -48,10 +48,10 @@
path := android.PathForModuleGen(ctx, "empty")
t.paths = android.Paths{path}
- rule := android.NewRuleBuilder()
+ rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().Text("rm -rf").Output(path)
rule.Command().Text("touch").Output(path)
- rule.Build(pctx, ctx, "fs_config_empty", "create empty file")
+ rule.Build("fs_config_empty", "create empty file")
}
}
diff --git a/tools/releasetools/Android.bp b/tools/releasetools/Android.bp
index 11fb584..cafc2bb 100644
--- a/tools/releasetools/Android.bp
+++ b/tools/releasetools/Android.bp
@@ -435,6 +435,7 @@
],
required: [
"checkvintf",
+ "host_init_verifier",
],
target: {
darwin: {
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 149deda..bae0b20 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -1102,6 +1102,29 @@
return merged_dict
+def PartitionMapFromTargetFiles(target_files_dir):
+ """Builds a map from partition -> path within an extracted target files directory."""
+ # Keep possible_subdirs in sync with build/make/core/board_config.mk.
+ possible_subdirs = {
+ "system": ["SYSTEM"],
+ "vendor": ["VENDOR", "SYSTEM/vendor"],
+ "product": ["PRODUCT", "SYSTEM/product"],
+ "system_ext": ["SYSTEM_EXT", "SYSTEM/system_ext"],
+ "odm": ["ODM", "VENDOR/odm", "SYSTEM/vendor/odm"],
+ "vendor_dlkm": [
+ "VENDOR_DLKM", "VENDOR/vendor_dlkm", "SYSTEM/vendor/vendor_dlkm"
+ ],
+ "odm_dlkm": ["ODM_DLKM", "VENDOR/odm_dlkm", "SYSTEM/vendor/odm_dlkm"],
+ }
+ partition_map = {}
+ for partition, subdirs in possible_subdirs.items():
+ for subdir in subdirs:
+ if os.path.exists(os.path.join(target_files_dir, subdir)):
+ partition_map[partition] = subdir
+ break
+ return partition_map
+
+
def SharedUidPartitionViolations(uid_dict, partition_groups):
"""Checks for APK sharedUserIds that cross partition group boundaries.
@@ -1134,6 +1157,36 @@
return errors
+def RunHostInitVerifier(product_out, partition_map):
+ """Runs host_init_verifier on the init rc files within partitions.
+
+ host_init_verifier searches the etc/init path within each partition.
+
+ Args:
+ product_out: PRODUCT_OUT directory, containing partition directories.
+ partition_map: A map of partition name -> relative path within product_out.
+ """
+ allowed_partitions = ("system", "system_ext", "product", "vendor", "odm")
+ cmd = ["host_init_verifier"]
+ for partition, path in partition_map.items():
+ if partition not in allowed_partitions:
+ raise ExternalError("Unable to call host_init_verifier for partition %s" %
+ partition)
+ cmd.extend(["--out_%s" % partition, os.path.join(product_out, path)])
+ # Add --property-contexts if the file exists on the partition.
+ property_contexts = "%s_property_contexts" % (
+ "plat" if partition == "system" else partition)
+ property_contexts_path = os.path.join(product_out, path, "etc", "selinux",
+ property_contexts)
+ if os.path.exists(property_contexts_path):
+ cmd.append("--property-contexts=%s" % property_contexts_path)
+ # Add the passwd file if the file exists on the partition.
+ passwd_path = os.path.join(product_out, path, "etc", "passwd")
+ if os.path.exists(passwd_path):
+ cmd.extend(["-p", passwd_path])
+ return RunAndCheckOutput(cmd)
+
+
def AppendAVBSigningArgs(cmd, partition):
"""Append signing arguments for avbtool."""
# e.g., "--key path/to/signing_key --algorithm SHA256_RSA4096"
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index b1b4a16..9360d7b 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -951,18 +951,15 @@
if not check_target_files_vintf.CheckVintf(output_target_files_temp_dir):
raise RuntimeError('Incompatible VINTF metadata')
+ partition_map = common.PartitionMapFromTargetFiles(
+ output_target_files_temp_dir)
+
# Generate and check for cross-partition violations of sharedUserId
# values in APKs. This requires the input target-files packages to contain
# *.apk files.
shareduid_violation_modules = os.path.join(
output_target_files_temp_dir, 'META', 'shareduid_violation_modules.json')
with open(shareduid_violation_modules, 'w') as f:
- framework_partitions = item_list_to_partition_set(framework_item_list)
- vendor_partitions = item_list_to_partition_set(vendor_item_list)
-
- partition_map = {}
- for partition in (framework_partitions.union(vendor_partitions)):
- partition_map[partition.lower()] = partition.upper()
violation = find_shareduid_violation.FindShareduidViolation(
output_target_files_temp_dir, partition_map)
@@ -970,6 +967,8 @@
f.write(violation)
# Check for violations across the input builds' partition groups.
+ framework_partitions = item_list_to_partition_set(framework_item_list)
+ vendor_partitions = item_list_to_partition_set(vendor_item_list)
shareduid_errors = common.SharedUidPartitionViolations(
json.loads(violation), [framework_partitions, vendor_partitions])
if shareduid_errors:
@@ -978,6 +977,17 @@
raise ValueError('sharedUserId APK error. See %s' %
shareduid_violation_modules)
+ # Run host_init_verifier on the combined init rc files.
+ filtered_partitions = {
+ partition: path
+ for partition, path in partition_map.items()
+ # host_init_verifier checks only the following partitions:
+ if partition in ['system', 'system_ext', 'product', 'vendor', 'odm']
+ }
+ common.RunHostInitVerifier(
+ product_out=output_target_files_temp_dir,
+ partition_map=filtered_partitions)
+
generate_images(output_target_files_temp_dir, rebuild_recovery)
generate_super_empty_image(output_target_files_temp_dir, output_super_empty)
diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py
index 0b368f9..ecd759c 100644
--- a/tools/releasetools/test_common.py
+++ b/tools/releasetools/test_common.py
@@ -996,6 +996,27 @@
},
sparse_image.file_map)
+ def test_PartitionMapFromTargetFiles(self):
+ target_files_dir = common.MakeTempDir()
+ os.makedirs(os.path.join(target_files_dir, 'SYSTEM'))
+ os.makedirs(os.path.join(target_files_dir, 'SYSTEM', 'vendor'))
+ os.makedirs(os.path.join(target_files_dir, 'PRODUCT'))
+ os.makedirs(os.path.join(target_files_dir, 'SYSTEM', 'product'))
+ os.makedirs(os.path.join(target_files_dir, 'SYSTEM', 'vendor', 'odm'))
+ os.makedirs(os.path.join(target_files_dir, 'VENDOR_DLKM'))
+ partition_map = common.PartitionMapFromTargetFiles(target_files_dir)
+ self.assertDictEqual(
+ partition_map,
+ {
+ 'system': 'SYSTEM',
+ 'vendor': 'SYSTEM/vendor',
+ # Prefer PRODUCT over SYSTEM/product
+ 'product': 'PRODUCT',
+ 'odm': 'SYSTEM/vendor/odm',
+ 'vendor_dlkm': 'VENDOR_DLKM',
+ # No system_ext or odm_dlkm
+ })
+
def test_SharedUidPartitionViolations(self):
uid_dict = {
'android.uid.phone': {
diff --git a/tools/signapk/Android.bp b/tools/signapk/Android.bp
index f5b2ba7..b90f010 100644
--- a/tools/signapk/Android.bp
+++ b/tools/signapk/Android.bp
@@ -27,7 +27,7 @@
"conscrypt-unbundled",
],
- required: ["libconscrypt_openjdk_jni"],
+ jni_libs: ["libconscrypt_openjdk_jni"],
// The post-build signing tools need signapk.jar (and its shared libraries,
// handled in their own Android.bp files)
diff --git a/tools/warn/html_writer.py b/tools/warn/html_writer.py
index b8d3fe6..026a6d0 100644
--- a/tools/warn/html_writer.py
+++ b/tools/warn/html_writer.py
@@ -359,6 +359,25 @@
csvwriter.writerow([total, '', 'All warnings'])
+def dump_csv_with_description(csvwriter, warning_records, warning_messages,
+ warn_patterns, project_names):
+ """Outputs all the warning messages by project."""
+ csv_output = []
+ for record in warning_records:
+ project_name = project_names[record[1]]
+ pattern = warn_patterns[record[0]]
+ severity = pattern['severity'].header
+ category = pattern['category']
+ description = pattern['description']
+ warning = warning_messages[record[2]]
+ csv_output.append([project_name, severity,
+ category, description,
+ warning])
+ csv_output = sorted(csv_output)
+ for output in csv_output:
+ csvwriter.writerow(output)
+
+
# Return s with escaped backslash and quotation characters.
def escape_string(s):
return s.replace('\\', '\\\\').replace('"', '\\"')
@@ -666,6 +685,12 @@
with open(flags.csvpath, 'w') as f:
dump_csv(csv.writer(f, lineterminator='\n'), warn_patterns)
+ if flags.csvwithdescription:
+ with open(flags.csvwithdescription, 'w') as f:
+ dump_csv_with_description(csv.writer(f, lineterminator='\n'),
+ warning_records, warning_messages,
+ warn_patterns, project_names)
+
if flags.gencsv:
dump_csv(csv.writer(sys.stdout, lineterminator='\n'), warn_patterns)
else:
diff --git a/tools/warn/warn_common.py b/tools/warn/warn_common.py
index 68ed995..b2dd8ab 100755
--- a/tools/warn/warn_common.py
+++ b/tools/warn/warn_common.py
@@ -77,6 +77,9 @@
help='Save CSV warning file to the passed path')
parser.add_argument('--gencsv', action='store_true',
help='Generate CSV file with number of various warnings')
+ parser.add_argument('--csvwithdescription', default='',
+ help="""Save CSV warning file to the passed path this csv
+ will contain all the warning descriptions""")
parser.add_argument('--byproject', action='store_true',
help='Separate warnings in HTML output by project names')
parser.add_argument('--url', default='',