1# Copyright 2015 The Native Client 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/config/nacl/config.gni")
6
7# Generate a nmf file
8#
9# Native Client Manifest (nmf) is a JSON file that tells the browser where to
10# download and load Native Client application files and libraries.
11#
12# Variables:
13#   executables: .nexe/.pexe/.bc executables to generate nmf for
14#   lib_prefix: path to prepend to shared libraries in the nmf
15#   nmf: the name and the path of the output file
16#   nmfflags: additional flags for the nmf generator
17#   stage_dependencies: directory for staging libraries
18template("generate_nmf") {
19  assert(defined(invoker.executables), "Must define executables")
20  assert(defined(invoker.nmf), "Must define nmf")
21
22  action(target_name) {
23    forward_variables_from(invoker,
24                           [
25                             "deps",
26                             "data_deps",
27                             "executables",
28                             "lib_prefix",
29                             "nmf",
30                             "nmfflags",
31                             "public_deps",
32                             "stage_dependencies",
33                             "testonly",
34                             "visibility",
35                           ])
36    if (!defined(nmfflags)) {
37      nmfflags = []
38    }
39
40    # TODO(phosek): Remove this conditional once
41    # https://bugs.chromium.org/p/nativeclient/issues/detail?id=4339 is
42    # resolved.
43    if (current_cpu == "pnacl") {
44      objdump = rebase_path("${nacl_toolchain_bindir}/x86_64-nacl-objdump")
45    } else {
46      objdump = rebase_path("${nacl_toolprefix}objdump")
47    }
48    if (host_os == "win") {
49      objdump += ".exe"
50    }
51
52    script = "//native_client_sdk/src/tools/create_nmf.py"
53    inputs = [ objdump ]
54    sources = executables
55    outputs = [ nmf ]
56    if (is_nacl_glibc) {
57      if (defined(stage_dependencies)) {
58        nmfflags += [ "--stage-dependencies=" +
59                      rebase_path(stage_dependencies, root_build_dir) ]
60        lib_path = stage_dependencies
61      } else {
62        lib_path = root_build_dir
63      }
64      if (defined(lib_prefix)) {
65        nmfflags += [ "--lib-prefix=" + lib_prefix ]
66        lib_path += "/${lib_prefix}"
67      }
68
69      # Starts empty so the code below can use += everywhere.
70      data = []
71
72      nmfflags +=
73          [ "--library-path=" + rebase_path(root_out_dir, root_build_dir) ]
74
75      # NOTE: There is no explicit dependency for the lib directory
76      # (lib32 and lib64 for x86/x64) created in the product directory.
77      # They are created as a side-effect of nmf creation.
78      if (current_cpu != "x86" && current_cpu != "x64") {
79        nmfflags +=
80            [ "--library-path=" +
81              rebase_path("${nacl_toolchain_tooldir}/lib", root_build_dir) ]
82        if (current_cpu == "arm") {
83          data += [ "${lib_path}/libarm/" ]
84        } else {
85          data += [ "${lib_path}/lib/" ]
86        }
87      } else {
88        # For x86-32, the lib/ directory is called lib32/ instead.
89        if (current_cpu == "x86") {
90          nmfflags +=
91              [ "--library-path=" +
92                rebase_path("${nacl_toolchain_tooldir}/lib32", root_build_dir) ]
93          data += [ "${lib_path}/lib32/" ]
94        }
95
96        # x86-32 Windows needs to build both x86-32 and x86-64 NaCl
97        # binaries into the same nmf covering both architectures.  That
98        # gets handled at a higher level (see the nacl_test_data template),
99        # so a single generate_nmf invocation gets both x86-32 and x86-64
100        # nexes listed in executables.
101        if (current_cpu == "x64" || target_os == "win") {
102          # For x86-64, the lib/ directory is called lib64/ instead
103          # when copied by create_nmf.py.
104          glibc_tc = "//build/toolchain/nacl:glibc"
105          assert(current_toolchain == "${glibc_tc}_${current_cpu}")
106          if (current_cpu == "x64") {
107            x64_out_dir = root_out_dir
108          } else {
109            x64_out_dir = get_label_info(":${target_name}(${glibc_tc}_x64)",
110                                         "root_out_dir")
111          }
112          nmfflags += [
113            "--library-path=" + rebase_path(x64_out_dir, root_build_dir),
114            "--library-path=" +
115                rebase_path("${nacl_toolchain_tooldir}/lib", root_build_dir),
116          ]
117          data += [ "${lib_path}/lib64/" ]
118        }
119      }
120    }
121    args = [
122             "--no-default-libpath",
123             "--objdump=" + rebase_path(objdump, root_build_dir),
124             "--output=" + rebase_path(nmf, root_build_dir),
125           ] + nmfflags + rebase_path(sources, root_build_dir)
126    if (is_nacl_glibc && current_cpu == "arm") {
127      deps += [ "//native_client/src/untrusted/elf_loader:elf_loader" ]
128    }
129  }
130}
131
132# Generate a nmf file for Non-SFI tests
133#
134# Non-SFI tests use a different manifest format from regular Native Client and
135# as such requires a different generator.
136#
137# Variables:
138#   executable: Non-SFI .nexe executable to generate nmf for
139#   nmf: the name and the path of the output file
140#   nmfflags: additional flags for the nmf generator
141template("generate_nonsfi_test_nmf") {
142  assert(defined(invoker.executable), "Must define executable")
143  assert(defined(invoker.nmf), "Must define nmf")
144
145  action(target_name) {
146    forward_variables_from(invoker,
147                           [
148                             "deps",
149                             "data_deps",
150                             "executable",
151                             "nmf",
152                             "testonly",
153                             "public_deps",
154                             "visibility",
155                           ])
156
157    script = "//ppapi/tests/create_nonsfi_test_nmf.py"
158    sources = [ executable ]
159    outputs = [ nmf ]
160
161    # NOTE: We use target_cpu rather than current_cpu on purpose because
162    # current_cpu is always going to be pnacl for Non-SFI, but the Non-SFI
163    # .nexe executable is always translated to run on the target machine.
164    if (target_cpu == "x86") {
165      arch = "x86-32"
166    } else if (target_cpu == "x64") {
167      arch = "x86-64"
168    } else {
169      arch = target_cpu
170    }
171    args = [
172      "--program=" + rebase_path(executable, root_build_dir),
173      "--arch=${arch}",
174      "--output=" + rebase_path(nmf, root_build_dir),
175    ]
176    if (defined(invoker.nmfflags)) {
177      args += invoker.nmfflags
178    }
179  }
180}
181