gflags (Google Flags) es una biblioteca de código abierto desarrolalda por Google que permite declarar, definir y analizar argumentos de línea de comandos en aplicaciones C++. Su principle ventaja es que los parámetros pueden definirse en varios archivos fuente en lugar de concentrarse cerca de la función main, lo que mejora la modularidad del código.
Documentación oficial: https://gflags.github.io/gflags/
Repositorio: https://github.com/gflags/gflags
1. Instalación de gflags
Instalación mediante gestor de paquetes
sudo apt-get install libgflags-dev
Instalación desde código fuente
git clone https://github.com/gflags/gflags.git
cd gflags/
mkdir build && cd build/
cmake ..
make
sudo make install
2. Uso de gflags
2.1 Incluir el archivo de cabecera
#include <gflags/gflags.h>
2.2 Enlazar durante la compilación
g++ main.cc -o main -lgflags
2.3 Definir parámetros
Se usa la macro DEFINE_tipo(nombre, valor_predeterminado, "texto de ayuda"). Los tipos principales son:
| Macro | Tipo C++ |
|---|---|
DEFINE_bool |
bool |
DEFINE_int32 |
int32_t |
DEFINE_int64 |
int64_t |
DEFINE_uint64 |
uint64_t |
DEFINE_double |
double |
DEFINE_string |
std::string |
Ejemplo:
DEFINE_bool(enable_reuse, true, "Activar reutilización de dirección de red");
DEFINE_int32(log_level, 1, "Nivel de registro: 1=DEBUG, 2=WARN, 3=ERROR");
DEFINE_string(log_file, "stdout", "Destino del registro, por defecto salida estándar");
2.4 Acceder a los parámetros
Tras el análisis, se accede mediante FLAGS_nombre:
FLAGS_enable_reuseFLAGS_log_levelFLAGS_log_file
2.5 Acceder desde otro archivo
Para usar un parámetro definido en otro archivo, se emplea la macro DECLARE_tipo(nombre). Por ejemplo, DECLARE_bool(enable_reuse) equivale a extern bool FLAGS_enable_reuse.
2.6 Inicializar todos los parámetros
En la función main se debe llamar a:
google::ParseCommandLineFlags(&argc, &argv, true);
- El tercer argumento (
remove_flags) controla si se eliminan los indicadores deargv(true) o solo se reordenan (false).
2.7 Establecer parámetros en la línea de comandos
Para cadenas y enteros
./ejecutable --log_file="./app.log"
./ejecutable -log_file="./app.log"
./ejecutable --log_file "./app.log"
./ejecutable -log_file "./app.log"
Para booleanos
./ejecutable --enable_reuse # true
./ejecutable --noenable_reuse # false
./ejecutable --enable_reuse=true
./ejecutable --enable_reuse=false
💡 El doble guión
--detiene el procesamiento de indicadores. Por ejemplo, enejecutable -f1 1 -- -f2 2, solo se procesaf1.
2.8 Uso de archivos de configuración
Cuando hay muchos parámetros, se puede usar un archivo de configuración. Notas importantes:
- En el archivo solo se usa
-(un guión). =no debe tener espacios alrededor.- Los valores de cadena no necesitan comillas dobles.
# config.conf
-enable_reuse=true
-ip=0.0.0.0
-port=8500
Ejecución:
./ejecutable --flagfile=config.conf
En el código se puede fijar un archivo por defecto:
google::SetCommandLineOption("flagfile", "config.conf");
2.9 Indicadores especiales
gflags proporciona algunos indicadores integrados:
--help # Muestra la ayuda de todos los indicadores
--helpfull # Similar a --help pero más completo
--helpshort # Solo muestra indicadores del archivo actual
--helpxml # Imprime la ayuda en XML
--version # Muestra la versión (definida con google::SetVersionString())
--flagfile # Carga indicadores desde un archivo
3. Ejemplo práctico
Estructura de archivos:
|-- main.cc
|-- config.conf
|-- Makefile
main.cc:
#include <iostream>
#include <gflags/gflags.h>
DEFINE_bool(enable_reuse, true, "Activar reutilización de dirección");
DEFINE_string(host, "127.0.0.1", "Dirección IP del servidor");
DEFINE_int32(service_port, 8888, "Puerto del servidor");
int main(int argc, char* argv[]) {
google::ParseCommandLineFlags(&argc, &argv, true);
std::cout << "enable_reuse: " << FLAGS_enable_reuse << std::endl;
std::cout << "host: " << FLAGS_host << std::endl;
std::cout << "service_port: " << FLAGS_service_port << std::endl;
return 0;
}
Makefile:
app: main.cc
g++ -std=c++17 -o $@ $^ -lgflags
Ejecución sin argumentos:
$ ./app
enable_reuse: 1
host: 127.0.0.1
service_port: 8888
Ejecución con argumentos en línea:
$ ./app --enable_reuse --host=0.0.0.0 --service_port=9999
enable_reuse: 1
host: 0.0.0.0
service_port: 9999
config.conf:
-enable_reuse=false
-host=0.0.0.1
-service_port=12024
Ejecución con archivo de configuración:
$ ./app --flagfile=./config.conf
enable_reuse: 0
host: 0.0.0.1
service_port: 12024
Si se agrega google::SetCommandLineOption("flagfile", "config.conf"); en el código, ya no es necesario pasar --flagfile en la línea de comandos.