Background
When I started with Erlang I used a simple Makefile to call erlc and pretty
much did things by hand. After a number of years in the wilderness I found out
about rebar from Basho and started using that
to compile my code. Everything was good, rebar knew how to compile OTP apps and pull down external
dependencies. Except when I needed to generate releases. It’s
not necessarily straight forward to get rebar to build you a nice release,
not that it’s impossible
it’s just not as simple as I’d like.
Enter Sinan, the somewhat forgotten erlang build tool.
Sinan is a build tool designed to build Erlang/OTP projects, releases and applications. It claims to be more OTP than rebar and uses the OTP metadata artefacts to build your project with little configuration needed.
Let’s see how well it delivers on the promise.
Sinan From Scratch
First you’ll need Erlang installed, which your friendly local package management tool should provide. I’m using Homebrew on OSX so I just did:
1 2 3 4 5 6 7 | |
Linux should be similarly straight forward and Windows well you’re on your own.
Grab sinan from the downloads page on github, I’m using version 4.1.1. Put it somewhere on your PATH, I’ve got mine in ~/bin which is on my PATH, and chmod +x it so it’s executable.
Now for the fun bit, type sinan gen and fill in the details.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
From that Sinan has generated a project, filling in your details, with an OTP application and some build configuration. Your directories should look something similar to this.
1 2 3 4 5 6 7 8 9 10 11 12 | |
It includes all the standard directories you’d expect plus a sinan.config
file.
First a little diversion, we need to add a line to the sinan config file, which
tells sinan to include the erlang runtime system when it generates a release.
Open sinan.config and add {include_erts, true}. as the last line. It should
look like this:
1 2 3 4 5 6 7 8 9 10 | |
Back to making our generated code runnable.
By default the generated supervisor doesn’t point to a valid module so you’ll
need to remedy that before trying to startup the application. Create a new file
called sinan_demo_server.erl in src and drop the following code in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | |
It’s a pretty standard OTP gen_server application with 2 API
methods. add_one/0 adds 1 to the counter and total/0 returns the value of the
counter. The record definition setups up the state record for this server with
just a count attribute. The 2 API functions use the gen_server:call/2 method
to hit the OTP callback for handle_call/3.
Next we need to fix the supervisor so it starts the correct module. Change
sinan_demo_sup.erl so it looks like the code below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
The 2 changes we have make is to start_link/0 so we can call the server
directly, and fix the child spec so it starts our new module.
Now we need to add the sinan_demo_server module to sinan_demo.app.src so we
know about it when generating the OTP application. Just add it to the list of
modules like so:
1 2 3 4 5 6 7 8 9 10 11 12 | |
Compile with sinan build and hopefully everything works.
From here you’ve got a few options to get your application running, but the easiest is just to use the sinan shell and start your application from there.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
We’ve started a shell and checked what applications are started with
application:which_applications(). Now start the demo application with:
1 2 | |
Now lets test that we can call the application.
1 2 3 4 | |
As you can see it’s calling the server and incrementing the call count.
The next step is to create a release, which is as simple as running sinan release
Sinan has created a number of new directories under _build
1 2 3 4 5 6 7 8 9 10 11 | |
The bin directory is still there from last time but now we have an erts, lib
and releases directories. erts is there because earlier we asked sinan to
include an erlang runtime, so you can copy everything under _build/sinan_demo to
another machine without erlang installed and run this application. The
limitation being that the CPU and OS needs to match the machine you’ve built
on. lib includes all the applications you asked sinan to include, they’ll
match what you have in your collective .app.src files. releases contains
configuration files specific to a particular release of the application.
Starting the release generated is as simple as
1 2 3 4 5 6 7 8 9 10 | |
We’ll leave it there for now, but if you’re curious like me you’ll probably have a bunch of questions of where to take sinan next.
Next time I’m going to cover:
- Generating Version 2
- Doing an OTP upgrade to Version 2
- Downgrading to Version 1
But if you’ve got other suggestions please leave them in the comments.