2011 2-25

    技术2022-05-20  51

     

    6, 自动生成依赖性

    编译器的 -M 选项,gnu compiler则要 -MM 

     

    %d: %.c

    @set -e; rm -f $@ /

    $(CC) -MM $(CPPFLAGS) $< > $@.$$$$;/

    sed 's, /($*/)/.o[ :]*,/1.o $@ : ,g' <$@.$$$ > $@; /

    rm -f $@.$$$$

     

    # $$$$ 自动生成的四位随机数

     

    ********************************************************************************

     

    WRITE COMMAND

     

    1, display the command

     

    @echo compiling module xxx

    (just print the content, not the command and the content)

     

    make -n (or --just-print)

    (This is useful to debug our makefile)

     

    2, command error

    We could add '-' before a command to ask make ignore the error returned from the command.

     

    Or, add option "-i" or "--ignore-errors"

     

    If a rule is the target of ".IGNORE", make will ignore all the errors from the command subtree.

     

    If we use "-k" or "--keep-going" option, make won't break if it meet error.

     

    3, execute make imbededly

     

    subsystem:

    cd subdir && $(MAKE)

     

    It's equal to:

    subsystem:

    $(MAKE) -C subdir

     

    4, variable export

     

    export variable

    # This is means the other makefile which is invoked by this makefile can use this variable.

     

    export

    # Export all variables of the makefile

     

    There are two variables is constantly passed to sub makefile: SHELL & MAKEFLAGES

    and of course, there is some OPTIONs could not passed to sub makefile: -C -W -f -h -o

     

    "-w" is "--print-directory" is very useful when imbededly call makefile

     

    If we use -C to start make sub makefile, -w is be defined defaultly.

    But if we defined -s "--silent", -w is always undefined.

     

    5, define command list

    e.g:

    define run-yacc

    yacc $(firstword $^)

    mv y.tab.c $@

    endef

     

    ********************************************************************************

    USING VARIABLE

     

    1, Basement of variable

    Using variable $(var) or ${var} ($$ stand for '$')

     

    2, Variable defined variable

    The difference between '=' and ':=' (hint: recursive call)

     

    nullstring :=

    space := nullstring #mark the end of the defination

     

    3, variable substitute

     

    foo := a.o b.o c.o

    bar := $(foo:.o=.c) is equal to

    静态模式-- bar := $(foo:%.o=%.c)

     

    4, +=

    += inherited from the pre-define of a variable.

    e.g:

    var := a

    var += b is equal to

    var := $(var) b

     

    var = a

    var += b is equal to

    var = $(var) b

     

    5, override ??

    override the variable which is defined before.

    Strongly substitute the variable setting from command line.

     

    6, define

     

    7, env

    recommend: define CFLAGS, CPPFLAGS,to compile anything in the same way.

     

    8, target based variable

    <target ...>: <variable-assignment> or

    <target ...>: override <variable-assignment>

     

    e.g:

    prog: CFLAGS = -g

    Prog: prog.o foo.o bar.o

     

    When compile prog module, -g flag will be used,

    even when compile the sub module of prog

     

    9, pattern variable

    <pattern ...>: <variable-assignment>

    <pattern ...>: override <variable-assignment>

     

    e.g:

    %.o:CFLAGS = -O

     

    ********************************************************************************

     

    CONDITION AND JUDGEING

     

    1, Key words: ifeq  else  endif ifneq

    Those keywords must be the head of a line.

     

    2, make 在读取makefile时计算条件表达式,因此在条件表达式中不能出现自动化变量

    因为自动化变量在运行时赋值。

     

    ********************************************************************************

     

    USING FUNCTION

     

    1,Grammar

    $(<funciton> <arguments>) or

    ${<funciton> <arguments>}

     

    2, string processing functions:

    subst arg1,arg2,arg3

    find substring arg1 from arg3 and substitute arg2

    e.g:

    $(subst ee,EE,feet on the street)

    fEEt on the strEEt

     

    patsubst <pattern>, <replacement>, <text>

    pattern based string substitution

    e.g:

    $(patsubst %.c,%.o,x.c.c bar.c)

    x.c.o bar.o

    the same as

    src = x.c.c bar.c

    $(src:.c=.o)

     

    override CFLAGS += $(patsubst %, -I%, $(subst :, ,$(VPATH)))

     

    strip <string>

    remove whitespace in the string from head and end.

    $(strip   a b c )

    a b c

     

    findstring <find>,<in>

    $(findstring a, a b c ) is equal to a

    $(findstring a, b c)    is equal to " "

     

    filter <pattern...>, <text>

    source := x.c b.c z.s g.h

    $(filter %c %s, $(source)) is equal to x.c b.c z.s

     

    filter-out <pattern...>, <text>

    filter-out is not filter

     

    sort <list>

    $(sort foo bar lose) -> bar foo lose

     

    word <n>, <text>

    get the nth word from the text

    $(word 2, foo bar baz) -> bar

     

    wordlist <s>, <e>, <text>

    get a word list from the sth to eth of the text

    $(wordlist 2,3,hello world is yours) -> world is

     

    words <text>

    Get the word number of text

    $(words hello world!) ->2

     

    firstword <text>

    Get the first word form the text.

    $(firstword hello world!) --> hello

     

     

    File name operation

     

    1, dir <names ...>

    $(dir src/foo.c hacks) returns src/ ./

     

    2, notdir <names ...>

    $(notdir src/foo.c hacks) returns foo.c hacks

     

    3, suffix <names ...>

    $(suffix src/foo.c hacks) returns .c

     

    4, basename <names ...>

    $(basename src/foo.c hacks) returns src/foo hacks

     

    5, addsuffix <suffix>, <names ...>

    $(addsuffix .c, foo bar) returns foo.c bar.c

     

    6, addprefix <prefix>, <names ...>

    $(addprefix src/, foo bar) returns src/foo src/bar

     

    7, join <list1>, <list2>

    $(join aaa bbb, 111 222 333) returns

    aaa111 bbb222 333

     

    8, foreach <var>, <list>, <text>

    names := a b c d

    files := $(foreach n, $(names), $(n).o) returns

    a.o b.o c.o d.o

     

    9, if <condition>, <then-part> (optional), <else-part>

     

    10, call <expression>, <parm1>, <parm2>, ...

    reverse = $(2) $(1)

    foo = $(call reverse,a,b)

    then, foo is b,a

     

    11, origin <variable>

    Tell me where the variable borns from.

    This function may return:

    undefined default file "command line" override automatic environment

     

    ifdef bletch

    ifeq "$(origin bletch)" "environment

    bletch = barf, gag, etc.

    endif

    endif

     

    12, shell

    contents := $(shell cat foo)

    files := $(shell echo *.c)

     

    --------------------------------------------------------------------------------

    CONTROL MAKE

     

    1, error <text ...>

    report an error message and break the make process.

     

    2, warning <text ...>

    report an warning message but keep going on

     

    ********************************************************************************

     

    RUNNING MAKE

     

    1, Return code

    0: return success

    1: error happend

    2: Using option '-q' and some target don't need to update.

     

    2, specified makefile "-f"

    make -f (or --file --makefile) makefilename

     

    3, specified target

    MAKECMDGOALS variable is used to save the make's terminal target.

     

    content = foo bar

    sources = $(addsuffix .c,$(content))

    ifneq ( $(MAKECMDGOALS), clean)

    include $(sources:.c=.d)

    endif

     

    the .PHONY target list:

    all

    clean

    install

    print

    tar

    dist

    TAGS

    check test

     

    4, Checking rule

    -n --just-print --dry-run --recon

    Just print the command, no matter whether the targets needs to be update. Often used to debug makefile

     

    -t --touch

    Just update the update time of targets, and do not compile the targets.

     

    -q --question

    If the target didn't exist, print an error message, else do nothing.

     

    -W <file>  --what-if=<file> --assum-new=<file> --new-file=<file>

    Just show the command path if specified file updated.

     

    5, Parameters of make

    -b or -m:

    ignore the compatibility to other versions.

     

    -B --always-make:

    Rebuild all

     

    -C <dir> --directory=<dir>

    Specify the directory of makefile to run

     

    --debug[=<options>]

    Output the debug info of make. We could specify following options:

    a: output all debug info.

    b: output basic debug info.

    v: verbose

    i: output implicit rules

    j: output the detail info like PID, return code, etc.

    m: output the info of reading, updating, executing makefile.

     

    -d

    Equal to --debug=a

     

    -e --environment-overrides

    Specify the env's value to override the value defined in makefile

     

    -f=<file> --file=<file>

    Specify the makefile to run

     

    -h --help

    Show help info.

     

    -i --ignore-errors

    Ignore errors when running a makefile

     

    -I <dir> --include-dir=<dir>

    Specify a directory to search when running makefile

     

    -j [<jobsnum>]  --jobs[=<jobsnum>]

    Specify how namy sub-shell make can invoke

     

    -k --keep-going

    Go even error happens

     

    -l <load> --load-average[=<load] --max-load[=<load>]

    Specify the load when make is running

     

    -o <file> --old-file=<file> --assume-old=<file>

    Do not update specified file, even the prerequisite file is newer than it.

     

    -p --print-data-base

     

    -r --no-builtin-rules

    Forbiden all the implicit rules.

     

    -R --no-builtin-variables

    Forbiden all the implicit rules on variable

     

    -s --silent --quiet

     

    -S --no-keep-going --stop

     

    -t --touch

     

    -v --version

     

    -w --print-directory

     

    --no-print-directory

    forbiden -w option

     

    --warn-undefined-variables

     

    ********************************************************************************

    IMPLICIT RULE

     

    1, Pattern Rule Introduction

    <target pattern>: <prerequist pattern>

    command list

     

    <target pattern>: <prerequist pattern>; command list

     

    e.g:

    %.o: %.c

    $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

     

    2, Auto-variable

     

    $@ target files

     

    $% target files only when the target is a library file

     

    $< the first prerequisit file

     

    $? all the prerequisit files which is newer than target, seperated by whitespace

     

    $^ all the prerequisit files, seperated by whitespace, and remove the repeated file name

     

    $+ like $^,but don't remove the repeated file name.

     

    $* The pattern part of the target string.

     

    D: directory F: file

    e.g:

    if $(@) is bin/run.exe

    $(@F) is run.exe

    $(@D) is bin/

     

     


    最新回复(0)