Processamento de Formato YAML com a Biblioteca yaml-cpp

Introdução ao Formato YAML

YAML, uma sigla para "YAML Ain't Markup Language", é um formato serializável projetado para ser legível por humanos. Diferentemente de INI, JSON ou XML, que utilizam chaves, colchetes ou tags, o YAML adota uma sintaxe indentada inspirada em Python, resultando em uma aparência mais limpa. Suas regras de sintaxe permitem grande flexibilidade, embora essa mesma flexibilidade possa ocasionalmente gerar interpretações ambíguas.

A especificação oficial do YAML está disponível em yaml.org. No ecossistema C++, a biblioteca principal para manipulação de YAML é o yaml-cpp, que oferece conformidade com a versão 1.2 da especificação.

Utilizando a Biblioteca yaml-cpp

O repositório do yaml-cpp está disponível no GitHub. O primeiro passo para utilizá-lo é incluir o cabeçalho correspondente em seu código.

#include "yaml-cpp/yaml.h"
#include <iostream>

Criação e Manipulação de Nós

A estrutura fundamental do yaml-cpp é o Node. Um nó pode representar um mapa, uma sequência, um escalar ou ser nulo.

YAML::Node configuracao;
configuracao["servidor"] = "exemplo.com";
configuracao["porta"] = 8080;

É possível adicionar sequências (arrays) a um nó de diversas maneiras.

configuracao["usuarios"].push_back("ana");
configuracao["usuarios"].push_back("carlos");
configuracao["usuarios"].push_back("maria");

// Criando uma sequência anônima diretamente
YAML::Node lista_cores;
lista_cores.push_back("vermelho");
lista_cores.push_back("azul");
lista_cores.push_back("verde");

Ambos os tipos (mapa e sequência) podem ser verificados com os métodos IsMap() e IsSequence().

Leitura e Escrita em Arquivos

Para carregar um documento YAML a partir de um arquivo, utilize um parser associado a um fluxo de entrada.

try {
    std::ifstream arquivo("configuracoes.yaml");
    YAML::Node documento = YAML::Load(arquivo);
    std::string host = documento["servidor"].as<std::string>();
    int porta = documento["porta"].as<int>();
    // ... processar os dados
} catch (const YAML::Exception& excecao) {
    std::cerr << "Erro ao analisar YAML: " << excecao.what() << std::endl;
}

Para escrever um nó de volta para um arquivo, basta inseri-lo em um fluxo de saída.

std::ofstream saida("saida.yaml");
saida << configuracao;

Integrando yaml-cpp com CMake

Para incorporar a biblioteca em um projeto CMake, uma abordagem comum é cloná-la como uma subdiretório e adicioná-la como um target.

Primeiro, clone o repositório:

git clone https://github.com/jbeder/yaml-cpp.git

Em seguida, configure seu CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(ProjetoYaml CXX)

# Incluir yaml-cpp como um subdiretório de construção
add_subdirectory(yaml-cpp)

add_executable(aplicativo main.cpp)
target_link_libraries(aplicativo PRIVATE yaml-cpp::yaml-cpp)

Um exemplo de main.cpp que utiliza a biblioteca pode ser estruturado da seguinte forma:

#include "yaml-cpp/yaml.h"
#include <fstream>

int main() {
    YAML::Node raiz;
    raiz["titulo"] = "Configuração do Sistema";
    raiz["versao"] = 2.1;

    YAML::Node modulos;
    modulos.push_back("autenticacao");
    modulos.push_back("log");
    modulos.push_back("cache");
    raiz["modulos_habilitados"] = modulos;

    std::ofstream arquivo_saida("novo_config.yaml");
    arquivo_saida << raiz;
    return 0;
}

Após criar os arquivos, você pode compilar o projeto executando:

mkdir build && cd build
cmake .. && make

O executável gerado criará o arquivo novo_config.yaml com a seguinte estrutura:

titulo: Configuração do Sistema
versao: 2.1
modulos_habilitados:
  - autenticacao
  - log
  - cache

Compilação Cruzada

Para realizar uma compilação cruzada (cross-compilation) voltada a uma arquitetura diferente, como ARM, basta especificar o compilador correspondente ao invocar o CMake.

cmake -D CMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ -B build_arm
cmake --build build_arm

Isso gerará um binário otimizado para a plaatforma alvo especificada.

Tags: yaml-cpp C++ YAML configuracao CMake

Publicado em 7-30 02:13