microsoft/openvmm
Publicmirrored fromhttps://github.com/microsoft/openvmmAvailable
flowey/flowey_trampoline/src/main.rs
50lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | //! Crate used to fix up environment variables before running another cargo |
| 5 | //! command, to be used in cargo aliases. |
| 6 | //! |
| 7 | //! This crate is used to work around a bug in the `linkme` crate on macOS, |
| 8 | //! <https://github.com/dtolnay/linkme/issues/61>. If a binary is built without |
| 9 | //! LTO on macOS, sometimes `linkme` will fail to include all the elements of a |
| 10 | //! distributed slice. This causes flowey runs to fail. |
| 11 | //! |
| 12 | //! To work around this, we set the `CARGO_PROFILE_FLOWEY_LTO` environment |
| 13 | //! variable to `thin` before running the `cargo` binary. This will cause the |
| 14 | //! `flowey_hvlite` binary to be built with thin LTO, which will work around the |
| 15 | //! `linkme` bug. |
| 16 | //! |
| 17 | //! We don't want to set this for non-macOS environments because it slows down |
| 18 | //! builds. |
| 19 | //! |
| 20 | //! This crate can be removed when the `linkme` bug is fixed or when cargo gains |
| 21 | //! enough support to do this kind of thing natively. |
| 22 | |
| 23 | use std::process::Command; |
| 24 | |
| 25 | fn main() { |
| 26 | let args = std::env::args_os().collect::<Vec<_>>(); |
| 27 | let cargo = std::env::var_os("CARGO").unwrap_or_else(|| "cargo".into()); |
| 28 | let mut cmd = Command::new(cargo); |
| 29 | cmd.args(&args[1..]); |
| 30 | |
| 31 | // Conditionally set LTO via environment variable. Note that this inherits |
| 32 | // to any child invocations of cargo, which is what we want. |
| 33 | // |
| 34 | // This check isn't completely accurate, since we might be cross compiling |
| 35 | // flowey from or to a different OS. But it's good enough for now. |
| 36 | if cfg!(target_os = "macos") { |
| 37 | cmd.env("CARGO_PROFILE_FLOWEY_LTO", "thin"); |
| 38 | } |
| 39 | |
| 40 | #[cfg(unix)] |
| 41 | { |
| 42 | let err = std::os::unix::process::CommandExt::exec(&mut cmd); |
| 43 | panic!("failed to exec: {:?}", err); |
| 44 | } |
| 45 | #[cfg(not(unix))] |
| 46 | { |
| 47 | let status = cmd.status().expect("failed to run command"); |
| 48 | std::process::exit(status.code().unwrap_or(1)); |
| 49 | } |
| 50 | } |
| 51 | |