2

Say your program is composed of two source files (main.c and auxiliary.c) and two header files (declarations.h and auxiliary.h).

Then you run the compiler as follows:

$gcc main.c auxiliary.c -o myprogram

Question 1: Will the compiler create one single object file for my program (i.e., just the libraries are missing) or will it create two object files, one for each source file (and then link everything together)?

Question 2: Is there ever the need to call the linker separately? Because if you use the command above the compiler will take care of that for you, right?

Question 3: Why some libraries get linked automatically (e.g., stdio) and why some require extra work (e.g., math.h requires adding a -lm when compiling). What does the -lm stand for?

Question 4: Suppose you have a single source file and your program doesn't need any external library. Does this mean that the object code you would get from the compiler would be executable already? (i.e., compiling it like $gcc -c main.c).

Daniel Scocco
  • 7,036
  • 13
  • 51
  • 78

3 Answers3

4
  1. gcc will usually makes one object per source files. But there is a -combine option to tell that you want otherwise.

  2. Recompiling everything when you have several tens of source files isn't a good idea (when you have more, you split them in libraries).

  3. History. There was a time -- before shared libraries -- when the math library was relatively big and putting it in every executable even those who didn't need it was considered as wasteful (using the math library involved alternative versions of function like printf, so you had a cost even when not used)

  4. I'm waiting to see a program which doesn't make use of any part of even the standard library (logically calling main is done as exit(main(argc, argv)) so at least exit is called) and then there is the startup and finish code.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
3
  1. gcc creates one object file per source file, then links them to build the executable.

  2. Your example proves that gcc is able to chain all needed steps

  3. The library that gets automatically linked is the standard C library. The others need to be specified. This allows to build a smaller executable when you don't need atan2().
    -lm indicates to the compiler that it should find the math library, whose id is m. On Unix, its filename is libm.so or libm.a depending whether the link is dynamic (performed at runtime and leading to a smaller executable) or static (performed at link time and leading to a standalone executable).

  4. No. It must be linked to the standard C library anyway. Moreover, the file format of an object code is different than an executable.

mouviciel
  • 66,855
  • 13
  • 106
  • 140
  • 4. Technically they're both ELF files, but with a few different properties. – Kristof Provost Dec 08 '11 at 13:46
  • Thanks. One more question: how come Wikipedia and other sources say that math.h is part of the standard library? -> http://en.wikipedia.org/wiki/C_standard_library – Daniel Scocco Dec 08 '11 at 13:49
  • There is a section about it in the Wikipedia article. Moreover, not every flavour of C conforms to the latest standard. – mouviciel Dec 08 '11 at 13:54
  • @Daniels: Because the ISO C standard says that it is. GCC breaks down the "ISO standard" library in a "default" and "optional" parts; `libm` being not part of the default. Microsoft, OTOH, doesn't have a separate math library. – MSalters Dec 08 '11 at 15:05
1

Question 1: Execute your gcc statement with '-save-temps' and you'll see that the compiler creates two object files.

Question 2: The call to the linker is implicit. The 'gcc' command isn't really a compiler, but drives the compilation process by calling the preprocessor, compiler, assembler and linker as required. In small programs it can be a good idea to let 'gcc' take care of everything, but for larger programs, with many source files, this would imply recompiling all source files even if they haven't changed.

Question 3: That's a matter of convention. (The m library is the math library.)

Question 4: No, that's not the case. There's always some additional code which must be linked in to take care of process startup/teardown requirements. On linux those are the crt1.o, crti.o, crtbegin.o and crtn.o files.

Kristof Provost
  • 26,018
  • 2
  • 26
  • 28
  • Thanks for the answers. I am guessing that when I use the -c option in gcc the compiler will output assembly code, and the assembler will transform it into and object file and stop there, right? In this case, would it be possible to stop at the assembly code step? (i.e., make gcc output assembly instead of an object file?) – Daniel Scocco Dec 08 '11 at 13:50
  • 1
    @DanielS Yes, it's possible. See this: http://stackoverflow.com/questions/137038/how-do-you-get-assembler-output-from-c-c-source-in-gcc – Vitor Py Dec 08 '11 at 17:12