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