gflags的使用(转载)

google开源的gflags是一套命令行参数解析工具,比getopt功能更强大,使用起来更加方便,gflags还支持从环境变量、配置文件读取参数(可用gflags代替配置文件)。本文简单介绍gflags的使用,内容主要译自 http://gflags.googlecode.com/svn/trunk/doc/gflags.html 。

定义参数 

使用flags需要包含头文件 

()
#include <gflags/gflags.h>
 
  
  

gflags主要支持的参数类型包括bool,int32, int64, uint64, double, string等,定义参数通过DEFINE_type宏实现,如下所示,分别定义了一个bool和一个string类型的参数,该宏的三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息。


 
  
  
  1. DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing"); 
  2. DEFINE_string(languages, "english,french,german"
  3.                  "comma-separated list of languages to offer in the 'lang' menu"); 

gflag不支持列表,用户通过灵活借助string参数实现,比如上述的languages参数,可以类型为string,但可看作是以逗号分割的参数列表。

访问参数 

当参数被定义后,通过FLAGS_name就可访问到对应的参数,比如上述定义的big_menu、languages两个参数就可通过FLAGS_big_menu、FLAGS_languages访问。


 
  
  
  1. if (FLAGS_languages. find( "english") != string::npos) 
  2.      HandleEnglish(); 

以上的访问方式,仅在参数定义和访问在同一个文件(或是通过头文件包含)时,FLAGS_name才能访问到参数,如果要访问其他文件里定义的参数,则需要使用DECLARE_type。比如在foo.cc中DEFINE_string(color, "red", "the color you want to use"); 这时如果你需要在foo_test.cc中使用color这个参数,你需要加入DECLARE_string(color, "red", "the color you want to use");

参数检查 

定义参数后,可以给参数注册一个检查函数(validator),当从命令行指定参数或通过SetCommandLineOption()指定参数时,检查函数就会被调用,两个参数分别为命令行参数名,以及设置的参数值。 


 
  
  
  1. static bool ValidatePort(const char* flagname, int32 value)
  2.    if (value > 0 && value < 32768)   // value is ok 
  3.      return true
  4.    printf( "Invalid value for --%s: %d\n", flagname, ( int)value); 
  5.    return false
  6. DEFINE_int32(port, 0, "What port to listen on"); 
  7. static const bool port_dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort); 

建议在定义参数后,立即注册检查函数。RegisterFlagValidator()在检查函数注册成功时返回true;如果参数已经注册了检查函数,或者检查函数类型不匹配,返回false。

初始化参数 

在引用程序的main()里通过 google::ParseCommandLineFlags(&argc, &argv, true); 即完成对gflags参数的初始,其中第三个参数为remove_flag,如果为true,gflags会移除parse过的参数,否则gflags就会保留这些参数,但可能会对参数顺序进行调整。 比如 "/bin/foo" "arg1" "-q" "arg2"  会被调整为 "/bin/foo", "-q", "arg1", "arg2",这样更好理解。


 
  
  
  1. #include <iostream>
  2. #include <gflags/gflags.h>
  3. DEFINE_bool(isvip, false, "If Is VIP");
  4. DEFINE_string(ip, "127.0.0.1", "connect ip");
  5. DECLARE_int32(port);
  6. DEFINE_int32(port, 80, "listen port");
  7. int main(int argc, char** argv)
  8. {
  9. google:: ParseCommandLineFlags(&argc, &argv, true);
  10. std::cout<< "ip:"<<FLAGS_ip<<std::endl;
  11. std::cout<< "port:"<<FLAGS_port<<std::endl;
  12. if (FLAGS_isvip)
  13. {
  14. std::cout<< "isvip:"<<FLAGS_isvip<<std::endl;
  15. }
  16. google:: ShutDownCommandLineFlags();
  17. return 0;
  18. }

链接时使用 -gflags ,运行使用 ./gflags -ip="211.152.52.106" -port=8080 -isvip=true ,但是很遗憾,使用 valgrind 检测有内存泄漏。

输出结果如下:


 
  
  
  1. ip:211.152.52.106
  2. port:8080
  3. isvip:1

在命令行指定参数 

比如要在命令行指定languages参数的值,可通过如下4种方式,int32, int64等类型与string类似。

  • 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

特殊参数

  • --help 打印定义过的所有参数的帮助信息
  • --version 打印版本信息 通过google::SetVersionString()指定
  • --nodefok  但命令行中出现没有定义的参数时,并不退出(error-exit)
  • --fromenv 从环境变量读取参数值 --fromenv=foo,bar表明要从环境变量读取foo,bar两个参数的值。通过export FLAGS_foo=xxx; export FLAGS_bar=yyy 程序就可读到foo,bar的值分别为xxx,yyy。
  • --tryfromenv 与--fromenv类似,当参数的没有在环境变量定义时,不退出(fatal-exit)
  • --flagfile 从文件读取参数值,--flagfile=my.conf表明要从my.conf文件读取参数的值。在配置文件中指定参数值与在命令行方式类似,另外在flagfile里可进一步通过--flagfile来包含其他的文件。

Caffe实例解析:

以 tools/caffe.cpp 为例分析gflags使用方法
在tools/caffe.cpp中首先包含了gflags的头文件

#include <gflags/gflags.h>
 
  
  

命令行参数传递

接下来定义了一些需要从命令行传递参数的变量


 
  
  
  1. DEFINE_string(gpu, "",
  2.     "Optional; run in GPU mode on given device IDs separated by ','."
  3.     "Use '-gpu all' to run on all available GPUs. The effective training "
  4.     "batch size is multiplied by the number of devices.");
  5. DEFINE_string(solver, "",
  6.     "The solver definition protocol buffer text file.");
  7. DEFINE_string(model, "",
  8.     "The model definition protocol buffer text file.");
  9. DEFINE_string(phase, "",
  10.     "Optional; network phase (TRAIN or TEST). Only used for 'time'.");
  11. DEFINE_int32(level, 0,
  12.     "Optional; network level.");
  13. ......

这些参数使用gflags提供的宏:DEFINE_xxx(变量名,默认值,help_string)。这些变量需要在全局范围内定义。变量支持以下类型:

定义  类型
DEFINE_bool 布尔型
DEFINE_int32 32位整形
DEFINE_int64 64位整形
DEFINE_uint64 64位无符号整形
DEFINE_double double型
DEFINE_string C++中string类型

在main函数中调用的GlobalInit()函数中调用了ParseCommandLineFlags()


 
  
  
  1. // Google flags.
  2. ::gflags:: ParseCommandLineFlags(pargc, pargv, true);

这个函数的作用就是解析命令行参数。 
pargc,pargv为命令行传递的参数个数和参数表,第三个参数作用为:

作用
true 函数处理完成后,argv中只保留argv[0],argc会被设置为1。
false argv和argc会被保留,但是注意函数会调整argv中的顺序。

执行完这参数后,就可以用FLAGS_xxx访问变量了。 
例如caffe.cpp中, FLAGS_solve表示命令行参数传递的模型文件,FLAGS_weights表示令行参数传递的权值文件


 
  
  
  1. // Train / Finetune a model.
  2. int train() {
  3.   CHECK_GT(FLAGS_solver. size(), 0) << "Need a solver definition to train.";
  4.   CHECK(!FLAGS_snapshot. size() || !FLAGS_weights. size())
  5.       << "Give a snapshot to resume training or weights to finetune "
  6.       "but not both.";

帮助信息

gflags::SetUsageMessage函数用于设置命令行帮助信息。


 
  
  
  1. // Usage message.
  2.   gflags:: SetUsageMessage( "command line brew\n"
  3.       "usage: caffe <command> <args>\n\n"
  4.       "commands:\n"
  5.       "  train           train or finetune a model\n"
  6.       "  test            score a model\n"
  7.       "  device_query    show GPU diagnostic information\n"
  8.       "  time            benchmark model execution time");

设置帮助信息后,当参数错误或加 -help选项是可以打印帮助信息


 
  
  
  1. $ ./build/tools/caffe
  2. caffe: command line brew
  3. usage: caffe < command> <args>
  4. commands:
  5.   train           train or finetune a model
  6.   test            score a model
  7.   device_query    show GPU diagnostic information
  8.   time            benchmark model execution time
  9. ...

版本信息

gflags::SetVersionString用于设置版本信息


 
  
  
  1.   // Set version
  2.   gflags:: SetVersionString( AS_STRING(CAFFE_VERSION));

这里的CAFFE_VERSION是在Makefile中定义的 
当命令行参数加 -version 时会打印版本信息

$ ./build/tools/caffe -version
 
  
  

caffe version 1.0.0-rc3

</article>

google开源的gflags是一套命令行参数解析工具,比getopt功能更强大,使用起来更加方便,gflags还支持从环境变量、配置文件读取参数(可用gflags代替配置文件)。本文简单介绍gflags的使用,内容主要译自 http://gflags.googlecode.com/svn/trunk/doc/gflags.html 。

定义参数 

使用flags需要包含头文件 

()

猜你喜欢

转载自blog.csdn.net/xp178171640/article/details/121494586