Merge "Add targets for building individual modules using javac"
diff --git a/core/binary.mk b/core/binary.mk
index 058c7e4..e11ab89 100644
--- a/core/binary.mk
+++ b/core/binary.mk
@@ -1365,13 +1365,17 @@
####################################################
my_link_type := $(intermediates)/link_type
+all_link_types: $(my_link_type)
ifdef LOCAL_SDK_VERSION
-$(my_link_type): PRIVATE_LINK_TYPE := ndk
-$(my_link_type): PRIVATE_ALLOWED_TYPES := ndk
+$(my_link_type): PRIVATE_LINK_TYPE := native:ndk
+$(my_link_type): PRIVATE_WARN_TYPES :=
+$(my_link_type): PRIVATE_ALLOWED_TYPES := native:ndk
else
-$(my_link_type): PRIVATE_LINK_TYPE := platform
-$(my_link_type): PRIVATE_ALLOWED_TYPES := (ndk|platform)
+$(my_link_type): PRIVATE_LINK_TYPE := native:platform
+$(my_link_type): PRIVATE_WARN_TYPES :=
+$(my_link_type): PRIVATE_ALLOWED_TYPES := native:ndk native:platform
endif
+$(eval $(call link-type-partitions,$(my_link_type)))
my_link_type_deps := $(strip \
$(foreach l,$(my_whole_static_libraries) $(my_static_libraries), \
$(call intermediates-dir-for,STATIC_LIBRARIES,$(l),$(my_kind),,$(LOCAL_2ND_ARCH_VAR_PREFIX),$(my_host_cross))/link_type))
@@ -1383,16 +1387,9 @@
$(my_link_type): PRIVATE_DEPS := $(my_link_type_deps)
$(my_link_type): PRIVATE_MODULE := $(LOCAL_MODULE)
$(my_link_type): PRIVATE_MAKEFILE := $(LOCAL_MODULE_MAKEFILE)
-$(my_link_type): $(my_link_type_deps)
+$(my_link_type): $(my_link_type_deps) $(CHECK_LINK_TYPE)
@echo Check module type: $@
- $(hide) mkdir -p $(dir $@) && rm -f $@
-ifdef my_link_type_deps
- $(hide) for f in $(PRIVATE_DEPS); do \
- grep -qE '^$(PRIVATE_ALLOWED_TYPES)$$' $$f || \
- ($(call echo-error,"$(PRIVATE_MAKEFILE): $(PRIVATE_MODULE) ($(PRIVATE_LINK_TYPE)) should not link to $$(basename $${f%_intermediates/link_type}) ($$(cat $$f))"); exit 1) \
- done
-endif
- $(hide) echo $(PRIVATE_LINK_TYPE) >$@
+ $(check-link-type)
###########################################################
diff --git a/core/config.mk b/core/config.mk
index 2d6ee17..525b639 100644
--- a/core/config.mk
+++ b/core/config.mk
@@ -571,6 +571,7 @@
JARJAR := $(HOST_OUT_JAVA_LIBRARIES)/jarjar.jar
DATA_BINDING_COMPILER := $(HOST_OUT_JAVA_LIBRARIES)/databinding-compiler.jar
FAT16COPY := build/tools/fat16copy.py
+CHECK_LINK_TYPE := build/tools/check_link_type.py
ifneq ($(ANDROID_JACK_EXTRA_ARGS),)
JACK_DEFAULT_ARGS :=
diff --git a/core/definitions.mk b/core/definitions.mk
index 0c169e4..29b6539 100644
--- a/core/definitions.mk
+++ b/core/definitions.mk
@@ -3116,6 +3116,35 @@
endef
###########################################################
+# Link type checking
+###########################################################
+define check-link-type
+$(hide) mkdir -p $(dir $@) && rm -f $@
+$(hide) $(CHECK_LINK_TYPE) --makefile $(PRIVATE_MAKEFILE) --module $(PRIVATE_MODULE) \
+ --type "$(PRIVATE_LINK_TYPE)" $(addprefix --allowed ,$(PRIVATE_ALLOWED_TYPES)) \
+ $(addprefix --warn ,$(PRIVATE_WARN_TYPES)) $(PRIVATE_DEPS)
+$(hide) echo "$(PRIVATE_LINK_TYPE)" >$@
+endef
+
+define link-type-partitions
+ifndef LOCAL_IS_HOST_MODULE
+ifeq (true,$(LOCAL_PROPRIETARY_MODULE))
+$(1): PRIVATE_LINK_TYPE += partition:vendor
+$(1): PRIVATE_ALLOWED_TYPES += partition:vendor partition:oem partition:odm
+else ifeq (true,$(LOCAL_OEM_MODULE))
+$(1): PRIVATE_LINK_TYPE += partition:oem
+$(1): PRIVATE_ALLOWED_TYPES += partition:vendor partition:oem partition:odm
+else ifeq (true,$(LOCAL_ODM_MODULE))
+$(1): PRIVATE_LINK_TYPE += partition:odm
+$(1): PRIVATE_ALLOWED_TYPES += partition:vendor partition:oem partition:odm
+else
+# TODO: Mark libraries in /data
+$(1): PRIVATE_WARN_TYPES += partition:vendor partition:oem partition:odm
+endif
+endif
+endef
+
+###########################################################
## Other includes
###########################################################
diff --git a/core/install_jni_libs_internal.mk b/core/install_jni_libs_internal.mk
index 9f5d445..14cc384 100644
--- a/core/install_jni_libs_internal.mk
+++ b/core/install_jni_libs_internal.mk
@@ -102,28 +102,26 @@
# Verify that all included libraries are built against the NDK
ifneq ($(strip $(LOCAL_JNI_SHARED_LIBRARIES)),)
my_link_type := $(call intermediates-dir-for,APPS,$(LOCAL_MODULE))/$(my_2nd_arch_prefix)jni_link_type
+all_link_types: $(my_link_type)
my_link_type_deps := $(strip \
$(foreach l,$(LOCAL_JNI_SHARED_LIBRARIES),\
$(call intermediates-dir-for,SHARED_LIBRARIES,$(l),,,$(my_2nd_arch_prefix))/link_type))
ifneq ($(LOCAL_SDK_VERSION),)
-$(my_link_type): PRIVATE_LINK_TYPE := sdk
-$(my_link_type): PRIVATE_ALLOWED_TYPES := ndk
+$(my_link_type): PRIVATE_LINK_TYPE := app:sdk
+$(my_link_type): PRIVATE_WARN_TYPES := native:platform
+$(my_link_type): PRIVATE_ALLOWED_TYPES := native:ndk
else
-$(my_link_type): PRIVATE_LINK_TYPE := platform
-$(my_link_type): PRIVATE_ALLOWED_TYPES := (ndk|platform)
+$(my_link_type): PRIVATE_LINK_TYPE := app:platform
+$(my_link_type): PRIVATE_WARN_TYPES :=
+$(my_link_type): PRIVATE_ALLOWED_TYPES := native:ndk native:platform
endif
+$(eval $(call link-type-partitions,$(my_link_type)))
$(my_link_type): PRIVATE_DEPS := $(my_link_type_deps)
$(my_link_type): PRIVATE_MODULE := $(LOCAL_MODULE)
$(my_link_type): PRIVATE_MAKEFILE := $(LOCAL_MODULE_MAKEFILE)
-$(my_link_type): $(my_link_type_deps)
+$(my_link_type): $(my_link_type_deps) $(CHECK_LINK_TYPE)
@echo Check JNI module types: $@
- $(hide) mkdir -p $(dir $@)
- $(hide) rm -f $@
- $(hide) for f in $(PRIVATE_DEPS); do \
- grep -qE '^$(PRIVATE_ALLOWED_TYPES)$$' $$f || \
- $(call echo-warning,"$(PRIVATE_MAKEFILE): $(PRIVATE_MODULE) ($(PRIVATE_LINK_TYPE)) should not link to $$(basename $${f%_intermediates/link_type}) ($$(cat $$f))"); \
- done
- $(hide) touch $@
+ $(check-link-type)
$(LOCAL_BUILT_MODULE): | $(my_link_type)
diff --git a/core/java_common.mk b/core/java_common.mk
index 432c96f..1119a37 100644
--- a/core/java_common.mk
+++ b/core/java_common.mk
@@ -379,6 +379,7 @@
###########################################################
ifndef LOCAL_IS_HOST_MODULE
my_link_type := $(intermediates.COMMON)/link_type
+all_link_types: $(my_link_type)
my_link_type_deps := $(strip \
$(foreach lib,$(LOCAL_STATIC_JAVA_LIBRARIES),\
$(call intermediates-dir-for, \
@@ -387,27 +388,25 @@
$(call intermediates-dir-for, \
APPS,$(lib),,COMMON)/link_type))
ifeq ($(LOCAL_SDK_VERSION),system_current)
-$(my_link_type): PRIVATE_LINK_TYPE := system
-$(my_link_type): PRIVATE_ALLOWED_TYPES := (sdk|system)
+$(my_link_type): PRIVATE_LINK_TYPE := java:system
+$(my_link_type): PRIVATE_WARN_TYPES := java:platform
+$(my_link_type): PRIVATE_ALLOWED_TYPES := java:sdk java:system
else ifneq ($(LOCAL_SDK_VERSION),)
-$(my_link_type): PRIVATE_LINK_TYPE := sdk
-$(my_link_type): PRIVATE_ALLOWED_TYPES := sdk
+$(my_link_type): PRIVATE_LINK_TYPE := java:sdk
+$(my_link_type): PRIVATE_WARN_TYPES := java:system java:platform
+$(my_link_type): PRIVATE_ALLOWED_TYPES := java:sdk
else
-$(my_link_type): PRIVATE_LINK_TYPE := platform
-$(my_link_type): PRIVATE_ALLOWED_TYPES := (sdk|system|platform)
+$(my_link_type): PRIVATE_LINK_TYPE := java:platform
+$(my_link_type): PRIVATE_WARN_TYPES :=
+$(my_link_type): PRIVATE_ALLOWED_TYPES := java:sdk java:system java:platform
endif
+$(eval $(call link-type-partitions,$(my_link_type)))
$(my_link_type): PRIVATE_DEPS := $(my_link_type_deps)
$(my_link_type): PRIVATE_MODULE := $(LOCAL_MODULE)
$(my_link_type): PRIVATE_MAKEFILE := $(LOCAL_MODULE_MAKEFILE)
-$(my_link_type): $(my_link_type_deps)
+$(my_link_type): $(my_link_type_deps) $(CHECK_LINK_TYPE)
@echo Check Java library module types: $@
- $(hide) mkdir -p $(dir $@)
- $(hide) rm -f $@
- $(hide) for f in $(PRIVATE_DEPS); do \
- grep -qE '^$(PRIVATE_ALLOWED_TYPES)$$' $$f || \
- $(call echo-warning,"$(PRIVATE_MAKEFILE): $(PRIVATE_MODULE) ($(PRIVATE_LINK_TYPE)) should not link to $$(basename $${f%_intermediates/link_type}) ($$(cat $$f))"); \
- done
- $(hide) echo $(PRIVATE_LINK_TYPE) >$@
+ $(check-link-type)
$(LOCAL_BUILT_MODULE): $(my_link_type)
endif # !LOCAL_IS_HOST_MODULE
diff --git a/core/main.mk b/core/main.mk
index 1eab0db..b20044a 100644
--- a/core/main.mk
+++ b/core/main.mk
@@ -1137,4 +1137,7 @@
ndk: $(SOONG_OUT_DIR)/ndk.timestamp
.PHONY: ndk
+.PHONY: all_link_types
+all_link_types:
+
endif # KATI
diff --git a/core/prebuilt_internal.mk b/core/prebuilt_internal.mk
index 41058ba..1aa864d 100644
--- a/core/prebuilt_internal.mk
+++ b/core/prebuilt_internal.mk
@@ -138,11 +138,12 @@
endif
my_link_type := $(intermediates)/link_type
-$(my_link_type): PRIVATE_LINK_TYPE := $(if $(LOCAL_SDK_VERSION),ndk,platform)
+$(my_link_type): PRIVATE_LINK_TYPE := native:$(if $(LOCAL_SDK_VERSION),ndk,platform)
+$(eval $(call link-type-partitions,$(my_link_type)))
$(my_link_type):
@echo Check module type: $@
$(hide) mkdir -p $(dir $@) && rm -f $@
- $(hide) echo $(PRIVATE_LINK_TYPE) >$@
+ $(hide) echo "$(PRIVATE_LINK_TYPE)" >$@
$(LOCAL_BUILT_MODULE) : | $(export_includes) $(my_link_type)
endif # prebuilt_module_is_a_library
@@ -397,16 +398,17 @@
my_link_type := $(intermediates.COMMON)/link_type
ifeq ($(LOCAL_SDK_VERSION),system_current)
-$(my_link_type): PRIVATE_LINK_TYPE := system
+$(my_link_type): PRIVATE_LINK_TYPE := java:system
else ifneq ($(LOCAL_SDK_VERSION),)
-$(my_link_type): PRIVATE_LINK_TYPE := sdk
+$(my_link_type): PRIVATE_LINK_TYPE := java:sdk
else
-$(my_link_type): PRIVATE_LINK_TYPE := platform
+$(my_link_type): PRIVATE_LINK_TYPE := java:platform
endif
+$(eval $(call link-type-partitions,$(my_link_type)))
$(my_link_type):
@echo Check module type: $@
$(hide) mkdir -p $(dir $@) && rm -f $@
- $(hide) echo $(PRIVATE_LINK_TYPE) >$@
+ $(hide) echo "$(PRIVATE_LINK_TYPE)" >$@
$(LOCAL_BUILT_MODULE): $(my_link_type)
ifeq ($(prebuilt_module_is_dex_javalib),true)
diff --git a/tools/check_link_type.py b/tools/check_link_type.py
new file mode 100755
index 0000000..40754ad
--- /dev/null
+++ b/tools/check_link_type.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 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.
+
+"""Utility to verify modules link against acceptable module types"""
+
+from __future__ import print_function
+import argparse
+import os
+import sys
+
+WARNING_MSG = ('\033[1m%(makefile)s: \033[35mwarning:\033[0m\033[1m '
+ '%(module)s (%(type)s) should not link to %(dep_name)s (%(dep_type)s)'
+ '\033[0m')
+ERROR_MSG = ('\033[1m%(makefile)s: \033[31merror:\033[0m\033[1m '
+ '%(module)s (%(type)s) should not link to %(dep_name)s (%(dep_type)s)'
+ '\033[0m')
+
+def parse_args():
+ """Parse commandline arguments."""
+ parser = argparse.ArgumentParser(description='Check link types')
+ parser.add_argument('--makefile', help='Makefile defining module')
+ parser.add_argument('--module', help='The module being checked')
+ parser.add_argument('--type', help='The link type of module')
+ parser.add_argument('--allowed', help='Allow deps to use these types',
+ action='append', default=[], metavar='TYPE')
+ parser.add_argument('--warn', help='Warn if deps use these types',
+ action='append', default=[], metavar='TYPE')
+ parser.add_argument('deps', help='The dependencies to check',
+ metavar='DEP', nargs='*')
+ return parser.parse_args()
+
+def print_msg(msg, args, dep_name, dep_type):
+ """Print a warning or error message"""
+ print(msg % {
+ "makefile": args.makefile,
+ "module": args.module,
+ "type": args.type,
+ "dep_name": dep_name,
+ "dep_type": dep_type}, file=sys.stderr)
+
+def main():
+ """Program entry point."""
+ args = parse_args()
+
+ failed = False
+ for dep in args.deps:
+ dep_name = os.path.basename(os.path.dirname(dep))
+ if dep_name.endswith('_intermediates'):
+ dep_name = dep_name[:len(dep_name)-len('_intermediates')]
+
+ with open(dep, 'r') as dep_file:
+ dep_types = dep_file.read().strip().split(' ')
+
+ for dep_type in dep_types:
+ if dep_type in args.allowed:
+ continue
+ if dep_type in args.warn:
+ print_msg(WARNING_MSG, args, dep_name, dep_type)
+ else:
+ print_msg(ERROR_MSG, args, dep_name, dep_type)
+ failed = True
+
+ if failed:
+ sys.exit(1)
+
+if __name__ == '__main__':
+ main()
diff --git a/tools/releasetools/check_ota_package_signature.py b/tools/releasetools/check_ota_package_signature.py
new file mode 100755
index 0000000..0da61b1
--- /dev/null
+++ b/tools/releasetools/check_ota_package_signature.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 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.
+
+"""
+Verify a given OTA package with the specifed certificate.
+"""
+
+from __future__ import print_function
+
+import argparse
+import common
+import re
+import subprocess
+import sys
+
+from hashlib import sha1
+from hashlib import sha256
+
+
+def cert_uses_sha256(cert):
+ """Check if the cert uses SHA-256 hashing algorithm."""
+
+ cmd = ['openssl', 'x509', '-text', '-noout', '-in', cert]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ cert_dump, _ = p1.communicate()
+
+ algorithm = re.search(r'Signature Algorithm: ([a-zA-Z0-9]+)', cert_dump)
+ assert algorithm, "Failed to identify the signature algorithm."
+
+ assert not algorithm.group(1).startswith('ecdsa'), (
+ 'This script doesn\'t support verifying ECDSA signed package yet.')
+
+ return algorithm.group(1).startswith('sha256')
+
+
+def verify_package(cert, package):
+ """Verify the given package with the certificate.
+
+ (Comments from bootable/recovery/verifier.cpp:)
+
+ An archive with a whole-file signature will end in six bytes:
+
+ (2-byte signature start) $ff $ff (2-byte comment size)
+
+ (As far as the ZIP format is concerned, these are part of the
+ archive comment.) We start by reading this footer, this tells
+ us how far back from the end we have to start reading to find
+ the whole comment.
+ """
+
+ print('Package: %s' % (package,))
+ print('Certificate: %s' % (cert,))
+
+ # Read in the package.
+ with open(package) as package_file:
+ package_bytes = package_file.read()
+
+ length = len(package_bytes)
+ assert length >= 6, "Not big enough to contain footer."
+
+ footer = [ord(x) for x in package_bytes[-6:]]
+ assert footer[2] == 0xff and footer[3] == 0xff, "Footer is wrong."
+
+ signature_start_from_end = (footer[1] << 8) + footer[0]
+ assert signature_start_from_end > 6, "Signature start is in the footer."
+
+ signature_start = length - signature_start_from_end
+
+ # Determine how much of the file is covered by the signature. This is
+ # everything except the signature data and length, which includes all of the
+ # EOCD except for the comment length field (2 bytes) and the comment data.
+ comment_len = (footer[5] << 8) + footer[4]
+ signed_len = length - comment_len - 2
+
+ print('Package length: %d' % (length,))
+ print('Comment length: %d' % (comment_len,))
+ print('Signed data length: %d' % (signed_len,))
+ print('Signature start: %d' % (signature_start,))
+
+ use_sha256 = cert_uses_sha256(cert)
+ print('Use SHA-256: %s' % (use_sha256,))
+
+ if use_sha256:
+ h = sha256()
+ else:
+ h = sha1()
+ h.update(package_bytes[:signed_len])
+ package_digest = h.hexdigest().lower()
+
+ print('Digest: %s\n' % (package_digest,))
+
+ # Get the signature from the input package.
+ signature = package_bytes[signature_start:-6]
+ sig_file = common.MakeTempFile(prefix='sig-', suffix='')
+ with open(sig_file, 'wb') as f:
+ f.write(signature)
+
+ # Parse the signature and get the hash.
+ cmd = ['openssl', 'asn1parse', '-inform', 'DER', '-in', sig_file]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ sig, _ = p1.communicate()
+ assert p1.returncode == 0, "Failed to parse the signature."
+
+ digest_line = sig.strip().split('\n')[-1]
+ digest_string = digest_line.split(':')[3]
+ digest_file = common.MakeTempFile(prefix='digest-', suffix='')
+ with open(digest_file, 'wb') as f:
+ f.write(digest_string.decode('hex'))
+
+ # Verify the digest by outputing the decrypted result in ASN.1 structure.
+ decrypted_file = common.MakeTempFile(prefix='decrypted-', suffix='')
+ cmd = ['openssl', 'rsautl', '-verify', '-certin', '-inkey', cert,
+ '-in', digest_file, '-out', decrypted_file]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ p1.communicate()
+ assert p1.returncode == 0, "Failed to run openssl rsautl -verify."
+
+ # Parse the output ASN.1 structure.
+ cmd = ['openssl', 'asn1parse', '-inform', 'DER', '-in', decrypted_file]
+ p1 = common.Run(cmd, stdout=subprocess.PIPE)
+ decrypted_output, _ = p1.communicate()
+ assert p1.returncode == 0, "Failed to parse the output."
+
+ digest_line = decrypted_output.strip().split('\n')[-1]
+ digest_string = digest_line.split(':')[3].lower()
+
+ # Verify that the two digest strings match.
+ assert package_digest == digest_string, "Verification failed."
+
+ # Verified successfully upon reaching here.
+ print('VERIFIED\n')
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('certificate', help='The certificate to be used.')
+ parser.add_argument('package', help='The OTA package to be verified.')
+ args = parser.parse_args()
+
+ verify_package(args.certificate, args.package)
+
+
+if __name__ == '__main__':
+ try:
+ main()
+ except AssertionError as err:
+ print('\n ERROR: %s\n' % (err,))
+ sys.exit(1)
diff --git a/tools/warn.py b/tools/warn.py
index 572ac68..5cb104f 100755
--- a/tools/warn.py
+++ b/tools/warn.py
@@ -91,9 +91,18 @@
'description':'make: overriding commands/ignoring old commands',
'patterns':[r".*: warning: overriding commands for target .+",
r".*: warning: ignoring old commands for target .+"] },
- { 'category':'make', 'severity':severity.HIGH, 'members':[], 'option':'',
+ { 'category':'make', 'severity':severity.HIGH, 'members':[], 'option':'',
'description':'make: LOCAL_CLANG is false',
'patterns':[r".*: warning: LOCAL_CLANG is set to false"] },
+ { 'category':'make', 'severity':severity.HIGH, 'members':[], 'option':'',
+ 'description':'SDK App using platform shared library',
+ 'patterns':[r".*: warning: .+ \(.*app:sdk.*\) should not link to .+ \(native:platform\)"] },
+ { 'category':'make', 'severity':severity.HIGH, 'members':[], 'option':'',
+ 'description':'System module linking to a vendor module',
+ 'patterns':[r".*: warning: .+ \(.+\) should not link to .+ \(partition:.+\)"] },
+ { 'category':'make', 'severity':severity.MEDIUM, 'members':[], 'option':'',
+ 'description':'Invalid SDK/NDK linking',
+ 'patterns':[r".*: warning: .+ \(.+\) should not link to .+ \(.+\)"] },
{ 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wimplicit-function-declaration',
'description':'Implicit function declaration',
'patterns':[r".*: warning: implicit declaration of function .+",