编译Elixir NIF时遇unknown application: :nif_bartender错误求助
问题描述
在FreeBSD环境(Elixir 1.14.4、OTP 25)编译包含bartender_filter(hex版本0.1.2,rustrict的Elixir绑定)依赖的应用时,出现编译错误:
[LOGIN@s1]:<~/domains/LOGIN.serv00.net/backend>$ linker=gcc mix compile ==> nif_bartender Compiling 1 file (.ex) == Compilation error in file lib/bartender.ex == ** (ArgumentError) unknown application: :nif_bartender (elixir 1.14.4) lib/application.ex:954: Application.app_dir/1 (elixir 1.14.4) lib/application.ex:981: Application.app_dir/2 (rustler 0.23.0) lib/rustler/compiler/config.ex:48: Rustler.Compiler.Config.from/3 (rustler 0.23.0) lib/rustler/compiler.ex:9: Rustler.Compiler.compile_crate/2 lib/bartender.ex:2: (module) could not compile dependency :bartender, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile bartender", update it with "mix deps.update bartender" or clean it with "mix deps.clean bartender"
单独克隆bartender仓库运行mix test正常,但在主应用中编译失败。
错误原因
核心问题是OTP应用名称不匹配:
- 在bartender的
mix.exs中,定义的OTP应用名称是:nif_bartender:def project do [ app: :nif_bartender, # ...其他配置 ] end - 但在
lib/bartender.ex中,Rustler引用的otp_app却是:bartender:use Rustler, otp_app: :bartender, crate: :bartender - 同时,hex包的名称是
bartender_filter,主应用中依赖使用了别名:bartender,进一步加剧了名称混淆:{:bartender, "~> 0.1.1", hex: :bartender_filter}
当主应用编译依赖时,Rustler尝试查找:bartender应用的目录,但实际OTP应用名称是:nif_bartender,导致找不到应用目录,抛出unknown application错误。
解决方案
需要统一OTP应用名称、Rustler配置和依赖引用,以下两种方案任选:
方案1:修复bartender包(推荐,从根源解决)
修改bartender项目的配置,统一名称:
- 修改
mix.exs:将OTP应用名称改为:bartender,和Rustler配置一致:def project do [ app: :bartender, # 原:nif_bartender改为:bartender version: "0.1.2", # ...其他配置保持不变 ] end - 保持
lib/bartender.ex的Rustler配置不变:use Rustler, otp_app: :bartender, crate: :bartender - 重新发布hex包:更新版本号(如0.1.3)后重新发布到hex.pm。
方案2:临时适配主应用(无需修改包)
如果暂时无法重新发布包,可以在主应用中调整依赖配置,显式指定OTP应用名称:
- 修改主应用的
mix.exs依赖,添加:app选项指定实际的OTP应用名称:nif_bartender:{:bartender, "~> 0.1.2", hex: :bartender_filter, app: :nif_bartender} - 清理并重新编译依赖:
mix deps.clean bartender mix deps.get linker=gcc mix compile
验证方法
修复后,运行以下命令确认编译正常:
linker=gcc mix compile mix test
如果是修改了包的情况,还可以创建一个新的测试应用,添加依赖后调用Bartender.censor("test")确认功能正常。
内容的提问来源于stack exchange,提问作者Clover Johnson
相关产品推荐
相关产品推荐

