gtest(google test)编译(静态库*.a和动态库*.so)与使用

很久没有写博客了,毕业前一段没怎么写,毕业之后刚来到公司,熟悉环境,现在要开始恢复写博客的习惯。再此宣布我的强势回归。2013-07-19

首先说明一下gtest是单元测试的一个工具,gtest测试框架是在不同平台上(Linux,Mac OS X,Windows,Cygwin,Windows CE和Symbian)为编写C++测试而生成的。它是基于xUnit架构的测试框架,支持自动发现测试,丰富的断言集,用户定义的断言,death测试,致命与非致命的失败,类型参数化测试,各类运行测试的选项和XML的试报告

经过解压之后,在make文件夹中,有一个Makefile文件,直接make,会生成*.o文件与一个静态库文件gtest-main.a。这不是我们想要的,需要对Makefile文件进行修改:

# A sample Makefile for building Google Test and using it in user
# tests.  Please tweak it to suit your environment and project.  You
# may want to move it to your project's root directory.
#
# SYNOPSIS:
#
#   make [all]  - makes everything.
#   make TARGET - makes the given target.
#   make clean  - removes all files generated by make.

# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn't modify.

# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file.
GTEST_DIR = ..

# Where to find user code.
USER_DIR = ../samples

# Flags passed to the preprocessor.
CPPFLAGS += -I$(GTEST_DIR)/include

# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -fPIC

# All tests produced by this Makefile.  Remember to add new tests you
# created to the list.
TESTS = sample1_unittest

# All Google Test headers.  Usually you shouldn't change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
                $(GTEST_DIR)/include/gtest/internal/*.h

STATICLIB_GTEST = libgtest.a
DYLIB_GTEST = libgtest.so.6.0
# House-keeping build targets.

all : $(TESTS) $(STATICLIB_GTEST) $(DYLIB_GTEST)

clean :
	rm -f $(TESTS) $(STATICLIB_GTEST) $(DYLIB_GTEST) gtest_main.a *.o

# Builds gtest.a and gtest_main.a.

# Usually you shouldn't tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)

# For simplicity and to avoid depending on Google Test's
# implementation details, the dependencies specified below are
# conservative and not optimized.  This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
gtest-all.o : $(GTEST_SRCS_)
	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
            $(GTEST_DIR)/src/gtest-all.cc

gtest_main.o : $(GTEST_SRCS_) $(STATICLIB_GTEST)
	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c \
            $(GTEST_DIR)/src/gtest_main.cc

$(STATICLIB_GTEST) : gtest-all.o
	$(AR) $(ARFLAGS) $@ $^

gtest_main.a : gtest-all.o gtest_main.o
	$(AR) $(ARFLAGS) $@ $^
$(DYLIB_GTEST) : gtest-all.o
	$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -shared -o $@ $^


# Builds a sample test.  A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.

sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc

sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
                     $(USER_DIR)/sample1.h $(GTEST_HEADERS)
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc

sample1_unittest : sample1.o sample1_unittest.o gtest_main.a
	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

行上面的makefile就会直接生动态库libgtest.so.6.0 与静态库libgtest.a。注意:标红的是需要修改或者添加的。在编译动态库的时候添加了-fPIC,具体为什么这么用,请看http://blog.csdn.net/laoyi19861011/article/details/9404269

在讲gtest怎样使用之前,先讲一下动态链接库的连接问题:

所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib 。动态库被创建后,一般都复制到这两个目录中。当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函 数,以及该动态库的其它资源了。在 Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定:
方法一:在配置文件 /etc/ld.so.conf 中指定动态库搜索路径。每次编辑完该文件后,都必须运行命令 ldconfig 使修改后的配置生效 。我们通过例 1 来说明该方法。
例 1 :
我们通过以下命令用源程序 pos_conf.c (见程序 1 )来创建动态库 libpos.so ,
# gcc –fpic -shared  -o libpos.so pos_conf.c 
接着通过以下命令编译 main.c (见程序 2 )生成目标程序 pos 。
# gcc -o pos main.c -L. -lpos 
方法二:通过环境变量 LD_LIBRARY_PATH 指定动态库搜索路径。
方法三:在编译目标代码时指定该程序的动态库搜索路径。
还可以在编译目标代码时指定程序的动态库搜索路径。 -Wl, 表示后面的参数将传给 link 程序 ld (因为 gcc 可能会自动调用ld )。这里通过 gcc 的参数 "-Wl,-rpath," 指定(如例 3 所示)。当指定多个动态库搜索路径时,路径之间用冒号 " : " 分隔。

例 3 

我们通过以下命令用源程序 pos.c (见程序 4 )来创建动态库 libpos.so 。

# gcc -c pos.c 
         # gcc -shared -fic -o libpos.so pos.o 
          #
因为我们需要在编译目标代码时指定可执行文件的动态库搜索路径,所以需要用 gcc 命令重新编译源程序 main.c( 见程序 2) 来生成可执行文件 pos 。
# gcc -o pos main.c -L. -lpos -Wl,-rpath=.:.:.:lib

搜索动态库的先后顺序


编译目标代码时指定的动态库搜索路径


LD_LIBRARY_PATH


/etc/ld.so.cache


default path /lib, and then /usr/lib.

至于gtest的测试使用要注意的要点是:



CFLAGS	= -g -I"."
CXXFLAGS = -g -I"." -I"./gtest/include" -L"./gtest/lib" -Wl,-rpath="./gtest/lib/"
CC		= gcc
CXX		= g++
LIBS	= -lgtest -pthread

TARGETS	= gentests

gentests: $(COBJS) $(GTOBJS)
	$(CXX) $(CXXFLAGS) -Wall -Wshadow -o $@ $^ $(LIBS)


所以我在进行编译的时候,我是利用的第三种方法,在编译的时候一定要注意红色的标注出来的,一定要加-ptread,要不会出错。在就是-L”./gtest/lib",是编译寻找库的路径,而-Wl,-rpath="./gtest/lib/"是程序运行时寻找动态库的路径。还有-Wl,-rpath之间没有空格只有逗号,W要大写,l为L的小写。要注意这些。生成的动态库为libgtest.so.6.0,你还要做一步:ln -s libgtest.so libgtest.so.6.0,进行连接。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章