error makefile C- opengl - c

I am trying to compile a .c file containing c-code for opengl.
But I keep getting the following error:
Interesting question.
undefined reference to 'glClear'
undefined reference to 'gluLookAt'
undefined reference to 'glLoadIdentity'
undefined reference to 'glColor3f'
undefined reference to 'glLineWidth'
undefined reference to 'glBegin'
undefined reference to 'glVertex3d'
undefined reference to 'glEnd'
etc...
I am pretty sure there is nothing wrong with my source code as it is example code that has been provided to us.
the headers i included:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
How could I fix this issue?
FYI: I am compiling this on ubuntu

Your problem lies here:
my3DTest: clean $(OBJS)
LDOPTS=\
cc -o my3DTest $(CFLAGS) $(OBJS) $(LIBPATH) $(LIBS)
the variable LDOPTS assignment is continued into the next line, due to the backslash (\), thereby your cc command is just assigned to that variable. Once that's done make continues by using its standard implicit target rules to build the binary. But since you didn't specify the linker options in a variable that make will use for that implicit rule, it will try to link without these variables.
Makefile, assuming that the sourcefile is names vlucht.c.
Important Notice: Indentation and whitespace does matter in a Makefile. Improper indentation will corrupt the Makefile!
LDLIBS = -lglut -lGLU -lGL -lXt -lXext -lm
EXE = vlucht
OBJS = vlucht.o
.PHONY: clean
all: $(EXE)
$(EXE): $(OBJS)
clean:
-$(RM) -f $(EXE) $(OBJS)

Related

Easy gnu make makefile rule to build of GCC executable from multiple source files

I'm trying to make a simple as possible make file that uses the math library (fmax below, the rest is C cruft for this examlpe):
easy.c:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, const char *argv[]) {
double x=atof(argv[1]);
double y=atof(argv[2]);
double z=fmax(x,y);
printf("max(%f,%f)=%f\n",x,y,z);
return 0;
}
Makefile:
CFLAGS=-g
LDFLAGS=-lm
easy : easy.c
However this creates a link error (missing fmax). This is because make places the LDFLAGS first in the compile line:
> make easy
cc -g -lm easy.c -o easy
/usr/bin/ld: /tmp/ccmN5G9c.o: in function `main':
/home/user/projects/easy/easy.c:8: undefined reference to `fmax'
collect2: error: ld returned 1 exit status
make: *** [<builtin>: easy] Error 1
Of course, if I explicitly put the LDFLAGS at the end using an explicit rule, it works:
CFLAGS=-g
LDFLAGS=-lm
easy : easy.c
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
Of course, understanding the Makefile is not nearly so easy now. Does anyone have a reason why the default rule does not put the link line at the end? Or is there an "easy" make that does allow a newcomer to link a number of source files into one executable (no lingering .o files)?
You should be using LDLIBS not LDFLAGS. LDFLAGS is for linker flags (such as -L). LDLIBS is for linker libraries (such as -lm).
If you investigate the default rules (make -pf/dev/null) you'll find this one:
LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)
%: %.o
# recipe to execute (built-in):
$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $#
(Ignore LOADLIBES as that's a deprecated name). Also see the documentation for LDLIBS and LDFLAGS.

undefined reference to pthread

I want to compile a program which is using threads. I use the #include <pthread.h> library, however when I compile it using my make file I get the following errors:
file.c:(.text+0x378): undefined referece to `pthread_create`
file.c:(.text+0x3ad): undefined referece to `pthread_join`
The program run fine with the normal gcc compilator using -lpthread flag
The source of the make file that I am using:
CC=gcc
COMPILE.c=$(CC) $(CFLAGS) $(CPPFLAGS) -c
LINK.c=$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -lpthread
CFLAGS = -Wall -O -I$(dir $(LIBLAB))
TEMPFILES = core core.* *.o temp.* *.out typescript*
all:
#echo "Please compile directly the intended programs by name"
clean:
rm -f ${TEMPFILES}
I have set the -lpthread flag in the make file but is not working, what changes should I make in the make file?
Your replacement for LINK.c is wrong. You can't add libraries to this because it means they appear on the link line first.
If you'd shown us the output of make, in addition to the makefile, probably we would have seen it more quickly. Libraries like -lpthread must come at the end of the link line, after any objects that might have needed to use the library.
As I mentioned in comments, you should remove the LINK.c setting and add:
CFLAGS = -pthread
and that should be good enough. If you do need to add libraries, you should use LDLIBS like this:
LDLIBS = -lpthread
not replace the LINK.c variable.

Linking error: Undefined reference to functions that're defined in a separate file?

I'm probably forgetting something obvious that'll solve this. While there's other questions on SO with the same issue, none of the solutions have been applicable to my situation.
I have a main file, sim.c, a header file net.h, a header file friends.h, and a file with the functions, net.c. I have a makefile, which I created with gmakemake > Makefile, and its contents are very basic.
Header.mak (makefile template):
CFLAGS = -Wall -Wextra -pedantic -std=c99 -ggdb
LFLAGS = -ggdb
LDFLAGS =
Makefile relevant contents:
CPP_FILES =
C_FILES = net.c sim.c
PS_FILES =
S_FILES =
H_FILES = net.h friends.h
SOURCEFILES = $(H_FILES) $(CPP_FILES) $(C_FILES) $(S_FILES)
.PRECIOUS: $(SOURCEFILES)
OBJFILES =
#
# Main targets
#
all: net sim
net: net.o $(OBJFILES)
$(CC) $(CFLAGS) -o net net.o $(OBJFILES) $(CLIBFLAGS)
sim: sim.o $(OBJFILES)
$(CC) $(CFLAGS) -o sim sim.o $(OBJFILES) $(CLIBFLAGS)
#
# Dependencies
#
net.o: net.h
sim.o: net.h
My sim.c file contains:
#include "net.h"
#include "friends.h"
My header file contains the functions in net.c and defines them all as stubs. I copied and pasted them to create the function headers, so there shouldn't be any typos.
My net.c file contains:
#include "net.h"
Yet any time a function in sim.c tries to call a function in net.c, it errors on that line with:
"undefined reference to `function_name`".
How can I make sim.c able to access the functions in net.c?
The message undefined reference to 'function_name' implies that of all the object files you're giving to the linker, none of them has a definition for function_name. That means that either
You're not linking with net.o
net.c (as compiled) does not contain a definition for function_name -- by 'as compiled' I mean with all of the various preprocessor options you use on it.
Since you show neither your link command line nor the contents of net.c, we can't tell which is the problem.
edit
with your edit, we can see clearly that you have the first problem -- when you try to link sim, you do not include net.o on the link command line. Most commonly, you would link sim with a makefile entry like:
sim: sim.o net.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $# $^ $(LDLIBS)
or more simply just:
sim: sim.o net.o
relying on the default make actions for linking object files
For the two functions "see" each other make sure that:
Both c/cpp files are included in the makefile
Both definition(c/cpp) and declaration (h) files contains the same definition of the function: name/params/return value
The function being called must not be static.
Make sure you don't declare (or include) the same type with different structure in the source files.
That should do, unless you are using a very old complier with even more evil things that can go wrong ;)

How to compile this lib for usage?

I'm new to C programming, and I'm trying to compile this Simple training example with GCC on Ubuntu 12.10.
Looks like fann.h should not be included (as stated on the file itself), so I included fixedfann.h instead.
First attempt (without include, just to see what the compiler will ask for):
$ gcc main.c -o output
/tmp/cckKyM92.o: In function `main':
main.c:(.text+0x62): undefined reference to `fann_create_standard'
main.c:(.text+0x7a): undefined reference to `fann_set_activation_function_hidden'
main.c:(.text+0x8e): undefined reference to `fann_set_activation_function_output'
main.c:(.text+0xba): undefined reference to `fann_train_on_file'
main.c:(.text+0xce): undefined reference to `fann_save'
main.c:(.text+0xda): undefined reference to `fann_destroy'
collect2: ld returned 1 exit status
fann_create_standard is on fann.h and fann.c. As fann.h is included by fixedfann.h, and fann.h should not be included directly, I believe I have to compile fann.c and fixedfann.c, and link then (tell me if I'm doing any mistake, I'm still not familiar with this "linking" stuff).
So I did:
$ gcc fann/fixedfann.c -o fann/fixedfann.o
fann/fixedfann.c:22:20: fatal error: config.h: No such file or directory
compilation terminated.
and then I did:
$ gcc fann/fixedfann.c -o fann/fixedfann.o -include fann/include/config.h
fann/fixedfann.c:22:20: fatal error: config.h: No such file or directory
compilation terminated.
Now, why it's not finding the config.h file here?
--update
Thanks #JonathanLeffler, I could make some steps here. But now I'm stuck at:
$ gcc fann/fixedfann.c -o fann/fixedfann.o -I./fann/include/ -lm
/usr/lib/gcc/i686-linux-gnu/4.6/../../../i386-linux-gnu/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
and, with grep, I could not find any reference to main on the fann folder... Also no function _start, and I don't know who is linking this crt1.o... Any idea what's wrong here?
--update2
Ok, I got the .o files using Harmeet's Makefile, now I'm trying to link everything.
I created the main.o with gcc -c main.c, and I tried:
gcc -o output main.o fann/fixedfann.o -lm
(-lm for the libmath, that is needed) and I got:
main.c:(.text+0xba): undefined reference to `fann_train_on_file'
This fann_train_on_file is on fann_train_data.c, so I tried:
gcc -o output main.o fann/fixedfann.o fann/fann_train_data.o -lm
but I got lots of multiple definition of... errors... :/
Looks like fann_train_data.o is already included/linked, but if so, why it's not finding fann_train_on_file?
--update3
I'm still really stuck here... Any idea of which (if any) of this two lines should work?:
gcc -o output main.o hello.o fann/fixedfann.o fann/fann_train_data.o -lm
or
gcc -o output main.o hello.o fann/fixedfann.o -lm
--update for Harmeet
The output was:
$ make
gcc -L./fann -lfann main.o -o main
main.o: In function `main':
main.c:(.text+0x62): undefined reference to `fann_create_standard'
main.c:(.text+0x7a): undefined reference to `fann_set_activation_function_hidden'
main.c:(.text+0x8e): undefined reference to `fann_set_activation_function_output'
main.c:(.text+0xba): undefined reference to `fann_train_on_file'
main.c:(.text+0xce): undefined reference to `fann_save'
main.c:(.text+0xda): undefined reference to `fann_destroy'
collect2: ld returned 1 exit status
make: *** [main] Error 1
You can use ar to make a static library and work with that.
Create a Makefile under your hello-fann-3/fann/ folder with the following contents -
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
CFLAGS = -c -Iinclude
all: libfann.a
libfann.a: $(OBJECTS)
ar rcs $# $^
%.o: %.c
gcc $(CFLAGS) $^
Then use the make command in hello-fann-3/fann/ to build the static library. The above Makefile will generate libfann.a that you can link to your program.
Create a Makefile under your hello-fann-3/ folder with the following contents -
SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)
CFLAGS = -c -I./fann/include
LFLAGS = -L./fann -lfann
main: $(OBJECTS)
gcc $(LFLAGS) $^ -o $#
%.o: %.c
gcc $(CFLAGS) $^
Then use the make command in hello-fann-3/ to build the main program.
In your main.c, you must include fan.h like -
#include "fann.h"
If you do not understand the Makefile, you can read about it here -
http://www.gnu.org/software/make/manual/html_node/index.html
You just need to link the fann library.
If you compile manually do this
gcc main.c -lfann -lm -o main
then simply run it like
./main
If you are on Ubuntu and you faced the following error
./main: error while loading shared libraries: libfann.so.2: cannot open shared object file: No such file or directory
Then run
sudo ldconfig
If you are using NetBeans, then simply Right click on your project -> Properties -> Build -> Linker,
then in the Libraries section click on the browse button [...] then in the new window click on Add Library...
Then add fann library (for example my fann library path is: /usr/local/lib/libfann.a) and click Ok
A fellow helped me, and we came to this line that compiled everything, and make the executable:
$ gcc fann/fann.c fann/fann_io.c fann/fann_train.c fann/fann_train_data.c fann/fann_error.c fann/fann_cascade.c main.c -Ifann/include -lm
And this is the answer.
That said, this is exactly what fixedfann.c is doing (include all this .c files). But if I try:
$ gcc fann/fixedfann.c main.c -Ifann/include -lm
..I get:
undefined reference to `fann_train_on_file'
This fann_train_on_file is on fann_train_data.c, which is included by fixedfann.c, so why it is undefined? I don't know... :/
--update
I realized that:
$ gcc fann/fixedfann.c main.c -Ifann/include -lm
will work if I comment the headers on fixedfann.c:
//#include "config.h"
//#include "fixedfann.h"
#include "fann.c"
#include "fann_io.c"
#include "fann_train.c"
#include "fann_train_data.c"
#include "fann_error.c"
#include "fann_cascade.c"

Calling a function from another C file

I am writing a graphics program in C/C++ using OpenGL. I have a bunch of .c files and right now, I am trying to call a function from main.cpp in assignment1gui.c. The teacher has given me a file with the compile code. It looks like this:
OBJS = assignment1gui.o shadertools.o main.o
TARGET = ass1
CXX = gcc
DBFLAGS = -O0 -g3 -ggdb3 -fno-inline
WFLAGS = -Wall -ansi
GLFLAGS = `pkg-config --cflags gtk+-2.0`
LGLFLAGS = `pkg-config --libs gtk+-2.0` -lGL -lGLEW -lGLU -lglut
CXXFLAGS = $(WFLAGS) $(DFLAGS) $(GLFLAGS)
LDFLAGS = -export-dynamic -lXext -lX11 $(LGLFLAGS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
.SUFFIXES: .cc
.cc.o:
$(CXX) -c $(CXXFLAGS) $<
.c.o:
$(CXX) -c $(CXXFLAGS) $<
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LDFLAGS)
The function I am trying to call is "drawPloygonLine()". I have declared this in "assignment1gui.h", and the definition, as I mentioned earlier, is in main.cpp.
From all the help on the Internet, I realized that there must some problem with the compile code. But I am not sure. Could someone please help me out?
Sorry I left out this part earlier. The errors I am getting are:
assignment1gui.o: In function `on_btn_color_color_set':
assignment1gui.c:(.text+0x1c): undefined reference to `drawPolygonLine'
assignment1gui.o: In function `on_rb_tool_line_toggled':
assignment1gui.c:(.text+0x8b): undefined reference to `drawPolygonLine'
assignment1gui.o: In function `on_rb_tool_circle_toggled':
assignment1gui.c:(.text+0xfc): undefined reference to `drawPolygonLine'
assignment1gui.o: In function `on_rb_tool_rect_toggled':
assignment1gui.c:(.text+0x16d): undefined reference to `drawPolygonLine'
assignment1gui.o: In function `on_rb_tool_edit_toggled':
assignment1gui.c:(.text+0x24a): undefined reference to `drawPolygonLine'
collect2: ld returned 1 exit status
make: *** [ass1] Error 1
The C/C++ files I have in the folder are main.cpp, assignment1gui.c and shadertools.c. I also have two header files- assignment1gui.h and shadertools.h. As I have mentioned earlier, I used the assignment1gui.h file to declare the new function "drawPolygonLine();"
Addition:
The declaration of the "drawPolygonLine();" is now in "main.h" and it looks like this:
#ifndef MAIN_H
#define MAIN_H
extern void drawPolygonLine();
#endif /* MAIN_H */
Both main.cpp and assignment1gui.c have "#include "main.h"" at their beginning. The definition of drawPolygonLine() is:
void drawPolygonLine()
{
if(option[opCount-1]==4 && drawn==false)
{
vCount++;
vertex[vCount].x=A;
vertex[vCount].y=B;
lines=lines+2;
vCount++;
vertex[vCount].x=polyX;
vertex[vCount].y=polyY;
clicks=0;
drawn=true;
}
}
All the variables used in the function are global in main.cpp.
An example of how I am calling drawPolygonLine(); in assignment1gui.c is in this function:
void on_btn_color_color_set(GtkColorButton *colorbutton, gpointer user_data)
{
drawPolygonLine();
GdkColor color;
gtk_color_button_get_color(colorbutton, &color);
printf("Color set rgb=(%i,%i,%i)\n",color.red,color.green,color.blue);
}
I hope this makes it clear.
The problem is that main.cpp isn't understood by this make file, since it only has rules for .cc or .c files. I suspect that main.o isn't being built - or, more likely, since you're getting as far as a failed compile, there is another file called main.c or main.cc which IS included in your program, but doesn't have drawPolygonLine() defined in it.
To solve this:
Remove or rename any existing main.c or main.cc files.
If your program is actually a C program, then change the filename to main.c
If your program is a C++ program, you could try changing the extension to .cc, but I suspect you'll then run in to problems since you're using gcc rather than g++. In this case, I'd also change:
CXX = gcc
to
CXX = g++
Remember that although a lot of C code is also valid C++ code, there are many subtle differences - and the best practices are very different in each language. For this reason, it's best to treat C and C++ as different languages.
If this doesn't fix it:
Check that the function signature of drawPolygonLine() declared in your header file is the same as the way it's defined in your main file. Check that these declarations match with the way you've called it.
Check that the files that call drawPolygonLine() have #include "assignment1gui.h" at the top
Check that drawPolygonLine() isn't declared as static (static functions aren't visible outside their translation unit - so the linker won't see them when compiling two output files together)
Also, it's good practice to have the function declaration in the header file corresponding to the source file it's defined in - so if you want to call a function in main.c from assignment.c, you would usually put the declaration in main.h, and #include it at the top of assignment.c. This won't be the cause of the problem that you're having, but it's good practice to get used to.

Resources