Packages and std
Packages
Section titled “Packages”A package is a directory of .volt files. Every file in it is wrapped in namespace NAME, so a
package’s names are reached as NAME::...: the ones it marks public (see
Visibility). voltc takes packages with --pkg:
voltc run main.volt --pkg geo=../geo --pkg json=../jsonbolt does this for a package’s dependencies. The name has to be a valid Volt name (letters,
digits, _), and each package is given once.
std is a package too, given as --std DIR (or found through $VOLT_STD, or as a std/ next to
voltc). The compiler knows only a few of its names (@derive falls back to std::derive’s traits;
bindings and C++ imports use std::vec and std::string); past those, a different std only has to
provide what the programs using it call. --no-std builds without one.
Two attributes connect a library to the compiler, and any package can use them:
@attributes([@intrinsic("println")])on a function without a body binds it to a compiler builtin (the print functions) or, for names starting withvolt_, a function of the C runtime.@attributes([@owns("field")])makes a struct an owning pointer (likestd::mem::box): used like aT&, deleting what it points at when it goes out of scope.
tests/std_alt in the repository is a minimal std written from scratch.
Prebuilt libraries
Section titled “Prebuilt libraries”Compiling a package once and reusing it saves time:
voltc lib geo --pkg geo=../geo -o libgeo.a # the package's non-generic codevoltc run main.volt --pkg geo=../geo --link geo=libgeo.aThe program still reads the package’s sources, since templates are instantiated per program, but
takes its non-generic functions from the library. bolt builds every dependency this way, once per
profile. The exception is a package with a global whose type holds a trait union: its layout depends
on the types the program attaches, so voltc builds that package from source and warns why, and the
same for every linked package that uses it (a path starting with its name), since their libraries
refer to its symbols. voltc lib never does this: a library built with --link keeps its
references to the packages it links, and the program linking it decides.
Symbol names and error codes are stable across builds, and the runtime lives in the program, not in
libraries. Each library carries a guard symbol made from a hash of its exact sources, its
--cfg settings and its mode (debug or release): a program checked against different sources, or
built in the other mode, fails to link instead of misbehaving.
Libraries for other languages
Section titled “Libraries for other languages”voltc lib NAME --shared builds a self-contained shared library (the package, what it uses from
std, and the runtime; without -o, libNAME.so, libNAME.dylib on macOS or NAME.dll on
Windows), and --static the same as a .a. voltc bindings NAME --lang L writes the
declarations another language needs. See Other languages.
Per-package configuration
Section titled “Per-package configuration”--cfg KEY=VALUE sets a key for the program’s own files; --cfg PKG:KEY=VALUE for package PKG’s.
@cfg in a file reads the settings for that file’s package, which is how bolt gives each package
its own features. The target’s keys (os, arch, pointer_bits) are the exception: one given
with --cfg applies to every package.