Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking error LNK2019 in MSVC, unresolved symbols with __imp__ prefix, but should be from static lib

I'm running into linking problems in MSVC for a project that I wrote for g++. Here's the problem:

I build libssh as a static library as part of my application, adding the target in cmake with

add_library(ssh_static STATIC $libssh_SRCS)

Libssh is in C, so I have 'extern "C" {...}' wrapping the includes in my c++ sources. I then link the ssh_static target to my executable, sshconnectiontest, with

target_link_libraries(sshconnectiontest ... ssh_static ...)

This all works fine in linux with gcc, but now in MSVC I get

error LNK2019: unresolved external symbol __imp__[function names here] referenced in [filename] 

for every libssh function I use.

Any ideas whats going wrong? I've read somewhere that the imp prefix means that the linker is expecting to link a .dll, but this should not be the case since ssh_static is declared a static library in the add_library call...

like image 974
dlonie Avatar asked Sep 13 '10 20:09

dlonie


People also ask

How do I fix unresolved external symbol in LNK2019?

A symbol is declared but not defined You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass . obj files or . lib files that contain the definitions to the linker.

What is __ imp __ prefix?

The __imp__ prefix appears whenever you are linking to a DLL. It does not appear when linking to statically linked libraries. Most likely the code is generated to be linked against a DLL import lib, but you have linked it with a static lib instead.

How do I fix unresolved external symbol?

So when we try to assign it a value in the main function, the linker doesn't find the symbol and may result in an “unresolved external symbol” or “undefined reference”. The way to fix this error is to explicitly scope the variable using '::' outside the main before using it.

What does unresolved external symbol mean?

Unresolved external references occur when the symbol for a function or global variable is referenced in a program, but none of the object files or libraries specified in the link step contain a definition for that symbol.


1 Answers

From what I remember of my Windows days, in MinGW-built DLLs, the __imp__ symbol prefix is used for the trampoline function that calls into the DLL proper. This symbol is then provided by a small static library with the extension .dll.a.

When you include libssh headers, you need to set a #define to indicate that you're expecting to link statically. If you don't, the libssh functions in the header will be declared __declspec(dllimport) and so the __imp__ symbols will be expected at link time.

I had a look at the libssh source and found this at the top of libssh.h:

#ifdef LIBSSH_STATIC   #define LIBSSH_API #else   #if defined _WIN32 || defined __CYGWIN__     #ifdef LIBSSH_EXPORTS       #ifdef __GNUC__         #define LIBSSH_API __attribute__((dllexport))       #else         #define LIBSSH_API __declspec(dllexport)       #endif     #else       #ifdef __GNUC__         #define LIBSSH_API __attribute__((dllimport))       #else         #define LIBSSH_API __declspec(dllimport)       #endif     #endif   #else     #if __GNUC__ >= 4       #define LIBSSH_API __attribute__((visibility("default")))     #else       #define LIBSSH_API     #endif   #endif #endif 

You need to define LIBSSH_STATIC, either through #define before the #include <libssh.h> line, or as a /D option. Since you're using CMake, you'll probably do this through add_definitions in CMakeLists.txt.

like image 128
Jack Kelly Avatar answered Sep 21 '22 10:09

Jack Kelly