diff --git a/rustler_mix/lib/rustler.ex b/rustler_mix/lib/rustler.ex index 9f79f6d63..ed984d650 100644 --- a/rustler_mix/lib/rustler.ex +++ b/rustler_mix/lib/rustler.ex @@ -88,25 +88,27 @@ defmodule Rustler do end defmacro __before_compile_nif__(_env) do - quote do - @on_load :rustler_init - - def rustler_path do - # TODO: Parametrise, and keep all crates in the list - {otp_app, path} = @load_from - Path.join(:code.priv_dir(otp_app), path) + quoted = + quote do + def rustler_path do + # TODO: Parametrise, and keep all crates in the list + {otp_app, path} = @load_from + Path.join(:code.priv_dir(otp_app), path) + end + + @on_load :rustler_init + @doc false + def rustler_init do + # Remove any old modules that may be loaded so we don't get + # :error, {:upgrade, 'Upgrade not supported by this NIF library.'}} + :code.purge(__MODULE__) + load_path = String.to_charlist(rustler_path()) + :ok = :erlang.load_nif(load_path, @load_data) + end end - @doc false - def rustler_init do - # Remove any old modules that may be loaded so we don't get - # :error, {:upgrade, 'Upgrade not supported by this NIF library.'}} - :code.purge(__MODULE__) - load_path = String.to_charlist(rustler_path()) - data = @load_data - :erlang.load_nif(load_path, data) - end - end + # quoted |> Macro.to_string |> IO.puts + quoted end @doc false diff --git a/rustler_mix/lib/rustler/compiler.ex b/rustler_mix/lib/rustler/compiler.ex index 57b8445a0..c5b5bb4ba 100644 --- a/rustler_mix/lib/rustler/compiler.ex +++ b/rustler_mix/lib/rustler/compiler.ex @@ -17,21 +17,39 @@ defmodule Rustler.Compiler do is_release = Mix.env() in [:prod, :bench] entry = artifacts[crate] - # Only a single file result per crate is supported right now - [filename] = entry[:filenames] - rel_filename = Path.basename(filename) + is_lib = :cargo_artifact.kind(entry) == :cdylib + is_bin = :cargo_artifact.kind(entry) == :bin - out_path = Path.join(priv_dir(entry, is_release), Path.basename(filename)) - dest = Path.join(:code.priv_dir(config.otp_app), out_path) - rel_dest = Path.relative_to_cwd(dest) + if !is_lib and !is_bin do + Mix.raise("Crate #{crate} is neither a 'bin' nor a 'cdylib' but #{entry[:kind]}") + end - shell.info(" Copying #{rel_filename} to #{rel_dest}") - File.mkdir_p!(Path.dirname(dest)) - File.copy!(filename, dest) + priv_dir = priv_dir(entry, is_release) + dest_root = :code.priv_dir(config.otp_app) - is_lib = entry[:kind] == ["cdylib"] + out_paths = + for filename <- :cargo_artifact.filenames(entry) do + out_path = Path.join(priv_dir, Path.basename(filename)) + dest = Path.join(dest_root, out_path) + rel_filename = Path.basename(filename) + rel_dest = Path.relative_to_cwd(dest) - %Config{config | lib: is_lib, load_path: Path.rootname(out_path)} + shell.info(" Copying #{rel_filename} to #{rel_dest}") + File.mkdir_p!(Path.dirname(dest)) + File.copy!(filename, dest) + + out_path + end + + [load_path] = + if is_lib do + out_paths |> Enum.filter(&:cargo_util.is_dylib/1) + else + exec = :cargo_artifact.executable(entry) + [Path.join(priv_dir, Path.basename(exec))] + end + + %Config{config | lib: is_lib, load_path: Path.rootname(load_path)} end defp priv_dir(entry, is_release) do @@ -42,7 +60,10 @@ defmodule Rustler.Compiler do "debug" end - "crates/#{entry[:name]}/#{entry[:version]}/#{type}" + name = :cargo_artifact.name(entry) + version = :cargo_artifact.version(entry) + + "crates/#{name}/#{version}/#{type}" end defp ensure_string(atom) when is_atom(atom) do diff --git a/rustler_mix/lib/rustler/compiler/server.ex b/rustler_mix/lib/rustler/compiler/server.ex index 827d62031..1808a4a61 100644 --- a/rustler_mix/lib/rustler/compiler/server.ex +++ b/rustler_mix/lib/rustler/compiler/server.ex @@ -26,14 +26,15 @@ defmodule Rustler.Compiler.Server do release: is_release } + Mix.shell().info("Starting build in #{File.cwd!()}") + cargo = :cargo.init(File.cwd!(), cargo_opts) - artifacts = :cargo.build_and_capture(cargo) + artifacts = :cargo.build(cargo) # This drops the unique key in favour of the crate name artifacts = artifacts - |> Map.values() - |> Map.new(&{&1[:name], &1}) + |> Map.new(&{:cargo_artifact.name(&1), &1}) {:reply, artifacts, artifacts} end diff --git a/rustler_mix/mix.lock b/rustler_mix/mix.lock index 65c756a4c..81e735df9 100644 --- a/rustler_mix/mix.lock +++ b/rustler_mix/mix.lock @@ -1,5 +1,5 @@ %{ - "cargo": {:git, "https://github.com/filmor/erlang-cargo.git", "1456f74ae8b064ad2c9e853953a30b6392a249ab", []}, + "cargo": {:git, "https://github.com/filmor/erlang-cargo.git", "b4159576565554e689eb1ac25ae2e634252d514b", []}, "earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"}, "ex_doc": {:hex, :ex_doc, "0.21.3", "857ec876b35a587c5d9148a2512e952e24c24345552259464b98bfbb883c7b42", [:mix], [{:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0db1ee8d1547ab4877c5b5dffc6604ef9454e189928d5ba8967d4a58a801f161"}, "jsx": {:hex, :jsx, "2.10.0", "77760560d6ac2b8c51fd4c980e9e19b784016aa70be354ce746472c33beb0b1c", [:rebar3], [], "hexpm", "9a83e3704807298016968db506f9fad0f027de37546eb838b3ae1064c3a0ad62"},