Compiling Multiple C++ OpenGL - c++

I'm writing a simple C++, opengl program and I'm having difficulty producing the executable from the object files. I can create object files of each .cpp without error using:
g++ -c filename.cpp ----> filename.o
Each .cpp creates an object, which leads me to assume that it is finding the opengl headers fine, but when I attempt to create the executable from the objects, it outputs:
g++ -o OUTPUT Main.o Time.o Map.o Vehicle.o
Main.o: In function `init()':
Main.cpp:(.text+0x12a): undefined reference to `glEnable'
Main.cpp:(.text+0x134): undefined reference to `glShadeModel'
Main.cpp:(.text+0x14d): undefined reference to `glViewport'
Main.cpp:(.text+0x157): undefined reference to `glMatrixMode'
Main.cpp:(.text+0x15c): undefined reference to `glLoadIdentity'
I realize that the g++ is telling me that it can't find the OpenGL functions anywhere, which means it is not linking to glu.h, gl.h etc. But why do the objects files get created without similar error, but I can't make my executable? Wouldn't the object files suffer from the same linking error as the .exe? I've tried -I and g++ -o RUN Time.o Main.o Map.o Vehicle.o -L/usr/include/GL/ -lGL -lGLU, and I've also verified the path of the OpenGL directory.
The headers of each files are below:
libgl.h:
#ifndef LIBGL_H
#define LIBGL_H
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include "Time.h"
#include "Link.h"
#endif
Time.h:
#ifndef TIME_H
#define TIME_H
extern float GLOBAL_TIME;
#endif
Map.h
#ifndef MAP_H
#define MAP_H
#include "libgl.h"
....
#endif
Vehicle.h:
#ifndef VEHICLE_H
#define VEHICLE_H
#include "libgl.h"
...
#endif
Main.cpp:
#include "libgl.h"
#include "Map.h"
#include "Vehicle.h"
...
There is something that I'm missing regarding my headers/linking and compiling, if anybody has any suggestions I would be much obliged.

You need to link with the OpenGL libraries: probably pass -lgl to the last g++ invocation.
If your system has pkg-config you can use pkg-config --cflags --libs gl to get all the right flags.
For future reference, an "undefined reference" is a linker error, and it always means the same thing: you missed an object file or a library. It only shows up when linking, never when simply compiling (i.e. using -c)

Related

C++ Compiles in Windows, multiple definition error in Linux

let me start by saying that I am not the best C++ and I know very little in ways of Linux. For a class project we had to implement a heap so I coded everything on my Windows PC assuming I could just upload the files to the Linux repository the school has. [Perhaps this is where I went wrong and this cannot be done this simply.] My codes compiles and clears all test cases provided on my Windows pc. When I upload the files to Linux, I created a makefile and when I use the make command I get back a laundry list of multiple definition errors. One error per function that I am using. I have done some searching and I am more confused then when I started.
My files are: main.cpp, main.h, heap.cpp, heap.h, util.cpp, and util.h.
I think the issue is with my include statements but I am not 100% sure.
Here is an example of the files.
main.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include "util.cpp"
#include "heap.cpp"
#include <fstream>
using namespace std;
main.h is blank.
heap.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "heap.h"
#include <cmath>
#include <math.h>
using namespace std;
//expanded functions found in the heap.h file
heap.h
//2 structs
//9 functions
util.cpp
#include <iostream> //needed to use basic inputs/outputs
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
using namespace std;
//expanded functions found in util.h
util.h
//1 function
Between heap.h and util.h I have 10 function and upon running the make command I get a warning about all ten:
multiple definition of 'FUNCTIONNAME'
main.o:main.cpp:(.text+0x1b7): first defined here
I am assuming the 0x1b7 is a memory location because they are each different.
Any help would be greatly appreciated.
You haven't shown the Makefile, but most likely, it includes this or a similar rule
program: main.o heap.o util.o
$(CXX) $(CXXFLAGS) -o program main.o heap.o util.o
What happens now, the compiler builds the three object files main.o, heap.o and util.o. Next the object files are linked together to build program.
The linker sees definitions of the various functions defined in both main.o and heap.o, or main.o and util.o respectively. This is why it complains about "multiple definition of 'FUNCTIONNAME'"
Why are these functions defined more than once?
When you include a file into another source, it is as if you copy the contents at the location of the #include. This means a function defined in heap.cpp:
void create_heap(int size)
{
// create a heap ...
}
is copied verbatim into main.cpp where the line
#include "heap.cpp"
is.
Because heap.cpp has the definition of create_heap() and main.cpp #includes the contents of heap.cpp, both contain their own copy of create_heap(). Now you compile both heap.o and main.o, and link them together. Each object file has a copy of create_heap() and this is where the linker is confused and complains
multiple definition of 'create_heap'
main.o:main.cpp:(.text+0x1b7): first defined here
To fix this, simply replace the lines including the cpp sources, e.g.
#include "util.cpp"
#include "heap.cpp"
with their respective header files
#include "util.h"
#include "heap.h"
Only keep the function definitions relevant to main.cpp, nothing else. Now main.cpp has no function definitions belonging to util.cpp or heap.cpp, and the linker errors are gone.
Presumably, this worked on Windows, because only main.cpp was included in the project file, and so only one definition (from main.o) was in the resulting executable.
If you had included all sources as in the Linux Makefile, the error could be seen in Windows as well.

Linking GLEW libraries when compiling with MinGW

I'm trying to write an OpenGL program which I'm compiling through MinGW. I've managed to successfully link OpenGL, GLUT, GLFW and GLM to my main.cpp file. Given the following headers:
#include "GL/glut.h"
#include "GLFW/glfw3.h"
#include "GL/glew.h"
#include "glm/vec3.hpp"
And the following cmd line:
g++ -o leaf.exe -Wall physics.cpp -mwindows lib/glut32.lib -lopengl32 -lglu32 -lglfw3dll -lglew32 -IC:/MinGW/include/GL
I manage to get it to compile successfully. However, when placing the .a files in MinGW/lib, the .dll file in source folder and the .h file in C:\MinGW\include and adding
#include "GL/glew.h"
With the following command line
g++ -o leaf.exe -Wall physics.cpp -mwindows lib/glut32.lib -lopengl32 -lglu32 -lglfw3dll -lglew32 -IC:/MinGW/include/GL
Then I get a long list of errors including:
In file included from physics.cpp:6:0:
c:\mingw\include\gl\glew.h:85:2: error: #error gl.h included before glew.h
#error gl.h included before glew.h
In file included from physics.cpp:6:0:
c:\mingw\include\gl\glew.h:1814:94: error: 'GLchar' does not name a type
typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name);
My first time trying to make something without using Visual Studio or Eclipse. Been trying lots of fixes for it I've found here but nothing concrete.
Thanks for reading this far!
You need to reorder your includes:
#include "GL/glew.h"
#include "GL/glut.h"
#include "GLFW/glfw3.h"
#include "glm/vec3.hpp"
GLFW (and GLUT?) automatically include GL.h, which is what GLEW is complaining about. Not sure why you're using GLUT and GLFW in the same build, they don't exactly go together...

C++ SDL2 - Incomprehensible link error

I setup SDL2 under C++ CDT Eclipse.
I added the include path "........SDL2-2.0.3\i686-w64-mingw32\include", the library path "........SDL2-2.0.3\i686-w64-mingw32\lib" and added the libraries 1."mingw32" 2."SDL2main" 3."SDL2".
So now, if I add a main.cpp with this content:
#include <SDL.h>
int main(int argc, char* args[])
{
return 0;
}
I can build the project fine, but if I use this:
#include <SDL.h>
int main()
{
return 0;
}
The project can't build and I get this error:
Info: Internal Builder is used for build g++ "-IO:\Eclipse CDT
Workspace\SDL OpenGL Lab\Libraries\SDL2\include\SDL2" -O0 -g3
-Wall -c -fmessage-length=0 -o main.o "..\main.cpp" g++ "-LO:\Eclipse CDT Workspace\SDL OpenGL Lab\Libraries\SDL2\lib" -o
"SDL OpenGL Lab.exe" main.o -lmingw32 -lSDL2main -lSDL2 O:\Eclipse
CDT Workspace\SDL OpenGL
Lab\Libraries\SDL2\lib/libSDL2main.a(SDL_windows_main.o): In function
console_main':
/Users/slouken/release/SDL/SDL2-2.0.3-source/foo-x86/../src/main/windows/SDL_windows_main.c:140:
undefined reference toSDL_main' collect2.exe: error: ld returned 1
exit status
I simply wonder me why this error is depending on my main method, I want to use the main method I want.
Why this is so, how I can fix this ?
Sorry, you're stuck with it. I also preferred a simpler main, but SDL doesn't support it.
Here's a little more on SDL and main in the Windows world. It doesn't say why you need their version of main -- but you do.
I get "Undefined reference to 'SDL_main'" ...
Make sure that you are declaring main() as:
#include "SDL.h"
int main(int argc, char *argv[])
https://wiki.libsdl.org/FAQWindows
I had the same problem and had to go through a lot of manipulations.
What I have found is the simple line #define SDL_MAIN_HANDLED before calling SDL.h. SDL has his own main that's why, I think.
For example, in my .h files, I write everytime this :
#include <stdio.h>
#include <stdlib.h>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

g++ "does not name a type" error

I'm working on a little project for my structures class and have run into an issue even the TA couldn't figure out. It was suggested that I post about it on here and I might get some help. So here it goes:
Overview:
I'm using g++ to compile a project containing a number of header (.h) files along with their corresponding implementation (.cpp) files. The project involves 3 separate structures and running a timing comparison between them. The structures being implemented and compared are a binary min heap, a leftist heap, and a skew heap. The min heap implementation is complete and is compiling just fine. However now that I'm moving onto the other structures I'm running into what I assume (I know) is a compiler error.
The Issue
I'm fleshing out the stub files for the leftist heap and have hit a brick wall as far as the compiler is concerned. In particular I'm getting an error that reads:
leftHeap.cpp:15:1: error: ‘LeftistHeap’ does not name a type
The Code
Here's a look at relevant code:
leftHeap.h
#ifdef LEFTHEAP_H
#define LEFTHEAP_H
class LeftistHeap{
public:
int *root;
LeftistHeap();
~LeftistHeap();
};
#endif
leftHeap.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdio.h>
#include <math.h>
#include "leftHeap.h"
using namespace std;
//Constuctor
LeftistHeap::LeftistHeap(){
root = NULL;
}
The only other place that leftHeap.h is included is in the main.cpp
main.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <stdio.h>
#include <math.h>
#include "minHeap.h"
#include "leftHeap.h"
#include "skewHeap.h"
using namespace std;
int main(){
...
here's the makefile I'm using:
makefile
all: lab10
lab10: comparison.o minHeap.o leftHeap.o skewHeap.o
g++ comparison.o minHeap.o leftHeap.o skewHeap.o -o lab10
comparison.o: comparison.cpp
g++ -c comparison.cpp
minHeap.o: minHeap.h minHeap.cpp
g++ -c minHeap.h minHeap.cpp
leftHeap.o: leftHeap.h leftHeap.cpp
g++ -c leftHeap.h leftHeap.cpp
skewHeap.o: skewHeap.h skewHeap.cpp
g++ -c skewHeap.h skewHeap.cpp
clean:
rm lab10 *.o
and just to be extra thorough I've also tried a more minimalist makefile
makefile (2)
test:
g++ minHeap.h leftHeap.h skewHeap.h comparison.cpp minHeap.cpp leftHeap.cpp skewHeap.cpp -o lab10
clean:
rm lab10 *.o
I hope that's not info overload. Please let me know if anyone has any ideas on this. I've looked at the other g++ "does not name a type" issues on here (and a couple of full page of google searches as well) but haven't found anything that may account for this. I have this sneaking suspicion that it may be something simple I've overlooked but any help would be greatly appreciated.
Thanks!
Look at your include guard really carefully: #ifdef LEFTHEAP_H.
This is just a typo (assuming it is transcribed accurately):
#ifdef LEFTHEAP_H
#define LEFTHEAP_H
in leftHeap.h should be #ifndef
#ifndef LEFTHEAP_H
#define LEFTHEAP_H

Headers not being recognised

The Background
I have the following source code
#include <libubuntuone-1.0/u1-music-store.h>
#include <libsyncdaemon-1.0/libsyncdaemon/libsyncdaemon.h>
static void
get_credentials (U1MusicStore *music_store,
gchar **oauth_consumer_token,
gchar **oauth_consumer_secret,
gchar **oauth_token,
gchar **oauth_token_secret)
{
SyncdaemonCredentials *credentials;
*oauth_consumer_token = *oauth_consumer_secret = *oauth_token = *oauth_token_secret = NULL;
*oauth_consumer_token = g_strdup (syncdaemon_credentials_get_consumer_key (credentials));
*oauth_consumer_secret = g_strdup (syncdaemon_credentials_get_consumer_secret (credentials));
*oauth_token = g_strdup (syncdaemon_credentials_get_token (credentials));
*oauth_consumer_secret = g_strdup (syncdaemon_credentials_get_token_secret (credentials));
}
int main()
{
return 0;
}
and I am compiling it with the following makefile
main: main.o
g++ main.o -o main
main.o: main.cpp
g++ -c main.cpp `pkg-config --cflags --libs gtk+-2.0`
I need to include the pkg-config option since the u1-music-store.h header tried to included gtk/gtk.h, but the compiler isn't able to find it on it's own.
libsyncdaemon.h is a meta-header whose only purpose is to include a larger list of headers, which can be seen below
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-authentication.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-config-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-credentials.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-daemon.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-events-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-file-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-filesystem-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-folder-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-folders-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-publicfiles-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-share-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-status-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-status-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-transfer-info.h>
My problem
Whenever I try to compile my code, I get the following error:
main.o: In function `get_credentials(_U1MusicStore*, char**, char**, char**, char**)':
main.cpp:(.text+0x34): undefined reference to `syncdaemon_credentials_get_consumer_key'
main.cpp:(.text+0x3c): undefined reference to `g_strdup'
main.cpp:(.text+0x4e): undefined reference to `syncdaemon_credentials_get_consumer_secret'
main.cpp:(.text+0x56): undefined reference to `g_strdup'
main.cpp:(.text+0x68): undefined reference to `syncdaemon_credentials_get_token'
main.cpp:(.text+0x70): undefined reference to `g_strdup'
main.cpp:(.text+0x82): undefined reference to `syncdaemon_credentials_get_token_secret'
main.cpp:(.text+0x8a): undefined reference to `g_strdup'
collect2: ld returned 1 exit status
make: *** [main] Error
Using grep, I've tracked down the four syncdaemon_credentials_get_* functions to syncdaemon-credentials.h, which I would expect the compiler to be able to find since it's listed in libsyncdaemon.h, but for some reason that's not happening. I'm assuming it's for the reason that u1-music-store.h was unable to find gtk/gtk.h that compelled me to use the pkg-config option in my makefile, but I'm having trouble understanding why this is even the case to begin with. If the file's #included, I would expect it to be included by the compiler.
Using grep again I was able to track down g_strdup to a number of headers, but I also discovered that when I replaced by makefile with the single command
g++ main.cpp -o main `pkg-config --cflags --libs gtk+-2.0`
I can eliminate the g_strdup warning, and I'm just left with the function errors.
My question
There are two things I'm looking to know here:
What should my makefile look like in order to solve my specific problem
What is the general solution to my problem? I'm guessing it's something to do with daisy-chaining #include directives together, and having to use pkg-config to fix that, but I'm not sure.
You need to link against libsyncdaemon.so. Get the appropriate arguments from pkg-config ... libsyncdaemon-1.0.
You need to link against libraries that export the required symbols. If there is a .pc file then you can use it to get the appropriate arguments.
"Unresolved external symbol" (MSVC) and "undefined reference to" (GCC) mean that the compiler found the declarations but the linker couldn't find the definitions.
This either means that you forgot to compile and/or link against a .cpp or that you forgot to link against an external library (.lib (Windows) / .a (Unix/Linux)) or object file (.o) which contains said definitions.