MickeyOoh

MickeyOoh

I am checking Nif function following Erlang erl_nif document and having an issue of compile error.
Could you please help me to solve this issue?

/* niftest.c */
#include <erl_nif.h>
static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
      { return enif_make_string(env, "Hello world!", ERL_NIF_LATIN1); }
static ErlNifFunc nif_funcs[] = { {"hello", 0, hello} };
ERL_NIF_INIT(niftest,nif_funcs,NULL,NULL,NULL,NULL)

compiling

$> gcc -fPIC -shared -o niftest.so niftest.c -I $ERL_ROOT/usr/include/
Undefined symbols for architecture x86_64:
 “_enif_make_string”, referenced from:
   _hello in niftest-cb9456.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

machine: macOS Monetery
gcc: Apple clang version 13.1.6 (clang-1316.0.21.2)
erlang: 24.3
include file: ERL_ROOT=~/.asdf/installs/erlang/24.3

It is where undefined symbol “enif_make_string” is defined.
erl_nif_api_funcs.h

#ifdef ERL_NIF_API_FUNC_DECL
  ERL_NIF_API_FUNC_DECL(
      ERL_NIF_TERM,
      enif_make_string,
      (ErlNifEnv* env, const char* string, ErlNifCharEncoding)
  );
#endif

#ifdef ERL_NIF_API_FUNC_MACRO
    #define enif_make_string ERL_NIF_API_FUNC_MACRO(enif_make_string)
#endif

The following is where two switching Macros is defined.
ERL_NIF_API_FUNC_DECL, ERL_NIF_API_FUNC_MACRO
erl_nif.h

#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
  #define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS typedef struct {
    #include "erl_nif_api_funcs.h"
    void* erts_alc_test;
  } TWinDynNifCallbacks;
  extern TWinDynNifCallbacks WinDynNifCallbacks;
  #undef ERL_NIF_API_FUNC_DECL
#endif
#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_)) 
        && !defined(STATIC_ERLANG_DRIVER) && !defined(STATIC_ERLANG_NIF)
  #define ERL_NIF_API_FUNC_MACRO(NAME) (WinDynNifCallbacks.NAME)
  #include "erl_nif_api_funcs.h"
  /* note that we have to keep ERL_NIF_API_FUNC_MACRO defined */
#else /* non windows or included from emulator itself */
  #define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) extern RET_TYPE NAME ARGS
  #include "erl_nif_api_funcs.h"
  #undef ERL_NIF_API_FUNC_DECL
#endif

I couldn’t find switching macros of “__WIN32__” anywhere although this looks WindowsOS macro.

This issue happened on Erlang 23.x and I installed 24.3. So installation doesn’t cause this.

Please help me to find what I am missing.
Thanks.

Showing Posts 1 to 4

garazdawi

garazdawi

Erlang Core Team

On MacOS you also need to pass -bundle -bundle_loader $ERL_ROOT/erts-*/bin/beam.smp to gcc/clang in order for it to work.

MickeyOoh

MickeyOoh OP

Thanks a lot.

However, I still have an error.

 gcc -fPIC -shared -o niftest.so niftest.c -I $ERL_ROOT/usr/include/ -bundle -bundle_loader $ERL_ROOT/erts-12.3/bin/beam.smp

clang: error: invalid argument '-bundle' not allowed with '-dynamiclib'

I think this comes from using clang instead of gcc although I don’t know how -bundle works. I will check the option.

garazdawi

garazdawi

Erlang Core Team

After checking again I think the -bundle is supposed to replace the -shared for clang. Does that work for you?

MickeyOoh

MickeyOoh OP

Thank garazdawi for your help.

The issue has been solved.

$ gcc -fPIC -o niftest.so niftest.c -I $ERL_ROOT/usr/include/ -bundle -bundle_loader $ERL_ROOT/erts-12.3/bin/beam.smp

$ ll niftest.so
-rwxr-xr-x  1 mickeyoh  staff    48K  6 Apr 13:09 niftest.so*

options (man ld - linker)

-bundle Produce a mach-o bundle that has file type MH_BUNDLE.
-bundle_loader executable
This specifies the executable that will be loading the bundle output file being linked. Undefined symbols from the bundle are checked against the specified executable like it was one of the dynamic libraries the bundle was linked with.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews