Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does calling make with a shell script target create an executable file?

I had written a simple shell script (called test.sh) to compile a test C++ file using two different compilers (g++ and clang++) and put some echo statements in to compare the output. On the command line, I accidentally typed make test, even though there was no Makefile in that directory. Instead of complaining about no Makefile or no target defined, it executed the following commands (my system is running the 64-bit Debian stretch OS with GNU Make 4.1 ):

user@hostname test_dir$ make test
cat test.sh >test
chmod a+x test
user@hostname test_dir$

Curious about that, I made another shell script (other.sh) and did the same thing.

Here is my other.sh file:

#!/bin/bash

echo ""
echo "This is another test script!"
echo ""

Command line:

user@hostname test_dir$ make other
cat other.sh >other
chmod a+x other
user@hostname test_dir$

My question is why does make automatically create an executable script (without the .sh extension) when running the make command in the terminal? Is this normal/expected/standard behavior? Can I rely on this behavior on all Linux machines?


Side question/note: Is there a list of supported "implicit suffixes" for which make will automatically create an executable?

like image 677
callyalater Avatar asked Apr 06 '17 19:04

callyalater


People also ask

Is a shell script an executable?

Shell scripts must be executable files in order to run. You can use the chmod command to indicate that the text file is executable (that is, its contents can be run as a shell script).

Which command will make a script an executable file?

Use chmod to make a script an executable program.

Does a bash script need to be executable?

Prerequisites. Before being able to run your script, you need your script to be executable. In order to make a script executable on Linux, use the “chmod” command and assign “execute” permissions to the file. You can either use the binary or the symbolic notation in order to make it executable.


2 Answers

This is one of a number of "implicit rules" which are built into Gnu make. (Every make implementation will have some implicit rules, but there is no guarantee that they are the same.)

  1. Why does make automatically create an executable script without the .sh extension?

There is an old source repository system called Source Code Control System (SCCS). Although it no longer has much use, it was once the most common way of maintaining source code repositories. It had the quirk that it did not preserve file permissions, so if you kept an (executable) shell script in SCCS and later checked it out, it would no longer be executable. Gnu make could automatically extract files from an SCCS repository; to compensate for the disappearing executable permission issue, it was common to use the .sh extension with shell scripts; make could then do a two-step extraction, where it first extracted foo.sh from the repository and then copied it to foo, adding the executable permission.

  1. Is this normal/expected/standard behavior? Can I rely on this behavior on all Linux machines?

Linux systems with a development toolset installed tend to use Gnu make, so you should be able to count on this behaviour on Linux systems used for development.

BSD make also comes with a default rule for .sh, but it only copies the file; it doesn't change permissions (at least on the bsdmake distribution on my machine). So the behaviour is not universal.

  1. Is there a list of supported "implicit suffixes" for which make will automatically create an executable?

Yes, there is. You'll find it in the make manual:

The default suffix list is: .out, .a, .ln, .o, .c, .cc, .C, .cpp, .p, .f, .F, .m, .r, .y, .l, .ym, .lm, .s, .S, .mod, .sym, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch, .web, .sh, .elc, .el.

For a more accurate list of implicit rules, you can use the command

make -p -f/dev/null
# or, if you like typing, make --print-data-base -f /dev/null 

as described in the make options summary.

like image 144
rici Avatar answered Nov 15 '22 01:11

rici


From the make man page:

The purpose of the make utility is to determine automatically which pieces of a large program need to be recompiled, and issue the commands to recompile them. The manual describes the GNU implementation of make, which was written by Richard Stallman and Roland McGrath, and is currently maintained by Paul Smith. Our examples show C programs, since they are most common, but you can use make with any programming language whose compiler can be run with a shell command. In fact, make is not limited to programs. You can use it to describe any task where some files must be updated automatically from others whenever the others change.

make really is more than most people make it out to be...

like image 23
l'L'l Avatar answered Nov 15 '22 00:11

l'L'l