Program Management: Header Files and make
Goals:
This lab provides practice dividing a program into pieces, compiling
those pieces separately, linking components together to form an
executable, and automating this process using the GNU utility
make
.
Activities for this laboratory exercise are organized into two parts:
Part A: Header and Implementation Files
The work that follows utilizes the Scheme-like lists
program scheme-lists.c
from the
recent lab.
-
For safety, make a new directory for multi-file scheme-lists and copy your
scheme-lists.c
program to it. For example:mkdir make-scheme-lists cp scheme-lists.c make-scheme-lists/
-
Separate the code in your
scheme-lists
program into three files as follows:-
scheme-lists.h
— containing the definition ofSTRMAX
, thestruct node
andnode_t
types, and all of the function prototypes. -
scheme-lists.c
— containing the implementation of all of yourscheme-lists
functions, exceptmain
. -
scheme-lists-test.c
— containing yourmain
function.
In order to get these source files to compile, both
scheme-lists.c
andscheme-lists-test.c
should contain the following line at the top of the file:#include "scheme-lists.h"
You should not
#include
your source filescheme-lists.c
anywhere. (It is good practice to only include header files, and not implementation files, in other source files.)As discussed in the reading, your header file should contain the following lines, and they should surround all type definitions and function declarations in the file.
#ifndef __SCHEME_LISTS_H__ #define __SCHEME_LISTS_H__ ... #endif
-
-
Defining a program made up of several pieces requires a more
careful treatment, as we explore below.
-
Try building your program with the following command, typed at
the shell prompt. Explain why it gives the error it
does.
clang scheme-lists-test.c
-
Compile each of your source files (to create object files, but
still not an executable program) with the following commands,
typed at the shell prompt:
clang -Wall -c scheme-lists.c clang -Wall -c scheme-lists-test.c
Use the shell commandls
to check that the object files were produced. -
Now create an executable file with the following command:
clang -o scheme-lists-test scheme-lists-test.o scheme-lists.o
Check that the filescheme-lists-test
exists withls
and then run the resulting program. -
Finally, compile both source files and link the resulting
object files together with the following single command.
clang -o scheme-lists-test scheme-lists-test.c scheme-lists.c
Note, however, that waiting for large programs to build this way quickly becomes tedious since every source file must be reqcompiled from scratch.
-
Try building your program with the following command, typed at
the shell prompt. Explain why it gives the error it
does.
As you finish this part of the lab, note that you have converted your
scheme-lists
code into an abstract data
type (ADT). By listing the function prototypes, the header
file tells other programmers
what operations are supported by the data type. It does not
specify how they are implemented; that is done in the
implementation file.
Your data type may now be used in client programs, such as
scheme-lists-test.c
. Doing so requires only the
following simple steps:
-
#include
the ADT's header file in the client source file, and - include the object file associated with the ADT in the link command when building the client program.
Part B: make and Makefiles
The reading for this
lab describes a
detailed Makefile with
directions for compiling, linking, and cleaning files related to a
namelist.c program. This part
considers a simplified Makefile
.
-
Copy a simplified Makefile to
your
make-scheme-lists
directory and review it. Explain what is accomplished by each line in the file. -
Adapt the
Makefile
so that it can be used to build yourscheme-lists-test
program. (When you do this you will of course, want to change the "Author" comment at the top of the file, but giving credit to the original.) -
In the terminal window, type these commands:
ls
— to see a listing of your filesmake clean
— to prepare for a fresh buildls
— to view the resultmake
— to compile and link all source filesls
— to view the result
-
Make a change in the source file
scheme-lists.c
. For example, you could add or modify aprintf
statement in some function. Which rules in the makefile do you expect will be run, the next time you invokemake
, as a result of this change?Run
make
again, to verify your prediction experimentally. -
Make a change in the header file
scheme-lists.h
. For example, you could add a comment to the top of the file. Which rules in the makefile do you expect will be run, the next time you invokemake
, as a result of this change?Run
make
again, to verify your prediction experimentally.
If You Have Time
-
Take a look at GNU's documentation regarding make and makefiles.
Note that this documentation is very lengthy, and it is not necessary for you to read or understand all of it in order to begin using makefiles. Reading through Section 3.2 or so provides a good introduction to the topic.