views:

430

answers:

6

Mostly for my amusement, I created a makefile in my $HOME/bin directory called rebuild.mk, and made it executable, and the first lines of the file read:

#!/bin/make -f
#
# Comments on what the makefile is for

...

all: ${SCRIPTS} ${LINKS} ...

...

I can now type:

rebuild.mk

and this causes make to execute.

What are the reasons for not exploiting this on a permanent basis, other than this:

  • The makefile is tied to a single directory, so it really isn't appropriate in my main bin directory.

Has anyone ever seen the trick exploited before?


Collecting some comments, and providing a bit more background information.

  1. Norman Ramsey reports that this technique is used in Debian; that is interesting to know. Thank you.
  2. I agree that typing 'make' is more idiomatic.
  3. However, the scenario (previously unstated) is that my $HOME/bin directory already has a cross-platform main makefile in it that is the primary maintenance tool for the 500+ commands in the directory.
  4. However, on one particular machine (only), I wanted to add a makefile for building a special set of tools. So, those tools get a special makefile, which I called rebuild.mk for this question (it has another name on my machine).
  5. I do get to save typing 'make -f rebuild.mk' by using 'rebuild.mk' instead.
  6. Fixing the position of the make utility is problematic across platforms.
  7. The #!/usr/bin/env make -f technique is likely to work, though I believe the official rules of engagement are that the line must be less than 32 characters and may only have one argument to the command.
  8. @dF comments that the technique might prevent you passing arguments to make. That is not a problem on my Solaris machine, at any rate. The three different versions of 'make' I tested (Sun, GNU, mine) all got the extra command line arguments that I type, including options ('-u' on my home-brew version) and targets 'someprogram' and macros CC='cc' WFLAGS=-v (to use a different compiler and cancel the GCC warning flags which the Sun compiler does not understand).

I would not advocate this as a general technique.

As stated, it was mostly for my amusement. I may keep it for this particular job; it is most unlikely that I'd use it in distributed work. And if I did, I'd supply and apply a 'fixin' script to fix the pathname of the interpreter; indeed, I did that already on my machine. That script is a relic from the first edition of the Camel book ('Programming Perl' by Larry Wall).

+4  A: 

One problem with this for generally distributable Makefiles is that the location of make is not always consistent across platforms. Also, some systems might require an alternate name like gmake.

Of course one can always run the appropriate command manually, but this sort of defeats the whole purpose of making the Makefile executable.

Greg Hewgill
Exactly. On my system for example, make is in /usr/bin.
Robert Gamble
But you're still no worse off than you were to start with.
recursive
/usr/ccs/bin/make, /usr/gnu/bin/make, /usr/local/bin/make - yes...
Jonathan Leffler
A: 

The reason I would not do this is that typing "make" is more idiomatic to building Makefile based projects. Imagine if every project you built you had to search for the differently named makefile someone created instead of just typing "make && make install".

grepsedawk
The usecase for this would probably not be so much a new command for building projects, rather looking at make as yet another language for writing scripts. I can see myself using make instead of bash, if my script contains a lot of if [ file.x -nt -file.y ].
Rolf Rander
Also, in my particular scenario, I have a cross-platform main makefile already in the directory, and I wanted a separate one for the particular machine and particular set of commands - hence rebuild.mk.
Jonathan Leffler
But I agree - typing 'make' is more idiomatic. This just saves me typing 'make -f rebuild.mk'.
Jonathan Leffler
+1  A: 

"make" is shorter than "./Makefile", so I don't think you're buying anything.

dicroce
True: but rebuild.mk is shorter than 'make -f rebuild.mk' so I do gain something.
Jonathan Leffler
+2  A: 

To address the problem of make not always being in the same place (on my system for example it's in /usr/bin), you could use

#!/usr/bin/env make -f

if you're on a UNIX-like system.

Another problem is that by using the Makefile this way you cannot override variables, by doing, for example make CFLAGS=....

dF
This assumes that env is always in the same place...
Robert Gamble
You can override - and provide other arguments on the command line. At least, that's what my experiments show.
Jonathan Leffler
Separately, officially, you can provide one argument (not two as shown). And the whole command line string has to be under 32 characters, I believe.
Jonathan Leffler
If env isn't in that place then you're using a Linux that is inventing problems for itself.
Max Howell
+5  A: 

I've seen this trick used before in the debian/rules file that is part of every Debian package.

Norman Ramsey
Thank you - that is interesting to know!
Jonathan Leffler
A: 

You could use a shell alias for this too.

PEZ
@PEZ: yes, I could. It would be one of very, very few aliases that I have, though; I grew up before they were routinely available, and generally uses scripts instead of aliases (not least because scripts work regardless of which shell I'm using). In other words, I wouldn't use an alias for this.
Jonathan Leffler
I think a script is good for this. It's what I most often use too. I just pointed out that you *cold* use a shell alias too. Could be good to know for some of the people who Google up your question.
PEZ