diff --git a/src/uu/stdbuf/build.rs b/src/uu/stdbuf/build.rs index 7483aeacf..b31a32235 100644 --- a/src/uu/stdbuf/build.rs +++ b/src/uu/stdbuf/build.rs @@ -5,6 +5,7 @@ // spell-checker:ignore (ToDO) dylib libstdbuf deps liblibstdbuf use std::env; +use std::env::current_exe; use std::fs; use std::path::Path; @@ -24,53 +25,25 @@ mod platform { } fn main() { - let out_dir = env::var("OUT_DIR").unwrap(); - let mut target_dir = Path::new(&out_dir); + let current_exe = current_exe().unwrap(); - // Depending on how this is util is built, the directory structure changes. - // This seems to work for now. Here are three cases to test when changing - // this: - // - // - cargo run - // - cross run - // - cargo install --git - // - cargo publish --dry-run - // - // The goal is to find the directory in which we are installing, but that - // depends on the build method, which is annoying. Additionally the env - // var for the profile can only be "debug" or "release", not a custom - // profile name, so we have to use the name of the directory within target - // as the profile name. - // - // Adapted from https://stackoverflow.com/questions/73595435/how-to-get-profile-from-cargo-toml-in-build-rs-or-at-runtime - let profile_name = out_dir - .split(std::path::MAIN_SEPARATOR) - .nth_back(3) - .unwrap(); + let out_dir_string = env::var("OUT_DIR").unwrap(); + let out_dir = Path::new(&out_dir_string); - let mut name = target_dir.file_name().unwrap().to_string_lossy(); - while name != "target" && !name.starts_with("cargo-install") { - target_dir = target_dir.parent().unwrap(); - name = target_dir.file_name().unwrap().to_string_lossy(); - } - let mut dir = target_dir.to_path_buf(); - dir.push(profile_name); - dir.push("deps"); - let mut path = None; + let deps_dir = current_exe.ancestors().nth(3).unwrap().join("deps"); + dbg!(&deps_dir); - // When running cargo publish, cargo appends hashes to the filenames of the compiled artifacts. - // Therefore, it won't work to just get liblibstdbuf.so. Instead, we look for files with the - // glob pattern "liblibstdbuf*.so" (i.e. starts with liblibstdbuf and ends with the extension). - for entry in fs::read_dir(dir).unwrap().flatten() { - let name = entry.file_name(); - let name = name.to_string_lossy(); - if name.starts_with("liblibstdbuf") && name.ends_with(platform::DYLIB_EXT) { - path = Some(entry.path()); - } - } - fs::copy( - path.expect("liblibstdbuf was not found"), - Path::new(&out_dir).join("libstdbuf.so"), - ) - .unwrap(); + let libstdbuf = deps_dir + .read_dir() + .unwrap() + .flatten() + .find(|entry| { + let n = entry.file_name(); + let name = n.to_string_lossy(); + + name.starts_with("liblibstdbuf") && name.ends_with(platform::DYLIB_EXT) + }) + .expect("unable to find libstdbuf"); + + fs::copy(libstdbuf.path(), out_dir.join("libstdbuf.so")).unwrap(); }