Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

exa is not available on Windows #32

Closed
sirxyzzy opened this issue Feb 23, 2015 · 53 comments
Closed

exa is not available on Windows #32

sirxyzzy opened this issue Feb 23, 2015 · 53 comments
Labels
help wanted Things I’m completely stuck on os › windows Soon™

Comments

@sirxyzzy
Copy link

sirxyzzy commented Feb 23, 2015

You mentioned you don't have a Windows machine, I do, I tried to compile exa (without git, for now) and it looks as if a couple of types are not in std. or maybe they are, but the error message is hard to understand...

C:\Users\andy.cargo\registry\src\github.com-1ecc6299db9ec823\users-0.2.3\src\lib.rs:117:27: 117:32 error: unresolved import libc::uid_t. There is no uid_t in libc
C:\Users\andy.cargo\registry\src\github.com-1ecc6299db9ec823\users-0.2.3\src\lib.rs:117 use libc::{c_char, c_int, uid_t, gid_t, time_t};
^~~~~
C:\Users\andy.cargo\registry\src\github.com-1ecc6299db9ec823\users-0.2.3\src\lib.rs:117:34: 117:39 error: unresolved import libc::gid_t. There is no gid_t in libc
C:\Users\andy.cargo\registry\src\github.com-1ecc6299db9ec823\users-0.2.3\src\lib.rs:117 use libc::{c_char, c_int, uid_t, gid_t, time_t};


Moderator edit: Windows support is being worked on in #820

@ogham ogham added the help wanted Things I’m completely stuck on label Feb 24, 2015
@ogham
Copy link
Owner

ogham commented Feb 24, 2015

There are currently three problems preventing Windows support:

  • The users crate uses the uid_t and gid_t types from libc, which are guaranteed to exist in Unix environments, but will not exist under Windows, which does users and groups differently. This is the error you're getting. I'm not sure how to adapt the users crate for Windows, but there would have to be equivalent functions of "find user information from ID" and "find list of users in a group" functions.
  • The locale crate looks for Unix-style month and day names in the Unix path. This would also have to use the Windows API.
  • The formatting codes in ansi-term are designed for ANSI-style terminals, rather than Windows terminals. (This won't stop it from compiling, but the output would make it unusable)

I'm not familiar enough with Windows to know if the API offers the functionality. I mean, it probably does, but I'm not sure how to find it.

@sirxyzzy
Copy link
Author

Thanks for the pointers, this is most helpful

OK,all those problems seem likely to have solutions, I even found an Ansi emulator (ansicon) C library that could be of use, but frankly this may be better solved by creating a slightly higher level abstraction for screen operations (move here, color there) type API which could be ANSI implemented on Unix platforms, and custom implemented for Windows.

I may noodle on this a bit, I like Rust a lot, but the Windows support in general seems a bit patchy. I feel that while that is the case any chance Rust has for widespread adoption is limited. I hope to improve that situation. If I get anything useful on the windows side, are you interested, or are you one of those who prefers not to support Windows at all? I could understand that given the oddly acrimonious history of the two tribes.

I plan on getting the git integration sorted too, as I want to build some new and novel tools around that, using Rust, I’m willing to bet that will have some challenges too.

Again, thanks.

Andy P++

From: Ben S
Sent: ‎Tuesday‎, ‎February‎ ‎24‎, ‎2015 ‎8‎:‎33‎ ‎AM
To: ogham/exa
Cc: Andy Philpotts

There are currently three problems preventing Windows support:
The users crate uses the uid_t and gid_t types from libc, which are guaranteed to exist in Unix environments, but will not exist under Windows, which does users and groups differently. This is the error you're getting. I'm not sure how to adapt the users crate for Windows, but there would have to be equivalent functions of "find user information from ID" and "find list of users in a group" functions.
The locale crate looks for Unix-style month and day names in the Unix path. This would also have to use the Windows API.
The formatting codes in ansi-term are designed for ANSI-style terminals, rather than Windows terminals. (This won't stop it from compiling, but the output would make it unusable)

I'm not familiar enough with Windows to know if the API offers the functionality. I mean, it probably does, but I'm not sure how to find it.


Reply to this email directly or view it on GitHub.

@ogham ogham added the os › windows Soon™ label Sep 2, 2015
@ogham ogham added this to the v1 milestone Sep 2, 2015
@ogham
Copy link
Owner

ogham commented Sep 2, 2015

As you can tell by the label -- I do want to have Windows support, but until I can work out how to do it, it'll have to be in the eventually column :(

@ogham ogham mentioned this issue Dec 22, 2015
8 tasks
@evhub
Copy link

evhub commented Aug 3, 2017

Just ran across exa and was disappointed to discover there was no Windows support! I don't know enough Rust to help out with the port, but if you don't have a Windows machine and you're looking for a way to test on Windows, you could try AppVeyor (which is free for open-source) with a configuration like the one here.

If it's at all helpful, I tried installing on my machine anyway and got:

> cargo install --git https://github.com/ogham/exa
    Updating git repository `https://github.com/ogham/exa`
   Compiling libc v0.2.24
   Compiling num-traits v0.1.39
   Compiling glob v0.2.11
   Compiling byteorder v0.4.2
   Compiling percent-encoding v1.0.0
   Compiling getopts v0.2.14
   Compiling matches v0.1.6
   Compiling rustc-serialize v0.3.24
error: the `?` operator is not stable (see issue #31436)
   --> C:\Users\Evan\.cargo\registry\src\github.com-1ecc6299db9ec823\percent-encoding-1.0.0\lib.rs:284:13
    |
284 |             formatter.write_str(c)?   Compiling unicode-bidi v0.3.3

    |             ^^^^^^^^^^^^^^^^^^^^^^^

error: attributes on non-item statements and expressions are experimental. (see issue #15701)
  --> C:\Users\Evan\.cargo\registry\src\github.com-1ecc6299db9ec823\unicode-bidi-0.3.3\src\prepare.rs:99:17
   |
99 |                 #[cfg(test)]
   |                 ^^^^^^^^^^^^

error: aborting due to previous errorerror[E0412]   Compiling locale v0.2.2
: type name `Range` is undefined or not in scope
  --> C:\Users\Evan\.cargo\registry\src\github.com-1ecc6299db9ec823\unicode-bidi-0.3.3\src\deprecated.rs:25:26
   |
25 | pub fn visual_runs(line: Range<usize>, levels: &[Level]) -> Vec<LevelRun> {
   |                          ^^^^^^^^^^^^ undefined or not in scope
   |
   = help: you can import several candidates into scope (`use ...;`):
   = help:   `std::collections::btree_map::Range`
   = help:   `std::collections::btree_set::Range`
   = help:   `std::ops::Range`

error[E0425]: unresolved name `min`
  --> C:\Users\Evan\.cargo\registry\src\github.com-1ecc6299db9ec823\unicode-bidi-0.3.3\src\deprecated.rs:45:25
   |
45 |             min_level = min(level, min_level);
   |                         ^^^

error[E0425]: unresolved name `max`
  --> C:\Users\Evan\.cargo\registry\src\github.com-1ecc6299db9ec823\unicode-bidi-0.3.3\src\deprecated.rs:46:25
   |
46 |             max_level = max(level, max_level);
   |

                        ^^^

Build failed, waiting for other jobs to finish...
error: aborting due to 4 previous errors

Build failed, waiting for other jobs to finish...
error: failed to compile `exa v0.7.0 (https://github.com/ogham/exa#f54bc417)`, intermediate artifacts can be found at `C:\Users\Evan\AppData\Local\Temp\cargo-install.XaPfveabwX8d`

Caused by:
  Could not compile `percent-encoding`.

To learn more, run the command again with --verbose.

I also tried installing libgit2 and got:

> cargo install --git https://github.com/alexcrichton/git2-rs
    Updating git repository `https://github.com/alexcrichton/git2-rs`
    Updating registry `https://github.com/rust-lang/crates.io-index`
   Compiling log v0.3.8
   Compiling winapi v0.2.8
   Compiling winapi-build v0.1.1
   Compiling unicode-xid v0.0.3
   Compiling bitflags v0.3.3
   Compiling libc v0.2.29
   Compiling vcpkg v0.2.2
   Compiling rustc-serialize v0.3.24
   Compiling pkg-config v0.3.9
   Compiling gcc v0.3.51
   Compiling kernel32-sys v0.2.2
   Compiling cmake v0.1.24
   Compiling libz-sys v1.0.16
error: attributes on non-item statements and expressions are experimental. (see issue #15701)
   --> C:\Users\Evan\.cargo\registry\src\github.com-1ecc6299db9ec823\cmake-0.1.24\src\lib.rs:423:21
    |
423 |                     #[cfg(windows)] {
    |                     ^^^^^^^^^^^^^^^

error: aborting due to previous error

Build failed, waiting for other jobs to finish...
error: failed to compile `systest v0.1.0 (https://github.com/alexcrichton/git2-rs#60a49f46)`, intermediate artifacts can be found at `C:\Users\Evan\AppData\Local\Temp\cargo-install.nsopyCWaNwbL`

Caused by:
  Could not compile `cmake`.

To learn more, run the command again with --verbose.

@kasajian
Copy link

kasajian commented Aug 3, 2017

Also, for those of you who typically use non-windows operating systems but would like access to one temporarily for testing your software, there are several options.
One, you can use the free VMs that Microsoft makes available: https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/
Two, everyone can get some limited number of hours per month on Azure, and they have Windows VMs that you can use, some with Visual Studio already installed.
Three, once the Windows code is done, you can use the free-tier of AppVeyor to do the continuous builds.

@martinlindhe
Copy link
Contributor

martinlindhe commented Aug 4, 2017

@evhub I believe the errors you are getting about experimental features is because your rust compiler is out of date, try rustup update.

Current stable version is 1.19, see which version you are using with rustc -V

@Kethku
Copy link

Kethku commented Aug 4, 2017

As for the ansi color code issues, a build which still outputs them is very useful on windows if you use conemu for your console emulator as it parses the codes and outputs color as you might expect. That means you can ignore that particular problem and solve it at a later date if need be.

@Kethku
Copy link

Kethku commented Aug 4, 2017

Also seems like finding the terminal size is a problem as it uses the unix ioctl command which I dont think works in windows...

Maybe that code can be replaced with https://github.com/eminence/terminal-size?

@PJB3005
Copy link
Contributor

PJB3005 commented Aug 5, 2017

My attempts at building on Windows with latest stable Rust so far have resulted in a ton of errors from the rust-users crate. Gonna see if I can get this to work though.

@PJB3005
Copy link
Contributor

PJB3005 commented Aug 5, 2017

Ok so right now, there's a couple dependencies that fail to compile outright on Windows:

  • users
  • datetime
  • zoneinfo-compiled

Then there's also the fact that basically all permissions handling is also Unix-specific, which is another blocker.
The last two of those failing crates are both date time handling and might be able to be replaced with chrono, users might be more tricky to replace however.

@mqudsi
Copy link
Contributor

mqudsi commented Aug 8, 2017

Note that on Windows 10, the WSL team has worked to make conhost mostly xterm-256color-compatible, so that should take care of one of the issues.

@Kethku
Copy link

Kethku commented Aug 9, 2017

Now if they could make powershell or cmd similarly compatible...

@mqudsi
Copy link
Contributor

mqudsi commented Aug 9, 2017

@Kethku I don't think you understand the split between shell and terminal under Windows. PowerShell and CMD both run under conhost.

@PJB3005
Copy link
Contributor

PJB3005 commented Aug 9, 2017

It might be possible to use the same approach as colorama, where on Windows it hooks stdout, strips control characters and instead fires off the relevant win32 API calls. Not sure how much Rust allows hooking stdout, but if it does this should make it possible to get colors working in conhost without touching the rest of the code much.

@Kethku
Copy link

Kethku commented Aug 9, 2017 via email

@Kethku
Copy link

Kethku commented Oct 9, 2017

Sweet. #237 fixes the terminal size problem.

@QrchackOfficial
Copy link

I'd like to mention as of now the Linux 64-bit binary works perfect under Windows Subsystem for Linux, can be posted on the website before the actual Windows support is ready.

@ntpeters
Copy link

ntpeters commented May 23, 2018

For anyone interested, here's how I'm setup on Windows to call exa in WSL from PowerShell more easily.

In your PowerShell profile (ie: %UserProfile%\Documents\Microsoft.PowerShell_profile.ps1):

function Invoke-Exa {
    & bash.exe -c "exa $args"
}

Set-Alias exa Invoke-Exa

Also, if you're on a recent build of Windows 10 (at least build 17093), I highly recommend configuring your /etc/wsl.conf mount options to support the new metadata flag. This allows file metadata such as permissions to persist on files accessed in Windows from WSL.

Call from PowerShell in ConEmu:
image

Call from vanilla PowerShell (obviously not as pretty):
image

@pbnoyz
Copy link

pbnoyz commented Jun 11, 2018

Is it possible to use GetNamedSecurityInfo winapi to retrieve user infos and permissions?

@sergeevabc
Copy link

Windows binary is still anticipated.

@RoniJacobson
Copy link

RoniJacobson commented Jun 30, 2019

  • The formatting codes in ansi-term are designed for ANSI-style terminals, rather than Windows terminals. (This won't stop it from compiling, but the output would make it unusable)

This has a simple solution.
It is unclear why this works, but it does: if you send an empty call out into the cmd, then ansi codes start working.
The following code will print hello in red in your terminal.

use std::process::Command;
fn main() {

let mut list_dir = Command::new("cmd");
list_dir.arg("/c");
// Execute `ls` in the current directory of the program.
list_dir.status().expect("process failed to execute");

println!("\x1b[31mhello\x1b[0m");
}

Also, in the new upcoming windows terminal the escape codes are enabled by default.

@vvuk
Copy link

vvuk commented Oct 7, 2019

I'm toying around with this. Current problems I've ran into and workarounds:

  • exa's fs::file is very Unix specific. Things like is_block_device/is_char_device don't really have a Windows equivalent. However, this is actually relatively easy to work around; a dummy trait can be implemented that just returns false for all of these. For eventual Windows-specific properties, the same approach can be taken to stub them out on Unix. It would be cleaner to split these things up into Windows and Unix file types, including separate styling extensions, but might be overkill to do that refactor.

  • the users crate can just be skipped entirely, and we can ignore users/groups on windows (for now) by providing some dummy impls in a few places, and just skipping User/Group support in a few other places

  • Windows has a much more complicated permissions model. However, the basic permissions can be distilled into Unix bits, at least as far as "does user have permission" or "does user not have permission". I can't implement this on the dummy traits though, so it would need to be implemented directly on file.

  • options::parser uses OsString and does direct manipulations, assuming that the string is composed of bytes. That's not the case on Windows. Would be better to convert from OsString to regular strings, and then iterate over string arguments -- or to use something like clap-rs for options parsing. (Just read the comments on the top -- I understand why it has its own parser now. I'll think about how to do this on windows.)
    -- Took a stab at this. It's going to be complicated, because it assumes that the args are &OsStr, and that this can be coverted to/from &[u8] at will. That's not true on Windows, though I really don't understand why. There is a encode_wide() that returns a u16 iterator, and I can create a brand new Vec<u16> from that. But I can't get the underlying u16 slice, and can't go back and forth between that and &OsStr.

I'm currently trying to figure out a quick workaround for the OsString bits in order to move further.

I think a version that handles the basics -- filenames, sizes, times, executable/not, directory/symlink/etc. and just stubs everything else out should be possible pretty quickly. Then the rest can be implemented piecemeal.

@rivy
Copy link

rivy commented Oct 9, 2019

@vvuk , I've thought about working to improve the Windows story here as well, but my stack is otherwise full at the moment. But, I did some initial research, and I came across lsd which is a similar program, also written in rust. lsd has a working Windows implementation with a display of ownership and permissions. It might be worth a look for some inspiration.

@sergeevabc
Copy link

@rivy, I have not found any Windows-ready binaries of lsd (checked Releases and Issue Tracker).

@rivy
Copy link

rivy commented Nov 20, 2019

lsd does build successfully under Windows.
But you're correct, there are no current Windows builds included in the release assets.
There is an open issue (see GH:Peltoche/lsd#188 requesting the addition of Windows builds, but it's obviously not resolved.

@rivy
Copy link

rivy commented Nov 20, 2019

@sergeevabc , I created a quick GitHub workflow that compiles and saves the results as artifacts (see rivy/rust.lsd:GHA). Both i686 and x86_64 versions are available from the "Artifacts" drop-down on the upper left.

@mqudsi
Copy link
Contributor

mqudsi commented May 2, 2020

You need to use Cow<OsStr>

@zkat
Copy link
Contributor

zkat commented May 2, 2020

@mqudsi that's what I'm using (and I'm using the os_str_bytes crate), but OsStr::from_bytes() creates a brand-new Cow that seems to be disconnected from the original so the lifetimes are messed up? I can push my code if you'd like to take a look. I haven't used Cow before.

@zkat
Copy link
Contributor

zkat commented May 2, 2020

@mqudsi https://github.com/zkat/exa/blob/master/src/options/parser.rs#L483-L497 Here's an example. This complains that I'm using a temporary value instead of having its lifetime be based on the input

@mqudsi
Copy link
Contributor

mqudsi commented May 2, 2020

I’m on my phone but you are using to_bytes instead of as_bytes, no?

@zkat
Copy link
Contributor

zkat commented May 2, 2020

That's correct -- as_bytes only exists on unix. to_bytes() is OsStrBytes::to_bytes() -> Cow<OsStr>

@mqudsi
Copy link
Contributor

mqudsi commented May 2, 2020

That's not going to work, because it creates a new Cow owning the underlying bytes, which you then need to move out of. Remember that the Cow is always assumed to be the owner of the underlying data (because in the worst case, it is), so you either need to take a &Cow in and then can return new Cows constructed from its parts or you need to copy the individual byte ranges in order to be able to "throw away" the input parameter altogether. (But you would just accept an &OsStr instead of a &Cow<OsStr>, anyway).

The OsStrBytes crate is weird. It'll force you to reference the temporary value in any return result or else copy out. I have my own snippet I use but it is unsafe; you can try it for demonstration purposes to see that it gets the job done. I think it's fundamentally safe, but I'm happy to be proven wrong.

use std::ffi::{OsStr, OsString};

pub(crate) trait RawOsStr {
    fn as_bytes(&self) -> &[u8];
    fn from_bytes(bytes: &[u8]) -> &Self;
}

pub(crate) trait RawOsString {
    fn from_bytes(bytes: Vec<u8>) -> Self;
}

impl RawOsStr for OsStr {
    fn as_bytes(&self) -> &[u8] {
        unsafe { std::mem::transmute(self) }
    }

    fn from_bytes(bytes: &[u8]) -> &Self {
        unsafe { std::mem::transmute(bytes) }
    }
}

impl RawOsString for OsString {
    fn from_bytes(bytes: Vec<u8>) -> Self {
        unsafe { std::mem::transmute(bytes) }
    }
}

which would give you a working solution:

fn split_on_equals<'a>(input: &'a OsStr) -> Option<(Cow<'a, OsStr>, Cow<'a, OsStr>)> {
    let input_bytes = input.as_bytes();
    if let Some(index) = input_bytes.iter().position(|elem| *elem == b'=') {
        let (before, after) = input_bytes.split_at(index);

        // The after string contains the = that we need to remove.
        if !before.is_empty() && after.len() >= 2 {
            return Some((
                OsStr::from_bytes(before).into(),
                 OsStr::from_bytes(&after[1..]).into(),
            ));
        }
    }

    None
}

fwiw, as I understand it there is talk about adding this to the standard library regardless of OS.

@zkat
Copy link
Contributor

zkat commented May 3, 2020

@mqudsi I don't understand how a transmute would work on Windows if the underlying representations are different. You can't just assume a u16 works fine getting turned into a u8, no?

@zkat
Copy link
Contributor

zkat commented May 3, 2020

image

So far so good :)

Only one test failing, and then it's time to start porting and enabling whatever bits of -l can actually be enabled on Windows...

@zkat
Copy link
Contributor

zkat commented May 3, 2020

anyway, cargo install --git https://github.com/zkat/exa should work as a workaround for those who just want a quick install without all the features yet.

@mqudsi
Copy link
Contributor

mqudsi commented May 3, 2020

You don’t turn the u16 into a u8, you map it to two u16. The only concern is alignment, but that’s ok here for other reasons. You cannot make any assumptions about the contents in byte form, all it lets you do is serialize an OsString to an equivalent in-memory binary payload where the only thing you can can do with it is store it and deserialize it back. (Technically Marshall and not serialized)

@ofek
Copy link

ofek commented May 4, 2020

@zkat Great job!!! FYI I'm getting a time zone error too:

Capture

@mardukbp
Copy link

mardukbp commented May 8, 2020

@zkat Thank you so much! It even works on a drive other than C: (as opposed to lsd).

@tim-harding
Copy link

@ogham Is there anyone currently working on this feature? I'd be curious to throw my hat in the ring if it isn't already on some else's plate.

@skyline75489
Copy link
Contributor

Hi guys. I've created #820 for Windows support. Check that out if you're interested 😄

@ariasuni ariasuni changed the title Windows build problems exa is not available on Windows Jul 14, 2021
@si-kotic
Copy link

si-kotic commented Jan 22, 2022

For anyone interested, here's how I'm setup on Windows to call exa in WSL from PowerShell more easily.

In your PowerShell profile (ie: %UserProfile%\Documents\Microsoft.PowerShell_profile.ps1):

function Invoke-Exa {
    & bash.exe -c "exa $args"
}

Set-Alias exa Invoke-Exa

Also, if you're on a recent build of Windows 10 (at least build 17093), I highly recommend configuring your /etc/wsl.conf mount options to support the new metadata flag. This allows file metadata such as permissions to persist on files accessed in Windows from WSL.

Call from PowerShell in ConEmu: image

Call from vanilla PowerShell (obviously not as pretty): image

Thanks for this; I didn't know I could call bash from windows like this.
I found this to be a bit more stable/convenient:

Function Invoke-Exa {
	Param (
		[string]$Path = "./",
		[switch]$Recurse
	)
	if ($Recurse) {
		$r = "--recurse"
	}
	$fullPath = (Get-Item $Path).FullName
	$linuxPath = "/mnt/" + $fullPath[0].ToString().ToLower() + ($fullPath.Substring(2) -replace "\\","/")
	& bash.exe -c "/usr/local/bin/exa --icons --group-directories-first -l $r $linuxPath"
}

@seanmamasde
Copy link

@si-kotic your enhanced version of code cannot list directories with spaces in name properly? At least from my testing it's not working though. (sorry I can't write in the PowerShell lang so can't really fix anything)

@Freed-Wu
Copy link
Contributor

Freed-Wu commented Apr 5, 2023

#820 should close this issue. And when a new version will be released?

@SillyCatto
Copy link

I compiled exa on my machine and ran it at the root of a partition and got Access denied os error 5 errors on some protected files and folders. I tried to ignore them with --ignore-globs="" but it doesn't work.

exa version 0.10.1
Win10 22H2
245188376-c855ed1c-c692-4520-a0cc-4cdc54b99891

@mhdadk
Copy link

mhdadk commented Jul 22, 2023

Any new ETA on when exa will be available on Windows?

@seanmamasde
Copy link

seanmamasde commented Jul 22, 2023

bro you definitely wanna check out lsd which stands for ls-deluxe, and it can be installed natively on Windows 11 using scoop. It's a good alternative if you don't want to use the default Get-Childitem cmdlet or don't want to run exa through WSL2 (which introduced some extra latency on my machine). It's also written in rust if that's what you care about.

@mhdadk
Copy link

mhdadk commented Jul 22, 2023

@seanmamasde thanks for mentioning. I'll try it out.

@ariasuni
Copy link
Collaborator

ariasuni commented Sep 6, 2023

Closing this, exa is unmaintained (see #1243), and the the active fork eza has better support for Windows than exa.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Things I’m completely stuck on os › windows Soon™
Projects
None yet
Development

No branches or pull requests