75 lines
1.6 KiB
Elixir
75 lines
1.6 KiB
Elixir
defmodule Mix.Tasks.Compile.Nif do
|
|
@shortdoc "Compile a NIF"
|
|
|
|
def run(_) do
|
|
config = Keyword.fetch!(Mix.project, :nif)
|
|
|
|
file = Keyword.fetch!(config, :file)
|
|
paths = Keyword.fetch!(config, :paths)
|
|
flags = Keyword.fetch!(config, :flags)
|
|
exts = Keyword.fetch!(config, :exts)
|
|
compiler =
|
|
Keyword.get(config, :compilers, ["cc", "gcc", "clang"])
|
|
|> find_compiler
|
|
|
|
# Create the directory (e.g. "priv/")
|
|
file |> Path.dirname |> File.mkdir_p!
|
|
|
|
# Figure out whether we should compile the NIF. Compare the source
|
|
# files with the target binary. If the target is newer, recompile.
|
|
to_compile = Mix.Utils.extract_files(paths, exts)
|
|
|
|
case Mix.Utils.extract_stale(to_compile, [file]) do
|
|
[] ->
|
|
:noop
|
|
_ ->
|
|
cmd =
|
|
[compiler, "-shared", "-fpic", "-o #{file}", to_compile, flags]
|
|
|> List.flatten
|
|
|> Enum.join(" ")
|
|
|
|
IO.puts System.cmd(cmd)
|
|
end
|
|
end
|
|
|
|
defp find_compiler([compiler | tail]) do
|
|
case System.find_executable(compiler) do
|
|
nil ->
|
|
find_compiler(tail)
|
|
path ->
|
|
path
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
defmodule Geef.Mixfile do
|
|
use Mix.Project
|
|
|
|
def project do
|
|
[ app: :geef,
|
|
version: "0.0.1",
|
|
compilers: [:nif, :elixir, :app],
|
|
nif: nif,
|
|
deps: deps ]
|
|
end
|
|
|
|
def nif do
|
|
[ paths: ["c_src"],
|
|
exts: [:c],
|
|
file: "priv/geef.so",
|
|
flags: "-lgit2" ]
|
|
end
|
|
|
|
# Configuration for the OTP application
|
|
def application do
|
|
[]
|
|
end
|
|
|
|
# Returns the list of dependencies in the format:
|
|
# { :foobar, "0.1", git: "https://github.com/elixir-lang/foobar.git" }
|
|
defp deps do
|
|
[]
|
|
end
|
|
end
|