20

I am using Cygwin and have GCC (version 4.3.4 20090804 (release) 1 ) installed as Cygwin package.

When I built C code using GCC under Cygwin shell, the generated executable output file is a executable of type (PE32 executable for MS Windows (console) Intel 80386 32-bit) and it can only be executed/run under Cygwin shell, not as standalone .exe on Windows shell/command prompt. If I try to run it standalone on Windows command prompt it gives an error window saying "The program can't run because cygwin.dll is missing from your computer".

  1. How can one make this .exe standalone, which can be executed on a command prompt of any other system or even in my own system?

  2. I thought GCC under Cygwin would build a Linux executable (ELF 32-bit LSB executable), but it's not so. How can I use the gcc-cygwin combination to generate a *.out kind of Linux executable file?

  3. Also, I cannot run a Linux executable generated on a Linux-gcc combination to execute under Cygwin.

Any pointers would be helpful.

alex
  • 6,818
  • 9
  • 52
  • 103
goldenmean
  • 18,376
  • 54
  • 154
  • 211

5 Answers5

16

Despite widespread rumours, Cygwin is not a Linux emulator, i.e. it doesn't produce or run Linux executables. For that you'll need a virtual machine or coLinux.

Instead, Cygwin is a compatibility layer, which aims to implement as much as possible of the POSIX and Linux APIs within Windows. This means that programs have to be compiled specifically for Cygwin, but it also means that it's better integrated with Windows, e.g. it lets you mix POSIX and Windows APIs in the same program.

It's the cygwin1.dll that provides that compatibility layer. If you build non-Cygwin executables using gcc-3's -mno-cygwin switch or one of the MinGW compilers, then of course you can't use any POSIX/Linux-specific APIs, and any such calls will need to be replaced with Windows equivalents.

ak2
  • 6,629
  • 31
  • 27
  • So from your reply i understand that Cygwin just provides the POSIX APIs for some function call, so the same code can be executed under windws without changes in the code. But what is that 'thing/component' called, which enables a compiler (gcc) to generate a Linux specific executable. In other words, Can a gcc compiler on linux system be able to generate a windows executable which can be run on Windows system, by giving some options to gcc? – goldenmean Nov 10 '10 at 13:41
  • Building a Windows executable on Linux requires a cross compiler. In other words, you need to invoke a different compiler; options won't do. Some Linux distributions have MinGW packages, whereby the actual gcc is called i686-pc-mingw32-gcc or some such. But again, if your program uses POSIX/Linux functions, you won't be able to build it with a MinGW compiler without changes. Cross compilers for building Cygwin programs on Linux also exist, but I don't think any distros ship with one. – ak2 Nov 10 '10 at 13:47
14

Cygwin is an emulation layer. It allows UNIX code to run on Windows, if you compile it to use the emulation layer. To Windows it looks like any normal DLL and makes OS calls as normal. But when you compile against it, it shows the same functions as UNIX (well, POSIX technically, but UNIX it is)

1) When you build with cygwin, it automatically brings in this cygwin1.dll. This is the code that you need to make it look like UNIX. There are flags to make it not use this cygwin dll, meaning ignore the UNIX stuff and use native Windows calls. the -mno-cygwin flag will make the binary a native Windows binary, not using cygwin emulation. As others have said, you also need the -mwindows to make actual GUI apps using cygwin gcc.

2) To compile on one platform to run on another platform, you need what's called a cross compiler. You also need the libraries and headers for the other system. For what you want you'd need a cygwin-Linux cross compiler, Linux headers and libraries. It would probably be much easier to run Linux in a virtual machine than to set this up.

3) Remember that Cygwin just looks like UNIX to UNIX source code, not to Linux binaries. Once you compile things, the function calls are windows DLL calls. A cygwin program is still a Windows program (which is why you need a Windows style DLL to run it). Cygwin provides code for UNIX functions/system calls such as fork(), but even the method of calling them is now different. fork() now calls into a Windows DLL, not into a Linux kernel. It's still a very different system.

Rich Homolka
  • 1,805
  • 2
  • 13
  • 13
4

Not a complete answer, but I think I am able to give some pointers.

1) http://www.cygwin.com/cygwin-ug-net/programming.html says you should use -mswindows parameter. Take a look of MinGW.

2) You need a cross gcc to do this. By default cygwin gcc produces binaries linked against cygwin.dll.

3) That it because it is a linux binary. Easiest way is to recompile software in cygwin.

Ahe
  • 2,124
  • 3
  • 19
  • 29
4

ad 1) There are currently three different mingw cross-compilers available for cygwin:
The old gcc3 -mno-cygwin is deprecated.
There are new mingw64 cross-compilers for 32 bit (mingw64-i686-gcc) and 64 bit windows targets (mingw64-x86_64-gcc).
There's no mingw-i686-gcc matching the official cygwin gcc4 compiler yet.

ad 2) There's no linux cross-compiler as cygwin package yet available. But people report success building such a cross-compiler by themselves.

ad 3) There's no cygwin cross-compiler as linux package available, but many mingw cross-compilers. Those mingw executables can also be executed under cygwin, though they cannot use cygwin features, just the simple windows runtime.

Correcting errors in others people posts:
-mswindows is not valid, -mwindows tells the linker to generate a GUI app without console.
-mno-cygwin is only valid for the old deprecated gcc3 compiler and is not supported anymore. Don't use it. With cygwin you should use ordinary host and target triples as with every other cross-compiler.

rurban
  • 4,025
  • 24
  • 27
3

You need to have cygwin.dll in your path.

Or just use MinGW to compile native windows code without dependencies.

leppie
  • 115,091
  • 17
  • 196
  • 297
  • @leppie: Got that, thanks. So for the exe to be made independent of cygwin & To be run on some other windows system which does not have cygwin installed, i need to use MingW. Is MingW a compiler or some kind of library that my code should link in? – goldenmean Nov 10 '10 at 11:01
  • @goldenmean: You can try the `-mno-cygwin` compiler option, but I read somewhere that it was removed from the newer versions of Cygwin. – leppie Nov 10 '10 at 11:05
  • @Leppie: Yes that gcc option seems to have gone When i tried to use it gave "gcc: The -mno-cygwin flag has been removed; use a mingw-targeted cross-compiler". Thanks. So now i need to use MingW compiler under cygwin instead of gcc, is it? – goldenmean Nov 10 '10 at 11:07
  • @goldenmean: I would say yes, and it is A LOT faster than cygwin (compiling, not the output). There is also an easy to install version lately. Look for mingw-get on the downloads page. Edit: No you dont need Cygwin, MinGW has it's own shell, or you can just setup your PATH's and use it from the Windows command prompt if you do not need shell functionality. – leppie Nov 10 '10 at 11:08
  • @goldenmean: You would need cross-compilers for that. Either way, you would still have a separate executable per platform. It's not .NET or Java :) – leppie Nov 10 '10 at 11:38
  • Cygwin itself also comes with cross compilers by the MinGW-w64 project, both for generating 32-bit and 64-bit executables. Just look for mingw64 in Cygwin setup.exe. – ak2 Nov 10 '10 at 12:28
  • @goldenmain: I very much doubt that the MinGW compilers are any faster than the Cygwin ones, since essentially it's the same compiler. Where Cygwin is slow is when forking processes, which is particularly noticeable in configure scripts. But that's much the same with MinGW's MSYS, which is based on an old Cygwin version. – ak2 Nov 10 '10 at 12:31
  • @ak2: Process forking is about 10 times faster in MSYS. In Cygwin, it is unbearably slow. – leppie Nov 10 '10 at 12:38
  • @leppie: Well, using ye olde `while true; do date; done | uniq -c` on my XP system, I get about 45 forks per second for Cygwin, and 70 for MSYS. Of course latest Cygwin does a lot more with regards to POSIX/Linux compatibility than MSYS, so it's got an excuse. Where did you see the 10x difference? – ak2 Nov 10 '10 at 13:17
  • @ak2: It was more of thumbsucked number, based on how long ./configure normally takes. – leppie Nov 10 '10 at 15:34
  • @ak2: I get 13 vs 50. Stock i7 860. Win 7 32bit. – leppie Nov 10 '10 at 15:39
  • @ak2: In a Linux VM I get ~725 :| – leppie Nov 10 '10 at 15:41
  • @leppie 9 vs 24 on a Win7x64 system here. Not good at all, but still some way from 10x, which of course can't be said vis-a-vis Linux. The basic problem here is that Windows processes simply weren't designed for forking, so for example the copy-on-write approach can't be used with them. – ak2 Nov 10 '10 at 21:05
  • Sample static compile of GUI windows app: `i686-pc-mingw32-g++ -static -mwindows -o A.exe A.cc` – maxpolk May 31 '13 at 16:59
  • This answer made more sense to me. I used Code::Blocks to get the end result. not what I wanted to do, but it worked. If I had a standalone MinGW install, it would work. – FilBot3 May 15 '15 at 01:49