标签 gflags 下的文章

“”

gflags是google的一个开源的处理命令行参数的库,使用c++开发

#include <iostream>
#include <string>

#include <gflags/gflags.h>

DEFINE_bool(a_bool_flag, true, "A Bool Flag");
DEFINE_string(ipaddr, "127.0.0.1", "IPAddress String");
DEFINE_int32(portno, 4000, "Port NO.");

static bool ipaddr_validator(
        const char* flagname,
        const std::string& ipaddr) {
    if (ipaddr.size() >= 7 && ipaddr.size() <= 15) {
        return true;
    }

    std::cerr << flagname << std::endl;
    std::cerr << "Invalid IP address: " << ipaddr << std::endl;

    return false;
}

static bool port_validator(
        const char* flagname,
        google::int32 portno) {
    if (portno > 0 && portno < 65536) {
        return true;
    }

    std::cerr << flagname << std::endl;
    std::cerr << "Invalid port: " << portno << std::endl;

    return false;
}

void func_use_flags() {
    std::cout << FLAGS_a_bool_flag << std::endl;
    std::cout << FLAGS_ipaddr << std::endl;
    std::cout << FLAGS_portno << std::endl;
}

int main(int argc, char* argv[]) {
    std::cout << google::RegisterFlagValidator(&FLAGS_ipaddr, &ipaddr_validator) << std::endl;;
    std::cout << google::RegisterFlagValidator(&FLAGS_portno, &port_validator) << std::endl;
    std::cout << "before ParseCommandLineFlags. argc : " << argc << std::endl;
    for (int i = 0; i < argc; ++i) {
        std::cout << "argv[" << i << "] : " << argv[i] << std::endl;
    }
    int r = google::ParseCommandLineFlags(&argc, &argv, false);
    std::cout << r << std::endl;
    std::cout << "after ParseCommandLineFlags. argc : " << argc << std::endl;
    for (int i = 0; i < argc; ++i) {
        std::cout << "argv[" << i << "] : " << argv[i] << std::endl;
    }

    func_use_flags();

    return 0;
}

gflags下载,安装,使用
下载地址:
官方主页:https://github.com/gflags/gflags
当前最新下载地址

wget https://github.com/gflags/gflags/archive/refs/tags/v2.2.2.tar.gz
tar xvf v2.2.2.tar.gz
cd gflags-2.2.2/
mkdir build
cd build
cmake -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DINSTALL_HEADERS=ON -DINSTALL_SHARED_LIBS=ON -DINSTALL_STATIC_LIBS=ON -DCMAKE_INSTALL_PREFIX=$(pwd)/../../install ..

不指定安装目录,就直接安装到系统里面了。
示例代码

#include "bits/stdc++.h"
using namespace std;
#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");
int main(int argc, char* argv[])
{
    google::SetVersionString("V1.0.0@const.net.cn");
    google::SetUsageMessage("-help ");
    google::ParseCommandLineFlags(&argc, &argv, true);
    std::cout << FLAGS_big_menu << std::endl;
    std::cout << FLAGS_languages << std::endl;
    return 0;
}

g++ test_gflags.cpp -o test_gflags -I ./install/include -L ./install/lib -lgflags

运行

./test_gflags -version

test_gflags version V1.0.0@const.net.cn

./test_gflags -helpshort

test_gflags: -help

Flags from test_gflags.cpp:

-big_menu (Include 'advanced' options in the menu listing) type: bool
  default: true
-languages (comma-separated list of languages to offer in the 'lang' menu)
  type: string default: "english,french,german"

./test_gflags -big_menu=false
0
english,french,german

./test_gflags -big_menu=true

1
english,french,german

./test_gflags -big_menu=true -languages=zh-cn

1
zh-cn

gflags 定义变量供多个文件使用
使用DECLARE_xxx与DEFINE_xxx方式,DECLARE_xxx在头文件中,DEFINE_xxx在源文件中。
示例:file flags.h

#ifndef FLAGS_H
#define FLAGS_H
#include "gflags/gflags.h"
#include <string>
using std::string;
DECLARE_int32(int32_var);
DECLARE_int64(int64_var);
DECLARE_bool(bool_var);
DECLARE_double(double_var);
DECLARE_uint32(uint32_var);
DECLARE_uint64(uint64_var);
DECLARE_string(string_var);
#endif 

示例:file flags.cpp

#include "flags.h"
DEFINE_int32(int32_var, 0, "int32 变量示例,默认为0");
DEFINE_int64(int64_var, 0, "int64 变量示例,默认为0");
DEFINE_bool(bool_var, true, "bool 变量示例,默认为true");
DEFINE_double(double_var, 0.0, "double 变量示例,默认为0.0");
DEFINE_uint32(uint32_var, 0, "uint32 变量示例,默认为0");
DEFINE_uint64(uint64_var, 0, "uint64 变量示例,默认为0");
DEFINE_string(string_var, "", "string 变量示例,默认为空");

示例使用:

#include "bits/stdc++.h"
#include <gflags/gflags.h>
#include "flags.h"
using namespace std;
int main(int argc, char* argv[])
{
    google::SetVersionString("V1.0.0@const.net.cn");
    google::SetUsageMessage("-help ");
    google::ParseCommandLineFlags(&argc, &argv, true);
    std::cout << FLAGS_string_var<< std::endl;
    std::cout << FLAGS_int32_var<< std::endl;
    std::cout << FLAGS_bool_var<< std::endl;
    return 0;
}

运行结果:

./test_gflags -help
Flags from flags.cpp:
    -bool_var (bool 变量示例,默认为true) type: bool default: true
    -double_var (double 变量示例,默认为0.0) type: double default: 0
    -int32_var (int32 变量示例,默认为0) type: int32 default: 0
    -int64_var (int64 变量示例,默认为0) type: int64 default: 0
    -string_var (string 变量示例,默认为空) type: string default: ""
    -uint32_var (uint32 变量示例,默认为0) type: uint32 default: 0
    -uint64_var (uint64 变量示例,默认为0) type: uint64 default: 0

在gflags的参数中,可以使用--flagfile指定flag的配置文件,而不需要在程序运行过程中指定参数。当flagfile为空时,程序指定默认值方法。以解析文件中的flags
主要代码:

gflags::SetVersionString("1.0.0");
    google::ParseCommandLineFlags(&argc, &argv, true);
    if (FLAGS_flagfile.empty()) 
    {
        google::SetCommandLineOption("flagfile", "/home/const/flag.cfg");
        cout<<"FLAGS_flagfile is empty. use default flag file.",<<endl;
    }

google::SetCommandLineOption("flagfile", "gflags_sample.flags");
FLAGS_flagfile更新后,会自动重新读取该文件并更新文件里的gflags。

该方法可以起到reload的效果,后者覆盖前者,如果后面调用的方法没有定义某flag,那么不影响前面方法已经解析出的value,类似于merge的效果。

gflags提供了一个检查传入flag值是否有效的功能,只要定义检测函数,并且注册就可以了。
检测函数以及注册方式的例子:

static bool ValidatePort(const char* flagname, int32 value) {
if (value > 0 && value < 32768) // value is ok

 return true;

printf("Invalid value for --%s: %dn", flagname, (int)value);
return false;
}
DEFINE_int32(port, 0, "What port to listen on");
static const bool port_dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
如果注册成功,regist函数返回值为ture。否则返回false,注册失败一般是一下两种原因:

第一个参数不是flag
该flag已经注册过