Cuando empiezas a trabajar con Zig, uno de los primeros retos es decidir dónde colocar cada archivo de tu proyecto. Una estructura de directorio clara no solo facilita la navegación, sino que también permite que las herramientas de Zig (como zig build y el propio zig mod) encuentren automáticamente los módulos y dependencias. A continuación, se detalla una convención de directorios muy usada por la comunidad y se ilustran sus componentes con ejemplos de código comentados.
1. La estructura típica de un proyecto Zig
En la práctica, un proyecto Zig suele contener los siguientes directorios y archivos de raíz:
src/– Código fuente principal.tests/– Casos de prueba unitarios.examples/– Pequeños programas que ilustran el uso de la librería.zig.mod– Archivo de metadatos de módulo.build.zig– Script de construcción personalizado.README.md– Documentación básica..zig-cache/– Caché de compilación (generado automáticamente).
Un árbol de directorio típico se vería así:
my_project/
├── src/
│ ├── main.zig # Punto de entrada del binario
│ ├── lib/
│ │ └── math.zig # Un módulo de la librería
├── tests/
│ └── math_test.zig
├── examples/
│ └── hello_world.zig
├── zig.mod
├── build.zig
└── README.md
2. El archivo zig.mod
Este archivo describe el módulo que se puede importar en otros proyectos Zig. Su contenido mínimo incluye el nombre, la versión y la licencia.
// zig.mod
// Define el nombre y la versión del módulo
name = "my_project"
version = "0.1.0"
// Licencia utilizada
license = "MIT"
3. El script de construcción build.zig
El build.zig permite configurar cómo se compila tu proyecto. A continuación se muestra un ejemplo sencillo que compila un binario y una librería.
// build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
// Define el objetivo de compilación: un ejecutable llamado "my_app"
const exe = b.addExecutable("my_app", "src/main.zig");
// Incluye la carpeta "src" en el árbol de búsqueda de módulos
exe.root_source_file = b.path("src/main.zig");
// Habilita optimización de lanzamiento
exe.optimize = .ReleaseSafe;
// Añade una librería estática que se construye a partir de "src/lib"
const lib = b.addStaticLibrary("my_lib", "src/lib/math.zig");
lib.optimize = .ReleaseSafe;
// Indica que el binario depende de la librería
exe.linkLibrary(lib);
// Publica los objetivos para que se puedan ejecutar con `zig build run`
b.installArtifact(exe);
}
Explicación del script línea por línea
const std = @import("std");– Importa el módulo estándar de Zig.pub fn build(b: *std.Build) void {– La funciónbuildes el punto de entrada para el sistema de construcción.const exe = b.addExecutable("my_app", "src/main.zig");– Crea un objetivo ejecutable llamadomy_appa partir desrc/main.zig.exe.root_source_file = b.path("src/main.zig");– Especifica el punto de entrada del binario.exe.optimize = .ReleaseSafe;– Selecciona un nivel de optimización seguro para producción.const lib = b.addStaticLibrary("my_lib", "src/lib/math.zig");– Define una librería estática que compilasrc/lib/math.zig.lib.optimize = .ReleaseSafe;– Igual que el ejecutable.exe.linkLibrary(lib);– Enlaza la librería al binario.b.installArtifact(exe);– Hace que el binario se copie al directorio de instalación.
4. Código fuente principal: src/main.zig
El archivo de entrada suele contener el punto de entrada de la aplicación (main). A continuación, un ejemplo que utiliza el módulo de matemáticas definido en src/lib/math.zig:
// src/main.zig
const std = @import("std");
const math = @import("math");
// El punto de entrada de cualquier programa Zig
pub fn main() !void {
// Obtener la salida estándar (stdout)
const stdout = std.io.getStdOut().writer();
// Imprime un mensaje inicial
try stdout.print("¡Hola, Zig!\n", .{});
// Calcula la suma de dos números usando la función del módulo math
const result = math.add(7, 5);
// Muestra el resultado en la consola
try stdout.print("7 + 5 = {d}\n", .{result});
}
Detalle línea por línea
const std = @import("std");– Importa el módulo estándar que contiene utilidades de entrada/salida, manejo de errores, etc.const math = @import("math");– Importa el módulo localsrc/lib/math.zigpara usar sus funciones.pub fn main() !void {– Declara la funciónmain; el signo exclamativo indica que puede devolver un error.const stdout = std.io.getStdOut().writer();– Obtiene un escritor (writer) para la salida estándar.try stdout.print("¡Hola, Zig!\n", .{});– Imprime un saludo;trypropaga cualquier error.const result = math.add(7, 5);– Llama a la funciónadddel módulomath.try stdout.print("7 + 5 = {d}\n", .{result});– Muestra el resultado.
5. Módulo de matemáticas: src/lib/math.zig
Este módulo ofrece una función simple de suma, pero también se puede extender con más operaciones.
// src/lib/math.zig
/// Suma dos enteros sin signo de 32 bits.
///
/// Este ejemplo muestra cómo declarar una función pública con un
/// comentario de documentación (`///`). Los comentarios así
/// aparecen cuando se usa `zig fmt
