aboutsummaryrefslogtreecommitdiff
path: root/build.rs
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2022-05-01 17:50:00 +0200
committerJohannes Stoelp <johannes.stoelp@gmail.com>2022-05-01 17:50:00 +0200
commit4754b66f72a8fbfd48e30ae0bd12a44d13a4ce10 (patch)
tree16551dd04684ff6e7bdc1107927faaafb6ff9bd9 /build.rs
downloadrv64i-linux-user-no-std-4754b66f72a8fbfd48e30ae0bd12a44d13a4ce10.tar.gz
rv64i-linux-user-no-std-4754b66f72a8fbfd48e30ae0bd12a44d13a4ce10.zip
initial commit
Build small no_std example for rv64i target. This code executes some linux syscalls as demo and therefore expects to be executed in rv64 linux.
Diffstat (limited to 'build.rs')
-rw-r--r--build.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..827c302
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,61 @@
+/// Generate rust constants for linux riscv syscall numbers.
+///
+/// Syscall numbers are parsed from the `linux/unistd.h` header.
+/// This script uses the `riscv64-linux-gnu-*` tools to find to header, make sure those tools are
+/// in the PATH.
+///
+/// For simplicity, this script unwraps any Option/Result because we want to fail in case of any
+/// error.
+
+fn main() {
+ // Get sysroot to find header location.
+ let out = std::process::Command::new("riscv64-linux-gnu-gcc")
+ .arg("-print-sysroot")
+ .output()
+ .unwrap();
+ let sysroot = std::str::from_utf8(&out.stdout).unwrap();
+ let header = format!("{}/include/linux/unistd.h", sysroot.trim_end());
+
+ // The header should "basically" never change.
+ println!("cargo:rerun-if-changed={}", header);
+
+ // Run header through preprocessor and dump macro definitions.
+ let out = std::process::Command::new("riscv64-linux-gnu-cpp")
+ .arg("-dM")
+ .arg(header)
+ .output()
+ .unwrap();
+ let defines = std::str::from_utf8(&out.stdout).unwrap();
+
+ let mut output = String::with_capacity(256);
+
+ // Parse out lines of the format
+ // #define __NR_<syscall> <nr>
+ // and generate output strings.
+ for line in defines.lines() {
+ let line = match line.strip_prefix("#define __NR_") {
+ Some(line) => line,
+ None => continue,
+ };
+
+ let (sys, nr) = match line.split_once(' ') {
+ Some(split) => split,
+ None => continue,
+ };
+
+ let nr = match nr.parse::<usize>() {
+ Ok(nr) => nr,
+ Err(_) => continue,
+ };
+
+ output.push_str(&format!(
+ "#[allow(unused)] const SYS_{}: usize = {};\n",
+ sys.to_uppercase(),
+ nr
+ ));
+ }
+
+ // Write out rust file with syscall numbers.
+ let outfile = format!("{}/syscalls.rs", std::env::var("OUT_DIR").unwrap());
+ std::fs::write(&outfile, output).unwrap();
+}