source.c ::
int source=0;
int desti=0;
char str[50]="";
source.h::
extern int source;
extern int desti;
extern char str[50];
station1.c
#include"source.h"
#include<stdio.h>
main()
{
printf("%d %d",source,desti);
}
When I compile station1.c I get the following error:
undefined reference to 'desti'
undefined reference to 'source'
Could anyone please tell me where I have gone wrong?
What did your compile command line look like?
Try:
cc -c station1.c -o station1.o
cc -c source.c -o source.o
cc -o a.out station1.o source.o
The first two compile the files by themselves and puts the result in a .o file.
The last line combines the .o files into an executable named 'a.out'.
When we use extern modifier with any variables it is only declaration i.e. memory is not allocated for these variable. Hence in your casecompiler is showing error unknown symbol source & desti. To define a variable i.e. allocate the memory for extern variables it is necessary to initialize the variables.
initialize the variables in source.c
or another way is to compile with combining the object file
gcc -c source.c station1.c -Isource.h
Related
I have the following two files:
// t.c
#include<stdio.h>
extern int x;
int main(void)
{
printf("%d\n", x);
}
// tt.c
int x=4;
And then I compile it into two object files with:
$ gcc -c tt.c t.c
So now I have two object files, tt.o and t.o. When I do the following to build an executable:
$ gcc tt.o t.o -o out
How does the linker resolve the definition of x? Does it basically do a "two-pass" where it saves all global variables with external linkage first, and then does a lookup in each file that needs an external definition, or what's the process that happens to resolve those lookups?
So I'm trying trying to use a function defined in another C (file1.c) file in my file (file2.c). I'm including the header of file1 (file1.h) in order to do this.
However, I keep getting the following error whenever I try to compile my file using gcc:
Undefined symbols for architecture x86_64:
"_init_filenames", referenced from:
_run_worker in cc8hoqCM.o
"_read_list", referenced from:
_run_worker in cc8hoqCM.o
ld: symbol(s) not found for architecture x86_64
I've been told I need to "link the object files together" in order to use the functions from file1 in file2, but I have no clue what that means :(
I assume you are using gcc, to simply link object files do:
$ gcc -o output file1.o file2.o
To get the object-files simply compile using
$ gcc -c file1.c
this yields file1.o and so on.
If you want to link your files to an executable do
$ gcc -o output file1.c file2.c
The existing answers already cover the "how", but I just wanted to elaborate on the "what" and "why" for others who might be wondering.
What a compiler (gcc) does: The term "compile" is a bit of an overloaded term because it is used at a high-level to mean "convert source code to a program", but more technically means to "convert source code to object code". A compiler like gcc actually performs two related, but arguably distinct functions to turn your source code into a program: compiling (as in the latter definition of turning source to object code) and linking (the process of combining the necessary object code files together into one complete executable).
The original error that you saw is technically a "linking error", and is thrown by "ld", the linker. Unlike (strict) compile-time errors, there is no reference to source code lines, as the linker is already in object space.
By default, when gcc is given source code as input, it attempts to compile each and then link them all together. As noted in the other responses, it's possible to use flags to instruct gcc to just compile first, then use the object files later to link in a separate step. This two-step process may seem unnecessary (and probably is for very small programs) but it is very important when managing a very large program, where compiling the entire project each time you make a small change would waste a considerable amount of time.
You could compile and link in one command:
gcc file1.c file2.c -o myprogram
And run with:
./myprogram
But to answer the question as asked, simply pass the object files to gcc:
gcc file1.o file2.o -o myprogram
Add foo1.c , foo2.c , foo3.c and makefile in one folder
the type make in bash
if you do not want to use the makefile, you can run the command
gcc -c foo1.c foo2.c foo3.c
then
gcc -o output foo1.o foo2.o foo3.o
foo1.c
#include <stdio.h>
#include <string.h>
void funk1();
void funk1() {
printf ("\nfunk1\n");
}
int main(void) {
char *arg2;
size_t nbytes = 100;
while ( 1 ) {
printf ("\nargv2 = %s\n" , arg2);
printf ("\n:> ");
getline (&arg2 , &nbytes , stdin);
if( strcmp (arg2 , "1\n") == 0 ) {
funk1 ();
} else if( strcmp (arg2 , "2\n") == 0 ) {
funk2 ();
} else if( strcmp (arg2 , "3\n") == 0 ) {
funk3 ();
} else if( strcmp (arg2 , "4\n") == 0 ) {
funk4 ();
} else {
funk5 ();
}
}
}
foo2.c
#include <stdio.h>
void funk2(){
printf("\nfunk2\n");
}
void funk3(){
printf("\nfunk3\n");
}
foo3.c
#include <stdio.h>
void funk4(){
printf("\nfunk4\n");
}
void funk5(){
printf("\nfunk5\n");
}
makefile
outputTest: foo1.o foo2.o foo3.o
gcc -o output foo1.o foo2.o foo3.o
make removeO
outputTest.o: foo1.c foo2.c foo3.c
gcc -c foo1.c foo2.c foo3.c
clean:
rm -f *.o output
removeO:
rm -f *.o
Since there's no mention of how to compile a .c file together with a bunch of .o files, and this comment asks for it:
where's the main.c in this answer? :/ if file1.c is the main, how do
you link it with other already compiled .o files? – Tom Brito Oct 12
'14 at 19:45
$ gcc main.c lib_obj1.o lib_obj2.o lib_objN.o -o x0rbin
Here, main.c is the C file with the main() function and the object files (*.o) are precompiled. GCC knows how to handle these together, and invokes the linker accordingly and results in a final executable, which in our case is x0rbin.
You will be able to use functions not defined in the main.c but using an extern reference to functions defined in the object files (*.o).
You can also link with .obj or other extensions if the object files have the correct format (such as COFF).
How to create an external character array in C?
I have tried various ways to define char cmdval[128] but it always says undefined reference to 'cmdval'
I want to put a string in cmdval in first.c file and use it in other second.c file. I tried adding a global.h file with extern char cmdval[128] but no luck.
UPDATE:
global.h
extern char cmdval[128];
first.c
#include "global.h"
char cmdval[128];
function(){
strcpy(cmdval, "a string");
}
second.c
#include "global.h"
function(){
printf("%s \n",cmdval); //error
}
FAIL :( "undefined reference to `cmdval'"
EDIT:
I am working in linux (editing a mini OS xv6 then compiling and running it in qemu), I don't know if it is a barrier
You need to declare it in the .h file
extern char cmdval[128];
And then define the value in first.c;
char cmdval[128];
Then anything that includes your .h file, provided it is linked with first.o will have access to it.
To elaborate, "extern" is saying, there is an external variable that this will reference... if you dont then declare cmdval somewhere, cmdval will never exist, and the extern reference will never reference anything.
Example:
global.h:
extern char cmdval[128];
first.c:
#include "global.h"
char cmdval[128];
int main() {
strcpy(cmdval, "testing");
test();
}
second.c:
#include "global.h"
void test() {
printf("%s\n", cmdval);
}
You can compile this using:
gcc first.c second.c -o main
Or make the .o files first and link them
gcc -c first.c -o first.o
gcc -c second.c -o second.o
gcc first.o second.o -o main
Extern doesn't mean find it somewhere, it changes the variable linkage to external, which means no matter how many time you declare a variable, it references to the same thing.
e.g. These references the same thing in c(not c++), a global variable's linkage by default is external.
external char cmdval[128];
char cmdval[];
char cmdval[128];
The problem is that you shoud first compile them into .o, then link those .o together.
gcc -c first.c second.c
gcc -o first.o second.o
or
gcc first.c second.c
You should have a compilation unit in which you define the cmdval variable. The extern keyword only declares that the variable exists, it does not define it.
Put the following line in first.c, second.c or in an other C file of your choice:
char cmdval[128];
In second.c
#include "global.h"
define extern char cmdval[128] in global.h as well.
Every time I compile I get the following error message:
Undefined reference to ( function name )
Let's say I have three files: Main.c, printhello.h, printhello.c. Main.c calls function print_hello(), which returns "Hello World". The function is defined in printhello.c.
Now, here's the following code of printhello.h:
#ifndef PRINTHELLO_H
#define PRINTHELLO_H
void print_hello();
#endif
I am sure this code is fine. I still don't know why is it giving me the error, though. Can you help me?
Undefined references are the linker errors. Are you compiling and linking all the source files ? Since the main.c calls print_hello(), linker should see the definition of it.
gcc Main.c printhello.c -o a.out
The error is, I think, a linker error rather than a compiler error; it is trying to tell you that you've not provided all the functions that are needed to make a complete program.
You need to compile the program like this:
gcc -o printhello Main.c printhello.c
This assumes that your file Main.c is something like:
#include "printhello.h"
int main(void)
{
print_hello();
return 0;
}
and that your file printhello.c is something like:
#include "printhello.h"
#include <stdio.h>
void print_hello(void)
{
puts("Hello World");
}
Your declaration in printhello.h should be:
void print_hello(void);
This explicitly says that the function takes no parameters. The declaration with the empty brackets means "there is a function print_hello() which returns no value and takes an indeterminate (but not variadic) list of arguments", which is quite different. In particular, you could call print_hello() with any number of arguments and the compiler could not reject the program.
Note that C++ treats the empty argument list the same as void print_hello(void); (so it would ensure that calls to print_hello() include no arguments), but C++ is not the same as C.
Another way to do it is to explicitly build object files for the printhello:
gcc -c printhello.c -o printhello.o
gcc -o Main main.c printhello.o
This has the added benefit of allowing other programs to use the print_hello method
It seems that the error is from the linker and not the compiler. You need to compile and link both the source files. I think what you are doing is simply including the header file in Main.c and you are not compiling the printhello.c
You need to :
gcc Main.c printhello.c -o myprog
or
construct the object files first
gcc -c printhello.c
gcc -c Main.c
then link them
gcc Main.o printhello.o
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.