Commit 02040379 authored by Tibor Goldschwendt's avatar Tibor Goldschwendt Committed by Commit Bot

[build] Use metadata to collect APK's shared libraries

Previously, we used runtime deps to collect the shared libraries. That
worked due to some special runtime dependency propagation rules around
shared_library targets. However, this will stop working with the new
linker assisted native feature module approach where some shared
libraries will become action targets. To solve this, this CL

- adds the shared library output file to metadata of each shared_library
  target,

- adds the new partitioned shared library output files to metadata as
  well,

- adds barriers where propagation should be interrupted, and

- adds generated_file targets to read the metadata.



Bug: 980569
Change-Id: Ib3f49a00d04d066a2fc1f0bb916d469adabac447
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1693023
Commit-Queue: Tibor Goldschwendt <tiborg@chromium.org>
Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#675773}
parent 25b13199
...@@ -83,12 +83,11 @@ def main(): ...@@ -83,12 +83,11 @@ def main():
exclude_shared_libraries = options.exclude_shared_libraries.split(',') exclude_shared_libraries = options.exclude_shared_libraries.split(',')
for f in open(options.runtime_deps): for f in open(options.runtime_deps):
f = f[:-1] f = f[:-1]
if f.endswith('.so'): assert f.endswith('.so')
p = f.replace('lib.unstripped/', '') if os.path.basename(f) in exclude_shared_libraries:
if os.path.basename(p) in exclude_shared_libraries: continue
continue unsorted_lib_paths.append(f)
unsorted_lib_paths.append(p) _library_path_map[os.path.basename(f)] = f
_library_path_map[os.path.basename(p)] = p
lib_paths = GetSortedTransitiveDependencies(unsorted_lib_paths) lib_paths = GetSortedTransitiveDependencies(unsorted_lib_paths)
......
...@@ -561,7 +561,8 @@ foreach(_target_type, ...@@ -561,7 +561,8 @@ foreach(_target_type,
"shared_library", "shared_library",
]) { ]) {
template(_target_type) { template(_target_type) {
target(_target_type, target_name) { _target_name = target_name
target(_target_type, _target_name) {
forward_variables_from(invoker, "*", [ "no_default_deps" ]) forward_variables_from(invoker, "*", [ "no_default_deps" ])
if (!defined(deps)) { if (!defined(deps)) {
deps = [] deps = []
...@@ -569,6 +570,35 @@ foreach(_target_type, ...@@ -569,6 +570,35 @@ foreach(_target_type,
if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) { if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) {
deps += [ "//build/config:${_target_type}_deps" ] deps += [ "//build/config:${_target_type}_deps" ]
} }
# On Android, write shared library output file to metadata. We will use
# this information to, for instance, collect all shared libraries that
# should be packaged into an APK.
if (!defined(invoker.metadata) && is_android &&
_target_type == "shared_library") {
_output_name = _target_name
if (defined(invoker.output_name)) {
_output_name = invoker.output_name
}
# Remove 'lib' prefix from output name if it exists.
_magic_prefix = "$0x01$0x01"
_output_name = string_replace("${_magic_prefix}${_output_name}",
"${_magic_prefix}lib",
_magic_prefix,
1)
_output_name = string_replace(_output_name, _magic_prefix, "", 1)
_shlib_extension = ".so"
if (is_component_build) {
_shlib_extension = ".cr.so"
}
metadata = {
shared_libraries =
[ "$root_out_dir/lib${_output_name}${_shlib_extension}" ]
}
}
} }
} }
} }
......
...@@ -62,27 +62,31 @@ template("create_native_executable_dist") { ...@@ -62,27 +62,31 @@ template("create_native_executable_dist") {
_libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list" _libraries_list = "${target_gen_dir}/${target_name}_library_dependencies.list"
_runtime_deps_file = "$target_gen_dir/${target_name}.runtimedeps" _shared_library_list_file = "$target_gen_dir/${target_name}.native_libs"
_runtime_deps_target_name = "${target_name}__runtime_deps" _shared_library_list_target_name = "${target_name}__shared_library_list"
group(_runtime_deps_target_name) { generated_file(_shared_library_list_target_name) {
data = _sanitizer_runtimes forward_variables_from(invoker, [ "deps" ])
data_deps = [] metadata = {
if (defined(invoker.deps)) { shared_libraries = _sanitizer_runtimes
data_deps += invoker.deps
} }
write_runtime_deps = _runtime_deps_file outputs = [
_shared_library_list_file,
]
data_keys = [ "shared_libraries" ]
walk_keys = [ "shared_libraries_barrier" ]
rebase = root_build_dir
} }
_find_deps_target_name = "${target_name}__find_library_dependencies" _find_deps_target_name = "${target_name}__find_library_dependencies"
# TODO(agrieve): Extract dependent libs from GN rather than readelf. # TODO(agrieve): Extract dependent libs from GN rather than readelf.
action_with_pydeps(_find_deps_target_name) { action_with_pydeps(_find_deps_target_name) {
deps = invoker.deps + [ ":$_runtime_deps_target_name" ] deps = invoker.deps + [ ":$_shared_library_list_target_name" ]
script = "//build/android/gyp/write_ordered_libraries.py" script = "//build/android/gyp/write_ordered_libraries.py"
depfile = "$target_gen_dir/$target_name.d" depfile = "$target_gen_dir/$target_name.d"
inputs = [ inputs = [
invoker.binary, invoker.binary,
_runtime_deps_file, _shared_library_list_file,
android_readelf, android_readelf,
] ]
outputs = [ outputs = [
...@@ -92,7 +96,7 @@ template("create_native_executable_dist") { ...@@ -92,7 +96,7 @@ template("create_native_executable_dist") {
"--depfile", "--depfile",
rebase_path(depfile, root_build_dir), rebase_path(depfile, root_build_dir),
"--runtime-deps", "--runtime-deps",
rebase_path(_runtime_deps_file, root_build_dir), rebase_path(_shared_library_list_file, root_build_dir),
"--output", "--output",
rebase_path(_libraries_list, root_build_dir), rebase_path(_libraries_list, root_build_dir),
"--readelf", "--readelf",
...@@ -2203,38 +2207,44 @@ if (enable_java_templates) { ...@@ -2203,38 +2207,44 @@ if (enable_java_templates) {
if (_shared_libraries_is_valid) { if (_shared_libraries_is_valid) {
_native_libs_deps += invoker.shared_libraries _native_libs_deps += invoker.shared_libraries
# To determine the filenames of all dependent shared libraries, write the # Write shared library output files of all dependencies to a file. Those
# runtime deps of |shared_libraries| to a file during "gn gen". # will be the shared libraries packaged into the APK.
# write_build_config.py will then grep this file for *.so to obtain the _shared_library_list_file =
# complete list. "$target_gen_dir/${_template_name}.native_libs"
_runtime_deps_file = generated_file("${_template_name}__shared_library_list") {
"$target_gen_dir/${_template_name}.native.runtimedeps"
group("${_template_name}__runtime_deps") {
deps = _native_libs_deps deps = _native_libs_deps
write_runtime_deps = _runtime_deps_file outputs = [
_shared_library_list_file,
]
data_keys = [ "shared_libraries" ]
walk_keys = [ "shared_libraries_barrier" ]
rebase = root_build_dir
} }
} else { } else {
# Must exist for instrumentation_test_apk() to depend on. # Must exist for instrumentation_test_apk() to depend on.
group("${_template_name}__runtime_deps") { group("${_template_name}__shared_library_list") {
} }
} }
if (_secondary_abi_shared_libraries_is_valid) { if (_secondary_abi_shared_libraries_is_valid) {
_secondary_abi_native_libs_deps += invoker.secondary_abi_shared_libraries _secondary_abi_native_libs_deps += invoker.secondary_abi_shared_libraries
# To determine the filenames of all dependent shared libraries, write the # Write shared library output files of all dependencies to a file. Those
# runtime deps of |shared_libraries| to a file during "gn gen". # will be the shared libraries packaged into the APK.
# write_build_config.py will then grep this file for *.so to obtain the _secondary_abi_shared_library_list_file =
# complete list. "$target_gen_dir/${_template_name}.secondary_abi_native_libs"
_secondary_abi_runtime_deps_file = generated_file("${_template_name}__secondary_abi_shared_library_list") {
"$target_gen_dir/${_template_name}.secondary.abi.native.runtimedeps"
group("${_template_name}__secondary_abi__runtime_deps") {
deps = _secondary_abi_native_libs_deps deps = _secondary_abi_native_libs_deps
write_runtime_deps = _secondary_abi_runtime_deps_file outputs = [
_secondary_abi_shared_library_list_file,
]
data_keys = [ "shared_libraries" ]
walk_keys = [ "shared_libraries_barrier" ]
rebase = root_build_dir
} }
} else { } else {
# Must exist for instrumentation_test_apk() to depend on. # Must exist for instrumentation_test_apk() to depend on.
group("${_template_name}__secondary_abi__runtime_deps") { group("${_template_name}__secondary_abi_shared_library_list") {
} }
} }
...@@ -2558,13 +2568,13 @@ if (enable_java_templates) { ...@@ -2558,13 +2568,13 @@ if (enable_java_templates) {
script = "//build/android/gyp/write_ordered_libraries.py" script = "//build/android/gyp/write_ordered_libraries.py"
deps = [ deps = [
":$_build_config_target", ":$_build_config_target",
":${_template_name}__runtime_deps", ":${_template_name}__secondary_abi_shared_library_list",
":${_template_name}__secondary_abi__runtime_deps", ":${_template_name}__shared_library_list",
] ]
if (_native_libs_deps != []) { if (_native_libs_deps != []) {
_deps_file_to_use = _runtime_deps_file _deps_file_to_use = _shared_library_list_file
} else { } else {
_deps_file_to_use = _secondary_abi_runtime_deps_file _deps_file_to_use = _secondary_abi_shared_library_list_file
} }
inputs = [ inputs = [
_deps_file_to_use, _deps_file_to_use,
...@@ -2772,11 +2782,11 @@ if (enable_java_templates) { ...@@ -2772,11 +2782,11 @@ if (enable_java_templates) {
# The dep is unnecessary since the runtime_deps file is created by gn gen # The dep is unnecessary since the runtime_deps file is created by gn gen
# and the runtime_deps file is added to write_build_config.py's depfile. # and the runtime_deps file is added to write_build_config.py's depfile.
if (_native_libs_deps != []) { if (_native_libs_deps != []) {
shared_libraries_runtime_deps_file = _runtime_deps_file shared_libraries_runtime_deps_file = _shared_library_list_file
} }
if (_secondary_abi_native_libs_deps != []) { if (_secondary_abi_native_libs_deps != []) {
secondary_abi_shared_libraries_runtime_deps_file = secondary_abi_shared_libraries_runtime_deps_file =
_secondary_abi_runtime_deps_file _secondary_abi_shared_library_list_file
} }
extra_shared_libraries = _extra_native_libs extra_shared_libraries = _extra_native_libs
...@@ -3680,15 +3690,15 @@ if (enable_java_templates) { ...@@ -3680,15 +3690,15 @@ if (enable_java_templates) {
# Ensure unstripped libraries are included in runtime deps so that # Ensure unstripped libraries are included in runtime deps so that
# symbolization can be done. # symbolization can be done.
deps = [ deps = [
":${_apk_target_name}__runtime_deps", ":${_apk_target_name}__secondary_abi_shared_library_list",
":${_apk_target_name}__secondary_abi__runtime_deps", ":${_apk_target_name}__shared_library_list",
] ]
if (defined(invoker.apk_under_test)) { if (defined(invoker.apk_under_test)) {
_under_test_label = _under_test_label =
get_label_info(invoker.apk_under_test, "label_no_toolchain") get_label_info(invoker.apk_under_test, "label_no_toolchain")
deps += [ deps += [
"${_under_test_label}__runtime_deps", "${_under_test_label}__secondary_abi_shared_library_list",
"${_under_test_label}__secondary_abi__runtime_deps", "${_under_test_label}__shared_library_list",
] ]
} }
} }
...@@ -3775,8 +3785,8 @@ if (enable_java_templates) { ...@@ -3775,8 +3785,8 @@ if (enable_java_templates) {
} }
shared_libraries = [ invoker.shared_library ] shared_libraries = [ invoker.shared_library ]
deps += [ deps += [
":${target_name}__runtime_deps", ":${target_name}__secondary_abi_shared_library_list",
":${target_name}__secondary_abi__runtime_deps", ":${target_name}__shared_library_list",
"//base:base_java", "//base:base_java",
"//testing/android/reporter:reporter_java", "//testing/android/reporter:reporter_java",
] ]
......
...@@ -64,6 +64,11 @@ template("partitioned_shared_library") { ...@@ -64,6 +64,11 @@ template("partitioned_shared_library") {
"-Wl,-soname,lib${_output_name}.so", "-Wl,-soname,lib${_output_name}.so",
"--link-only", "--link-only",
] ]
# This shared library is an intermediate artifact that should not packaged
# into the final build. Therefore, reset metadata.
metadata = {
}
} }
template("partition_action") { template("partition_action") {
...@@ -79,9 +84,9 @@ template("partitioned_shared_library") { ...@@ -79,9 +84,9 @@ template("partitioned_shared_library") {
invoker.unstripped_output, invoker.unstripped_output,
invoker.stripped_output, invoker.stripped_output,
] ]
data = [ metadata = {
invoker.stripped_output, shared_libraries = [ invoker.stripped_output ]
] }
args = [ args = [
"--objcopy", "--objcopy",
rebase_path("$clang_base_path/bin/llvm-objcopy", root_build_dir), rebase_path("$clang_base_path/bin/llvm-objcopy", root_build_dir),
......
...@@ -38,5 +38,11 @@ template("generate_resource_whitelist") { ...@@ -38,5 +38,11 @@ template("generate_resource_whitelist") {
foreach(input, invoker.inputs) { foreach(input, invoker.inputs) {
args += [ rebase_path(input, root_build_dir) ] args += [ rebase_path(input, root_build_dir) ]
} }
# This target's dependencies are needed at build time only. Make sure shared
# library dependencies don't get packaged into the final build.
metadata = {
shared_libraries_barrier = []
}
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment