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