Skip to content

Commit cf9b01d

Browse files
committed
Add example project
1 parent 094ea2f commit cf9b01d

File tree

12 files changed

+132
-1
lines changed

12 files changed

+132
-1
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
with:
1818
otp-version: "27.2"
1919
elixir-version: "1.18.2"
20-
- run: mix deps.get
20+
- run: mix deps.get --check-locked
2121
- run: mix deps.compile
2222
- run: mix format --check-formatted
2323
- run: mix deps.unlock --check-unused
@@ -59,3 +59,11 @@ jobs:
5959
working-directory: test
6060
- run: mix test
6161
working-directory: test
62+
- name: Test example/
63+
run: |
64+
mix deps.get --check-locked
65+
mix format --check-formatted
66+
mix deps.unlock --check-unused
67+
mix test --warnings-as-errors
68+
working-directory: example
69+
if: ${{ !startsWith(matrix.os.id, 'windows') }}

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ FINE_NIF(add, 0);
110110
FINE_INIT("Elixir.MyLib.NIF");
111111
```
112112
113+
See [`example/`](https://github.com/elixir-nx/fine/tree/main/example) project.
114+
113115
## Encoding/Decoding
114116

115117
Terms are automatically encoded and decoded at the NIF boundary based

example/.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

example/.gitignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# The directory Mix will write compiled artifacts to.
2+
/_build/
3+
4+
# If you run "mix test --cover", coverage assets end up here.
5+
/cover/
6+
7+
# The directory Mix downloads your dependencies sources to.
8+
/deps/
9+
10+
# Where third-party dependencies like ExDoc output generated docs.
11+
/doc/
12+
13+
# If the VM crashes, it generates a dump, let's ignore it too.
14+
erl_crash.dump
15+
16+
# Also ignore archive artifacts (built via "mix archive.build").
17+
*.ez
18+
19+
# Ignore package tarball (built via "mix hex.build").
20+
example-*.tar
21+
22+
# Temporary files, for example, from tests.
23+
/tmp/

example/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
SRC := c_src/example_nif.cpp
2+
TARGET := $(MIX_BUILD_DIR)/example_nif.so
3+
4+
CPPFLAGS := -std=c++17 -fvisibility=hidden -fPIC -I$(ERL_INCLUDE_DIR) -I$(FINE_INCLUDE_DIR)
5+
6+
ifeq ($(shell uname -s),Darwin)
7+
LDFLAGS := -dynamiclib -undefined dynamic_lookup
8+
else
9+
LDFLAGS := -shared
10+
endif
11+
12+
all: $(TARGET)
13+
14+
$(TARGET): $(SRC)
15+
$(CXX) $(CPPFLAGS) $(LDFLAGS) -o $@ $^

example/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Example
2+
3+
Example project using Fine to implement NIFs.
4+
5+
To run tests, execute:
6+
7+
```shell
8+
$ mix deps.get
9+
$ mix test
10+
```

example/c_src/example_nif.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <fine.hpp>
2+
3+
int64_t add(ErlNifEnv *env, int64_t x, int64_t y) {
4+
return x + y;
5+
}
6+
7+
FINE_NIF(add, 0);
8+
FINE_INIT("Elixir.Example");

example/lib/example.ex

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
defmodule Example do
2+
@on_load :load_nif
3+
@mix_build_dir Mix.Project.build_path()
4+
5+
defp load_nif do
6+
:erlang.load_nif(~c"#{@mix_build_dir}/example_nif", 0)
7+
end
8+
9+
@doc """
10+
Adds two numbers using NIF.
11+
12+
## Examples
13+
14+
iex> Example.add(1, 2)
15+
3
16+
"""
17+
def add(_x, _y) do
18+
:erlang.nif_error("nif not loaded")
19+
end
20+
end

example/mix.exs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
defmodule Example.MixProject do
2+
use Mix.Project
3+
4+
def project do
5+
[
6+
app: :example,
7+
version: "0.1.0",
8+
elixir: "~> 1.15",
9+
compilers: [:elixir_make] ++ Mix.compilers(),
10+
make_env: fn ->
11+
%{
12+
"MIX_BUILD_DIR" => Mix.Project.build_path(),
13+
"ERL_INCLUDE_DIR" => "#{:code.root_dir()}/usr/include",
14+
"FINE_INCLUDE_DIR" => Fine.include_dir()
15+
}
16+
end,
17+
deps: deps()
18+
]
19+
end
20+
21+
def application do
22+
[
23+
extra_applications: [:logger]
24+
]
25+
end
26+
27+
defp deps do
28+
[
29+
{:elixir_make, "~> 0.9.0"},
30+
{:fine, path: ".."}
31+
]
32+
end
33+
end

example/mix.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
%{
2+
"elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"},
3+
}

example/test/example_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
defmodule ExampleTest do
2+
use ExUnit.Case, async: true
3+
doctest Example
4+
end

example/test/test_helper.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ExUnit.start()

0 commit comments

Comments
 (0)