Every program the compiler links carries a manifest: one JSON document that says what the program was built for and what it may be told when it starts. It is part of the program file, so you can read it without running the program:
mica --inspect ./server{"mica_manifest":1,"kind":"program","version":"1.4.0","compiler":{"version":"7.6.5","commit":"3176d5e33"},"platform":{"operating_system":"linux","architecture":"amd64","encoding":"utf-32"},"optimization":{"profile":"release","checked":false,"profiling":false,"passes":["constant_folding","assembly_peephole","graph_allocator","il_static_single_assignment","function_inlining","loop_optimization"]},"memory":{"class":"hosted-heap","arena_bytes":null},"tasking":{"flavor":"multicore","carriers":2,"pinned":true,"processes":null},"stack_size_bytes":null,"runtime_flags":"sealed","gpu":{"device_code":false},"libraries":[{"name":"sqlite","language":"mica","version":"2.0.0"},{"name":"sqlite3","language":"c","version":"3.46.1"}],"interface":null}The same document is printed by the running program itself when it is started
with the info runtime flag, beside what its
start resolved:
./server +mica info -micaBoth read the same bytes, so the two answers always agree. The document is one
line; pipe it into jq to read it comfortably:
mica --inspect ./server | jq .The members
Every value is spelled the way the command line spells it, so each one reads as a flag you could have typed.
| Member | Meaning |
|---|---|
mica_manifest | the layout version, 1 |
kind | what the file is: program, or library for an archive or a shared object |
version | the program’s or library’s own version, as its mica.project states it, or null when it states none |
compiler.version | the release of the compiler that built the program |
compiler.commit | the commit that compiler was built from, or null when its build recorded none |
platform.operating_system | linux |
platform.architecture | amd64 or arm64 |
platform.encoding | utf-32 or utf-8, or null for an archive every encoding links: the standard library’s and the runtime floor’s |
optimization | the optimization set below, or null for an archive of C objects |
optimization.profile | debug or release |
optimization.checked | whether the build keeps every runtime guard (checked in --optimize) |
optimization.profiling | whether the build keeps the line table for a profiler (profiling in --optimize) |
optimization.passes | the passes the build ran, in the words --optimize accepts; an empty list when it ran none |
memory.class | hosted-heap or fixed-arena |
memory.arena_bytes | the fixed arena’s size in bytes, or null on the hosted heap, which has none |
tasking.flavor | single or multicore |
tasking.carriers | the build’s carrier count: 1 for a single build, the --tasking multicore,<n> count, or null when the pool counts the machine’s processors at start |
tasking.pinned | whether the build pinned the count with ,fixed, so the carriers runtime flag is refused |
tasking.processes | the build’s --processes count of worker processes that may run tasks placed on processes at once, or null when the program counts the processors it may use at start |
stack_size_bytes | the --stack-size request, or null when the platform’s default stack serves |
runtime_flags | the runtime-flag policy: open, sealed, sealed,rtp or none |
gpu.device_code | whether any of the program’s code is placed on a GPU, so the program needs one to run |
gpu.modules | the device floor’s kernel modules the program carries: floor, the general kernels every program that places code on a GPU loads, and each of NVIDIA’s own attention and pointwise modules only in the number formats the program’s code computes in, as attention_float32 or pointwise_bfloat16. A half-precision attention brings attention_float32 along, which serves the shapes the half kernels do not take. A library names the modules its own code reaches, and a program that links it carries them too. Absent where no code is placed on a GPU |
gpu.images | the NVIDIA card generations on which every kernel the program runs, the device floor’s and its own, comes precompiled, as sm_89; the program loads them ready there and never starts NVIDIA’s runtime compiler. On another generation its kernels compile when it starts, and so do its own kernels where it was built without the runtime compiler installed; +mica info says which holds on the card it finds. The device floor’s archive names the generations its own kernels come precompiled for. Absent where there are none |
libraries | the libraries the program was built against through contracts of its own, each with its name, its language, mica or c, and its version: the one its contract states or, for a C library whose contract names its pkg-config package, the one the building machine’s pkg-config answered, and null when there is none; an empty list when there are none |
interface | a library’s interface digest: the SHA-256 of the surface its contract states, which the contract its build emitted states as well. A program’s link compares it with the contract the program was built against and refuses an archive of another build by the library’s name. null for a program |
A reader checks mica_manifest first and refuses a version it does not know.
New members can appear in a later release without a new version; the version
changes only when a member changes its meaning or disappears.
Where it lives
The manifest is stored in the program file’s .mica.manifest section, which
is loaded with the program. --strip removes the symbol table and keeps the
manifest, so a shipped binary can still be inspected. A policy of none keeps
it as well: that program reads no runtime flag, but its file still says what
it is.
A library carries a manifest too, in its archive’s generated member or its
shared object’s section: its kind is library, it states its own version, its
interface digest and the libraries it was built against, and its memory class, tasking, stack
request and runtime-flag policy are null, because those are decided by the
program that links it. A program linked by a tool other than the Mica compiler
carries none.
The standard library and the runtime floor carry one as well, the first member of each archive, naming the release and the commit of the compiler whose build made them. A program links only the standard library and the floor of its own compiler: before the linker runs, the compiler reads both manifests and refuses another compiler’s archive by name, as rustc refuses a crate another compiler built:
Failed to link: the standard library '/usr/lib/mica-stdlib-amd64.a' was built by the Mica compiler 7.6.0 (3176d5e33), and this is the Mica compiler 7.6.5 (8c1f2a0b4): a program links the standard library and the runtime floor its own compiler's build made, which a release installs beside the compiler and 'scripts/build-compiler.sh' builds in a checkoutRefusals
mica --inspect reads one file and combines with no other flag. When it
cannot answer, it prints one line on standard error and exits with status 1:
| Situation | The line |
|---|---|
| the file does not exist | cannot inspect './server': no such file or directory |
| the file is not a binary | cannot inspect './server.mica': it is neither an ELF file nor a static archive, so it carries no Mica manifest |
| the file carries no manifest | './libtool.so' carries no Mica manifest: every program, archive and shared object the Mica compiler links carries one |
| the manifest is damaged | the Mica manifest in './server' is damaged: unexpected end of JSON input |
| another flag beside it | the flag '-optimize' cannot be combined with '--inspect': the inspect mode reads one linked program and combines with no other flag |
| a further word | the inspect mode reads one linked program, but 'extra' was given as well |