【gflags】【gflags实践】【gflags的学习使用记录】

0 前言

1 gflags介绍

  • gflags是google开源的一套命令行参数解析工具。通常在项目开发中会有一种需求:
  1. 可以在代码运行的时候指定某些代码中某些参数的值
  2. 如果没有显式指定,这些参数可以使用默认的值
  3. 在工程实践中,有专门定义gflags的文件,通过–flagfile=filename来指定gflags配置文件,其他文件在使用gflags时需要先声明;通常将gflags定义在专门的配置文件中,以方便对程序运行参数管理。

2 gflags安装

参考:【多传感器融合定位】【ubuntu18.06配置环境】【ROS melodic】【g2o】【ceres】【Geographic】【gflags】【glog】【sophus】【GTSAM】【gtest】

3 gfalgs使用

3.1 CMakeLists.txt

# gflags
find_package(GFlags REQUIRED)
include_directories(${
    
    GFLAGS_INCLUDE_DIRS})

add_executable(xxx xxx.cpp)
target_link_libraries(xxx  ${
    
    GFLAGS_LIBRARIES})

3.2 头文件

#include <gflags/gflags.h>

3.3 使用

3.3.1 使用案例一,slam十四讲的cmake使用

3.3.1.1 案例代码

参考:【slam十四讲第二版】【课本例题代码向】【第十三讲~实践:设计SLAM系统】的3.2.1 run_kitti_stereo.cpp

//
// Created by gaoxiang on 19-5-4.
//

#include <gflags/gflags.h>
#include "myslam/visual_odometry.h"

DEFINE_string(config_file, "./config/default.yaml", "config file path");

int main(int argc, char **argv) {
    
    

    // 解析gflags参数,只需要1行代码
    google::ParseCommandLineFlags(&argc, &argv, true);
    //gflags::ParseCommandLineFlags(&argc, &argv, true);
    myslam::VisualOdometry::Ptr vo(
        new myslam::VisualOdometry(FLAGS_config_file));
    //assert(vo->Init() == true);//注释去这句话my_czy
    vo->Init();
    vo->Run();

    return 0;
}

3.3.1.2 使用说明

3.3.1.2.1 使用前定义要使用的参数
  • DEFINE_string(config_file, "./config/default.yaml", "config file path");,这个宏的三个参数分别是:
  1. 参数config_file:参数名
  2. 参数"./config/default.yaml":参数的默认值
  3. 参数 "config file path":参数的说明
  • gflags支持以下参数类型
  1. DEFINE_bool: bool
  2. DEFINE_int32: 32-bit integer
  3. DEFINE_int64: 64-bit integer
  4. DEFINE_uint64: unsigned 64-bit integer
  5. DEFINE_double: double
  6. DEFINE_string: C++ string
3.3.1.2.2 参数的使用
  • 使用参数要在参数名前加上FLAG_
  • 例如前面代码中的FLAGS_config_file
3.3.1.2.3 必要的初始化
  • 在main函数开始时要初始化flags
  • 例如前面代码中google::ParseCommandLineFlags(&argc, &argv, true);
3.3.1.2.4 DECLARE_XXX的使用
  • 参考3.3.4.1.2 主文件的DECLARE_声明
3.3.1.2.4 执行可执行文件常用的特殊flag
  • --help 显示所有文件的所有flag,按文件、名称排序,显示flag名、默认值和帮助

  • --helpshort 只显示执行文件中包含的flag,通常是 main() 所在文件

  • --version 打印执行文件的版本信息

3.3.2 使用案例二,简单c++编译

摘自:gflags简明使用指南

3.3.2.1 案例代码

//test2.cc
#include <iostream>
#include <string>
#include <gflags/gflags.h> //gflags库的头文件
//else header file

#define LOG

DEFINE_string(ip, "127.0.0.1", "IP address");
DEFINE_int32(port, 8080, "port");

class Server{
    
    
public:
  Server(const std::string& ip, uint16_t port) : _ip(ip), _port(port) {
    
    
    std::cout << "Init Server..." << std::endl;
#ifdef LOG 
    std::cout << "ip  : " << _ip << std::endl;
    std::cout << "port: " << _port << std::endl;
#endif
    std::cout << "Init OK!" << std::endl;
  }
  //else code
private:
  std::string _ip;
  uint16_t _port;
  //else code
};


int main(int argc, char* argv[]) {
    
    
  gflags::ParseCommandLineFlags(&argc, &argv, true);  
  Server* pserver = new Server(FLAGS_ip, FLAGS_port);

  return 0;
}

3.3.2.2 编译方式

g++ test2.cc -o test2 -lgflags -lpthread
  • 在编译的时候要加上-lgflags和-lpthread,因为gflags内部是需要POSIX线程库支持的,所以还需要加上-lpthread。
  • 除了这两个外,也需要指定你安装的gflags的库文件(gcc选项:-L)和头文件(gcc选项:-I)。由于我把这两个放到了系统默认寻找的路径,所以在编译的时候没有显式指定。

3.3.3 使用案例三,运行可执行文件的参数设置

3.3.3.1 案例代码

  • simple_gflags.cpp
#include <iostream>
#include "gflags/gflags.h"  
 
// 定义gflags
DEFINE_bool(foo, false, "a simple gflags named foo, default value is flase, wuruilong, 2018-08-16");
DEFINE_int32(thread_num, 10, "thread number, default value is 10, wuruilong, 2018-08-16");
 
int main(int argc, char **argv) {
    
    
  // 解析gflags参数,只需要1行代码
  google::ParseCommandLineFlags(&argc, &argv, true);
 
  // 使用gflags
  if (FLAGS_foo) {
    
    
    std::cout << "foo is true" << std::endl;
  } else {
    
    
    std::cout << "foo is false" << std::endl;
  }
 
  // 使用gflags
  int thread_num = FLAGS_thread_num;
  std::cout << "thread number:" << thread_num << std::endl;
  return 0;
}

3.3.3.2 编译方式

g++ simple_gflags.cpp -I./gflags-2.0/src -L./ -lgflags

3.3.3.3 运行方式

3.3.3.3.1 无参数
./a.out

输出:

foo is false
thread number:10
3.3.3.3.2 指定单个参数
./a.out -foo=true

输出:

foo is true
thread number:10
3.3.3.3.3 指定多个参数
./a.out -foo=true -thread_num=99

输出:

foo is true
thread number:99

3.3.4 使用案例四,配置gflags文件

3.3.4.1 案例代码

  • 下面是工程实践中使用gflags的例子,新开发的功能用bool类型的gflags包住,新旧代码互不干扰,在gflags开关没有打开时,就好像没有这段代码一样。从这个例子中可以看到gflags在多人开发模式中也能发挥很大的作用。
3.3.4.1.1 专门定义gflags的头文件gflags_def.cpp
#include "gflags/gflags.h"
 
// 定义gflags
DEFINE_bool(add_new_feature_x, false, "x feature, gaojingying, 2018-08-16");
DEFINE_bool(add_new_featrue_y, false, "y feature, xiechao, 2018-08-16");
DEFINE_bool(fix_memory_leak_bug, false, "fix memory leak bug, xiechao, 2018-08-16");
DEFINE_bool(fix_cpu_high_bug, false, "fix cpu high bug, xiechao, 2018-08-16");
DEFINE_int32(thread_pool_worker_num, 10, "thread pool worker number, default value is 10, ligang, 2018-08-16");
DEFINE_string(server_ip, "127.0.0.1", "x server's ip address, gaojingying, 2018-08-16");
3.3.4.1.2 主文件的DECLARE_声明
  • 其他文件中使用gflags之前,需要先通过DECLARE_声明。
  • main.cpp
#include <iostream>
#include <string>
#include <cstdio>
#include "gflags/gflags.h"
 
// 声明gflags
DECLARE_bool(add_new_feature_x);
DECLARE_bool(add_new_featrue_y);
DECLARE_bool(fix_memory_leak_bug);
DECLARE_bool(fix_cpu_high_bug);
DECLARE_int32(thread_pool_worker_num);
DECLARE_string(server_ip);
 
void Work(std::string &name) {
    
    
  name = "feature";
  // 启用x功能
  if (FLAGS_add_new_feature_x) {
    
    
    name += "_x";
  }
 
  // 启用y功能
  if (FLAGS_add_new_featrue_y) {
    
    
    name += "_y";
  }
 
  char *value = new char[100];
  snprintf(value, 100, "thread number: %d", FLAGS_thread_pool_worker_num);
  name = name + "," + value + "," + FLAGS_server_ip;
 
  // 留下消缺记录
  if (FLAGS_fix_memory_leak_bug) {
    
    
    delete []value;
  }
}
 
int main(int argc, char **argv) {
    
    
  google::ParseCommandLineFlags(&argc, &argv, true);
 
  std::string name;
  Work(name);
  std::cout << name << std::endl;
  return 0;
}

3.3.4.2 编译方式

g++ main.cpp gflags_def.cpp –I./gflags-2.0/src -L./ -lgflags

3.3.4.3 运行

3.3.4.3.1 配置.gflags文件
  • gflags配置文件demo_project.gflags
-add_new_feature_x=false
-add_new_featrue_y=true
-fix_memory_leak_bug=true
-fix_cpu_high_bug=false
-thread_pool_worker_num=20
-server_ip="127.0.0.1"
3.3.4.3.2 运行
3.3.4.3.2.1 不指定gflags配置文件
./a.out

输出:

feature,thread number: 10,127.0.0.1
3.3.4.3.2.2 指定gflags配置文件
./a.out --flagfile=demo_project.gflags

输出:

feature_x,thread number: 20,"127.0.0.1"
3.3.4.3.2.3 测试修改.gfalgs演示
  • 修改demo_project.gflags,关闭feature_x功能,启用feature_y功能:
./a.out --flagfile=demo_project.gflags

输出:

feature_y,thread number: 20,"127.0.0.1"

4 参考

  1. gflags简明使用指南
  2. 【多传感器融合定位】【ubuntu18.06配置环境】【ROS melodic】【g2o】【ceres】【Geographic】【gflags】【glog】【sophus】【GTSAM】【gtest】
  3. 后端系统开发利器,gflags概述

猜你喜欢

转载自blog.csdn.net/qq_45954434/article/details/126343147