
# 24.1 An introduction to binary files

Top > An introduction to binary files
Purpose

In this section you will be introduced to the different types of binary files that you encounter while programming.

One of the first things you become aware of when you start programming is the distinction between the readable source code, and the unreadable, but executable, program code. In this tutorial you will learn about a couple more file types:

• A source file can be compiled to an object file, which is

a bit like a piece of an executable: by itself it does nothing, but it can be combined with other object files to form an executable.

• A library is a bundle of object files that can be used to

form an executable. Often, libraries are written by an expert and contain code for specialized purposes such as linear algebra manipulations. Libraries are important enough that they can be commercial, to be bought if you need expert code for a certain purpose.

You will now learn how these types of files are created and used.

# 24.2 Simple compilation

Top > Simple compilation
Purpose

In this section you will learn about executables and object files.

Let's start with a simple program that has the whole source in one file. \listing{One file: hello.c}{tutorials/compile/c/hello.c} Compile this program with your favourite compiler; we will use gcc in this tutorial, but substitute your own as desired. As a result of the compilation, a file a.out is created, which is the executable.

hello world

You can get a more sensible program name with the -o option:
hello world


Now we move on to a program that is in more than one source file. \listing{Main program: fooprog.c}{tutorials/compile/c/fooprog.c} \listing{Subprogram: fooprog.c}{tutorials/compile/c/foosub.c} As before, you can make the program with one command.

hello world

However, you can also do it in steps, compiling each file separately and then linking them together.
hello world

The -c option tells the compiler to compile the source file, giving an object file . The third command than acts as the linker , tieing together the object files into an executable. (With programs that are spread over several files there is always the danger of editing a subroutine definition and then forgetting to update all the places it is used. See the make' tutorial, section  , for a way of dealing with this.)

# 24.3 Libraries

Top > Libraries
Purpose

In this section you will learn about libraries.

If you have written some subprograms, and you want to share them with other people (perhaps by selling them), then handing over individual object files is inconvenient. Instead, the solution is to combine them into a library. First we look at static libraries , for which the archive utility ar is used. A~static library is linked into your executable, becoming part of it. This may lead to large executables; you will learn about shared libraries next, which do not suffer from this problem.

Create a directory to contain your library (depending on what your library is for this can be a system directory such as /usr/bin), and create the library file there.

The
\indextermtt{nm} command tells you what's in the library:


../lib/libfoo.a(foosub.o):
00000000 T _bar
U _printf

Line with T indicate functions defined in the library file; a~U indicates a function that is used.

The library can be linked into your executable by explicitly giving its name, or by specifying a library path:

# or
hello world

A third possibility is to use the LD_LIBRARY_PATH shell variable. Read the man page of your compiler for its use, and give the commandlines that create the foo executable, linking the library through this path.

Although they are somewhat more complicated to use, shared libraries have several advantages. For instance, since they are not linked into the executable but only loaded at runtime, they lead to (much) smaller executables. They are not created with ar, but through the compiler. For instance:



../lib/libfoo.so(single module):
00000fc4 t __dyld_func_lookup
00000fd2 T _bar
U _printf
00000fb0 t dyld_stub_binding_helper

Shared libraries are not actually linked into the executable; instead, the executable will contain the information where the library is to be found at execution time:
hello world

The link line now contains the library path twice: \begin{enumerate}

• once with the -L directive so that the linker can resolve

all references, and

• once with the linker directive \verb+-Wl,-rpath,pwd`/../lib+ which stores the path into the executable so that it can be found at runtime. \end{enumerate} Build the executable again, but without the -Wl directive. Where do things go wrong and why? You can also fix this problem by using LD_LIBRARY_PATH. Explore this.