Polyglot in C, Makefile and Shell Script

In replying jokingly to a post here, I wrote a polyglot in C, GNU make and shell script, The post's OP phrased the question mistakenly, it literally means, "How to code C with bash script?", thus the code.


 1 #/* \
 2 echo "hello world from shell." && make compile 2>/dev/null; exit \
 4 default:
 5         @echo hello, world from make.
 6 compile:
 7         @gcc -xc Makefile
 8         @false
 9 #*/
10 #include <stdio.h>
11         const char *what = "hello, world from c."; \
12         int main(int argc, char *argv[]) \
13         { \
14                 (void)argc; \
15                 (void)argv; \
16                 printf("%s\n", what); \
17                 return 0; \
18         }


Makefile requires hard tabs (<Tab> characters) to work, if you want to try it, you can download the original file from the 'Raw' hyperlink.

To run as Makefile

$ make
hello, world from make.

To compile and run as C source code

$ gcc -xc Makefile -o hello
$ ./hello
hello, world from c.

To run as shell script

$ sh Makefile
hello world from shell.

Since it is both a shell script and makefile, it can be used as expected. In fact, when you run this code as shell script, in addition to printing 'hello world from shell.', it invokes make, using itself as makefile, which in turn compile itself as C source code.

See it yourself:

$ sh Makefile
hello world from shell.
$ ls a.out
$ ./a.out
hello, world from c.