Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIFs fail to compile on Windows #9015

Closed
essen opened this issue Nov 4, 2024 · 2 comments · Fixed by #9016
Closed

NIFs fail to compile on Windows #9015

essen opened this issue Nov 4, 2024 · 2 comments · Fixed by #9016
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM

Comments

@essen
Copy link
Contributor

essen commented Nov 4, 2024

Describe the bug

NIFs fail to compile on Windows, probably since b9ded16

In my case this is via MSYS2, but an Erlang forums users reported it with MINGW. It's possible that we are simply missing something, but at least in my case the Erlang.mk test suite used to compile NIFs fine, now it doesn't. Regardless of what the problem is I'll appreciate some help!

Since it's Windows I have not run git bisect, just went looking through the file's history. I could try different OTP versions to confirm, please tell me which ones I should try.

An example output from a failure in the Erlang.mk test suite:

/mingw64/bin/gcc -c -o c_src/my_dep.o c_src/my_dep.c  -finline-functions -Wall -fPIC -I "d:/a/_temp/.setup-beam/otp/erts-15.1.2/include" -I "d:/a/_temp/.setup-beam/otp/lib/erl_interface-5.5.2/include" -fPIC 
In file included from c_src/my_dep.c:1:
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:34:81: error: 'enif_free' undeclared here (not in a function)
   34 | ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size) ERL_NAPI_ATTR_MALLOC_USD(1,enif_free,1));
      |                                                                                 ^~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:341:72: note: in definition of macro 'ERL_NIF_API_FUNC_DECL'
  341 | #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
      |                                                                        ^~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_drv_nif.h:221:8: note: in expansion of macro 'ERL_NAPI_ATTR_MALLOC_D'
  221 |        ERL_NAPI_ATTR_MALLOC_D(DTOR, PTRPOS)
      |        ^~~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:34:54: note: in expansion of macro 'ERL_NAPI_ATTR_MALLOC_USD'
   34 | ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size) ERL_NAPI_ATTR_MALLOC_USD(1,enif_free,1));
      |                                                      ^~~~~~~~~~~~~~~~~~~~~~~~
In file included from d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:343:
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:34:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
   34 | ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size) ERL_NAPI_ATTR_MALLOC_USD(1,enif_free,1));
      | ^~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:34:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:63:90: error: 'enif_mutex_destroy' undeclared here (not in a function)
   63 | ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_mutex_destroy,1));
      |                                                                                          ^~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:341:72: note: in definition of macro 'ERL_NIF_API_FUNC_DECL'
  341 | #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
      |                                                                        ^~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:63:67: note: in expansion of macro 'ERL_NAPI_ATTR_MALLOC_D'
   63 | ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_mutex_destroy,1));
      |                                                                   ^~~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:63:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
   63 | ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_mutex_destroy,1));
      | ^~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:68:88: error: 'enif_cond_destroy' undeclared here (not in a function)
   68 | ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_cond_destroy,1));
      |                                                                                        ^~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:341:72: note: in definition of macro 'ERL_NIF_API_FUNC_DECL'
  341 | #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
      |                                                                        ^~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:68:65: note: in expansion of macro 'ERL_NAPI_ATTR_MALLOC_D'
   68 | ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_cond_destroy,1));
      |                                                                 ^~~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:68:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
   68 | ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_cond_destroy,1));
      | ^~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:73:92: error: 'enif_rwlock_destroy' undeclared here (not in a function)
   73 | ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_rwlock_destroy,1));
      |                                                                                            ^~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:341:72: note: in definition of macro 'ERL_NIF_API_FUNC_DECL'
  341 | #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
      |                                                                        ^~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:73:69: note: in expansion of macro 'ERL_NAPI_ATTR_MALLOC_D'
   73 | ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_rwlock_destroy,1));
      |                                                                     ^~~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:73:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
   73 | ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_rwlock_destroy,1));
      | ^~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:85:101: error: 'enif_thread_opts_destroy' undeclared here (not in a function)
   85 | ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_thread_opts_destroy,1));
      |                                                                                                     ^~~~~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:341:72: note: in definition of macro 'ERL_NIF_API_FUNC_DECL'
  341 | #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
      |                                                                        ^~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:85:78: note: in expansion of macro 'ERL_NAPI_ATTR_MALLOC_D'
   85 | ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_thread_opts_destroy,1));
      |                                                                              ^~~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:85:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
   85 | ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name) ERL_NAPI_ATTR_MALLOC_D(enif_thread_opts_destroy,1));
      | ^~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:111:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
  111 | ERL_NIF_API_FUNC_DECL(void *, enif_alloc_resource, (ErlNifResourceType *type, size_t size) ERL_NAPI_ATTR_MALLOC_US(2));
      | ^~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:187:103: error: 'enif_ioq_destroy' undeclared here (not in a function)
  187 | ERL_NIF_API_FUNC_DECL(ErlNifIOQueue *,enif_ioq_create,(ErlNifIOQueueOpts opts) ERL_NAPI_ATTR_MALLOC_D(enif_ioq_destroy,1));
      |                                                                                                       ^~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:341:72: note: in definition of macro 'ERL_NIF_API_FUNC_DECL'
  341 | #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
      |                                                                        ^~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:187:80: note: in expansion of macro 'ERL_NAPI_ATTR_MALLOC_D'
  187 | ERL_NIF_API_FUNC_DECL(ErlNifIOQueue *,enif_ioq_create,(ErlNifIOQueueOpts opts) ERL_NAPI_ATTR_MALLOC_D(enif_ioq_destroy,1));
      |                                                                                ^~~~~~~~~~~~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif_api_funcs.h:187:1: warning: 'malloc' attribute ignored; valid only for functions [-Wattributes]
  187 | ERL_NIF_API_FUNC_DECL(ErlNifIOQueue *,enif_ioq_create,(ErlNifIOQueueOpts opts) ERL_NAPI_ATTR_MALLOC_D(enif_ioq_destroy,1));
      | ^~~~~~~~~~~~~~~~~~~~~
c_src/my_dep.c: In function 'nif_init':
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:379:29: error: implicit declaration of function 'memcpy' [-Wimplicit-function-declaration]
  379 | #  define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks))
      |                             ^~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:440:5: note: in expansion of macro 'ERL_NIF_INIT_BODY'
  440 |     ERL_NIF_INIT_BODY;                  \
      |     ^~~~~~~~~~~~~~~~~
c_src/my_dep.c:51:1: note: in expansion of macro 'ERL_NIF_INIT'
   51 | ERL_NIF_INIT(my_dep, nif_funcs, load, NULL, upgrade, unload)
      | ^~~~~~~~~~~~
c_src/my_dep.c:2:1: note: include '<string.h>' or provide a declaration of 'memcpy'
    1 | #include "erl_nif.h"
  +++ |+#include <string.h>
    2 | 
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:379:29: warning: incompatible implicit declaration of built-in function 'memcpy' [-Wbuiltin-declaration-mismatch]
  379 | #  define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks))
      |                             ^~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:440:5: note: in expansion of macro 'ERL_NIF_INIT_BODY'
  440 |     ERL_NIF_INIT_BODY;                  \
      |     ^~~~~~~~~~~~~~~~~
c_src/my_dep.c:51:1: note: in expansion of macro 'ERL_NIF_INIT'
   51 | ERL_NIF_INIT(my_dep, nif_funcs, load, NULL, upgrade, unload)
      | ^~~~~~~~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:379:29: note: include '<string.h>' or provide a declaration of 'memcpy'
  379 | #  define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks))
      |                             ^~~~~~
d:/a/_temp/.setup-beam/otp/erts-15.1.2/include/erl_nif.h:440:5: note: in expansion of macro 'ERL_NIF_INIT_BODY'
  440 |     ERL_NIF_INIT_BODY;                  \
      |     ^~~~~~~~~~~~~~~~~
c_src/my_dep.c:51:1: note: in expansion of macro 'ERL_NIF_INIT'
   51 | ERL_NIF_INIT(my_dep, nif_funcs, load, NULL, upgrade, unload)
      | ^~~~~~~~~~~~

To Reproduce
The Erlang forums user provided a simple NIF to try on MINGW: https://erlangforums.com/t/encountering-errors-when-compiling-nif-using-mingw-on-windows/4037

The same NIF will fail on MSYS2.

Alternatively this test builds a NIF:

git clone https://github.com/ninenines/erlang.mk
cd erlang.mk
make check c=core-autopatch-rebar

All NIF related tests fail so I can provide a few more if you need me to.

Expected behavior
Should compile on Windows.

Affected versions
At least 27 but probably since the mentioned commit was included.

@essen essen added the bug Issue is reported as a bug label Nov 4, 2024
@garazdawi
Copy link
Contributor

Your guess on which commit introduced it seems like a good one :) We don't test that it works to compile nifs with gcc/clang on Windows (only cl.exe), so I guess that is why this slipped through. Should be easy enough to fix.

garazdawi added a commit to garazdawi/otp that referenced this issue Nov 4, 2024
garazdawi added a commit to garazdawi/otp that referenced this issue Nov 4, 2024
On windows nifs can be compiled with gcc/clang which
means that __has_attribute(malloc) is defined. This
was never intended to work so we disable it on Windows.

closes erlang#9015
@garazdawi
Copy link
Contributor

Please test the windows version in #9016 once github actions finished building it.

@IngelaAndin IngelaAndin added the team:VM Assigned to OTP team VM label Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants