Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I stop gcc under Cygwin from adding ".exe" to compiled executables?

Tags:

c

gcc

cygwin

I would like to know how I can prevent gcc under Cygwin from automatically adding the .exe extension to compiled files, because I just caused myself a lot of confusion with "missing files". For context, I am working on a C project for university and I usually work in the labs which run Ubuntu (dual-boot with Windows), but to work from home I prefer using my Windows machine, ergo Cygwin. If I just remove the extension it still works just fine on either system, but it is rather frustrating to have to change the command to include the extension whenever I've just compiled it under Cygwin.

I looked up the FAQ from Cygwin to find that it is probably an issue related to an environment variable in .bashrc or .bash_profile (see here), but I am no command-line ninja and am not very familiar with editing configuration files... I found two related questions as well that show the same behaviour, but have nothing to do with trying to change it:

Compiling with gcc (cygwin on windows)

Executable file generated using gcc under cygwin

Any ideas?

It is actually for an MPI in C project so I have a Makefile that calls mpicc but that is not really relevant to the problem, since I just tried with gcc as well and both do the same thing. For the purpose of this question, the commands and outputs I get are:

$ gcc -o hello hello.c
$ ls
hello.c    hello.exe
$./hello
Hello, world!
$./hello.exe
Hello, world!

Note that running with or without the extension does the same thing in the shell, but it does not with mpirun which is why I want to change this behaviour.

I eventually decided that Windows is not the programming environment for me. From now on all work that can be done in Linux will be.

like image 913
CrystalDuck Avatar asked May 13 '13 13:05

CrystalDuck


1 Answers

7 years and no one to tell ?

My answer : Yes it's possible to produce an executable without .exe extension under Cygwin GCC. By telling the linker how to name its output.

$ echo -e "#include <stdio.h>\nint main(int nbargs, char *args[]) {
  printf(\"Hello \\\n\");
  }" | gcc -pipe  -x c - -Wl,-oess2

This will produce an ess PE32 / PE32+ executable file, not a ess.exe. The -pipe option instructs the GCC build chain to not write temporary files but use pipe between stages instead. The -Wl,-o option inhibits the default --force-exe-suffix.

And this way you can really nullify Cygwin GCC output with -Wl,-o/dev/null, the linker will fail when trying to close the output but you can trap the error message. If you get it, you can be assured that GCC reaches the link stage far enough to produce an output, which means that GCC can build an executable with this code.

From the ld man page :

--noinhibit-exec Retain the executable output file whenever it is still usable. Normally, the linker will not produce an output file if it encounters errors during the link process; it exits without writing an output file when it issues any error whatsoever.

DO NOT USE -Wl,-o/dev/stdout under Cygwin. Under Cygwin, /dev/stdout is a symlink, and if the linker fails it will DELETE /dev/stdout.

On the other end, -Wl,-o/proc/self/fd/1 will do no harm, but the linker will fail and will produce only an error message on stdout. Currently, it seems there is no direct way under Cygwin to pipe the linker output, even with named pipes.

like image 142
Zilog80 Avatar answered Sep 19 '22 16:09

Zilog80