Search code examples
compilationmakefileerlangrebar

rebar compile fails with bitcask - "errno.h": no such file


I am new to Erlang, so i am going through Joe Armstrong's book "Programming Erlang". In chapter 25 there's an example on how to work with rebar. I followed the instructions and created a Makefile

all:
    test -d deps || rebar get-deps
    rebar compile -v
    @erl -noshell -pa './deps/bitcask/ebin' -pa './ebin' -s myapp start

and rebar.config

{deps, [
    {bitcask, ".*", {git, "git://github.com/basho/bitcask.git", "master"}}
]}.

Getting the dependencies works, but compiling fails.

The verbose output tells me that this command fails

cmd: cc -c $CFLAGS -g -Wall -fPIC  -I"/usr/lib/erlang/lib/erl_interface-3.7.18/include" -I"/usr/lib/erlang/erts-6.2/include"   c_src/bitcask_nifs.c -o c_src/bitcask_nifs.o

with this error

/home/user/folder/deps/bitcask/c_src/bitcask_nifs.c:22:19: fatal error: errno.h: No such file or directory

But

find /usr/include -name errno.h

gives me

/usr/include/x86_64-linux-gnu/asm/errno.h
/usr/include/asm/errno.h
/usr/include/linux/errno.h
/usr/include/asm-generic/errno.h

So I was asking myself..

  • what am I missing?
  • how can I tell rebar about the depencies on the C libraries and where to find them?
  • why isn't this configured correctly in the Makefile of bitcask?

Maybe I was searching for the wrong terms, but I couldn't find any solution in the internets.
Many thanks in advance


Solution

  • There are two thing to consider

    rebar options

    You can set options for compiling C code with port_env option in rebar.config.

    comiling deps

    Since bitstack is your dependency, it is not compiled with yours rebar config, but with it's own. So if you would like to change anything, you would have to modify the bitcask file.

    Fortunately, if you look into config their writen all C compilation is done with environment variable $ERL_CFLAGS. And again, in rebar source code you can see that this flag is responsible for include paths in your compilation.

    So easist way would be extending $ERL_CFLAGS in your Makefile before compilation, with something like this

    all: ERL_CFLAGS = "$ERL_CFLAGS -I /usr/include/linux/errno.h"
    all: 
        test -d deps || rebar get-deps
        rebar compile -v
        @erl -noshell -pa './deps/bitcask/ebin' -pa './ebin' -s myapp start
    

    Just make sure that this include works for you, and that you are not overwriting any flags you are using.