Page 1 of 1

Undefined reference to '_unlink_r' (also to '_getpid_r')

Posted: Fri May 30, 2025 6:22 pm
by atesin
hi... i am trying to embed Lua language in a esp8266 application, based on this = https://github.com/sfranzyshen/ESP-Arduino-Lua

for that i developed a library header that is simply a lua wrapper

Code: Select all

#include "lua/lua.hpp"
with folder `<libraries>/LuaWrapper/lua/` having the lua source code (v5.4.7 at this time), i also made some adjusts to make Lua able to `print()`

so, my sketch at some point have code like

Code: Select all

lua_State* L = luaL_newstate();
luaopen_base(L);
luaopen_table(L);
luaopen_string(L);
//luaopen_io(L);
and everything after seem to work fine: `luaL_loadstring()`, `lua_pcall()`, etc

you have noticed that i had commented a line in the code... when i uncomment just THAT single line and try to compile again it fails with the message:

Code: Select all

c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-remove.o):(.literal+0x0): undefined reference to `_unlink_r'
c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-remove.o): in function `_remove_r':
/workdir/repo/newlib/newlib/libc/stdio/remove.c:65: undefined reference to `_unlink_r'
c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-tmpnam.o):(.literal+0x14): undefined reference to `_getpid_r'
c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-tmpnam.o): in function `_tmpnam_r':
/workdir/repo/newlib/newlib/libc/stdio/tmpnam.c:129: undefined reference to `_getpid_r'
c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: c:/users/atesin/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.1.0-gcc10.3-e5f9fec/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/lib\libc.a(lib_a-tmpnam.o): in function `_tempnam_r':
/workdir/repo/newlib/newlib/libc/stdio/tmpnam.c:161: undefined reference to `_getpid_r'
collect2.exe: error: ld returned 1 exit status
is important for me to add `luaopen_io()` to my sketch because i want my Lua app to support files in the future (LittleFS, SD or whatever)

i noticed that macros/functions are present in esp8266 source files but for some reason they are not compiling

Re: Undefined reference to '_unlink_r' (also to '_getpid_r')

Posted: Sun Jun 01, 2025 11:24 am
by ahsrabrifat
Manually modify the Lua source code (in liolib.c) to:

Remove references to tmpnam, getpid, remove, etc.

Replace them with your own functions that use LittleFS.open, LittleFS.remove, etc.

Re: Undefined reference to '_unlink_r' (also to '_getpid_r')

Posted: Sun Jun 01, 2025 6:23 pm
by atesin
thanks for your response

i really dont want to modify the Lua source code.. i know this can be done this way but i think this is the fast and dirty way to do it... that way, everytime on a Lua release i will have to browse code and do modifications?, and additionally those modifications would be just for ME (i.e. anybody with similar problem won't be aware of this solution/patch and had to find it by him/herself)

i was thinking more in patching the esp toolchain to handle these situations, according what i investigated, redhat newlib (on what esp8266-arduino api was based) HAS code to handle posix functions ...

anyway, by inspecting the ESP tooulchain code, this is the "solution" i invented by reimplementing "dummy" versions (simplified here):

Code: Select all

// MyLib.h
#include <errno.h>
extern "C" {
  // these are statically linked into <toolchain>/lib/libc.a so macros won't work
  int _getpid_r(struct _reent*);
  int _unlink_r(struct _reent*, const char*);
}
#include "lua/lua.hpp"
}

Code: Select all

// MyLib.cpp
// minimal functionality where OS services are not available
// with a pitiful attempt to make it thread-safe
int _getpid_r(struct _reent* r) {
  (void*) r;
  return 1;
}
int _unlink_r(struct _reent* r, const char* path) {
  (void*) r;
  (void*) path;
  errno = ENOENT;
  return -1; 
}
but i am not sure if i use filesystem libraries later (like LittleFS, SF-FAT, LuaFilesystem or whatever) it will handle file operations correctly :/

additionally, newlib has a special way to handle non thread-safe functions by turning reentrant (i.e. functions that rely on global variables, pointers and structures, like "errno")... but it seem to had been totally stripped down from ESP toolchain :/ ... i want to activate this, how to do it? (actually "_<func>_r()" are reentrant versions that are called but not implemented)

thanks in advance