gflags,glog,gtest学习

1. 引言

SLAM开发过程中常会用到gflags, glog, gtest 这三件套,gflags 是参数管理工具,glog 是日志打印工具,而 gtest是单元测试工具,下面对其进行学习和初步使用。

2. gflags

直观的理解,就是对命令行参数中的flag进行管理的一个库,比如ls -l中的-l就是一个flag,后面没有跟参数。这就是最初步的理解。

先挖个坑,到时候来填:
参考1
参考2

安装:

git clone https://github.com/gflags/gflags.git
cd gflags
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_SHARED_LIBS=ON -DGFLAGS_NAMESPACE=gflags ../
make -j4
sudo make install

注意上面要设置为默认生成动态库,下面会讲到。

工程/foo.cpp:

#include 
#include 

using namespace std;

//宏定义gflags
DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");
DEFINE_string(languages, "english,french,german", "comma-separated list of languages to offer in the 'lang' menu");
DEFINE_int32(tmp, 100, "This is temp test value!");

static bool ValidatePort(const char* flagname, int value) {
   if (value > 0 && value < 32768)   // value is ok
     return true;
   printf("Invalid value for --%s: %d\n", flagname, (int)value);
   return false;
}

int main(int argc, char** argv)
{
        DEFINE_validator(tmp, &ValidatePort);
        if(tmp_validator_registered)
        {
                cout<<"tmp 定义成功"<<endl;
                cout<<"tmp值为:"<<FLAGS_tmp<<endl;
                cout<<"请输入要修改的tmp值:";
                cin>>FLAGS_tmp;
                cout<<endl<<"修改成功,修改后tmp为:"<<FLAGS_tmp<<endl;
        }
        else cout<<"tmp 定义失败"<<endl;
        return 0;
}

工程/CMakeLists.txt:

PROJECT(GFLAGS_)
FIND_PACKAGE(gflags REQUIRED)

IF (GFLAGS_INCLUDE_DIR)
MESSAGE(INFO "找到了gflags库")
ENDIF (GFLAGS_INCLUDE_DIR)

ADD_EXECUTABLE(foo foo.cpp)
TARGET_LINK_LIBRARIES(foo gflags)   #这里不是gflags::gflags,找不到

访问定义的FLAGS就直接可以当作正常的变量访问,只是需要加前缀FLAGS_,如上面定义的tmp变量,访问可以直接FLAGS_tmp:

多文件使用FLAGS需要声明,在hello.h文件中声明,然后直接#include "hello.h"就可以直接使用这个FLAGS了

ADD_EXECUTABLE(sayhello useHello.cpp)
INCLUDE_DIRECTORIES(../include)  #添加一个头文件搜索路径
FIND_PACKAGE(gflags REQUIRED)
TARGET_LINK_LIBRARIES(sayhello hello gflags)  #最最最重要的事情:千万不要忘记把所有的库都link到sayhello上

强调一定要把所有的库都link到sayhello上。

#pragma once
#include 
DECLARE_int32(tmp);  //声明FLAGS
void sayHello(); 

直接使用flags即可,因为是默认安装到usr/local/下的,所以也不用SET(PACKAGE_DIR)FIND_PACKAGE(gflags)

main

#include 
#include "hello.h"
#include 

DEFINE_int32(print_times, 1, "The print times");

int main( int argc, char** argv )
{
        gflags::ParseCommandLineFlags(&argc, &argv, true);  //用于接受命令行的flag参数并更新默认参数
        for(int i=FLAGS_print_times; i>0;--i)
          sayHello();
        std::cout<<"FLAGS_tmp的值为:"<<FLAGS_tmp<<std::endl;
        return 0;
}

gflags::ParseCommandLineFlags(&argc, &argv, true); 用于接受命令行的flag参数并更新默认参数

./sayhello -print_times 10

传入参数

3.glog

先装gflags,再装glog
但是在装glog时会出现编译动态库时不能使用静态库,

/usr/bin/ld: /usr/local/lib/libgflags.a(gflags.cc.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: 最后的链结失败: bad value
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/glog.dir/build.make:84:libglog.so.0.6.0] 错误 1
make[1]: *** [CMakeFiles/Makefile2:1102:CMakeFiles/glog.dir/all] 错误 2
make: *** [Makefile:163:all] 错误 2

所以gflags要安装动态库.so,所以前面安装时设置了DBUILD_SHARED_LIBS=ON

cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DBUILD_SHARED_LIBS=ON -DGFLAGS_NAMESPACE=gflags ../

看了半天,没发现这个glog的优势在哪,除了一些判断语句的输出,为什么不直接用cout??
先放着。

4. gtest

有tests,test suits, test programs

1.Assertions

ASSERT*EXPECT*类的函数,前者如果断言错误则直接中止程序,后者不会,更倾向于后者,很严重的断言采用ASSERT*

test/CMakeLists.txt为:

INCLUDE_DIRECTORIES(../include)  #hello.h搜索路径
FIND_PACKAGE(gflags REQUIRED)  #找到gflags包
FIND_PACKAGE(glog REQUIRED)    #找到glog包


set(CMAKE_CXX_STANDARD 11)
include(FetchContent)  #载入模块
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

#后面又添加的
enable_testing()
add_executable(  main_test  main_test.cpp)
target_link_libraries(main_test  gtest_main hello gflags glog)

#使CMake runner能够在二进制中找到测试,使用GoogleTest模块
include(GoogleTest)  #用来载入 CMakeLists.txt 文件,也用于载入预定义的 cmake 模块. INCLUDE(file1 [OPTIONAL])  INCLUDE(module [OPTIONAL])
gtest_discover_tests(main_test) 

test/main_test.cpp为:

#include 
#include 
#include 
#include 

TEST(FactorialTest, ZeroInput){
        EXPECT_EQ(my_fac(0), 1);
}
TEST(FactorialTest, PositiveInput){
        EXPECT_EQ(my_fac(1), 1);
        EXPECT_EQ(my_fac(2), 2);
        EXPECT_EQ(my_fac(3), 6);
}

你可能感兴趣的:(SLAM,Ubuntu,slam,ubuntu,c++)