Mixing elixir / erlang / alpaca in an umbrella application

I’m trying to integrate an alpaca module with an Elixir umbrella application.

I have no idea how to tackle this, but I think I have the various pieces of the puzzle:

  • a rebar3 project can contain a mix of erlang (.erl) and alpaca (.alp) files
  • the alpaca files can export functions in modules:

E.g, with this module in a my_module.alp file:

module my_module

-- one function that takes a single argument will be publicly accessible:
export double/1

let double x =
  let add a b = a + b in
  add x x

It should export an erlang module named alpaca_my_module, with the double/1 function

  • the rebar3 project will compile the .alp file if it has a rebar.config file like this:
{erl_opts, [debug_info]}.
{deps, []}.

{shell, [
  % {config, "config/sys.config"},
    {apps, [alpatest]}
]}.

{plugins, [
    {rebar_prv_alpaca, ".*", {git, "https://github.com/alpaca-lang/rebar_prv_alpaca.git", {branch, "master"}}}
]}.

{provider_hooks, [{post, [{compile, {alpaca, compile}}]}]}.

When running rebar3 compile in an alpaca project, I manage to produce a file like ./_build/default/lib/alpatest/ebin/alpaca_my_module.beam

  • mix seems to have built-in support for building elixir projects. I’m in an umbrella project, so I tried doing something like this:
project/
  apps/
         my_alpaca_app/
             src/
                 .... . erl
                 my_module.alp
             rebar.config
             mix.exs
          an_elixir_app
             lib/
                foo.ex
  • The mix.exs file for the my_alpaca application is a default one (I have not even changed the list of compilers.)

  • I want to call the double function in my elixir application. So the mix.exs file for my_elixir_app mentions it as an “in_umbrella” dependency:

defp deps() do 
  [ { :my_alpaca_app, in_umbrella: true} ....
  • When I run mix compile in my elixir app, it seems like the erlang part of my_alpaca project is build ; but the alp one is not build (the alpaca_my_module.beam file is not created.)

So my understanding is that mix ignores the rebar.config file entirely.
Does it looks like a good lead ? How would I tell mix to use it ?

  • The next step would be to call the erlang / alp function in my elixir code:
def foo() do
  x = :alpaca_my_module.double(42)
  ... 
end

Should this be the right syntax ?

1 Like

If it’s not a mix project then it shouldn’t be in am umbrella, use a path dependency or so instead and see if that works?

Yep yep. :slight_smile:

I have a toy project that has Elixir, Erlang, LFE, and Gleam child apps all in the same umbrella: https://github.com/wojtekmach/hello_beam and so by that token Alpaca should work too if it’s built by rebar3. If you get it working a PR to hello_beam would be very appreciated! :slight_smile:

3 Likes

I should have make it clear, but what I’m trying to do is to have only mix projects in my umbrella.

What I really want is to be able to run “mix compile” as usual, and have both the alpaca and elixir code be compiled properly.

OvermindDL1

    October 3

If it’s not a mix project then it shouldn’t be in am umbrella, use a path dependency or so instead and see if that works?

phtrivier:
Should this be the right syntax ?

Yep yep. :slight_smile:

1 Like

Sounds like you could make a Mix compiler for alpaca then? They aren’t actually very hard at all. :slight_smile:

I do not doubt they’re easy, but I have no idea how to do them. Is there a doc somewhere ?

Here’s an example for LFE: https://github.com/elixir-lang/elixir/blob/v1.9.2/lib/mix/lib/mix/compilers/erlang.ex#L17:L28. You use this code inside a mix task that has use Mix.Task.Compiler, like this one: https://github.com/elixir-lang/elixir/blob/v1.9.2/lib/mix/lib/mix/tasks/compile.erlang.ex

2 Likes