【问题标题】:How do you setup an Erlang NIF project with rebar?您如何使用 rebar 设置 Erlang NIF 项目?
【发布时间】:2013-06-22 18:36:46
【问题描述】:

我查看了 StackOverflow 上的问题,并在 Google 上搜索了一个在 rebar 中设置 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_hookpost_hookrebar.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)

因为我已经克隆了 tuncer 的 RE2 绑定项目,并且当我执行 rebar compile 时,请查看他的 build_deps.sh 脚本的输出。我的权限和他的一致:

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

知道我在这里缺少什么吗?我相信钢筋配置正确,可以调用脚本并进行编译。

【问题讨论】:

    标签: erlang rebar erlang-nif


    【解决方案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).
    

    【讨论】:

    • 感谢 Nym - 我选择了第二种方法。我没有看到如何控制共享库的名称,它始终是“emtn_drv.so”(无论我如何命名文件/等)。这里提交的更改:github.com/project-z/emutton/commit/…
    • 我实际上发现了我的问题,我的 rebar.config 文件实际上命名为"rebar.config ",末尾有两个空格。我什至不想承认我犯了这个错误,但我不得不向钢筋邮件列表上的人承认,他们很好地尝试回答我的问题。所以,我犯了愚蠢的错误。既然我已经正确命名了 rebar.config,那么 emtn.so 和 emtn_drv.so 已正确构建在 /priv/ 中。
    猜你喜欢
    • 2015-07-05
    • 2013-12-08
    • 2013-11-15
    • 2016-07-19
    • 2013-03-15
    • 2016-10-06
    • 2016-03-30
    • 2013-06-30
    • 2023-03-26
    相关资源
    最近更新 更多