Repository: eza-community/eza (language: rust)

Issue:
Build v0.18.4 on NetBSD10RC4
Hello,

I tried to install eza on NetBSD10 RC4 outside from the version in pkgsrc through `cargo install eza` and with libgit and libcurl and else linked with; in .cargo/config :
```
[target.x86_64-unknown-netbsd]
rustflags = ["-C", "link-args=-Wl,-R/usr/pkg/lib"]
```
(no libtool by default on NetBSD but pkgsrc version might install and use it)

- It is eza version v0.18.4 
- Rust netbsd version:  rustc 1.73.0 (cc66ad468 2023-10-03)

- and config:
```
$ rustc --print cfg
debug_assertions
panic="unwind"
target_arch="x86_64"
target_endian="little"
target_env=""
target_family="unix"
target_feature="fxsr"
target_feature="sse"
target_feature="sse2"
target_has_atomic="16"
target_has_atomic="32"
target_has_atomic="64"
target_has_atomic="8"
target_has_atomic="ptr"
target_os="netbsd"
target_pointer_width="64"
target_vendor="unknown"
unix
```

Here is the error:
```
error: linking with `cc` failed: exit status: 1                                                                       
  |                                                                                                                   
  = note: LC_ALL="C" PATH="/usr/pkg/lib/rustlib/x86_64-unknown-netbsd/bin:/home/naguam/.cargo/bin:/usr/pkg/java/openjd
k17/bin:/usr/pkg/sbin:/usr/pkg/bin:/home/naguam/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R7/bin:/usr/pkg/bin:/usr/pkg
/sbin:/usr/games:/usr/local/bin:/usr/local/sbin" VSLANG="1033" "cc" "-Wl,-L/usr/pkg/lib/libatomic" "-m64" "/tmp/rustc3
VUv44/symbols.o" "/tmp/cargo-installQfP0Zm/release/deps/eza-36627e75085c137a.eza.3d1ab9f77878754a-cgu.0.rcgu.o" "-Wl,-
-as-needed" "-L" "/tmp/cargo-installQfP0Zm/release/deps" "-L" "/tmp/cargo-installQfP0Zm/release/build/libgit2-sys-a091
6002135398e2/out/build" "-L" "/usr/pkg/lib/rustlib/x86_64-unknown-netbsd/lib" "-Wl,-Bstatic" "/tmp/rustc3VUv44/liblibg
it2_sys-38d9318d26a2d2e7.rlib" "/usr/pkg/lib/rustlib/x86_64-unknown-netbsd/lib/libcompiler_builtins-dcf87f8b2c75a1a2.r
lib" "-Wl,-Bdynamic" "-lz" "-lutil" "-lrt" "-lutil" "-lexecinfo" "-lexecinfo" "-lpthread" "-lrt" "-lgcc_s" "-lc" "-lm"
 "-lrt" "-lpthread" "-lutil" "-lrt" "-lutil" "-lexecinfo" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/usr/pkg/lib
/rustlib/x86_64-unknown-netbsd/lib" "-o" "/tmp/cargo-installQfP0Zm/release/deps/eza-36627e75085c137a" "-Wl,--gc-sectio
ns" "-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-Wl,--strip-all" "-Wl,-R/usr/pkg/lib"                                     
  = note: ld: /tmp/cargo-installQfP0Zm/release/deps/eza-36627e75085c137a.eza.3d1ab9f77878754a-cgu.0.rcgu.o: in functio
n `eza::output::table::Table::display':
          eza.3d1ab9f77878754a-cgu.0:(.text._ZN3eza6output5table5Table7display17h23df455df1d82620E+0x4b7): undefined r
eference to `fflagstostr'
                                                           
  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path
 specified                                                 
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc
.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
                             
error: could not compile `eza` (bin "eza") due to previous error
error: failed to compile `eza v0.18.4`, intermediate artifacts can be found at `/tmp/cargo-installQfP0Zm`.
To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path.
```

At first I though I just made a mistake in my linking configurtion to access pkgsrc installed libraries, but with other programs such as bat, this is my linking configuration that actually fixed the missing linking and made my binaries work (proper linking rpath)

Furthermore, `fflagstostr` seems to be a FreeBSD specific library function despite being mentioned in NetBSD man pages for other functions (maybe from code imports, or comparison, as `fflagstostr` has no dedicated manual pages in NetBSD contrary to FreeBSD.

Now somebody seems to have managed having it right in pkgsrc.
Maybe I made a mistake. In any case, I'm happy if this could help bringing a fix.

It seems they added a fix on pkgsrc https://pkgsrc.se/files.php?messageId=20231230030848.AE0E8FA42@cvs.NetBSD.org but it could be nice for it to build natively from upstream.

Cheers,


---



Discussion / hints:
Hi @naguam, I don't think any of the developers use NetBSD but if you can get it to build and submit a patch we'd be happy to review and include it. Do the changes in http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/eza/patches/patch-src_output_render_mod.rs?rev=1.1&content-type=text/x-cvsweb-markup allow it to build if you apply them manually along with the MAKE_ENV and RUSTFLAGS from http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/sysutils/eza/Makefile?rev=1.20&content-type=text/x-cvsweb-markup?

Fix patch:
diff --git a/src/output/render/flags_bsd.rs b/src/output/render/flags_bsd.rs
index 48e5e0ea9..952d9ce5a 100644
--- a/src/output/render/flags_bsd.rs
+++ b/src/output/render/flags_bsd.rs
@@ -1,20 +1,37 @@
 use ansiterm::Style;
 use std::ffi::CStr;
 
+#[cfg(target_os = "netbsd")]
+use std::ffi::CString;
+
 use crate::fs::fields as f;
 use crate::output::cell::TextCell;
 use crate::output::table::FlagsFormat;
 
+#[cfg(not(target_os = "netbsd"))]
 extern "C" {
     fn fflagstostr(flags: libc::c_ulong) -> *const libc::c_char;
 }
 
-/// Wrapper around the C library call fflagstostr.  If returned string is NULL
-/// or empty a "-" is returned
-fn flags_to_string(flags: f::flag_t) -> String {
+#[cfg(target_os = "netbsd")]
+extern "C" {
+    fn flags_to_string(flags: libc::c_ulong, def: *const libc::c_char) -> *const libc::c_char;
+}
+
+/// Wrapper around the C library call fflagstostr or the netbsd equivalent
+/// If returned string is NULL or empty a "-" is returned
+fn wrapper_flags_to_string(flags: f::flag_t) -> String {
+    #[cfg(target_os = "netbsd")]
+    let empty_string = CString::new("").expect("This string is always valid");
+
     // SAFETY: Calling external "C" function
+    #[cfg(not(target_os = "netbsd"))]
     let flags_c_str = unsafe { fflagstostr(libc::c_ulong::from(flags)) };
 
+    // SAFETY: Calling external "C" function
+    #[cfg(target_os = "netbsd")]
+    let flags_c_str = unsafe { flags_to_string(libc::c_ulong::from(flags), empty_string.as_ptr()) };
+
     if flags_c_str.is_null() {
         "-".to_string()
     } else {
@@ -35,6 +52,6 @@ fn flags_to_string(flags: f::flag_t) -> String {
 
 impl f::Flags {
     pub fn render(self, style: Style, _format: FlagsFormat) -> TextCell {
-        TextCell::paint(style, flags_to_string(self.0))
+        TextCell::paint(style, wrapper_flags_to_string(self.0))
     }
 }


Test patch: