Skip to content

Instantly share code, notes, and snippets.

@hcs64
Last active October 25, 2018 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hcs64/1886c963b02584bf56d2082168a908e0 to your computer and use it in GitHub Desktop.
Save hcs64/1886c963b02584bf56d2082168a908e0 to your computer and use it in GitHub Desktop.
Example of using a Rust crate in a binary

This creates a crate called lib_test in toolkit/mozapps/update/rust and links it into the updater.

Because we're only currently allowing one Rust static library per C++ program (see bug 1310063) it may be best to introduce a level of indirection in case we want to include any other Rust in the updater, e.g. an updater_rust crate that just reexports everything. toolkit/library/rust uses this setup.

The lib_test.h file for inclusion in C++ came out of cbindgen, it seems like we manually run that rather than autogenerating as part of the build, you can find some instructions in another such file at source/gfx/webrender_bindings/webrender_ffi_generated.h

Though... we added cbindgen to the build environment, so we may be able to use it to generate a header as in bug 1478813. But if the interface changes rarely it may not be worth the trouble.

A helpful reference is https://firefox-source-docs.mozilla.org/build/buildsystem/rust.html

diff --git a/Cargo.lock b/Cargo.lock
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1146,16 +1146,20 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazycell"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "lib_test"
+version = "0.1.0"
+
+[[package]]
name = "libc"
version = "0.2.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libloading"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,16 +7,17 @@
members = [
"js/src",
"js/rust",
"js/src/frontend/binsource", # Code generator.
"testing/geckodriver",
"toolkit/crashreporter/rust",
"toolkit/library/gtest/rust",
"toolkit/library/rust/",
+ "toolkit/mozapps/update/rust",
]
# Excluded crates may be built as dependencies, but won't be considered members
# of the workspace and their dev-dependencies won't be included.
exclude = [
# Exclude third-party code vendored into mozilla-central.
"gfx/webrender",
"gfx/webrender_api",
diff --git a/toolkit/mozapps/update/moz.build b/toolkit/mozapps/update/moz.build
--- a/toolkit/mozapps/update/moz.build
+++ b/toolkit/mozapps/update/moz.build
@@ -2,16 +2,17 @@
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_MODULE = 'update'
DIRS += [
+ 'rust',
'updater',
]
XPIDL_SOURCES += [
'nsIUpdateService.idl',
]
TEST_DIRS += ['tests']
diff --git a/toolkit/mozapps/update/rust/Cargo.toml b/toolkit/mozapps/update/rust/Cargo.toml
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/rust/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "lib_test"
+version = "0.1.0"
+
+[dependencies]
+
+[lib]
+path = "lib.rs"
+crate-type = ["staticlib"]
diff --git a/toolkit/mozapps/update/rust/lib.rs b/toolkit/mozapps/update/rust/lib.rs
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/rust/lib.rs
@@ -0,0 +1,4 @@
+#[no_mangle]
+pub extern "C" fn exported_fn() -> u8 {
+ 42
+}
diff --git a/toolkit/mozapps/update/rust/lib_test.h b/toolkit/mozapps/update/rust/lib_test.h
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/rust/lib_test.h
@@ -0,0 +1,8 @@
+#include <cstdint>
+#include <cstdlib>
+
+extern "C" {
+
+uint8_t exported_fn();
+
+} // extern "C"
diff --git a/toolkit/mozapps/update/rust/moz.build b/toolkit/mozapps/update/rust/moz.build
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/rust/moz.build
@@ -0,0 +1,5 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+RustLibrary('lib_test')
diff --git a/toolkit/mozapps/update/updater/updater-common.build b/toolkit/mozapps/update/updater/updater-common.build
--- a/toolkit/mozapps/update/updater/updater-common.build
+++ b/toolkit/mozapps/update/updater/updater-common.build
@@ -44,16 +44,17 @@ if CONFIG['OS_ARCH'] == 'WINNT':
elif CONFIG['OS_ARCH'] == 'Linux' and CONFIG['MOZ_VERIFY_MAR_SIGNATURE']:
USE_LIBS += [
'nss',
'signmar',
]
OS_LIBS += CONFIG['NSPR_LIBS']
USE_LIBS += [
+ 'lib_test',
'mar',
'updatecommon',
'xz-embedded',
]
if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
have_progressui = 1
srcs += [
@@ -87,16 +88,17 @@ SOURCES += sorted(srcs)
DEFINES['NS_NO_XPCOM'] = True
DisableStlWrapping()
for var in ('MAR_CHANNEL_ID', 'MOZ_APP_VERSION'):
DEFINES[var] = '"%s"' % CONFIG[var]
LOCAL_INCLUDES += [
'/toolkit/mozapps/update/common',
+ '/toolkit/mozapps/update/rust',
'/xpcom/base', # for nsVersionComparator.cpp
]
DELAYLOAD_DLLS += [
'crypt32.dll',
'comctl32.dll',
'userenv.dll',
'wsock32.dll',
diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -29,16 +29,17 @@
* -----------
* method = "remove" | "rmdir"
*/
#include "bspatch.h"
#include "progressui.h"
#include "archivereader.h"
#include "readstrings.h"
#include "errors.h"
+#include "lib_test.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -2645,16 +2646,20 @@ int LaunchCallbackAndPostProcessApps(int
int NS_main(int argc, NS_tchar **argv)
{
// The callback is the remaining arguments starting at callbackIndex.
// The argument specified by callbackIndex is the callback executable and the
// argument prior to callbackIndex is the working directory.
const int callbackIndex = 6;
+ if (exported_fn() != 42) {
+ return 1;
+ }
+
#ifdef XP_MACOSX
// We want to control file permissions explicitly, or else we could end up
// corrupting installs for other users on the system. Accordingly, set the
// umask to 0 for all file creations below and reset it on exit. See Bug 1337007
UmaskContext umaskContext(0);
bool isElevated =
strstr(argv[0], "/Library/PrivilegedHelperTools/org.mozilla.updater") != 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment