Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link and use Rust runtime from C++ main #801

Merged
merged 11 commits into from
Apr 16, 2020
Merged

Link and use Rust runtime from C++ main #801

merged 11 commits into from
Apr 16, 2020

Conversation

daviddrysdale
Copy link
Contributor

@daviddrysdale daviddrysdale commented Apr 1, 2020

Checklist

  • Pull request affects core Oak functionality (e.g. runtime, SDK, ABI)
    • I have written tests that cover the code changes.
    • I have checked that these tests are run by Cloudbuild
    • I have updated documentation accordingly.
    • I have raised an issue to
      cover any TODOs and/or unfinished work.
  • Pull request includes prototype/experimental work that is under
    construction.

@daviddrysdale daviddrysdale added the WIP Work in progress label Apr 1, 2020
@daviddrysdale
Copy link
Contributor Author

Fixes #729

@tiziano88 tiziano88 mentioned this pull request Apr 3, 2020
4 tasks
@tiziano88 tiziano88 added this to In progress in planning via automation Apr 6, 2020
@daviddrysdale daviddrysdale removed the WIP Work in progress label Apr 7, 2020
@daviddrysdale daviddrysdale marked this pull request as ready for review April 7, 2020 12:29
@daviddrysdale
Copy link
Contributor Author

There's obviously a lot of stuff here, but reviewing commit-by-commit will help. They're also in chunks:

  • First, some preparatory commits fixing up the C++ runtime slightly:
    • 3b59117 runtime: drop unneeded return statements
    • d88f934 runtime: give each node an ID as well as a name
    • e426559 runtime: always reply on invocation fail
  • Next, some tweaks to the build of the Rust runtime to make integration work:
    • 9759f6a runtime/rust: check in prost-generated Rust files
    • aeaca3c runtime/rust: pull in default features of rand
    • e1afe0e runtime/rust: add WASI placeholders
    • 92166f4 runtime/rust: make handle/ID structs public
  • Getting Bazel->rustc build systems working:
    • 9110b98 runtime/rust: set up cargo raze
    • c160b48 runtime/rust: add BUILD files for Rust crates
  • Now start on the actual code for C++ & Rust interop:
    • 10d346d runtime/rust: allow creation of external nodes
    • 39fe05a runtime/glue: add C++->Rust FFI glue code
  • Then plumb in the hooks so the C++ code invokes Rust runtime function:
    • 9aa922a runtime: defer functionality to Rust runtime
  • Now this works, we can delete huge swathes of C++ code:
    • 382c6b9 runtime: remove now-unused C++ functionality
  • The current C++ runtime doesn't really do shutdown. Fix that, so we can check it still works in a C++/Rust world:
    • 5518c8b runtime: use Create() factory method
    • e6011b6 runtime/runner: trigger termination on SIGINT
  • Sadly, I can't figure out how to keep the ARM build working with cargo raze in the picture:
    • 99c9042 (origin/rust-link, rust-link) cloudbuild: cross-compile to ARM no longer works

If it helps, I can split out the preparatory commits (the first two sections) into separate PRs.

Copy link
Collaborator

@tiziano88 tiziano88 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete all the C++ code! (well, almost)

@@ -29,6 +29,7 @@ fn main() {
}

prost_build::Config::new()
.out_dir("src/proto/")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this end up rebuilding everything every single time, because it generates files within the source tree directly, and then assume that things have changed and rebuild everything unconditionally? I think we had to change this in the past exactly to avoid this problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem to, not sure why:

drysdale@ring:~/src/oak/oak/server/rust/oak_abi{rust-link}:cargo build --verbose
       Fresh cfg-if v0.1.10
       Fresh unicode-xid v0.2.0
       Fresh ppv-lite86 v0.2.6
       Fresh remove_dir_all v0.5.2
       Fresh autocfg v1.0.0
       Fresh either v1.5.3
       Fresh bytes v0.5.4
       Fresh same-file v1.0.6
       Fresh fixedbitset v0.2.0
       Fresh unicode-segmentation v1.6.0
       Fresh autocfg v0.1.7
       Fresh multimap v0.8.0
       Fresh maplit v1.0.2
       Fresh c2-chacha v0.2.3
       Fresh itertools v0.8.2
       Fresh walkdir v2.3.1
       Fresh heck v0.3.1
       Fresh libc v0.2.66
       Fresh proc-macro2 v1.0.8
       Fresh log v0.4.8
       Fresh protobuf v2.10.1
       Fresh anyhow v1.0.26
       Fresh getrandom v0.1.14
       Fresh quote v1.0.2
       Fresh protobuf-codegen v2.10.1
       Fresh which v3.1.0
       Fresh protoc v2.10.1
       Fresh rand v0.4.6
       Fresh indexmap v1.3.2
       Fresh syn v1.0.14
       Fresh rand_core v0.5.1
       Fresh grpc-compiler v0.7.0 (/usr/local/google/home/drysdale/src/oak/third_party/grpc-rust/grpc-compiler)
       Fresh tempdir v0.3.7
       Fresh petgraph v0.5.0
       Fresh rand_chacha v0.2.1
       Fresh prost-derive v0.6.1
       Fresh proc-macro-hack v0.5.11
       Fresh rand v0.7.3
       Fresh prost v0.6.1
       Fresh const-random-macro v0.1.8
       Fresh tempfile v3.1.0
       Fresh prost-types v0.6.1
       Fresh const-random v0.1.8
       Fresh protoc-rust v2.10.1
       Fresh prost-build v0.6.1
       Fresh ahash v0.2.18
       Fresh protoc-rust-grpc v0.7.0 (/usr/local/google/home/drysdale/src/oak/third_party/grpc-rust/protoc-rust-grpc)
       Fresh hashbrown v0.6.3
       Fresh oak_utils v0.1.0 (/usr/local/google/home/drysdale/src/oak/sdk/rust/oak_utils)
       Fresh oak_abi v0.1.0 (/usr/local/google/home/drysdale/src/oak/oak/server/rust/oak_abi)
    Finished dev [unoptimized + debuginfo] target(s) in 0.29s

@@ -93,16 +95,17 @@ class OakRuntime : public BaseRuntime {
// to the initial Application Wasm Node.
Handle app_handle_;

// Next index for node name generation.
mutable absl::Mutex mu_; // protects nodes_, next_index_;
// Next indexes for node name/ID generation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indices? 🤷‍♂️

@@ -796,9 +852,12 @@ impl super::Node for WasmNode {
{
let (abi, _) =
WasmInterface::new(self.config_name.clone(), self.runtime.clone(), self.reader);
let wasi_stub = WasiStub {};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is {} even needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, gone.

* limitations under the License.
*/

#ifndef OAK_SERVER_RUST_OAK_GLUE_H_
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered / looked into using https://github.com/rust-lang/rust-bindgen to generate Rust stubs from this header file? Not sure how well it would work with Bazel though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I just went for manual generation (I basically resurrected the old oak_tests host functions)

Comment on lines +43 to +45
// The following functions are analogous to those on the Oak ABI, with the
// addition of an initial node_id parameter that identifies the Node performing
// the operation.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(optional) Personally I think it would be more appropriate to say that the are the same as the Oak Rust API. "Oak ABI" really means Wasm host function calls, and the fact that we even have Wasm nodes seems an implementation detail here. If anything, we should have a doc comment on the Wasm ABI saying that the functions there are analogous to the Rust API :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really agree.

  • The Oak Rust API, as provided by the SDK, gives access to Oak functionality using normal Rust types (e.g. with no need to worry about raw memory).
  • The Oak ABI gives access to Oak functionality using a defined arrangement of low-level bytes, linear memory offsets and host functions.
  • The glue here gives access to Oak functionality using a defined arrangement of low-level bytes, raw memory pointers, and extern "C" functions.

So "analogous to .. the ABI" seems the most helpful description for the glue.

Comment on lines 142 to 159
let size = oak_abi::SPACE_BYTES_PER_HANDLE * count as usize;
let mut handle_data = Vec::<u8>::with_capacity(size);
std::ptr::copy_nonoverlapping(buf, handle_data.as_mut_ptr(), size);
handle_data.set_len(size);
let mut handles = Vec::with_capacity(count as usize);
let mut mem_reader = Cursor::new(handle_data);
for _ in 0..count {
let handle = mem_reader.read_u64::<byteorder::LittleEndian>().unwrap();
let _b = mem_reader.read_u8().unwrap();
debug!("{{{}}}: wait_on_channels handle {:?}", node_id, handle);
handles.push(Some(oak_runtime::Handle(handle)));
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is from_raw_parts not good here because of potentially different endianness? Either way, perhaps add a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow – from_raw_parts isn't relevant here because we're not building a slice from a contiguous sequence of elements in memory (every ninth byte gets skipped). Added a comment.

.unwrap_or(OakStatus::ErrInternal as u32)
}

/// # Safety
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps add a see [`Runtime::channel_read`] or similar "redirect" comment (also elsewhere).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -0,0 +1 @@

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines +55 to +71
impl super::Node for PseudoNode {
fn start(&mut self) -> Result<(), OakStatus> {
// Clone or copy all the captured values and move them into the closure, for simplicity.
let config_name = self.config_name.clone();
let runtime = self.runtime.clone();
let reader = self.reader;
let thread_handle = thread::Builder::new()
.name(format!("external={}", config_name))
.spawn(move || {
let pretty_name = format!("{}-{:?}:", config_name, thread::current());
let factory_fn: NodeFactory = FACTORY
.read()
.expect("unlock failed")
.expect("no registered factory");
info!(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a big fan of all this two-way registering protocol, and also the fact that the Runtime does not actually know what's going to happen when creating an unrecognized pseudo-node. I think it's fine to assume that if we add a new pseudo-node type in C++, we can manage adding a bit of code to the Rust runtime to connect things in a more idiomatic way, and avoid the External configuration enum type too. Perhaps just keep an ExternalNode struct here that wraps the thread creation, and forwards to the actual C method that executes the main node event loop. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there's a certain amount of path-of-least-resistance:

  • With main in C++, we only want explicit linkage from C++ to Rust, not vice versa (to avoid cycles)
  • Rust needs to up-call to C++ for pseudo-Node creation, which therefore has to happen via a function pointer.
  • Any such function pointer then has to be registered via a call from C++ to Rust.
  • A single such function pointer can currently be used for all pseudo-Node types, because the C++ runtime has a full copy of the configuration and so the config name is all that's needed, regardless of pseudo-Node type (no need to pass pseudo-Node-specific configuration values extracted from the ApplicationConfiguration).

A lot of the above will change once main is in Rust, so I don't think it's worth changing things here – #724 will require a re-work of the C++ pseudo-Node registration stuff anyway (and I've added a reminder TODO).

OAK_LOG(INFO) << "Dropping " << channel_halves_.size() << " handles for Node";
channel_halves_.clear();
int count = statuses->size();
std::vector<uint8_t> space(9 * count);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give 9 a name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Contributor Author

@daviddrysdale daviddrysdale left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that #772 has been merged, this now has an awkward clash:

@@ -0,0 +1 @@

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -29,6 +29,7 @@ fn main() {
}

prost_build::Config::new()
.out_dir("src/proto/")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't seem to, not sure why:

drysdale@ring:~/src/oak/oak/server/rust/oak_abi{rust-link}:cargo build --verbose
       Fresh cfg-if v0.1.10
       Fresh unicode-xid v0.2.0
       Fresh ppv-lite86 v0.2.6
       Fresh remove_dir_all v0.5.2
       Fresh autocfg v1.0.0
       Fresh either v1.5.3
       Fresh bytes v0.5.4
       Fresh same-file v1.0.6
       Fresh fixedbitset v0.2.0
       Fresh unicode-segmentation v1.6.0
       Fresh autocfg v0.1.7
       Fresh multimap v0.8.0
       Fresh maplit v1.0.2
       Fresh c2-chacha v0.2.3
       Fresh itertools v0.8.2
       Fresh walkdir v2.3.1
       Fresh heck v0.3.1
       Fresh libc v0.2.66
       Fresh proc-macro2 v1.0.8
       Fresh log v0.4.8
       Fresh protobuf v2.10.1
       Fresh anyhow v1.0.26
       Fresh getrandom v0.1.14
       Fresh quote v1.0.2
       Fresh protobuf-codegen v2.10.1
       Fresh which v3.1.0
       Fresh protoc v2.10.1
       Fresh rand v0.4.6
       Fresh indexmap v1.3.2
       Fresh syn v1.0.14
       Fresh rand_core v0.5.1
       Fresh grpc-compiler v0.7.0 (/usr/local/google/home/drysdale/src/oak/third_party/grpc-rust/grpc-compiler)
       Fresh tempdir v0.3.7
       Fresh petgraph v0.5.0
       Fresh rand_chacha v0.2.1
       Fresh prost-derive v0.6.1
       Fresh proc-macro-hack v0.5.11
       Fresh rand v0.7.3
       Fresh prost v0.6.1
       Fresh const-random-macro v0.1.8
       Fresh tempfile v3.1.0
       Fresh prost-types v0.6.1
       Fresh const-random v0.1.8
       Fresh protoc-rust v2.10.1
       Fresh prost-build v0.6.1
       Fresh ahash v0.2.18
       Fresh protoc-rust-grpc v0.7.0 (/usr/local/google/home/drysdale/src/oak/third_party/grpc-rust/protoc-rust-grpc)
       Fresh hashbrown v0.6.3
       Fresh oak_utils v0.1.0 (/usr/local/google/home/drysdale/src/oak/sdk/rust/oak_utils)
       Fresh oak_abi v0.1.0 (/usr/local/google/home/drysdale/src/oak/oak/server/rust/oak_abi)
    Finished dev [unoptimized + debuginfo] target(s) in 0.29s

OAK_LOG(INFO) << "Dropping " << channel_halves_.size() << " handles for Node";
channel_halves_.clear();
int count = statuses->size();
std::vector<uint8_t> space(9 * count);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

/// Caller must ensure that the memory range [config_buf, config_buf+config_len) is
/// accessible and holds a protobuf-serialized ApplicationConfiguration message.
#[no_mangle]
pub unsafe extern "C" fn glue_start(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what I understood unsafe to mean, in this context – an unsafe function has "requirements we need to uphold when we call this function, because Rust can’t guarantee we’ve met these requirements".

#[no_mangle]
pub unsafe extern "C" fn glue_start(
config_buf: *const u8,
config_len: u32,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer an explicitly sized type here so there's no need to think about whether the C++ and Rust int/pointer sizes match.

(I may be slightly contradicting myself with #279, but the more important part of that was the linear-memory offset integer type, which isn't relevant here because there are actual pointer types available.)

Comment on lines +43 to +45
// The following functions are analogous to those on the Oak ABI, with the
// addition of an initial node_id parameter that identifies the Node performing
// the operation.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really agree.

  • The Oak Rust API, as provided by the SDK, gives access to Oak functionality using normal Rust types (e.g. with no need to worry about raw memory).
  • The Oak ABI gives access to Oak functionality using a defined arrangement of low-level bytes, linear memory offsets and host functions.
  • The glue here gives access to Oak functionality using a defined arrangement of low-level bytes, raw memory pointers, and extern "C" functions.

So "analogous to .. the ABI" seems the most helpful description for the glue.

* limitations under the License.
*/

#ifndef OAK_SERVER_RUST_OAK_GLUE_H_
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, I just went for manual generation (I basically resurrected the old oak_tests host functions)

.unwrap_or(OakStatus::ErrInternal as u32)
}

/// # Safety
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines 142 to 159
let size = oak_abi::SPACE_BYTES_PER_HANDLE * count as usize;
let mut handle_data = Vec::<u8>::with_capacity(size);
std::ptr::copy_nonoverlapping(buf, handle_data.as_mut_ptr(), size);
handle_data.set_len(size);
let mut handles = Vec::with_capacity(count as usize);
let mut mem_reader = Cursor::new(handle_data);
for _ in 0..count {
let handle = mem_reader.read_u64::<byteorder::LittleEndian>().unwrap();
let _b = mem_reader.read_u8().unwrap();
debug!("{{{}}}: wait_on_channels handle {:?}", node_id, handle);
handles.push(Some(oak_runtime::Handle(handle)));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow – from_raw_parts isn't relevant here because we're not building a slice from a contiguous sequence of elements in memory (every ninth byte gets skipped). Added a comment.

Comment on lines +55 to +71
impl super::Node for PseudoNode {
fn start(&mut self) -> Result<(), OakStatus> {
// Clone or copy all the captured values and move them into the closure, for simplicity.
let config_name = self.config_name.clone();
let runtime = self.runtime.clone();
let reader = self.reader;
let thread_handle = thread::Builder::new()
.name(format!("external={}", config_name))
.spawn(move || {
let pretty_name = format!("{}-{:?}:", config_name, thread::current());
let factory_fn: NodeFactory = FACTORY
.read()
.expect("unlock failed")
.expect("no registered factory");
info!(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there's a certain amount of path-of-least-resistance:

  • With main in C++, we only want explicit linkage from C++ to Rust, not vice versa (to avoid cycles)
  • Rust needs to up-call to C++ for pseudo-Node creation, which therefore has to happen via a function pointer.
  • Any such function pointer then has to be registered via a call from C++ to Rust.
  • A single such function pointer can currently be used for all pseudo-Node types, because the C++ runtime has a full copy of the configuration and so the config name is all that's needed, regardless of pseudo-Node type (no need to pass pseudo-Node-specific configuration values extracted from the ApplicationConfiguration).

A lot of the above will change once main is in Rust, so I don't think it's worth changing things here – #724 will require a re-work of the C++ pseudo-Node registration stuff anyway (and I've added a reminder TODO).

@daviddrysdale
Copy link
Contributor Author

This is going to be a pain to rebase, so I've pulled the preparatory commits into #836 to try to make things easier.

@daviddrysdale
Copy link
Contributor Author

Merged up to latest master. Things it would be nice still to fix:

  • Get prost-build building under and integrated into Bazel, so generated code files don't need to be checked in.
  • Restore the cross-compile to ARM build.

@daviddrysdale
Copy link
Contributor Author

Notes on prost-build under Bazel:

This is needed as a prerequisite for generating proto code via Bazel rules, which in turn would be needed so that we don't have to check in the auto-generated Rust files, as done in this PR.

In a normal cargo build, the build.rs for prost-build emits

cargo:rustc-env=PROTOC=<path>
cargo:rustc-env=PROTOC_INCLUDE=<path>

values. These are inserted into the environment for the rustc compilation step, and the prost-build code relies on them being set.

Under Bazel there's no immediate mechanism to get these environment variables set automatically. Adding the gen_buildrs = true flag to cargo raze config gives a BUILD stanza that builds and runs the build.rs script, emitting these tags to stdout, but there's no way to capture them.

Trying to set them manually using the --action-env Bazel flag doesn't seem to work, possibly because of bazelbuild/bazel#4008.

@@ -25,5 +25,6 @@ fn main() {
"../../../../third_party/google/rpc/status.proto",
],
&["../../../.."],
"src/proto/",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this re-introduce the issue that everything gets rebuilt every time now, even if nothing actually changed? #510

Either way, since this seems to be against the cargo book guidelines I think we should have a TODO (and issue) to restore it to just use OUT_DIR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still doesn't seem to; maybe we weren't emitting the cargo:rerun-if-change markers before?

Raised #850 to cover fixing this.

Comment on lines +1 to +6
[package]
name = "oak_glue"
version = "0.1.0"
authors = ["David Drysdale <drysdale@google.com>"]
edition = "2018"
license = "Apache-2.0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be possible to just nest this stuff under oak_runtime::glue instead of creating another top-level crate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be possible, but I deliberately made this a separate crate to make sure this would be easy to reverse and/or remove when the C++->Rust linkage flips to a Rust->C++ linkage.

/// Caller must ensure that the memory range [config_buf, config_buf+config_len) is
/// accessible and holds a protobuf-serialized ApplicationConfiguration message.
#[no_mangle]
pub unsafe extern "C" fn glue_start(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(genuine question) By your definition, should any function that accepts a raw pointer and uses it for anything (which it is forced to do in an unsafe block anyways) be marked as unsafe? I think I agree with that view, though I could see arguments for both sides I guess.

module: Arc<wasmi::Module>,
},

External,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Allow override of the out_dir for the code generation.
Make the generated files visible in the source tree to make it easier
to perform Bazel / BUILD file integration.
Followed the instructions at
https://github.com/google/cargo-raze#remote-dependency-mode
for setting up cargo raze in remote dependency mode.

Manual steps:
 - Edit cargo/Cargo.toml to list a set of [dependencies] that match
   the combination of those in oak_abi and oak_runtime crates, plus:
    - the `std` feature for `log` (and force `atomic_cas` to be set
      when building it)
    - the `simple_logger` crate
    - the `lazy_static` crate
 - Run `cd cargo && cargo raze` to generate `cargo/BUILD` and all
   the files in `cargo/remote/`
 - Check the build works with `bazel build //cargo:all`
 - Adjustments to versions and build flags for problematic crates.
Add BUILD files for the oak_abi and oak_runtime crates, mirroring
the dependencies from Cargo.toml into "//cargo:<dep>" equivalents
in the BUILD file.

Check that `bazel build //oak/server/rust/oak_abi` and
`bazel build //oak/server/rust/oak_runtime` work afterwards.
Use a mutable global to hold references to the Rust runtime, and to the
C++ pseudo-Node factory function that's registered.

Check builds with both:
 - cargo build --manifest-path oak/server/rust/oak_glue/Cargo.toml
 - bazel build //oak/server/rust/oak_glue
Convert OakRuntime to be a proxy for the Rust runtime, and convert the
OakNode base class to proxy on to the C++->Rust FFI glue code.
Slim down the C++ runtime now that the Rust runtime handles messaging
and Wasm nodes.
 - Use a Create() factory method.
 - Make methods const, given that data fields don't change after
   construction
 - Don't start the Rust runtime (and its threads) until after
   the OakRuntime object's contents are filled in.
The BUILD files for Rust dependencies that are generated by
`cargo raze` are specific to a particular configured `target`
architecture triple, in our case "x86_64-unknown-linux-gnu".

This means that cross-compiles don't work, in particular prost
and proc-macro fail to build.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
planning
  
Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants