1、 gflags 是Google开源的命令行工具。命令行工具主要关注的是两个部分: flags 和 values。下面看,什么是flags,什么是values。
/usr/bin/myapp --name="nilboy"
在上面的命令行中,"name" 即是flags, “nilboy” 即是 values
2、在程序中,如何定义flags:
命令行的首要任务,即是将命令行中的变量值传递到程序中去。那么如何在程序中定义flags:
#include <gflags/gflags.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");
a : flag name b : default value c : help information(--help)
DEFINE_bool
: booleanDEFINE_int32
: 32-bit integerDEFINE_int64
: 64-bit integerDEFINE_uint64
: unsigned 64-bit integerDEFINE_double
: doubleDEFINE_string
: C++ string3. 声明flags:
声明flags的语法如下:
DECLARE_bool(big_menu);其本质是:
extern bool FLAGS_big_menu。
所以,很明显 声明flags的语句要放在.h 文件中,而定义flags的语句要放在.c or .cc 文件中。
3. 访问flags:
每个flags对应一个变量: 例如上面的两个flags对应的变量为:
FLAGS_big_menu FLAGS_languages
4. 如何从命令行中,读取flag和值到程序中:
google::ParseCommandLineFlags(&argc, &argv, true);参数:
argc: main函数参数
argv: main 函数参数
第三个参数: remove_flags
如果remove_flags = true,删除 argv 中所有flags 以及它们对应的参数,并且修改argc的值。
如果remove_flags = false, argc不变,调整argv 的顺序,具体顺序参考官方文档。
5. flags的value的验证:
通常情况下flags 都是需要验证它的value。
需要在main解析命令行参数之前,注册验证函数:
static bool ValidatePort(const char* flagname, int32 value) { if (value > 0 && value < 32768) // value is ok return true; printf("Invalid value for --%s: %d\n", flagname, (int)value); return false; } DEFINE_int32(port, 0, "What port to listen on"); static const bool port_dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
By doing the registration at global initialization time (right after the DEFINE), we ensure that the registration happens before the commandline is parsed at the beginning of main()
.
至于什么时候调用验证函数呢?每次通过 SetCommandLineOption()修改flag的值,或者命令行解析的时候,都会调用。如果默认或命令行解析时,validation函数返回false则报错;其他情况,返回false,则继续保持之前的值。
注:如果直接通过FLAGS_**改变flag的值,则不会调用validation函数。
6. 在命令行中传递参数的值的方法:
Note the atypical syntax for setting a boolean flag to false: putting "no" in front of its name. There's a fair bit of flexibility to how flags may be specified. Here's an example of all the ways to specify the "languages" flag:
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"
For boolean flags, the possibilities are slightly different:
app_containing_foo --big_menu
app_containing_foo --nobig_menu
app_containing_foo --big_menu=true
app_containing_foo --big_menu=false
(as well as the single-dash variant on all of these).
推荐方法:
using only a single form: --variable=value
for non-boolean flags, and --variable/--novariable
for boolean flags
==========================
#include <gflags/gflags.h> #include <iostream> using namespace std; static bool ValidatePort(const char* flagname,google::int32 value){ if(value>0 && value<100) return true; return false; } DEFINE_int32(age,10,"aaaaaa"); static const bool dummy=google::RegisterFlagValidator(&FlAGS_age, &ValidatePort);//line a int main(int argc,char *argv[]){ //google::RegisterFlagValidator(&FLAGS_age, &ValidatePort); google::ParseCommandLineFlags(&argc, &argv, false); cout<<FLAGS_age<<endl; cout<<argc<<endl; cout<<argv<<endl; return 0; }编译报错: line a FLAGS_age is not declared.
??????????????????????????????????????????????????????????????
If your application has code like this:
#define STRIP_FLAG_HELP 1 // this must go before the #include! #include <gflags/gflags.h>
we will remove the help messages from the compiled source. This can reduce the size of the resulting binary somewhat, and may also be useful for security reasons.