Multiple definition of variable First defined here error - c++

I have this c++ project with classes' definitions inside .hpp files and methods' declarations inside .cpp files.
The project uses a makefile to build and run.
The program ran without errors before but LinkedList didn't work as I wanted so I re-wrote it entirely.
Now LinkedList.hpp includes both the class definition and its methods' declarations.
I adjusted the other classes' methods so that they use LinkedList correctly.
Now when debugging the program I get this multiple definition of, first defined here error.
find: ‘lib’: No such file or directory
g++ -std=c++17 -Wall -Wextra -g -Iinclude -o output/main src/Game.o src/Hero.o src/Title.o src/Level.o src/Menu.o src/Entity.o src/Window.o src/main.o src/Map.o src/Object.o -lncurses
/usr/bin/ld: src/Hero.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: multiple definition of `TileTypeStr'; src/Game.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: first defined here
/usr/bin/ld: src/Level.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: multiple definition of `TileTypeStr'; src/Game.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: first defined here
/usr/bin/ld: src/Entity.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: multiple definition of `TileTypeStr'; src/Game.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: first defined here
/usr/bin/ld: src/Map.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: multiple definition of `TileTypeStr'; src/Game.o:/home/user/projects/project-X-githubClone/projectX/include/Object.hpp:2: first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:74: main] Error 1
So if I get this correctly, the problem is the multiple definitions of const char* TileTypeStr[].
But why then when I change that array's name to, say, tts the error message still reads "multiple definitions of TileTypeStr"?
and why if I comment out the only 2 references (including its declaration and initialisation) of this array inside the whole project the error message is still the same?

TileTypeStr[] was misplaced after all, moved it inside the toString() method I needed it for, then ran make clean to recompile all of the source files and make to build main.cpp.
By running make and not recompiling the source files I was stuck running the bugged version of the program.

Related

Makefile not working when changing function argument to const

I have a strange problem when compiling a C++ code using a makefile. The code first compiles perfectly. Then I change one function argument to "const". If I then compile, I will receive the error message when the code tries to use the function in which I changed the argument to const. This can be resolved by removing all .o files and then compiling again, but I am curious as to what causes this issue in the first place. My files are:
MyClass.h
class MyClass {
public:
void fun(double*const c);
};
MyClass.cpp
#include "MyClass.h"
void MyClass::fun(double *const c){
};
Main.cpp
#include "MyClass.h"
int main(int argc,char* argv[]) {
MyClass foo;
double *bar=new double[2];
foo.fun(bar);
};
Makefile
all: main
main: Main.o MyClass.o
g++ -o a.out Main.o MyClass.o
Main.o: Main.cpp
g++ -c Main.cpp
MyClass.o: MyClass.cpp
g++ -c MyClass.cpp
If I now first run make, everything works. But then I change the signature of fun to fun(const double *const c), I receive the error message
Main.cpp:(.text+0x3b): undefined reference to `MyClass::fun(double*)'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'main' failed
make: *** [main] Error 1
However, if I remove all the .o files and then run make again, it compiles.
The rule
main.o: Main.cpp
says thay the main.o object file only depend on the Main.cpp source file. But it actually depends on another file: The MyClass.h header file.
There's also an error in the capitalization of the name of the target.
The above two problems means that when you change the header file MyClass.h to update the function signature, the Main.o object file will not be recreated and still reference the old function.
So the rule should be
Main.o: Main.cpp MyClass.h
That addition will cause the Main.o object file to be recompiled when you change the header file.
This change should also be done for the MyClass.o target.
Also note that the main target uses MyClass.o as a dependency, but then you use the MyClass.cpp source file when linking, instead of the object file.
The name of the target should also be the name of the generated file (i.e. a.out in your case).
The problem is, that your Makefile is broken: It ignores the fact that a .o file does not only depend on the corresponding .cpp file, but also on the .h files it includes. A correct Makefile rule must include all dependencies, including the directly, or even indirectly included .h files.
Since you Makefile is incomplete, make did not recompile the calling site of your function when its definition changed, so the stale object still references the non-const function. Due to C++ name-mangling, the linker caught it in the act, the error would have gone unnoticed in C!
To fix this situation for good, I recommend spending an hour or two reading this article on automatic dependency generation, and implementing some of the solutions it offers into your Makefile. Once you have done this, you will likely just copy-cat your existing solution into the Makefiles of future projects, and otherwise forget about the problem.

MinGW crash if not compiled with -static-libstdc++

I'm using MinGW with g++ (5.3.0) to compile C and C++ for a while now.
I'm pretty sure I changed nothing but apparently I did because when I compiled my DLLs I noticed I couldn't load them when I used std::string or std::unique_ptr.
Later on I noticed that every single programm I compiled just crashed on startup.
Kinda got around that using -static-libstdc++ as a linker flag, which blew up my file sizes.
Today I fired up my computer and everything went nuts.
SSCCE:
int main() {}
When compiling with g++ sscce.cpp -o sscce.exe it works, but when I do
g++ -c sscce.cpp -o sscce.o
g++ sscce.o -o sscce.exe
I get this:
main.o:main.cpp:(.text+0x280): multiple definition of `_mingw32_init_mainargs'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../crt2.o:(.text+0x280): first defined here
main.o:main.cpp:(.text+0x2c0): multiple definition of `mainCRTStartup'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../crt2.o:(.text+0x2c0): first defined here
main.o:main.cpp:(.text+0x2e0): multiple definition of `WinMainCRTStartup'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../crt2.o:(.text+0x2e0): first defined here
main.o:main.cpp:(.text+0x300): multiple definition of `atexit'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../crt2.o:(.text+0x300): first defined here
main.o:main.cpp:(.text+0x310): multiple definition of `_onexit'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../crt2.o:(.text+0x310): first defined here
main.o:main.cpp:(.text+0x320): multiple definition of `__gcc_register_frame'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/crtbegin.o:(.text+0x0): first defined here
main.o:main.cpp:(.text+0x410): multiple definition of `__gcc_deregister_frame'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/crtbegin.o:(.text+0xf0): first defined here
main.o:main.cpp:(.bss+0x4): multiple definition of `_argc'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../crt2.o:(.bss+0x4): first defined here
main.o:main.cpp:(.bss+0x0): multiple definition of `_argv'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../crt2.o:(.bss+0x0): first defined here
main.o:main.cpp:(.eh_fram+0xc8): multiple definition of `__EH_FRAME_BEGIN__'
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/crtbegin.o:(.eh_frame+0x0): first defined here
d:/mingw/bin/../lib/gcc/mingw32/5.3.0/crtbegin.o:(.text+0x92): undefined reference to `_Jv_RegisterClasses'
collect2.exe: error: ld returned 1 exit status
Why does this happen and what can I do to make it stop?
Literally didn't touch anything, not even my PC, and now it works again.

Deleting *.cpp file after compiling with wrong flag order?

I really need your help on this one!
I had a problem with my makefile. The error was very common:
makefile:11: recipe for target 'exec' failed
My makefile looks like this:
CC = g++
PY = python
FLAGS = -std=c++11 -O3
all: main exec data
main: main.cpp
$(CC) $(FLAGS) -o $# $<
exec: main
time ./$<
data: plot.py main
$(PY) $<
As far as im concerned there is no mistake but I still got the error, maybe main.cpp was not compiled?
Anyway I then tried (out of curiosity):
g++ -std=c++11 -O3 -o main.cpp main
And then I got this error:
main: In function `_start':
(.text+0x1360): multiple definition of `_start'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.text+0x0): first defined here
main: In function `_fini':
(.fini+0x0): multiple definition of `_fini'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crti.o:(.fini+0x0): first defined here
main:(.rodata+0x0): multiple definition of `_IO_stdin_used'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.rodata.cst4+0x0): first defined here
main: In function `data_start':
(.data+0x0): multiple definition of `__data_start'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crt1.o:(.data+0x0): first defined here
main:(.rodata+0x8): multiple definition of `__dso_handle'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/crtbegin.o:(.rodata+0x0): first defined here
main: In function `_init':
(.init+0x0): multiple definition of `_init'
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/../../../../lib64/crti.o:(.init+0x0): first defined here
/usr/lib/gcc/x86_64-redhat-linux/6.3.1/crtend.o:(.tm_clone_table+0x0): multiple definition of `__TMC_END__'
main:(.data+0x8): first defined here
/usr/bin/ld: error in main(.eh_frame); no .eh_frame_hdr table will be created.
collect2: error: ld returned 1 exit status
And now my main.cpp is gone. What the actual.. How can I recover it? I have an older version of it because I'm using git, but its rather unfinished and I really need this version.
The error was very common
That's the make error. What did it show before that? Did it run the compiler at all? Was there a compile error? What was it?
I addressed your proximate problem below, but the original issue is the compile error. You're fixating on the fact that a build target failed, rather than on understanding why it failed.
Builds fail all the time: very commonly because there's a mistake in the code, and very rarely because of an error in a previously-working makefile. As a consequence, you usually want to worry about understanding and fixing the compiler error, before you start changing your makefile or running the compiler manually.
And now my main.cpp is gone. What the actual..
Well, in
g++ -std=c++11 -O3 -o main.cpp main
the option -o filename tells g++ to use filename for output. So, it opened main.cpp for output and clobbered the contents.
You meant
g++ -std=c++11 -O3 -o main main.cpp
It's an easy mistake to make, which is why we have build systems to do this stuff for us. And backups. And version control.
In future, you can just type make main to select a single target, and make should tell you what it's doing.
How can I recover it?
From your editor, or version control, or backup, or filesystem-level snapshotting if you have a fancy SAN or, in extremis, from memory.
Nothing teaches good source control and backup habits like having to rewrite something from scratch.
there is no main.cpp file anymore. why exactly is that?
When the build failed, the incomplete output file was deleted.
Consider, for reference, how make works. You have a target called main, so it checks whether a file called main exists.
if main exists, it looks at the dependencies, and sees if any of those files are newer then main
if it thinks main should be (re-)generated (either it doesn't exist or is older than a dependency), it runs the rule you gave it
Now if g++ left an empty (or incomplete) version of main lying around after a failed compilation, how would make know to re-generate it the next time you built?
It's essential that the output file be deleted when compilation fails, because otherwise make wouldn't work correctly. You'd also have a directory full of empty or corrupt partly-compiled executables and object files, which doesn't sound like such a great idea.
In other news, your exec target doesn't create a file called exec. This should be a .PHONY rule. So, probably, should data.
The problem is:
g++ -std=c++11 -O3 -o main.cpp main
Where you specify that the output should be placed in main.cpp. You try to compile main and store the result in main.cpp. Since the compile failed, the output file is removed after compilation stopped. So no main.cpp.
It's simple: Just save the file again in your editor.
To do so, press C-x C-w and type the filename again.

C++ Static Library Linker Error

I'm creating a simple spell checker program with the use of static libraries, as I want other people to be able to use the spell checker functions. The two problem areas are in the library source code and the library header. When I compile the library, this is the error I get:
ar -cvq libspellcheck.a checker.o
a - checker.o
g++ -o spell-check main.o meta.o libspellcheck.a
libspellcheck.a(checker.o): In function `check_spelling(char*, char*)':
checker.cpp:(.text+0x0): multiple definition of `check_spelling(char*, char*)'
libspellcheck.a(checker.o):checker.cpp:(.text+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [spellcheck] Error 1
The checker.cpp code is located here.
The header file (spellcheck.h) is located here.
What I would like to know is what is causing the errors above, as I can't figure it out.
It looks as though you've added checker.cpp to the archive twice.
Try using this command instead:
ar -cvr libspellcheck.a checker.o
Using r instead of q will replace any existing file with the same name, rather than adding another copy of it.
Alternatively, just ensure you delete the archive before you add any files to it, so it always starts empty.
The problem seems to be linking checker.cpp twice - can you add your makefiles (also make sure check_spelling isn't defined twice in checker.cpp and try to clean the intermediary files before build)?

c++ undefined reference to <a function>

HI,
I have some questions about .h files and .cpp files in c++/linux(ubuntu).
It is possible to compile a .h file using g++ or you can just compile a .cpp file that includes the .h file?
From a .h file and it's .cpp file (.cpp where i include some code to the methods i've defines in .h file) I create a .so file using the command:
g++-fPIC -shared my_code.cpp -o my_code.so`
In the test.cpp I include the .h file and using dlopen i create a handler over the .so file. Why do I have the following error:
undefined reference to bool `Class::method(std::string)` `collect2: ld returned 1 exit status
If I say virtual bool method... in the .h file there is no error when I compile test.cpp. Can someone explain what am I doing wrong? The thing is that i have a template. With templates I cannot use virtual..so..i have this undefined error and i don't know how to resolve it. THX
EDIT:
When i compile the my_code.cpp I have the errors:
/usr/bin/ld: .usr/lib/debug/usr/lib/crt1.o relocation 0 has invalid symbol index 12 (same with index 13,2,14...22 ).
But when i create the .so file there is no error . I use:
g++ test.coo -ldl -o test
for the test.cpp compilation.
Ad 1: It is possible to compile .h file (you can explicitly override the language detection), but you don't want to do it. The .h file is intended to be included and will not compile to anything useful on it's own.
Ad 2: You have to link against the library you created by passing the -lmy_code (but note that for that to work you have to create it as libmy_code.so) along with appropriate -L flag (directory where you placed libmy_code.so) to the linker. Like this:
g++ test.cpp -L. -lmy_code -ldl -o test
But you also have to change the first command to:
g++ -fPIC -shared my_code.cpp -o libmy_code.so
^^^
libraries *must* have `lib` prefix on unix systems.
and this assumes both are done in the same directory—if not, you have to adjust the -L option to point to the directory where libmy_code.so is. Also you have to place libmy_code.so somewhere where the dynamic linker can find it. Either by installing it or by setting environment variable LD_LIBRARY_PATH to appropriate directory. Alternatively you can compile by using
g++ test.cpp my_code.so -ldl -o test
This does not force the lib prefix and it creates an "rpath" entry in the binary so it will find the library in the original place.
This all assumes you want to use it as regular library in which case you don't want to use dlopen. dlopen is for opening libraries as plugins at runtime and than they can only be accessed by fetching pointers to symbols using dlsym(), but if you want to access the library normally, you have to link against it so the linker can resolve the symbols.
If instead you wanted to use dlopen, you must not include my_code.h in test.cpp and must not use anything it defines except by getting the symbols with dlsym. And since this is C++, it in turn requires you understand the symbol mangling scheme, because dlsym will not do this for you.
Generally there is no need to compiling a .h file, it simply generates a huge file with .gch extension I guess.
The error you are getting is a link time. While creating the .so file, you do not actually link the code. So all undefined symbol are assumed to be present at some place. When you link it, the linker will find for those symbols. So, you should compile/link all the .cpp file together. The error will go away.
Also, For templates, the definition of the code must always be visible. So wherever you write the templated function/variable definition, include that file everywhere.
Edit:
You can have virtual method with template classes; but you can not have virtual template methods.
template<typename T>
class A {
virtual void foo(int); // ok
};
class A {
template<typename T>
virtual void foo(T); // illegal
};