• TD makefile常用规则


    makefile 文件中最难写的是各种规则,但是我们的图丁系统已经提供了常用的所有规则(在
    /tdGUI/x86/output/rules.mk 文件中),

    # zhangjie design 2.2
    #########################################################################################
    # CROSS: 交叉编译时的gcc前缀(默认没有)
    # DEBUG: 编译是否带调试信息(默认没有,即编译优化版本-O3)
    # EXTRACFLAGS: 额外的编译选项
    # EXTRALDFLAGS: 额外的链接选项
    # CPPFLAGS: C++文件的编译选项
    # STATICLIB: 是否编译成静态库(默认没有,即编译成动态库)
    # (建议都编译成动态库,因为静态库的函数属性__attribute__((constructor))在函数不使用时无效)
    # EXE2PIE: 可执行程序是否编译成位置无关的(-fPIE, -pie)
    # LIB_UNDEFINED: 创建动态链接库时,允许有未定义的符号(ld的默认情况)
    #
    # TD_PKG_PATH: 该目录下的include,lib也加入编译目录,要加在最后
    #
    # OUTPUT: 全局系统配置目录,该目录中有全局编译配置文件config.mk和rules.mk
    # TOP: 该软件包的顶层目录,该目录中有该软件包的默认配置文件def_config.mk文件,
    # 该文件中可以定义一系列的XXXX1=y XXXX2=n ...等变量来配置编译过程,
    # 并且可以定义CONFIG_H=XXXX1 XXXX2 ...来自动生成一个包含这些宏定义的头文件CONFIG_H_FILE
    #
    # OUTPUT目录和TOP目录必须定义,内容可以相同
    # 编译生成的文件自动放在TOP目录下
    #
    # INSTALL_NAME: 该软件包安装的子目录名, 如果没有设置,默认为$(shell basename "$(TOP)")
    # INSTALL_TOP: 软件包的安装目录, $(TOP)/{bin,include,lib,etc} --> $(INSTALL_TOP)/$(INSTALL_NAME)/
    #
    # 如果要把一个目录下的多个软件包安装到同一个目录,
    # 比如要把 apps/{app1,app2,...} 都要安装到$(INSTALL_TOP)/group/中,
    # 那么app1,app2,...编译时就在自己的makefile中设置INSTALL_NAME:=group,
    #
    # INSTALL_TOP目录是全局设置的,如果没有设置就没有install
    # INSTALL_NAME是软件包自己设置的,如果没有设置默认是TOP的目录名
    #
    # 如果设置了INSTALL_TO_OUTPUT, 即直接安装在$(OUTPUT)目录
    #
    # CONFIG_H_FILE
    #
    # EXENAME 指明生成的可执行文件名
    # EXESRCS 指定要编译的源代码文件
    # EXECFLAGS 指定编译时的参数
    # EXELDFLAGS 指定链接时的参数
    #
    # LIBNAME
    # LIBSRCS
    # LIBCFLAGS
    # LIBLDFLAGS
    # LIBARFLAGS
    # LIBVERSION
    # LIBVERSION_SUB
    #
    # 在Makefile中首先定义OUTPUT目录和TOP目录
    # 第一次包含rules.mk: 包含$(OUTPUT)/config.mk和$(TOP)/def_config.mk
    # 第二次包含rules.mk: 根据EXENAME和LIBNAME 做编译安装的工作
    # 变量总是先定义后使用,先确定变量的值再写依赖
    #########################################################################################
    
    ifeq ($(origin ALREADYFIRST),undefined)
    #@@@@@@@@@@@@@@@@ 第一次包含rules.mk, 做默认配置的工作 @@@@@@@@@@@@@@@@@@@
    ALREADYFIRST := Y
    
    TOP := $(strip "$(TOP)")
    ifeq ("$(TOP)",)
    $(error "you are not set TOP dir")
    endif
    ifneq ($(shell if [ -d "$(TOP)" ]; then echo true; fi),true)
    $(error "TOP directory $(TOP) does not exist")
    endif
    TOP := $(shell cd "$(TOP)" && /bin/pwd)
    
    OUTPUT := $(strip $(OUTPUT))
    ifeq ($(OUTPUT),)
    $(error "you are not set OUTPUT directory")
    endif
    ifneq ($(shell if [ -d "$(OUTPUT)" ]; then echo true; fi),true)
    $(error "OUTPUT directory $(OUTPUT) does not exist")
    endif
    OUTPUT := $(shell cd $(OUTPUT) && /bin/pwd)
    
    -include $(OUTPUT)/config.mk
    -include $(TOP)/def_config.mk
    
    CC := $(CROSS)gcc
    CCP := $(CROSS)g++
    LD := $(CROSS)ld
    AR := $(CROSS)ar
    RANLIB := $(CROSS)ranlib
    STRIP := $(CROSS)strip
    
    CCEXE := $(CC)
    CCLIB := $(CC)
    
    #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    else
    #@@@@@@@@@@@@@ 第二次包含rules.mk,做编译安装的工作,一直到该文件尾 @@@@@@@@@
    
    ifeq ($(INSTALL_TO_OUTPUT),Y)
    
    INSTALL := $(OUTPUT)
    
    else
    
    INSTALL :=
    INSTALL_TOP := $(strip $(INSTALL_TOP))
    ifneq ($(INSTALL_TOP),)
    ifneq ($(shell if [ -d "$(INSTALL_TOP)" ]; then echo true; fi),true)
    $(error "INSTALL_TOP directory $(INSTALL_TOP) does not exist")
    endif
    INSTALL_TOP := $(shell cd $(INSTALL_TOP) && /bin/pwd)
    INSTALL_NAME := $(strip $(INSTALL_NAME))
    ifeq ($(INSTALL_NAME),)
    INSTALL_NAME := $(shell basename "$(TOP)")
    endif
    INSTALL := $(INSTALL_TOP)/$(INSTALL_NAME)
    endif
    
    endif
    
    EXEOBJS := $(patsubst %.c, %.o, $(EXESRCS))
    LIBOBJS := $(patsubst %.c, %.lo, $(LIBSRCS))
    EXEDEPS := $(patsubst %.c, %.d, $(EXESRCS))
    LIBDEPS := $(patsubst %.c, %.d, $(LIBSRCS))
    
    EXEOBJS := $(patsubst %.cpp, %.oo, $(EXEOBJS))
    LIBOBJS := $(patsubst %.cpp, %.loo, $(LIBOBJS))
    EXEDEPS := $(patsubst %.cpp, %.dd, $(EXEDEPS))
    LIBDEPS := $(patsubst %.cpp, %.dd, $(LIBDEPS))
    
    #GCOVFILES:=$(patsubst %.c, %.gc*, $(EXESRCS)) $(patsubst %.c, %.gc*, $(LIBSRCS)) $(patsubst %.c, %.c.gcov, $(EXESRCS)) $(patsubst %.c, %.c.gcov, $(LIBSRCS)) 
    
    ifeq ($(findstring .cpp, $(EXESRCS)), .cpp)
    CCEXE := $(CCP)
    endif
    
    ifeq ($(findstring .cpp, $(LIBSRCS)), .cpp)  
    CCLIB := $(CCP)
    endif
    
    ################################################
    
    CFLAGS := -DLINUX=1 -DUNIX=1 -Dlinux -Dunix -Wall -D_GNU_SOURCE -D_REENTRANT
    LDFLAGS := 
    
    ifeq ($(DEBUG),Y)
    CFLAGS += -DTD_DEBUG -O0 -ggdb3
    #CFLAGS += -pg -fprofile-arcs -ftest-coverage
    #LDFLAGS += -pg -fprofile-arcs -ftest-coverage
    else
    CFLAGS += -DNDEBUG -O3 -fomit-frame-pointer
    endif
    
    CFLAGS += "-I$(TOP)/include"
    LDFLAGS += "-L$(TOP)/lib"
    
    ifneq ($(INSTALL),)
    ifneq ("$(TOP)",$(INSTALL))
    CFLAGS += -I$(INSTALL)/include
    LDFLAGS += -L$(INSTALL)/lib
    endif
    endif
    
    ifneq ("$(TOP)",$(OUTPUT))
    ifneq ($(INSTALL),$(OUTPUT))
    CFLAGS += -I$(OUTPUT)/include
    LDFLAGS += -L$(OUTPUT)/lib
    endif
    endif
    
    ifneq ($(TD_PKG_PATH),)
    CFLAGS += -I$(TD_PKG_PATH)/include
    LDFLAGS += -L$(TD_PKG_PATH)/lib
    endif
    
    ################################################
    ifneq ($(LIBNAME),)
    
    $(shell mkdir -p "$(TOP)/lib")
    LIBCFLAGS += -fPIC -DPIC
    
    ifeq ($(STATICLIB),Y)
    #=====================如果是编译静态链接库===================
    
    ifeq ($(EXE2PIE),Y)
    LIBCFLAGS += -fPIE
    endif
    
    REALLIBNAME = $(LIBNAME).a
    $(LIBNAME): $(CONFIG_H_FILE) $(LIBDEPS) $(LIBOBJS)
        $(AR) cr $(REALLIBNAME) $(LIBOBJS) $(LIBARFLAGS)
        $(RANLIB) $(REALLIBNAME)
        mv -f $(REALLIBNAME) "$(TOP)/lib/"
        @echo -e 'e[32m' ========= generate static libray $@ end ========= 'e[0m'
    
    else
    #=====================如果是编译动态链接库===================
    
    REALLIBNAME = $(LIBNAME).so
    ifneq ($(LIBVERSION),)
    SETSONAME := -Wl,-soname,$(LIBNAME).so.$(LIBVERSION)
    REALLIBNAME = $(LIBNAME).so.$(LIBVERSION)
    SIMPLE_LIBNAME = $(LIBNAME).so
    ifneq ($(LIBVERSION_SUB),)
    SOLIBNAME = $(LIBNAME).so.$(LIBVERSION)
    REALLIBNAME = $(LIBNAME).so.$(LIBVERSION).$(LIBVERSION_SUB)
    endif
    endif
    
    ifeq ($(LIB_UNDEFINED),)
    LIBLDFLAGS += -Wl,--no-undefined
    endif
    
    $(LIBNAME): $(CONFIG_H_FILE) $(LIBDEPS) $(LIBOBJS)
        $(CCLIB) -shared -Wl,-Bsymbolic -Wl,-Bsymbolic-functions $(SETSONAME) -o $(REALLIBNAME) $(LIBOBJS) $(LIBLDFLAGS) $(LDFLAGS) $(EXTRALDFLAGS)
        mv -f $(REALLIBNAME) "$(TOP)/lib"
        [ "$(DEBUG)" = "Y" ] || $(STRIP) "$(TOP)/lib/$(REALLIBNAME)"
        @[ -z $(SOLIBNAME) ] || ln -sf $(REALLIBNAME) $(SOLIBNAME)
        @[ -z $(SOLIBNAME) ] || mv -f $(SOLIBNAME) "$(TOP)/lib"
        @[ -z $(SIMPLE_LIBNAME) ] || ln -sf $(REALLIBNAME) $(SIMPLE_LIBNAME)
        @[ -z $(SIMPLE_LIBNAME) ] || mv -f $(SIMPLE_LIBNAME) "$(TOP)/lib"
        @echo -e 'e[32m' ========= generate share libray $@ end ========= 'e[0m'
    
    endif
    endif
    ##################################################
    
    ##################################################
    ifneq ($(EXENAME),)
    ifeq ($(EXE2PIE),Y)
    EXECFLAGS += -fPIE
    EXELDFLAGS += -pie -Wl,-Bsymbolic -Wl,-Bsymbolic-functions
    endif
    $(shell mkdir -p "$(TOP)/bin")
    $(EXENAME): $(CONFIG_H_FILE) $(EXEDEPS) $(EXEOBJS)
        $(CCEXE) -Wl,--allow-shlib-undefined -Wl,--no-as-needed -o $(EXENAME) $(EXEOBJS) $(EXELDFLAGS) $(LDFLAGS) $(EXTRALDFLAGS)
        mv -f $(EXENAME) "$(TOP)/bin/"
        [ "$(DEBUG)" = "Y" ] || $(STRIP) "$(TOP)/bin/$(EXENAME)"
        @echo -e 'e[32m' ========= generate execute $@ end ========= 'e[0m'
    endif
    ##################################################
    
    .PHONY: rules_clean rules_install rules_build_info
    
    #因为后面包含依赖文件会自动在all前面执行.d的规则,所以后面要加上$(CONFIG_H_FILE),
    #因为在规则中$<表示第一个依赖文件名
    %.d: %.c $(CONFIG_H_FILE)
        @$(CC) -MM $(EXECFLAGS) $(LIBCFLAGS) $(CFLAGS) $(EXTRACFLAGS) $< | sed -e 's,^[0-9a-zA-Z._-]*: ([0-9a-zA-Z._-]*/),1&,' -e 's,^([0-9a-zA-Z.-_/]*).o:,1.o 1.d 1.lo:,' > $@
    
    %.o: %.c
        $(CC) $(EXECFLAGS) $(CFLAGS) $(EXTRACFLAGS) -c -o $@ $<
    
    %.lo: %.c
        $(CC) $(LIBCFLAGS) $(CFLAGS) $(EXTRACFLAGS) -c -o $@ $<
    
    %.dd: %.cpp $(CONFIG_H_FILE)
        @$(CCP) -MM $(EXECFLAGS) $(LIBCFLAGS) $(CPPFLAGS) $(CFLAGS) $(EXTRACFLAGS) $< | sed -e 's,^[0-9a-zA-Z._-]*: ([0-9a-zA-Z._-]*/),1&,' -e 's,^([0-9a-zA-Z.-_/]*).o:,1.oo 1.dd 1.loo:,' > $@
    
    %.oo: %.cpp
        $(CCP) $(EXECFLAGS) $(CPPFLAGS) $(CFLAGS) $(EXTRACFLAGS) -c -o $@ $<
    
    %.loo: %.cpp
        $(CCP) $(LIBCFLAGS) $(CPPFLAGS) $(CFLAGS) $(EXTRACFLAGS) -c -o $@ $<
    
    rules_clean:
        -rm -f $(CONFIG_H_FILE) $(EXENAME) $(REALLIBNAME) $(EXEOBJS) $(LIBOBJS) $(EXEDEPS) $(LIBDEPS) $(GCOVFILES)
        -[ -z $(EXENAME) ] || rm -f "$(TOP)/bin/$(EXENAME)"
        -[ -z $(LIBNAME) ] || rm -f "$(TOP)/lib/$(LIBNAME)."*
        -rm -f "$(TOP)/build_info.ini"
    
    ifneq ($(INSTALL),)
    rules_install: $(LIBNAME) $(EXENAME)
        -mkdir -p $(INSTALL)
        -[ ! -f "$(TOP)/package.ini" ] || cp -af "$(TOP)/*.ini" $(INSTALL)/
        -[ ! -d "$(TOP)/include" ] || cp -af "$(TOP)/include" $(INSTALL)/
        -[ ! -d "$(TOP)/lib" ] || cp -af "$(TOP)/lib" $(INSTALL)/
        -[ ! -d "$(TOP)/bin" ] || cp -af "$(TOP)/bin" $(INSTALL)/
        -[ ! -d "$(TOP)/etc" ] || cp -af "$(TOP)/etc" $(INSTALL)/
        -[ ! -d "$(TOP)/style" ] || cp -af "$(TOP)/style" $(INSTALL)/
        -[ ! -d "$(TOP)/share" ] || cp -af "$(TOP)/share" $(INSTALL)/
        -[ ! -d "$(TOP)/local" ] || cp -af "$(TOP)/local" $(INSTALL)/
        -[ ! -d "$(TOP)/var" ] || cp -af "$(TOP)/var" $(INSTALL)/
        @echo -e 'e[32m' ========= install $(LIBNAME) $(EXENAME) to $(INSTALL) end ========= 'e[0m'
    else
    rules_install:
        @echo -e 'e[33;1m' you not set INSTALL_TOP, so no install. 'e[0m'
    endif
    
    ifneq ($(CONFIG_H_FILE),)
    define CONFIG_H_ITEM
    if [ "$($(1))" = "Y" ] || [ "$($(1))" = "y" ] ; then echo "#define $(1) 1" >> $(CONFIG_H_FILE) ; else echo "/*no define $(1) */" >> $(CONFIG_H_FILE) ; fi ;
    endef
    $(CONFIG_H_FILE): $(TOP)/def_config.mk
        @echo "/*this file is auto generated by rules.mk from config.mk*/" > $(CONFIG_H_FILE)
        @echo "#ifndef _$(EXENAME)_$(LIBNAME)_CONFIG_H"  >> $(CONFIG_H_FILE)
        @echo "#define _$(EXENAME)_$(LIBNAME)_CONFIG_H"  >> $(CONFIG_H_FILE)
        @echo ""  >> $(CONFIG_H_FILE)
        @$(foreach ITEM,$(CONFIG_H),$(call CONFIG_H_ITEM,$(ITEM)))
        @echo ""  >> $(CONFIG_H_FILE)
        @echo "#endif"  >> $(CONFIG_H_FILE)
        @echo ""  >> $(CONFIG_H_FILE)
        @echo -e 'e[32m' ========= generate $@ end ========= 'e[0m'
    endif
    
    rules_build_info:
        @grep -s -m 1 "version" "$(TOP)/package.ini" > "$(TOP)/build_info.ini" || true
        @echo "time="`date '+%Y/%m/%d-%H:%M:%S'`"" >> "$(TOP)/build_info.ini"
        @cat  "$(TOP)/build_info.ini"
        @echo -e 'e[32m' ========= generate build_info.ini end ======== 'e[0m'
    
    ifneq ($(MAKECMDGOALS),clean)
    -include $(EXEDEPS) $(LIBDEPS)
    endif
    
    #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    endif
    # EXENAME 指明生成的可执行文件名
    # EXESRCS 指定要编译的源代码文件
    # EXECFLAGS 指定编译时的参数
    # EXELDFLAGS 指定链接时的参数
  • 相关阅读:
    JQuery 日历控件
    恢复xp_cmdshell SQL Server阻止了对组件 'xp_cmdshell' 的过程'sys.xp_cmdshell' 启用
    XML基础总结
    09.09.16总结
    草根
    设计模式学习总结
    检索 COM 类工厂中 CLSID 为{0002450000000000C000000000000046} 的组件时失败,原因是出现以下错误: 80070005。
    09.09.22总结
    Singleton 单态模式
    【Tomcat源码学习】5.请求处理
  • 原文地址:https://www.cnblogs.com/senior-engineer/p/14062137.html
Copyright © 2020-2023  润新知