文章目录
- [一、gflags 介绍](#一、gflags 介绍)
- [二、gflags 安装](#二、gflags 安装)
-
- [1. 直接命令安装(适用于 Ubuntu/Debian 系统)](#1. 直接命令安装(适用于 Ubuntu/Debian 系统))
- [2. 源码编译安装](#2. 源码编译安装)
- [三、gflags 使用](#三、gflags 使用)
-
- [1. 包含头文件](#1. 包含头文件)
- [2. 定义参数](#2. 定义参数)
-
- [2.1 定义参数的方法](#2.1 定义参数的方法)
- [2.2 定义参数的作用解析](#2.2 定义参数的作用解析)
- [3. 修改定义参数](#3. 修改定义参数)
-
- [3.1 命令行输入 修改定义参数](#3.1 命令行输入 修改定义参数)
- [3.2 通过配置文件 修改定义参数](#3.2 通过配置文件 修改定义参数)
- [4. 不同文件访问参数(主文件 DEFINE_类型 定义,其它文件 DECLARE_类型 声明)](#4. 不同文件访问参数(主文件 DEFINE_类型 定义,其它文件 DECLARE_类型 声明))
- [5. 特殊参数标识(如何查看定义参数时 指定的帮助信息)](#5. 特殊参数标识(如何查看定义参数时 指定的帮助信息))
一、gflags 介绍
gflags 是 Google 开发的一个开源库,用于 C++ 应用程序中命令行参数的声明、定义和解析。
gflags 库提供了一种简单的方式来添加、解析和文档化命令行标志(flags),使得程序可以根据不同的运行时配置进行调整。
它具有如下几个特点:
- 易于使用: gflags 提供了一套简单直观的 API 来定义和解析命令行标志,使得开发者可以轻松地为应用程序添加新的参数。
- 自动帮助和文档: gflags 可以自动生成每个标志的帮助信息和文档,这有助于用户理解如何使用程序及其参数。
- 类型安全: gflags 支持多种数据类型的标志,包括布尔值、整数、字符串等,并且提供了类型检查和转换。
- 多平台支持: gflags 可以在多种操作系统上使用,包括 Windows、Linux 和 macOS。
- 可扩展性: gflags 允许开发者自定义标志的注册和解析逻辑,提供了强大的扩展性。
二、gflags 安装
1. 直接命令安装(适用于 Ubuntu/Debian 系统)
(1)步骤:
bash
sudo apt-get update # 更新软件源
sudo apt-get install libgflags-dev # 安装开发库
(2)特点:
- 简单快捷:适合快速部署,无需手动编译。
- 版本受限:依赖系统仓库的版本,可能非最新(如 Ubuntu 20.04 默认版本较旧)。
(3)验证安装:
- 检查头文件:ls /usr/include/gflags/
- 检查库文件:ls /usr/lib/x86_64-linux-gnu/libgflags*

2. 源码编译安装
bash
# 下载源码
git clone https://github.com/gflags/gflags.git
# 切换目录
cd gflags/
# 创建并进入构建目录
mkdir build
cd build/
# 执行构建命令,生成 Makefile
cmake ..
# 编译代码
make
# 安装到系统目录(默认 /usr/local)
sudo make install

至此,gflags 安装完毕。
三、gflags 使用
1. 包含头文件
使用 gflags 库来定义/解析命令行参数必须包含如下头文件
cpp
#include <gflags/gflags.h>
2. 定义参数
2.1 定义参数的方法
利用 gflag 提供的宏定义来定义参数。该宏的 3 个参数分别为参数名,参数默认值,参数的帮助信息。
- 基本形式:
cpp
DEFINE_<类型>(参数名, 默认值, "帮助信息");
- gflags 支持定义多种类型的宏函数:
仅支持基本类型,不支持自定义类型
cpp
DEFINE_bool
DEFINE_int32
DEFINE_int64
DEFINE_uint64
DEFINE_double
DEFINE_string
- 使用示例:
cpp
DEFINE_bool(reuse_addr, true, "是否开始网络地址重用选项");
DEFINE_int32(log_level, 1, "日志等级: 1-DEBUG, 2-WARN, 3-ERROR");
DEFINE_string(log_file, "stdout", "日志输出位置设置,默认为标准输出");
2.2 定义参数的作用解析
- 项目结构:
bash
.
├── main.cc
└── Makefile
./main.cc
cpp
#include <gflags/gflags.h>
#include <iostream>
// 设置 bool FLAGS_reuse_addr = true; 的全局变量
DEFINE_bool(reuse_addr, true, "是否开始网络地址重用选项");
// 设置 int32_t FLAGS_log_level = 3; 的全局变量
DEFINE_int32(log_level, 3, "日志等级: 1-DEBUG, 2-WARN, 3-ERROR");
// 设置 std::string FLAGS_log_file = "stdout"; 的全局变量
DEFINE_string(log_file, "stdout", "日志输出位置设置,默认为标准输出");
int main()
{
std::cout << "FLAGS_reuse_addr: " << FLAGS_reuse_addr << std::endl;
std::cout << "FLAGS_log_level: " << FLAGS_log_level << std::endl;
std::cout << "FLAGS_log_file: " << FLAGS_log_file << std::endl;
return 0;
}

./Makefile
链接时,-l显式指定库名:gflags
bash
main:main.cc
g++ -o main main.cc -lgflags
- make执行编译链接过程,形成可执行文件main。再运行main,查看执行结果:

3. 修改定义参数
3.1 命令行输入 修改定义参数
cpp
#include <gflags/gflags.h>
#include <iostream>
// 设置 bool FLAGS_reuse_addr = true; 的全局变量
DEFINE_bool(reuse_addr, true, "是否开始网络地址重用选项");
// 设置 int32_t FLAGS_log_level = 3; 的全局变量
DEFINE_int32(log_level, 3, "日志等级: 1-DEBUG, 2-WARN, 3-ERROR");
// 设置 std::string FLAGS_log_file = "stdout"; 的全局变量
DEFINE_string(log_file, "stdout", "日志输出位置设置,默认为标准输出");
int main(int argc, char* argv[])
{
// 遍历 argv 数组,识别 --参数名=值 或 --参数名 值 格式的字符串
// 根据命令行指示,修改所有定义参数
gflags::ParseCommandLineFlags(&argc, &argv, true);
std::cout << "FLAGS_reuse_addr: " << FLAGS_reuse_addr << std::endl;
std::cout << "FLAGS_log_level: " << FLAGS_log_level << std::endl;
std::cout << "FLAGS_log_file: " << FLAGS_log_file << std::endl;
return 0;
}


gflags 为我们提供了多种命令行设置参数的方式:
(1)string 和 int 设置参数
- main --参数名=值
- main -参数名=值
- main --参数名 值
- main -参数名 值
(2)bool 设置参数
- main --参数名
- main --no参数名
- main --参数名=true
- main --参数名=false
3.2 通过配置文件 修改定义参数
- 项目结构:
bash
.
├── main
├── main.cc
├── main.conf
└── Makefile
./main.conf
配置文件中内容
bash
--reuse_addr=false
--log_level=15
--log_file=./log/main.log
- gflags 通过 --flagfile 参数加载配置文件,将文件内容等效转换为命令行参数

4. 不同文件访问参数(主文件 DEFINE_类型 定义,其它文件 DECLARE_类型 声明)
一个项目下往往包含多个源文件,假设 main.cc、ui.cc 属于同一项目:
(1)在 main.cc 开头,DEFINE_bool 定义全局变量:
cpp
#include <gflags/gflags.h>
// bool FLAGS_big_menu = true;
DEFINE_bool(big_menu, true, "启用高级菜单"); // 实际定义
(2)如果在 ui.cc 中想使用 main.cc 中 DEFINE_bool 定义的全局变量,需要声明:
cpp
#include <gflags/gflags.h>
DECLARE_bool(big_menu); // 外部声明
宏定义 DECLARE_bool(big_menu); 展开是:
extern bool FLAGS_big_menu;
5. 特殊参数标识(如何查看定义参数时 指定的帮助信息)
- gflags 也默认为我们提供了几个特殊的标识:
bash
--help # 显示文件中所有标识的帮助信息
--helpfull # 和-help 一样, 帮助信息更全面一些
--helpshort # 只显示当前执行文件里的标志
--helpxml # 以 xml 方式打印,方便处理
--version # 打印版本信息,由 google::SetVersionString()设定
- 使用--help选项,查看定义参数时 指定的帮助信息
