metalbear-co / mirrord

Connect your local process and your cloud environment, and run local code in cloud conditions.
https://mirrord.dev
MIT License
3.74k stars 101 forks source link

Reduce the overhead of running the frida-gum-sys build script on our build times #223

Open abhirag opened 2 years ago

abhirag commented 2 years ago

frida-gum-sys Running the frida-gum-sys build script is the third biggest overhead for us during building. This overhead is primarily because we use the the auto-download feature. The time is basically spent downloading the complete compressed frida devkit, extracting everything and then statically linking against frida-gum, details can be found here. My initial thoughts are that we really don't need to download the whole devkit, keeping frida-gum static library in our source tree and statically linking against it depending on the platform in our own cargo build script can save us a lot of time. Interestingly build scripts are always run even if we are using something like sccache so this overhead is also present in CI builds.

Note: The idea is to modify the build script of frida-gum-sys to our use-case so refer to that build script for reference

abhirag commented 2 years ago

Alright, so I have made some progress on this. We basically need to do three things --

  1. Defer as much of the work as possible to the existing frida-gum-sys build script
  2. Keep frida-gum libs in the source tree and use cargo:rustc-link-search to add the appropriate directory for the platform to the linker path
  3. frida-gum-sys build script generates appropriate bindings using the platform specific frida-gum.h and bindgen so make sure that bindgen can find frida-gum.h
abhirag commented 2 years ago

The first issue we face is that the lifecycle of a cargo build script is such that it is executed just before compiling the binary, which means that the build scripts of all the dependent crates are executed before the build script of mirrord-layer (and we can't have build script on the workspace level).

This basically implies that we need a mechanism to make bindgen aware of the include path for frida-gum.h and we need to it before executing our build script. Adding the appropriate path to the linker path can still be done in our build script without any problem.

abhirag commented 2 years ago

So I have two approaches I need to discuss:

  1. As of now frida-gum has no support for configuring the include directory, this approach tweaks the frida-gum-sys build script to support configuring the include directory using an environment variable and then uses the cargo feature to set this environment variable before building mirrord. In my limited testing I have found this approach to work well, just that we would have to get the required changes included in frida-rust. Also we would need to keep a single header file for frida-gum with appropriate pre-processor flags for conditional compilation. Prototype for this approach can be found here.
  2. The second approach doesn't quite work yet, laying it down here in the hope that someone else can provide a better insight. This approach uses the fact that bindgen allows arguments to be passed to clang through environment variables. So we can pass the appropriate include directory by setting this environment variable in cargo configuration. The only problem being that I have not been able to figure out how to make this work with relative paths and this approach is useless without that. If we can make this work with relative paths we can probably set TARGET env var and then use BINDGEN_EXTRA_CLANG_ARGS_<TARGET> to set include paths based on target. The working code for this approach can be found here, although you would have to tweak the absolute path to make it work for you.
aviramha commented 2 years ago

What about forking the auto download crate then using replace to use the fork?