41

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++).

  • 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 Nov 23 '16 at 21:48
  • 1
    @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 Nov 24 '16 at 5:49
  • @Ho1 : The robot might ask, Which cake you want to have sir ? :) :D – Thushi Jan 4 '17 at 8:17
68

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

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.)

  • 2
    I thought so, but POSIX specifies them too! – Stephen Kitt Nov 22 '16 at 18:47
  • 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... – Stephen Kitt Nov 22 '16 at 21:39
  • 4
    @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 Nov 23 '16 at 1:07
  • 3
    @jamesqf CPP still invokes the preprocessor (cc -E typically); the C++ compiler is CXX. – Stephen Kitt Nov 23 '16 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. – Stephen Kitt Nov 23 '16 at 10:47

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.