GFlags使用方法教程

GFlags: 方便的使用c++命令行参数

Posted by YuCong on August 17, 2020

GFlags提供了一种方便的使用c++命令行参数的解决方案。


Created 2020.08.17 by Cong Yu; Last modified: 2020.08.17-v1.0.2

Contact: windmillyucong@163.com

Copyleft! 2022 Cong Yu. Some rights reserved.


GFlags使用方法指南

References

1. 安装

1
2
3
4
5
6
7
8
git clone https://github.com/gflags/gflags

cd gflags
mkdir build
cd build
cmake ..
make -j 24
sudo make install

2. 使用

2.1 代码

头文件

1
#include <gflags/gflags.h>

定义需要使用命令行参数的变量

1
2
3
4
DEFINE_类型(变量名,默认值,描述);
DEFINE_string(img_path, "./test.png", "img to process");
DEFINE_bool(use_camera, false, "use camera or not");
DEFINE_int32(camera_id, 1, "camera id");

支持的所有类型:

gflags类型 描述
DEFINE_bool 布尔类型
DEFINE_int32 32位整数
DEFINE_int64 64位整数
DEFINE_uint64 无符号 64 位整数
DeFINE_double 浮点类型 double
DEFINE_string C++ string 类型

在main函数加入如下解析命令行参数,通常放在 main 开始位置。

在程序中使用时直接以FLAGS_ 前缀加参数名使用即可,类似于FLAGS_img_path。而且该变量也可以在程序运行时被自由修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
DEFINE_string(img_path, "./test.png", "img to process");
DEFINE_bool(use_camera, false, "use camera or not");
DEFINE_int32(camera_id, 1, "camera id");

int main(int argc, char **argv) {  
  google::InitGoogleLogging(argv[0]);  
  google::InstallFailureSignalHandler();  
  google::ParseCommandLineFlags(&argc, &argv, false);  

  std::cout << "imput image:" << FLAGS_img_path << std::endl;
  
  if (FLAGS_use_camera) {
    FLAGS_camera_id += 10; // 可以自由修改
    // balabala...
  }

}

2.2 编译

2.2.1 g++编译
1
➜ g++ hello_gflags.cpp -o hello_gflags -lgflags -lpthread
2.2.2 cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
################################## helpers ##################################  
  
################## add_third_party()  
#  
# CMake function to define a named third party library interface, with included  
# headers and linked libraries.  
#  
# Parameters:  
# NAME: name of target  
# INCLUDES: list of include directories for the library  
# LINKS: list of other libraries to be linked in to the library  
# DEFINES: list of compile definitions  
# COMPILE_OPTIONS: list of compile options  
# )  
function(ADD_THIRD_PARTY)  
    cmake_parse_arguments(ADD_THIRD_PARTY  
            ""  
            "NAME"  
            "INCLUDES;LINKS;DEFINES;COMPILE_OPTIONS"  
            ${ARGN})  
  
    unset(${ADD_THIRD_PARTY_NAME}_LIB_DEPENDS CACHE)  
    add_library(${ADD_THIRD_PARTY_NAME} INTERFACE)  
    target_include_directories(${ADD_THIRD_PARTY_NAME} INTERFACE  
            ${ADD_THIRD_PARTY_INCLUDES})  
    target_link_libraries(${ADD_THIRD_PARTY_NAME} INTERFACE  
            ${ADD_THIRD_PARTY_LINKS})  
    target_compile_definitions(${ADD_THIRD_PARTY_NAME} INTERFACE  
            ${ADD_THIRD_PARTY_DEFINES})  
    target_compile_options(${ADD_THIRD_PARTY_NAME} INTERFACE  
            ${ADD_THIRD_PARTY_COMPILE_OPTIONS})  
endfunction()


# gflags: Google Commandline Flags  
find_package(gflags CONFIG HINTS ${CMAKE_INSTALL_PREFIX})  
if (gflags_FOUND)  
    add_third_party(NAME gflag LINKS gflags)  
else (gflags_FOUND)  
    MESSAGE(FATAL_ERROR "gflag not found")  
endif ()

add_executable(hello_gflags src/hello_gflags.cpp)  
target_link_libraries(hello_gflags  
        gflags
        )

2.3 运行

2.3.1 输入参数

运行程序时,如何输入参数?

  • 用户不指定参数时,使用代码里面的默认参数
  • 用户指定参数时,可以采用两种方式:
    1. 使用 = 赋值: –flag1=值1 –flag2=值2
    2. flag名称 空格 赋值:–flag1 值1 –flag2 值2
    3. 以上两种方式可以混合使用,但是使用=赋值的方式时,无法使用tab自动补全
1
./hello_gflags --img_path=../src/pic.png --camera_id 2
  • 使用 双横线– 或者 单横线 -都是可以的

每一种类型的定义和使用都跟上面的例子相似,但是注意 bool 参数。

2.3.2 当输入bool参数时

bool 参数在命令行可以不指定值也可以指定值

1
2
3
4
5
➜  ./hello_gflags -debug_bool 		# 这样就是 true
➜  ./hello_gflags -debug_bool=true	# 这样也是 true
➜  ./hello_gflags -debug_bool=1 	# 这样也是 true
➜  ./hello_gflags -debug_bool=false # 0是false
➜  ./hello_gflags -debug_bool=0     # 0是false

但是注意使用bool变量时,不能通过空格赋值,即以下写法是无效的

1
➜  ./hello_gflags -debug_bool false

2.4 help 信息

当用户运行程序时,可能并不知道代码里面定义了哪些参数,也不知道他们的默认值是多少,则可以通过打印help信息,获取代码里的gflags信息。

1
2
3
4
5
6
7
8
➜  ./hello_gflags -help

输出:
 Flags from /home/congyu/hello_gflags.cpp
    -camera_id (camera id when using camera) type: int64 default: 4
    -img_path (img path when using image) type: string default: "./test.png"
    -use_camera (true:use camera as input or false: use a image as input)
      type: bool default: false

3. 进阶使用

3.3.1. 跨文件调用

// todo(congyu)

3.3.2. 参数检查

// todo(congyu)

3.3.3. flagfile 使用配置文件

// todo(congyu)

在一个配置文件中写上,在此将其命名为 user.flags


Contact

Feel free to contact me windmillyucong@163.com anytime for anything.

License

Creative Commons BY-SA 4.0

CC0