How do I link object files in C? Fails with "Undefined symbols for architecture x86_64"

CGccCompilation

C Problem Overview


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 :(

C Solutions


Solution 1 - C

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

Solution 2 - 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.

Solution 3 - C

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

Solution 4 - C

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

Solution 5 - C

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).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionadiView Question on Stackoverflow
Solution 1 - Cbash.dView Answer on Stackoverflow
Solution 2 - CSeKaView Answer on Stackoverflow
Solution 3 - CjohnsywebView Answer on Stackoverflow
Solution 4 - CAr majView Answer on Stackoverflow
Solution 5 - Cashmew2View Answer on Stackoverflow