Possible linker errors to parse for visual studio compiling with GCC - c++

As per this question, Visual Studio cannot parse and display errors from GCC in c or c++. I have found at least one instance where linker errors are not found by the error parsing script in the answer.
As far as i have found there are two major linker errors that occur.
Unresolved external symbol
Caused by the following examples (amoung others):
extern int i; // No definition of i
void nodef(); // No definition of a function
class A {
static int b; // No external definition (int A::b) of b (c++ only)
}
No Such file or directory
If an object file (.o) is removed before the linker runs, you have an error occur. This is usually caused by a git-cleanup followed by a regular build (instead of rebuild), currently this error case is not covered by the linked questions answer. But this is an easy fix.
Are there any other linker errors (other than unresolved external and no such file) in c/c++ that I need to be aware of for complete coverage of this error parsing script?

At least one other error is Multiple definition of when something is defined multiple times.

Related

What / where is __scrt_common_main_seh?

A third party library in my program is trying to call __scrt_common_main_seh by way of the Microsoft library msvcrt.lib, but is defined by some unknown library and therefore gives a linker error. I don't know what this function is supposed to do or where it is defined.
I looked online for this function, but did not find any clues except for general descriptions of what linker errors are.
I believe it might be doing some setup for win32 GUI applications. The library which defines it might be configured as project dependency by Visual Studio but my project is using Bazel.
Summary
For non-console applications having error error LNK2019: unresolved external symbol main referenced in function "int __cdecl __scrt_common_main_seh(void)" try adding linker flag /ENTRY:wWinMainCRTStartup or /ENTRY:WinMainCRTStartup
For console applications having that error, make sure to implement a main() function.
Details
This answer shows that __scrt_common_main_seh is normally called during mainCRTStartup which is the default entry point for windows console applications. __scrt_common_main_seh is then (indirectly) responsible for calling main().
My program did not have a main() function, which might have prevented the compiler from generating __scrt_common_main_seh (Just speculating. I am totally clueless about who defines __scrt_common_main_seh)
I did find, however, that the library I was linking against defined a wWinMain() function. So I tried adding the linker flag /ENTRY:wWinMainCRTStartup and the linker error went away.

Why do I get link errors when the symbol is clearly present in the static library I link against?

I've decided to start using ICU in my project, but sadly VS2015 is officially unsupported (i.e. the developers list the incompatibility as a known issue). Luckily someone was kind enough to fix the problems on their own and share the binaries with the world: http://www.npcglib.org/~stathis/blog/precompiled-icu/ . I've downloaded the ICU 56 VS15 package and I'm trying to compile the following simple program:
#include <iostream>
#include <unicode\unistr.h>
int main()
{
auto myStr = icu::UnicodeString::fromUTF8(u8"кошка");
std::cout << "length: " << myStr.length() << std::endl;
std::getchar();
return 0;
}
When I use the compile time import .lib libraries, everything works fine, but of course I need the DLL libraries at runtime. When I compile against the static ones, sicuxxx.lib, I get link errors for some reason (there are six similar ones, omitted for brevity):
Error LNK2001 unresolved external symbol "__declspec(dllimport) private: int __thiscall icu_56::UnicodeString::getShortLength(void)const " (__imp_?getShortLength#UnicodeString#icu_56##ABEHXZ)
I did dumpbin /symbols sicuuc.lib, and in the output I can see the following:
0E8 00000000 SECT47 notype () External | ?getShortLength#UnicodeString#icu_56##ABEHXZ (private: int __thiscall icu_56::UnicodeString::getShortLength(void)const )
My linker input is as follows: kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;sicudt.lib;sicuin.lib;sicuio.lib;sicule.lib;siculx.lib;sicutest.lib;sicutu.lib;sicuuc.lib;. All the files can clearly be opened by the linker because no "cannot open file" error appears.
Since the symbol is clearly present in the library as shown by dumpbin, why does lib.exe have problems finding it?
You need to define U_STATIC_IMPLEMENTATION when compiling your code so that the ICU functions are not marked as imports.
(You can see that the function it is currently trying to find is marked as __declspec(dllimport), which doesn't match the one in the static library.)
I would suggest to try to change the mode of linking of runtime in your project (either statically or dynamically).
You will find this setting in Settings -> C/C++ -> Code Generation -> Runtime Library (change from either /MT -> /MD or vice versa) .
Hope this helps.

Linker error when declaring a function just before calling it

I've got an update function in my game that contains the following code:
void DrawMiniFPSCounter();
DrawMiniFPSCounter();
The DrawMiniFPSCounter() function is declared in a file called miniFPSCounter.cpp, which is part of the build target (I'm using Xcode). When building, I get a linker error saying that the DrawMiniFPSCounter symbol cannot be found. I've tried removing the declaration above and just calling DrawMiniFPSCounter() but that results in a 'symbol not found' error during compilation. Why would the linker have trouble finding this symbol? Is it something to do with the order in which symbols are resolved in the project?
EDIT: I ran the command nm hrMiniFPSCounter.o | grep Draw in my build directory, and got the following output:
00000000 T __Z15DrawMiniCounteriiiii
0002d040 S __Z15DrawMiniCounteriiiii.eh
00000a00 T __Z18DrawMiniFPSCounterv
0002d148 S __Z18DrawMiniFPSCounterv.eh
00000560 t __ZL9DrawDigitiiib
0002d128 s __ZL9DrawDigitiiib.eh
is this normal? Why the extra characters on the end of the function names?
In my experience most common "errors":
Was the file (really) compiled?
Was it (really) linked correctly?
Did you give the function the name you thought you did?
new Namespace issues :)
Are you sure that the miniFPSCounter.cpp file is compiled (/have been incouded in the project in the right way)? I guess what you are experiencing could be caused by a few different things,but in lack of more information I would say: Try to make sure that the cpp file is being compiled (maybe introduce a few syntax errors which would give rise to a compilation error if it is indeed compiled) and when you are sure about that, you can start checking for other stuff (suchas that it is being linked correctly, etc)
Edit: Putting checklist on top.

OpenCV 2.3 with Qt 4.3.7

I have successfully build and ran both Qt 4.3.7 and OpenCV 2.3 with Qt enabled. When I start a window using:
cvNamedWindow( "video", 0 );
I successfully load a full Qt interface! wonderful :)
However!! when I use the command
void callbackButton(int state, void* userdata){
int x;
x=3;
}
cvCreateButton(nameb2,callbackButton,nameb2,CV_CHECKBOX,0);
I get the error message
error LNK2001: unresolved external symbol _cvCreateButton
I don't understand as the Qt interface already has lots of buttons on it? could someone please explain what I am missing from the include that could cause this?
Thanks!
You use the wrong parameters for to call to cvCreateButton. According to the documentation here the signature of the function is
cvCreateButton(const char* button_name CV_DEFAULT(NULL), CvButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL), int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0)
and sample calls are:
cvCreateButton(NULL,callbackButton);
cvCreateButton("button2",callbackButton,NULL,CV_CHECKBOX,0);
cvCreateButton("button3",callbackButton,&value);
cvCreateButton("button5",callbackButton1,NULL,CV_RADIOBOX);
cvCreateButton("button6",callbackButton2,NULL,CV_PUSH_BUTTON,1);
and the declaration of the callback function has to be:
CV_EXTERN_C_FUNCPTR( *CvButtonCallback)(int state, void* userdata));
You get a linking error and not a compiler error because cvCreateButton has extern "C" linkage - which means that parameters cannot be checked at compile time.
I solved this issue by calling the function cv::createButton instead of cvCreateButton (which is if I am correct the way to call methods in OpenCV2).
The third argument must be a void*. Change to:
cvCreateButton(nameb2,callbackButton,NULL,CV_CHECKBOX,0);
and it will work.
Edit
The statement above was given an error.
The third needed argument is a "void *" - this is compatible with anything and thus neither C nor C++ should have a problem with what you were providing. You can not raise a linker error with that.
The only reason a linker error can be raised by coding is when you don't use prototypes (forgot to use the header file) in C++ and then C++ creates a mangled name on its own that wont be part of any library. In such a case the compiler will first tell you with a warning at compile time that you are missing the prototype (for C and C++) - and then the linker will probably raise an error (for c++ only).
If you don't see a prototype warning from the compiler then that is not your problem.
This is a linking error.
Try to add the opencv .lib file (or files) to the project libraries path.
This may help : VS2010 OpenCV.
Edit
Refined problem: Even if adding any OpenCV libary to your project the linking will fail.
Reason: The symbol is often simply not there in the libraries.
Solution: You have to change a few settings and compile them on your own.
See also: openCV 2.2 createButton LNK 2019 error in Visual Studio 2010

Can I link unresolved reference to abort?

I'm trying to write some small tests for a fairly small part of a fairly large project. Attempting to link this beast is unfortunately fairly impossible without linking the entire project together, which I don't want to do (it's a pretty complex system for finding all the dependencies and stuff, and I perfer not to meddle with it).
Now, I know for certain that the functions that the referenced functions won't be called during my test, the just happen to be part of functions which share file with stuff that I do test.
Is there any way to simply link these unresolved references to, let's say, abort, or something? Or is there a tool which creates the appropriate stub object file where all calls result in abort, given the set of object files that I have?
I use gcc (g++) for compiling/linking, version 3.4.4. Platform is unix (solaris/sparc if that's important).
You can just tell linker to ignore unresolved symbols. I couldn't find option that links them to abort or something like that.
The policy to ignore unresolved symbols in object files only is the most natural, I suppose:
gcc -Wl,--unresolved-symbols=ignore-in-object-files obj.o another.o etc.o
Other options include (quoting man ld):
--unresolved-symbols=method
Determine how to handle unresolved symbols. There are four possi-
ble values for method:
ignore-all
Do not report any unresolved symbols.
report-all
Report all unresolved symbols. This is the default.
ignore-in-object-files
Report unresolved symbols that are contained in shared
libraries, but ignore them if they come from regular object
files.
ignore-in-shared-libs
Report unresolved symbols that come from regular object files,
but ignore them if they come from shared libraries. This can
be useful when creating a dynamic binary and it is known that
all the shared libraries that it should be referencing are
included on the linker's command line.
The behaviour for shared libraries on their own can also be con-
trolled by the --[no-]allow-shlib-undefined option.
Normally the linker will generate an error message for each
reported unresolved symbol but the option --warn-unresolved-sym-
bols can change this to a warning.
On my Linux system attempts to call the unresolved function result in "Segmentation fault".
Trying to compile the following program
#include <iostream>
extern int bar();
int foo()
{
return bar() + 3;
}
int main()
{
std::cout << "Hello, world!" << std::endl;
// std::cout << foo() << std::endl;
return 0;
}
results in
$ g++ -o main main.cc
/tmp/ccyvuYPK.o: In function `foo()':
main.cc:(.text+0x5): undefined reference to `bar()'
collect2: ld returned 1 exit status
But we can tell the linker to ignore unresolved symbols and run it just fine:
$ g++ -Wl,--unresolved-symbols=ignore-all -o main main.cc
$ ./main
Hello, world!
Say some unresolved function is called by your test harness (simulate this by uncommenting the call to foo), it will compile and link fine, but you'll get a segfault when you execute the program. Be sure to ulimit -c unlimited so you get a core.
Well one way I can think of is to first compile the .o files for you library.
Then use a tool like nm (common on *nix systems) to get all of the symbols, in nm, all "external" (aka ones which are not found in this .o) are of type U (it may be different for non-GNU versions of nm see your documentation).
If your library is all one source file, then it is simple, pretty much all symbols of type U will be either a function found in another library or will be unresolved at link time. It is slightly more complicated if your library is going to be more than one source file since you will have inter-source file dependencies.
So now you have a a means to create a potential list of unresolved externals, then you can create a "test_stub.c" which has a stub symbols for each one, which you could fill with something like this:
void some_func() { abort(); }
where some_func is a would be unresolved external. Compile and link this with your library and all calls should result in an abort.
Try GCC alias attribute:
/* cannot directly alias to yet undefined symbols,
* so need an intermediate function.
*/
static void do_abort() { abort(); }
void func0() __attribute__ ((weak, alias ("do_abort")));
void func1() __attribute__ ((weak, alias ("do_abort")));
...