1. The introduction of a Makefile

Makefiles are used in conjunction with the make command.

Compilation on many large projects is organized through Makefiles, and without makefiles, the dependencies between libraries and code in many projects would be incredibly complex.

The ability of makefiles to organize processes is so powerful that it can be used not only to compile projects, but also to organize some of our daily operations. This requires you to use your imagination.

 

This blog post is based on {essence} and the Makefile I wrote together, with some cuts and examples added.

Many thanks to gunguymadman_cu for providing such a detailed introduction to makefiles. This is exactly what I have been looking for in Chinese for makefiles.

 

1.1 The five main parts of makefiles (display rules, hidden rules, variable definitions, file directives, comments)

The basic format of the Makefile is as follows:

target ... : prerequisites ... command ... .Copy the code

Among them,

  • Target – A target File, which can be an Object File or an executable File
  • Prerequisites – File or target that is required to generate target
  • Command-make Specifies the command to execute (any shell command). The command in the Makefile must start with [TAB]

 

  1. Display rules :: describes how to generate one or more object files (including generated files, file dependencies, generated commands)
  2. Implicit rules: Rules executed by make’s automatic derivation function
  3. Variable definitions: Variables defined in the: Makefile
  4. Other makefiles are referenced in :: makefiles; Specifies the valid part of the Makefile; Define a multi-line command
  5. Comment: The Makefile only has a line comment “#”. If you want to use or print “#” characters, you need to escape “\#”.

 

1.2 How GNU Make works

  1. Read the master Makefile (the master Makefile can reference other makefiles)
  2. Read other makefiles to be included
  3. Initialize a variable in a file
  4. Derive implicit rules and analyze all rules
  5. Create dependency chains for all object files
  6. Based on the dependencies, decide which targets to regenerate
  7. Execute build command

 

2. Makefile elementary syntax

2.1 the Makefile rules

2.1.1 Rule Syntax

Rules have two main parts: dependencies and methods for generating targets.

There are two types of syntax:

target ... : prerequisites ...
    command
    ...Copy the code

or

target ... : prerequisites ; command
    command
    ...Copy the code

* Note * Command is too long, you can use “\” as a newline

 

2.1.2 Wildcard Characters in rules

  • * :: Indicates any one or more characters
  • ? :: Indicates any character
  • […]. :: ex. [abcd] Indicates any character of a, B, C, and D. [^abcd] indicates any character of a, B, C, and D. [0-9] indicates any digit of 0 to 9
  • ~ :: indicates the user’s home directory

 

2.1.3 Path Search

When a Makefile contains a large number of source files (most likely not in the same directory as the Makefile),

In this case, it is a good idea to have the source file’s path explicitly in the Makefile for easy look-up at compile time. There is a special variable VPATH in the Makefile that does this.

If no file or dependent file is found in the current directory after the VPATH is specified, the Makefile goes back to the path specified by VPATH to look for..

VPATH:

  • Vpath

    :: When no files are found in the current directory, search through

  • Vpath
    :: Files that fit the format will be searched from
  • Vpath :: Clears the search paths for files that match the format
  • Vpath :: Clears all preset file paths

 

# Example 1 - From the SRC directory in order when files cannot be found in the current directory.. /parent-dir VPATH SRC :.. /header # example 3 - Clear rules set in Example 2. VPATH %. H # example 4 - Clear all VPATH Settings VPATHCopy the code

 

2.2 Variables in makefiles

2.2.1 Variable Definition (= OR :=)

O OBJS -add = $(OBJS) programC. O OBJS -add := $(OBJS) programC.oCopy the code

The difference between = and := is that := can only use previously defined variables, and = can use later defined variables

Test =

OBJS2 = $(OBJS1) programc. o OBJS1 = programa.o programb. o all: $make programa.o programb.o programc.o echo $(OBJS2) # bash $make programa.o programc.oCopy the code

 

Test: =

# Makefile OBJS2 := $(OBJS1) programc. o OBJS1 := programa.o programb. o all: Echo $(OBJS2) # make $(OBJS1) $make programc.oCopy the code

 

2.2.2 Variable Substitution

SRCS: = programa.c programb.c programc.c OBJS: = $(SRCS:%.c=%.o) all: @echo "SRCS: "$(SRCS) @echo "OBJS: = programa.c programb.c programc.c OBJS: = $(SRCS:%.c=%.o) all: @echo "SRCS:" $(SRCS) @echo "OBJS: $(OBJS) # bash make $make SRCS: programa.c programb.c programc.c OBJS: programa.o programb.o programc.oCopy the code

 

2.2.3 Append variable +=

SRCS: = programa.c programb.c programc.c SRCS += programd.c all: @echo "SRCS: = programa.c programb.c programc.c SRCS += programd.c all: @echo" $(SRCS) # bash make $make SRCS: programa.c programb.c programc.c programd.cCopy the code

 

2.2.4 Overriding Override variable

The Makefile allows variables defined in the Makefile to override variables specified in the make command arguments

Grammar:

  • override <variable> = <value>
  • override <variable> := <value>
  • override <variable> += <value>

 

Here’s an example of override:

SRCS: = programa.c programb.c programc.c all: @echo "SRCS: = programa.c programb.c programc.c all: @echo" $(SRCS) # bash make $make SRCS=nothing SRCS: Nothing # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Makefile content (override) override SRCS: = programA. C Programb.c programc.c all: @echo "SRCS: "$(SRCS) # make $make SRCS=nothing SRCS: programA.c programB.c programC.cCopy the code

 

2.2.5 Target variables

The effect is to limit the scope of the variable to the target, unlike the variables defined in the previous example, which are valid for the entire Makefile.

Grammar:


  • ::


  • :: override

 

Example:

SRCS: = programa.c programb.c programc.c target1: target1 -SRCS := programd.c target1: @echo "SRCS: = programd.c target1: @echo "SRCS: = programd.c target1: @echo" " $(SRCS) @echo "SRCS: " $(TARGET1-SRCS) target2: @echo "SRCS: " $(SRCS) @echo "SRCS: $make $make TARGET1 SRCS: programa.c programb.c programc.c SRCS: Programd. c $make target2 <-- target1-srcs SRCS: programa.c programb.c programc.c SRCS:Copy the code

 

2.3 Makefile command prefix

Shell commands in makefiles can be prefixed with @ and -, or without prefixes.

The differences of shell commands in the three formats are as follows:

  • Do not use the prefix :: Displays the command executed and the result of command execution. If an error occurs, the execution is stopped
  • The @ :: prefix outputs only the command execution results. If an error occurs, the command execution is stopped
  • Prefix – :: If any error occurs during command execution, ignore the error and continue to execute the command

 

Example:

# Makefile contents (without prefix) all: Echo "no prefix" cat this_file_not_exist echo "error after the command" <-- this command will not be executed # bash make $make echo "no prefix" <-- the command itself shows no prefix <-- Cat this_FILe_not_exist cat: this_FILe_not_exist: No such file or directory make: * * * [all] Error 1 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Makefile content (prefix @) all: @cat this_file_not_exist @cat this_file_not_exist @cat this_file_not_exist @cat this_file_not_exist @cat this_file_not_exist @cat this_file_not_exist @cat this_file_not_exist @cat this_file_not_exist Cat: this_file_not_exist: No such file or directory make: * * * [all] Error 1 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Makefile content (prefix -) all: -echo "no prefix" -cat this_file_not_exist -echo "error after the command" <-- this command will be executed # bash make $make echo "no prefix" <-- the command itself shows no prefix <-- The command execution result is displayed. Cat this_file_not_exist cat: this_file_NOT_exist: No such file or directory make: [all] Error 1 (ignored) echo "Command after Error" <-- Command after Error is displayed. <-- Command after Error is executedCopy the code

 

2.4 the pseudo target

A pseudo target is not a “target “, unlike a real target, which generates a target file.

A typical pseudo target is a clean pseudo target in a Makefile used to clean intermediate files during compilation. The general format is as follows:

PHONY: clean <-- that's fine, but clean: -rm -f *.o would be niceCopy the code

 

2.5 Reference other Makefiles

Syntax: include <filename> (filename can contain wildcards and paths)

Example:

# Makefile contents all: @echo "main Makefile begin" @make other-all @echo" main Makefile end" include./other/Makefile #./other/Makefile content other-all: @echo "other makefile begin" @echo "other makefile end" # bash make $ll total 20K -rw-r--r-- 1 wangyubin Wangyubin 125 Sep 23 16:13 Makefile -rw-r--r-- 1 wangyubin wangyubin 11K Sep 23 16:15 makefile.org <-- drwxr-xr-x 2 Wangyubin Wangyubin 4.0k Sep 23 16:11 Other $ll Other/total 4.0k-rw-r --r-- 1 Wangyubin wangyubin 4.0k Sep 23 16:11 Makefile $make Main Makefile begin make[1]: Entering directory `/path/to/test/makefile' other makefile begin other makefile end make[1]: Leaving directory '/path/to/test/makefileCopy the code

 

2.6 Checking Dependencies of C Files

When writing makefiles, you need to determine the dependencies of each target.

GNU provides a mechanism to see which C code files depend on so that we don’t have to open the C source code to see which C code files depend on when we write Makefile targets.

For example, the following command shows the dependencies in the kernel source virt/ KVM /kvm_main.c

$ cd virt/kvm/ $ gcc -MM kvm_main.c kvm_main.o: Kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- This can be added to the Makefile as a dependency to compile kvm_main.oCopy the code

 

2.7 make Exit code

There are three exit codes for makefiles:

  • 0 :: Indicates that the execution is successful
  • 1 :: Indicates that the make command is incorrect
  • 2 :: the “-q” option is used, and make does not update some targets

 

2.8 Specifying a Makefile to specify a specific target

When make is executed by default, GNUmake searches the current directory for the following three files: “GNUmakefile”, “makefile”, “makefile”,

Once the corresponding file is found, the first target in the file is executed. If you can’t find these 3 files, report an error.

 

By default, specific makefiles and specific targets can be specified in the make command.

Example:

# Makefile filename MyMake, content target1: @echo "target [1] begin" @echo "target [1] end" target2: @echo "target [2] begin" @echo "target [2] end" make $ls Makefile $mv Makefile MyMake $ls MyMake $make < span style = "max-width: 100%; clear: both; min-height: 1em; *** No targets specified and No makefile found.stop. $make -f MyMake <-- specify the specified makefile target [1] begin target [1] end $make -f MyMake target2 <-- target [2] begin Target [2] endCopy the code

 

2.9 This section describes make parameters

You can use make-h to check the parameters of make. Here are a few that I think are useful.

parameter

meaning

–debug[=<options>] Output make debugging information. Options can be a, B, or V
-j –jobs The number of commands to run simultaneously, i.e., multithreaded execution makefiles
-r –no-builtin-rules Do not use any implied rules
-R –no-builtin-variabes Disallow any implicit rules that apply to variables
-B –always-make Assume that all targets are updated, that is, recompile is forced

 

2.10 Implicit rules for Makefiles

I’ll just list one that’s relevant to compiling C.

When C is compiled, the target of <n>.o is automatically derived to <n>.c

O GCC -o main main.o GCC -o main main.o main. C <-- main.o This target is implicitly generated GCC -c main.cCopy the code

 

2.11 Command variables and command parameter variables in implied rules

2.11.1 Command variables that can be used when writing a Makefile directly to the shell.

Just a few of the C-related ones are listed below

The variable name

meaning

RM rm -f
AR ar
CC cc
CXX g++

Example:

All: @echo $(RM) @echo $(AR) @echo $(CC) @echo $(CXX) # make RM -f AR CC g++Copy the code

 

2.11.2 Command Parameter Variables

The variable name

meaning

ARFLAGS AR Command parameters
CFLAGS C compiler parameters
CXXFLAGS C++ compiler parameters

 

Example: The following uses CFLAGS as an example

#include <stdio.h> int main(int argc, char *argv[]) {printf ("Hello Makefile\n"); return 0; } # Makefile content test: O $(CC) -o test test.o # bash $ll total 24K -rw-r--r-- 1 wangyubin wangyubin 69 Sep 23 17:31 Makefile -rw-r--r-- 1 wangyubin wangyubin 14K Sep 23 19:51 makefile.org <-- please ignore this file. -rw-r--r-- 1 wangyubin wangyubin 392 Sep 23 17:31 test.c $make cc -c -o test.o test.c cc -o test test.o $rm -f test test.o $make CFLAGS= -wall Cc-wall -c -o test.o test.c cc -o test test.oCopy the code

 

2.12 Automatic Variables

Many times in makefiles we simplify writing by using automatic variables, each of which has the following meanings:

Automatic variables

meaning

$@ The target set
$% When the target is a function library file, represents the target file name in it
$< The first depends on the target. If there are multiple dependency targets, one by one indicates the dependency targets
$? A collection of new dependent targets than targets
$^ The set of all dependent targets removes duplicate dependent targets
+ $ The collection of all dependent targets does not remove duplicate dependent targets
$* This is specific to GNU Make and may not be supported by other Makes

 

3. Advanced Makefile syntax

3.1 nested Makefile

Methods that reference other makefiles have been mentioned in the Makefile primitives syntax. Here’s another way to write it, and you can pass parameters to other referenced makefiles.

Example: (Pass no arguments, just call Makefile in subfolder other)

/other && make @echo "main Makefile end" #./other/Makefile content other-all: @echo "other makefile begin" @echo "other makefile end" # bash make $ll total 28K -rw-r--r-- 1 wangyubin Wangyubin 109 Sep 23 20:43 Makefile -rw-r--r-- 1 wangyubin wangyubin 17K Sep 23 20:44 makefile.org <-- drwxr-xr-x 2 Wangyubin wangyubin 4.0k Sep 23 20:42 Other $ll Other/total 4.0K-rw-r --r-- 1 Wangyubin wangyubin 4.0k Sep 23 16:11 Makefile $make Main Makefile begin make[1]: Entering directory `/path/to/test/makefile/other' other makefile begin other makefile end make[1]: Brigade directory ` / path/to/test/makefile/other 'main makefile endCopy the code

 

Example: (pass parameters as export)

# Makefile export VALUE1 := export. C < VALUE2 := no-export. C <-- This variable cannot be passed to./other/Makefile all: Make @echo "Makefile end" #./other/Makefile content other-all: @echo "other makefile begin" @echo "VALUE1: " $(VALUE1) @echo "VALUE2: "$(VALUE2) @echo "other makefile end" # make $make main makefile begin make[1]: If the directory ` / path/to/test/makefile/other 'other makefile begin VALUE1: export. C < - VALUE1 transfer success VALUE2: < -- VALUE2 transmission failure other makefile end make [1] : brigade directory ` / path/to/test/makefile/other 'main makefile endCopy the code

 

* Add * export syntax format as follows:

  • export variable = value
  • export variable := value
  • export variable += value

 

3.2 Defining a Command package

A command package is a bit like a function that combines successive identical commands into one, reducing the amount of code in the Makefile for later maintenance.

Grammar:

define <command-name>
command
...
endefCopy the code

 

Example:

# Makefile contents define run-hello-makefile @echo -n "hello" @echo "Makefile!" @echo "Here can execute multiple Shell commands!" Endef all: $(run-hello-makefile) # bash make $make hello makefile! Multiple Shell commands can be executed here!Copy the code

 

3.3 Condition Judgment

The keywords of the conditional judgment mainly include ifeq ifneq ifdef ifndef

Grammar:

<conditional-directive>
<text-if-true>
endif

# 或者
<conditional-directive>
<text-if-true>
else
<text-if-false>
endifCopy the code

 

Example: IFEQ example, ifNEQ and IFEQ are used in a similar way, but inverse

# Makefile contents all: ifeq ("aa", "bb") @echo "equal" else @echo "not equal" endif # make $make not equalCopy the code

 

Example: Ifdef example, ifndef and ifdef are used in a similar way, except in reverse

# Makefile contents SRCS := program.c all: Ifdef SRCS @echo $(SRCS) else @echo "no SRCS" endif # bash make $make program.cCopy the code

 

3.4 Functions in makefiles

Makefiles come with functions that make writing makefiles easier.

The function call syntax is as follows:

$(function> <arguments>) # ${<function> <arguments>}Copy the code

  • is the function name

  • are function arguments

 

3.4.1 String functions

$(subst <from>,<to>,<text>)

Replace <from> with <to> in string <text>

Returns: replaced string

All: @echo $(subst t,e,maktfilt) <-- replace t with e #Copy the code

 

$(patsubst <pattern>,<replacement>,<text>)

Function: Find words in <text> (words are separated by “space “,” TAB “, “newline”) that match <pattern>. If so, <replacement> is used.

Returns: replaced string

All: @echo $(patsubst %.c,%.o, programa.c programb.c) # make $make programa.o programb.oCopy the code

 

$(strip <string>)

Function: Remove null characters at the beginning and end of <string> strings

Returns: string value with whitespace removed

# Makefile contents VAL := "aa bb cc" all: @echo "$(VAL) @echo" $(strip $(VAL)) # bash make $make aa bb ccCopy the code

 

$(findString <find>,<in>)

Function: Find <find> string in string <in>

Return: Returns <find> string if found, empty string otherwise

# Makefile contents VAL := "aa bb cc" all: @echo $(findString ab,$(VAL)) @echo $(findString ab,$(VAL)Copy the code

 

Filter function: $(filter <pattern… >,<text>)

Function: Filter string <text> by <pattern> pattern, * retain * words that match pattern <pattern>, there can be multiple patterns

Returns: a string that matches the pattern <pattern>

All: @echo $(filter %.o %.a,program.c program.o program.a) # make $make program.o program.aCopy the code

 

$(filter-out <pattern… >,<text>)

Function: Filter string <text> by <pattern> pattern, * remove * words that match pattern <pattern>, there can be multiple patterns

Returns: a string that does not match the pattern <pattern>

All: @echo $(filter-out %.o %.a,program.c program.o program.a) # make $make program.cCopy the code

 

$(sort <list>)

Function: Sort the words in the string <list> (ascending order)

Returns: sorted string

All: @echo $(sort bac ABC ACb cabCopy the code

 

$(word <n>,<text>)

Function: select the <n> word in the string <text> (n starts from 1)

Returns: the <n> word in <text>, or an empty string if <n> is greater than the number of words in <text>

# Makefile contents all: @echo $(word 1,aa bb cc dd) @echo $(word 5, AA bb cc dd) @echo $(word 4,aa bb cc ddCopy the code

 

$(wordlist <s>,<e>,<text>)

Fetches a string of words from <s> to <e> from the string <text>. <s> and <e> are a number.

Returns: a string from <s> to <e>

# Makefile contents all: @echo $(wordlist 1,3,aa bb cc dd) @echo $(word 5,6,aa bb cc dd) @echo $(word 2,5,aa bb cc dd) # make $make aa bb cc bbCopy the code

 

$(words <text>)

Function: Count the number of words in the string <text>

Returns: Number of words

All: @echo $(words aabbccdd) @echo $(words aabbccdd) @echo $(words) # make $make 4 1 0Copy the code

 

Firstword function: $(firstword <text>)

Function: Take the first word in the string <text>

Returns: the first word in the string <text>

# Makefile contents all: @echo $(firstword aabbccdd) @echo $(firstword aabbccdd) @echo $(firstword aabbccdd) @echo $(firstword aabbccdd) # make $make AA aabbccddCopy the code

 

3.4.2 File name function

$(dir <names… >)

Fetches the directory part from the file name sequence <names>

Returns: directory part of the file name sequence <names>

All: @echo $(dir /home/a.c. /bb.c.. Make $make /home/.. /.. / /.Copy the code

 

Fetch file function: $(notdir <names… >)

Fetches non-directory parts from file name sequence <names>

Return: the non-directory part of the file name sequence <names>

All: @echo $(notdir /home/a.c. /bb.c.. /c c d.c) # make $make a.bb. C c d.cCopy the code

 

Suffix function: $(suffix <names… >)

Function: Retrieve the suffix of each filename from the filename sequence <names>

Returns the suffix of each file name in the file name sequence <names>, or an empty string if there is no suffix

# Makefile contents all: @echo $(suffix /home/ a.c. / b.O... /c. D) # make $make. C. O. aCopy the code

 

$(basename <names… >)

Function: Retrieve the prefix of each filename from the filename sequence <names>

Returns: The prefix of each file name in the file name sequence <names>, or an empty string if there is no prefix

All: @echo $(basename /home/ a.c. / b.o... Make $make /home/ a. /b.. /c /home/Copy the code

 

Suffix function: $(addsuffix <suffix>,<names… >)

Function: Add the suffix <suffix> to each word in <names>

Returns: suffixed file name sequence

# Makefile contents all: @echo $(addsuffix.c,/home/a b. / c.o... Make $make /home/a.c.c. / C.O.C... /d.c.cCopy the code

 

$(addprefix <prefix>,<names… >)

Function: Appends the prefix <prefix> to each word in <names>

Returns: prefixed sequence of file names

# Makefile contents all: Make $make test_/home/a.c test_b.c test_./ d.c.Copy the code

 

Join function: $(join <list1>,<list2>)

Function: add corresponding words in <list2> to <list1>

Returns: the concatenated string

# Makefile contents all: Echo $(join a b c d,1 2 3 4) @echo $(join a b c d,1 2 3 4) @echo $(join a b c d,1 2 3 4) @echo $(join a b c d,1 2 3 4) @echo $(join a b c d,1 2 3 4) @echo $(join a b c d,1 2 3 4 b2 c3 d4 a1 b2 c3 d4 5 a1 b2 c3 d4 eCopy the code

 

Rule 3.4.3 foreach

Grammar:

$(foreach <var>,<list>,<text>)

 

Example:

# targets := ac d objects := $(targets),$(I).o) all: @echo $(targets) @echo $(objects) # make $make a b c d A.O.B.O.O.OCopy the code

 

3.4.4 if

Here, if is a function, unlike the previous condition, which belongs to the key of the Makefile

Grammar:

$(if <condition>,<then-part>)

$(if <condition>,<then-part>,<else-part>)

 

Example:

# Makefile contents val := a objects := $(if $(val),$(val).o,nothing) no objects := $(if $(no-val),$(val).o,nothing) all: @echo $(objects) @echo $(no-objects) # make $make a.o nothingCopy the code

 

3.4.5 Call – Creates a new parameterized function

Grammar:

$(call <expression>,<parm1>,<parm2>,<parm3>…)

 

Example:

Log # Makefile content = "= = = = the debug = = = =" $(1) "= = = = = = = = end" all: Echo $(call log," making ") # Make $Make ====debug==== making ====end====Copy the code

 

3.4.6 Origin – Determine the source of the variable

Grammar:

$(origin <variable>)

Return values are of the following types:

type

meaning

undefined <variable> is not defined
default <variable> is a default definition, such as CC variables
environment <variable> is an environment variable, and make does not use -e
file <variable> is defined in the Makefile
command line <variable> is defined on the command line
override <variable> was redefined by Override
automatic <variable> is an automation variable

 

Example:

# Makefile contents val in-file := test-file override val-override := test-file override all: @echo $(Origin not-define) # not-define @echo $(origin CC) # CC is the variable defined by default in Makefile @echo $(Origin PATH) # PATH is bash @echo $(origin val-in-file) # Echo $(origin val-in-cmd) # Echo $(origin val-in-file) # Echo $(origin val-in-cmd) # echo $(origin val-in-file) # Val-override) # Override variable @echo $(origin @) # override variable defined in this Makefile Make $make val-in-cmd=val-cmd undefined default environment file command line override automaticCopy the code

 

3.4.7 shell

Grammar:

$(shell <shell command>)

It executes a shell command and returns the result of the shell command as a function.

Same as’

‘, ‘are backquotes

 

3.4.8 Make control function

Raises a fatal error: $(error <text… >)

Function: Output an error message to stop the Makefile

All: $(error there is an error!) @echo "No execution here!" Make $make Makefile:2: *** there is an error! . Stop.Copy the code

 

$(warning <text… >)

Function: Outputs warning messages and the Makefile continues to run

All: $(warning there is an warning!) @echo "Execute here!" Make $make Makefile:2: There is an warning! This will be executed!Copy the code

 

Some GNU dummy targets in 3.5 makefiles

Make clean, make install is familiar if you’ve ever installed software on Linux from source code.

Pseudo targets like Clean and install are well known and don’t need to be explained.

Here are some common dummy targets that can be used wisely to make your own makefiles look more professional

The pseudo target

meaning

all The target of all targets, whose function is generally to compile all targets
clean Delete all files created by make
install To install a compiled program, you simply copy the target executable file into the specified directory
print List the changed source files
tar Package the source program as a backup. That’s a tar file
dist Create a zipped file, usually from a tar file to a Z file. Or gz file
TAGS Update all targets for full recompilation
The check or test Typically used to test the flow of makefiles