(Optional) Unix Tools Assignment
This assignment is unofficial: you don't have to turn it in and it won't
count toward your grade. If you don't have a lot of experience with programming-in-the-large
in Unix, however, we strongly recommend that you complete it.
CISC 672 -Advanced Compiler Construction
(Not to be turned in)
The purpose of this assignment is to familiarize you with some of the
tools you will be using for the assignments this semester. You may already
know this stuff. If not, now's the time to learn it!
1. If you don't already have a university account,
you need to do this as soon as possible. You
do not need a CIS research account for this course. Learn how to log
in, both in person and remotely.
2. Try out the man command. At the prompt, type
man passwd
You will see the name of the passwd command, the list
of possible command line options, and a description of what
the command and the options do. You will find that almost
every command has more options than you realized, most
of which no one ever uses (try man cat!). Try also the
following commands (don't bother reading all the details about
every option - you won't remember them anyway).
man more
man less
man od
You can find out more about the man command (which stands for
"manual") by typing
man man
3. Write a "hello, world" program in C++. You can use the following
program.
#include <iostream.h>
main ()
// this is a comment
/* this is also
a comment */
{
int i;
cout << "Hello, world.\n";
i = 3;
cout << "i = " << i << "\n";
}
Use an editor (vi or emacs) to type this in to a file named "hello.cc"
(all C++ source files must end with ".cc"). For those not familiar
with C++ (learn fast!), the #include command tells the compiler to read
declarations from another file, in this case "stream.h". The pointy
brackets around the name tell the compiler to look in a library of
"standard" declaration files. Among other things, stream.h declares
the cout output stream, to which you can write things that you want to
appear on your terminal.
4. Compile the "hello, world" program using the command
g++ -v hello.cc
The -v option (for verbose) shows the name and arguments of
each program the compiler executes.
5. You should now have an executable file "a.out" which you can run by
simply typing
a.out
6. Read the man page for the compiler and find the command-line switches
that will cause it to save the various intermediate files you saw in
step 4 above. Take a look at these files, using 'more' (or 'less') to
look at text, and 'nm' or 'od' to look at object (machine language) files.
You can find out if a file is text or data by using the 'file' command
with the filename as the argument.
7. Type in the following lines into a file named "Makefile":
hello: hello.cc hello.h
echo first message
@echo another message
g++ -o hello hello.cc
Be warned that the indented lines have to start with a tab character,
not a series of spaces. Create a file called "hello.h" with the
following line in it:
const VAL = 3;
Finally, edit hello.cc and change it so that it reads as follows:
#include <stream.h>
#include "hello.h"
main ()
// this is a comment
/* this is also
a comment */
{
int i;
cout << "Hello, world."n";
i = VAL;
cout << "i = " << i << "\n";
}
Type make and notice the output. You should now have a file called
"hello" which you can run. Type make again and notice that it does not
recompile hello.
8. To see an example of separately compiled source files, type the
following into a file called "main.cc":
#include <iostream.h>
#include "dumb.h"
main ()
{
cout << "Hello, world.\n";
dumb (10);
}
and type the following lines into a file called "dumb.cc".
#include <iostream.h>
#include "dumb.h"
void dumb (int n)
{
cout << "n = " << n << "\n";
}
The header file "dumb.h" should have this line in it:
void dumb (int n);
Finally, change your Makefile to read as follows:
.cc.o:
g++ -c $*.cc
hello: main.o dumb.o
g++ -o hello main.o dumb.o
main.o: main.cc dumb.h
dumb.o: dumb.cc dumb.h
Now type make and observe what happens The strange looking new rule at
the top of the file tells make how to turn an arbitrary .cc file into a
.o file. A warning: make has some built-in rules. If you forget to
provide the .cc.o rule, make will use its own, and will call Sun's C++
compiler instead of the GNU compiler. Files created by the two
compilers are not compatible with one another. For the most part you
can run all the files of a program through either compiler, though
there are some differences in the language dialects they accept (the
PL/0 compiler that you will be modifying this semester is written in
the GNU dialect, and will not compile successfully with the Sun
compiler).
Change each of the files main.cc, dumb.cc, and dumb.h and run make
after each change. Notice that a change to a source file does not
force recompilation of unrelated source files.
9. Use gdb to run one of the above programs or one of your own. You
should change your Makefile so that it compiles your program
with the "-g" option, which facilitates debugging. You can
force make to use this option automatically by including it in the
.cc.o rule:
.cc.o:
g++ -c -g $*.cc
To use gdb type "gdb filename" where filename is the name of the
executable file. If you have not used gdb before, type "help" at the
prompt. Experiment with setting breakpoints and singlestepping, and
use the commands "list", "display", "where", and "print".
10. Tag files contain the source file locations of all function, macro,
and type definitions used in a programming project. Most
editors, including vi and emacs, are able to jump directly to
the source code location of a function, macro, or type definition,
as specified in the project's tag file.
To create tag files, edit Makefile and add the following makefile
target:
tags:
etags *.cc *.h
ctags *.cc *.h
Now run make tags to create tag files for both vi and emacs. To use
the tags, edit hello.cc (or any of the source files in our projects)
and type the appopriate command for your editor:
vi:
:ta dumb
emacs:
Meta-x find-tag
dumb
11. RCS (the revision control system) is a handy tool to keep track of the
history of changes made to files. It maintains only the diffs between
versions, minimizing space requirements. It allows you to "back out" to
a previous version of a file at any time. It also facilitates logging
of notes about your changes. Advanced features include a locking
mechanism to prevent partners on a team from making changes to the same
file at the same time and a "3-way merge" mechanism to combine changes
made independently to a common source.
Read the man pages for 'ci', 'co', and 'rcs'.
"Check in" your file with
ci hello.cc
Check it out with
co hello.cc
Make a change and check it in again. Now type
rlog hello.cc
to see a history of your changes.
Modified from Michael Scott's assignment.
pollock@cis.udel.edu