Problem: getting a simple program using the libssh library to compile successfully without getting a linker error.
Program:
#include <iostream>
#define LIBSSH_STATIC 1
#include <libssh/libssh.h>
#include <stdlib.h>
void sftpSession()
{
ssh_session test_session = ssh_new();
if (!test_session) {
throw std::runtime_error("Could not create a session?!");
return;
}
ssh_free(test_session);
std::cout << "Session created & freed successfully." << std::endl;
}
int main(int argc, char **argv)
{
std::cout << "SFTP test program" << std::endl;
try {
sftpSession();
}
catch (const std::runtime_error &e) {
std::cout << "thrown: " << e.what() << std::endl;
}
return EXIT_SUCCESS;
}
Machine is 64-bit, running Windows. Using MinGW (via CodeBlocks) and the build log (edited slightly for readability) shows the compiler command as:
x86_64-w64-mingw32-g++.exe
-Wall -fexceptions -O2 -std=c++0x -g -m64 -Dmine_dev=1
-I"C:\Program Files\zlib\zlib-1.2.8-dll\include"
-I"C:\Program Files (x86)\libssh\libssh-0.6.5\include"
-c C:\Users\ ... \SFTP_testing\main.cpp
-o obj\Release\main.o
x86_64-w64-mingw32-g++.exe
-L"C:\Program Files (x86)\Ingres\IngresII\ingres\lib"
-o bin\Release\SFTP_testing.exe
obj\Release\main.o
-s
"C:\Program Files (x86)\libssh\libssh-0.6.5\lib\libssh.dll.a"
obj\Release\main.o: In function `sftpSession()':
C:/Users/ ... /SFTP_testing/main.cpp:9: undefined reference to `ssh_new'
C:/Users/ ... /SFTP_testing/main.cpp:14: undefined reference to `ssh_free'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 2 second(s))
3 error(s), 0 warning(s) (0 minute(s), 2 second(s))
Things I have tried/investigated
I understand that the undefined reference to
refers to the linker being able to find the declaration of the functions, but not their definitions.
The compiler is indeed finding the header file and the functions' definitions.
The header file does have the necessary
extern "C"
code, including the following:#ifdef __cplusplus extern "C" { #endif ... LIBSSH_API ssh_session ssh_new(void); ... LIBSSH_API void ssh_free(ssh_session session); ... #ifdef __cplusplus } #endif
The linker is sucessfully finding the library. (Checked via the ProcessMonitor program. It is definitely accessing the
libssh.dll.a
file.)Using the nm utility I checked that the object code in
libssh.dll.a
did indeed contain references forssh_new
andssh_free
Checked no confusion between 32-bit/64-bit issues: there are two versions of the pre-compiled library supplied. One is
...\libssh-0.6.5\bin\libssh.dll
and the other is...\libssh-0.6.5\lib\libssh.dll.a
and the former gives me the following error:i386 architecture of input file 'C:\Program Files (x86)\libssh\libssh-0.6.5\bin\libssh.dll' is incompatible with i386:x86-64 output
but the latter gives no such error, so I assume that thelibssh.dll.a
file is the correct library file to use.Checked the advice given in this very similar question about libssh2 about the order of libraries linked, but here the call to g++ looks right as the
libssh.dll.a
argument is right at the end.Checked the more general advice about linker errors too but could not find anything that seemed to be applicable.
Cleaned before rebuilding to avoid effects from "dead wood".
Tried other older versions of the library. Same error message.
Tried (unsuccessfully) to compile a newer version of libssh.