本文通过总结makefile的相关使用,并将以前大型项目中用到的Makefile简单的记录下,以便以后快速应用:
- Makefile常用命令
- GCC/G++常用编译参数
- 简单Makefile框架实现
Makefile常用命令
make Makefile/makefile/GNUMakefile
当Makefile名字不是上述三个名字时,需要加-f 去编译,如xxx.mk文件,需使用make -f xxx.mk 去编译;
GCC/G++常用编译参数
- -shared
Produce a shared object which can then be linked with other objects to for man executable. Not all systems support this option. - -D_REENTRANT
在一个多线程程序里,默认情况下,只有一个errno变量供所有的线程共享。在一个线程准备获取刚才的错误代码时,该变量很容易被另一个线程中的函数调用所改变。类似的问题还存在于fputs之类的函数中,这些函数通常用一个单独的全局性区域来缓存输出数据。
为解决这个问题,需要使用可重入的例程。可重入代码可以被多次调用而仍然工作正常。编写的多线程程序,通过定义宏_REENTRANT来告诉编译器我们需要可重入功能,这个宏的定义必须出现于程序中的任何#include语句之前。
_REENTRANT为我们做三件事情,并且做的非常优雅:
(1)它会对部分函数重新定义它们的可安全重入的版本,这些函数名字一般不会发生改变,只是会在函数名后面添加_r字符串,如函数名gethostbyname变成gethostbyname_r。
(2)stdio.h中原来以宏的形式实现的一些函数将变成可安全重入函数。 - Makefile三个非常有用的变量
分别是 ^, <–第一个依赖文件。 - -w -W和-Wall选项
-w的意思是关闭编译时的警告,也就是编译后不显示任何warning,因为有时在编译之后编译器会显示一些例如数据转换之类的警告,这些警告是我们平时可以忽略的。
-Wall选项意思是编译后显示所有警告。
-W选项类似-Wall,会显示警告,但是只显示编译器认为会出现错误的警告。
简单Makefile框架实现
此处将写三个makefile文件,它们为了大型项目的集成,将一个全要素的makefile文件拆分开来编写,然后通过include相关联;
Makefile代码框架
MakeFileTemplate
#########################################################
###############Makefile Path公共变量定义#################
#########################################################
EB_SRC_PATH = $(JTTS_SRC_ROOT)/src/Product/Engine/jTTS_EB9
EB_SRC_COMMON=$(JTTS_SRC_ROOT)/src/Product/Engine/common
EB_RELEASE_PATH =$(JTTS_SRC_ROOT)/bin
EB_LIB_PATH=$(JTTS_SRC_ROOT)/libs
##########################################################
####GCC编译参数定义
##########################################################
CC :=g++
INCLUDE :=
LIBS :=
DEFS :=
CFLAGS := -g -w -O2 -rdynamic
SRC_FILES :=
INSTDIR :=
LIB_INC :=
###########################################################
# define gloab variable
###########################################################
TARGET = libjTTS_EB9.so
TARGET_COPY = libjTTS_EB9.so
MODULE_OUTPUT_PATH = $(EB_RELEASE_PATH)/$(TARGET_COPY)
INCLUDE +=-I$(EB_SRC_PATH) \
-I$(JTTS_SRC_ROOT)/src/Product/OSLayer/include \
-I$(EB_SRC_COMMON) \
-I$(EB_SRC_PATH) \
-I$(JTTS_SRC_ROOT)/src/Ext_SDK/Ext_SDK/EB/include \
-I$(JTTS_SRC_ROOT)/src/Common/include \
-I$(JTTS_SRC_ROOT)/src/Product/Common/include \
-I$(JTTS_SRC_ROOT)/src/Ext_SDK/Encrypt \
-I$(JTTS_SRC_ROOT)/depends/ACE_wrappers \
-I$(JTTS_SRC_ROOT)/depends
LIB_INC +=-L$(EB_LIB_PATH) \
-L$(EB_RELEASE_PATH) \
-L$(EB_SRC_PATH)
SRC_FILES += $(shell find $(EB_SRC_PATH) -name jTTS_EB.cpp)
SRC_FILES += $(shell find $(EB_SRC_PATH) -name ejTTSAgent.cpp)
SRC_FILES += $(shell find $(EB_SRC_PATH) -name ejTTSInstance.cpp)
SRC_FILES += $(shell find $(EB_SRC_PATH) -name Win_Linux_file_func.cpp)
SRC_FILES += $(shell find $(EB_SRC_COMMON) -name CQueue.cpp)
SRC_FILES += $(shell find $(EB_SRC_COMMON) -name backaudio.cpp)
SRC_FILES += $(shell find $(EB_SRC_COMMON) -name JIniFile.cpp)
LIBS += -lOSLayer \
-lACE \
-ljTTS_Audio \
-liconv \
libjtsecure_app.a \
libjtsecure_engine.a \
-lmkl_rt \
-lSmallFile \
-lz \
-lpthread \
-lrt \
-ldl
ALL:$(TARGET)
cp $(EB_SRC_PATH)/$(TARGET) $(EB_RELEASE_PATH)/$(TARGET_COPY) -f
%.o:%.cpp
$(CC) -fPIC -c $(SRC_FILES) $(INCLUDE)
OBJ_SRC=$(addprefix $(EB_SRC_PATH)/,$(notdir $(SRC_FILES:%.cpp=%.o)))
$(TARGET): $(OBJ_SRC)
$(CC) -shared -o $(TARGET) $(OBJ_SRC) ${LIBS} $(LIB_INC)
clean:
-rm -f $(TARGET)
-rm -f *.o
def.app.mak
########################################################## #所有的编译用的makefile都必须引用该文件 ##########################################################
include $(XS_ROOT)/build/common_mak/def_pub.mak
CC :=g++
INCLUDE :=
LIBS :=
DEFS :=
#ifeq ($(ATN_FLAG_WALL_DELETE),yes)
#CFLAGS := -Os
#else
CFLAGS := -O2
#endif
SRC_FILES :=
INSTDIR :=
########################################################### # define gloab variable ###########################################################
ifneq ($(PRODUCT_TYPE),PTN)
ENDIAN_DEFS := -DVOS_BYTE_ORDER=VOS_BIG_ENDIAN
endif
### public define ###
ifeq ($(CPU_INSX),x8664)
DEFS += -DVOS_OS_VER=4
DEFS += -DVOS_HARDWARE_PLATFORM=3
DEFS += -DVOS_CPU_TYPE=44
endif
ifeq ($(CPU_INSX),ARM64)
DEFS += -DVOS_OS_VER=4
DEFS += -DVOS_HARDWARE_PLATFORM=3
DEFS += -DVOS_CPU_TYPE=44
endif
INCLUDE += -I/usr/include
def_pub.mak
XS_ROOT=/home/heyongxin/xs_epoll
CPU_INSX=ARM64
PRODUCT_TYPE=PTN
SROUTER=0
exec_app.mak
CFLAGS += -D_REENTRANT -Wall -pedantic -Isrc -g
LIBS += -lpthread
all: $(TARGET)
clean:
rm -f $(TARGET) *~ */*~ */*.o
$(TARGET): $(SRC_FILES) $(XS_ROOT_INC_PATH)/*
$(CC) -fPIC ${CFLAGS} -o $@ $< $(INCLUDE) ${LIBS}
xs_epoll_build.mk
include $(XS_ROOT)/build/common_mak/def_pub.mak
include $(XS_ROOT)/build/common_mak/def_app.mak
XS_ROOT_SRC_PATH = $(XS_ROOT)
XS_ROOT_INC_PATH =$(XS_ROOT)/include
XSEPOLL_RELEASE_PATH =$(XS_ROOT)/bin
DEFS += -DAA_AA
ifeq ($(CPU_INSX),ptn)
CFLAGS += -DBYTEORDER_LITTE
else
CFLAGS += -DBYTEORDER_BIG
endif
MODULE = xs_epoll
TARGET = $(XSEPOLL_RELEASE_PATH)/$(MODULE)
MODULE_OUTPUT_PATH = $(XSEPOLL_RELEASE_PATH)/$(MODULE)
TARGET_COPY = lxs_epoll.so
SRC_FILES += $(shell find $(XS_ROOT_SRC_PATH)/src -name xs_epoll.c)
#SRC_FILES += $(shell find $(XS_ROOT_SRC_PATH)/src -name xs_epoll.c)
#SRC_FILES += $(shell find $(XS_ROOT_SRC_PATH)/src -name xs_epoll.c)
ifeq ($(SROUTER),1)
LIBS += -lsfeaa
DEFS += -DCPU_INSA_X86
endif
ifdef UT_FILES
CC += -O2
endif
INCLUDE += -I$(XS_ROOT)/include
# -I$(XS_ROOT)/product/xframe/aa/include \
# -I$(XS_ROOT)/product/xframe/aa/include \
# -I$(XS_ROOT)/product/aa/include \
include $(XS_ROOT)/build/common_mak/exec_app.mak
build.sh
#!/bin/bash
# testing the script
export XS_ROOT="/home/heyongxin/xs_epoll"
#./build.sh build xs_epoll all clean
function Main_Build_Entrance {
echo $1
echo $2
echo $3
echo $4
if [[ $4 -eq "clean" ]]
then
make -f ./xs_epoll_build.mk clean
make -f ./xs_epoll_build.mk
elif [ $4 -eq "gdb" ] && [ $1 -eq "run" ]
then
gdb $(XS_ROOT)/bin/xs_epoll
else
make -f ./xs_epoll_build.mk
fi
}
Main_Build_Entrance $1 $2 $3 $4
#make -f ./xs_epoll_build.mk