The Makefile is a scripting language for compiling C/C ++, so you need to know its rules.

  1. Grammar rules
  2. What does @ $^ etc mean
  3. @ -What does it mean?
  4. Part of the API, eg: subpath addfix
  5. ? = : =, etc
  6. . The meaning of phony
  7. Execute the make process

The following source code, put on my Github, there is a need to be able to view above

Grammar rules

Grammar:

Target: dependencies< TAB > Execution itemCopy the code

Example:

say_hello:
        @echo "Hello World"
generate:say_hello
        @echo "Creating empty text files..."touch file-{1.. 10}.txtclean:
        @echo "Cleaning up..."
        rm *.txt
Copy the code

Execute the process

The first target is executed by default

This can be modified by using.default_goal := generate

Or all: say_hello generate

variable

# Declare variables
a = 1
b := 1
# Use variables
echo ${a} 
echo $(a)
Copy the code

Logic statements

conditional-directive-one
	text-if-one-is-true
else conditional-directive-two
	text-if-two-is-true
else
	text-if-one-and-two-are-false
endif

# conditional-directive is one of the following four methods
ifeq 'arg1' 'arg2' # Both of these are acceptable with and without parentheses
ifneq (arg1, arg2) 

ifdef variable-name # Determine whether a value has a value
ifndef variable-name
Copy the code

If you want to write conditional statements in the target, use the condition judgment of shell syntax. The only difference is that you have to put a semicolon on each line. Look here

eg:

 # is not in the target item
 ifeq ("x${x}"."x")
     @echo "judge success"
 endif
 
 t2:
 	< span style = "font-size: 14px;"
     if [ x = x"${xx}"]; then \ @echo"same"; \ 
     else \
         @echo "different"; \
     fi
Copy the code

$< $@ $^What do you mean wait

$@ : The name of the target

$^ : all the names of the dependencies

$< : The first name of the dependency

$? : Constructs the updated files in the list of required files

%: %.o
        @echo "Checking.."
        ${CC} ${LINKERFLAG} $< -o $@
Copy the code

% indicates % can match any target name

Assuming a target is: foo, the above example is translated as

foo: foo.o
        @echo "Checking.."
        gcc -lm foo.o -o foo
Copy the code

@ -What does it mean?

@ indicates that the command to be executed will not be printed

– Indicates that the execution continues even if an error occurs

t1:
    @echo hello # will not print the statement, only the result
    -mkdir test # If it cannot be created, an error will be reported
t2:
    echo hello # prints not only the statement, but also the result
    mkdir test # If it cannot be created, an error will be reported and the operation will stop
Copy the code

= : =The difference between

= indicates when the defined variable is used

:= indicates to expand immediately, do not wait until use to expand

Eg:

FOO = $(BAR) When used, it will determine where the value of BAR is. If it is found, it will assign the value
BAR = bar

CC = gcc
CC = ${CC} # This place causes an infinite loop and a stack overflow

all:
    @echo ${CC}
Copy the code

and

FOO := $(BAR) # Immediate assignment, which is null
BAR = bar

CC := gcc
CC := ${CC}

all:
    @echo ${CC}
Copy the code

.phonyThe meaning of

.phony, pseudo target item, whether or not there is a file with the same name

Make: ‘XXX’ is up to date: make: ‘XXX’ is up to date: make: ‘XXX’ is up to date

If you add.phony, the target item of the Makefile must be executed

Common functions, part OF the API

${function arguments}
# or
$(function arguments)
Copy the code

$(subst The string to be replaced, the string to be replaced, the string to be processed)

$(subst from**,to,text)**

$(patsubst pattern**,replacement,var)** Can be replaced by pattern matching

$(var:pattern=replacement

$(the file wildcard looked for) :

$(Wildcard pattern**)** Searches for patterns

$(abspath names * *…). ** Absolute path

* *, $(addprefix prefix names…). ** Adds a prefix

$(addsuffix suffix * *, names…). ** indicates the suffix

$(foreach var,list,text **)

dirs := a b c d
files := $(foreach dir,$(dirs),$(wildcard $(dir)/*))
Copy the code
$(LOCAL_SRC_FILES). CPP is replaced with.o and $(OUT_OBJ_DIR)/ is prefixed
LOCAL_OBJ_FILES = $( addprefix $(OUT_OBJ_DIR)/,$(LOCAL_SRC_FILES)) LOCAL_DEP_FILES = $(patsubst %.o,%.o.d,$(LOCAL_OBJ_FILES)Copy the code

Experience:

If the statements are executed in sequence, you can use this command. If not on the same line, you need to use \ for concatenation

t1:
	cd t1; \
	-mkdir t2 # to enter the t1 folder and create the T2 folder
	
Copy the code

FAQ

六四事件() the difference between **

This problem can be viewed here. The general idea is that there is no difference in make, only when the makefile is passed to make. () means that what’s in () will be executed in the shell first, and then we can use the return value

You can create a new Makefile with a target that looks like this: then you’ll notice the difference

all: 
     @echo ${pwd}
     @echo $${pwd}@echo $(pwd) @echo ? (pwd)# Only this will be executed
     @echo $(shell pwd) # is a command that uses the shell
Copy the code

reference

make file

The makefile website

Hey, follow a wave of wechat public accounts