LibSSH-ESP32 library examples not compiling

Hi, I’m trying to start a project that uses the LibSSH-ESP32 on an ESP32.
To start I wanted to just run one of the included examples but I can’t get them to compile.
The “exec” example gives a long list of warnings and the following error:

In file included from Z:/Projects/ESP_SSH/src/exec.ino:84:0:
Z:/Projects/ESP_SSH/src/exec.ino: In function 'int verify_knownhost(ssh_session)':
.pio\libdeps\tinypico\LibSSH-ESP32\src/libssh/priv.h:401:24: error: expected primary-expression before '__attribute__'
 #  define FALL_THROUGH __attribute__ ((fallthrough))

The “keygen2” example seems to compile further (again with a lot of warnings about things being redefined) but gives an error during the linking step:

Linking .pio\build\tinypico\firmware.elf
.pio\build\tinypico\lib599\libLibSSH-ESP32.a(init.c.o):(.literal._ssh_init+0xc): undefined reference to `ssh_mutex_lock'
.pio\build\tinypico\lib599\libLibSSH-ESP32.a(init.c.o):(.literal._ssh_init+0x10): undefined reference to `ssh_mutex_unlock'
.pio\build\tinypico\lib599\libLibSSH-ESP32.a(init.c.o): In function `_ssh_init':
Z:\Projects\ESP_SSH/.pio\libdeps\tinypico\LibSSH-ESP32\src/init.c:155: undefined reference to `ssh_mutex_lock'
Z:\Projects\ESP_SSH/.pio\libdeps\tinypico\LibSSH-ESP32\src/init.c:155: undefined reference to `ssh_mutex_unlock'
.pio\build\tinypico\lib599\libLibSSH-ESP32.a(threads.c.o):(.literal.ssh_threads_init+0x8): undefined reference to `ssh_threads_get_default'
.pio\build\tinypico\lib599\libLibSSH-ESP32.a(threads.c.o): In function `ssh_threads_init':
Z:\Projects\ESP_SSH/.pio\libdeps\tinypico\LibSSH-ESP32\src/threads.c:55: undefined reference to `ssh_threads_get_default'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\tinypico\firmware.elf] Error 1

This is the content of platformio.ini:

[env:tinypico]
platform = espressif32
board = tinypico
framework = arduino
lib_deps = ewpa/LibSSH-ESP32@^1.2.3

The examples compile just fine in the Arduino IDE.

Any tips that could help getting this to work? Thanks!

If I change

to

 #include <sys/select.h> /* for fd_set * */
 #undef IPADDR_NONE
 #include <lwip/sockets.h>
 #undef IPADDR_NONE

and change

to

#define HAVE_PTHREAD 0

I can get the keygen2 to compile. (Also changed keygen2.ino to keygen2.cpp).

But I also verified compilation works in the Arduino IDE with also core version 1.0.6 and compiler 5.2.0, which is the same PlatformIO is using. So I’m not sure why it is working in the Arduino IDE. It also produces no warnings in the Arduino IDE, whereas in PlatformIO it does, but that might be due to having more warning flags enabled.

In file included from libdeps\tinypico\LibSSH-ESP32\src\connect.c:82:0:
libdeps\tinypico\LibSSH-ESP32\src\libssh/priv.h:2:0: warning: "HAVE_COMPILER__FUNC__" redefined
 #define HAVE_COMPILER__FUNC__
 ^
In file included from libdeps\tinypico\LibSSH-ESP32\src\connect.c:24:0:
libdeps\tinypico\LibSSH-ESP32\src\config.h:257:0: note: this is the location of the previous definition
 #define HAVE_COMPILER__FUNC__ 1
 ^

To get the exec example to compile I additionally have to change the config.h file to comment out

so that it does not use

# ifdef HAVE_FALLTHROUGH_ATTRIBUTE
#  define FALL_THROUGH __attribute__ ((fallthrough))

which isn’t supported by this compiler version.

I’ll try and see why this is so different…

Aha. Under the Arduino IDE, it doesn’t include the correct config.h from the library…

If the right config.h was loaded, the macro

PORT_ESP32_CONFIG_H_ would have to be defined.

But if I place the code

#include "config.h"

#ifdef PORT_ESP32_CONFIG_H_
#error "PORT_ESP32_CONFIG_H_ is defined"
#else
#error "PORT_ESP32_CONFIG_H_ is not defined"
#endif

I get

keygen2:74:2: error: #error "PORT_ESP32_CONFIG_H_ is not defined"
 #error "PORT_ESP32_CONFIG_H_ is not defined"
  ^

When I place this code in the exact same place for the keygen2 example in PlatformIO I get

C:/Users/Max/temp/folder_test/src/keygen2.ino:72:2: error: #error "PORT_ESP32_CONFIG_H_ is defined"
 #error "PORT_ESP32_CONFIG_H_ is defined"
  ^

the exact opposite :slight_smile:

so clearly in the Arduino, it hasn’t loaded the config.h from the ssh library, but something else and it still works by sheer chance / defaults. And when PlatformIO loads the actual config.h of the library, it fails. Incredible.

Maybe has got something to do with the include order.

Also when I take the Arduino library and do a string-replacement with config.h to libssh_config.h and adapt the filename, to make absolutely sure the unqiue libssh_config.h is loaded and not some other config.h, I get the exact same errors as initially with PlatformIO.

C:\Users\Max\AppData\Local\Temp\arduino_build_669303\libraries\LibSSH-ESP32_Mod\LibSSH-ESP32_Mod.a(init.c.o):(.literal._ssh_init+0xc): undefined reference to `ssh_mutex_lock'
C:\Users\Max\AppData\Local\Temp\arduino_build_669303\libraries\LibSSH-ESP32_Mod\LibSSH-ESP32_Mod.a(init.c.o):(.literal._ssh_init+0x10): undefined reference to `ssh_mutex_unlock'
C:\Users\Max\AppData\Local\Temp\arduino_build_669303\libraries\LibSSH-ESP32_Mod\LibSSH-ESP32_Mod.a(init.c.o): In function `_ssh_init':
C:\Users\Max\Documents\Arduino\libraries\LibSSH-ESP32_Mod\src/init.c:155: undefined reference to `ssh_mutex_lock'
C:\Users\Max\Documents\Arduino\libraries\LibSSH-ESP32_Mod\src/init.c:155: undefined reference to `ssh_mutex_unlock'
C:\Users\Max\AppData\Local\Temp\arduino_build_669303\libraries\LibSSH-ESP32_Mod\LibSSH-ESP32_Mod.a(init.c.o): In function `_ssh_finalize':
C:\Users\Max\Documents\Arduino\libraries\LibSSH-ESP32_Mod\src/init.c:182: undefined reference to `ssh_mutex_lock'
C:\Users\Max\Documents\Arduino\libraries\LibSSH-ESP32_Mod\src/init.c:180: undefined reference to `ssh_mutex_unlock'
C:\Users\Max\AppData\Local\Temp\arduino_build_669303\libraries\LibSSH-ESP32_Mod\LibSSH-ESP32_Mod.a(init.c.o): In function `is_ssh_initialized':
C:\Users\Max\Documents\Arduino\libraries\LibSSH-ESP32_Mod\src/init.c:231: undefined reference to `ssh_mutex_lock'
C:\Users\Max\Documents\Arduino\libraries\LibSSH-ESP32_Mod\src/init.c:278: undefined reference to `ssh_mutex_unlock'
C:\Users\Max\AppData\Local\Temp\arduino_build_669303\libraries\LibSSH-ESP32_Mod\LibSSH-ESP32_Mod.a(threads.c.o):(.literal.ssh_threads_init+0x8): undefined reference to `ssh_threads_get_default'
C:\Users\Max\AppData\Local\Temp\arduino_build_669303\libraries\LibSSH-ESP32_Mod\LibSSH-ESP32_Mod.a(threads.c.o): In function `ssh_threads_init':
C:\Users\Max\Documents\Arduino\libraries\LibSSH-ESP32_Mod\src/threads.c:85: undefined reference to `ssh_threads_get_default'
collect2.exe: error: ld returned 1 exit status

this is definitely about a confusion of the config.h file with something else.

I’ve opened Library uncompilable in PlatformIO, weirdness with `config.h` · Issue #7 · ewpa/LibSSH-ESP32 · GitHub for this.

Wow thanks! Wouldn’t have been able to figure that out by myself :sweat_smile: I was just getting stuck trying to get it to compile using different versions of the GCC Toolchain for a couple of hours already.
Thanks as well for opening an issue on GitHub, let me know whether I can help in any way by for example testing something out!

I’ve pushed the exec example at GitHub - maxgerhardt/pio-libssh-example along with a fixed library version if you want to test it with PlatformIO.

The keygen2 example should also work like in the Arduino IDE if you copy all of its example files in the src/ folder.