From 322d99e4ae3afda270a195d961bc87d75836ea9b Mon Sep 17 00:00:00 2001 From: Ian Chamberlain Date: Mon, 20 Mar 2023 14:04:38 -0400 Subject: [PATCH] Add all `libctru` files to rerun-if-changed Also simplify version checking logic a bit. It's just a warning, so we can check for exact version just to be safe and skip the major/minor comparisons for semver. Also update the README a bit to explain the versioning scheme. --- README.md | 21 +++++++++++++++++++-- ctru-sys/build.rs | 34 +++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9722c7c..f719b4b 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,24 @@ A Rust wrapper library for smealum's [ctrulib](https://github.com/smealum/ctruli ## Structure This repository is organized as follows: -* `ctru-rs`: Safe, idiomatic wrapper around `ctru-sys`. -* `ctru-sys`: Low-level, unsafe bindings to ctrulib + +* `ctru-rs`: Safe, idiomatic wrapper around `ctru-sys` + +* `ctru-sys`: Low-level, unsafe bindings to ctrulib. + + This crate's version changes according to the version of `libctru` + used to generate the bindings, with the following convention: + + * `libctru` version `X.Y.Z-W` + * `ctru-sys` version `XY.Z.P+X.Y.Z-W` + + where `P` is usually 0 but may be incremented for fixes in e.g. + binding generation, `libc` dependency bump, etc. + + It may be possible to build this crate against a different version of `libctru`, + but you may encounter linker errors or ABI issues. A build-time Cargo warning + (displayed when built with `-vv`) will be issued if the build script detects + a mismatch or is unable to check the installed `libctru` version. ## License @@ -37,3 +53,4 @@ applies to every file in the tree, unless otherwise noted. Rust is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0), with portions covered by various BSD-like licenses. See [LICENSE-APACHE](https://github.com/rust-lang/rust/blob/master/LICENSE-APACHE), [LICENSE-MIT](https://github.com/rust-lang/rust/blob/master/LICENSE-MIT), and [COPYRIGHT](https://github.com/rust-lang/rust/blob/master/COPYRIGHT) for details. + diff --git a/ctru-sys/build.rs b/ctru-sys/build.rs index e6c17f2..a695d47 100644 --- a/ctru-sys/build.rs +++ b/ctru-sys/build.rs @@ -27,9 +27,6 @@ fn main() { println!("cargo:rustc-env=LIBCTRU_MAJOR={maj}"); println!("cargo:rustc-env=LIBCTRU_MINOR={min}"); println!("cargo:rustc-env=LIBCTRU_PATCH={patch}"); - - // It would be nice if we could rerun-if-changed on libctru itself, - // maybe we can write a file to OUT_DIR and check that file? } Err(err) => println!("cargo:warning=failed to check libctru version: {err}"), } @@ -50,7 +47,7 @@ fn parse_version(version: &str) -> Result<(String, String, String), &str> { fn check_libctru_version() -> Result<(String, String, String), Box> { let pacman = which::which("dkp-pacman").or_else(|_| which::which("pacman"))?; - let Output { stdout, .. } = Command::new(pacman) + let Output { stdout, .. } = Command::new(&pacman) .args(["--query", "libctru"]) .stderr(Stdio::inherit()) .output()?; @@ -59,26 +56,33 @@ fn check_libctru_version() -> Result<(String, String, String), Box> { let (_pkg, lib_version) = output_str .split_once(char::is_whitespace) - .ok_or("unexpected output format")?; + .ok_or("unexpected pacman output format")?; + + let lib_version = lib_version.trim(); let cargo_pkg_version = env::var("CARGO_PKG_VERSION").unwrap(); let (_, crate_built_version) = cargo_pkg_version .split_once('+') .expect("crate version should have '+' delimeter"); - let (lib_major, lib_minor, lib_patch) = parse_version(lib_version)?; - let (crate_supported_major, crate_supported_minor, _crate_supported_patch) = - parse_version(crate_built_version)?; - - // TODO: does == comparison make sense, or should we use >= or something? - if crate_supported_major != lib_major || crate_supported_minor != lib_minor { - // TODO: should this be a panic (i.e. induce build failure)? Maybe only for major version? - + if lib_version != crate_built_version { return Err(format!( - "libctru version is {lib_major}.{lib_minor}.{lib_patch}, \ - but this crate only supports {crate_supported_major}.{crate_supported_minor}.x" + "libctru version is {lib_version} but this crate was built for {crate_built_version}" ))?; } + let Output { stdout, .. } = Command::new(pacman) + .args(["--query", "--list", "libctru"]) + .stderr(Stdio::inherit()) + .output()?; + + for line in String::from_utf8_lossy(&stdout).split('\n') { + let Some((_pkg, file)) = line.split_once(char::is_whitespace) + else { continue }; + + println!("cargo:rerun-if-changed={file}"); + } + + let (lib_major, lib_minor, lib_patch) = parse_version(lib_version)?; Ok((lib_major, lib_minor, lib_patch)) }