This would be fantastic. I’ve tested it myself with WSL, but not on native Windows. I’ve heard people have succeeded in building it on Windows, but as I’m not super familiar with Windows, I don’t know exactly what they’ve done, and what needs to be done to make it work.
Can you get a working build?
The main challenge, I believe, is not really to make it work once, but rather to setup a pipeline to make this work continually, with each new release, with minimal manual intervention.
A potential issue is how some things implicitly depend on Linux – e.g. the pager implementation depends on the less
binary. I don’t know if this works / exists on Windows or not.
We might have to feature- / cfg
-gate that specific thing, or let it be configured to a pager that works / exists on Windows.
I’ve heard people have succeeded in building it on Windows
I guess it is possible with some compatibility layer like MSYS. Obviously it has some overhead but git-for-windows is doing fine, I daresay. I think both solutions (WSL and MSYS) are completely acceptable.
I have tried building Pijul on Windows via Cargo, here is a bit about what I encountered.
I had Cargo / rustc configured for x86_64-pc-windows-msvc.
You will need a build of OpenSSL that Cargo can find. I got one via Microsoft’s vcpkg (Cargo wanted OpenSSL built with the triple ‘x64-windows-static-md’). I could not get Cargo to find the library without running ‘vcpkg integrate install’, though setting the VCPKG_ROOT environment variable is suppose to be enough. I also had Cargo install ‘cargo-vcpkg’, but I am not sure if that was needed or not.
The main issue is that the ‘pager’ dependency appears to be written in a platform dependent manner and needs a Unix/Posix libc. Not sure it building for Windows with GCC instead of MSVC would fix this. But if it could, then to provide a ‘less’ binary I would suggest looking at Git for Windows which has a bundled port of ‘less’ that works on Windows.
Since the build fails at ‘pager’ I don’t know if there are other issues.
Commenting out the pager
dependency lets it continue on, but it then fails on thrussh-keys
error[E0433]: failed to resolve: could not find `UnixStream` in `net`
--> C:\Users\thede\.cargo\registry\src\github.com-1ecc6299db9ec823\thrussh-keys-0.18.8\src\agent\client.rs:34:34
|
34 | let stream = tokio::net::UnixStream::connect(path).await?;
| ^^^^^^^^^^ could not find `UnixStream` in `net`
error[E0412]: cannot find type `UnixStream` in module `tokio::net`
--> C:\Users\thede\.cargo\registry\src\github.com-1ecc6299db9ec823\thrussh-keys-0.18.8\src\agent\client.rs:30:30
|
30 | impl AgentClient<tokio::net::UnixStream> {
| ^^^^^^^^^^ not found in `tokio::net`
Even in the latest version of Tokio this isn’t supported on Windows, Tokio issue
Hey @cole-h @The_Decryptor and @Skia. I made a post on the discourse about the paging crate that I am currently working on, and I would say it’s almost ready for use. Here’s the GitHub https://github.com/arijit79/minus.git
I have not personally tested it on Pijul (I am currently busy working on it). Could anyone try to write an implementation and file issues if there are bugs
Edit: I am currently working on the documentation in the README, although function doc’s are present. Run
cargo doc --all-features
to see them
@The_Decryptor: Thanks a lot for testing this. Would you mind submitting changes to pijul/thrussh?
Sure, I’ll have to set it up in WSL first, because I’m not having a huge amount of luck 😂
Good news is that I’ve successfully managed to compile it, and the resulting binary runs, but I can’t clone the main repository with it (Currently working with a source tarball I grabbed from crates.io)
> ..\target\release\pijul.exe clone https://nest.pijul.com/pijul/pijul
✓ Updating remote changelist
Error: error sending request for url (https://nest.pijul.com/pijul/pijul/.pijul?change=PCEJFKFXAFGYGHMM4BOBGFV3WRFXEBF2UQYQHLJ7MURRYBKRM3EAC): connection closed before message completed
I thought this might just be a network issue (I reran the command a few times and it gave different change hashes each time), so I tried with SSH
> ..\target\release\pijul.exe clone ssh://The_Decryptor@nest.pijul.com/pijul/pijul
Unknown key for "nest.pijul.com", fingerprint "djurQfjodtXZF0O72O3Ppbh2anhjlByNHvZqGwt/kec". Learn it (y/N)? y
Password for The_Decryptor@nest.pijul.com:
✓ Cloning channel
✓ Downloading changes ████████████████████████████████████████████████████████████████████████████████████████████ 99/99
Error: The filename, directory name, or volume label syntax is incorrect. (os error 123)
Now I’ve got no idea if that’s how I’m supposed to clone a public repo over SSH, but it seemed to work at least before it hit the OS error.
There’s an issue with SSH support though, the ssh-agent
in Windows uses named pipes to talk to clients instead of domain or TCP sockets. Now according to the documentation being a client of the pipe should just use pretty normal file I/O, so I whipped up something using the existing Tokio fs
support. The compiler accepted it, but I’ve got absolutely no idea if even works, let alone makes sense in the context of Windows IPC.
I want to mention that WSL is absolutely not acceptable, imo. WSL isn’t Windows, it’s a Linux VM/emulator on Windows.
MSYS is much more acceptable, because they are Windows binaries that can be run on computers without MSYS (afaik), not linux binaries. WSL executables are Linux executables. They won’t work outside of WSL/Linux, which means you’d be forcing everyone to use WSL just for pijul, and this won’t work when integrating into things like VSCode, for example (until WSL gets graphics support, I suppose… but then you’re requiring people run graphics programs from WSL just to get pijul integration working).
One of the hardest challenges I think is trying to get OpenSSL built. This is just the way it is when Linux developers cross over onto Windows - they have a bunch of Linux-specific software or expectations that are hard to transfer over, and so it becomes very complicated to build on Windows computers. It’s like this with most big linux software that can be built on Windows - OpenSSL, QT, etc.
I do want to mention that Windows 10 now has OpenSSL client integrated into the OS. Another thing people might want to try is vcpkg, which is supposed to make things like building openssl on windows easier.
One more thing, I think windows does have a pager, and I believe it’s called “more”, but I’ll have to check on this.
MSYS is much more acceptable, because they are Windows binaries that can be run on computers without MSYS (afaik), not linux binaries.
When everything is statically linked, yes (does Cargo do that?). But you also would have to build Pijul anew everytime a new version of OpenSSH or any other dependency gets published, defeating the purpose of doing so; I mean, that’s why dynamic libraries (among other reasons) were invented. And it’s the same reason people don’t fully embrace the idea of Flatpak.
And like I said: Git is using the MINGW environment since forever and nobody complains about it.
which means you’d be forcing everyone to use WSL just for pijul, and this won’t work when integrating into things like VSCode
You could say that about any Linux application that you want to run under Windows, and obviously there is demand for it. I don’t see that as an obstacle; many people even prefer it to MSYS/MINGW, which also doesn’t have a graphical user-interface. And while Pijul itself doesn’t have a GUI, it’s not worth complaining about the lack of GUI somewhere else.
And yes, there is integration for WSL in VSCode, and the filesystems can interact with each other seamlessly (when not completely without overhead), either through PowerShell / Bash or the Explorer.
I think windows does have a pager, and I believe it’s called “more”
Indeed it is.
By the way, I’m releasing pijul 1.0.0-alpha.12, which depends on a version of thrussh-keys that shouldn’t have the compilation problem on Windows.
When everything is statically linked, yes (does Cargo do that?). But you also would have to build Pijul anew everytime a new version of OpenSSH or any other dependency gets published, defeating the purpose of doing so; I mean, that’s why dynamic libraries (among other reasons) were invented. And it’s the same reason people don’t fully embrace the idea of Flatpak. And like I said: Git is using the MINGW environment since forever and nobody complains about it.
This is kinda irrelevant to Pijul, but: This is the way it should be done - statically linked - because Windows isn’t like Linux where things suddenly break all the time because of dynamically-linked libraries being updated. A program is programmed with a specific version of a library. It doesn’t make sense to swap that out. This has literally led to one of the biggest Linux problems, and is exactly why AppImage is even a thing…. and containers.
Anyways, of course git doesn’t have problems, it uses Windows binaries and ships with MINGW. Anything built under WSL has to be ran under WSL - WSL is Linux, not Windows. Git … runs under Windows. You don’t even need to use git bash to run git. Git is very easily accessible to programs under Windows. Etc.
And yes, there is integration for WSL in VSCode, and the filesystems can interact with each other seamlessly (when not completely without overhead), either through PowerShell / Bash or the Explorer.
Sure, that’s done by running a server on the WSL instance so Windows can use the network to see the filesystem. Pijul would also have to implement something like this if you want to call out to pijul that’s under WSL from Windows. Doing this is a waste of time when you can just make a native Windows program, and we already have tools, which have been mentioned prior already, like vcpkg, to help with the building of openssl.
This doesn’t matter anyways, because it seems they’re getting it to work on Windows natively, which is good.
My experience trying to build pijul v1.0.0-alpha.12 on windows:
pager
dependency, as suggested by @The_Decryptorzstd-seekable
and more specifically bindgen
, I had to install clang
. I don’t know if there is a way around this, but I thought it was relevant since many windows devs do not have clang
installed as far as I am aware.@TheNappap: thanks a lot for trying this out, this is really helpful. I believe I’ve just fixed these:
cfg(not(unix))
).zstd-seekable
, I’ve just published a version that doesn’t need bindgen anymore.AgentClient
for Windows, while we wait on https://github.com/tokio-rs/tokio/issues/2201.One of the hardest challenges I think is trying to get OpenSSL built.
Getting OpenSSL built is not a big issue as you can use Microsoft’s vcpkg package manager to build it from source. The one I build was compiled and linked against the Windows SDK with MSVC as the compiler.
It is just seems that simply setting the VCPKG_ROOT alone is not enough to get Cargo to find vcpkg’s installed libraries on its own even though the documentation indicates that should be enough. When I was trying the point at which Cargo starting locating it was after running vcpkg integrate install
marking the specific vcpkg instance at a system wide installation. I also cargo install cargo-vcpkg
.
As I mentioned in my other post, Cargo wants vcpkg’s OpenSSL to be built with the triple ‘x64-windows-static-md’ if building with MSVC and targeting x86_64 architecture.
Compiling thrussh-keys v0.18.10 error[E0412]: cannot find type
UnixStream
in moduletokio::net
–> C:\Users....cargo\registry\src\github.com-1ecc6299db9ec823\thrussh-keys-0.18.10\src\agent\client.rs:51:30 | 51 | impl AgentClienttokio::net::UnixStream { | ^^^^^^^^^^ not found intokio::net
error[E0282]: type annotations needed –> C:\Users....cargo\registry\src\github.com-1ecc6299db9ec823\thrussh-keys-0.18.10\src\agent\client.rs:55:9 | 55 | Err(Error::AgentFailure.into()) | ^^^ cannot infer type for type parameter
T
declared on the enumResult
error: aborting due to 2 previous errors
Alright, I just published 1.0.0-alpha.14. If you care to try again, it would be very useful.
Compiling pijul v1.0.0-alpha.14 error[E0433]: failed to resolve: use of undeclared crate or module
pager
–> C:\Users\…\.cargo\registry\src\github.com-1ecc6299db9ec823\pijul-1.0.0-alpha.14\src\commands\mod.rs:109:5|
109 | pager::Pager::with_pager(“less -RF”).setup()
| ^^^^^ use of undeclared crate or module `pager`
Looks like all that is left to at least get it to build is the pager for Windows to be changed out.
Getting OpenSSL built is not a big issue as you can use Microsoft’s vcpkg package manager to build it from source.
I suppose you didn’t read all of my posts…
Doing this is a waste of time when you can just make a native Windows program, and we already have tools, which have been mentioned prior already, like vcpkg, to help with the building of openssl.
Good news, everything compiles. The bad news is there are linking errors. The error messages are extremely long and all on one line, so I will describe the problems rather than posting the full messages.
The linker being used by Cargo is MSVC’s link.exe.
First off, there are two libraries file not being found: ‘zstd.lib’ and ‘xxhash.lib’. After going through the library search paths passed to the linker (as these are not being passed as absolute paths), I am pretty sure these libraries are suppose to be build as part of zstdseek-able (in “C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out”).
In that folder are ‘xxh64.o’ ‘libzstdseek.a’ and ‘zstdseek.lib’. ‘zstdseek.lib’ is a renamed copy of ‘libzstdseek.a’. I tried running the build again and put copies of the previously build ‘xxh64.o’ and ‘zstdseek.lib’ renamed as ‘xxhash.lib’ and ‘zstd.lib’ in the directory. There were unresolved externals after that, here are a few ‘ZSTD_isError’, ‘XXH64_reset’, and ‘ZSTD_createDStream’ they are expected by ‘C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\deps\libzstd_seekable-26ba2eec83d5af3e.rlib’.
Also there was one other error when I did the retry other than the unresolved externals, LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
. /NODEFAULTLIB:library
would be an example, what would be passed to the linker is /NODEFAULTLIB:LIBCMT
.
Finally, here is the contents of “C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\output”:
TARGET = Some(“x86_64-pc-windows-msvc”)
HOST = Some(“x86_64-pc-windows-msvc”)
CC_x86_64-pc-windows-msvc = None
CC_x86_64_pc_windows_msvc = None
HOST_CC = None
CC = None
CFLAGS_x86_64-pc-windows-msvc = None
CFLAGS_x86_64_pc_windows_msvc = None
HOST_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
CARGO_CFG_TARGET_FEATURE = Some(“fxsr,sse,sse2”)
DEBUG = Some(“false”)
running: “C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\cl.exe” “-nologo” “-MD” “-O2” “-Brepro” “-I” “zstd/lib/common” “-I” “zstd/lib” “-W4” “-FoC:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out\zstd/contrib/seekable_format/zstdseek_compress.o” “-c” “zstd/contrib/seekable_format/zstdseek_compress.c” zstdseek_compress.c
zstd/contrib/seekable_format/zstdseek_compress.c(73): warning C4267: ‘=’: conversion from ‘size_t’ to ‘U32’, possible loss of data
zstd/contrib/seekable_format/zstdseek_compress.c(207): warning C4267: ‘+=’: conversion from ‘size_t’ to ‘U32’, possible loss of data
zstd/contrib/seekable_format/zstdseek_compress.c(251): warning C4267: ‘+=’: conversion from ‘size_t’ to ‘U32’, possible loss of data
zstd/contrib/seekable_format/zstdseek_compress.c(252): warning C4267: ‘+=’: conversion from ‘size_t’ to ‘U32’, possible loss of data
zstd/contrib/seekable_format/zstdseek_compress.c(293): warning C4267: ‘+=’: conversion from ‘size_t’ to ‘U32’, possible loss of data
exit code: 0
running: “C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\cl.exe” “-nologo” “-MD” “-O2” “-Brepro” “-I” “zstd/lib/common” “-I” “zstd/lib” “-W4” “-FoC:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out\zstd/contrib/seekable_format/zstdseek_decompress.o” “-c” “zstd/contrib/seekable_format/zstdseek_decompress.c” zstdseek_decompress.c
C:\Users\…\.cargo\registry\src\github.com-1ecc6299db9ec823\zstd-seekable-0.1.4\zstd\contrib\seekable_format\zstdseek_decompress.c(132) : warning C4701: potentially uninitialized local variable ‘newOffset’ used
exit code: 0
running: “C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\cl.exe” “-nologo” “-MD” “-O2” “-Brepro” “-I” “zstd/lib/common” “-I” “zstd/lib” “-W4” “-FoC:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out\xxh64.o” “-c” “xxh64.c” xxh64.c
xxh64.c(4): warning C4244: ‘return’: conversion from ‘XXH64_hash_t’ to ‘unsigned int’, possible loss of data
exit code: 0
AR_x86_64-pc-windows-msvc = None
AR_x86_64_pc_windows_msvc = None
HOST_AR = None
AR = None
running: “C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\HostX64\x64\lib.exe” “-out:C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out\libzstdseek.a” “-nologo” “C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out\zstd/contrib/seekable_format/zstdseek_compress.o” “C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out\zstd/contrib/seekable_format/zstdseek_decompress.o” “C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out\xxh64.o”
exit code: 0
cargo:rustc-link-lib=static=zstdseek
cargo:rustc-link-search=native=C:\Users\…\AppData\Local\Temp\cargo-installWOFCHQ\release\build\zstd-seekable-2ecca625db751009\out
cargo:rustc-link-lib=zstd
cargo:rustc-link-lib=xxhash
Alright, we’re almost there! On Unix you would need to install two external libraries: xxHash and Zstd. Do you think you can find the relevant libraries somewhere?
The unresolved symbols you describe are from these libraries. I should definitely do something in the zstd-seekable
crate, to try and build if it isn’t installed.
After installing xxHash and Zstd via vcpkg, pijul installs successfully and can init a new empty repository.
Trying to pijul clone https://nest.pijul.com/pijul/pijul
results in an error once the download finishes: Error: The filename, directory name, or volume label syntax is incorrect. (os error 123)
. The folder it was using for temporary storage during the download was deleted and no repository was created.
You can’t imagine how thankful I am.
Could you try and run the same command, setting the environment variable RUST_LOG
to pijul=debug
, and paste the result here?
I tried that but there was no additional output in the console window. Is there a log file somewhere I should look for?
Also, before seeing your latest comment I tried creating an empty repository and running pijul pull https://nest.pijul.com/pijul/pijul
in that directory which did work.
It will be late tonight before I can try any thing else saddly.
Releasing 1.0.0-alpha.16, which should have a clearer error message.
Yay!!!!! I’m very glad Windows is almost ready!
Oh that is a cool trick with pulling into a empty repo, that works for me and I can avoid using tarballs from crates.io now.
I looked a bit last night into the (os error 123)
issue I was hitting during clones, what I found was that pijul was trying to write filenames in the form of pijul/Cargo.toml
i.e. the wrong directory separator was being used. The error I kept hitting originated from write_file
and create_dir_all
in libpijul\src\working_copy\filesystem.rs
, but I’m not sure where the choice of separator is coming from (I assumed it was directly from the rust stdlib, but I couldn’t reproduce that in a sample app when I tried)
And also the status
command fails with a different error
PS C:\Users\thede\Code\pijul> $env:RUST_LOG="pijul=debug"
PS C:\Users\thede\Code\pijul> .\target\debug\pijul.exe status
Error: The system cannot find the file specified. (os error 2)
PS C:\Users\thede\Code\pijul>
I looked a bit last night into the (os error 123) issue I was hitting during clones, what I found was that pijul was trying to write filenames in the form of pijul/Cargo.toml i.e. the wrong directory separator was being used. The error I kept hitting originated from write_file and create_dir_all in libpijul\src\working_copy\filesystem.rs, but I’m not sure where the choice of separator is coming from (I assumed it was directly from the rust stdlib, but I couldn’t reproduce that in a sample app when I tried)
Pijul represents files internally with strings, and the separator is /
. There is an arbitrary choice to make anyway, and Unix conventions are often considered more rational (because MS-DOS backwards-compatibility is not a goal). I’ll look into this right away, thanks!
It’s a bit annoying, vcpkg installs the lib files for zstd/xxhash and openssl in separate folders (Because OpenSSL is statically linked, while the others are dynamically linked), but only adds one of them to the search path that the linker uses. For PowerShell I had to run this to get it to pick up the needed files.
$env:LIB = 'C:\Users\thede\Code\vcpkg\installed\x64-windows\lib'
(Of course changing the path to where you’ve installed vcpkg, the env variable was also unset for me so check that as well)
You’ll also need to move the .dll files from the bin
folder (next to the lib
folder) next to the pijul.exe
file, otherwise it’ll just silently fail to start.
Thanks! That was indeed the problem. So the only pain points left are: everything vcpkg related and copying the dll files next to pijul.exe. Which can be fixed if it is precompiled and distributed with the dll files. (unless that’s not desired?)
Is there any chance we can distribute Pijul via a package manager of some sort? (is there any popular one on Windows?)
I specify the triple ‘x64-windows-static-md’ to the vcpkg command line for all three required libraries (OpenSSL, xxHash, and Zstd). This forces them to all be static libraries and be under the same folder. Also, I believe the ‘md’ part of the triple is specifying a specific version of the Windows C Runtime to build against (looking at the MSVC compiler flags, it should be the multi threaded DLL version).
My installed library list is:
The issue with cloning appears to be gone in 1.0.0-alpha.17.
The one package manager I am aware of that works similar to those on Linux distros is Chocolatey: https://chocolatey.org
To make pijul easily accessible so people are more likely to give it a try, the best course would be to have an intaller (*.msi or *.exe) available for download. I presume @scottnm had some thoughts about how to do so when they opened this discussion.
For the prerequisites of zstd-seekable, I would suggest looking at the openssl crate since it also requires a library to be available. OpenSSL creates an error telling the user about its external requirement and provides a link to a webpage telling how to get it.
These steps worked for me, compiled Pijul without errors and it works. YMMV.
Install compilers:
Install libraries:
pushd %LOCALAPPDATA%
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
bootstrap-vcpkg.bat
vcpkg install --triplet=x64-windows-static-md xxhash zstd openssl openssl-windows
cd installed\x64-windows-static-md\lib
copy zstd_static.lib zstd.lib
Install Pijul:
set LIB=%LOCALAPPDATA%\vcpkg\installed\x64-windows-static-md\lib
set OPENSSL_DIR=%LOCALAPPDATA%\vcpkg\installed\x64-windows-static-md
set LIBCLANG_PATH=C:\Program Files\LLVM\bin
cargo install pijul --version 1.0.0-alpha.17
@pmeunier Microsoft has a package manager now, but it’s still in preview: https://docs.microsoft.com/en-us/windows/package-manager/
There’s also chocolatey. Most windows users don’t use a package manager though, btw. The best thing is to just provide a pre-built portable folder of the program in a zip.
It’d be cool to get a CI up and running that will automatically build mac, linux, and windows binaries, which would then require less work by you on releasing pre-built binaries. :)
well, I’ve just set up CI to build a new Windows binary for every new Pijul release, per @Ron’s instructions: https://github.com/boringcactus/pijul-windows-builds
I’m trying to close as many discussions as possible before releasing the beta, so I’m closing this one, I believe @Ron and @boringcactus pretty much solved it. Thanks again to everyone involved, you’re great!
The docs mentioned reaching out if there was interest in helping bring this to windows.
Is there any known work that an interested dev like myself could pitch in on? Or is bringing this to Windows still such an unknown that the best way to be helpful is to just fiddle around with it myself and see what it takes to get things running on Windows?