I can't link my opengl program to math3d.h - c++

I was writing an OpenGL program and it happens that I have a problem with linking with math3d.h.
I am using Ubuntu and g++.
The thing is that I didn't install the package for the math3d because I got the header file and a cpp file from the net with OpenGL superbible. So I just copied the header file and .cpp file to the local directory and did
#include "math3d.h"
But the thing is that I used to use switches to link the other header files like gl.h, glu.h ,glut.h by giving.
g++ test.cpp -lGL -lGLU -lglut.
But I don't know what to give for math3d. I get an error saying undefined reference to the functions. This error I used to get when I don't give -lGL etc. for the functions in those respective libraries.
I am totally stuck here and I don't know what to do and without this I cannot go forward.

You don't link header files. You include them, and then link the object files produced by the *.cpp files together.
Short answer
g++ test.cpp math3d.cpp -lGL -lGLU -lglut
... and it works.
Long Answer
What you are lacking is any kind of build system (read up on Makefile). You need to first build the math3d.cpp, then your test program.
Sample Makefile:
CC=g++
CFLAGS=-c -Wall
LDFLAGS=-lGL -lGLU -lglut
SOURCES=test.cpp math3d.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=test
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
Well, y'know, this one might even work :>

Need to compile math3d.cpp as well:
g++ test.cpp math3d.cpp -lGL -lGLU -lglut

There are a couple of problems with your question:
You don't link to header files - you include header files, you link object files or libraries
Besides including the appropriate header files you need to link in the library - you said you copied the .cpp file from the 'local directory' does this mean you added one of the .cpp files from the OpenGL project into your project? This can work if you make sure you get all the .cpp files you need (the functions you use that are declared in 'math3d.h' may be implemented across a number of .cpp files). However, it is MUCH better to build openGL as a library and link against that. You may want to consult the OpenGL documentation to see how to build it.

Related

Compiling larger C++ projects in VSCode

Im trying to compile a C++ project using MinGW and can compile a simple main.cpp file with hello world without problems using g++ main.cpp -o main and also with external libraries using main.cpp extlib.cpp -o main.
But say im working on a rather large project with 10s of .cpp files organised inside of different files, how can I get the compiler to find all the cpp files that are needed? I know i can use main.cpp libs/*.cpp -o main but this will only compile all the source files inside of libs but not inside folders in libs.
Ive looked into make and cmake but dont understand how those automate the process if you still have to manually enter the directories. Is there no way to simply hit compile or at least a command line command to compile all the needed files inside a directory? This seems to work with #include without issues?
If you want to stick with MinGW and GNU Make I would probably use a Makefile that looks something like this to start with. You basically only need to maintain the srcs-variable by adding your source-files there. Usually you can use the wildcard-function for this if you have sub dirs. The rest of the Makefile (which can be left alone) sets up a build of an executable main.exe that depends on all the object-files. I also included dependency-handling via the deps-variable and the compiler flag -MMD which comes in handy when the project grows.
srcs := $(wildcard *.cpp) $(wildcard dir1/*.cpp) $(wildcard dir2/*.cpp)
objs := $(srcs:.cpp=.o)
deps := $(objs:.o=.d)
app := main.exe
CXXFLAGS := -MMD -Og -g -Wall -Werror -Wpedantic -std=c++2a
$(app): $(objs)
$(CXX) $(LDFLAGS) -o $# $^ $(LDLIBS)
-include $(deps)
.PHONY: clean
clean:
rm -f $(objs) $(deps)
I use CMake for simple projects.
Here's the simplest example I came with (CMakeLists.txt to put along your main.cpp in the root of your project):
cmake_minimum_required(VERSION 3.1)
SET(CMAKE_APP_NAME "Project")
project (${CMAKE_APP_NAME})
# list here your directories
INCLUDE_DIRECTORIES(dir1)
INCLUDE_DIRECTORIES(dir2)
# add an executable and list all files to compile
add_executable(${CMAKE_APP_NAME} main.cpp
dir1/file1.cpp
dir1/file1.h
dir2/file2.h
dir2/file2.cpp
)
Once your project becomes more complex, you could use file(GLOB*) to avoid writing all the files.
Overall, the most "automated" way to build a larger project is to use CMake. Keep learning it. You can use file(GLOB) to avoid listing every file in CMakeLists.txt. This is not recommended (see discussion here), but I do it anyway and never had any issues.

Undefined reference to function in linux makefile

I have a problem with make compiling on linux.... getting error about undefined reference.
Briefly, we use FLUID, a GUI designer. The codes from FLUID are inside the class MyProjectGUI. I wrote a callback function outside of FLUID, which is called from within functions of MyProjectGUI.
MyProjectGUI.h has include to callback function header:
#include "students/stu_callbacks.h"
MyProjectGUI.cxx:
#include "MyProjectGUI.h"
....
void MyProjectGUI::somecallback_i([args])
{ ...
brandNewCallback();
...
}
In "students/stu_callbacks.h":
#include "../main_utils.h"
void brandNewCallback();
Then in "students/stu_callbacks.cpp":
#include "stu_callbacks.h"
void brandNewCallback()
{ ...stuffs...
}
Makefile I used:
VXLDIR = [....]
CFLAGS = [...VXL header paths...] -Wno-deprecated -DJPEG_LIB_VERSION=80
CC = g++
#fltk library paths and libraries
FLTKLDFLAGS = -L/local/lib -L/usr/lib/x86_64-linux-gnu/ -Wl,-rpath,/local/lib -lfltk_gl -lGLU -lGL -lfltk -L/usr/X11R6/lib -lpthread -lm -lXext -lX11 -lsupc++
#vxl library paths and libraries
VXLLDFLAGS = -L$(VXLDIR)/bin/lib -lvil -lvnl_algo -lvnl_io -lvnl -lv3p_netlib -lvcl -lvul -lpng -ltiff -lopenjpeg2 -lgeotiff
LDFLAGS = -lstdc++ $(FLTKLDFLAGS) $(VXLLDFLAGS)
FLUID = fluid
%.o: %.cxx
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $# $<
%.cxx: %.fl
$(FLUID) -c $<
BASIC_OBJ = gl/glutils.o gl/Texture.o main.o file/load_image.o
IMDRAW_OBJ = [...imdraw...]
UI_OBJ = MyProjectUI.o
UI_CPP = MyProjectUI.cxx MyProjectUI.h
GRAPHIC_OBJ = graphics/graphics.o
STUDENT_OBJ = graphics/graphics_algorithm.o
imdraw-code/myproject: $(UI_CPP) $(BASIC_OBJ) $(UI_OBJ) $(STUDENT_OBJ) $(GRAPHIC_OBJ) $(IMDRAW_OBJ)
$(CC) -o ../bin/viscomp $(BASIC_OBJ) $(UI_OBJ) $(GRAPHIC_OBJ) $(IMDRAW_OBJ) $(STUDENT_OBJ) $(LDFLAGS)
Compiling with this Makefile under Linux at university gets error about undefined reference to function "brandNewCallback()", from MyProjectGUI.cxx. Note it did NOT complain about not finding "students/stu_callbacks.h", so the header should be read.
The exact same code compiled without issue using Visual Studio.
The structure of this is similar to that "file/load_image" listed in the Makefile, ("load_image" function is called from within MyProjectGUI, the includes are setup very similarly)... yet that one doesn't cause any issue.
Tried adding "students/stu_callbacks.o" to "STUDENT_OBJ in Makefile, then I got fatal errors about not finding the includes within the "main_utils.h" include of stud_callbacks.h, which doesn't make sense at all. Other files source "main_utils.h" without issue.
Tried calling the func as ::brandNewCallback();, still same error.
The immediate workaround is to put all this callback code within MyProjectGUI...
I don't get how I can't get this to work as it, and it bugs the hack out of me. I already spent 5+hours last night trying/googling... so any help will be greatly appreciated!
Your rule %.o: %.cxx instructs Make how to compile source files with extension .cxx. However, your
own C++ source file is students/stu_callbacks.cpp. You did not provide rule to make object file(s) out of .cpp files, or to make object file out of the students/stu_callbacks.cpp file. Therefore, your stu_callbacks were not linked in, and naturally linker complains.
The problem with header file is similar - C++ compiler probably does not have include path set.

Eclipse CDT shows some errors, but the project is successfully built

I have a project of multiple source and header files and I wrote my own Makefile by specifying the required external libraries and headers (the directory containing the OpenCV header files and the directory containing the OpenCV libraries).
When I start compiling the project, it is compiled without any errors. However when writing the code, Eclipse reports errors on some functions of OpenCV, as if it did not know these functions. Since I have listed all the required headers and libraries in the makefile (see below), why does this problem occur?
CXXFLAGS = -O3 -g -Wall -fmessage-length=0 -I./include -I/usr/local/include/opencv
LIBS = -L/usr/local/lib -lcv -lcvaux -lhighgui -lcxcore -limgproc
MAIN_PROG_OBJS = MainProgram.o src/Utilities.o src/ImageStream.o src/VideoStream.o
MAIN_PROG_TARGET = MainProgram
TEST_PROG_OBJS = TestProgram.o src/Utilities.o
TEST_PROG_TARGET = TestProgram
$(MAIN_PROG_TARGET): $(MAIN_PROG_OBJS)
$(CXX) -o $(MAIN_PROG_TARGET) $(MAIN_PROG_OBJS) $(LIBS)
$(TEST_PROG_TARGET): $(TEST_PROG_OBJS)
$(CXX) -o $(TEST_PROG_TARGET) $(TEST_PROG_OBJS) $(LIBS)
all: $(MAIN_PROG_TARGET) $(TEST_PROG_TARGET)
clean:
rm -f $(MAIN_PROG_OBJS) $(MAIN_PROG_TARGET) $(TEST_PROG_OBJS) $(TEST_PROG_TARGET)
Eclipse tries to find the errors quickly, but does not update all the time. Do not rely only on the error messages of Eclipse.
For example if you have just added a file to your project, Eclipse might still be telling you that it could not find the file while in fact it is there.
Use Project -> Clean to update the error checking of Eclipse.

Include a .cpp file using Make

I want to include GeometricRecognizer.cpp into run.cpp , I have the solution(below mentioned) for CMake which works, i want to include it in another project which uses make the format of makefile is also given below .How to add the dependency of GeometricRecognizer.cpp using makefile ?
CMake:
ADD_EXECUTABLE(run run.cpp lib/GeometricRecognizer.cpp)
TARGET_LINK_LIBRARIES(run)
Make :
INCS_GTK=-I/usr/include/gtk-2.0 -I/usr/include/glib-2.0 -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0
INCS=-I/usr/include/freetype2 -I/usr/include/mysql -Iframeworks ${INCS_GTK}
LDLIBS=-lconfig++ -lcxcore -lcv -lGL -lGLU -lglut
This line in a CMake file does not include a cpp file in another cpp file:
ADD_EXECUTABLE(run a.cpp b.cpp)
It creates an executable target called run which is the result of compiling a.cpp and b.cpp and linking those files.
In your Makefile the following lines:
MAINCXX=${shell find -name '*.cxx'}
TARGETS=${MAINCXX:%.cxx=%}
Are the two important lines which actually setup the executable targets to compile and which source files they are created from. As can be seen in those two lines MAINCXX is just a list of all files *.cxx in the source tree and TARGETS will be the same list just without the .cxx part (so if MAINCXX=run.cxx then it will be TARGETS=run.cxx)
Your makefile seems to be heavily designed to support that specific usecase, also the real Make magic happens in the last line of Makefile where it includes another Makefile.
You need to look at the file named generic.mk and understand how it is designed. If you just want to add another target you can add the following:
run: run.cpp lib/GeometricRecognizer.cpp
g++ -o run $(DEFINES) $(INCS) $(WARNINGS) run.cpp lib/GeometricRecognizer.cpp
The listing of source files can be replaced by a builtin variable in GNU Make.

Makefile using a library

I have made a project in Xcode who implements an algorithm in just 1 c++ file. To compile it needs an library who is in a directory called libgambit in an other directory. The directory structure looks like this:
lib/
libgambit/libgambit.cc
libgambit.h
game.cc
game.h
...
src/Game\ Theoretic\ Analysis/convertion.cc
convertion.h
Makefile
So what I need is a makefile who first builds everything whats in libgambit and uses the object files who result from that to build and link convertion.cc. The executable should then be in the same folder as the makefile.
It seems a pretty easy question but I'm suffering on it for 2 days now.
There's more than one way to do it. Here is a crude but effective way:
LIBSRCS := $(wildcard $(PATHTOLIB)/lib/libgambit/*.cc)
LIBOBJS := $(LIBSRCS:.cc=.o)
convertion: convertion.o $(LIBOBJS)
#g++ -Wall $^ -o $#
%.o: %.cc
#g++ -Wall -Ilib/libgambit -c $< -o $#
This does not track dependencies very well (if you alter a header file, Make won't notice that some objects must be rebuilt), but it is good enough for now. Let us know if you want to try advanced dependency handling.
You can use the Makefile developed here. It allows you to add new files and directories to the build without changing the Makefile.