zoukankan      html  css  js  c++  java
  • Linux下通用的Makefile 转载

    Linux下通用的Makefile

     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    ####################################################
    # Generic makefile
    # for compiling and linking C++ projects on Linux
    ####################################################
    ### Customising
    #
    # Adjust the following if necessary; EXECUTABLE is the target
    # executable's filename, and LIBS is a list of libraries to link in
    # (e.g. alleg, stdcx, iostr, etc). You can override these on make's
    # command line of course, if you prefer to do it that way.
    #
    #
    EXECUTABLE := main    # 可执行文件名
    LIBDIR:=              # 静态库目录
    LIBS :=               # 静态库文件名
    INCLUDES:=.           # 头文件目录
    SRCDIR:=              # 除了当前目录外,其他的源代码文件目录
    #
    # # Now alter any implicit rules' variables if you like, e.g.:
     
    CC:=g++
    CFLAGS := -g -Wall -O3
    CPPFLAGS := $(CFLAGS)
    CPPFLAGS += $(addprefix -I,$(INCLUDES))
    CPPFLAGS += -MMD
    #
    # # The next bit checks to see whether rm is in your djgpp bin
    # # directory; if not it uses del instead, but this can cause (harmless)
    # # `File not found' error messages. If you are not using DOS at all,
    # # set the variable to something which will unquestioningly remove
    # # files.
    #
     
    RM-F := rm -f
     
     
    # # You shouldn't need to change anything below this point.
    #
    SRCS := $(wildcard *.cpp) $(wildcard $(addsuffix /*.cpp, $(SRCDIR)))
    OBJS := $(patsubst %.cpp,%.o,$(SRCS))
    DEPS := $(patsubst %.o,%.d,$(OBJS))
    MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
    MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.cpp,$(MISSING_DEPS)))
     
     
    .PHONY : all deps objs clean veryclean rebuild info
     
    all: $(EXECUTABLE)
     
    deps : $(DEPS)
     
    objs : $(OBJS)
     
    clean :
            @$(RM-F) *.o
            @$(RM-F) *.d
    veryclean: clean
            @$(RM-F) $(EXECUTABLE)
     
    rebuild: veryclean all
    ifneq ($(MISSING_DEPS),)
    $(MISSING_DEPS) :
            @$(RM-F) $(patsubst %.d,%.o,$@)
    endif
    -include $(DEPS)
    $(EXECUTABLE) : $(OBJS)
            $(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS))
     
    info:
            @echo $(SRCS)
            @echo $(OBJS)
            @echo $(DEPS)
            @echo $(MISSING_DEPS)
            @echo $(MISSING_DEPS_SOURCES)

    注:1)命令行前的空白符必须为一个制表符(Tab);如,@$(RM-F) *.o前不是空格,而是一个制表符;

    内容解析

    1.Makefile基本语法

    target为要生成的目标文件;dependency为target的依赖文件;command为用于生成target的命令行;

    <target> : <dependency> <dependency> ...
    (tab)<command>
    (tab)<command>
     .
     .
     .

    2.赋值符号 := 与 =

      :=与=的区别在于,符号:=表示立即展开变量值。例如:

    A:=foo

    B:=$(A)

    A:=bar

    这时,B的值仍为foo,因为它已被展开,不会再随A的值改变而改变。

    3.符号#是Makefile的注释符号

    4.wildcard函数

    SRCS:=$(wildcard *.cpp) 表示列举当前目录中扩展名为.cpp的所有文件,然后赋值给变量SRCS。详细请google之。

    5.patsubst函数

    OBJS := $(patsubst %.cpp,%.o,$(SRCS))表示,将$(SRCS)中所有满足模式%.cpp的字符串替换为%.o。

    6.filter-out函数

    $(filter-out $(A),$(B))表示从B中过滤掉A中的内容,返回剩余内容;

    7. “.PHONY”

    用.PHONY修饰的target是“伪目标”,不需要生成真实的文件;make假定phony target是已经生成的,然后更新它后边的依赖文件和执行它下边的命令(command);

    8.all deps objs clean veryclean rebuild info

    这些都是“伪目标”。

    all是第一个目标,所以输入make时它被默认执行;all生成或更新所有*.cpp文件对应的*.d文件和*.o文件,并链接所有*.o文件生成可执行文件$(EXECUTABLE)。

    deps仅仅生成*.d文件;.d文件是什么文件?它包含了代码文件的依赖信息。

    objs仅仅生成*.o文件;.o文件是C++代码编译后的中间结果文件,废话!

    clean用于删除*.d文件和*.o文件。

    veryclean删除*.d文件、*.o文件,还有名为$(EXECUTABLE)的可执行文件。

    rebuild先调用veryclean清除结果文件,再调用all重新编译和链接。

    info查看某些信息。

    使用方法:

    make deps即可执行deps;

    9.ifneq...else...endif

    条件语句,ifneq表示如果不想等,则...;

    10.include <files>语句

    include表示把<files>的内容包含进来;

    $(DEPS)是包含依赖信息的文件,每个源文件对应一个.d文件;-include $(DEPS)表示把这些依赖信息包含进来;

    11.链接*.o文件,生成可执行文件

    主菜来了!

    1
    2
    $(EXECUTABLE) : $(OBJS)
            $(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))

    $(EXECUTABLE)为可执行文件名;$(OBJS)为所有.o文件名;$(CC)在这里是g++;$(addprefix -l,$(LIBS)添加引用库;

    前面说好的*.d文件和*.o文件是怎么生成的呢?貌似没有命令指出要生成它们呀!请看隐含规则!

    12. 隐含规则(Implicit rules)

    $(EXECUTABLE)依赖于$(OBJS),但makefile中没有指明$(OBJS)依赖于谁,也没指明命令生成它们;

    这时,make的隐含规则开始起作用;针对$(OBJS)中的每个目标,make自动调用:

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

    依次生成.o文件和.d文件;

    $<表示依赖文件列表的第一个文件名;

    $@表示目标文件名;

    之所以会生成.d文件,是由于“-MMD”这一编译选项。为g++加上这一选项后,编译器会生成文件依赖信息,并存放至.d文件中。

    每一个.cpp文件相应地生成一个.d文件和一个.o文件。

    13.@符号

    命令行前的@符号表示不回显命令行;

    14.CFLAGS和CPPFLAGS

    这两者包含编译选项,更详细内容请Google之。

    -g 添加gdb调试信息;

    -Wall 提示warning信息;

    -O3 表示第3级优化;

  • 相关阅读:
    jmeter脚本开发:插件安装和设计场景(五)
    jmeter脚本开发:SOAP接口和JDBC(四)
    jmeter脚本开发:控制器和参数化(三)
    gauge自动化框架踩坑(六):关于csv
    gauge自动化框架踩坑(五):关于表格
    gauge自动化框架踩坑(四):在测试报告中自定义messages
    MediaPlayer播放音频,也可以播放视频
    soundpool播放声音
    ContentProvider
    了解 IMyInterface.Stub
  • 原文地址:https://www.cnblogs.com/986YAO/p/9856165.html
Copyright © 2011-2022 走看看