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,進行連接。


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