PackBEAM CLI
Relevant source files
The following files were used as context for generating this wiki page:
The PackBEAM CLI is a command-line utility used to aggregate BEAM files and other data into a single AtomVM (PackBEAM Format) file. These files, typically ending in .avm, serve as the code base for applications running on the AtomVM virtual machine. The tool allows developers to create, list, extract, and manipulate the contents of these archives, facilitating the deployment of multi-module Erlang and Elixir applications to resource-constrained embedded devices.
While the tool can be used directly, its functionality is frequently embedded within higher-level build tools like the atomvm_rebar3_plugin and ExAtomVM. It is essential for generating both "runnable" AVM files, which contain a defined entry point for execution, and "archive" AVM files used as library aggregations.
Sources: tools/packbeam/README.md:10-23, doc/src/atomvm-tooling.md:576-586, doc/src/packbeam-format.md:12-21
Core Functionality and Architecture
The CLI is implemented in C and interfaces with the core libAtomVM library. It processes input files by reading their binary data, validating their format (BEAM or AVM), and writing them into a structured output file with appropriate headers and alignment.
Operation Modes
The tool supports several sub-commands that define its behavior:
- Create: Packs a collection of
.beamfiles or existing.avmfiles into a new AVM. - List: Displays the modules and data files contained within an AVM.
- Extract: Retrieves specific elements from an AVM and writes them to the local filesystem.
- Delete: Removes specific elements from an AVM file.
Sources: tools/packbeam/packbeam.c:64-92, doc/src/atomvm-tooling.md:600-606
Internal Logic Flow
When creating a pack, the tool iterates through provided input files. If an input is a BEAM file, it extracts relevant chunks and writes a module header. If the input is an existing AVM, it "folds" the contents into the new output file.
The logic ensures that files are 4-byte aligned and that mandatory BEAM chunks are preserved while non-essential metadata is stripped.
Sources: tools/packbeam/packbeam.c:196-246, doc/src/packbeam-format.md:28-36
File Headers and Data Structures
PackBEAM files utilize specific header structures to manage the sequence of files. Every AVM file begins with a fixed 24-byte magic sequence: #!/usr/bin/env AtomVM\n\0\0.
File Header Structure
Each embedded element (BEAM or data) is preceded by a header defined by the following fields:
| Field | Type | Description |
|---|---|---|
size | 32-bit BE | Total size of the entry including padding. |
flags | 32-bit BE | Metadata (e.g., 0x02 for BEAM, 0x01 for start function). |
reserved | 32-bit BE | Unused (set to 0x00). |
module_name | Null-term String | The name of the module or path of the data file. |
Sources: doc/src/packbeam-format.md:52-78, tools/packbeam/packbeam.c:438-450
BEAM Chunk Filtering
To minimize flash footprint, PackBEAM strips non-essential chunks. The following chunks are typically preserved:
AtU8(Atoms)Code(Bytecode)ExpT,LocT,ImpT(Export, Local, and Import tables)LitU/LitT(Literals)FunT(Function table),StrT(String table)
Sources: doc/src/packbeam-format.md:92-110, tools/packbeam/packbeam.c:283-345
CLI Options and Usage
The CLI behavior is controlled through various flags that modify how the AVM is constructed or displayed.
Command Reference
| Sub-command | Option | Description |
|---|---|---|
create | --start / -s | Designates a module as the application entry point. |
create | --prune / -p | Removes BEAM files with no transitive references from the start module. |
create | --remove_lines / -r | Strips line number information to save space. |
list | --format / -f | Output format (csv, bare, or default). |
extract | --out / -o | Specifies output directory for extracted files. |
Sources: doc/src/atomvm-tooling.md:738-769, tools/packbeam/packbeam.c:64-92
Start Modules and Search Order
For a "Runnable" AVM, the tool identifies the entry point using the start/0 function. When the AtomVM runtime boots, it scans the AVM file from start to finish. The first module encountered with the start/0 flag (flags mask 0x03) is executed. It is conventional to place the boot module first in the file.
Sources: tools/packbeam/README.md:15-20, doc/src/packbeam-format.md:72-78
Literal Handling and ZLib
One critical function of the PackBEAM CLI is the handling of literal tables. While standard Erlang BEAM files may compress literals using ZLib, the AtomVM runtime often lacks decompression support on embedded targets. Consequently, the CLI uncompresses LitT chunks and converts them to LitU (uncompressed) chunks before insertion.
static void *uncompress_literals(const uint8_t *litT, int size, size_t *uncompressedSize)
{
unsigned int required_buf_size = READ_32_ALIGNED(litT + LITT_UNCOMPRESSED_SIZE_OFFSET);
// ... logic for ZLib inflate ...
ret = inflate(&infstream, Z_NO_FLUSH);
// ...
}
Sources: tools/packbeam/packbeam.c:405-430, doc/src/packbeam-format.md:108-112
Summary
The PackBEAM CLI is the foundational tool for preparing AtomVM applications. By aggregating modules, stripping unnecessary metadata, and ensuring proper alignment, it enables complex Erlang and Elixir logic to reside within the strict memory and storage limits of microcontrollers like the ESP32 and STM32. Its ability to create both libraries (archives) and executable bundles makes it a versatile component of the AtomVM ecosystem.