Closed maxgerhardt closed 2 years ago
Thank you for your initial investigation on this. I have not tested with PlatformIO but your comments indicate some subtle issue is present regardless of the environment. I had hoped to keep code as close to upstream as possible but understand that is not possible sometimes.
For reference: I've uploaded a compilable PlatformIO example at https://github.com/maxgerhardt/pio-libssh-example with the changes I talked about above, which are in the fork https://github.com/maxgerhardt/LibSSH-ESP32
I pulled your changes locally and quickly checked it compiled and linked. I would like to refactor to make it clear the files are effectively 'from' libssh_esp32 versus libssh. I will also assess my porting process to prevent any regression, and run internal tests.
Please could you let me know why the following change is needed so I may investigate further?
diff --git a/src/libssh/libssh.h b/src/libssh/libssh.h
index 0624295..efff4fc 100644
--- a/src/libssh/libssh.h
+++ b/src/libssh/libssh.h
@@ -67,7 +67,9 @@
#include <winsock2.h>
#else /* _WIN32 */
#include <sys/select.h> /* for fd_set * */
- #include <netdb.h>
+ #undef IPADDR_NONE
+ #include <lwip/sockets.h>
+ #undef IPADDR_NONE
#endif /* _WIN32 */
Remove these changes, try the exec
example and you'll see why :D
In file included from C:\Users\Max\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\lwip/lwip/ip_addr.h:43:0,
from C:\Users\Max\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\lwip/lwip/sockets.h:46,
from .pio\libdeps\esp32dev\LibSSH-ESP32\src/libssh/libssh.h:71,
from src\exec.cpp:25:
C:\Users\Max\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\lwip/lwip/ip4_addr.h:79:37: error: expected ')' before numeric constant
#define IPADDR_NONE ((u32_t)0xffffffffUL)
^
C:\Users\Max\.platformio\packages\framework-arduinoespressif32\tools\sdk\include\lwip/lwip/inet.h:71:29: note: in expansion of macro 'IPADDR_NONE'
#define INADDR_NONE IPADDR_NONE
^
C:\Users\Max\.platformio\packages\framework-arduinoespressif32\cores\esp32/IPAddress.h:94:17: note: in expansion of macro 'INADDR_NONE'
const IPAddress INADDR_NONE(0, 0, 0, 0);
^
lwip defines the macro IPADDR_NONE
to 0xfffffff but the Arduino-ESP32 core creates a variable called INADDR_NONE
but if the macro would exist at that point the variable declaration would read, in expanded form,
const IPAddress ((u32_t)0xffffffffUL)(0, 0, 0, 0);
which is ofc invalid. Hence I try to get rid of that asap by undef
-ing if.
Actually I tested this again and the more minimal form
#ifdef _WIN32
#include <winsock2.h>
#else /* _WIN32 */
#include <sys/select.h> /* for fd_set * */
#include <netdb.h>
#undef IPADDR_NONE
#endif /* _WIN32 */
works too.
The exec example has this problem because after it includes libssh (which includes this internal lwip header) it does #include "IPv6Address.h"
which pulls in IPAddress.h
from the Arduino core, with the macro activated that would lead to the error above.
On a sidenote: The fork is just a proof-of-concept, there's a few points in there that are not good, like:
In file included from .pio\libdeps\esp32dev\LibSSH-ESP32\src\dh.c:28:0:
.pio\libdeps\esp32dev\LibSSH-ESP32\src\libssh/priv.h:2:0: warning: "HAVE_COMPILER__FUNC__" redefined
#define HAVE_COMPILER__FUNC__
which stems from the fact that lots apparently priv.h
has duplicate definitions of the options which are already in the configuration header file. The Arduino IDE doesn't seem to have that warning turned on in GCC, but PlatformIO does, and the log is quite flooded with them.
#define HAVE_PTHREAD 1
to get it compiling with probably has the side effect of there not being any mutex implementation / protection at all. Arduino-ESP32 is based on FreeRTOS and multithreaded if the user creates more tasks, so mutex protection should definitely be implemented. Not sure if there is a pthread API emulation layer that maps to FreeRTOS, but using the native APIs sohuld be easy enough to implementPlease could you test with the feature-platformio branch and feed your results back:
Hi ALL I have the same issue reported by Maximilian Gerhardt but in ESP-IDF . After successfully ported the code from arduino to ESP-ID. I hope there is some fix for that
ssh_mutex_lock' /home/ammar/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: esp-idf/arduino/libarduino.a(init.c.obj):(.literal._ssh_init+0x10): undefined reference to
ssh_mutex_unlock'
/home/ammar/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: esp-idf/arduino/libarduino.a(init.c.obj): in function _ssh_init': /home/ammar/esp/SSH_TO_IDF/build/../components/arduino/libraries/LibSSH-ESP32/src/init.c:66: undefined reference to
ssh_mutex_lock'
/home/ammar/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /home/ammar/esp/SSH_TO_IDF/build/../components/arduino/libraries/LibSSH-ESP32/src/init.c:91: undefined reference to ssh_mutex_unlock' /home/ammar/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: esp-idf/arduino/libarduino.a(init.c.obj): in function
_ssh_finalize':
/home/ammar/esp/SSH_TO_IDF/build/../components/arduino/libraries/LibSSH-ESP32/src/init.c:104: undefined reference to ssh_mutex_lock' /home/ammar/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: /home/ammar/esp/SSH_TO_IDF/build/../components/arduino/libraries/LibSSH-ESP32/src/init.c:185: undefined reference to
ssh_mutex_unlock'
/home/ammar/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: esp-idf/arduino/libarduino.a(threads.c.obj):(.literal.ssh_threads_init+0x8): undefined reference to ssh_threads_get_default' /home/ammar/.espressif/tools/xtensa-esp32-elf/esp-2020r3-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: esp-idf/arduino/libarduino.a(threads.c.obj): in function
ssh_threads_init':
/home/ammar/esp/SSH_TO_IDF/build/../components/arduino/libraries/LibSSH-ESP32/src/threads.c:55: undefined reference to `ssh_threads_get_default'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
ninja failed with exit code 1thank you
undefined reference to ssh_mutex_unlock
This is fixed by commenting out the PTHREAD macro in the config header file, see my branch linked above.
Sorry I haven't been able to look at @ewpa branch above yet, I hope I can do that rather soon.
thank you Maximilian ! do you mean tcommenting out his define ?
/ Define to 1 if you have the
No, see here as I've also linked above.
Ok , i will try this changes. thank you again i try it it works !. but i run with new issue with argp_parse :-)
Please raise a new issue for argp_parse
.
Please test release 1.3.0, commit 4f3da87. I intend to close this issue shortly.
Per https://community.platformio.org/t/libssh-esp32-library-examples-not-compiling/21446/.
When using this libraray with PlatformIO, e.g. using the
exec
andkeygen2
examples, a lot of warnings regarding redefinitions appear (stemming from conflicts withconfig.h
), and ultimately errors are thrown regarding theFALL_THROUGH
macro and undefined references tossh_mutex_lock
and related functions.I confirmed that the library compiles in the Arduino IDE with the latest framework version.
However, this may be due a subtle include order difference between PlatformIO and the Arduino IDE, ultimately boiling down to a maybe error in the library.
When you e.g. use the
exec
example, it doeshttps://github.com/ewpa/LibSSH-ESP32/blob/e15200e305b3b0f0c3763b71ebdacc9cddd01bf9/examples/exec/exec.ino#L77-L77
which I expect to pull in the
config.h
from the library, that is,https://github.com/ewpa/LibSSH-ESP32/blob/e15200e305b3b0f0c3763b71ebdacc9cddd01bf9/src/config.h#L1-L4
However, if you open the exec.ino example in the Arduino IDE and place the following code after all the
#include
s have happened(that is, to check whether the macro in the
config.h
header file was activated as we expect to), you will getindidicating that not this
config.h
that we thought it loaded was actually loaded.Doing the exact same in PlatformIO (after a few
config.h
tweaks to get it compilable at all), the opposite occursThe file
config.h
also exists in the Arduino-ESP32 core (see https://github.com/espressif/arduino-esp32/find/1.0.6 and typeconfig.h
), so maybe there is some confusion going on as to which file (e.g., library code, example code) is actually loaded when#include "config.h"
is done.The most interesting part is when I rename the
config.h
of this repository to something unique, saylibssh_config.h
, and replace all#include "config.h"
accordingly (usingsed
), I get the exact same compiler errors as I get in PlatformIO.so for some code files, the wrong
config.h
may actually be loaded which magically works out in the Arduino IDE but not on PlatformIO, but you should take care that the right file will always be loaded anyways -- and if it is, it causes errors though. (See referenced topic).