Penguin
Note: You are viewing an old revision of this page. View the current version.

How compiling works under Linux (and Unixies in general)

Note this is the long winded approach, gcc(1) is smart enough to do most of these steps for you automagically. :)

When compiling a C program the first step is to PreProcess? the source. This is done with cpp(1). This will take a .c and some .h files and generate you a .i file( PreProcess?ed) that has all the #include's expanded out, and all the #defines replaced.

gcc(1) then takes a .i file and generates a .s file (assembler information).

as(1) then takes a .s file and generates a .o file (object file).

ld(1) then takes the .o file and links it with any libraries as required and generates an executable or a library.

strip(1) can then optionally remove any unneeded information in the executable (such as debugging information) reducing it's size.

alternatively

gcc foo.c baz.c -o baz

will sort the entire thing out for you :)


Object files are .o files. They are fragments of code that may have some unresolved symbols. You link them together with ld(1) which resolves all the symbols from other .o files or from libraries.

.a files are libraries of .o files. They are kinda like a .zip file for .o files. ar(1) is the tool to manage .a files. if you run ranlib(1) over a .a file it will create an index of all the symbols making your compiles faster. I believe GNU ar(1) keeps the symbol table up to date so ranlib(1) isn't required, but I could be wrong.

libtool(1) is a program to manage libraries in a CrossPlatform manner under Unix.

Instead of making an executable, you can make a shared library by compiling with the flags "-shared" (this is a shared library), and -fPIC (create PositionIndependantCode?). the -fPIC is optional, if you don't use it then when the library is loaded into memory ld.so(8) will relocate the symbols for you (See RelocatingSymbols?) which will write to the memory used by the library, and thusly will cause that library not to be shared between processes due to CopyOnWrite. I don't know why you wouldn't want to use -fPIC if your platform supports it, so use it :)

gcc foo.c -shared -fPIC -c -o foo.o

You can open dynamically loaded modules using dlopen(3). You can probably link against these, although I've never bothered figuring out how.

If you want to make a library that is statically compiled into a program then compile it into a .a file called libthenameofyourlibrary.a and put it in some directory. Then when compiling your main program use -L/path/to/the/libraries to make the compiler search that directory and put -lthenameofyourlibrary on the command line. eg
gcc foo.c -c -o foo.o ar rcs libs/libfoo.a foo.o ranlib libs/libfoo.a gcc baz.c -Llibs/ -lfoo -o baz

a.out is the default name given to a program if none was specified with the -o command line option. The reason for this is that it used to be the assembler output (Before seperate linking was used), thus a (the assembler) .out (output).


SeeAlso? MakefileHowto