最近阅读yugabyte源码时,看到代码对对gflags的使用,不甚了解,于是去简单查了一下资料学习一下。

简介

GFlags是Google开源的一套命令行参数处理的开源库,包括C++的版本和python 版本。它与其他库(例如getopt())不同之处在于flag可以定义在不同的源代码中,而不仅仅是列在一个地方。一个源码文件可以定义一些对它自己有意义的flag,同时其他任何链接了该文件的应用也都能使用这些flag。 由于这种技术,灵活性和代码重用的简易性有了显着的提高。但是,存在两个文件定义相同标志的危险,当它们链接在一起时会发生错误。

Flags定义

定义一个标志很容易:只需为您希望标志的类型使用适当的宏。 示例:

// foo.cc
#include <gflags/glags.h>

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_bool定义一个布尔标志。以下是支持的类型:

  • DEFINE_bool: 布尔值
  • DEFINE_int32: 32 位整数
  • DEFINE_int64: 64 位整数
  • DEFINE_uint64: 无符号 64 位整数
  • DEFINE_double: double浮点数
  • DEFINE_string: C++ 字符串

DEFINE宏包含三个参数:flag名、默认值、描述方法的帮助。帮助会在执行 --help flag时显示。

可以在任何源文件中定义flag,但是每个只能定义一次。如果需要在多处使用,那么在一个文件中 DEFINE ,在其他文件中 DECLARE 。比较好的方法是在 .cc 文件中 DEFINE ,在 .h 文件中 DECLARE ,这样包含头文件即可使用flag了。

Flags声明

如果我们需要在不同的文件中使用同一个flag,而每个flag有只允许定义一次。这个时候就需要用到DECLARE_type 例如我们正在写bar.cc需要访问到上面例子foo.cc中定义的big_menu, 这个时候只用在bar.cc文件的顶部声明即可。

// bar.cc
# include <gflags/glags.h>
 DECLARE_bool(big_menu);

但这种声明会在两个文件之间引入依赖关系。在大型项目中,这种隐式依赖可能难以管理。因此,当我们在foo.cc中定义了一个flag时,要么只在紧要的测试中声明它;要么就在foo.h中声明,其他要用到它的文件,只需要引入包含# foo.h即可。

Flags使用

定义的flag可以像正常的变量一样使用,只需在前面加上FLAGS_前缀。如前面例子中的定义了FLAGS_big_menuFLAGS_languages两个变量。可以像一般变量一样读写:

if (FLAGS_consider_made_up_languages)
  FLAGS_languages += ",klingon";   // implied by --consider_made_up_languages
if (FLAGS_languages.find("finnish") != string::npos)
  HandleFinnish();

命令行设置flag

对于上面的的flag,我们可以在程序启动时,指定参数: app_containing_foo --nobig_menu -languages="chinese,japanese,korean" ...

这样当我们的main函数调用:

int main(int argc, char** argv) {
    ...
    google::ParseCommandLineFlags(&argc, &argv, true);
    ...
}

后,FLAGS_big_menu = falseFLAGS_languages = "chinese,japanese,korean"

以下的几种命令行参数指定方式是有效地:

  • app_containing_foo --languages="chinese,japanese,korean"
  • app_containing_foo -languages="chinese,japanese,korean"
  • app_containing_foo --languages "chinese,japanese,korean"
  • app_containing_foo -languages "chinese,japanese,korean"

对于bool类型:

  • app_containing_foo --big_menu
  • app_containing_foo --nobig_menu
  • app_containing_foo --big_menu=true
  • app_containing_foo --big_menu=false

flagfile

如果我们定义了很多参数,那么每次启动时都在命令行指定对应的参数显然是不合理的。 这个时候,可以把 flag 参数和对应的值写在文件中,然后运行时使用 -flagfile来指定对应的 flag 文件就好

Copyright © itrunner.cn 2020 all right reserved,powered by Gitbook该文章修订时间: 2022-08-28 07:44:16

results matching ""

    No results matching ""