Modularizando tu proyecto C++ con Meson
⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.
r8vnhill/echo-app-cpp-meson
- Añadir un glosario rápido.
🏗️ Estructura esperada del proyecto
- Añadir un diagrama de flujo de la estructura del proyecto.
📦 Paso 1: Crear la estructura de carpetas
Desde la raíz del proyecto:
- Windows
- macOS
- Ubuntu/Debian
@{
App = @("src/app/main.cpp", "src/app/meson.build")
Core = @("src/core/echo.cpp", "src/core/echo.hpp", "src/core/meson.build")
}.GetEnumerator() | ForEach-Object {
$module = $_.Key
$files = $_.Value
Write-Host "📁 Creating structure for module: $module" -ForegroundColor Cyan
foreach ($file in $files) {
$dir = Split-Path $file -Parent
if (-not (Test-Path $dir)) {
New-Item -Path $dir -ItemType Directory -Force | Out-Null
}
New-Item -Path $file -ItemType File -Force | Out-Null
Write-Host "✅ $file" -ForegroundColor Green
}
}
Write-Host "🟢 Project initialized successfully." -ForegroundColor Green
Este script de PowerShell automatiza la creación de una estructura de carpetas y archivos mínima para un proyecto modular en C++ usando Meson como sistema de construcción.
- Define un diccionario con dos módulos:
App
yCore
, cada uno asociado a los archivos que necesita. - Por cada archivo:
- Crea la carpeta contenedora si no existe (por ejemplo,
src/app/
osrc/core/
). - Crea un archivo vacío (
main.cpp
,echo.cpp
,meson.build
, etc.) en la ubicación indicada. - Muestra en consola un mensaje de confirmación (
✅
) por cada archivo creado.
- Crea la carpeta contenedora si no existe (por ejemplo,
Puedes crear el archivo CreateProjectStructure.ps1
y ejecutarlo desde PowerShell para crear la estructura de carpetas y archivos automáticamente.
.\scripts\ps1\CreateProjectStructure.ps1
#!/bin/sh
set -e # Exit immediately if a command exits with a non-zero status
echo "📦 Creating project structure..."
for file in \
src/app/main.cpp \
src/app/meson.build \
src/core/echo.cpp \
src/core/echo.hpp \
src/core/meson.build
do
dir=$(dirname "$file")
mkdir -p "$dir"
touch "$file"
echo "✅ $file"
done
echo "🟢 Project initialized successfully."
Este script Bash automatiza la creación de la estructura mínima de carpetas y archivos para un proyecto modular en C++ que utiliza Meson como sistema de construcción.
- Activa
set -e
para que el script se detenga si ocurre algún error. - Define una lista de archivos que forman parte de los módulos
app
ycore
, incluyendo archivos fuente (.cpp
,.hpp
) y archivos de configuración (meson.build
). - Por cada archivo:
- Crea la carpeta correspondiente si no existe (
mkdir -p
). - Crea un archivo vacío (
touch
), que luego podrá completarse con el contenido necesario. - Imprime un mensaje de confirmación (
✅
) con el nombre del archivo creado.
- Crea la carpeta correspondiente si no existe (
Puedes crear el archivo create_project_structure_2.sh
y ejecutarlo desde la terminal:
chmod +x scripts/sh/create_project_structure_2.sh
./scripts/sh/create_project_structure_2.sh
#!/bin/sh
set -e # Exit immediately if a command exits with a non-zero status
echo "📦 Creating project structure..."
for file in \
src/app/main.cpp \
src/app/meson.build \
src/core/echo.cpp \
src/core/echo.hpp \
src/core/meson.build
do
dir=$(dirname "$file")
mkdir -p "$dir"
touch "$file"
echo "✅ $file"
done
echo "🟢 Project initialized successfully."
Este script Bash automatiza la creación de la estructura mínima de carpetas y archivos para un proyecto modular en C++ que utiliza Meson como sistema de construcción.
- Activa
set -e
para que el script se detenga si ocurre algún error. - Define una lista de archivos que forman parte de los módulos
app
ycore
, incluyendo archivos fuente (.cpp
,.hpp
) y archivos de configuración (meson.build
). - Por cada archivo:
- Crea la carpeta correspondiente si no existe (
mkdir -p
). - Crea un archivo vacío (
touch
), que luego podrá completarse con el contenido necesario. - Imprime un mensaje de confirmación (
✅
) con el nombre del archivo creado.
- Crea la carpeta correspondiente si no existe (
Puedes crear el archivo create_project_structure_2.sh
y ejecutarlo desde la terminal:
chmod +x scripts/sh/create_project_structure_2.sh
./scripts/sh/create_project_structure_2.sh
Puedes borrar los archivos creados en la lección pasada o guardarlos como recuerdo.
- Windows
- macOS
- Ubuntu/Debian
'src\main.cpp', 'src\meson.build' | Remove-Item -Force -Verbose
#!/bin/sh
echo "🗑️ Removing files..."
for file in src/main.cpp src/meson.build; do
if [ -f "$file" ]; then
rm -f "$file"
echo "✅ Removed: $file"
else
echo "⚠️ File not found: $file"
fi
done
#!/bin/sh
echo "🗑️ Removing files..."
for file in src/main.cpp src/meson.build; do
if [ -f "$file" ]; then
rm -f "$file"
echo "✅ Removed: $file"
else
echo "⚠️ File not found: $file"
fi
done
🧾 Paso 2: Declarar el archivo raíz meson.build
En este archivo indicamos a Meson que estamos creando un proyecto en C++, especificamos su versión, y declaramos qué subdirectorios contienen código que debe ser compilado.
project('echo-app', 'cpp', version: '0.2.0') # Nombre, lenguaje y versión del proyecto
subdir('src/core') # Biblioteca reutilizable
subdir('src/app') # Ejecutable principal
Este archivo es el punto de entrada del sistema de construcción de Meson. Declara el proyecto y registra los subdirectorios que contienen sus propios archivos meson.build
. Así, Meson podrá compilar correctamente tanto la biblioteca (core
) como la aplicación (app
).
🧩 Paso 3: Implementar la biblioteca core
En este paso definimos la biblioteca core
, que encapsula una función simple echo
. Para ello, configuramos el archivo meson.build
del módulo y escribimos su implementación.
core_sources = files('echo.cpp')
core_lib = static_library(
'core',
core_sources,
include_directories: include_directories('.'),
cpp_args: ['-std=c++23'],
)
Este archivo configura la compilación del módulo core
como una biblioteca estática.
static_library('core', ...)
indica que se generará una.a
o.lib
con ese nombre.- Se incluyen los archivos fuente del módulo (
echo.cpp
) y el directorio actual como ruta de inclusión (.
), donde está el archivoecho.hpp
. - Se fuerza el estándar
c++23
para habilitar características modernas del lenguaje.
Esto permite que otros módulos, como app
, puedan vincularse contra core
y reutilizar sus funciones.
✍️ Implementación de echo
Ahora escribimos la función echo
, que devuelve una copia del mensaje recibido. Usamos std::string_view
para mayor eficiencia en el paso de argumentos.
#pragma once
#include <string>
#include <string_view>
[[nodiscard]] std::string echo(std::string_view message);
#include "echo.hpp"
std::string echo(std::string_view message) {
return {message.begin(), message.end()};
}
-
En
echo.hpp
, definimos la interfaz pública de la biblioteca.
Usamosstd::string_view
como entrada para aceptar cadenas sin copiar, y[[nodiscard]]
para evitar que se ignore el resultado de la función. -
En
echo.cpp
, implementamosecho
devolviendo una copia explícita del contenido usando rangos. Esto funciona igual questd::string(message)
pero es más explícito en su conversión.
Esta biblioteca es mínima pero funcional. Ilustra cómo separar la lógica de negocio (core
) del ejecutable principal (app
), siguiendo una estructura modular mantenible.
🚀 Módulo app
: ejecutable
app_sources = files('main.cpp')
executable('app', app_sources,
dependencies: [],
link_with: core_lib,
include_directories: include_directories('..')
)
Código principal:
#include <iostream>
#include "core/echo.hpp"
int main() {
std::cout << echo("Hello from Meson!") << std::endl;
return 0;
}
🔨 Compilación
Desde la raíz del proyecto:
meson setup build
meson compile -C build
Y ejecuta el binario:
./build/src/app/app
Echo: Hello from Meson!
El ejecutable app
se compila en build/src/app/app
y enlaza con la biblioteca core
. Gracias a la configuración modular, puedes mantener core
como una unidad reutilizable o independiente.