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

Rust build cache invalidated by build.rs execution #510

Closed
tiziano88 opened this issue Jan 21, 2020 · 14 comments · Fixed by #533
Closed

Rust build cache invalidated by build.rs execution #510

tiziano88 opened this issue Jan 21, 2020 · 14 comments · Fixed by #533
Assignees

Comments

@tiziano88
Copy link
Collaborator

I noticed that, even without changing any Rust code, if I re-run a build or tests, it always takes a long time for the command to finish, while I would normally expect most artifacts and test results to be cached.

I suspect the issue is that we use build.rs scripts in a number of places in our repository, mostly to generate protobuf objects, and somehow that invalidates the build cache. I am not sure it is an issue with build scripts in general, or the particular steps that our build scripts execute.

I note that, by removing (or renaming) all the build scripts from our repository, the build and test results seem indeed to be cached, and these commands run very quickly.

@tiziano88
Copy link
Collaborator Author

I have not tried leaving around the build.rs file, but with an empty main, I guess that could be a useful test to figure out if the issue is due to the presence of these files, or their contents. If it turns out to be caused by protoc_rust_grpc, we should then investigate how to mitigate it.

@daviddrysdale
Copy link
Contributor

#514 possibly related?

@tiziano88
Copy link
Collaborator Author

To reproduce, run the following command twice, notice the second time it rebuilds all the crates that include a build.rs file, if present. Other crates are cached instead.

cargo build --release --target=wasm32-unknown-unknown --manifest-path=examples/hello_world/module/rust/Cargo.toml

@ipetr0v
Copy link
Contributor

ipetr0v commented Jan 23, 2020

Why do we need grpc-compiler hardcoded into third_party ?
https://github.com/project-oak/oak/tree/2a2a3e4d491b1847b0e10390166252d62ce16424/third_party/grpc-rust/grpc-compiler

[build-dependencies]
protoc-rust-grpc = { path = "../../../../third_party/grpc-rust/protoc-rust-grpc" }

Can we download it from crates.io instead?

@tiziano88
Copy link
Collaborator Author

We maintain a forked version, the code generation is different.

@ipetr0v
Copy link
Contributor

ipetr0v commented Jan 23, 2020

Could it be that grpc-compiler (and protoc-rust-grpc) doesn't use Cargo's cache?

@ipetr0v
Copy link
Contributor

ipetr0v commented Jan 23, 2020

@ipetr0v
Copy link
Contributor

ipetr0v commented Jan 28, 2020

I'm running Rust tests and receive this error in random places:

error[E0425]: cannot find function `type_name` in module `any`
   --> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/rustc-ap-serialize-610.0.0/serialize.rs:852:21
    |
852 |                any::type_name::<S>(),
    |                     ^^^^^^^^^ not found in `any`
help: possible candidates are found in other modules, you can import them into scope
    |
7   | use core::intrinsics::type_name;
    |
7   | use std::intrinsics::type_name;
    |

error[E0425]: cannot find function `type_name` in module `any`
   --> /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/rustc-ap-serialize-610.0.0/serialize.rs:854:21
    |
854 |                any::type_name::<T>(),
    |                     ^^^^^^^^^ not found in `any`
help: possible candidates are found in other modules, you can import them into scope
    |
7   | use core::intrinsics::type_name;
    |
7   | use std::intrinsics::type_name;
    |

@ipetr0v
Copy link
Contributor

ipetr0v commented Jan 29, 2020

Since I have added protoc-rust-grpc to dependencies in oak_utils, I started to receive the following errors:

error: struct update has no effect, all the fields in the struct have already been specified
  --> /opt/my-project/third_party/grpc-rust/protoc-rust-grpc/src/lib.rs:44:15
   |
44 |             ..Default::default()
   |               ^^^^^^^^^^^^^^^^^^
   |
   = note: `-D clippy::needless-update` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_update
error: Statics have by default a `'static` lifetime
  --> /opt/my-project/third_party/grpc-rust/protoc-rust-grpc/src/lib.rs:71:28
   |
71 |         static DOT_SLICE: &'static [&'static str] = &["."];
   |                           -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
   |
   = note: `-D clippy::redundant-static-lifetimes` implied by `-D warnings`
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes

error: Statics have by default a `'static` lifetime
  --> /opt/my-project/third_party/grpc-rust/protoc-rust-grpc/src/lib.rs:71:38
   |
71 |         static DOT_SLICE: &'static [&'static str] = &["."];
   |                                     -^^^^^^^---- help: consider removing `'static`: `&str`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes

error: unneeded return statement
   --> /opt/my-project/third_party/grpc-rust/protoc-rust-grpc/src/lib.rs:137:9
    |
137 |         return Some(&path[prefix.len() + 1..]);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `Some(&path[prefix.len() + 1..])`
    |
    = note: `-D clippy::needless-return` implied by `-D warnings`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return

error: unneeded return statement
   --> /opt/my-project/third_party/grpc-rust/protoc-rust-grpc/src/lib.rs:139:9
    |
139 |         return None;
    |         ^^^^^^^^^^^^ help: remove `return`: `None`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return

Is it ok to change protoc-rust-grpc in the third_party, or it supposed to be an unchanged fork?

ipetr0v added a commit that referenced this issue Feb 4, 2020
This change:
- Adds `oak_utils` crate, that runs `protoc`/`protoc_grpc` and checks updated files
- Updates `build.rs` files to use `oak_utils`

Fixes #510
tiziano88 added a commit to tiziano88/oak that referenced this issue Feb 5, 2020
We should find a way of enforcing that we always use `oak_utils`
wrappers instead of the underlying `grpc` functions.

See project-oak#510
tiziano88 added a commit that referenced this issue Feb 6, 2020
We should find a way of enforcing that we always use `oak_utils`
wrappers instead of the underlying `grpc` functions.

See #510
@tiziano88
Copy link
Collaborator Author

I realised that perhaps the root cause is that the build script emits files outside of OUT_DIR, against guidelines.

The build script is re-run when any change in the source files within the package is detected, based on timestamps, but generating proto files under src means that the compiler thinks the package is always modified.

@ipetr0v could you try using OUT_DIR and see if that works for us? I think that would mean that we would not be checking in the generated files, but perhaps that's what we should be doing anyways.

@tiziano88 tiziano88 reopened this Feb 6, 2020
@ipetr0v
Copy link
Contributor

ipetr0v commented Feb 18, 2020

Tried to use an example from rust-bindgen

pub mod oak_api {
    include!(concat!(env!("OUT_DIR"), "/oak_api.rs"));
}

It leads to the following errors:

error: an inner attribute is not permitted following an outer attribute
  --> /usr/local/google/home/ivanpetrov/src/oak/target/debug/build/oak_abi-70604563f2c30de3/out/oak_api.rs:18:3
   |
18 | #![allow(unused_imports)]
   |   ^
   |
   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item follo
wing them.

error: an inner attribute is not permitted following an outer attribute
  --> /usr/local/google/home/ivanpetrov/src/oak/target/debug/build/oak_abi-70604563f2c30de3/out/oak_api.rs:19:3
   |
19 | #![allow(unused_results)]
   |   ^
   |
   = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files. Outer attributes, like `#[test]`, annotate the item follo
wing them.

error: expected outer doc comment
  --> /usr/local/google/home/ivanpetrov/src/oak/target/debug/build/oak_abi-70604563f2c30de3/out/oak_api.rs:20:1
   |
20 | //! Generated file from `oak_api.proto`
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items

So it's not possible to have inner attributes in the included files.

The workaround that I have found is to open the generated file, add 'mod proto { }' around the contents and write it back:
https://github.com/googlecartographer/point_cloud_viewer/blob/bb73289523a3cee8091e9b6547b7b989d0fc61c7/build.rs#L16-L33

@tiziano88
Copy link
Collaborator Author

@ipetr0v thanks for looking into it, I don't think it's worth exploring this more, let's stick to the current version, unless you think otherwise?

@tiziano88
Copy link
Collaborator Author

I think could be closed now @ipetr0v ?

@ipetr0v
Copy link
Contributor

ipetr0v commented Mar 15, 2020

Yes, I agree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants