tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

rust.rst (8761B)


      1 .. _rust:
      2 
      3 ==============================
      4 Including Rust Code in Firefox
      5 ==============================
      6 
      7 This page explains how to add, build, link, and vendor Rust crates.
      8 
      9 The `code documentation <../../writing-rust-code>`_ explains how to write and
     10 work with Rust code in Firefox. The
     11 `test documentation <../../testing-rust-code>`_ explains how to test and debug
     12 Rust code in Firefox.
     13 
     14 Linking Rust crates into libxul
     15 ===============================
     16 
     17 Rust crates that you want to link into libxul should be listed in the
     18 ``dependencies`` section of
     19 `toolkit/library/rust/shared/Cargo.toml <https://searchfox.org/mozilla-central/source/toolkit/library/rust/shared/Cargo.toml>`_.
     20 You must also add an ``extern crate`` reference to
     21 `toolkit/library/rust/shared/lib.rs <https://searchfox.org/mozilla-central/source/toolkit/library/rust/shared/lib.rs>`_.
     22 This ensures that the Rust code will be linked properly into libxul as well
     23 as the copy of libxul used for gtests. (Even though Rust 2018 mostly doesn't
     24 require ``extern crate`` declarations, these ones are necessary because the
     25 gkrust setup is non-typical.)
     26 
     27 After adding your crate, execute ``cargo update -p gkrust-shared`` to update
     28 the ``Cargo.lock`` file. You will also need to do this any time you change the
     29 dependencies in a ``Cargo.toml`` file. If you don't, you will get a build error
     30 saying **"error: the lock file /home/njn/moz/mc3/Cargo.lock needs to be updated
     31 but --frozen was passed to prevent this"**.
     32 
     33 By default, all Cargo packages in the mozilla-central repository are part of
     34 the same
     35 `workspace <https://searchfox.org/mozilla-central/source/toolkit/library/rust/shared/lib.rs>`_
     36 and will share the ``Cargo.lock`` file and ``target`` directory in the root of
     37 the repository.  You can change this behavior by adding a path to the
     38 ``exclude`` list in the top-level ``Cargo.toml`` file.  You may want to do
     39 this if your package's development workflow includes dev-dependencies that
     40 aren't needed by general Firefox developers or test infrastructure.
     41 
     42 The actual build mechanism is as follows. The build system generates a special
     43 'Rust unified library' crate, compiles that to a static library
     44 (``libgkrust.a``), and links that into libxul, so all public symbols will be
     45 available to C++ code. Building a static library that is linked into a dynamic
     46 library is easier than building dynamic libraries directly, and it also avoids
     47 some subtle issues around how mozalloc works that make the Rust dynamic library
     48 path a little wonky.
     49 
     50 Linking Rust crates into something else
     51 =======================================
     52 
     53 To link Rust code into libraries other than libxul, create a directory with a
     54 ``Cargo.toml`` file for your crate, and a ``moz.build`` file that contains:
     55 
     56 .. code-block:: python
     57 
     58    RustLibrary('crate_name')
     59 
     60 where ``crate_name`` matches the name from the ``[package]`` section of your
     61 ``Cargo.toml``. You can refer to `the moz.build file <https://searchfox.org/mozilla-central/rev/603b9fded7a11ff213c0f415198cd637b7c86614/toolkit/library/rust/moz.build#9>`_ and `the Cargo.toml file <https://searchfox.org/mozilla-central/rev/603b9fded7a11ff213c0f415198cd637b7c86614/toolkit/library/rust/Cargo.toml>`_ that are used for libxul.
     62 
     63 You can then add ``USE_LIBS += ['crate_name']`` to the ``moz.build`` file
     64 that defines the binary as you would with any other library in the tree.
     65 
     66 .. important::
     67 
     68    You cannot link a Rust crate into an intermediate library that will be
     69    eventually linked into libxul. The build system enforces that only a single
     70    ``RustLibrary`` may be linked into a binary. If you need to do this, you
     71    will have to add a ``RustLibrary`` to link to any standalone binaries that
     72    link the intermediate library, and also add the Rust crate to the libxul
     73    dependencies as in `linking Rust Crates into libxul`_.
     74 
     75 Conditional compilation
     76 ========================
     77 
     78 Edit `tool/library/rust/gkrust-features.mozbuild
     79 <https://searchfox.org/mozilla-central/source/toolkit/library/rust/gkrust-features.mozbuild>`_
     80 to expose build flags as Cargo features.
     81 
     82 Standalone Rust programs
     83 ========================
     84 
     85 It is also possible to build standalone Rust programs. First, put the Rust
     86 program (including the ``Cargo.toml`` file and the ``src`` directory) in its
     87 own directory, and add an empty ``moz.build`` file to the same directory.
     88 
     89 Then, if the standalone Rust program must run on the compile target (e.g.
     90 because it's shipped with Firefox) then add this rule to the ``moz.build``
     91 file:
     92 
     93 .. code-block:: python
     94 
     95    RUST_PROGRAMS = ['prog_name']
     96 
     97 where *prog_name* is the name of the executable as specified in the
     98 ``Cargo.toml`` (and probably also matches the name of the directory).
     99 
    100 Otherwise, if the standalone Rust program must run on the compile host (e.g.
    101 because it's used to build Firefox but not shipped with Firefox) then do the
    102 same thing, but use ``HOST_RUST_PROGRAMS`` instead of ``RUST_PROGRAMS``.
    103 
    104 Where should I put my crate?
    105 ============================
    106 
    107 If your crate's canonical home is mozilla-central, you can put it next to the
    108 related code in the appropriate directory.
    109 
    110 If your crate is mirrored into mozilla-central from another repository, and
    111 will not be actively developed in mozilla-central, you can simply list it
    112 as a ``crates.io``-style dependency with a version number, and let it be
    113 vendored into the ``third_party/rust`` directory.
    114 
    115 If your crate is mirrored into mozilla-central from another repository, but
    116 will be actively developed in both locations, you should send mail to the
    117 dev-builds mailing list to start a discussion on how to meet your needs.
    118 
    119 Third-party crate dependencies
    120 ==============================
    121 
    122 Third-party dependencies for in-tree Rust crates are *vendored* into the
    123 ``third_party/rust`` directory of mozilla-central. This means that a copy of
    124 each third-party crate's code is committed into mozilla-central. As a result,
    125 building Firefox does not involve downloading any third-party crates.
    126 
    127 If you add a dependency on a new crate you must run ``mach vendor rust`` to
    128 vendor the dependencies into that directory. (Note that ``mach vendor rust``
    129 `may not work as well on Windows <https://bugzilla.mozilla.org/show_bug.cgi?id=1938341>`_
    130 as on other platforms.)
    131 
    132 When it comes to checking the suitability of third-party code for inclusion
    133 into mozilla-central, keep the following in mind.
    134 
    135 - ``mach vendor rust`` will check that the licenses of all crates are suitable.
    136 - ``mach vendor rust`` will run ``cargo vet`` to ensure that the crates have been audited. If not,
    137  you will have to audit them using ``mach cargo vet`` to check that the code looks reasonable
    138  (especially unsafe code) and that there are reasonable tests. All vendored crates must be audited.
    139 - Third-party crate tests aren't run, which means that large test fixtures will
    140  bloat mozilla-central. Consider working with upstream to mark those test
    141  fixtures with ``[package] exclude = ...`` as described
    142  `here <https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields>`_.
    143 - If you specify a dependency on a branch, pin it to a specific revision,
    144  otherwise other people will get unexpected changes when they run ``./mach
    145  vendor rust`` any time the branch gets updated. See `bug 1612619
    146  <https://bugzil.la/1612619>`_ for a case where such a problem was fixed.
    147 - Other than that, there is no formal sign-off procedure, but one may be added
    148  in the future.
    149 
    150 Note that all dependencies will be vendored, even ones that aren't used due to
    151 disabled features. It's possible that multiple versions of a crate will end up
    152 vendored into mozilla-central.
    153 
    154 Patching third-party crates
    155 ===========================
    156 
    157 Sometimes you might want to temporarily patch a third-party crate, for local
    158 builds or for a try push.
    159 
    160 To do this, first add an entry to the ``[patch.crates-io]`` section of the
    161 top-level ``Cargo.toml`` that points to the crate within ``third_party``. For
    162 example
    163 
    164 .. code-block:: toml
    165 
    166    bitflags = { path = "third_party/rust/bitflags" }
    167 
    168 Next, run ``cargo update -p $CRATE_NAME --precise $VERSION``, where
    169 ``$CRATE_NAME`` is the name of the patched crate, and ``$VERSION`` is its
    170 version number. This will update the ``Cargo.lock`` file.
    171 
    172 Then, make the local changes to the crate.
    173 
    174 Finally, make sure you don't accidentally land the changes to the crate or the
    175 ``Cargo.lock`` file.
    176 
    177 For an example of a more complex workflow involving a third-party crate, see
    178 `mp4parse-rust/README.md <https://searchfox.org/mozilla-central/source/media/mp4parse-rust/README.md>`_.
    179 It describes the workflow for a crate that is hosted on GitHub, and for which
    180 changes are made via GitHub pull requests, but all pull requests must also be
    181 tested within mozilla-central before being merged.