Install

1. Build & install Strada

perla compiles your Perl to C and links the Strada runtime, so it builds against an installed Strada. Build and install Strada first:

$ git clone https://github.com/strada-lang/strada-lang
$ cd strada-lang
$ ./configure
$ make
$ sudo make install        # installs strada to /usr/local

2. Build & install perla

perla uses the strada on your PATH by default:

$ git clone https://github.com/strada-lang/perla
$ cd perla
$ make
$ sudo make install        # optional — puts `perla` on your PATH

To build against a Strada source tree instead of the system install, pass STRADA_DIR: make STRADA_DIR=/path/to/strada-lang. If you skip make install, run perla from its build directory as ./perla.

Prerequisites

Quick sanity check:

$ perla -e 'print "hello from perla\n"'
hello from perla

If that works, you're done installing.

Your first program

Create a file hello.pl:

# hello.pl
use strict;
use warnings;

sub fib {
    my $n = shift;
    return $n if $n < 2;
    return fib($n - 1) + fib($n - 2);
}

for my $i (0..10) {
    print "fib($i) = ", fib($i), "\n";
}

Compile and run

$ perla hello.pl
fib(0) = 0
fib(1) = 1
fib(2) = 1
...
fib(10) = 55

Default ./perla foo.pl compiles and runs, cleaning up the binary after. To keep the executable:

$ perla -o hello hello.pl
$ ./hello
$ file hello
hello: ELF 64-bit LSB pie executable, x86-64, statically linked

One file. No perl required on the target. Ship it.

Optimization levels

Default is -O0 — fast compile, slow binary. For release, use -O2 or -O3:

$ perla -O2 -o app app.pl          # -O2 + -flto
$ perla -O3 -o app app.pl          # adds -march=native

For a typical web-app-size program the difference is:

FlagCompile time (gcc phase)Runtime perf
-O0 (default)Fast (~15s)Slower
-O2~100sFast
-O3~100sFastest (native CPU)

When you have modules

perla handles use Module::Name the way you'd expect — the module's source is found on the search path and included. The search path is built from the input file's directory, ., $PERL5LIB, and any use lib "..." statements.

$ mkdir -p lib/My
$ cat > lib/My/Greeter.pm <<'EOF'
package My::Greeter;
use strict;
sub hello { return "Hello, $_[0]!"; }
1;
EOF
$ cat > greet.pl <<'EOF'
use lib 'lib';
use My::Greeter;
print My::Greeter::hello("perla"), "\n";
EOF
$ perla greet.pl
Hello, perla!

Precompile for faster iteration

When your module tree gets large, compiling the script repeatedly means re-parsing every .pm every time. Precompile them once:

$ perla -M lib/My/Greeter.pm
Compiled lib/My/Greeter.pm.o (module: My::Greeter, init: perla_mod_init_My_Greeter)

$ perla greet.pl          # now uses cached .pm.o
Hello, perla!

Or precompile a whole directory recursively:

$ perla -M lib/
[perla] precompiling 42 .pm files under lib/
[perla] [1/42] ok lib/My/Greeter.pm
...
[perla] precompile done: 42 built, 0 skipped, 0 failed

It's idempotent — already-built modules are skipped on re-runs. Force a rebuild with --force-rebuild.

Make targets for larger projects: if you're shipping a real-world-sized app, add these to your Makefile:

PERLA ?= /path/to/perla

precompile:
	$(PERLA) -M lib/

precompile-force:
	$(PERLA) --force-rebuild -M lib/

precompile-clean:
	find lib -type f \( -name '*.pm.o' -o -name '*.pm.so' -o -name '*.pm.deps' \) -delete

Using CPAN modules

The most-used modules are built into perla's runtime — JSON, DBI, Carp, Data::Dumper, List::Util, Scalar::Util, Storable, Encode, File::Temp, Digest::*, MIME::Base64, Time::HiRes and more all work with no install step. For anything else, perla-cpan pulls it from CPAN:

# One-time: choose an install prefix
$ export PERLA_LIB=$HOME/.perla/local/lib/perla5
$ export PERLA5LIB=$PERLA_LIB

# Install by name — pure-Perl and XS alike, deps resolved for you
$ perla-cpan Try::Tiny Path::Tiny JSON::MaybeXS

# ...then just use them
$ perla myprog.pl

Unlike cpanm, there's no perl in the loop: perla-cpan compiles XS ahead of time against perla's perl.h shim and links it into your binary. See the CPAN docs for flags (--no-xs, --no-deps, --precompile, --dry-run) and the honest caveats.

Debugging what perla is doing

The --debug flag prints every compile-time decision (module search, cache hits, auto-builds) plus the exact gcc invocation:

$ perla --debug -o app app.pl 2>&1 | head -20
[perla] debug mode enabled
[perla] cc: gcc
[perla] compile-time lib paths (5):
[perla]   [0] .
[perla]   [1] /opt/bzperl/lib/site_perl/5.42.0
...
[perla] use Carp
[perla]   Carp: cache HIT /opt/bzperl/.../Carp.pm [.pm.o (static)]
[perla] use File::Spec
[perla]   File::Spec: cache MISS /opt/bzperl/.../File/Spec.pm — auto-building via perla -M
...
[cc] gcc -O0 -w -o app app.c /opt/bzperl/.../Carp.pm.o ... 2>&1
[cc] done in 16.03s (ok)

Use this when a use resolves to an unexpected file, when you want to see what the compiler spawned, or when compile time is surprising.

--keep to inspect the generated C

If something compiles but behaves weirdly, keep the intermediate .c:

$ perla --keep -o app app.pl
[perla] kept C file: app.c
$ grep 'perla_sub_main_' app.c    # see what each sub compiled to

Dropping into C

For FFI or performance-critical sections, perla supports __C__ blocks:

use strict;

# file-scope __C__: #includes, statics
__C__ {
    #include <sys/time.h>
}

sub ms_now {
    my $ms = 0;
    __C__ {
        /* Perl $foo → C var v_foo. Block is emitted verbatim. */
        struct timeval tv;
        gettimeofday(&tv, NULL);
        strada_decref(v_ms);
        v_ms = strada_new_int((int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000);
    }
    return $ms;
}

print "now: ", ms_now(), "ms\n";

See the full __C__ guide for the variable-name mapping, runtime helpers you can call, and memory rules.

Running under Cannoli (web apps)

Compile your Perl app as a .pm.so and serve it via Cannoli's preforking HTTP server:

$ perla -M MyApp.pm
Compiled MyApp.pm.so (module: MyApp, init: perla_mod_init_MyApp)

$ cannoli --library "./cannoli_perla.so:\
    so=$(pwd)/MyApp.pm.so;\
    init=perla_mod_init_MyApp;\
    handler=perla_sub_MyApp_handle" --dev -p 8080

The cannoli_perla.so bridge is under cannoli/lib/perla/ in the Cannoli repo.

Where to next

Full Documentation →

Compile flags, optimization, module cache, __C__ reference, module search paths, common failure modes.

Installing CPAN Modules →

perla-cpan: fetch from MetaCPAN, resolve dependencies, compile XS, install into a prefix.

Porting from Perl →

Converting Perl scripts to Strada source directly (alternative path — for when you want to embrace Strada's type annotations).

Cannoli Web Server →

The preforking web server perla-compiled handlers plug into.

Source on GitHub →

Browse the perla compiler, runtime, and test suite.