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.
                        CSC 254 - Programming Systems
  
                                September 2016
  
                            Homework Assignment #0
                             (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, in which case feel free to just skim it.  If not, now's the
  time to learn!
  
  1.  If you don't already have an account on the CS research machines,
      see Marty Guenther in CSB 735.  Learn how to log in, both in
      person and remotely.  Also learn to use an X window server for
      graphical interaction with remote clients.  MacOS comes with X
      windows built-in.  Free X servers for Microsoft Windows (e.g.
      Cygwin/X) are also widely available.

  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 less
             man ls
             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>
             using namespace std;
  
             int main()
             // this is a comment
             /* this is also
                  a comment */
             {
                   int i;
                   cout << "Hello, world.\n";
                   i = 3;
                   cout << "i = " << i <<endl;
                   return 0;
             }
  
      Use an editor (vim or emacs) to type this into a file named "hello.cc".  
      For those not familiar with C++ (learn fast!), the #include command 
      tells the compiler to read declarations from another file.  The pointy
      brackets around the name tell the compiler to look in a library of
      "standard" declaration files.
  
  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 'less' to look at
      text, and 'nm', 'od', or 'objdump' 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 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 int VAL = 3;
  
      Finally, edit hello.cc and change it so that it reads as follows:
  
             #include <iostream>
             #include "hello.h"
             using namespace std;
  
             int main()
             // this is a comment
             /* this is also
                  a comment */
             {
                   int i;
                   cout << "Hello, world.\n";
                   i = VAL;
                   cout << "i = " << i <<endl;
                   return 0;
             }
  
      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 (because you haven't changed it).
  
  8.  To see an example of separately compiled source files,  type the
      following into a file called "main.cc":
  
             #include <iostream>
             #include "dumb.h"
             using namespace std;
  
             int main()
             {
                   cout << "Hello, world.\n";
                   dumb(10);
                   return 0;
             }
  
      and type the following lines into a file called "dumb.cc".
  
             #include <iostream>
             #include "dumb.h"
             using namespace std;
  
             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, which
      may not call g++ the way you expect.
  
      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 single-stepping, 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 vim 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 vim and emacs.
       To use the tags, open hello.cc in your favorite editor, and type
       the appopriate command:
  
              vim:
                    :ta dumb
  
              emacs:
                    Meta-.
                    dumb

       To return to where you came from, type ^t (control-t) in vim, or
       Meta-* in emacs.
  
  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 -l hello.cc
  
       Check it out with
  
              co -l hello.cc
  
       Make a change and check it in again.  Now type
  
              rlog hello.cc
  
       to see a history of your changes.

       NB: RCS is very old.  There are several substantially more capable
       alternatives, including cvs (which is built on rcs, and still
       pretty old), svn, git, mercurial, and perforce.  For this course
       you won't need the power of these newer systems, but feel free to
       learn about them if you like: they'll almost certainly come in
       handy in your future career.
  

Last Change: 31 August 2016 / Michael Scott's email address