1*8975f5c5SAndroid Build Coastguard Worker# Copyright 2019 The Chromium Authors 2*8975f5c5SAndroid Build Coastguard Worker 3*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker 6*8975f5c5SAndroid Build Coastguard Workerimport("//build/config/android/config.gni") 7*8975f5c5SAndroid Build Coastguard Workerimport("//build/config/clang/clang.gni") 8*8975f5c5SAndroid Build Coastguard Workerimport("//build/config/compiler/compiler.gni") 9*8975f5c5SAndroid Build Coastguard Workerif (build_with_chromium) { 10*8975f5c5SAndroid Build Coastguard Worker import("//third_party/jni_zero/jni_zero.gni") 11*8975f5c5SAndroid Build Coastguard Worker} 12*8975f5c5SAndroid Build Coastguard Worker 13*8975f5c5SAndroid Build Coastguard Worker# This template creates a set of shared libraries, by linking a single 14*8975f5c5SAndroid Build Coastguard Worker# "partitioned" shared library, then splitting it into multiple pieces. 15*8975f5c5SAndroid Build Coastguard Worker# The intention is to facilitate code-splitting between a base library and 16*8975f5c5SAndroid Build Coastguard Worker# additional feature-specific libraries that may be obtained and loaded at a 17*8975f5c5SAndroid Build Coastguard Worker# later time. 18*8975f5c5SAndroid Build Coastguard Worker# 19*8975f5c5SAndroid Build Coastguard Worker# The combined library is an intermediate product made by leveraging the LLVM 20*8975f5c5SAndroid Build Coastguard Worker# toolchain. Code modules may be labeled via compiler flag as belonging to a 21*8975f5c5SAndroid Build Coastguard Worker# particular partition. At link time, any symbols reachable by only a single 22*8975f5c5SAndroid Build Coastguard Worker# partition's entrypoints will be located in a partition-specific library 23*8975f5c5SAndroid Build Coastguard Worker# segment. After linking, the segments are split apart using objcopy into 24*8975f5c5SAndroid Build Coastguard Worker# separate libraries. The main library is then packaged with the application 25*8975f5c5SAndroid Build Coastguard Worker# as usual, while feature libraries may be packaged, delivered and loaded 26*8975f5c5SAndroid Build Coastguard Worker# separately (via an Android Dynamic Feature Module). 27*8975f5c5SAndroid Build Coastguard Worker# 28*8975f5c5SAndroid Build Coastguard Worker# When loading a feature library, the intended address of the library must be 29*8975f5c5SAndroid Build Coastguard Worker# supplied to the loader, so that it can be mapped to the memory location. The 30*8975f5c5SAndroid Build Coastguard Worker# address offsets of the feature libraries are stored in the base library and 31*8975f5c5SAndroid Build Coastguard Worker# accessed through special symbols named according to the partitions. 32*8975f5c5SAndroid Build Coastguard Worker# 33*8975f5c5SAndroid Build Coastguard Worker# The template instantiates targets for the base library, as well as each 34*8975f5c5SAndroid Build Coastguard Worker# specified partition, based on the root target name. Example: 35*8975f5c5SAndroid Build Coastguard Worker# 36*8975f5c5SAndroid Build Coastguard Worker# - libmonochrome (base library) 37*8975f5c5SAndroid Build Coastguard Worker# - libmonochrome_foo (partition library for feature 'foo') 38*8975f5c5SAndroid Build Coastguard Worker# - libmonochrome_bar (partition library for feature 'bar') 39*8975f5c5SAndroid Build Coastguard Worker# 40*8975f5c5SAndroid Build Coastguard Worker# Note that the feature library filenames are chosen based on the main 41*8975f5c5SAndroid Build Coastguard Worker# library's name (eg. libmonochrome_foo.so), but the soname of the feature 42*8975f5c5SAndroid Build Coastguard Worker# library is based on the feature name (eg. "foo"). This should generally be 43*8975f5c5SAndroid Build Coastguard Worker# okay, with the caveat that loading the library multiple times *might* cause 44*8975f5c5SAndroid Build Coastguard Worker# problems in Android. 45*8975f5c5SAndroid Build Coastguard Worker# 46*8975f5c5SAndroid Build Coastguard Worker# This template uses shared_library's default configurations. 47*8975f5c5SAndroid Build Coastguard Worker# 48*8975f5c5SAndroid Build Coastguard Worker# Variables: 49*8975f5c5SAndroid Build Coastguard Worker# partitions: A list of library partition names to extract, in addition to 50*8975f5c5SAndroid Build Coastguard Worker# the base library. 51*8975f5c5SAndroid Build Coastguard Worker 52*8975f5c5SAndroid Build Coastguard Workertemplate("partitioned_shared_library") { 53*8975f5c5SAndroid Build Coastguard Worker assert(is_clang) 54*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, [ "testonly" ]) 55*8975f5c5SAndroid Build Coastguard Worker 56*8975f5c5SAndroid Build Coastguard Worker _combined_library_target = "${target_name}__combined" 57*8975f5c5SAndroid Build Coastguard Worker 58*8975f5c5SAndroid Build Coastguard Worker # Strip "lib" from target names; it will be re-added to output libraries. 59*8975f5c5SAndroid Build Coastguard Worker _output_name = string_replace(target_name, "lib", "") 60*8975f5c5SAndroid Build Coastguard Worker 61*8975f5c5SAndroid Build Coastguard Worker shared_library(_combined_library_target) { 62*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, "*", [ "partitions" ]) 63*8975f5c5SAndroid Build Coastguard Worker if (!defined(ldflags)) { 64*8975f5c5SAndroid Build Coastguard Worker ldflags = [] 65*8975f5c5SAndroid Build Coastguard Worker } 66*8975f5c5SAndroid Build Coastguard Worker ldflags += [ 67*8975f5c5SAndroid Build Coastguard Worker "-Wl,-soname,lib${_output_name}.so", 68*8975f5c5SAndroid Build Coastguard Worker "--partitioned-library", 69*8975f5c5SAndroid Build Coastguard Worker ] 70*8975f5c5SAndroid Build Coastguard Worker 71*8975f5c5SAndroid Build Coastguard Worker # This shared library is an intermediate artifact that should not packaged 72*8975f5c5SAndroid Build Coastguard Worker # into the final build. Therefore, reset metadata. 73*8975f5c5SAndroid Build Coastguard Worker metadata = { 74*8975f5c5SAndroid Build Coastguard Worker } 75*8975f5c5SAndroid Build Coastguard Worker } 76*8975f5c5SAndroid Build Coastguard Worker 77*8975f5c5SAndroid Build Coastguard Worker template("partition_action") { 78*8975f5c5SAndroid Build Coastguard Worker action(target_name) { 79*8975f5c5SAndroid Build Coastguard Worker deps = [ ":$_combined_library_target" ] 80*8975f5c5SAndroid Build Coastguard Worker script = "//build/extract_partition.py" 81*8975f5c5SAndroid Build Coastguard Worker sources = 82*8975f5c5SAndroid Build Coastguard Worker [ "$root_out_dir/lib.unstripped/lib${_output_name}__combined.so" ] 83*8975f5c5SAndroid Build Coastguard Worker outputs = [ 84*8975f5c5SAndroid Build Coastguard Worker invoker.unstripped_output, 85*8975f5c5SAndroid Build Coastguard Worker invoker.stripped_output, 86*8975f5c5SAndroid Build Coastguard Worker ] 87*8975f5c5SAndroid Build Coastguard Worker data = [ invoker.unstripped_output ] 88*8975f5c5SAndroid Build Coastguard Worker metadata = { 89*8975f5c5SAndroid Build Coastguard Worker shared_libraries = [ invoker.stripped_output ] 90*8975f5c5SAndroid Build Coastguard Worker } 91*8975f5c5SAndroid Build Coastguard Worker args = [ 92*8975f5c5SAndroid Build Coastguard Worker "--objcopy", 93*8975f5c5SAndroid Build Coastguard Worker rebase_path("$clang_base_path/bin/llvm-objcopy", root_build_dir), 94*8975f5c5SAndroid Build Coastguard Worker "--unstripped-output", 95*8975f5c5SAndroid Build Coastguard Worker rebase_path(invoker.unstripped_output, root_build_dir), 96*8975f5c5SAndroid Build Coastguard Worker "--stripped-output", 97*8975f5c5SAndroid Build Coastguard Worker rebase_path(invoker.stripped_output, root_build_dir), 98*8975f5c5SAndroid Build Coastguard Worker ] 99*8975f5c5SAndroid Build Coastguard Worker if (defined(invoker.partition) && invoker.partition != "") { 100*8975f5c5SAndroid Build Coastguard Worker args += [ 101*8975f5c5SAndroid Build Coastguard Worker "--partition", 102*8975f5c5SAndroid Build Coastguard Worker "${invoker.partition}", 103*8975f5c5SAndroid Build Coastguard Worker ] 104*8975f5c5SAndroid Build Coastguard Worker } 105*8975f5c5SAndroid Build Coastguard Worker 106*8975f5c5SAndroid Build Coastguard Worker if (use_debug_fission) { 107*8975f5c5SAndroid Build Coastguard Worker args += [ "--split-dwarf" ] 108*8975f5c5SAndroid Build Coastguard Worker outputs += [ invoker.unstripped_output + ".dwp" ] 109*8975f5c5SAndroid Build Coastguard Worker } 110*8975f5c5SAndroid Build Coastguard Worker args += [ rebase_path(sources[0], root_build_dir) ] 111*8975f5c5SAndroid Build Coastguard Worker } 112*8975f5c5SAndroid Build Coastguard Worker } 113*8975f5c5SAndroid Build Coastguard Worker 114*8975f5c5SAndroid Build Coastguard Worker partition_action(target_name) { 115*8975f5c5SAndroid Build Coastguard Worker stripped_output = "$root_out_dir/lib${_output_name}.so" 116*8975f5c5SAndroid Build Coastguard Worker unstripped_output = "$root_out_dir/lib.unstripped/lib${_output_name}.so" 117*8975f5c5SAndroid Build Coastguard Worker } 118*8975f5c5SAndroid Build Coastguard Worker 119*8975f5c5SAndroid Build Coastguard Worker # Note that as of now, non-base partition libraries are placed in a 120*8975f5c5SAndroid Build Coastguard Worker # subdirectory of the root output directory. This is because partition 121*8975f5c5SAndroid Build Coastguard Worker # sonames are not sensitive to the filename of the base library, and as such, 122*8975f5c5SAndroid Build Coastguard Worker # their corresponding file names may be generated multiple times by different 123*8975f5c5SAndroid Build Coastguard Worker # base libraries. To avoid collisions, each base library target has a 124*8975f5c5SAndroid Build Coastguard Worker # corresponding subdir for its extra partitions. 125*8975f5c5SAndroid Build Coastguard Worker # 126*8975f5c5SAndroid Build Coastguard Worker # If this proves problematic to various pieces of infrastructure, a proposed 127*8975f5c5SAndroid Build Coastguard Worker # alternative is allowing the linker to rename partitions. For example, 128*8975f5c5SAndroid Build Coastguard Worker # feature "foo" may be a partition. If two different base libraries both 129*8975f5c5SAndroid Build Coastguard Worker # define "foo" partitions, the linker may be made to accept an extra command 130*8975f5c5SAndroid Build Coastguard Worker # to rename the partition's soname to "foo1" or "foo2". Other build config 131*8975f5c5SAndroid Build Coastguard Worker # can name the libraries foo1.so and foo2.so, allowing them to reside in the 132*8975f5c5SAndroid Build Coastguard Worker # same directory. 133*8975f5c5SAndroid Build Coastguard Worker foreach(_partition, invoker.partitions) { 134*8975f5c5SAndroid Build Coastguard Worker partition_action("${target_name}_${_partition}") { 135*8975f5c5SAndroid Build Coastguard Worker partition = "${_partition}_partition" 136*8975f5c5SAndroid Build Coastguard Worker stripped_output = "$root_out_dir/lib${_output_name}_${partition}.so" 137*8975f5c5SAndroid Build Coastguard Worker unstripped_output = 138*8975f5c5SAndroid Build Coastguard Worker "$root_out_dir/lib.unstripped/lib${_output_name}_${partition}.so" 139*8975f5c5SAndroid Build Coastguard Worker } 140*8975f5c5SAndroid Build Coastguard Worker } 141*8975f5c5SAndroid Build Coastguard Worker} 142*8975f5c5SAndroid Build Coastguard Worker 143*8975f5c5SAndroid Build Coastguard Workerset_defaults("partitioned_shared_library") { 144*8975f5c5SAndroid Build Coastguard Worker configs = default_shared_library_configs 145*8975f5c5SAndroid Build Coastguard Worker} 146*8975f5c5SAndroid Build Coastguard Worker 147*8975f5c5SAndroid Build Coastguard Worker# native_with_jni for partitioned shared libraries - see native_with_jni for 148*8975f5c5SAndroid Build Coastguard Worker# details. 149*8975f5c5SAndroid Build Coastguard Workertemplate("partitioned_shared_library_with_jni") { 150*8975f5c5SAndroid Build Coastguard Worker native_with_jni(target_name) { 151*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY) 152*8975f5c5SAndroid Build Coastguard Worker forward_variables_from(invoker, TESTONLY_AND_VISIBILITY) 153*8975f5c5SAndroid Build Coastguard Worker target_type = "partitioned_shared_library" 154*8975f5c5SAndroid Build Coastguard Worker target_type_import = "//build/partitioned_shared_library.gni" 155*8975f5c5SAndroid Build Coastguard Worker } 156*8975f5c5SAndroid Build Coastguard Worker} 157*8975f5c5SAndroid Build Coastguard Workerset_defaults("partitioned_shared_library_with_jni") { 158*8975f5c5SAndroid Build Coastguard Worker configs = default_shared_library_configs 159*8975f5c5SAndroid Build Coastguard Worker} 160