LNK2005 error, already defined: Possibly one definition rule violation? - c++

I searched and found various similar questions though I wasn't able to find a solution for my problem.
It's a SDL2 + OpenGL program, I can compile it with no problems in Linux using g++ 4.9.1 though not on Windows (VS 2013).
I get errors like:
Error 1 error LNK2005: "union SDL_Event e" (?e##3TSDL_Event##A) already defined in engine.obj PATH_TO_PROJECT\main.obj Game
for all the variables defined in the file engine.h:
//engine.h
#ifndef ENGINE_H
#define ENGINE_H
#include <SDL.h>
#include <SDL_opengl.h>
#include <iostream>
#include "player.cpp"
SDL_Event e;
bool running = true;
bool up = false, down = false, left = false, right = false;
bool attack = false;
player hero(20, 300, 50, 50, 10.0); //x, y, lenght, height, speed
void init(char* title, int WIDTH, int HEIGHT);
void draw(SDL_Window* screen, SDL_GLContext context, int WIDTH, int HEIGHT);
#endif
engine.cpp consists of:
//engine.cpp
#include "engine.h"
void init(int WIDTH, int HEIGHT) {
//BODY OF THE FUNCTION
}
void draw(SDL_Window* screen, SDL_GLContext context, int WIDTH, int HEIGHT) {
//BODY OF THE FUNCTION
}
main.cpp is the only file that includes engine.cpp:
//main.cpp
#include <SDL.h>
#include <SDL_opengl.h>
#include "engine.cpp"
#include <iostream>
#define WIDTH 800
#define HEIGHT 600
int main() {
SDL_Init(SDL_INIT_EVERYTHING);
STD::cout << "SDL started." << STD::endl;
init(WIDTH, HEIGHT);
//Create the window
SDL_Window *screen = SDL_CreateWindow("game title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(screen);
draw(screen, context, WIDTH, HEIGHT);
SDL_Quit();
return 0;
}
I also get these:
Warning 9 warning LNK4098: defaultlib 'msvcrt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library PATH_TO_PROJECT\MSVCRTD.lib(cinitexe.obj) Game
Error 10 error LNK2019: unresolved external symbol _SDL_main referenced in function _main PATH_TO_PROJECT\SDL2main.lib(SDL_windows_main.obj) Game
Error 11 error LNK1120: 1 unresolved externals PATH_TO_PROJECT\Game.exe Game
I can't really understand what is going on, specially since I can compile it on Linux, could someone please help me out?
The libraries are corrected linked, verified that. Also, if I put all the code in the main function and use only one file it compiles and runs with no problem.

Your main.cpp file should include engine.h, not engine.cpp.
Further, you do define the global e multiple times, in every translation unit that includes the engine.h header. In the engine.h header declare it extern instead, which tells the compiler that e exists somewhere but doesn't actually define it:
extern SDL_Event e;
Then define it in only one translation unit; put this in engine.cpp:
SDL_Event e;
You need to do the same thing with all of the other global variables as well. Note that you need to initialize them where you define them, so this goes in the header:
extern bool running, attack, up, down, left, right;
And this goes in engine.cpp:
bool running = true;
bool attack = false; /* and so on */

You are getting these redefinition issues as you have included .cpp file in your main:-
#include "engine.cpp"
You should always include header files only. ( Also these header files should contain appropriate header gaurds ).

Related

Linker warning causes random linking errors every few compilations

I can't get a minimal reproduceable example any smaller than what I have. Mainly because I can't debug the issue, it seems completely random and I don't consistently get the error, sometimes it compiles, sometimes it doesn't. I have reverted back to when I had the error so I can copy the code, but since then, I haven't gotten an error. Basically, I have no other ideas left other than to fix all my linker warnings. I remember it was mostly related to this warning LNK4042 object specified more than once; extras ignored in main.obj. There is also another warning I don't understand, that being I have the binaries for a library named GLEW, yet statically linking it invokes a linker warning, LNK4099 PDB 'vc120.pdb' was not found with 'glew32s.lib(glew.obj)' or at '\SolutionDir\Debug\vc120.pdb'; linking object as if no debug info
What are the fixes for these warnings? Hopefully to stop me randomly getting errors that, when I change one thing it compiles, and then revert it back and it still compiles.
Here is the code, main.h
#pragma once
#ifndef MAIN_H
#define MAIN_H
#include <GL/glew.h> // Initialize with glewInit()
#ifndef GLFW_INCLUDE_NONE
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors.
#endif // GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h>
#include "ImGui/imgui.h"
#include "ImGui/implot.h"
#include "ImGui/imgui_impl_glfw.h"
#include "ImGui/imgui_impl_opengl3.h"
#include <iostream> //std::string
class Main ///Singleton
{
public:
Main(const Main&) = delete;
Main(Main&&) = delete;
Main& operator=(const Main&) = delete;
Main& operator=(Main&&) = delete;
private:
Main();
static Main& Get_Instance();
friend int main(int argc, char* argv[]);
static void Mainloop();
static void Init();
static void Free();
GLFWwindow* m_Window = nullptr;
std::string m_GLSL_Version = "";
int m_Window_Width = 1280;
int m_Window_Height = 720;
};
#endif // MAIN_H
and main.cpp
#include "main.h"
Main::Main()
{
}
Main& Main::Get_Instance()
{
static Main instance;
return instance;
}
void Main::Init()
{
// Setup window
Get_Instance(); //Init constructor
if (!glfwInit()) {
std::cout << "Could not initialize GLFW" << std::endl;
std::cin.get();
exit(EXIT_FAILURE);
}
Get_Instance().m_GLSL_Version = "#version 460";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
// Create window with graphics context
Get_Instance().m_Window = glfwCreateWindow(Get_Instance().m_Window_Width, Get_Instance().m_Window_Height, "Program", NULL, NULL);
if (Get_Instance().m_Window == NULL) {
std::cout << "Could not create GLFW window" << std::endl;
std::cin.get();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(Get_Instance().m_Window);
glfwSwapInterval(0); // vsync
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
std::cin.get();
exit(EXIT_FAILURE);
}
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImPlot::CreateContext();
// Setup Dear ImGui style
ImGui::StyleColorsClassic();
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(Get_Instance().m_Window, true);
ImGui_ImplOpenGL3_Init(Get_Instance().m_GLSL_Version.c_str());
}
void Main::Mainloop()
{
// Main loop
while (!glfwWindowShouldClose(Get_Instance().m_Window))
{
//Events
glfwPollEvents();
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Text("%.3f", ImGui::GetIO().Framerate);
// Rendering
ImGui::Render();
glfwGetFramebufferSize(Get_Instance().m_Window, &Get_Instance().m_Window_Width, &Get_Instance().m_Window_Height);
glViewport(0, 0, Get_Instance().m_Window_Width, Get_Instance().m_Window_Height);
glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(Get_Instance().m_Window);
}
}
void Main::Free()
{
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImPlot::DestroyContext();
ImGui::DestroyContext();
glfwDestroyWindow(Get_Instance().m_Window);
glfwTerminate();
}
int main(int argc, char* argv[])
{
Main::Init();
Main::Mainloop();
Main::Free();
return 0;
}
Edit: It happened again, here are the errors:
Error LNK1561 entry point must be defined
Warning LNK4042 object specified more than once; extras ignored (THIS IS IN MY main.obj file, its the only linker issue that references my actual files, the rest reference either 'LINK' or 'libucrt.lib(something here)'
Error LNK2005 __cexit already defined in ucrtd.lib(ucrtbased.dll)
Error LNK2005 __crt_atexit already defined in ucrtd.lib(ucrtbased.dll)
Error LNK2005 __crt_at_quick_exit already defined in ucrtd.lib(ucrtbased.dll)
Error LNK2005 __execute_onexit_table already defined in ucrtd.lib(ucrtbased.dll)
Error LNK2005 __initialize_narrow_environment already defined in ucrtd.lib(ucrtbased.dll)
Error LNK2005 __initialize_onexit_table already defined in ucrtd.lib(ucrtbased.dll)
Error LNK2005 __register_onexit_function already defined in ucrtd.lib(ucrtbased.dll)
Error LNK2005 __seh_filter_dll already defined in ucrtd.lib(ucrtbased.dll)
Regarding the LNK4042 warning, you may be able to resolve the issue, if you open the properties for the entire project, and the change the value under C/C++ -> Output Files -> "Object File Name" to be the following:
$(IntDir)/%(RelativeDir)/

How to initialize all variables from a namespace in one class

I am making a small game using SFML.
I want to load all my resources in one go when the game launches, so every time a new entity is created new resources don't need to be loaded to memory slowing down the game.
I have made a header file with a namespace for each kind of resource I need:
#pragma once
#include <SFML/Graphics.hpp>
#include <iostream>
#include "spritesheet.h"
namespace PlayerSprite {
extern Spritesheet playerSpritesheet;
extern sf::Sprite sp1, sp2, sp3, sp4, sp5, sp6;
extern int width = 16;
extern int height = 16;
}
namespace ButtonSprite {
extern Spritesheet buttonSpritesheet;
extern sf::Sprite button;
extern int width = 32;
extern int height = 16;
}
class Resources {
public:
Resources() = default;
void loadResources();
};
Now I don't know much about namespaces only very basic stuff, this is the first reason to use one.
Now in the cpp file:
#include <iostream>
#include "../headers/resources.h"
void Resources::loadResources() {
// PLAYER
PlayerSprite::playerSpritesheet.setSprite("./res/img/tiles.png");
PlayerSprite::sp1 = PlayerSprite::playerSpritesheet.getSprite(0, 0, PlayerSprite::width,
PlayerSprite::height);
PlayerSprite::sp2 = PlayerSprite::playerSpritesheet.getSprite(32, 0, PlayerSprite::width,
PlayerSprite::height);
PlayerSprite::sp3 = PlayerSprite::playerSpritesheet.getSprite(48, 0, PlayerSprite::width,
PlayerSprite::height);
PlayerSprite::sp4 = PlayerSprite::playerSpritesheet.getSprite(64, 0, PlayerSprite::width,
PlayerSprite::height);
PlayerSprite::sp5 = PlayerSprite::playerSpritesheet.getSprite(80, 0, PlayerSprite::width,
PlayerSprite::height);
PlayerSprite::sp6 = PlayerSprite::playerSpritesheet.getSprite(0, 16, PlayerSprite::width,
PlayerSprite::height);
// PLAYER
// BUTTONS
ButtonSprite::buttonSpritesheet.setSprite("./res/img/tiles.png");
ButtonSprite::button = ButtonSprite::buttonSpritesheet.getSprite(48, 16, 32, 16);
// BUTTONS
}
I then call this function in the main game file, but when I run I get this error in the player class:
undefined reference to 'PlayerSprite:sp1'
I don't know if this is because of the namespace declaration, or me coding the system wrong.
After looking at some comments on this question I have added this:
void Resources::allocateStorage() {
sf::Sprite PlayerSprite::spritesheet;
sf::Sprite PlayerSprite::sp1;
}
In the cpp file, but I am now getting this error:
unqualified-id in declaration before ';' token on the 1st line after the implementation of the function.
The problem seems to be that the variables are not actually defined anywhere, just declared. When using extern, the compiler will assume that this variable exists, so the compiler can continue on assuming that the variable exists. The linker will then come in, and see where that variable exists. If it does not, you get an undefined reference error. To fix this, you need to define the variables somewhere.
For example, in say resources.cpp, you would have:
#include "../headers/resources.h"
sf::Sprite PlayerSpriter::sp1;
sf::Sprite PlayerSpriter::sp2;
sf::Sprite PlayerSpriter::sp3;
// etc...
void Resources::loadResources() {
// …
}
This is in addition to what you already have in your header.
NOTE: From your edit, this would occur outside any function.

Getting errors when compiling game with GCC. (error: changes meaning of ”Screen” from ”class Screen” [-fpermissive])

Screen.h
#ifndef SCREEN_H
#define SCREEN_H
#include <SFML/Graphics.hpp>
class Screen
{
public:
virtual void handleInput(sf::RenderWindow& window) = 0;
virtual void update(sf::Time delta) = 0;
virtual void render(sf::RenderWindow& window) = 0;
};
#endif
Game.h
#ifndef GAME_H
#define GAME_H
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <vector>
#include <memory>
#include "Screen.h"
namespace sfSnake
{
class Game
{
public:
Game();
void run();
void handleInput();
void update(sf::Time delta);
void render();
static const int Width = 640;
static const int Height = 480;
static std::shared_ptr<Screen> Screen;
private:
sf::RenderWindow window_;
sf::Music bgMusic_;
static const sf::Time TimePerFrame;
};
}
#endif
I have problems with these two headers. The code compiles fine with visual studio but won't with GCC.
I get the errors:
Description Resource Path Location Type
error: changes meaning of ”Screen” from ”class Screen” [-fpermissive] Screen.h /Snake line 6 C/C++ Problem
error: declaration of ”std::shared_ptr<Screen> sfSnake::Game::Screen” [-fpermissive] Game.h /Snake line 28 C/C++ Problem
I have looked around for a while now and haven't found a solution. I really feel lost...
Also this is not my code it was written by the user 'jh1997sa' on reddit. The source on github. His thread on reddit.
You haven't named your platform, but I presume it's some flavor of Linux running X11. If so, this is most likely a name conflict with the Screen struct defined in X11/Xlib.h. SFML is almost certainly using Xlib behind the scenes to interact with the windowng system.
Because Xlib is a C library, all symbols it defines live in the global namespace. Fortunately in C++ you have the option of putting your Screen class in a namespace of your choosing. As long as you then refer to it by its fully qualified name, you can avoid the name clash.
From what I understand, if you are trying to compile on a linux system you should be using g++ to compile instead of gcc.

SDL with classes

Hello am having a problem with my IDE Visual Studio 2012. I have started to learn SDL so am quite new to it and I am trying apply good structure when using SDL. The problems lays when I start using SDL with classes. It works fine if I type everything in main. I don't know what am doing wrong can you help here are the errors
1>MSVCRT.lib(MSVCR110.dll) : error LNK2005: _exit already defined in LIBCMT.lib (crt0dat.obj)
1>MSVCRT.lib(MSVCR110.dll) : error LNK2005: ___iob_func already defined in LIBCMT.lib(_file.obj)
1>MSVCRT.lib(MSVCR110.dll) : error LNK2005: _fclose already defined in LIBCMT.lib(fclose.obj)
1>LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
1>C:\Users\User\documents\visual studio 2012\Projects\Nebula\Debug\Nebula.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Here is my code if there is something wrong
Main
#include <SDL.h>
#include "System.h"
int main(int argc, char* argv[])
{
System RedObject;
RedObject.SetUp();
SDL_Quit();
return 0;
}
Second file.
#include "System.h"
System::System()
{
}
System::~System()
{
}
void System::SetUp()
{
SDL_Init(SDL_INIT_EVERYTHING); // The SDL Set up bit.
SDL_Surface * screen;
SDL_WM_SetCaption("Window Name", NULL);
fullscreen = false;
if(fullscreen == true)
{
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_FULLSCREEN);
}
else
{
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
}
bool running = true;
while(running)
{
SDL_Event Event;
while(SDL_PollEvent(&Event))
{
switch(Event.type)
case SDL_QUIT:
running = false;
break;
}
SDL_Flip(screen);
}
}
Second Files Header:
#ifndef SYSTEM_H
#define SYSTEM_H
#include <SDL.h>
class System
{
private:
int SHeight, SLenght;
bool fullscreen;
public:
System();
~System();
void SetUp();
};
#endif
Also I have set up the IDE code generator to run on Multi-threaded DLL (/MD) I don't know if that is the problem. Sorry if this question has been already answered I could find an answer. Thank you in advance.
I think the problem is that Visual Studio's .NET Framework uses System as a root-level namespace, so you're probably running into a name conflict. Try naming your class something other than System.
I figured it out! This problem come up when you build objects with SDL and there are conflicts of two lib's you need to ignore one of them. You need to ignore LIBCMT.lib. If you don't know how to here are the steps:
Open the project's Property Pages.
Click the Linker folder.
Click the Input page.
Select the Ignore Specific Default Libraries and go into the edit and put in LIBCMT.lib press ok then apply setting and you should be good to go.
I hope this saves you days of pain :)

Error C2061 In visual studio

I try to reference a struct from another class in my code and it gives me an error, saying I have a syntax problem.
#pragma once
#include "Definitions.h"
#include "GV.h"
#include "UI.h"
#include "Tile.h"
#include "Item.h"
class Figure {
public:
//Figure index
struct FIGURE_TYPE {
//Where to crop the image from
SDL_Rect crop;
int x;
int y;
};
//The game figure
FIGURE_TYPE figure_index[FIGURE_COUNT];
//The figure array
int figure_array[MAP_HEIGHT / 64][MAP_WIDTH / 64];
//Functions
Figure ( void );
bool draw_figures ( SDL_Surface* screen, SDL_Surface* figures, SDL_Rect camera, Figure::FIGURE_TYPE figure_spec[FIGURE_COUNT] );
};
That's the struct in Figure.h,
#pragma once
#include "Definitions.h"
#include "GV.h"
#include "Tile.h"
#include "Item.h"
#include "Figure.h"
class UI {
public:
UI ( void );
void set_camera ( SDL_Rect& camera, Figure::FIGURE_TYPE figure_spec[FIGURE_COUNT] );
bool draw_map ( SDL_Surface* screen, SDL_Rect& camera, SDL_Surface* tiles, SDL_Surface* figures, Figure::FIGURE_TYPE figure_spec[FIGURE_COUNT] );
bool draw_status ( void );
};
And that is where I reference it, from another header file called UI.h. I know there is a problem with referencing structures, I just don't know how to fix it. Simple problem, any one wanna help?
The problem is not that Figure Type is declared outside of Figure.h, or that it is private as opposed to public.
Error Reports
Error 1 error C2653: 'Figure' : is not a class or namespace name c:\users\jim\documents\c++\roguelike\roguelike\ui.h 13 1 roguelike
Error 3 error C2653: 'Figure' : is not a class or namespace name c:\users\jim\documents\c++\roguelike\roguelike\ui.h 14 1 roguelike
Error 2 error C2061: syntax error : identifier 'FIGURE_TYPE' c:\users\jim\documents\c++\roguelike\roguelike\ui.h 13 1 roguelike
Error 4 error C2061: syntax error : identifier 'FIGURE_TYPE' c:\users\jim\documents\c++\roguelike\roguelike\ui.h 14 1 roguelike
You have a circular dependency: UI.h depends on Figure.h, and Figure.h depends on UI.h. You need to break the circular dependency by removing the #include of one file in the other. In this case, since I don't see anything in Figure.h using anything in UI.h, you should just remove the #include "UI.h" from Figure.h and be all set.
Your syntax is fine.
What is not fine is that you have a circular dependency between your headers, and this is breaking your #includes.
In this case, it's leading to Figure not being visible from within "UI.h"; even though your syntax is correct, this causes the errors you've seen because "UI.h" doesn't know that your syntax is correct, because it doesn't know what Figure is.
Do not have circular dependencies. Use forward declarations where possible to help you.