Как настроить проект Erlang NIF с арматурой?

Я просмотрел вопросы здесь, в StackOverflow, и погуглил пример настройки проекта Basic NIF в арматуре для упаковки библиотеки C++.

Я использовал проект библиотеки на GitHub в качестве руководства:

https://github.com/tuncer/re2

Мой проект здесь:

https://github.com/project-z/emutton/

Когда я делаю rebar compile && rebar eunit, я получаю ошибку в тесте eunit, потому что он не может найти emtn.so:

$ rebar compile && rebar eunit 
==> emutton (compile)
==> emutton (eunit)
undefined
*** test module not found ***
**emtn

=ERROR REPORT==== 25-Jun-2013::12:21:55 ===
The on_load function for module emtn returned {error,
                                               {load_failed,
                                                "Failed to load NIF library: 'dlopen(/.../source/emutton/priv/emtn.so, 2): image not found'"}}
=======================================================
  Failed: 0.  Skipped: 0.  Passed: 0.
One or more tests were cancelled.
ERROR: One or more eunit tests failed.
ERROR: eunit failed while processing /.../source/emutton: rebar_abort

Когда я вызываю rebar compile, он создает только один файл драйвера, emtn_drv.so и не emtn.so:

$ tree priv 
priv
└── emtn_drv.so

0 directories, 1 file

У меня есть оператор эха в c_src/build_deps.sh, который я не вижу при вызове rebar clean. Кажется, что мои pre_hook и post_hook в rebar.config полностью игнорируются:

{pre_hooks, [{compile, "c_src/build_deps.sh"}]}.
{post_hooks, [{clean, "c_src/build_deps.sh clean"}]}.

Примеры отсутствия вывода из rebar:

$ rebar compile 
==> emutton (compile)
$ rebar clean 
==> emutton (clean)

Потому что я клонировал проект привязки RE2 tuncer, и когда я делаю rebar compile, вижу вывод из его скрипта build_deps.sh. Разрешения у меня совпадают с разрешениями у него:

-rwxr-xr-x  1 ajl  staff   891B Jun 25 12:30 c_src/build_deps.sh

Есть идеи, что мне здесь не хватает? Я считаю, что арматура настроена правильно, чтобы вызвать скрипт и выполнить компиляцию.


person lenards    schedule 25.06.2013    source источник


Ответы (1)


Ваша проблема в том, что строка в вашем rebar.config

https://github.com/project-z/emutton/blob/master/rebar.config%20#L1

Не соответствует тому, что вы пытаетесь загрузить

https://github.com/project-z/emutton/blob/master/src/emtn.erl#L25

Вы должны либо изменить rebar.config на

{port_specs, [{"priv/emtn.so",["c_src/emtn_nif.c"]}]}.

и измените emtn.erl на

erlang:load_nif(filename:join(PrivDir, "emtn"), 0).  % ?MODULE is an atom, I believe you need a string

Или измените emtn.erl на

erlang:load_nif(filename:join(PrivDir, "emtn_drv"), 0).
person Nym    schedule 25.06.2013
comment
Спасибо, Ним - я выбрал второй подход. Я не видел, как управлять именем общей библиотеки, это всегда было emtn_drv.so (независимо от того, как я называл файлы/и т. д.). Вот зафиксированные изменения: github.com/project-z/emutton/commit/ - person lenards; 26.06.2013
comment
Я действительно разобрался со своей проблемой, мой файл rebar.config на самом деле назывался "rebar.config " с двумя пробелами в конце. Я даже не хочу признавать, что совершил эту ошибку, но я должен был признаться людям из списка рассылки по арматуре, которые были достаточно любезны, чтобы попытаться ответить на мой вопрос. Так что глупая ошибка с моей стороны. Теперь, когда я правильно назвал rebar.config, emtn.so и emtn_drv.so правильно встроены в /priv/. - person lenards; 26.06.2013