欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用makefie编译具有子目录结构的动态库文件和动态库的测试文件

程序员文章站 2024-03-11 20:00:31
...

需求:我需要写一个根目录makefile和许多子目录makefile,编译动态库文件libnck.so,同时,我还需要编译一个测试动态库文件的可执行测试文件libtest.

先用tree查看我的目录结构

用makefie编译具有子目录结构的动态库文件和动态库的测试文件

debug就是用于处理所有动态库文件的.o文件和可执行文件的目录

相对于makefile来说比较关键,需要创建debug/bin和debug/obj和debug/test和debug/test/test_bug和debug/test/test_bug/bin和debug/test/test_bug/obj文件夹,而debug/test/main.cpp就是我的测试文件源文件,如果需要更复杂的源文件结构,也可以在debug/test/下建立关于测试文件的源文件目录结构.

debug/obj 下存放根目录下的源文件编译的o文件

debug/bin 存放debug/obj链接的来的动态库文件

debug/test目录下存放着测试文件相关的所有文件

debug/test/test_bug 处理测试文件的编译

debug/test/test_bug/obj 下存放debug/test目录下的测试文件的源文件编译的o文件

debug/test/test_bug/bin  存放debug/test/test_bug/obj链接的来的测试文件

 

bus  decode目录是我的动态库的源文件和头文件目录,他们的子目录下的makefile都是一样的:

./makefile  也就是根目录的makefile如下

#设置编译器
CC       = gcc
CPP 	 = g++
LINK     = g++
CFLAGS   = -Wall -g -O -fPIC #需要加上 -fPIC
CXXFLAGS = -Wall -g -O -fPIC #需要加上 -fPIC
#LIB_TARGET是动态库的目标文件
LIB_TARGET   = libnck.so
TEST_TARGET  = libtest
CLIBS        =
SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "debug") print $$9}')
#无需下一行的注释代码,因为我们已经知道debug里的makefile是最后执行的,所以最后直接去debug目录下执行指定的makefile文件就行,具体下面有注释
DEBUG=$(shell ls -l | grep ^d | awk '{if($$9 == "debug") print $$9}')
#记住当前工程的根目录路径
ROOT_DIR=$(shell pwd)
INC = -I$(ROOT_DIR) -I$(ROOT_DIR)/bus -I$(ROOT_DIR)/decode 
#目标文件所在的目录
OBJS_DIR=$(DEBUG)/obj

#bin文件所在的目录
BIN_DIR=$(DEBUG)/bin
#获取当前目录下的c文件集,放在变量CUR_SOURCE中
CCUR_SOURCE=${wildcard *.c}
CPPCUR_SOURCE = ${wildcard *.cpp}
#将对应的c文件名转为o文件后放在下面的CUR_OBJS变量中
CCUR_OBJS=${patsubst %.c, %.o, $(CCUR_SOURCE)} 
CPPCUR_OBJS=${patsubst %.cpp, %.o, $(CPPCUR_SOURCE)} 
#将以下变量导出到子shell中,本次相当于导出到子目录下的makefile中
export CC CPP LINK OBJS_DIR BIN_DIR ROOT_DIR CFLAGS CXXFLAGS INC LIB_TARGET TEST_TARGET CLIBS
#注意这里的顺序,需要先执行SUBDIRS最后才能是DEBUG
all:$(SUBDIRS) $(CCUR_OBJS) $(CPPCUR_OBJS) $(DEBUG)
#递归执行子目录下的makefile文件,这是递归执行的关键
$(SUBDIRS):ECHO
	make -C aaa@qq.com
#直接去debug目录下执行makefile文件
$(DEBUG):ECHO
	make -C aaa@qq.com
ECHO:
	@echo $(SUBDIRS)
#将c文件编译为o文件,并放在指定放置目标文件的目录中即OBJS_DIR
$(CCUR_OBJS):%.o:%.c
	$(CC) -c -pthread $(INC) $(CFLAGS) $^ -o $(ROOT_DIR)/$(OBJS_DIR)/aaa@qq.com
$(CPPCUR_OBJS):%.o:%.cpp
	$(CPP) -c -pthread $(INC) $(CXXFLAGS) $^ -o $(ROOT_DIR)/$(OBJS_DIR)/aaa@qq.com

.PHONY:clean
clean:
	@rm -rf $(OBJS_DIR)/*.o
	@rm -rf $(BIN_DIR)/*
	@cd $(DEBUG); make clean

上图的代码大部分我借鉴了https://www.cnblogs.com/Shirlies/p/4282182.html这篇博客的结构

decode/makefile 和bus/makefile一样,内容如下

#子目录的Makefile直接读取其子目录就行
SUBDIRS=$(shell ls -l | grep ^d | awk '{print $$9}')
#以下同根目录下的makefile的相同代码的解释
CCUR_SOURCE=${wildcard *.c}
CPPCUR_SOURCE=${wildcard *.cpp}
CCUR_OBJS=${patsubst %.c, %.o, $(CCUR_SOURCE)}
CPPCUR_OBJS=${patsubst %.cpp, %.o, $(CPPCUR_SOURCE)}
all:$(SUBDIRS) $(CCUR_OBJS) $(CPPCUR_OBJS)
$(SUBDIRS):ECHO
	make -C aaa@qq.com
$(CCUR_OBJS):%.o:%.c
	$(CC) -c -pthread $(INC) $(CFLAGS) $^ -o $(ROOT_DIR)/$(OBJS_DIR)/aaa@qq.com
$(CPPCUR_OBJS):%.o:%.cpp
	$(CPP) -c -pthread $(INC) $(CXXFLAGS) $^ -o $(ROOT_DIR)/$(OBJS_DIR)/aaa@qq.com
ECHO:
	@echo $(SUBDIRS)

debug目录下的makefiile结构我写得有点复杂,我一一阐明:

debug/makefile内容如下:

OBJS=*.o
ODIR=obj
TEST_DIR=test
all:$(ROOT_DIR)/$(BIN_DIR)/$(LIB_TARGET) $(TEST_DIR)
$(ROOT_DIR)/$(BIN_DIR)/$(LIB_TARGET):$(ODIR)/$(OBJS)
	$(LINK)  $(LIBS) -Wall -fPIC -shared -o aaa@qq.com $^


$(TEST_DIR):ECHO
	make -C aaa@qq.com
ECHO:
	@echo $(TEST_DIR)

.PHONY:clean
clean:
	@cd $(TEST_DIR); make clean

 

debug/test/makefile:

#书写用于测试动态库的可执行文件libtest的makefile
#子目录的Makefile直接读取其子目录就行
SUBDIRS=$(shell ls -l | grep ^d | awk '{if($$9 != "test_debug") print $$9}')
#以下同根目录下的makefile的相同代码的解释
TEST_DEBUGDIR = $(shell pwd)/test_debug
CCUR_SOURCE=${wildcard *.c}
CPPCUR_SOURCE=${wildcard *.cpp}
CCUR_OBJS=${patsubst %.c, %.o, $(CCUR_SOURCE)}
CPPCUR_OBJS=${patsubst %.cpp, %.o, $(CPPCUR_SOURCE)}
OBJS  = obj
all:$(SUBDIRS) $(CCUR_OBJS) $(CPPCUR_OBJS) $(TEST_DEBUGDIR)
$(SUBDIRS):ECHO
	make -C aaa@qq.com
$(CCUR_OBJS):%.o:%.c
	$(CC) -c -pthread $(INC) $(CFLAGS) $^ -o $(TEST_DEBUGDIR)/$(OBJS)/aaa@qq.com
$(CPPCUR_OBJS):%.o:%.cpp
	$(CPP) -c -pthread $(INC) $(CXXFLAGS) $^ -o $(TEST_DEBUGDIR)/$(OBJS)/aaa@qq.com
$(TEST_DEBUGDIR):ECHO
	make -C aaa@qq.com
ECHO:
	@echo $(SUBDIRS)
.PHONY:clean
clean:
	@cd $(TEST_DEBUGDIR); make clean

 

debug/test/test_debug/makefile:

OBJS=*.o
ODIR=obj
BDIR=bin
TEST_DIR=test
all:$(BDIR)/$(TEST_TARGET) 
$(BDIR)/$(TEST_TARGET):$(ODIR)/$(OBJS)
	$(LINK)  $(LIBS) -Wall -o aaa@qq.com $^
.PHONY:clean
clean:
	rm -rf $(ODIR)/*.o
	rm -rf $(BDIR)/*

 

相关标签: makefile