简体   繁体   中英

Good alternatives to Cygwin? - Cygwin doesn't support natively support Win32 apps

Update 1/9/2014: TL;DR version: Go to bottom of this post for a way to get Cygwin to be able to call non-Cygwin programs.

After having spent the time to make some bash scripts that happen to be of significant size, newer versions of Cygwin have broken them. These scripts call into native Win32 applications that don't link with Cygwin, which is apparently not officially supported by Cygwin.

This has come as a surprise to me, as for years I was under the impression that Cygwin could be used in a more mixed environment that combines both native non-Cygwin Win32 apps, and POSIX programs using the Cygwin compatibility layer. But apparently only the POSIX compatibility layer is really supported, and if native Win32 non-Cygwin apps work then it is considered a happy coincidence.

I found this out from an incompatibility I ran into with running programs compiled against the .NET Framework from within Cygwin. This used to work fine, but was broken a few months ago. Specifically, standard output from a .NET program that is piped to any other Win32 program's standard input will generally cause the receiving Win32 program to get a premature end-of-file signal because Cygwin recently switched to message pipes from byte pipes a few months ago - and message pipes appear to be incompatible with any receiving app using Visual C++ or .NET Framework. This is because .NET issues a null write to the standard output, which is only passed on to the receiving app if a message pipe is used. The receiving app successfully reads zero bytes, so thinks it is end-of-file. The project lead doesn't appear to consider this to be a real problem, since they apparently don't really support running non-Cygwin programs from within Cygwin (surprise!).

To quote the project lead Christopher Faylor from multiple e-mails on the mailing list:

What you are seeing may be because Cygwin was changed to use message-type pipes a couple of revisions ago. This is not going to change. The change was adopted to fix a problem with Cygwin programs and those are obviously our #1 priority.

Regardless of how many people use Visual C++ or .NET they are really not our target audience. It's nice when things work for people who don't want to use UNIX tools but they are not our primary focus. Fixing problems for people who want to use non-Cygwin stuff is not something that I find a high priority.

From pipe.cc: Note that the write side of the pipe is opened as PIPE_TYPE_MESSAGE. This seems to more closely mimic Linux pipe behavior and is definitely required for pty handling since fhandler_pty_master writes to the pipe in chunks, terminated by newline when CANON mode is specified.

The above comment shows an "and" relationship here. Message type pipes more closely mimic Linux (UNIX) pipe behavior AND are definitely required for ptys.

I agree with James that the runtimes are probably buggy BUT I also agree that cygwin should be able to have a handle these scenarios.

Your complete agreement with each other is not going to have much effect. Cygwin source code is not changed by voting.

Even if this one issue is ultimately fixed somehow - who knows - they might break something else in 3 months and not care to fix the regression. They might consider a patch, but it would take me quite awhile to figure out something that works. I think my time is better spent elsewhere, because it's clear that they are quite willing to break compatibility with native Win32 apps and don't want to waste more time on getting Win32 apps to work. So I guess Cygwin shouldn't be considered a stable platform for mixed Win32/Cygwin environments - what are my alternatives? Where should I start that would avoid a complete rewrite into something other than bash? I don't use more than the base Cygwin installation + some basic perl scripts.

UPDATE: After the posting of this original question, they did eventually a new pipe_byte flag in the CYGWIN environment variable: look at the documentation. If this flag is set, it will fix the problem discussed above. When invoking a non-Cygwin Win32 program, always make sure that the pipe_byte flag is set.

However, I have since uncovered an incompatibility with .NET Framework 4.0 and Cygwin. Previous versions of .NET Framework don't have this issue. I mentioned the issue first on the Cygwin mailing list here:

Pipe syncronization and incompatibility between Cygwin and .NET Framework 4.0

Getting no fruitful responses, I investigated further and found that Cygwin is creating overlapped pipes, which causes the problem. Note that trying to use non-overlapped Win32 API calls with an overlapped pipe is undefined, and most (all?) Win32 non-Cygwin programs don't use overlapped I/O with their standard file handles. I submitted a patch that creates a pipe_nooverlap flag in the CYGWIN environment variable that prevents this from happening:

Patch to optionally disable overlapped pipes

Unfortunately, they have rejected the patch, so you'll never see this in the main Cygwin DLL:

Re: Patch to optionally disable overlapped pipes

The reasoning for rejecting the patch:

  1. It was implied that I broke the signal implementation in Cygwin; I have not found this to be the case, as signals still use overlapped pipes.
  2. They don't feel like adding an environment variable flag, even though it is apparently fixing problems.
  3. They don't want to support code that even has the option of having non-overlapped pipes.

With reasoning and attitudes like this, I'm afraid I can't think of any way to change the patch to suit their requirements... they seem determined to forbid non-overlapped pipes from ever being used. I have been using the patch for awhile now, and have not had any problems with it. Also, I can't think of any situations that the pipe_nooverlap flag will break (see my follow-up e-mail on their mailing list), but I left it as a flag just in case there is trouble.

So, if you want to call non-Cygwin Win32 or .NET Framework programs from Cygwin, you need to do the following:

  1. Apply my patch to the source of whatever Cygwin version you are using. Do not expect this patch to show up in future Cygwin versions.
  2. Set the pipe_byte and pipe_nooverlap flags in the CYGWIN environment variable.

This works... for now!!! I post this in case it helps anyone else who still wants to use Cygwin for some things.

The best alternative I found is Gow (Gnu On Windows) .

It's a lightweight alternative to Cygwin, about 10 times lighter. As far as I know the 130 tools installed with Gow are regular Win32 applications.

2016 Answer


I built Cash this year, a cross-platform implementation of Linux commands running on Node.js .

This supports both global installations of each command in your path , or an interactive shell with full support for bash-like syntax, command piping, autocompletion and history.

This additionally runs win32 apps within the shell.

MSYS

There may be fewer "supported" packages, in that you have to install things by hand, but there won't be:

  • Path issues ( cygpath is a non-solution, as you can't always shove it in)
  • Programs confused by cygwin packages reporting their OS as 'cygwin'
  • .dll/.so/.lib/.a confusion

And there is much better interop with windows applications.

Cygnal is my project to create a modified Cygwin, serving as a run-time support library for applications intended to run as native Windows programs, following external conventions familiar to Windows users.

The idea is that you can use the full Cygwin environment to develop, using its default toolchain: the same compiler that makes Cygwin executables. Then you can deploy your program as a Cygnal program by bundling it with the modified cygwin1.dll from the Cygnal project.

This is especially useful for programs that have a lot of POSIX dependencies and need a decently feature-rich, good quality POSIX implementation.

The project lead doesn't appear to consider this to be a real problem, since they apparently don't really support running non-Cygwin programs from within Cygwin (surprise!).

By contrast, in the Cygnal project, this sort of thing is considered an issue for which a reasonable solution will be merged.

I used to use cygwin mainly for the X11 server feature. It was useful to run any tools on a remote server and export the display to local cygwin. I find that I can achieve the same thing using Xming server which is a lot lighter.

2022 answer


This is the simplest and most lightweight method to get Linux commands on Windows.

  1. Install the command-line installer for Windows scoop.sh

  2. Install busybox using scoop

    scoop install busybox

You now have access to a ton of Linux commands. The commands are available across different terminals, for example cmd, Tabby, Hyper or some other terminal.

Example of using Linux commands on Tabby and cmd:

在此处输入图像描述

Some of the available commands:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM