C program Compilation error : reference to main - c

I am new to C programming and need help in resolving the compilation issue :
There are 3 .c files (main.c, file1.c , file2.c) file1.c and file2.c just contain the function definitions that are called in main.c. When I am trying to compile my main.c file using the below command, it gives me the errors:
gcc -Wall ./trigger-solve/main.c
_approx_help", referenced from:
_print_help in main-9e2c6e.o
"_approximate", referenced from:
_main in main-9e2c6e.o
"_free_matrix", referenced from:
_main in main-9e2c6e.o
"_print_matrix", referenced from:
_main in main-9e2c6e.o
"_read_matrix", referenced from:
_main in main-9e2c6e.o
"_read_sparse_matrix", referenced from:
_main in main-9e2c6e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However after reading about this error , I figured out its happening because file1.c and file2.c do not contain the main function . So I added this main function in both files :
int main()
{
return 1;
}
At this point when I compile file1.c and file2.c they DO NOT give me errors , however I am still getting the same compilation errors while running main.c. Also I don't know after compiling file1.c and file2.c how should I link them to main.c ?
Can someone please help .

You need to link all your translation units together. Perhaps all in one wash, like this:
gcc -Wall main.c file1.c file2.c
Now you have an executable file called a.out ready for your enjoyment.
Of course rebuilding the entire project every time you change one file isn't feasible, so normally you'd compile each TU separately and then link everything in a final step (and give the output file a better name):
gcc -Wall -c main.c
gcc -Wall -c file1.c
gcc -Wall -c file2.c
gcc -o myprog main.o file1.o file2.o

Did you do any research yourself on this? There are plenty of relevant examples available online.
You should not define main function in file1.c and file2.c. You should compile all .c files with -c option and then link them to main like this :
gcc main.o file1.o file2.o

you can just
gcc -Wall *.c
will compile all .c files in the current directory... thats a good shortcut if you save your each of your project in a separate folder

Basically, you have got the linking error. Remember, any program has only one main() function. In your example, this main() must be finally linked with the other files to create an executable. The main() is the entry point of any C program. Thus, there should be only one main() in your source code in order to create an executable. For your case, I will say use the Makefile for compiling and linking. The makefile saves time of compilation and is quite handy.
I will say - use the Makefile. The Makefile makes the job easier. In future, if you have to extend the functionality, add a new file and add a new entry in the makefile. This is the simplest form of makefile here.
Once you issue make - the executable name - app will be created. Next, run the ./app
Makefile
target = file1.0 file2.o main.o
[tab] gcc file1.o file2.o main.o -o app
file1.o: file1.c
[tab] gcc -c file1.c -o file1.o
file2.o: file2.c
[tab] gcc -c file2.c -o file2.o
main.o: main.c
[tab] gcc -c main.c -o main.o
Now, run the Makefile.
$make target

Related

C Link External Library in Makefile

I am having issues linking a library (termbox) when compiling. I get the error:
make: *** No rule to make target `termbox.h', needed by `test.o'. Stop.
Makefile:
edit: test.o
gcc -Wall -o edit test.o
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src
Include:
#include "termbox/src/termbox.h"
I have also tried using the compiled library but ran into similar issues. Do I have to use some sort of combination of specifying the header file and the location of the compiled library?
The directory of my termbox folder is in the same directory as test.c.
Thanks!
You have managed to compile and include the header file for the library, but you did not yet tell the compiler where the code (definitions) are - i.e. you did not tell it to link in the library yet.
You will need to do that next, this is done in a similar way to telling the linker what files to link, but with some extra syntax. It appears to be a static library (.a suffix) so you can link like this:
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -Itermbox/src -Lsrc -ltermbox
Where -L... specifies where libraries can be found and -l... specifies the library name to link to minus the lib prefix and the .a or .so suffix. Also note that order is important, so leave the library linkage at the end.
More on library linking order here
UPDATE
Sorry I added the linking to the wrong line! - here is the updated answer:
# The linker stage
edit: test.o
gcc -Wall -o edit test.o -Lsrc -ltermbox
# Compile stage
test.o: test.c termbox/src/termbox.h
gcc -Wall -c test.c -ltermbox/src

Create a simple dynamic library

What linking step am I missing? I'm trying to make a dynamic library from file c.c:
#include "a.h"
#include "b.h"
int my_function(void)
{
return a() + EIGHT;
}
which depends on a.c:
int a(void)
{
return 1;
}
and b.h:
enum {
EIGHT = 8,
};
I run gcc -c c.c -o c.o to compile the object file. Then I run
gcc -Wall -dynamiclib -o libc.dylib c.c
and I get this error.
Undefined symbols for architecture x86_64:
"_a", referenced from:
_b in ccx5LSkL.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
How can I properly link the files? References addressing this specific problem would be awesome.
So your first line, gcc -c c.c -o c.o, compiled the object file c.o. Now you then have to use c.o for creating the final result. So your linking step should be using c.o, not c.c.
Next, the error you are getting is that the symbol "_a" was not found. This is coming from you calling the function a(), but not including it in the linking step. To do that you need to also compile a.c and include it when linking your final product.
So in total, your process should be:
1) compile:
gcc -c a.c -o a.o
gcc -c c.c -o c.o
2) link:
gcc -Wall -dynamiclib -o libc.dylib a.o c.o
Note that to compile libc.dylib, you had to include all the sources that the final result would depend on.
Finally, you don't actually need to compile all of the object files separately. You can compile and link together in one combined step by just providing the *.c files right away.
gcc -Wall -dynamiclib -o libc.dylib a.c c.c
So your problem was really just about not including both sources together. (Other than -dynamiclib, everything actually works basically just like compiling a regular executable.)

Trying to make a simple Makefile fails

I have 3 files, main.c, lists.c, and lists.h.
Im trying to write a Makefile with all the files are in the same directory:
maman21: lists.c lists.h main.c
gcc -g -Wall -ansi main.c -o maman21 -lm
going to the folder through terminal and using make shows me this message:
gcc -g -Wall -ansi main.c -o maman21 -lm
Undefined symbols for architecture x86_64: "_linkedListWay",
referenced from:
_main in main-C9dUT4.o "_reallocWay", referenced from:
_main in main-C9dUT4.o ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to
see invocation)
make: *** [maman21] Error 1
reallocWay and linkedListWay are to functions I'm using in the file.
Thank you for your help.
You've failed to include the lists.c file in the compiler invocation so it doesn't get built.
It should be:
CFLAGS=-g -Wall -ansi
LDLIBS=-lm
maman21: main.o lists.o
main.o: main.c
lists.o: lists.c lists.h
The above uses implicit Makefile rules, it "knows" how to convert a C file to an object (.o) file.
Also, is it normal for Clang to be called gcc?

Compiling multiple C files with gcc

I have two files, main.o and modules.o, and I'm trying to compile them so that main.o can call functions in modules.o. I was explicitly told not to try #include module.o. I really don't know what I should be doing instead. I tried a few different versions of gcc (such as gcc -x c driver main.o modules.o), but nothing I get works: the compiler continuously returns
error: called object is not a function
The .o files are my source code files (I was instructed to put my source code in files with extension .o.) What do I do to compile this?
If you have your two source files, you can compile them into object files without linking, as so:
gcc main.c -o main.o -c
gcc module.c -o module.o -c
where the -c flag tells the compiler to stop after the compilation phase, without linking. Then, you can link your two object files as so:
gcc -o myprog main.o module.o
This is all perfectly normal behavior, you'll usually get your makefile to compile things separately and link them at the end, so you don't have to recompile every single source file every time you change one of them.
Talking about main.o "calling functions in" module.o is perfectly fine, but an .o file is not a source file, it's a compiled object file. If "put my source code in files with extension .o" actually meant "compile my source code into files with extension .o" then the situation would make a whole lot more sense.
You should define the functions that you want to call from modules.c into main.c into a header file, let us say modules.h, and include that header file in main.c. Once you have the header file, please compile both of the files together: gcc main.c modules.c -o output
Two additional notes. First, modules.o is an object file and it should not be included in a C source file. Second, we cannot have a C file have a .o extension. You should actually get an error when compiling a .o file. Something like:
$ cat t.o
int main() {
int x = 1;
return 0;
}
$
$ gcc t.o
ld: warning: in t.o, file is not of required architecture
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
program: main.o
gcc -o main main.c anotherSource.c
This works for me.
You should be including .h files which are "headers". So if your main file is using modules then you should include module's header file.

Missing symbol compile error in C. Basic header file setup

I'm working on a C project implementing some generic containers and am having this weird issue when compiling. Here is some sample code that also replicates the error.
foo.h
void fooprint(void);
foo.c
#include "foo.h"
#include <stdio>
void fooprint(void){
printf("bar");
return;
}
main.c
#include "foo.h"
int main(void){
fooprint();
return 0;
}
I compile by typing
gcc main.c -o main
and this is what terminal outputs
Undefined symbols:
"_fooprint", referenced from:
_main in ccfMXGzj.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
I'm compiling this on an OSX system but have also tried compiling on a red hat machine with the same effect.
The solution is probably painfully obvious but I have had multiple friends I'm working with look at this and they couldnt see the problem. I've googled around a lot but most symbol error issues are usually pertaining to objective C.
You need to compile them together:
gcc -Wall -Wextra -o main main.c foo.c
Or maybe make a Makefile ?
all: main
main: main.o foo.o
main.o: main.c
foo.o: foo.c
You have to compile also foo.c into an object file and link all of them together:
gcc -o foo.o foo.c
gcc -o main.o main.c
gcc -o main main.o foo.o
Yes, this is simple, so I recommend you to read a good C book and step these easy steps.

Resources