1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import("//build/toolchain/toolchain.gni")
6import("//mojo/public/mojo_constants.gni")
7
8if (is_android) {
9  import("//build/config/android/rules.gni")
10  import("//build/config/zip.gni")
11}
12
13# Generate a binary Mojo application in a self-named directory.
14# Application resources are copied to a "resources" directory alongside the app.
15# The parameters of this template are those of a shared library.
16template("mojo_native_application") {
17  base_target_name = target_name
18  if (defined(invoker.output_name)) {
19    base_target_name = invoker.output_name
20  }
21
22  final_target_name = target_name
23
24  mojo_deps = []
25  if (defined(invoker.deps)) {
26    mojo_deps += invoker.deps
27  }
28
29  mojo_data_deps = []
30
31  if (defined(invoker.resources)) {
32    copy_step_name = "${base_target_name}__copy_resources"
33    copy(copy_step_name) {
34      sources = invoker.resources
35      outputs = [
36        "${root_out_dir}/${mojo_application_subdir}/${base_target_name}/resources/{{source_file_part}}",
37      ]
38      if (defined(invoker.testonly)) {
39        testonly = invoker.testonly
40      }
41      deps = mojo_deps
42    }
43    mojo_data_deps += [ ":$copy_step_name" ]
44  }
45
46  output = base_target_name + ".mojo"
47  library_target_name = base_target_name + "_library"
48  library_name = "${shlib_prefix}${library_target_name}${shlib_extension}"
49
50  shared_library(library_target_name) {
51    if (defined(invoker.cflags)) {
52      cflags = invoker.cflags
53    }
54    if (defined(invoker.cflags_c)) {
55      cflags_c = invoker.cflags_c
56    }
57    if (defined(invoker.cflags_cc)) {
58      cflags_cc = invoker.cflags_cc
59    }
60    if (defined(invoker.cflags_objc)) {
61      cflags_objc = invoker.cflags_objc
62    }
63    if (defined(invoker.cflags_objcc)) {
64      cflags_objcc = invoker.cflags_objcc
65    }
66    if (defined(invoker.defines)) {
67      defines = invoker.defines
68    }
69    if (defined(invoker.include_dirs)) {
70      include_dirs = invoker.include_dirs
71    }
72    if (defined(invoker.ldflags)) {
73      ldflags = invoker.ldflags
74    }
75    if (defined(invoker.lib_dirs)) {
76      lib_dirs = invoker.lib_dirs
77    }
78    if (defined(invoker.libs)) {
79      libs = invoker.libs
80    }
81
82    data_deps = []
83    if (!defined(invoker.avoid_runner_cycle) || !invoker.avoid_runner_cycle) {
84      # Give the user an out; as some mojo services are depended on by the
85      # runner.
86      data_deps += [ "//services/shell/standalone" ]
87    }
88    if (defined(invoker.data_deps)) {
89      data_deps += invoker.data_deps
90    }
91    data_deps += mojo_data_deps
92
93    deps = [
94      "//mojo/public/c/system:set_thunks_for_app",
95      "//services/shell/public/cpp:application_support",
96    ]
97
98    deps += mojo_deps
99    if (defined(invoker.public_deps)) {
100      public_deps = invoker.public_deps
101    }
102    if (defined(invoker.all_dependent_configs)) {
103      all_dependent_configs = invoker.all_dependent_configs
104    }
105    if (defined(invoker.public_configs)) {
106      public_configs = invoker.public_configs
107    }
108    if (defined(invoker.check_includes)) {
109      check_includes = invoker.check_includes
110    }
111    if (defined(invoker.configs)) {
112      configs += invoker.configs
113    }
114    if (defined(invoker.data)) {
115      data = invoker.data
116    }
117    if (defined(invoker.inputs)) {
118      inputs = invoker.inputs
119    }
120    if (defined(invoker.public)) {
121      public = invoker.public
122    }
123    if (defined(invoker.sources)) {
124      sources = invoker.sources
125    }
126    if (defined(invoker.testonly)) {
127      testonly = invoker.testonly
128    }
129  }
130
131  copy(final_target_name) {
132    forward_variables_from(invoker,
133                           [
134                             "testonly",
135                             "visibility",
136                           ])
137    deps = [
138      ":${library_target_name}",
139    ]
140
141    sources = [
142      "${root_shlib_dir}/${library_name}",
143    ]
144    outputs = [
145      "${root_out_dir}/${mojo_application_subdir}/${base_target_name}/${output}",
146    ]
147  }
148
149  if (is_android) {
150    android_assets("${final_target_name}_assets") {
151      forward_variables_from(invoker, [ "testonly" ])
152      deps = [
153        ":${library_target_name}",
154      ]
155      if (defined(invoker.deps)) {
156        deps += invoker.deps
157      }
158      renaming_sources = [ "${root_shlib_dir}/${library_name}" ]
159      renaming_destinations = [ "${base_target_name}/${output}" ]
160      if (defined(invoker.resources)) {
161        renaming_sources += invoker.resources
162        renaming_destinations += process_file_template(
163                invoker.resources,
164                [ "$base_target_name/resources/{{source_file_part}}" ])
165      }
166    }
167  }
168}
169
170if (is_android) {
171  # Declares an Android Mojo application consisting of an .so file and a
172  # corresponding .dex.jar file.
173  #
174  # Variables:
175  #   input_so: the .so file to bundle
176  #   input_dex_jar: the .dex.jar file to bundle
177  #   deps / public_deps / data_deps (optional):
178  #       Dependencies. The targets that generate the .so/jar inputs should be
179  #       listed in either deps or public_deps.
180  #   output_name (optional): override for the output file name
181  template("mojo_android_application") {
182    assert(defined(invoker.input_so))
183    assert(defined(invoker.input_dex_jar))
184
185    base_target_name = target_name
186    if (defined(invoker.output_name)) {
187      base_target_name = invoker.output_name
188    }
189
190    mojo_data_deps = []
191    if (defined(invoker.resources)) {
192      copy_step_name = "${base_target_name}__copy_resources"
193      copy(copy_step_name) {
194        sources = invoker.resources
195        outputs = [
196          "${root_out_dir}/${mojo_application_subdir}/${base_target_name}/resources/{{source_file_part}}",
197        ]
198        if (defined(invoker.testonly)) {
199          testonly = invoker.testonly
200        }
201        if (defined(invoker.deps)) {
202          deps = invoker.deps
203        }
204      }
205      mojo_data_deps += [ ":$copy_step_name" ]
206    }
207
208    zip_action_name = "${target_name}_zip"
209    zip_action_output = "$target_gen_dir/${target_name}.zip"
210    prepend_action_name = target_name
211    zip(zip_action_name) {
212      visibility = [ ":$prepend_action_name" ]
213      inputs = [
214        invoker.input_so,
215        invoker.input_dex_jar,
216      ]
217      output = zip_action_output
218      forward_variables_from(invoker,
219                             [
220                               "deps",
221                               "public_deps",
222                               "data_deps",
223                             ])
224    }
225
226    _mojo_output = "${root_out_dir}/${mojo_application_subdir}/${base_target_name}/${base_target_name}.mojo"
227
228    action(target_name) {
229      script = "//mojo/public/tools/prepend.py"
230
231      input = zip_action_output
232      inputs = [
233        input,
234      ]
235
236      outputs = [
237        _mojo_output,
238      ]
239
240      rebase_input = rebase_path(input, root_build_dir)
241      rebase_output = rebase_path(_mojo_output, root_build_dir)
242      args = [
243        "--input=$rebase_input",
244        "--output=$rebase_output",
245        "--line=#!mojo mojo:android_handler",
246      ]
247
248      data_deps = mojo_data_deps
249
250      public_deps = [
251        ":$zip_action_name",
252      ]
253    }
254
255    android_assets("${target_name}_assets") {
256      forward_variables_from(invoker, [ "testonly" ])
257      deps = [
258        ":$prepend_action_name",
259      ]
260      renaming_sources = [ _mojo_output ]
261      renaming_destinations = [ "${base_target_name}/${base_target_name}.mojo" ]
262      if (defined(invoker.resources)) {
263        renaming_sources += invoker.resources
264        renaming_destinations += process_file_template(
265                invoker.resources,
266                [ "$base_target_name/resources/{{source_file_part}}" ])
267      }
268    }
269  }
270}
271