Johnathan Van Why | 9765062 | 2021-01-11 16:18:30 -0800 | [diff] [blame] | 1 | use std::fs::copy; |
| 2 | use std::path::PathBuf; |
| 3 | |
| 4 | // auto_layout() identifies the correct linker scripts to use based on the |
| 5 | // LIBTOCK_PLATFORM environment variable, and copies the linker scripts into |
| 6 | // OUT_DIR. The cargo invocation must pass -C link-arg=-Tlayout.ld to rustc |
| 7 | // (using the rustflags cargo config). |
| 8 | #[cfg(not(feature = "no_auto_layout"))] |
| 9 | fn auto_layout(out_dir: &str) { |
| 10 | const PLATFORM_CFG_VAR: &str = "LIBTOCK_PLATFORM"; |
| 11 | const LAYOUT_GENERIC_FILENAME: &str = "layout_generic.ld"; |
| 12 | |
| 13 | // Note: we need to print these rerun-if commands before using the variable |
| 14 | // or file, so that if the build script fails cargo knows when to re-run it. |
| 15 | println!("cargo:rerun-if-env-changed={}", PLATFORM_CFG_VAR); |
| 16 | |
| 17 | // Read configuration from environment variables. |
| 18 | |
| 19 | // Read the platform environment variable as a String (our platform names |
| 20 | // should all be valid UTF-8). |
Johnathan Van Why | 6c8be57 | 2021-01-11 16:39:13 -0800 | [diff] [blame] | 21 | let platform = std::env::var(PLATFORM_CFG_VAR).expect("Please specify LIBTOCK_PLATFORM"); |
Johnathan Van Why | 9765062 | 2021-01-11 16:18:30 -0800 | [diff] [blame] | 22 | |
| 23 | // Copy the platform-specific layout file into OUT_DIR. |
| 24 | let platform_filename = format!("{}.ld", platform); |
| 25 | let platform_path: PathBuf = ["layouts", &platform_filename].iter().collect(); |
| 26 | println!("cargo:rerun-if-changed={}", platform_path.display()); |
Johnathan Van Why | fdd0c36 | 2021-01-19 14:32:06 -0800 | [diff] [blame] | 27 | assert!(platform_path.exists(), "Unknown platform {}", platform); |
Johnathan Van Why | 9765062 | 2021-01-11 16:18:30 -0800 | [diff] [blame] | 28 | let out_platform_path: PathBuf = [out_dir, "layout.ld"].iter().collect(); |
| 29 | copy(&platform_path, out_platform_path).expect("Unable to copy platform layout into OUT_DIR"); |
| 30 | |
| 31 | // Copy the generic layout file into OUT_DIR. |
| 32 | let out_layout_generic: PathBuf = [out_dir, LAYOUT_GENERIC_FILENAME].iter().collect(); |
| 33 | println!("cargo:rerun-if-changed={}", LAYOUT_GENERIC_FILENAME); |
| 34 | copy(LAYOUT_GENERIC_FILENAME, out_layout_generic) |
| 35 | .expect("Unable to copy layout_generic.ld into OUT_DIR"); |
| 36 | } |
| 37 | |
| 38 | fn main() { |
| 39 | // Note: cargo fails if run in a path that is not valid Unicode, so this |
| 40 | // script doesn't need to handle non-Unicode paths. Also, OUT_DIR cannot be |
| 41 | // in a location with a newline in it, or we have no way to pass |
| 42 | // rustc-link-search to cargo. |
| 43 | let out_dir = &std::env::var("OUT_DIR").expect("Unable to read OUT_DIR"); |
Johnathan Van Why | fdd0c36 | 2021-01-19 14:32:06 -0800 | [diff] [blame] | 44 | assert!( |
| 45 | !out_dir.contains('\n'), |
| 46 | "Build path contains a newline, which is unsupported" |
| 47 | ); |
Johnathan Van Why | 9765062 | 2021-01-11 16:18:30 -0800 | [diff] [blame] | 48 | |
| 49 | #[cfg(not(feature = "no_auto_layout"))] |
| 50 | auto_layout(out_dir); |
| 51 | |
| 52 | // This link search path is used by both auto_layout() and extern_asm(). |
| 53 | // TODO: Add external assembly and extern_asm(). |
| 54 | println!("cargo:rustc-link-search={}", out_dir); |
| 55 | } |