mingw linker error when using vector templates - c++

I'm using MinGw on Windows 7. The following simple program compiles fine, but the linker complains and I do not understand what's wrong:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<int> iv;
iv.push_back(7);
cout << iv.back() << endl;
return 0;
}
the compiler/linker messages look as follows:
mingw32-g++.exe -Wall -fexceptions -std=c++0x -Wall -g -std=c++0x -Wall -g -frepo -IC:\cppbuchincludes\include -IG:\Boost -IG:\Users\thomas\cpp\STLUsage\\include -c G:\Users\thomas\cpp\STLUsage\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\STLUsage.exe obj\Debug\main.o G:\Boost\stage\lib\libboost_filesystem-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_regex-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_system-mgw45-mt-d-1_45.dll.a G:\Boost\stage\lib\libboost_thread-mgw45-mt-1_45.dll.a G:\Boost\stage\lib\libboost_unit_test_framework-mgw45-mt-d-1_45.dll.a
collect: recompiling G:\Users\thomas\cpp\STLUsage\main.cpp
collect: relinking
collect2: '_ZNSt12_Vector_baseIiSaIiEEC1Ev' was assigned to 'obj\Debug\main.rpo', but was not defined during recompilation, or vice versa
obj\Debug\main.o: In function `vector':
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_vector.h:208: undefined reference to `std::_Vector_base<int, std::allocator<int> >::_Vector_base()'
(...and so on...)
I can use templates I defined myself.
I have that MinGw binary from a book and followed the instructions in that book regarding compiler settings. In particular the references to the Boost libs are taken from there.
This must be a simple thing, I just want to make trivial use of the STL.
Edit following the advice given in an answer, I replaced the binary to be used to compile by g++.exe in the Settings -> Compiler and debugging -> toolchain executables dialog, but I'm getting the same error messages (with mingw32-g++.exe now replaced by g++.exe).
Edit (once more) this has to be problem eith the Code::Blocks settings, since compiling using g++ from the command line works just fine.

Use g++ to compile and link the program. mingw32-g++.exe doesn't do that.
FAQ says,
What's the difference between gcc and mingw32-gcc?
The mingw32-gcc, mingw32-g++, etc. binaries exist as an aid to cross development. They are created in a typical build of gcc. They are therefore distributed as the maintainers of GCC meant them to be. The gcc.exe indicates that the binary produces binaries for a target equal to the build, while the mingw32-gcc binary produces binaries to be executed on the mingw32 target.
So I guess the problem is because of mingw32-g++.exe which you're not supposed to use, for normal build.
Try these:
g++ program.cpp //simple build
g++ program.cpp -Wall //build with all warnings enabled
g++ program.cpp -Wall -O2 //enable warnings and optimization level 2
g++ program.cpp -std=c++0x //use C++11 features
Hope that helps.

Related

Can't work with String library on g++ 12.2.0 but working just fine on OnlineGDB [duplicate]

I'm trying to use the JsonCpp library. I'm on Windows, using MinGW and CodeBlocks.
When I include anything from the json headers, my linker implodes and gives out this two errors. I've started to look around and I found these two other questions which basically describe my problem:
problem with g++ and "undefined reference to `__gxx_personality_v0'"
What is __gxx_personality_v0 for?
And if I declare the two missing variables as void pointers, like below, the problem goes away:
void * __gxx_personality_v0=0;
void * _Unwind_Resume =0;
However, I don't understand why this error happens. CodeBlocks is set up so that it uses migw32-g++ for cpp files, and also adding the -lstdc++ option does not fix the problem. Neither does the option -fno-exception ( I want exceptions, mind you, I was just trying ).
I'm also including a boost library in the same file and that does not cause any problems.
EDIT:
The error output is exactly what I said in my title: I get a total of 22 undefined references to _Unwind_Resume and __gxx_personality_v0 during the linking. My code is:
#include <boost/algorithm/string.hpp>
#include <include/json/value.h>
//void * __gxx_personality_v0=0;
//void * _Unwind_Resume =0;
int main () {
std::string str1("Hello world!");
boost::to_upper(str1);
Json::Value k;
return 0;
}
The error is there only when I include/use the JsonCPP library. Uncommenting the commented lines fixes the problem.
The command line output is this:
mingw32-g++.exe -Wall -fexceptions -g -DSFML_DYNAMIC -IC:\Users\Svalorzen\Documents\Projects\boost_1_49 -IC:\Users\Svalorzen\Documents\Projects\jsoncpp-src-0.5.0 -IC:\Users\Svalorzen\Documents\Projects\SFML-1.6\include -IC:\Users\Svalorzen\Documents\Projects\hge181\include -c C:\Users\Svalorzen\Documents\Projects\test\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -LC:\Users\Svalorzen\Documents\Projects\jsoncpp-src-0.5.0 -LC:\Users\Svalorzen\Documents\Projects\SFML-1.6\lib -LC:\Users\Svalorzen\Documents\Projects\hge181\lib -o bin\Debug\test.exe obj\Debug\main.o -fno-exceptions -lsfml-graphics -lsfml-window -lsfml-system C:\Users\Svalorzen\Documents\Projects\jsoncpp-src-0.5.0\libs\mingw\libjson_mingw_libmt.a C:\Users\Svalorzen\Documents\Projects\hge181\lib\gcc\libhge.a C:\Users\Svalorzen\Documents\Projects\hge181\lib\gcc\libhelp.a
Output size is 1.22 MB
Process terminated with status 0 (0 minutes, 3 seconds)
0 errors, 0 warnings
SECOND EDIT:
I'm adding the command lines I use to compile the library:
g++ -o buildscons\mingw\src\lib_json\json_reader.o -c -DWIN32 -DNDEBUG -D_MT -Iinclude src\lib_json\json_reader.cpp
g++ -o buildscons\mingw\src\lib_json\json_value.o -c -DWIN32 -DNDEBUG -D_MT -Iinclude src\lib_json\json_value.cpp
g++ -o buildscons\mingw\src\lib_json\json_writer.o -c -DWIN32 -DNDEBUG -D_MT -Iinclude src\lib_json\json_writer.cpp
ar rc buildscons\mingw\src\lib_json\libjson_mingw_libmt.a buildscons\mingw\src\lib_json\json_reader.o buildscons\mingw\src\lib_json\json_value.o buildscons\mingw\src\lib_json\json_writer.o
ranlib buildscons\mingw\src\lib_json\libjson_mingw_libmt.a
For those coming to this from google (like i did), the real cause of the undefined references to _Unwind_Resume and __gxx_personality_v0 is "using a gcc that uses a different stack unwinding method than dwarf2" [1]
In my case it was attempting to link code compiled with GCC 4.9 upwards with a library compiled with GCC 4.8 or below. The solution is to recompile the library with the same compiler you're building with.
I encountered that same problem attempting to use g++ -g -std=c++17 ... . I removed that option and, once I had removed use of a C++17 feature, it compiled, linked and ran.
I finally fixed this by importing into Code::Blocks the source code of JsonCpp and creating the library myself. I am still baffled though as to why the library created with Scons didn't work, since it was using the same compiler that Code::Blocks uses, but at the same time it was not ( or the error wouldn't have been there ).

How do retain debug symbols when profiling C++ code on Windows?

I'm trying to profile a C++ shared library on Windows 10, in order to find which lines the program is spending most time on. (The code happens to form part of an R package.)
I've previously used
AMD µprof and
Very Sleepy. However, I'm now having trouble compiling the code: all these profilers show is which DLL is being used, rather than which function / line.
I suspect that the problem relates to debugging symbol tables being missing. Per
Enabling debug symbols in shared library using GCC, I've ensured that a -g flag is applied when compiling each file, and that there is no -s flag at the linker stage. What else do I need to do to allow µprof / Very Sleepy to tell me which lines of the code are proving a bottleneck?
Detailed compilation notes
I'm using RBuildTools MinGW-w64 v3 g++ 8.3.0 to compile the code on 64-bit Windows 10.
Here are some sample compile commands, which are being generated by R, using Makevars / Makeconf templates.
g++ -std=gnu++14 -I"<<include paths>>" -DNDEBUG -g -O2 -Wall
-mfpmath=sse -msse2 -mstackrealign
-c source_file.cpp -o source_file.o
g++ -shared -static-libgcc -g -Og
-o PackageName.dll tmp.def source_file.o <<Other files>>
-L<<Library paths>>
I've also tried replacing -g with -gdwarf-2 -g3, and adding -fno-omit-frame-pointer, per Very Sleepy doesn't see function names when capturing MinGW compiled file.
Running without shared library
ssbssa suggested running against a simple executable.
I tried:
#include <chrono>
#include <thread>
#include <iostream>
long sumto(long n) {
if(n > 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
return n + sumto(n - 1);
}
return 1;
}
int main() {
std::cout << sumto(1000) << std::endl;
return 0;
}
>"C:/RBuildTools/4.0/mingw64/bin/"g++ -std=gnu++14 -gdwarf-2 -g3 -Og -c test.cpp
>"C:/RBuildTools/4.0/mingw64/bin/"g++ -std=gnu++14 -gdwarf-2 -g3 -Og -o test test.o
test.exe runs as expected. When I profile test.exe, AMD µprof states "The raw file has no data!", whereas VerySleepy does detect activity in sumto and displays the associated source code.

Debian gcc undesirable behaviour

I am creating a gcc shared library having a static library dependency.
I compile the parts for static library as following:
gcc -c -m64 -O2 -fPIC -std=c99 -Wall ms*.c //there are 10 C files, no warnings
Next I create a static library with:
ar rc static_lib.a ms*.o
Next I compile the parts for my program as following:
g++ -c -m64 -O2 -fPIC -std=c++14 -Wall ab*.cpp //there are 5 C++ files, just -Wunused-variable warnings
Then I create a shared library as following:
g++ -shared -g -Wall ab*.o static_lib.a -o shared_lib.so
in the normal case, this shared_lib.so will be called by a Ruby program using a foreign function interface. There is no problem if I do it on ubuntu or mac(.dylib), but if I try this on debian stretch I get an error related to the static library as if the configurations are not set properly. If I run the application without foreign function interface, such as creating a tester and running with the cpp file main function as following:
> g++ -o library_test ab*.o static_lib.a
> ./library_test
There is no problem!
My question is what kind of configuration for creating a shared library may be missing here to not get that undesirable behaviour. Especially on debian stretch 9.5!
Or is there a way that I can understand if there is a problem in the shared library.
From the comments, you indicate the problem is with a #define. Those are preprocessor directives. Libraries are for the linker.
You might be confused because g++ does include the preprocessor phase, and might call the linker depending on the requested output. Still, g++ follows the C++ language rules.

Why does gcc produce a different result when bulding from source compared to linking a static library?

I have a single C++14 file, my.cpp, and from within it I'm trying to use a C99 library called open62541. For the latter, both full source open62541.c/.h and a library libopen62541.a exist. In my.cpp, where I include the open62541.h, I'm using C++ specific code (e.g. iostream), so technically I'm mixing C and C++.
I can get my.cpp to compile successfully by referencing the libopen62541.a:
gcc -x c++ -std=c++14 -Wall my.cpp -l:libopen62541.a -lstdc++ -o out
This outputs no warnings, and creates an executable out.
However, if I try to compile using source code only:
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out
I get a lot of ISO C++ warnings (e.g. "ISO C++ forbids converting a string constant to ‘char'*") and some "jump to label" errors originating from within open62541.c, resulting in compilation failure.
I can get compilation to succeed by using the -fpermissive switch:
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -fpermissive -o out
which still outputs a lot of warnings, but creates the executable successfully. However, I'm unsure if doing this is a good idea.
Perhaps worth mentioning is that open62541.h considers C++ at the beginning:
#ifdef __cplusplus
extern "C" {
#endif
Given that .a library, which comes bundled with the open62541 library code, is supposedly built from the same source, why are the first two approaches not consistent in terms of warnings and errors generated? Why does one work and the other doesn't?
Should one method - linking .a vs referring to .c - be preferred to another? I was under impression that they should be equivalent, but apparently they aren't.
Is using -fpermissive in this case more of a hack that could mask potential problems, and should thus be avoided?
The error (and warning) you see are compilation errors (and warning) output by a C++ compiler when compiling C code.
For instance, in C "literal" has type char[] while in C++ it has type const char[].
Would you get a C++ compiler build libopen62541.a from open62541.c, you would see the same errors (warnings). But a C compiler might be OK with it (depending on the state of that C source file).
On the other hand, when you compile my.cpp and links it against libopen62541.a, the compiler doesn't see that offending C code, so no errors (warnings).
From here, you basically have two options:
Use the procompiled library if it suits you as is
g++ -std=c++14 -Wall -Wextra -Werror my.cpp -lopen62541.a -o out
Compile the library's code as a first step if you need to modify it
gcc -Wall -Wextra -Werror -c open62541.c
g++ -std=c++14 -Wall -Wextra -Werror -c my.cpp
g++ open62541.o my.o -o out
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out
This command forces the C code in open62541.c to be compiled as C++. That file apparently contains constructs that are valid in C but not C++.
What you should be doing is compiling each file as its own language and then linking them together:
gcc -std=gnu11 -Wall -c open62541.c
g++ -std=gnu++14 -Wall -c my.cpp
g++ -o out my.o open62541.o
Wrapping up those commands in an easily repeatable package is what Makefiles are for.
If you're wondering why I changed from the strict -std=c++14 to the loose -std=gnu++14 mode, it's because the strict mode is so strict that it may break the system headers! You don't need to deal with that on top of everything else. If you want a more practical additional amount of strictness, try adding -Wextra and -Wpedantic instead ... but be prepared for that to throw lots of warnings that don't actually indicate bugs, on the third-party code.

Why am I getting "undefined reference to main"

I am a very new to programming and have a very basic question that may be answered in other threads however I think they are far too advanced for me to understand how. I have actually found many answers so far on this site but this is the first problem that forced me to create an account and ask.
Anyway i am running a very basic example program on linux mint 18.3. Now I have seen this exact code work on a machine with windows 8 I believe so I was wondering if that could be the problem. I have created a class and when i plug in my object then build and run I get:
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o||In function _start':|
(.text+0x20)||undefined reference tomain'|
This is the entire code:
#include <iostream>
#include "Gladius.h"
using namespace std;
int main()
{
Gladius io;
return 0;
}
Thats it very basic. here is the .h
#ifndef GLADIUS_H
#define GLADIUS_H
class Gladius
{
public:
Gladius();
};
#endif // GLADIUS_H
and the .cpp for the class.
#include "Gladius.h"
#include <iostream>
using namespace std;
Gladius::Gladius()
{
cout << "The Gladius is a short sword" << endl;
}
I know this seems extremely simple but I am just learning to code and i have been looking all over for an explanation why this isn't working yet I see it work on another pc exactly as is. Anyway any explanation would be greatly appreciated.
Here is what i found in command line If this answers your questions about what was in the cmd.
g++ -Wall -fexceptions -g -std=c++11 -Wall -I -c /home/gator/Documents/Spartan1/Gladius.cpp -o obj/Debug/Gladius.o
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function _start':
(.text+0x20): undefined reference tomain'
collect2: error: ld returned 1 exit status
Know the compiler options(gcc/g++ compiler):
-c : Compile and assemble, but do not link
-o file : Place the output into file
So when you run
g++ filename.cpp -o executable_name
, you generate an application which can be executed.
The problem is you are compiling, assembling as well as linking when you are trying to compile "Gladius.cpp" and compiler is trying to search for main() definition.
So in your case, the compilation steps would be:
First compile "Gladius.cpp" and generate object file "Gladius.o":
g++ -Wall -fexceptions -g -std=c++11 -c Gladius.cpp
Next compile "main.cpp" and generate object file "main.o":
g++ -Wall -fexceptions -g -std=c++11 -c main.cpp
Generate executable by linking "main.o" and "Gladius.o"
g++ -Wall -fexceptions -g -std=c++11 -o main main.o Gladius.o
Now you can run "main":
./main
Your compiler's command line contains -I -c sequence.
This -I option "swallows" your -c option. -I requires an additional argument, which is an include directory name. You failed to supply that argument, which is why -I assumes that -c that follows it is the directory name. So that -I consumes that -c.
The compiler never sees that -c. Without -c it assumes that you want to compile and link your program. Since Gladius.cpp does not have main in it, you get the error at linking stage.
Here 's a simple demo of the same problem: http://coliru.stacked-crooked.com/a/8a37cd3e90a443e2
You need to figure out why you have an orphaned -I in your command line.
If you are compiling this code using a command line like:
g++ -Wall -Wextra -Werror -O gladius.cpp -o output.exe
then make sure that you include all the .cpp files (not .h files) that contain code that your program needs.
g++ -Wall -Wextra -Werror -O gladius.cpp main.cpp -o output.exe
I explain this to beginners all the time as each .cpp being a bag of Lego's in a kit. You need all the bags that came with the box in order to build the kit. If you omitted main.cpp (or the file that contains main) then you will get the linker error that you are currently getting.
What command are you using to compile, link, and then execute? It should look something like
$ g++ main.cpp gladius.cpp -odemo
$ ./demo
check your command line for linking step.. You may forgot file with main as input, or you had forgot output file name after -o (and masked main.o in result)
I had this very kind of problem myself, and though it may not be the conventional, "proper" solution, I simply renamed the ".c" file to ".cpp", and it all worked.
After all, I was compiling both c and c++ together with a c++ compiler (recommended by the library), and the c code already had the proper c++ #extern flags (see here for more on that).
Also related:
C++ Error: undefined reference to `main'
Including C Code in C++
Why do you need an explicit `-lm` compiler option
Compilation on Linux - In function '_start': (.text+0x20): undefined reference to 'main'