Undefined reference maybe makefile is wrong? - c

I had some issues earlier with declaring my array set of records. Now I think there is something wrong with my Makefile or something.
Here is my Makefile:
EEXEC = proj1
CC = gcc
CFLAGS = -c -Wall
$(EXEC) : main.o set.o
$(CC) -o $(EXEC) main.o set.o
main.o : main.h main.c
$(CC) $(CFLAGS) main.c
set.o : set.h set.c
$(CC) $(CFLAGS) set.c
There are more functions I have in my set.c file but these are the functions I am testing at the moment:
DisjointSet *CreateSet(int numElements);
DisjointSet *MakeSet(DisjointSet *S,int ele, int r);
void Print(DisjointSet *S);
And the errors I am receiving in the terminal is:
main.o: In function `main':
main.c:(.text+0x19): undefined reference to `CreateSet'
main.c:(.text+0x43): undefined reference to `MakeSet'
main.c:(.text+0x5f): undefined reference to `Print'

The errors that you're getting are linker errors, telling you that while linking your program the linker can't find a function named 'CreateSet' (etc.). It's not immediately obvious why that should be the case, because it appears that you're including "set.o" in the build command.
To troubleshoot build problems, it's often useful to figure out what make is trying to do, and then run the commands individually one at a time so you can see where things go wrong. "make -n" will show you what commands "make" would run, without actually doing them. I would expect to see a command like:
gcc -o proj1 main.o set.o
try running that by hand and see where it gets you.

Make sure you have included set.h in main.c
Also you declare EEXEC but use EXEC...

If these are all on one line in the makefile:
EEXEC = proj1 CC = gcc CFLAGS = -c -Wall
Then you have one macro EEXEC whose value is proj1 CC = gcc CFLAGS = -c -Wall, and you have no CC or CFLAGS macro. CC probably has a default, which is why that much is working.

Related

Undefined reference when using ta-lib/ta_lib.h file and Makefile

I want to use the ta_lib functions in my C code and am trying to import the ta_lib functions. The header file gets imported correctly but i cannot get the linker to find the actual library.
I want to do the compiling process with MAKE and gcc.
Firstly I import the header
#include <ta-lib/ta_libc.h>
And then when i need to use a function
TA_ADOSC(0, CSV_LENGTH - 1, temp_high, temp_low, temp_close, temp_volume, 3, 10, &beginIdx, &endIdx, tmp_adosc);
The program compiles fine using my makefile
# create CC variable
CC = gcc
# create CFLAGS variable
CFLAGS = -L/usr/local/lib -Wall -g
LDLIBS = -lta_lib -I/usr/local/include -lm
output: main.o
$(CC) $(CFLAGS) -o output main.o
main.o: main.c
$(CC) $(LDLIBS) -c main.c
# target: dependencies
# action
clean:
rm -f \*.o output
Once I try to run make i get the following
gcc -L/usr/local/lib -Wall -g -o output main.o
/usr/bin/ld: main.o: in function `calculate_indicators': main.c:(.text+0x226): undefined reference to `TA_ADOSC'
collect2: error: ld returned 1 exit status
make: \*\*\* \[Makefile:10: output\] Error 1
From my understanding I need to fix the linking to the shared library.
The library is installed:
ldconfig -p | grep libta_lib.so
Returns the following
libta_lib.so.0 (libc6,x86-64) => /usr/local/lib/libta_lib.so.0
libta_lib.so.0 (libc6,x86-64) => /lib/libta_lib.so.0
libta_lib.so (libc6,x86-64) => /usr/local/lib/libta_lib.so
libta_lib.so (libc6,x86-64) => /lib/libta_lib.so
Since i am fairly new to C and using external libraries I can't find what seems to be the problem
You are adding the libraries to the compile line. They need to be added to the link line. And preprocessor options like -I are used by the compiler, and "where to find libraries" options like -L are used by the linker.
Also, libraries always must come at the end of the link line, after all the object files. And, the -L "where to search" option should come before the -l "what library to find" option.
Write your rules like this:
CFLAGS = -I/usr/local/include -Wall -g
LDFLAGS = -L/usr/local/lib
LDLIBS = -lta_lib -lm
output: main.o
$(CC) $(CFLAGS) $(LDFLAGS) -o output main.o $(LDLIBS)
main.o: main.c
$(CC) $(CFLAGS) -c main.c
However, it's better to just let make do the work for you; it knows how to correctly compile things (as long as you set the standard variables). You don't need to include a rule to build main.o at all.

Makefile: "undefined reference to cos"

I have just started learning about makefile files. I created a program that consists of two functions and wanted to use a makefile to put it all together. This is my file:
#Makefile
all: main
main: main.o find_root.o
clang -o main main.o find_root.o
main.o: main.c
clang -c -Wall --pedantic -std=c11 main.c -lm
find_root.o: find_root.c
clang -c -Wall --pedantic -std=c11 find_root.c -lm
clean: rm -f main *.o*
However, when I run this, I get an error - "undefined reference to cos". I am using the cosine functions in my program, but I have already linked the library to the compilation of those two files. I thought about adding "-lm" to the first clang option as well. This led to no errors, but it made a warning instead - saying that "-lm linker is unused". What should I change in my file?
The "-lm" is a linker option but you have only included it in your compilation rule (main.o: main.c). You need to include it in your linker rule (main: main.o find_root.o).
As it stand the -lm option is ignored during compilation and missing during linking.
The linker flags aren't used when compiling, but when linking, so the command for the main rule should have -lm, rather than the command for the *.o files.
Better would be just to set the appropriate variables, and let Make use its built-in rules:
#Makefile
LDLIBS += -lm
CFLAGS += -Wall --pedantic -std=c11
C = clang
all: main
main: main.o find_root.o
$(LINK.c) $^ $(LDLIBS) -o $#
clean:
$(RM) main *.o *~

Compiling multiple C and header files with 1 main

[Files in my directory][1]
Need help compiling in a make file.
So I have this link list assignment i'm doing and the directions were.
stringlist.h is supposed to contain the node and the function prototypes
stringlist.c is supposed to have the functions completed that are defined in stringlist.h. BUT stringlist.c is not supposed to contain main at all. Then, namelist.c is supposed to contain main and just have the I/O and its just supposed to call the command functions that are in stringlist.c.
So to compile this we are supposed to create a make file. Whenever I try to I get an error because main doesn't exit in one of the c files. Throughout the term we compiled code like this "gcc -std=gnu99 -m32 -Wall -g -o file file.c"
But it doesn't work.
How would I create the make file? Been spending hours and can't figure it out.
As stated by Jonathan Leffler, the sample Makefile I provided had a few bad ideas. Here's an improvement:
# compiler:
CC = gcc
# compiler flags:
CFLAGS = -g -Wall
# the build target executable:
TARGET = executable
# object files to build:
OBJ = namelist.o stringlist.o
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ)
Try this:
OBJ := namelist.c stringlist.c
GCC := gcc -g
CFLAGS := -std=gnu99 -m32 -Wall
compile: $(OBJ)
$(GCC) $(CFLAGS) $(OBJ) -o executable

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"

Figuring out multiple file compilation with make & C

For a project, I was working with a partner writing a decision tree implementation. Since both of us are relative newcomers to C and had to work quickly, we basically dumped all the functionality in a single file, which ended up being over 1600 lines. It was a quick and dirty project to get working, but now the next assignment has us responsible for extending and re-implementing the code. In its current condition, that isn't going to happen.
Right now, I'm breaking up the original source based on function responsibility. Thing is, many of the functions are intertwined, and I'm getting major errors with my make file. More specifically, the other source files are reporting implicit declaration of functions that are declared in a separate file.
I really have no experience with multiple file makefiles. The current syntax is borrowed from a simple shell implmentation in last years Systems Programming class, although this current project is an order of magnitude greater in complexity.
cc= gcc
CFLAGS= -g -Wall -lm
proj2: main.o split.o tree.o id3.o output.o
$(CC) $(CFLAGS) -o proj2 main.o split.o tree.o id3.o output.o
I also tried a previous version where each object file was compiled separately like
main.o: main.c split.c tree.c id3.c output.c
$(CC) $(CFLAGS) -o main.c split.c tree.c id3.c output.c
and this repeated to create a .o file for each source, which then was compiled into an executable.
However, that didn't work and I got about 500 lines of compiler complaints and warnings, mainly about implicit function declarations.
So, essentially I have two related questions:
is it possible to intertwined function calls between different source files?
if so, how can I make it possible here?
First a word about your makefiles.
proj2: main.o split.o tree.o id3.o output.o
$(CC) $(CFLAGS) -o proj2 main.o split.o tree.o id3.o output.o
This should work (if the code is correct) but if you're using GNUMake (which you should) you can tidy it up:
proj2: main.o split.o tree.o id3.o output.o
$(CC) $(CFLAGS) -o $# $^
Now you have only one copy of the object list to maintain.
The other version is just wrong:
main.o: main.c split.c tree.c id3.c output.c
$(CC) $(CFLAGS) -o main.c split.c tree.c id3.c output.c
First, you're trying to compile all of the source files into one object file, which kind of defeats the purpose of object files. Second, you're naming your one object file main.o when that name should really belong to an object file made from main.cc. Third, the command tells the compiler to compile all of the other source files (split.c, tree.c, ...) into an object file called "main.c"-- not illegal, but you're bound to trip yourself up.
Also, you should try to use C++, not C, but that's for another day.
Now for breaking up the Big Ball of Mud. I assume you know how to break big functions into smaller ones, so the problem is segregating functions into different source files (and then compiling and linking them correctly). Suppose main() calls a function foo():
/* main.c */
void foo()
{
// do foo things
}
int main()
{
// do main things
foo();
return(0);
}
As you know, the foo must come first, otherwise the compiler would balk when main tried to call an undeclared function. But we can declare foo beforehand:
/* main.c */
void foo();
int main()
{
// do main things
foo();
return(0);
}
void foo()
{
// do foo things
}
When the compiler reaches the call to foo(), it already knows that such a function exists, and trusts us to define it later. Now here's the trick: if we instruct the compiler to compile, but not link (that is, produce an object file like main.o, not an executable like proj2), it will trust us even farther:
/* main.c */
void foo();
int main()
{
// do main things
foo();
return(0);
}
That will compile into main.o quite nicely. The compiler trusts us to provide the definition of void foo() in some other object file when we link things together into an executable. The definition will be in another file like so:
/* foo.c */
void foo()
{
// do foo things
}
We could build this by hand:
gcc -g -Wall -lm -c foo.c -o foo.o
gcc -g -Wall -lm -c main.c -o main.o
gcc -g -Wall -lm foo.o main.o -o proj2
But that gets tedious fast, so we'll write a makefile:
cc= gcc
CFLAGS= -g -Wall -lm
proj2: main.o foo.o
$(CC) $(CFLAGS) -o $# $^
%.o: %.c
$(CC) $(CFLAGS) -c -o $# $<
So far so good. If this much is clear then we can move on to header files...
You need to create header files for each of the source code to have the declarations in them. You then #include the appropriate header files at the top of the source code.

Resources