Ir al contenido
Molto

El manifiesto

Todas las claves que lee Project.toml, qué emiten en la línea de comandos y los límites que se niega a sobrepasar.

Un único Project.toml vive en la raíz del proyecto. Todos los comandos lo buscan subiendo desde el directorio actual, así que molto build funciona desde cualquier subdirectorio.

La regla sobre la que descansa el archivo entero:

Molto descubre tus fuentes; no descubre tus ajustes de build.

Cada archivo .c, .cpp y .cc bajo src/ y tests/ se compila automáticamente: nunca enumeras archivos. Los include, los defines, las librerías y la disposición de los tests son únicamente lo que diga este archivo. Nada se deduce de la estructura de directorios, y no hay vuelta atrás a un Makefile.

Las rutas relativas de include y test.sources se resuelven contra la raíz del proyecto, nunca contra el directorio desde el que lanzaste el comando. flags se pasa literalmente por contrato y nunca se reescribe.

Lo que escribe molto new

[package]
name = "my_app"
version = "0.1.0"

[target]
std = "c17"
include = ["include"]

[profile.debug]
opt_level = 0
debug_info = true

[profile.release]
opt_level = 3
debug_info = false

Eso es un proyecto completo. No hay un segundo archivo ni un paso generador.

[package]

Clave Tipo Notas
name string Obligatoria. snake_case, debe empezar por minúscula
version string Libre; por defecto 0.0.0
artifact string Error duro. Hoy todo proyecto enlaza un ejecutable

name y version llegan a cada unidad de traducción como MOLTO_PKG_NAME y MOLTO_PKG_VERSION, así que un programa puede reportar su propia versión sin una cabecera que mantener sincronizada.

artifact se rechaza en vez de aceptarse y luego ignorarse: static y shared necesitarían ar, -shared y -fPIC, y nada de eso existe todavía.

[target]

Clave Tipo Emite
compiler string Nada directamente: gcc, g++, clang, llvm o msvc. Ausente significa autodetección
std string -std= para las fuentes C
cpp_std string -std= para las fuentes C++
requires array Nada: capacidades que deben demostrar que compilan
include array -I, relativo a la raíz del proyecto
defines array -D, en la forma que corresponda a cada compilador
link array -l, nombres sin el prefijo
flags array Literal, tanto al compilador como al enlazador

compiler es una preferencia de fabricante, no un binario. Nombrar un fabricante en vez de una ruta es lo que mantiene portable un manifiesto: gcc es la versión 9 en una máquina y la 14 en otra. Cualquier cosa fuera de esa lista es un error.

std elige el modo; requires declara lo que tiene que funcionar de verdad. Aceptar -std=c2x no es lo mismo que implementarlo: un compilador puede tragarse el flag y aun así rechazar [[nodiscard]]. Molto le pregunta a pickup qué toolchain local demuestra cada capacidad compilando un programa que la usa, y cachea la respuesta en .bin/wsdb. --refresh-toolchain vuelve a preguntar.

Omitir std hereda el valor por defecto del compilador, que cambia según la toolchain y la versión. Decláralo.

Para un flag de enlazado que no es una librería —-Wl,... o -pthread en tiempo de compilación— usa flags, no link.

Molto elige el driver de C para .c y el de C++ para .cpp y .cc, ambos de la misma toolchain resuelta, así que un proyecto mixto nunca mezcla compiladores. Un proyecto con C++ cuya toolchain no tiene driver de C++ se reporta de entrada, no se descubre al enlazar.

[test]

Clave Tipo Notas
mode string per_file (por defecto) o single
sources array Fuentes extra compiladas sólo para los tests; los directorios se recorren
defines, include, flags array Se aplican sólo al compilar tests/

per_file construye un ejecutable por archivo de tests/, cada uno enlazado contra los objetos del proyecto menos src/main.c, y cada uno con su propio main(). La salida va a build/<perfil>/tests/<nombre>.

single enlaza todo en un solo binario, en build/<perfil>/tests/<paquete>_tests. Es lo que necesita un framework que registra sus casos y es dueño de main().

Un framework que vive fuera de src/ no se compila en absoluto salvo que sources lo nombre. Esa es la causa más habitual de que un build de tests falle con los símbolos del propio framework.

[profile.*]

Existen cuatro perfiles: debug (el de por defecto), release, bench y custom. Se elige con molto build --profile release; la salida va a build/<perfil>/.

Clave Tipo Notas
opt_level entero -O
debug_info bool -g
defines, include, flags array Se suman a [target], nunca lo sustituyen

Valores por defecto cuando la tabla no está:

Perfil opt_level debug_info
debug 0 true
release 3 false
bench 3 false
custom 2 true

Cambiar cualquier ajuste de compilación provoca una recompilación: Molto registra el comando exacto de cada objeto y reconstruye cuando difiere.

[env]

[env]
MY_APP_LOG = "debug"

Las claves son nombres de variables y los valores tienen que ser cadenas. Se exportan a las invocaciones del compilador y el enlazador, y al programa bajo molto run y molto test. Las variables se establecen en el proceso hijo después del fork, así que el entorno de Molto nunca se modifica y el [env] de un proyecto no puede colarse en otro.

Límites

Sobrepasar uno es un error del manifiesto, nunca un recorte silencioso: perder un flag produciría un build en verde con opciones que no pediste.

Límite
Entradas en defines / include / flags / requires / test.sources 16
Longitud de una de esas entradas 95 caracteres
Entradas en link, y longitud de una 32 / 63 caracteres
Entradas en [env] 32
Longitud de nombre / valor en [env] 63 / 255 caracteres

Las claves desconocidas se descartan sin avisar

Una errata en el nombre de una clave simplemente desaparece. Si un ajuste parece no tener efecto, revisa primero cómo está escrito.

El manifiesto tolera claves desconocidas porque la RFC-0003 especifica tablas que este binario aún no implementa, y rechazarlas descartaría manifiestos que son válidos por diseño.

La excepción son [deps] y [dev-deps], que fallan en cerrado: una clave desconocida, dos orígenes o un rango de versiones es un error que nombra la dependencia. Igual hacen format.json y linter.json. Una dependencia mal leída es una dependencia que en silencio no está.

Especificado pero no implementado

Tabla o clave Qué pasa hoy
package.artifact Error duro
dep.recipe, artifact, optional, features Rechazadas, no ignoradas
[features], [build-deps], [workspace] No se leen
target.triple, tablas por sistema operativo No se leen
profile.lto, strip, sanitizers, warnings_as_errors No se leen

Si vienes de un Makefile

Lee CFLAGS y LDFLAGS y coloca cada pieza bajo la clave que le corresponde. Frente a un Makefile que pasa -Iinclude -D_DEFAULT_SOURCE -Wall -Wextra -Wpedantic y construye sus tests como un solo binario:

[target]
std      = "c2x"
requires = ["attr_nodiscard"]
defines  = ["_DEFAULT_SOURCE"]
include  = ["include"]
flags    = ["-Wall", "-Wextra", "-Wpedantic"]

[test]
mode    = "single"
sources = ["modules/moltest/src"]
include = ["modules/moltest/include"]

Ese es el manifiesto del propio Molto, menos los perfiles: el repositorio se construye con su propia herramienta.

Resolución de problemas

Síntoma Causa Arreglo
fatal error: 'pkg/foo.h' file not found No hay include declarado include = ["include"]
Los tests no enlazan, falta o sobra main El framework es dueño de main() mode = "single"
Los tests fallan en las cabeceras del framework Vive fuera de src/ test.sources y test.include
Faltan avisos que esperabas flags sin declarar flags = ["-Wall", "-Wextra"]
Un #ifdef nunca se activa defines sin declarar Añádelo a [target].defines
undefined reference a sqrt, pthread_create Librería sin enlazar link = ["m", "pthread"]
unknown compiler '…' compiler nombra un binario Usa un fabricante, o quita la clave
Una clave parece no hacer nada Errata, o no implementada Compruébala en las tablas de arriba
not inside a molto workspace No hay manifiesto aquí ni arriba molto init