Skip to content

Commit

Permalink
Use runtime: false for rustler dependency (#559)
Browse files Browse the repository at this point in the history
When using `runtime: false`, we do not have access to the `Rustler`
module. Thus, we also cannot call `Rustler.construct_load_data/2` when
loading the NIF module. In order to allow `runtime: false` and also
construct `load_data` at load time, we need to add
`construct_load_data/2` to the target module.
  • Loading branch information
evnu committed Aug 29, 2023
1 parent ef06753 commit af496ee
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ See [`UPGRADE.md`](./UPGRADE.md) for additional help when upgrading to newer ver
* Deprecated `:rustler_crates` project configuration
* Mark `use Rustler` module configuration as compile-time
* Bump Rust edition to 2021
* Make `:rustler` a compile-time-only dependency (#516, #559)

## [0.29.1] - 2023-06-30

Expand Down
2 changes: 1 addition & 1 deletion prepare_release.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ sed -i "s/^version = \"[^\"]*\" # rustler_codegen version$/version = \"$VERSION\
sed -i "s/^rustler.*$/rustler = {path = \"..\/rustler\", version = \"$VERSION\"}/" rustler_bigint/Cargo.toml
sed -i "s/def rustler_version, do: \"[^\"]*\"$/def rustler_version, do: \"$VERSION\"/" rustler_mix/mix.exs rustler_mix/lib/rustler.ex
sed -i "s/@version .*$/@version \"$VERSION\"/" rustler_mix/mix.exs
sed -i "s/{:rustler, \".*\"}/{:rustler, \"~> $VERSION\"}/" rustler_mix/README.md
sed -i "s/{:rustler, \".*\"/{:rustler, \"~> $VERSION\"/" rustler_mix/README.md

echo "Committing version.."
git commit -m "(release) $VERSION" \
Expand Down
2 changes: 1 addition & 1 deletion rustler_benchmarks/mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ defmodule RustlerBenchmarks.MixProject do
defp deps do
[
{:benchee, "~> 1.0"},
{:rustler, path: "../rustler_mix"}
{:rustler, path: "../rustler_mix", runtime: false}
]
end
end
2 changes: 1 addition & 1 deletion rustler_mix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This package is available on [Hex.pm](https://hex.pm/packages/rustler). To insta
```elixir
def deps do
[
{:rustler, "~> 0.29.1"}
{:rustler, "~> 0.29.1", runtime: false}
]
end
```
Expand Down
57 changes: 30 additions & 27 deletions rustler_mix/lib/rustler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ defmodule Rustler do
end

defmacro __before_compile__(_env) do
default_load_data_value = %Rustler.Compiler.Config{}.load_data
default_fun_value = %Rustler.Compiler.Config{}.load_data_fun

quote do
@on_load :rustler_init

Expand All @@ -130,37 +133,37 @@ defmodule Rustler do
|> Application.app_dir(path)
|> to_charlist()

load_data = Rustler.construct_load_data(@load_data, @load_data_fun)
load_data = _construct_load_data(@load_data, @load_data_fun)

:erlang.load_nif(load_path, load_data)
end
end
end

def construct_load_data(load_data, load_data_fun) do
default_load_data_value = %Rustler.Compiler.Config{}.load_data
default_fun_value = %Rustler.Compiler.Config{}.load_data_fun

case {load_data, load_data_fun} do
{load_data, ^default_fun_value} ->
load_data

{^default_load_data_value, {module, function}}
when is_atom(module) and is_atom(function) ->
apply(module, function, [])

{^default_load_data_value, provided_value} ->
raise """
`load_data` has to be `{Module, :function}`.
Instead received: #{inspect(provided_value)}
"""

{load_data, load_data_fun} ->
raise """
Only `load_data` or `load_data_fun` can be provided. Instead received:
>>> load_data: #{inspect(load_data)}
>>> load_data_fun: #{inspect(load_data_fun)}
"""
defp _construct_load_data(load_data, load_data_fun) do
default_load_data_value = unquote(default_load_data_value)
default_fun_value = unquote(default_fun_value)

case {load_data, load_data_fun} do
{load_data, ^default_fun_value} ->
load_data

{^default_load_data_value, {module, function}}
when is_atom(module) and is_atom(function) ->
apply(module, function, [])

{^default_load_data_value, provided_value} ->
raise """
`load_data` has to be `{Module, :function}`.
Instead received: #{inspect(provided_value)}
"""

{load_data, load_data_fun} ->
raise """
Only `load_data` or `load_data_fun` can be provided. Instead received:
>>> load_data: #{inspect(load_data)}
>>> load_data_fun: #{inspect(load_data_fun)}
"""
end
end
end
end

Expand Down
7 changes: 6 additions & 1 deletion rustler_mix/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ defmodule TestRustlerMix.MixProject do
def application, do: [ ]
defp deps, do: [ {:rustler, path: "$rustler_mix"} ]
defp deps, do: [ {:rustler, path: "$rustler_mix", runtime: false} ]
end
EOF

Expand Down Expand Up @@ -90,5 +90,10 @@ EOF

mix test

# See https://github.com/rusterlium/rustler/issues/516, we also need to verify that everything
# we need is part of a release.
mix release
_build/dev/rel/test_rustler_mix/bin/test_rustler_mix eval 'RustlerMixTest.add(1, 2)'

echo "Done; cleaning up"
rm -r $tmp

0 comments on commit af496ee

Please sign in to comment.