makefile

how do makefile dependencies work?


I am currently confused as to how makefile targets work. I have a current understanding, and I don't know if it is correct because the tutorials I've been reading aren't very clear to me. Here is my current understanding

  1. when you run 'make' in the terminal, the makefile utility finds the first target in the makefile and tries to run it, but before doing so it looks at all of the dependencies in the file
  2. (this is where I start getting confused): If the dependency is a target in the makefile, but does not exist as a file in the makefile's directory, make simply runs the target. If the dependency is a file name, but not a target in the makefile, the utility checks for the existance of the file, and if the file doesn't exist, the utility yells at you. If the dependency is a file that exists in the directory AND a target, the target is run provided that any of the files that the file-target depend on are newer than the associated file.

Do I have it down right? Is it simpler than I'm making it out to be?


Solution

  • You have it right, more or less, but it can be stated a little more clearly. You're right about how make chooses the initial target, except of course if the user specifies a specific target on the make command line then that one is used instead of the first one.

    Then make basically implements a recursive algorithm for each target, that works like this:

    1. Find a rule to build that target. If there is no rule to build the target, make fails.
    2. For each prerequisite of the target, run this algorithm with that prerequisite as the target.
    3. If either the target does not exist, or if any prerequisite's modification time is newer than the target's modification time, run the recipe associated with the target. If the recipe fails, (usually) make fails.

    That's it! Of course, this hides a number of complex issues: in particular item #1 (finding a rule) can be complex in situations where you have no explicit rule for the target. Also behaviors such as what to do when a rule fails can be modified.

    But that's the basic algorithm!