make - command execution utility that processes a file containing rules to take specified actions based on time-stamps of specified files.

See :


make - commonly used to compile many the code file of a projects without redundantly compiling files that are in acceptable shape.

make by default, uses the makefile found in the directory from which it is called.

Options :


make rule structure

The rules are composed of :

  • Run by simply issuing the make command.

  • Rules stored in a file called makefile unless the -f option used.

  • Stored in directory where target is being made.

  • Rules test prerequisites in current directory unless path info included.


    The makefile rule structure

    target: [prerequisite] [prerequisite] [\]
        [prerequisite] ...
    [<tab>recipe]
    [<tab>recipe]
    ...
    
    
    
    target:
    
    • target name followed by colon (no space) and optional list of space separated prerequisites.
    • target usually a file being made.
    • But can be a pseudo-target, will trigger prerequisites to be evaluated and recipes run every time because target itself may not exist.
    • target and prerequisites may have path info.
    • target may have no prerequisites.
      • Usually the most primitive (lowest level) file/action.
      • Or if not listed as a prerequisite of another rule, meant to be invoked directly from command line.
          make special-rule
      • Used for special purposes such as cleanup or special prep.
    Prerequisite[s]
    • List of files or dependent rules needed to complete target.
    • appears on same line as target following the colon.
    • Prerequisite must have a rule defined for it.
    • Or a file of the same name must already exist.
    • Prerequisites are time-stamp checked. If any prerequisite newer than target, recipe is run.
    • Use backslash to continue prerequisite list on following lines.
    • Blank prerequisite will cause recipe to always run.
    • Useful to run cleanup activity.
    Recipe
    • Actions to take if target is older than prerequisite.
    • Each line contains a command sequence to be run.
    • Each action line must start with a tab.
    • A recipe for a specific target can list multiple actions.

    Rule processing. Rule processing is a recursive process. Think of the rule lists as a tree structure with the 1st target at the root. make starts by examining the 1st rule unless a specific target was named when invoking make It examines the the prerequisites to see they have rules associated with them. It then examines each of those rules for prerequisites, etc. Once it has traversed to the end of a rule chain it looks to see if a prerequisite is newer than the target or the target does not exist. If so, it runs the recipe for that rule. It proceeds to work its way back up each branch and down the next until all branches are processed. If a rule other than the 1st rule is not a prerequisite of another rule, it won't run unless explicitly invoked. make clean
    
    starget: st1 st2 st3
      # Prerequisites must exist as either an actual file or a rule or both.
      # If rule but no file, 
      #   rule will always run, even if it doesn't create file.
      # If file in current directory but no rule,
      #   it will be treated as a true test condition for current rule.
      # If no file and no rule
      #   it will be treated as a make error.
      #
      # All prerequisite rules must run successfully to complete.
      #
      # make -k (keep on) will NOT override failure prerequisite rules. 
      # 
    	touch starget
    
    st1:
    	# st2b must be created externally.
      # Because there is no st1 target file, ^ this line will aways be displayed.
    
    st2: st2b st2a st2c 
    	touch st2 
      # This will run if either st2a, st2b, or st2c is newer than st2.
      #
      # st2b is not created by make, so it is assumed to be created externally.
      # If no st2b target, make will stop/fail if st2b doesn't exist 
      #   before running st2a
      #   -k (keep on) will force make to continue to evaluate the rest
      #   of prerequisites for this rule.
      #
      # Because st2c target exists but no file is created, this recipe will always 
      #   run. And because this recipe runs and touch st2, the main target's recipe
      #   also runs
    
    st2a:
    	touch st2a
      # This will only run if st2a does not exist.
    
    st2c:
    	echo "I'm not making st2c, I will always run"
      # This rule does not actually create anything
    
    st3:
    	ls -l st*
      # This will run every time.
    
    sweep:
    	rm st*
    	# remember to recreate st2b
      # this must be specifically invoked.
    
    A word on comments. # will allow embedded comments If a line begins with a tab immediately followed by # comment, the comment will be displayed when make runs the recipe lines for that target. If a line begins with # or spaces followed by #, then comments are strictly internal to the makefile.
    Variables make supports variable declarations. This can be useful where a particular aspect of the rules may change. A variable can be defined at the beginning of the make file with the current particulars and then the variable is referenced later. This allows user to change the variable assignment in one place rather than having to edit the whole make file. A variable may hold a list of strings which represent file-names. A variable may hold a a string that is a command and its options. A variable is referenced using $(varname).
    CC = gcc
    objects = pgm1.o util.o myio.o
    
    pgm1 : 
    	$(CC) -o pgm1 $(objects)
    
    
    Variables can reference other variables.
    foo = $(bar)
    bar = $(ugh)
    ugh = Huh?
    
    all:;echo $(foo)
    
    will print Huh? The variable reference, not the value is assigned to the new variable. The problem with this is that you cannot reassign a variable while referencing it. CFLAGS = $(CFLAGS) -O will start an infinite loop. The GNU version and POSIX (2012) of make supports a different flavor of variable assignment. := (GNU), ::= (POSIX) Any variable references are resolved when the new variable is created once.
    next := and a two
    start := one $(next)
    next := and a one two three
    
    The reference to $(next) when creating start is done once, the reassignment of next after does not affect start.
    makefile contents
  • explicit rules - rules as described above.
  • implicit rules - rules predefined as part of make usually based on file type, file.c, file.cc, file.p, etc. make will process the following makefile with the rule :
      statter.o:
    
    by running the following recipe : $(CC) $(CPPFLAGS) $(CFLAGS) -c make has a fairly broad collection of pre-defined (implicit) rules.
  • directives make can be directed to run other makefiles.
  • conditional execution. make may use an if-else construct to conditionally execute a recipe based on something besides the time stamp.
    
    bs_for_gcc = -lgnu
    normal_libs =
    
    foo: $(objects)
    ifeq ($(CC),gcc)
            $(CC) -o foo $(objects) $(libs_for_gcc)
    else
            $(CC) -o foo $(objects) $(normal_libs)
    endif
    
    source : http://www.gnu.org/software/make/manual/make.html#Conditionals