File: rust_cxx.gni

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (173 lines) | stat: -rw-r--r-- 6,060 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//build/config/clang/clang.gni")
import("//build/config/rust.gni")
import("//build/config/sysroot.gni")

set_defaults("rust_cxx") {
  native_header_deps = []
}

# Template to build Rust/C++ bindings using the tooling
# described at https://cxx.rs.
#
# (Specifically, this builds the C++ side of the bindings.
# The Rust side of the bindings are not 'built' as such, but
# automatically expanded by the Rust compiler by virtue of a
# proc macro which is a simple dependency relationship on the
# Rust target).
#
# This template expands to a source_set containing the
# C++ side of the bindings. Simply treat it as a dependency.
#
# If you're using this, consider whether you should be using
# rust_static_library.gni or mixed_static_library.gni which have
# facilities to do the same code generation in an easier
# way.
#
# Parameters:
#
# sources:
#   The .rs files containing a #[cxx::bridge] section.
#
# deps (optional)
#   C++ targets on which the headers depend in order to build
#   successfully.
#
# export_symbols
#   Whether the C++ side of the bindings should be exported
#   from any shared objects in which it finds itself.
#   This is not necessary if the Rust and C++ side of the
#   bindings will always find themselves within the same binary,
#   which is usually the case in a non-component build.
#   Even in a component build, the Rust and C++ code will
#   often find itself within the same binary and no exporting
#   is required. However, there may be other binaries - most
#   commonly Rust unit test executables - which contain the
#   Rust side of the bindings but not the C++ side. In such
#   a case, it's important that the C++ side symbols are
#   exported such that the Rust unit tests can link against
#   them. This does the equivalent of adding BASE_EXPORT
#   or similar.
#   Example:
#     Non-component build:
#       group of libfoo.a, foo.rlib # contain
#          # C++ and Rust side bindings, always both linked
#          # into final targets
#       foo_rs_unittests # contains Rust side bindings,
#          # and any C++ dependencies which will include
#          # all of the libfoo code.
#     Component build:
#       libfoo.so # contains C++ and Rust side bindings
#       foo_rs_unittests # contains Rust side test code,
#          # but links against libfoo.so to get the C++
#          # side bindings. So libfoo.so must make those
#          # symbols visible.
template("rust_cxx") {
  assert(defined(invoker.sources),
         "Must specify the Rust file to use as input.")
  _target_name = target_name
  _testonly = false
  if (defined(invoker.testonly)) {
    _testonly = invoker.testonly
  }
  if (defined(invoker.visibility)) {
    _visibility = invoker.visibility
  }

  action_foreach("${_target_name}_gen") {
    testonly = _testonly
    visibility = [ ":${_target_name}" ]
    if (defined(_visibility)) {
      visibility += _visibility
    }

    sources = invoker.sources

    output_h = "{{source_gen_dir}}/{{source_file_part}}.h"
    output_cc = "{{source_gen_dir}}/{{source_file_part}}.cc"

    # Below we use $rust_macro_toolchain rather than $host_toolchain since we
    # are building a standalone Rust target that is not part of the Chromium
    # production build, and this unblocks it from building while the Chromium
    # stdlib is still compiling, further freeing up other Rust proc-macro
    # targets (if they used cxxbridge for some reason).
    cxxbridge_target =
        "//third_party/rust/cxxbridge_cmd/v1:cxxbridge($rust_macro_toolchain)"

    cxxbridge_out_dir = get_label_info(cxxbridge_target, "root_out_dir")
    cxxbridge_executable = "${cxxbridge_out_dir}/cxxbridge"

    # The executable is always built with the `rust_macro_toolchain` which
    # targets the `host_os`. The rule here is on the `target_toolchain` which
    # can be different (e.g. compiling on Linux, targeting Windows).
    if (host_os == "win") {
      cxxbridge_executable = "${cxxbridge_executable}.exe"
    }

    script = "//third_party/rust/cxx/chromium_integration/run_cxxbridge.py"
    inputs = [
      cxxbridge_executable,
      script,
    ]
    outputs = [
      output_h,
      output_cc,
    ]
    deps = [ cxxbridge_target ]

    args = [
      "--exe",
      rebase_path(cxxbridge_executable, root_build_dir),
      "--header",
      output_h,
      "--cc",
      output_cc,
      "{{source}}",
      "--",
    ]

    if (invoker.export_symbols) {
      # See explanation of 'export_symbols' above for what this does.
      # Implementation note: we could have required users of this template to
      # specify a preprocessor symbol, e.g. BASE_EXPORT, which would vary
      # per-component. However, since we're building only the definition of the
      # bindings, not any header files, the export specifications are
      # predictable and we don't need to foist that complexity on users of this
      # template. The default behavior here should be correct. If this proves to
      # be insufficient in future, this template should be modified to accept a
      # parameter where users can specify 'BASE_EXPORT' or the equivalent for
      # their component. cxxbridge --cxx-impl-annotations adds this annotation
      # to each exported C++ function.
      args += [ "--cxx-impl-annotations" ]
      if (is_win) {
        args += [ "__declspec(dllexport)" ]
      } else {
        args += [ "__attribute__((visibility(\"default\")))" ]
      }
    }
  }

  static_library(target_name) {
    forward_variables_from(invoker, [ "deps" ])

    testonly = _testonly
    if (defined(invoker.visibility)) {
      visibility = invoker.visibility
    }
    sources = get_target_outputs(":${target_name}_gen")
    if (!defined(deps)) {
      deps = []
    }
    deps += [
      ":${target_name}_gen",
      "//build/rust:cxx_cppdeps",
    ]
    if (defined(invoker.configs)) {
      configs = []
      configs = invoker.configs
    }
  }
}