0

I'm learning how to use header files and I have a problem while linking these 3 files:

f.c:

#include "f.h"

int getfavoritenumber(void)
{
    return 3;
}

f.h:

#ifndef _f_H_
#define _f_H_

int getfavoritenumber(void);

#endif

main.c:

#include <stdio.h>
#include "f.h"

int main (void)

    {
        printf("%d\n", getfavoritenumber());
    
        return 0;
    }

Compiling gcc main.c -o f I get this error:

Undefined symbols for architecture x86_64:
  "_getfavoritenumber", referenced from:
      _main in main-7be23f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

But if I include the f.c file with gcc main.c f.c -o f it works.

So, when compiling, should I include each C file that I used in my project, or am I missing something? Because adding each single file to gcc is very annoying.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • You might want to look up commands like `make` and makefiles. Or other project/build systems. Such systems will not only handle this for you, but perhaps also things like system configuration and finding libraries, as well as handle dependency checking so you don't need to rebuild source files which haven't been modified. – Some programmer dude Apr 29 '21 at 14:26
  • 1
    You could do `gcc *.c` to compile all .c files in a directory. – cigien Apr 29 '21 at 14:26
  • You don't need to provide every C file in command line unless you compile them separately with -c option `gcc -c foo.c` and then link all compiled C objects files into one executable `gcc foo.o bar.o -o foobar`. Note that when compiling without -c you need to provide main() function – shjeff Apr 29 '21 at 14:28
  • @cigien Should be accepted as solution. – federico D'Armini Apr 29 '21 at 14:32
  • 1
    Does this answer your question? [Compile all .c files in a directory using GCC compiler in CMD](https://stackoverflow.com/questions/19765536/compile-all-c-files-in-a-directory-using-gcc-compiler-in-cmd) – cigien Apr 29 '21 at 14:34
  • Well, your question has been asked before, so I'd rather not write an answer. You can accept the duplicate suggestion if it works for you. – cigien Apr 29 '21 at 14:35
  • Mmmh more or less but @dbush answer is very exhaustive – federico D'Armini Apr 29 '21 at 14:37
  • @cigien no it's not this duplicate because I think a make file is the best solution – federico D'Armini Apr 29 '21 at 14:38

2 Answers2

1

When you have multiple source files that together make an executable, they must be each compiled and then linked together. This is done by specifying each source file when the compiler is invoked as you've discovered.

Note also that you can either do the compiling and linking in one step as you've done, or you can separate them as follows:

gcc -c main.c
gcc -c f.c
gcc -o f main.o f.o 

Managing multiple source files and their dependencies is where using a makefile comes into play.

dbush
  • 205,898
  • 23
  • 218
  • 273
1

You need to understand there are three stages from c source code to run able binary. For etch and every file this stages must be followed except for header file or .h file.

  1. First Stage : Source to assembly. gcc -S -o source.s source.c
  2. Second Stage : assembly to Compiled Binary Object. Which can not be runned directly. gcc -c source.s -o source.o
  3. Third Stage : In this stage we marge all the compiled binary to a single compiled binary where an input binary object holds an entry function int main().This the file which we can run on our operating system.gcc -o OutputFile source1.o source2.o source3.o ......

After this three stages we can run our program by ./OutputFile. You can avoid making assembly file and directly make object file.

Yeah you must include all the file for compilation in you project. You can use automation tools like automake or linux shell script for doing this job.

NomanMahdi
  • 157
  • 1
  • 8