在Linux工程编译中,一个工程通常需要编译多个静态库和动态库,顶层Makefile需要调用下层多个目录中的Makefile,最终生成相应的静态库和动态库以及相应的目标执行程序。
在下面例子中
工程中Ser为顶层目录,makefile为顶层makefile,libBJWTest为最终生成的可执行目录,VLConfig.xml为顶层的参数配置文件;
cpsbase,mxml需要生成的基础静态库,zeros是与工程相关的静态库和动态库,以及生成可执行目标的库;
上图是zeros目录的下层目录,其中libCoreService为静态库,libBJW、libMediaBJW、libVLMediaBJW、libVLTask为动态库,libBJWTest为可执行目录;
顶层makefile如下:
RootDir := /home/yxz/serverload_EndVersion1.0/ser/ //根目录
mxml_src_dir := $(RootDir)mxml //mxml静态库源文件目录
CPSBASE_src_Dir := $(RootDir)cpsbase
libCoreService_src_Dir := $(RootDir)zeros/libCoreService
libBJW_src_Dir := $(RootDir)zeros/libBJW
libMediaBJW_src_Dir := $(RootDir)zeros/libMediaBJW
libVLMediaBJW_src_Dir := $(RootDir)zeros/libVLMediaBJW //下载媒体服务器的动态库源目录
libVLTask_src_Dir := $(RootDir)zeros/libVLTask
libBJWTest_src_Dir := $(RootDir)zeros/libBJWTest //生成可执行代码的源文件目录
ALL: MXML CPSBASE LIBCORESERVICE LIBBJW LIBMEDIABJW LIBVLMEDIABJW LIBVLTASK LIBBJWTEST //依赖目标集,每个目标生成静态库或是动态 库或是可执行目标;
.PHONE: ALL //将ALL设置成伪目标,ALL会第一个执行,但 不会生成目标,依赖的目标会依次执行
MXML:
$(MAKE) -C $(mxml_src_dir) //进入到mxml目录中,并执行目录下的makfile文件,生成libmxml.a中
CPSBASE:
$(MAKE) -C $(CPSBASE_src_Dir)
LIBCORESERVICE:
$(MAKE) -C $(libCoreService_src_Dir)
LIBBJW:
$(MAKE) -C $(libBJW_src_Dir)
LIBMEDIABJW:
$(MAKE) -C $(libMediaBJW_src_Dir) //进入到libMediaBJW中执行该目录的makefile,生成动态库libMediaBJW.so
LIBVLMEDIABJW:
$(MAKE) -C $(libVLMediaBJW_src_Dir)
LIBVLTASK:
$(MAKE) -C $(libVLTask_src_Dir)
LIBBJWTEST:
$(MAKE) -C $(libBJWTest_src_Dir) //进入到libBJWTest中执行该目录下的Makefile,生成可执行目标libBJWTest
mxml_src_dir := $(RootDir)mxml //mxml静态库源文件目录
CPSBASE_src_Dir := $(RootDir)cpsbase
libCoreService_src_Dir := $(RootDir)zeros/libCoreService
libBJW_src_Dir := $(RootDir)zeros/libBJW
libMediaBJW_src_Dir := $(RootDir)zeros/libMediaBJW
libVLMediaBJW_src_Dir := $(RootDir)zeros/libVLMediaBJW //下载媒体服务器的动态库源目录
libVLTask_src_Dir := $(RootDir)zeros/libVLTask
libBJWTest_src_Dir := $(RootDir)zeros/libBJWTest //生成可执行代码的源文件目录
ALL: MXML CPSBASE LIBCORESERVICE LIBBJW LIBMEDIABJW LIBVLMEDIABJW LIBVLTASK LIBBJWTEST //依赖目标集,每个目标生成静态库或是动态 库或是可执行目标;
.PHONE: ALL //将ALL设置成伪目标,ALL会第一个执行,但 不会生成目标,依赖的目标会依次执行
MXML:
$(MAKE) -C $(mxml_src_dir) //进入到mxml目录中,并执行目录下的makfile文件,生成libmxml.a中
CPSBASE:
$(MAKE) -C $(CPSBASE_src_Dir)
LIBCORESERVICE:
$(MAKE) -C $(libCoreService_src_Dir)
LIBBJW:
$(MAKE) -C $(libBJW_src_Dir)
LIBMEDIABJW:
$(MAKE) -C $(libMediaBJW_src_Dir) //进入到libMediaBJW中执行该目录的makefile,生成动态库libMediaBJW.so
LIBVLMEDIABJW:
$(MAKE) -C $(libVLMediaBJW_src_Dir)
LIBVLTASK:
$(MAKE) -C $(libVLTask_src_Dir)
LIBBJWTEST:
$(MAKE) -C $(libBJWTest_src_Dir) //进入到libBJWTest中执行该目录下的Makefile,生成可执行目标libBJWTest
底层目录下的makefile如下:以一个动态库,静态库和可执行目标为例;
mxml静态库下的makefile如下:
CC = gcc //设置编译工具Wiegcc
AR = ar rcs //生成的静态库命令
TARGET = libmxml.a //生成目标静态库文件
OBJECT_LINKFILE = $(wildcard *.o) //展开目录下生成的.o文件
ALL: clear mxml //依赖目标,先执行clear,后执行mxml目标
.PHONE: ALL
clear:
ifneq ($(shell find $(TARGET)),) //如果存在已生成的静态库文件,则先删除;
rm $(TARGET)
endif
ifneq ($(OBJECT_LINKFILE),) //如果目录下存在.o链接文件,则删除
rm $(OBJECT_LINKFILE)
endif
mxml:
$(CC) -g -c *.c //gcc生成中间链接.o文件
$(AR) $(TARGET) *.o //所有的中间.o文件打包生成目标静态库
AR = ar rcs //生成的静态库命令
TARGET = libmxml.a //生成目标静态库文件
OBJECT_LINKFILE = $(wildcard *.o) //展开目录下生成的.o文件
ALL: clear mxml //依赖目标,先执行clear,后执行mxml目标
.PHONE: ALL
clear:
ifneq ($(shell find $(TARGET)),) //如果存在已生成的静态库文件,则先删除;
rm $(TARGET)
endif
ifneq ($(OBJECT_LINKFILE),) //如果目录下存在.o链接文件,则删除
rm $(OBJECT_LINKFILE)
endif
mxml:
$(CC) -g -c *.c //gcc生成中间链接.o文件
$(AR) $(TARGET) *.o //所有的中间.o文件打包生成目标静态库
libVLMedia下Makefile文件如下:
CC = g++//编译工具为g++
AR = ar rcs
CFLAGS = -fpic -shared //编译选项
TARGET = libVLMediaBJW.so //生成目标动态库文件
OBJECT_LINKFILE = $(wildcard *.o)
LIBDIR = -lpthread -L../../cpsbase -lcpsbase //需要使用的其他的动态库
ALL: clear libVLMediaBJW
.PHONE: ALL
clear:
ifneq ($(shell find $(TARGET)),) //如果目标文件已经存在,则需要先生成
rm $(TARGET)
endif
ifneq ($(OBJECT_LINKFILE),) //删除上次已经生成的中间链接.o文件
rm $(OBJECT_LINKFILE)
endif
libVLMediaBJW:
$(CC) -g -c *.cpp //编译.cpp文件,生成中间的.o文件
$(CC) $(CFLAGS) *.o -o $(TARGET) $(LIBDIR) //链接生成动态库文件
AR = ar rcs
CFLAGS = -fpic -shared //编译选项
TARGET = libVLMediaBJW.so //生成目标动态库文件
OBJECT_LINKFILE = $(wildcard *.o)
LIBDIR = -lpthread -L../../cpsbase -lcpsbase //需要使用的其他的动态库
ALL: clear libVLMediaBJW
.PHONE: ALL
clear:
ifneq ($(shell find $(TARGET)),) //如果目标文件已经存在,则需要先生成
rm $(TARGET)
endif
ifneq ($(OBJECT_LINKFILE),) //删除上次已经生成的中间链接.o文件
rm $(OBJECT_LINKFILE)
endif
libVLMediaBJW:
$(CC) -g -c *.cpp //编译.cpp文件,生成中间的.o文件
$(CC) $(CFLAGS) *.o -o $(TARGET) $(LIBDIR) //链接生成动态库文件
libBJWTest目录下生成可执行目标代码,目录下的makefile文件如下:
CC = g++
AR = ar rcs
CFLAGS = -fpic -shared //编译选项
TARGET_INSTALL = /home/yxz/serverload_EndVersion1.0/ //目标文件安装目录
TARGET = libBJWTest
OBJECT_LINKFILE = $(wildcard *.o)
LIBDIR = -L../libBJW/ -L../libVLMediaBJW -L../libMediaBJW -L../libCoreService -L../libVLTask -L../../cpsbase -L../../mxml -lpthread -lcpsbase -lBJW -lMediaBJW -lVLMediaBJW -lVLTask -lCoreService -lmxml //生成可执行文件所需要包含的库
ALL: clear libBJWTest
.PHONE: ALL
clear:
ifneq ($(shell find $(TARGET_INSTALL)$(TARGET)),)
rm $(TARGET_INSTALL)$(TARGET)
endif
ifneq ($(shell find $(TARGET)),)
rm $(TARGET)
endif
ifneq ($(OBJECT_LINKFILE),)
rm $(OBJECT_LINKFILE)
endif
libBJWTest:
$(CC) -g -c *.cpp //编译.cpp文件生成.o链接文件
$(CC) *.o -o $(TARGET) $(LIBDIR) //生成可执行文件
mv $(TARGET) $(TARGET_INSTALL) //将可执行文件移动到安装目录中
AR = ar rcs
CFLAGS = -fpic -shared //编译选项
TARGET_INSTALL = /home/yxz/serverload_EndVersion1.0/ //目标文件安装目录
TARGET = libBJWTest
OBJECT_LINKFILE = $(wildcard *.o)
LIBDIR = -L../libBJW/ -L../libVLMediaBJW -L../libMediaBJW -L../libCoreService -L../libVLTask -L../../cpsbase -L../../mxml -lpthread -lcpsbase -lBJW -lMediaBJW -lVLMediaBJW -lVLTask -lCoreService -lmxml //生成可执行文件所需要包含的库
ALL: clear libBJWTest
.PHONE: ALL
clear:
ifneq ($(shell find $(TARGET_INSTALL)$(TARGET)),)
rm $(TARGET_INSTALL)$(TARGET)
endif
ifneq ($(shell find $(TARGET)),)
rm $(TARGET)
endif
ifneq ($(OBJECT_LINKFILE),)
rm $(OBJECT_LINKFILE)
endif
libBJWTest:
$(CC) -g -c *.cpp //编译.cpp文件生成.o链接文件
$(CC) *.o -o $(TARGET) $(LIBDIR) //生成可执行文件
mv $(TARGET) $(TARGET_INSTALL) //将可执行文件移动到安装目录中