The beans.pot manifest
beans.pot is the manifest file at the root of a Beans module. It names the
module, says whether the module is an application or a library, pins Git
dependencies, and passes native linker directives. It is parsed in
src/module.b.
Syntax
Section titled “Syntax”The manifest is line-based. It is not TOML and not JSON. Each line is one
directive. Blank lines are ignored. A line starting with // is a comment and
is ignored.
The smallest real manifests are one line. The example project ships a
beans.pot that is just:
module shopThe compiler’s own manifest is just module compiler.
Create a minimal manifest in the current directory with
beansc pot init <module-name>. The command does not overwrite an existing
manifest.
Fields
Section titled “Fields”module <name> (required)
Section titled “module <name> (required)”Names the module. Exactly one module line is required. The name is the
module path: the root that local packages and the lock file hang off of.
module shopkind application or kind library (optional)
Section titled “kind application or kind library (optional)”Says what the module builds. The default is application.
kind application: the module needs anfn main().kind library: the module must not have amain.
module shopkind applicationSee Building for how a library build produces a .a, a
.dylib/.so, and an optional C header.
require <host/owner/repo> <ref> (repeatable)
Section titled “require <host/owner/repo> <ref> (repeatable)”Pins one Git dependency. The path is a Git host path; the ref is a tag, branch, or commit-like reference.
require github.com/acme/http v1.2Requiring the same path at two different refs is an error — anywhere in the
graph, including a ref your dependency pinned. Full detail, and how this feeds
beans.lock, is on Dependencies and the lock file.
require path "<directory>" (repeatable)
Section titled “require path "<directory>" (repeatable)”Names another module on this machine, relative to this beans.pot. Nothing is
fetched and nothing enters beans.lock.
require path "../shared"It is for modules that travel together — a repository’s own sibling modules, or
a checkout you are editing. A published package requires its dependencies from
Git instead: a require path row in a package someone fetches names a
directory that is not in their tree, and the failure arrives as an unknown
package rather than as a manifest error.
cflags <selector> "<flag>" (repeatable)
Section titled “cflags <selector> "<flag>" (repeatable)”Passes a compile flag to the C sources this module’s csrc rows declare.
cflags linux "-I/usr/include/gtk-4.0"- Selectors are the same as
link:all, an OS name, or an exact triple. - One quoted word per flag, so a path with a space in it survives.
- A flag that names a directory —
-I,-iquote,-isystem,-idirafter,-F— resolves a relative value against the package that declared the row, exactly as that package’scsrcpaths do. An absolute value passes through untouched.
beansc pot add --system <pkg> [<selector>] generates these rows from
pkg-config --cflags on the build machine and writes them between markers it
manages.
The package-relative rule is what lets a package vendor a C library that has its own include tree, without naming a path that exists on one machine:
cflags all "-Ivendor/postgresql/src/include"-include and -imacros are not rewritten. They name a file the include
search looks up, exactly as #include "name" in the source would, so a package
that wants its own prelude writes the directory as -I and the file as
-include name.h.
link <selector> <search|library|framework> "<value>" (repeatable)
Section titled “link <selector> <search|library|framework> "<value>" (repeatable)”Passes a native linker directive, for modules that link against C libraries.
selectorisall, an OS name (for examplemacos,linux,windows), or an exact target triple (for examplex86_64-unknown-linux-gnu).- The kind is one of:
search: a library search directory. Search paths are relative to thebeans.potfile.library: a library to link (by name).framework: a framework to link (macOS).
- The value is a quoted string.
Entries pass to the linker in the order you declare them.
csrc <selector> "<file.c>" (repeatable)
Section titled “csrc <selector> "<file.c>" (repeatable)”Declares a C source file that ships with the package. The toolchain compiles it during the Beans build, without requiring a prebuilt binary or a separate build step from the consumer.
- Selectors are the same as
link:all, an OS name, or an exact triple. - The path is relative to the
beans.potthat declares it, and the file must exist — a missing file is a manifest error. - Native builds compile each selected file with the build’s own Clang and
flags into a content-hash-cached object that rides every emit path: linked
into binaries and shared objects, archived into
--emit static, placed beside--emit objoutput. beansc runcompiles the selected set once into a host shared library, cached under$BEANS_HOME/cache/csrc, and resolvesextern "C"symbols through it. The host-targetlink ... search,library, andframeworkrows are passed to this link too, so run mode and native builds resolve the same dependencies. Those selected link rows are part of the cache key.- Quoted
#include "..."and#import "..."headers resolve beside each source file, and both count toward the object’s cache key. - Rows propagate from local and Git dependencies exactly like
linkrows.
A fuller example
Section titled “A fuller example”module shopkind applicationrequire github.com/acme/http v1.2link all search "native/lib"link all library "shop_native"link macos framework "CoreFoundation"link x86_64-unknown-linux-gnu library "platform_helper"csrc all "native/shim.c"This module is an application, pulls in one Git dependency, links a native
library it ships under native/lib plus a macOS framework and one Linux-only
helper, and compiles its own C shim on every target.
See Dependencies and the lock file for how require feeds
beans.lock, and the FFI guide for how link fits with C
interop.