Repository: pkolaczk/fclones (language: rust)

Issue:
unable to compile on aarch64 musl
hello,
I'm unable to (cross)compile a musl binary on aarch64 ("cross" as in from ubuntu, still aarch64)
[also tried compiling native on alpine aarch64, same result]
```
$ cargo install --target aarch64-unknown-linux-musl fclones
[cut]
   Compiling reflink v0.1.3
error[E0308]: mismatched types
  --> .cargo/registry/src/github.com-1ecc6299db9ec823/reflink-0.1.3/src/sys/unix.rs:21:39
   |
21 |         libc::ioctl(dest.as_raw_fd(), IOCTL_FICLONE, src.as_raw_fd())
   |                                       ^^^^^^^^^^^^^ expected `i32`, found `u64`
   |
help: you can convert a `u64` to an `i32` and panic if the converted value doesn't fit
   |
21 |         libc::ioctl(dest.as_raw_fd(), IOCTL_FICLONE.try_into().unwrap(), src.as_raw_fd())
   |                                                    ++++++++++++++++++++

For more information about this error, try `rustc --explain E0308`.
error: could not compile `reflink` due to previous error
warning: build failed, waiting for other jobs to finish...
error: failed to compile `fclones v0.17.1`
```
compiling with glibc works correctly

(rust 1.57.0)

regards,
m


Discussion / hints:
The reflink master (already 2 years old) has a fix for that, try using that one instead of the one from crates.io by changing the `reflink = "0.1.3"` line in `Cargo.toml` to
`reflink = { git = "https://github.com/nicokoch/reflink.git", rev = "e8d93b465f5d9ad340cd052b64bbc77b8ee107e2" }`

Also happens with cargo build in Debian armhf/arm7vl (Raspberry Pi).  Dunno if this is relevant but just putting it here for search engines.

Using the reflink (check out the repo, change `Cargo.toml` as above, do a `cargo build --release` ) works.
> The reflink master (already 2 years old) has a fix for that, try using that one instead of the one from crates.io by changing the `reflink = "0.1.3"` line in `Cargo.toml` to

Is there any reason fclones isn't using that version?
It is not possible to publish a crate that relies on an unpublished crate. All dependencies must be in crates.io.
RE: Piotr

Oh I see, that's just perfect 😆


Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 10160fb..b3b7ac7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,7 +42,6 @@ nom = { version = "5.1", features = ["regexp"] }
 num_cpus = "1.13"
 rand = "0.8"
 rayon = "1.5"
-reflink = "0.1"
 regex = "1.5"
 serde_json = "1.0"
 serde = { version = "1.0", features = ["derive"] }
@@ -64,7 +63,11 @@ libc = "0.2"
 winapi = "0.3"
 winapi-util = "0.1"
 
+[target.'cfg(not(any(target_os = "linux", target_os = "android")))'.dependencies]
+reflink = "0.1"
+
 [dev-dependencies]
+reflink = "0.1"
 serde_test = "1.0"
 tempfile = "3.3"
 
diff --git a/src/reflink.rs b/src/reflink.rs
index adee152..4fdc940 100644
--- a/src/reflink.rs
+++ b/src/reflink.rs
@@ -7,7 +7,6 @@ use filetime::FileTime;
 use crate::dedupe::{FileMetadata, FsCommand};
 use crate::lock::FileLock;
 use crate::log::Log;
-use crate::Path as FcPath;
 
 /// Calls OS-specific reflink implementations with an option to call the more generic
 /// one during testing one on Linux ("crosstesting").
@@ -165,7 +164,8 @@ fn restore_some_metadata(path: &std::path::Path, metadata: &Metadata) -> io::Res
 }
 
 // Reflink which expects the destination to not exist.
-fn copy_by_reflink(src: &FcPath, dest: &FcPath) -> io::Result<()> {
+#[cfg(any(not(any(target_os = "linux", target_os = "android")), test))]
+fn copy_by_reflink(src: &crate::Path, dest: &crate::Path) -> io::Result<()> {
     reflink::reflink(&src.to_path_buf(), &dest.to_path_buf()).map_err(|e| {
         io::Error::new(
             e.kind(),
@@ -180,11 +180,18 @@ fn copy_by_reflink(src: &FcPath, dest: &FcPath) -> io::Result<()> {
 }
 
 // Create a reflink by removing the file and making a reflink copy of the original.
+#[cfg(any(not(any(target_os = "linux", target_os = "android")), test))]
 fn safe_reflink(src: &FileMetadata, dest: &FileMetadata, log: &Log) -> io::Result<()> {
     FsCommand::safe_remove(&dest.path, |link| copy_by_reflink(&src.path, link), log)?;
     Ok(())
 }
 
+// Dummy function so non-test cfg compiles
+#[cfg(not(any(not(any(target_os = "linux", target_os = "android")), test)))]
+fn safe_reflink(_src: &FileMetadata, _dest: &FileMetadata, _log: &Log) -> io::Result<()> {
+    unreachable!()
+}
+
 #[cfg(not(test))]
 pub mod test {
     pub mod cfg {
@@ -235,6 +242,7 @@ pub mod test {
     use crate::util::test::{cached_reflink_supported, read_file, with_dir, write_file};
 
     use super::*;
+    use crate::Path as FcPath;
 
     // Usually /dev/shm only exists on Linux.
     #[cfg(any(target_os = "linux"))]


Test patch: