• makefile文件编写


    1.make命令调用格式:

    make [-f makefile文件名][选项][宏定义][目标]

    2.常用选项有:

    -Idirname 指定被包含的makefile所在目录

    -w 如果make在执行时改变目录,打印当前目录名

    -d 打印调试信息

    -k 用该选项,即使make程序遇到错误也会继续向下运行

    3.makefile文件主要包含了6部分内容

    1、显式规则:用于描述系统中模块之间的相互依赖关系,以及产生目标文件所要执行的命令(规则)。

    编写规则通用形式:

    target : dependency [depenency [...] ]

        command

        command

        [...]

    注:command前是tab键,而非空格

    使用这些命令来根据依赖模块产生目标,这里的command既可以是gcc/g++编译命令,也可以是shell命令或是其他可执行文件。

    main : main.o f1.o f2.o

        gcc -o main main.o f1.o f2.o

    main.o : main.c def1.h

        gcc -c main.c

    f1.o : f1.c def1.h def2.h

        gcc -c f1.c

    f2.o : f2.c def2.h def3.h

        gcc -c f2.c

    2、隐式规则:又称预定义规则。隐式规则简化了makefile的编写和维护。(make命令带-p选项),

    比如:后缀规则,可以指定:.SUFFIXES: .o .cpp

    .cpp.o:

        $(CPP) –c $<

    3、模式规则提供的一种扩展make隐式规则的方法,规则与普通规则一样,主要是目标必定含有%号,

    比如:%.o : %.c

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

    4、变量定义(自动变量/预定义变量/自定义变量)

    5、文件指示(include, make -I, #if include)。

    6、特殊字符:注释# 转义/ 通配符* 宿主目录~ 模式字符“%”

    “*.c”代表了当前工作目录下所有的以“.c”结尾的文件

    “%”意思是匹配一个或者多个字符,例如,“%.h”表示所有以“.h”结尾的文件

    4.变量(或者说宏)

    1、定义方法: VARNAME=some_text [...]

    如: OBJS := howdy.o helper.o

    2、变量引用:$(VARNAME)或 ${VARNAME)

    3、变量扩展:VARNAME += $(VARNAME) some_textn..

    注:在使用变量时要注意库的连接左右问题

    建议使用:VARNAME := some_textn $(VARNAME)

    4、作用:用代表某些多处使用而又可能发生变化的内容,节省重复修改的工作,避免遗漏。一般用来代表一些文件名或选项。

    5、自动变量

    $@ 规则的目标所对应的文件名

    $< 规则中的第一个相关文件名

    $^ 规则中所有相关文件的列表,以空格为分隔符

    $? 规则中日期新于目标的所有相关文件的列表

    $(@D) 目标文件的目录部分

    $(@F) 目标文件的文件名部分

    $* 这个变量表示目标模式中“%”及其之前的部分。

    6、预定义变量

    CC C编译程序,默认值=cc

    CFLAGS 传给C编译器的标志

    CPP C++编译程序,默认值=cpp

    CPPFLAGS

    LDFLAGS 传给链接程序(ld)的标志,默认值=

    AR 归档维护程序,默认值=ar

    ARFLAGS 默认值=rv

    AS 汇编程序,默认值=as

    ASFLAGS

    5.makefile实例

    1、通过g++的MM选项显示各文件间依赖关系

    gcc -MM main.c f1.c f2.c

    main.o: main.c def1.h

    f1.o: f1.c def1.h def2.h

    f2.o: f2.c def2.h def3.h

    2、多目标

    $(OBJ_DIR)%.o:$(SRC_DIR)%.cpp

        @echo "Compiling $< ==> $@..."

        $(CXX) $(INC) $(C_FLAGS) -c $< -o $@

    3、静态模式

    objects = foo.o bar.o

    all: $(objects)

    %.o: %.c

        $(gcc) -c $(CFLAGS) $< -o $@

    4、大项目makefile的处理

    Ø给源文件分类,并存放在不同的目录中,给各个目录定义变量。

    Ø按层定义makefile.pub文件,该文件主要定义一些变量(如INC, SRC)、函数、本层会生成的lib文件。

    Ø子层文件include上层及相关makefile.pub文件。并根据情况对变量进行扩展。

    Ø生成库文件提供给下一级makefile进行链接。

    Ø嵌套调用make

    subsystem:

        cd subdir && $(MAKE)

    subsystem:

        $(MAKE) –C subdir

    Ø在makefile文件中定义VPATH = src:../headers

    Ø使用环境变量

    5、程序包(函数的定义)

    •定义程序包:

    define run-yacc

        yacc $(firstword $^)

        mv y.tab.c $@

    endef

    •程序包的使用

    %.c : %.y

        $(run-yacc)

    6、函数使用

    $(<function> <arguments>)

    或是:

    i := ${<function> <arguments>}

    示例:

    INC = $(patsubst %,-I%,$(ALLINC))

    make支持的函数有:

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

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

    $(filter <pattern...>,<text>) .....

    7、分支语法

    < conditional-directive>

        < text-if-true>

    endif

    以及:

    < conditional-directive>

        <text-if-true>

    else

        <text-if-false>

    endif

    注:conditional-directive可以是:ifeq(), ifneq(), ifdef, ifndef

    分支语法示例:

    libs_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

    注:上面示例的这个规则中,目标foo可以根据变量$(CC)的值选取不同的函数库来编译程序

    8.make的妙用

    •同步文件至远端服务器:

    cmdscp:

    scp -P3600 exe user_00@172.25.32.162:/usr/local/..

  • 相关阅读:
    Android 适配底部返回键等虚拟键盘的完美解决方案
    Android 第三方库导致jar包冲突解决办法
    git强制push
    解决因为本地代码和远程代码冲突,导致git pull无法拉取远程代码的问题
    上周热点回顾(4.4-4.10)团队
    上周热点回顾(3.28-4.3)团队
    上周热点回顾(3.21-3.27)团队
    上周热点回顾(3.14-3.20)团队
    .NET跨平台之旅:corehost 是如何加载 coreclr 的团队
    .NET跨平台之旅:探秘 dotnet run 如何运行 .NET Core 应用程序团队
  • 原文地址:https://www.cnblogs.com/lidan/p/2239515.html
Copyright © 2020-2023  润新知