42

I was using a Makefile from the book "Advanced Linux Programming (2001)" [code]. It was strange for me to see that GNU make does compile the code correctly, without even specifying a compiler in the Makefile. It's like baking without any recipe!

This is a minimal version of the code:

test.c

int main(){}

Makefile

all:            test

and make really works! This is the command it executes:

cc     test.c   -o test

I couldn't find anything useful in the documentation. How this is possible?


P.S. One additional note: Even the language is not specified; Because test.c is available, GNU make uses cc. If there exists test.cpp or test.cc (when there is no test.c), it uses g++ (and not c++).

3
  • 4
    "It's like baking without any recipe!" A recipe would tell you to boil water, but not whether you should boil water using a pan on a gas stove, a pan on an induction stove, an electric kettle, or a cauldron placed on a tripod over a fire. It wouldn't even tell ou where you should get your water. This is like telling make to boil water, and using its internal rules, make will just figure out how ;)
    – Rhymoid
    Commented Nov 23, 2016 at 21:48
  • 2
    @Rhymoid It's like yelling out: I want a cake! And then a robot called make checks your fridge and finds out there's some flour available, then bakes a default cake for you from its internal recipe. :-)
    – Ho1
    Commented Nov 24, 2016 at 5:49
  • @Ho1 : The robot might ask, Which cake you want to have sir ? :) :D
    – Thushi
    Commented Jan 4, 2017 at 8:17

1 Answer 1

70

Make does this using its built-in rules. These tell it in particular how to compile C code and how to link single-object programs.

You actually don't even need a Makefile:

make test

would work without one.

To see the hidden rules that make all of this possible, use the -p option with no Makefile:

make -p -f /dev/null

The -r option disables these built-in rules.

As pointed out by alephzero, Make has had built-in rules for a very long time (if not always); Stuart Feldman's first version in Unix V7 defines them in files.c, and his 1979 paper mentions them. They're also part of the POSIX specification. (This doesn't mean that all implementations of Make support them — the old Borland Make for DOS doesn't, at least up to version 3.0.)

20
  • 5
    @KingZoingo Make is in effect an inference engine of sorts: it has a set of rules (built-in and from the Makefile), existing artifacts (files in the current directory or named in the Makefile), and requested artifacts (targets in the Makefile); it simply tries to match rules and existing artifacts to determine whether it can use them to obtain the requested artifacts. The built-in rules tell it test.c can be used to produce test. make -d will show you the process in detail... Commented Nov 22, 2016 at 21:39
  • 5
    @Ho1 @StephenKitt This was been in make long before GNU or POSIX were invented. The first version was written nearly 40 years ago, and there were some prototype versions built from shell scripts even before that.
    – alephzero
    Commented Nov 23, 2016 at 1:07
  • 3
    @jamesqf CPP still invokes the preprocessor (cc -E typically); the C++ compiler is CXX. Commented Nov 23, 2016 at 5:22
  • 3
    @Ho1 CXX in this context is the Make variable, not a command — $(CXX) in a Makefile will be replaced by a command to run a C++ compiler. Commented Nov 23, 2016 at 10:47
  • 2
    make cares about extensions on Unix. make (and cc) is probably the main reason to actually care about extensions, in fact, since pattern rules are easier to use than writing the same rule for every source file. Commented Nov 24, 2016 at 3:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .