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
- 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).
-
:io_lib.format("~ts/erts-~ts/include", [:code.root_dir(), :erlang.system_info(:version)])
will return exactly what you need for building NIFs.
- 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.