zoukankan      html  css  js  c++  java
  • makefile解析:一些常用函数

    #=======================================================================

    #指定目标文件名,makefile中的变量直接使用不用申明

    EXENAME = game_snake

    #加-g 生成debug调试信息 注释掉DEFINES则编译RELEASE模式
    DEFINES = -g

    #编译器
    CC = g++
    LINK = buildserver

    #动态库
    LIB_SO += curl

    #静态库
    #STATIC_LIB = /usr/local/lib/liblua.a


    #源文件目录
    ROOT = $(shell pwd)        #ROOT = $(shell pwd) 获得Makefile的当前路径

    SRC_DIR = $(ROOT)/src/
    SRC_DIR += $(ROOT)/comm/

    #头文件目录
    INCS = $(shell find $(SRC_DIR) -name '*.h')     #寻找pwd目录下的所有名字后缀为.h的头文件
    INC_DIR = $(dir $(INCS))

    #头文件目录排序
    INCLUDE = -I.
    INCLUDE += $(sort $(foreach i, $(INC_DIR), -I$(i)))  #对INC_DIR所代表的头文件进行排序
    #INCLUDE += /usr/local/include/

    #源文件
    #SRCS = $(wildcard *.cpp)                             #制定目录下的cpp文件全部展开
    _SRCS = $(shell find $(SRC_DIR) -name '*.cpp')        #寻找SRC_DIR所代表目录下的所有名字后缀为.cpp的头文件

    #需要排除的目录
    #_EXCLDIR = XXX

    #需要排除的源文件
    _EXCLUS = $(shell find $(_EXCLDIR) -name '*.cpp')

    #排除后的源文件
    SRCS = $(filter-out $(_EXCLUS), $(_SRCS))        #排除指定目录下的文件


    #中间文件
    OBJS = $(patsubst %.cpp, %.o, $(SRCS))                #生存.cpp相对应的.o文件,   模式匹配替换SRCS所代表的字符串中后缀为.cpp的替换为.o

    #$(subst FROM, TO, TEXT),即将字符串TEXT中的子串FROM变为TO。 subst 是全字符串替换,patsubst 是模式替换


    #目标文件目录
    ifndef DEFINES
    EXE_DIR = $(ROOT)/bin
    else
    EXE_DIR = $(ROOT)/bin
    endif

    #目标文件
    EXES = $(EXE_DIR)/$(EXENAME)


    #编译优化选项 -O1:一级优化 为release版本
    ifeq ($(origin DEFINES), undefined)  #origin函数判断DEFINES的出生情况,如果DEFINES未定义过那么$(origin DEFINES)返回undefined 这个if判断为真
    DEFINES = -O1
    OPTIONS = -s
    endif


    #编译选项:_LOGSCR - 日志信息输出到屏幕;_LOGFILE - 日志输出到文件;
    CFLAGS = -Wall $(DEFINES) -D_LOGFILE  #选项 -Wall 开启编译器几乎所有常用的警告──强烈建议你始终使用该选项。编译器有很多其他的警告选项,但 -Wall 是最常用的。默认情况下GCC 不会产生任何警告信息。


    ifeq ($(origin OPTIONS), undefined)
    CFLAGS += -D_LOGSCR  #输出日志到屏幕
    else
    CFLAGS += -D_RUNSERVICE  #后台模式 日志不屏显
    endif


    #连接选项
    LFLAGS = $(OPTIONS)
    LFLAGS += -lm -m64 -ldl -rdynamic -L$(LIB_DIR) -L$(TUXDIR)/lib -L$(LIB_DIR)/ActiveMQ -lcurses     ## -lm: 显示连接数学库,,-m32: 编译为32位代码,,-ldl: 表示生成的对象模块需要使用共享库,,-rdynamic: 用来通知链接器将所有符号添加到动态符号表中(目的是能够通过使用 dlopen 来实现向后跟踪) 
    #LFLAGS += -L/usr/local/lib -DLUA_USE_READLINE
    LFLAGS += $(foreach i, $(LIB_SO), -l$(i)) #动态库连接
    #LFLAGS += /usr/lib/cjson.so


    #规则
    #all:$(EXES)               #目标文件

    $(EXES):$(OBJS)            #依赖关系
    $(CC) -o $@ $(LFLAGS) $(OBJS) $(LFLAGS) $(STATIC_LIB)  #连接选项LFLAGS,,依赖哪些动态库 + 依赖哪些目标文件 + 依赖哪些静态库

    $(OBJS):%.o:%.cpp 
    $(CC) -o $@ -c $< $(CFLAGS) $(INCLUDE)    #有的.o文件的生成依赖其他.o文件,,$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件

    #$(SRCS:.cpp=.o):$(INCS)

    clean:
    -rm -f $(OBJS)
    -rm -f $(EXE_DIR)/ULOG.*
    -rm -f $(EXE_DIR)/access.*
    -rm -f $(EXE_DIR)/good.*
    -rm -f $(EXE_DIR)/*.log
    -rm -f $(EXES)

    cleanall: clean
    rm -f $(EXES)

    rebuild: cleanall
    make

    #=======================================================================

    1.Makefile基本语法

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

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



    $(shell find $(SRC_DIR) -name '*.h') #寻找SRC_DIR所代表目录下的所有名字后缀为.h的头文件  

    $(sort $(foreach i, $(INC_DIR), -I$(i))) #对INC_DIR所代表的头文件进行排序

    $(shell find $(SRC_DIR) -name '*.cpp') #寻找SRC_DIR所代表目录下的所有名字后缀为.cpp的头文件

    $(patsubst %.cpp, %.o, $(SRCS)): 模式匹配替换SRCS所代表的字符串中后缀为.cpp的替换为.o

    $(subst FROM, TO, TEXT),即将字符串TEXT中的子串FROM变为TO。 ------subst 是全字符串替换,patsubst 是模式替换

    ifeq ($(origin DEFINES), undefined) --判断是否相等。。 origin函数判断DEFINES的出生情况,如果DEFINES未定义过那么$(origin DEFINES)返回undefined 这个if判断为真
    g++ 后面跟的参数: -lm -m32 -ldl -rdynamic

    -lm: 显示连接数学库

    -m32: 编译为32位代码

    -ldl: 表示生成的对象模块需要使用共享库

    -rdynamic: 用来通知链接器将所有符号添加到动态符号表中
    (目的是能够通过使用 dlopen 来实现向后跟踪)

    选项 -Wall 开启编译器几乎所有常用的警告──强烈建议你始终使用该选项。编译器有很多其他的警告选项,但 -Wall 是最常用的。默认情况下GCC 不会产生任何警告信息。
    $@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件
    http://blog.csdn.net/kesaihao862/article/details/7332528



  • 相关阅读:
    Windows消息机制
    inherited 为什么可以调用父类的private函数? [问题点数:100分,结帖人:h2plus0]
    C++Buidler6中需要注意的几个问题
    BGA封装芯片拆装全程纪实
    Delphi组件开发教程指南(四)组件生成过程(TWinControl)
    Delphi技巧集六 (等待执行完一个外部程序再执行另一个程序)
    C++ Builder高级应用开发指南
    干掉“Spirale”病毒
    完全看懂新世代x86指令集結構
    Delphi 组件撰写常问问题delphi 在整合环境中如何找出组件所产生的问题
  • 原文地址:https://www.cnblogs.com/bitter-first-sweet-last/p/4019030.html
Copyright © 2011-2022 走看看