make

发布时间 2023-08-14 04:39:08作者: 七块蛋糕

  当一个工程里的某些文件需要更新,此时你想执行这个工程,那么此时make就排上用场了。使用make时需要同时有一个对应的makefile(或者Makefile),它定义了一系列需要编译,处理的任务。

make调用编译器编译一系列源代码为二进制文件。

  makefile里的基本结构是rule,其由三部分组成:target,prerequistes,recipes

1 target: prerequisites
2 <Tab> recipe

 

以下是一个例子:

# Usage:
# make        # compile all binary
# make clean  # remove ALL binaries and objects

.PHONY = all clean

CC = gcc            # compiler to use

LINKERFLAG = -lm

SRCS := $(wildcard *.c)
BINS := $(SRCS:%.c=%)

all: ${BINS}

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

%.o: %.c
    @echo "Creating object.."
    ${CC} -c $<

clean:
    @echo "Cleaning up..."
    rm -rvf *.o ${BINS}

    Lines starting with # are comments.

    Line .PHONY = all clean defines phony targets all and clean.

    Variable LINKERFLAG defines flags to be used with gcc in a recipe.

    SRCS := $(wildcard *.c): $(wildcard pattern) is one of the functions for filenames. In this case, all files with the .c extension will be stored in a variable SRCS.

    BINS := $(SRCS:%.c=%): This is called as substitution reference. In this case, if SRCS has values 'foo.c bar.c', BINS will have 'foo bar'.

    Line all: ${BINS}: The phony target all calls values in${BINS} as individual targets.

    Rule:

    %: %.o
      @echo "Checking.."
      ${CC} ${LINKERFLAG} $&lt; -o $@

Let's look at an example to understand this rule. Suppose foo is one of the values in ${BINS}. Then % will match foo(% can match any target name). Below is the rule in its expanded form:
As shown, % is replaced by foo. $< is replaced by foo.o. $< is patterned to match prerequisites and $@ matches the target. This rule will be called for every value in ${BINS}
# Usage:
# make        # compile all binary
# make clean  # remove ALL binaries and objects

.PHONY = all clean

CC = gcc            # compiler to use

LINKERFLAG = -lm

SRCS := foo.c
BINS := foo

all: foo

foo: foo.o
    @echo "Checking.."
    gcc -lm foo.o -o foo

foo.o: foo.c
    @echo "Creating object.."
    gcc -c foo.c

clean:
    @echo "Cleaning up..."
    rm -rvf foo.o foo