Error Compiling in Erlang: Missing ‘erl_nif.h’ File

The error indicates that the 'erl_nif.h' file is missing during the compilation of the USB dependency. This is causing the build to fail in the Erlang/Elixir project. You can attempt to resolve the issue by recompiling, updating, or cleaning the USB dependency using mix commands.

Code with Original Error:

Failed to eval: io:format("~ts/erts-~ts/include/", [code:root_dir(), erlang:system_info(version)]).

C usb_nif.o
usb_nif.c:8:10: fatal error: 'erl_nif.h' file not found
#include <erl_nif.h>
^~~~~~~~~~~
1 error generated.
make: *** [_build/usb_nif.o] Error 1
===> Hook for compile failed!

==> palmsync4mac
** (Mix) Could not compile dependency :usb, "/Users/marbury/.mix/elixir/1-17/rebar3 bare compile --paths /Users/marbury/Projects/Private/palmsync4mac/_build/dev/lib/*/ebin" command failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile usb --force", update it with "mix deps.update usb" or clean it with "mix deps.clean usb".

Resolving the Missing ‘erl_nif.h’ File Error

When compiling Erlang/Elixir projects that have dependencies on native code, such as the usb library in this case, you might encounter the error:

codefatal error: 'erl_nif.h' file not found

This error generally occurs when the required header files from Erlang’s Native Interface (NIF) are not available in the system’s include paths. In this case, the missing erl_nif.h file prevents the compilation of usb_nif.c, causing the build to fail.

Here’s a step-by-step guide to resolve this issue:

1. Install or Reinstall Erlang/OTP Development Headers

The file erl_nif.h is part of the Erlang/OTP development environment. Ensure that you have Erlang installed correctly, along with its development headers.

For macOS users, you can install Erlang using Homebrew:

codebrew install erlang

If you already have Erlang installed, but are still facing this issue, try reinstalling it to ensure the necessary files are present:

codebrew reinstall erlang

2. Check the Path for Erlang Include Files

Erlang’s header files, including erl_nif.h, are typically located in a directory like:

code/usr/local/lib/erlang/usr/include/

You can verify this by running the following Erlang command to check where Erlang is installed:

codeio:format("~ts/erts-~ts/include/", [code:root_dir(), erlang:system_info(version)]).

This command should return the correct path to the Erlang installation, including the include directory. If the path is incorrect, you may need to update your environment variables to point to the correct location.

3. Set the ERL_INTERFACE_DIR Environment Variable

In some cases, the build process may not be able to find the header files because the environment variables are not set correctly. You can manually set the ERL_INTERFACE_DIR variable to point to the correct location of the Erlang headers.

For macOS or Linux:

codeexport ERL_INTERFACE_DIR=/usr/local/lib/erlang/usr/include

Add this line to your .bash_profile or .zshrc file to make the change permanent. Then reload your shell:

codesource ~/.bash_profile   # or ~/.zshrc

4. Force Recompile the USB Dependency

If the error persists, try forcing the compilation of the usb dependency again by using the following Mix command:

codemix deps.compile usb --force

This will force a recompilation of the usb dependency, which might resolve any lingering build issues.

5. Update or Clean the USB Dependency

If recompiling doesn’t fix the issue, try updating or cleaning the usb dependency:

  • To update: codemix deps.update usb
  • To clean: codemix deps.clean usb

After cleaning, run mix deps.get and try compiling again.

Conclusion

By following these steps, you should be able to resolve the missing erl_nif.h error during compilation. Ensuring that your Erlang installation is correct, your environment variables are set up properly, and the dependencies are correctly compiled should help in avoiding such errors in the future.

Related blog posts