How to specify C include path for asdf managed elixir in a generic way?

I have erlang and elixir under asdf. I would like to specify the include path for erl_nif.h in a generic way. That is I do not want to hard code a path like this:

-I/Users/xx/.asdf/installs/erlang/23.3.1/usr/include

Is there a way in which I can create an include path in my mix.exs file that can work even when erlang/elixir versions are changed?

Thank you much.

1 Like

Which (Mix) compiler for NIFs you are using?

I’m afraid I don’t understand the term “Mix compiler”. But here’s my mix file below.

EDIT: This compiles and runs fine ,but that is because I have set INCLUDE_PATH and LIBRARY_PATH environment variables, which I would like to avoid if I can.

Thank you for your help.


  def project do
    [
      app: :cam,
      version: "0.1.0",
      elixir: "~> 1.11",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      compilers: [:cam] ++ Mix.compilers
    ]
  end

defmodule Mix.Tasks.Compile.Cam do
  def run(_args) do
    {result, _errcode} = System.cmd("g++",
      ["--std=c++11",
        "-undefined",
        "dynamic_lookup",
        "-dynamiclib",
        "-O3",
        "-o", "cap.so",
        "clib/cap.cpp"
      ], stderr_to_stdout: true)
    IO.puts(result)
  end
end
  1. Use CC and CXX env variables instead of defining g++ directly. What if user is on macOS/*BSD or want to use other compiler (for example for cross compiling)? You can specify defaults to cc and cxx respectively, as these are POSIX-y standard names for C and C++ compilers (should be linked to whatever user wants as a default).
  2. :io_lib.format("~ts/erts-~ts/include", [:code.root_dir(), :erlang.system_info(:version)]) will return exactly what you need for building NIFs.
  3. With fairly modern GCC --std=c++11 is not needed as --std=gnu++11 is default for some time now.

Alternatively, instead of writing your own compiler you can use elixir_make together with plain old Makefile.

1 Like

You are right. I actually wanted to not hard-code the compiler as well, not just the include path.

Thank you muchly much for the pointers to elixir_make and to :io_lib.format.