【gflags】【gflags实践】【gflags的学习使用记录】
0 前言
1 gflags介绍
- gflags是google开源的一套命令行参数解析工具。通常在项目开发中会有一种需求:
- 可以在代码运行的时候指定某些代码中某些参数的值
- 如果没有显式指定,这些参数可以使用默认的值
- 在工程实践中,有专门定义gflags的文件,通过–flagfile=filename来指定gflags配置文件,其他文件在使用gflags时需要先声明;通常将gflags定义在专门的配置文件中,以方便对程序运行参数管理。
- Github上的gflags项目:https://github.com/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");
,这个宏的三个参数分别是:
- 参数
config_file
:参数名 - 参数
"./config/default.yaml"
:参数的默认值 - 参数
"config file path"
:参数的说明
- gflags支持以下参数类型
- DEFINE_bool: bool
- DEFINE_int32: 32-bit integer
- DEFINE_int64: 64-bit integer
- DEFINE_uint64: unsigned 64-bit integer
- DEFINE_double: double
- 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"