I have a mysterious problem!
In the main.c I have the following:
#include "jogo.h"
int main(){
int i;
sef_startup();
vg_init(0x105);
batalha_naval();
sleep(5);
vg_exit();
return 0;
}
In the jogo.h I have:
#ifndef __JOGO_H
#define __JOGO_H
void batalha_naval(void);
#endif
And in the main.c I have:
#include "core.h"
void batalha_naval(void) {
vg_draw_line(0, 0, 1023, 0, 12);
}
But when doing a make the compiler gives a undefined _batalha_naval(); in the main.c. If I define the function in the jogo.h an error doesn't appear, but if I do like this the error appears.
I am using CC compiler.
Your jogo.h appears correct.
You need it if you wish to use function "batalha_naval()" in multiple compilation units.
You should '#include "jogo.h"' in main.c, and in jogo.c.
You must include both main and jogo in your link command.
How are you linking? You need to do either:
$ cc -c main.c
$ cc -c jogo.c
$ cc main.o jogo.o
or
$ cc main.c jogo.c
Related
In my project, I have two libraries and one program.
Lib1.c and Lib1.h are two files of first library(Lib1.so).
Lib2.c and Lib2.h are two files of second library(Lib2.so).
prog.c is the main file of program(prog).
The program(prog) is linked only to the second library(Lib2.so) and the second library(Lib2.so) is linked to the first library(Lib1.so).
In Lib1.c, I have a declaration of global variable (int var = 0;) and in Lib1.h, I have a declaration (extern int var;).
In Lib2.h, I have a declaration (extern int var;) in order to use var variable in main program.
In main() function, I include the Lib2.h in prog.c file and I have a declaration (var = 5;)
Lib1.c :
#include <stdio.h>
#include "Lib1.h"
int var = 0;
int funct(void)
{
printf("hello world \n");
return 0;
}
Lib1.h :
extern int var;
int funct(void);
Lib2.c :
#include <stdio.h>
#include "Lib2.h"
int funct2(void)
{
printf("Library 2 \n");
funct();
return 0;
}
Lib2.h :
#include "Lib1.h"
extern int var;
int funct2(void);
prog.c :
#include <stdio.h>
#include "Lib2.h"
int main()
{
var = 5;
printf("===>var=%d\n", var);
funct2();
return 1;
}
Commands :
gcc -c -Wall -Werror -fpic Lib1.c
gcc -shared -o Lib1.so Lib1.o
gcc -c -Wall -Werror -fpic Lib2.c
gcc -shared -o Lib2.so Lib2.o -ldl /home/test/Lib1.so
gcc prog.c -o prog -ldl /home/test/Lib2.so
When I try to compile the program(prog.c), I get an error in the link step as below.
/usr/bin/ld: /tmp/ccKaq16a.o: undefined reference to symbol 'var'
/home/test/Lib1.so: error adding symbols: DSO missing from command line
Is there a way to use var variable in the main function when its defined in the first library?
You link your program against Lib2 but not Lib1. You need to add that as well. You also don't need to explicitly link Lib1 when you create Lib2
gcc -c -Wall -Werror -fpic Lib1.c
gcc -shared -o Lib1.so Lib1.o
gcc -c -Wall -Werror -fpic Lib2.c
gcc -shared -o Lib2.so Lib2.o
gcc prog.c -o prog /home/test/Lib2.so /home/test/Lib1.so
I created a sample .h file in C and it didn't work, for some reason. The files are as follows:
header.c:
#include <stdio.h>
#include "header.h"
int add(int a, int b) {
int tmp=a;
int i;
for(i=0, i==tmp, i++) {
b++;
}
return(b);
}
header.h:
#ifndef HEADER_H
#define HEADER_H
int add(int a, int b);
#endif
main.c:
#include <stdio.h>
#include "header.h"
int main(void) {
int foo=add(1, 2);
printf("%i \n", foo);
return(0);
}
When I try to compile main.c with make and gcc it says that add is undefined. Help!
You need to compile both main.c and header.c into the same executable:
all: main
main: main.o header.o
gcc -o main main.o header.o
header.o: header.c header.h
gcc -c header.c
main.o: main.c header.h
gcc -c main.c
Or for a one-liner without a make file:
gcc -g -o main main.c header.c
Including the header file only includes the function prototype. You need to link the actual definition of add() by compiling separate object files or you can compile them together in a single command line:
gcc -Wall -Wextra header.c main.c -o main
Perhaps, you may want to consider Makefiles for larger projects.
Your add() function has issues:
1) Semi-colons ; are used in for loops, not commas.
2) The condition should be i!=tmp for addition.
This:
for(i=0, i==tmp, i++) { .. }
should be
for(i=0; i!=tmp; i++) { .. }
You need to add header.c to the compile call. You can't just compile main.c.
The code is as follows:
global.h
#ifndef GLOBAL_H
#define GLOBAL_H
#include <stdio.h>
int test;
void test_fun(void);
#endif
global.c
#include "global.h"
void test_fun()
{
printf("%d\n", test);
}
main.c
#include "global.h"
int main(void)
{
test_fun();
test = 1;
printf("%d\n", test);
}
Makefile using gcc compiler
main: main.o global.o
gcc -o main main.o global.o
main.o: main.c global.h
gcc -c main.c
global.o: global.c global.h
gcc -c global.c
clean:
rm -f global.o main.o main
This works well.
However, when I change my code to C++, as follows:
global.h
#ifndef GLOBAL_H
#define GLOBAL_H
#include <iostream>
int test;
void test_fun(void);
#endif
global.cpp
#include "global.h"
void test_fun()
{
cout << test
}
main.cpp
#include "global.h"
int main(void)
{
test_fun();
test = 1;
std::cout << test;
}
Makefile using g++ compiler
main: main.o global.o
g++ -o main main.o global.o
main.o: main.cpp global.h
g++ main.cpp
global.o: global.cpp global.h
g++ global.cpp
clean:
rm -f global.o main.o main
The code above throws the output:
global.o:(.bss+0x0): multiple definition of `test'
What makes the different here?
You've int test; in a header which is included in 2 TUs, hence the error. Both the translation units main.c (or .cpp depending upon the compiler used) and global.c have global.h included, which leads to two definitions of the same variable in two object files, thus the linker error.
Pass test as an arguement to test_fun, thereby avoiding the usage of a global.
If you absolutely have to share the variable between the TUs, then remove int test; from global.h and in main.cpp do
int test;
and in global.cpp do
extern int test;
As an aside, since it's a global variable, test would be initialized to 0 and hence in main when you test_fun();, it should print 0 and then after setting it to 1, it'll print 1.
It's illegal in both C and C++ from a language standpoint, but as for why it works with a C compilers (like GCC) is because they implement a common extension, a legacy cruft.
... You are using a different programming language
I'm writing a simple application in ANSI C. I am using GCC in a Unix environment.
I have the following sample application:
//main.c
#include "foo.h"
int main()
{
int result;
result = add(1,5);
return0;
}
Header:
//foo.h
#ifndef FOO_H_INCLUDED
#define FF_H_INCLUDED
int add(int a, int b);
#endif
Implementation:
//foo.c
int add(int a, int b)
{
return a+b;
}
I am compiling my program with the following command:
cc main.c -o main.o
The compiler complains that 'reference to add is undefined'. Is this a linking problem? How do properly make use of my header?
Thanks!
You need to compile both your source files together:
cc main.c foo.c -o main
Also, in this case, -o produces an executable, so calling it main.o can be misleading.
Yet another tidbit, though unrelated to the question: the #ifndef and #define in foo.h don't match.
The header is not your current problem. Your current problem is that you're not compiling the add function definition in foo.c.
Try
cc main.c foo.c -o main.o
If you are trying to compile main.c into an assembled object file, you need to prevent gcc from trying to link. This is done via
cc -c main.c -o main.o
You can compile all other object files, then when you have all of your object files ready, you simply do
cc main.o obj1.o anotherOBJ.o -o myExecutableBinary
"undefined reference" is a linker error, not a compiler error.
The compiler sees the declaration in the header, but you have not compiled or linked the definition in foo.c. Your title uses the term definition incorrectly.
How can I include foo() function of foo.c in this small program (sorry for my noob question):
In my foo.h file:
/* foo.h */
#include <stdio.h>
#include <stdlib.h>
int foo(double largeur);
In foo.c:
/* foo.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int foo(double largeur)
{
printf("foo");
return 0;
}
And in main.c:
/* main.c */
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int main(int argc, char *argv[])
{
printf("Avant...");
foo(2);
printf("Apres...");
return 0;
}
After compiling:
$ gcc -Wall -o main main.c
I get this error:
Undefined symbols: "_foo",
referenced from:
_main in ccerSyBF.o ld: symbol(s) not found collect2: ld
returned 1 exit status
Thanks for any help.
$ gcc -Wall -o main main.c foo.c
GCC doesn't know to look for foo.c if you don't tell it to :)
Creating a program in C requires two steps, compiling and linking. To just run the compiling part, use the -c option to gcc:
gcc -c main.c
This creates an object file, main.o (or main.obj on Windows). Similarly for gcc -c foo.c. You won't get the error message above at this stage. Then you link these two object files together. At this stage, the symbol foo is resolved. The reason you got the error message was because the linker couldn't find the symbol, because it was only looking at main.o and not foo.o. The linker is usually run from gcc, so to link your object files and create the final executable file main, use
gcc -o main main.o foo.o
You have to compile foo.c also because it is another module. Let me see how they do it in gcc:
$ gcc -Wall main.c foo.c -o main
You could also do this in your MakeFiles, like this:
APP_NAME = Foo
Foo_HEADERS = foo.h
Foo_FILES = main.c foo.c
If you're not so much familiar with MakeFiles i suggest you to take a look at Make Docs, but this is a simple example, APP_NAME sets the name of the compiled executable(in this case is Foo), Foo_HEADERS will set the headers used by your application, Foo_FILES you will set the source files of your applications, remember to put the APP_NAME(in this case Foo) at the beginning of _HEADERS and _FILES. I suggest you to use MakeFiles because they will organize you application build process and will be better for the end-user.