Building Erlang OTP R14B on OpenBSD 4.7

Summary: OpenBSD is not GNU/Linux!

I just spent the last 20 minutes baffled by some weird errors as I was building Erlang on an OpenBSD box I am setting up.

$ make
make: "/home/acces/otp_src_R13B04/Makefile" line 88: Missing dependency operator
make: "/home/acces/otp_src_R13B04/Makefile" line 89: Missing dependency operator
100 similar lines follow

The problem is… that when you type make, OpenBSD — and probably NetBSD and FreeBSD — all use BSD make by default, NOT GNU make! Silly me. I even had just installed GNU make a couple hours earlier!

So anyway:

$ pkg_add -i -v gmake
[download, unzip, configure Erlang OTP]
$ make # WILL FAIL!
$ gmake

Bitstrings and Binaries (Erlang bit syntax minihowto part 2)

What’s the difference between the Binary and Bitstring types in Erlang? Well, a bitstring is a sequence of bits of any length; a binary is a sequence of bits where the number of bits is evenly divisible by 8. (So any binary is also a bitstring.)

Some examples:

1> <<2#11110000:5>>.
2> <<2#11110000:6>>.
3> erlang:is_bitstring(<<2#11110000:6>>).
4> erlang:is_binary(<<2#11110000:6>>).
5> erlang:is_bitstring(<<2#11110000:8>>).
6> erlang:is_binary(<<2#11110000:8>>).

In the Erlang bit syntax there are 2 clarifying (?) type synonyms:

bytes == binary
bits  == bitstring

which are basically telling you to think of binaries as sequence of bytes, and bitstrings as sequence of bits. Quite obvious right? Well, it wasn’t for me at first.

It’s also worth noting how binaries and bitstrings are converted into text strings. Given the binary <<16#50>> storing the letter ‘P’,

7> <<16#50>>
8>erlang:bitstring_to_list(<<16#50>>). #I could've used binary_to_list()
"P"          %great!
[<<16:5>>]  %mmh...

The result of command #9 is not exactly what I had imagined. Yes, it’s a list, but it’s certainly not a text string, and I was expecting a text string. Why was I expecting a text string if the API is named bitstring_to_list() ? Because if I was in the middle of coding a text manipulation algorithm and called bitstring_to_list(), I would probably (wrongly) assume that it would do some magic and transform any bitstring in a usable text string. Why? Because we are used to treat text strings as lists. Why? Because we don’t have APIs that mention “strings”: all the builtin APIs only mention lists. That’s the problem. We are using a list API as if it was a string API, when a generic list is not necessarily a string.

Erlang bit syntax mini How-To

I don’t know why but Erlang bit syntax always confused me. I always skipped it while reading the docs, until, well, now that I need it. I should say this is not meant to be an exhaustive how-to by any means. It’s just a collection of notes, but howto sounded better. 🙂 There are better guides out there. [Reference docs too.]

Anyway. Here’s some binary data in Erlang:


What does all this mean? Let’s analyze it, left to right.

  1. 16# This specifies we want to express the number in base 16.
  2. We have an eight digits hex number.
  3. No type specification is provided: default is unsigned integer.
  4. No unit specification is provided: default for integer is 1, which means ‘bits’.
  5. :32 Size specification: this tells erlang to consider 32 units, which in our case means 32 bits, since we are dealing with bits.

Let’s evaluate it:

86> <<16#2092105a:32>>.

What if we forget to specify the size spec? In that case the default will apply and since we’re dealing with an integer type, the default is 8 (bits). For Erlang this means we are going to return the least significant byte:

87> <<16#2092105a>>.

Now that we know that, we can get a subset of bits by setting the size accordingly:

88> <<16#2092105a:16>>.
<<16,90>>     %two least significant bytes

We don’t need to specify a size multiple of 8:

89> <<16#1192FFFF:15>>.

It’s pretty cool how easy it is to slice bytes apart at the bit level. I was sort of surprised that if we slice some internal bits it looks like the bits at the right are moved to the left. E.g. here we take the 4 least significant bits of the first 0xFF:

90> <<16#FF:4,0,16#FF,0>>.

but instead of obtaining:

F 00 FF 00

we get:

F0 0F F0 0          [240 == F0]

Also, the value doesn’t need to be a literal, it can be an expression:

91> N = 16#FF00FF01.
92> <<N:32>>.

And therefore, given some binary data, we can also pattern-match it super easily:

<SourcePort:16, DestinationPort:16, CheckSum:16, Payload/binary>> = SomeBinary.

There’s more to Erlang bit syntax than this, but I’ll stop here for now.