1# Copyright 2019 The Dawn Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import("${skia_root_dir}/build_overrides/build.gni")
16import("dawn_features.gni")
17import("dawn_overrides_with_defaults.gni")
18
19###############################################################################
20# Template to produce a component for one of Dawn's libraries.
21###############################################################################
22
23# Template that produces static and shared versions of the same library as well
24# as a target similar to Chromium's component targets.
25#  - The shared version exports symbols and has dependent import the symbols
26#    as libname.so with target name libname_shared
27#  - The static library doesn't export symbols nor make dependents import them
28#  - The libname target is similar to a Chromium component and is an alias for
29#    either the static or the shared library.
30#
31# The DEFINE_PREFIX must be provided and must match the respective "_export.h"
32# file.
33#
34# Example usage:
35#
36#   dawn_component("my_library") {
37#     // my_library_export.h must use the MY_LIBRARY_IMPLEMENTATION and
38#     // MY_LIBRARY_SHARED_LIBRARY macros.
39#     DEFINE_PREFIX = "MY_LIBRARY"
40#
41#     sources = [...]
42#     deps = [...]
43#     configs = [...]
44#   }
45#
46#   executable("foo") {
47#     deps = [ ":my_library_shared" ] // or :my_library for the same effect
48#   }
49template("dawn_component") {
50  # Copy the target_name in the local scope so it doesn't get shadowed in the
51  # definition of targets.
52  name = target_name
53
54  # The config that will apply to dependents of the shared library so they know
55  # they should "import" the symbols
56  config("${name}_shared_public_config") {
57    defines = [ "${invoker.DEFINE_PREFIX}_SHARED_LIBRARY" ]
58
59    # Executable needs an rpath to find our shared libraries on OSX and Linux
60    if (is_mac) {
61      ldflags = [
62        "-rpath",
63        "@executable_path/",
64      ]
65    }
66    if ((is_linux || is_chromeos) && dawn_has_build) {
67      configs = [ "${skia_root_dir}/build/config/gcc:rpath_for_built_shared_libraries" ]
68    }
69  }
70
71  shared_library("${name}_shared") {
72    # The "tool" for creating shared libraries will automatically add the "lib" prefix
73    output_name = name
74
75    # Copy all variables except "configs", which has a default value
76    forward_variables_from(invoker, "*", [ "configs" ])
77    if (defined(invoker.configs)) {
78      configs += invoker.configs
79    }
80
81    # Tell dependents where to find this shared library
82    if (is_mac) {
83      ldflags = [
84        "-install_name",
85        "@rpath/lib${name}.dylib",
86      ]
87    }
88
89    # Use the config that makes the ${DEFINE_PREFIX}_EXPORT macro do something
90    if (!defined(public_configs)) {
91      public_configs = []
92    }
93    public_configs += [ ":${name}_shared_public_config" ]
94
95    # Tell sources of this library to export the symbols (and not import)
96    if (!defined(defines)) {
97      defines = []
98    }
99    defines += [ "${invoker.DEFINE_PREFIX}_IMPLEMENTATION" ]
100
101    # Chromium adds a config that uses a special linker script that removes
102    # all symbols except JNI ones. Remove this config so that our
103    # shared_library symbols are visible. This matches what Chromium's
104    # component template does.
105    if (build_with_chromium && is_android) {
106      configs -= [ "${skia_root_dir}/build/config/android:hide_all_but_jni_onload" ]
107    }
108  }
109
110  static_library("${name}_static") {
111    output_name = name + "_static"
112
113    complete_static_lib = dawn_complete_static_libs
114
115    # Copy all variables except "configs", which has a default value
116    forward_variables_from(invoker, "*", [ "configs" ])
117    if (defined(invoker.configs)) {
118      configs += invoker.configs
119    }
120  }
121
122  group(name) {
123    if (is_component_build) {
124      public_deps = [ ":${name}_shared" ]
125    } else {
126      public_deps = [ ":${name}_static" ]
127    }
128  }
129}
130