cs154-2019 Lab 1

Introduction

By the end of this lab, you should be able to use the source code control system Subversion confidently, have a working checkout of your CNETID-cs154-aut-19 repository, use the build tool make, and create a Makefile. Because of the need to verify that every single student's svn repository is working, students should do this work individually.

Although we are not grading the lab, we will know that you haven't completed the lab by looking at your repository, and we may ask you to complete the lab if you are having problems with the basic usage of svn or make. If you report problems submitting Homework 1 by svn, the first question you may be asked is: "Did you have this problem when you completed Lab1?"

If you are not currently registered for this class, you will not be able to do the lab work, because you will not have a "CNETID-cs154-aut-19" svn repository created for you. If you only recently registered for cs154, you may have the same problem.

If you are not able to log into a CSIL Linux machine and get a working unix shell, see the Lab TA.

Subversion: How to start

Open a separate window for reading our Handing in work for cs154 page.

Read points #1 (you can ignore the sub-bullets for now), #2, and #3.

Read and follow the instructions in #4 and #5. If you are having problems with this step see the Lab TA, so that we can determine whether or not a CNETID-cs154-aut-19 repository exists for you on Phoenixforge.

Go to https://phoenixforge.cs.uchicago.edu/projects/CNETID-cs154-aut-19/repository). Change "CNETID" with your CNETID. This takes you to the web view of your lab1 directory. As is mentioned in point #7 of the "Handing in work for cs154" page, you should use this file, and the web page it links to, to double check (independent of using svn) that the files you intend to submit are really there.

Go into the "testSVN" part of lab1 in your new CNETID-cs154-aut-19 checkout (always replacing CNETID with your CNetID in the following), and then edit test.c (you can use your favorite editor instead of emacs):

cd CNETID-cs154-aut-19
cd lab1/testSVN
emacs test.c
Edit the comment at the top of the file test.c to remove Daniel Burnham's name, put your name in instead, remove the following blank line. Then save, and exit the editor. To take a look at the change:
svn diff
You should see some header information talking about what the base version number of the file in the repository is and a note that the file being compared against is the working copy (what subversion calls the set of files you have on-disk after performing a "checkout"). Notice that the top one is prefixed with "---" and the working copy is prefixed by "+++". These are the characters that appear in the contextual differences below to indicate a line that appears in the base version of the file ("-") or in your modified version ("+"). Make sure you understand what the diff is saying about which line is in which file!

Next, add a file to the directory and then see what changes are pending locally for commit back to the repository:

echo "" > documentation.txt
svn status
The status command will show you all of the files that have been modified, added, deleted, or have just appeared. Note that the file test.c will have an "M" before it, for modified. The file documentation.txt, though, will have a "?". This indicates that it is a new file on disk that has not yet been added to the repository. To do so:
svn add documentation.txt
svn status
And now, documentation.txt should have an "A" before it, for "added". Now try
svn delete test.c
This command should generate an error message, as you can't delete a modified file, you must revert it first. Reverting discards any changes you have made to a file and replaces it with the copy that you last got from the repository. Note that it does not copy down the most recent version in the repository - it just restores what you were working from originally.
svn revert test.c
svn delete test.c
svn status
Now it should say that you have removed the file. Let's make sure the files in the local directory are up to date:
svn update
Subversion should tell you what version of the files you currently have, but not make any local changes as you are already up to date. Unless you provide extra arguments, this command will check all of the files in and below the current directory to see if they need to be updated with new status from the repository. Your CNET-cs154-aut-19 repository in Phoenixforge will be regularly populated with new assignments and labs by the teaching staff, and running update from your CNET-cs154-aut-19 directory is how you will pick them up.

At this point, you can do an svn commit to submit the changes made above to the repository. Commit (and several other subversion commands) require a log message to associate with your change. You may either provide this at the command-line by using an argument of the form -m "Log message" or by setting the EDITOR environment variable and just running the command. For example, if you do the following, emacs will be launched whenever the svn client needs you to edit text. You should edit the file to contain a comment about the commit, save, and exit.

export EDITOR=emacs
svn commit
If svn cannot launch your editor and is not able to get a log message, you will get an error message stating that the commit failed, with a possibly confusing error message involving the file svn-commit.tmp. Just set your EDITOR environment variable or provide the -m "Log message" argument on the command-line and try again.

Get in the habit of writing log messages that concisely describe the reasons and goals for the changes that were made. Do not include your name or the date, as the repository already has that information.

Subversion: Exercises

Just follow the instructions for the exercises. Your lab submission for these will be the correct files and structure in your personal lab directory.

Exercise 1 (create a readme.txt)

If you followed the instructions above, you should have a ~/cs154/CNETID-cs154-aut-19 directory with a checkout of your personal files from Phoenixforge. If you skipped straight to here, go back and do that!

In the lab1 subdirectory of CNETID-cs154-aut-19, create a file called readme.txt. Put your name in it, then:

svn add readme.txt
svn commit readme.txt -m "Readme file"
That's it for the first exercise. You will be creating this file for every lab this quarter.

Exercise 2 (change some files)

In your CNETID-cs154-aut-19/lab1/ex2/ directory, there are some files. Find them, perform one (1) edit, one (1) deletion (with svn delete), and then commit your changes to the repository. Type the following commands, paste the output of the log into your readme.txt file from the previous step, and commit the changes.
svn up
svn log
"svn up" is a short form of "svn update".

Exercise 3 (creating and exploring history)

First, you'll need to create a directory to store the file that you will create. From within your ~/cs154/CNETID-cs154-aut-19/lab1 directory:
mkdir ex3
cd ex3
This will create a directory on your file system under your local copy of the files in the Subversion repository. In that directory, create a file named names.txt, put your family name in it and add that file.

If you just did an "svn add names.txt", then you should get an error from svn saying "svn: '.' is not a working copy." (Note: this is with svn version 1.6, as you learn with svn --version on a CSIL linux machine. Newer versions of svn generate a longer error message). Subversion relies on a .svn/ directory in each local directory to understand where the files are from and what the original copies were. In the case of a new directory, that .svn/ directory doesn't exist. But don't try to add it yourself: you must let svn create and manage the .svn directories and everything inside them. You will need to change to the parent directory and perform the svn add from there:

cd ..
svn add ex3
Now svn will add the ex3 directory and all of that directory's contents. If there were any files in that directory that you did not want to add, you would need to svn revert them. Now use svn to commit the directory and file additions.

Edit names.txt in the ex3 directory to have your full name (given and family) instead of just your family name. Do an svn diff, and record the output in your readme.txt. Now, commit the change.

Now use svn log to show the history of changes in names.txt:

svn log names.txt
There is a good section in the SVN book on examining history, including the use of svn log. In your lab1/readme.txt file, make a note of the revision numbers associated with the first (just family name) and with the second (full name) revision of the file. The revision number is the number following "r" on the line that notes the date of the revision. Also, notice that the lines in the log are in reverse chronological order: the most recent revision (higher revision numbers) are at the top.

If you do an svn diff at this point, you will see nothing, because there are no local changes in your working copy. However, you can see the difference between two specific revision numbers (learned from svn log):

svn diff -r P:Q
where P and Q are the revision numbers for before (P) and after (Q) the change. Save this output to your readme.txt, and compare it to your earlier recorded svn diff output, and make note of how they differ. This shows how you can use svn commands to understand the history of what has happened to your files.

Exercise 4 (on second thought...)

Continue to work in the lab1/ex3 directory for this exercise. We have decided to return to the previous version of names.txt, with just the family name. While you could simply edit the file to return it to its previous state, often you will need to undo a much more substantial change. Svn's merge command can make this much easier!

To start the merge, issue the following command, substituting Q and P with the after and before revision numbers from above. Note that order matters here!

svn merge -r Q:P names.txt
At this point, you should do an svn diff and look at the output. Please copy that output into your lab1/readme.txt file and commit. It should basically be the inverse of the output from the previous diff output.

You can now do an svn commit to commit your changes. If this had been a more complicated revision - in particular, one that was from the "middle" of a series of changes - there could have been a merge conflict and you might have had to do some small cleanup by hand before doing the commit. There's additional guidance on this in the Undoing Changes part of the SVN book.

Make: Introduction

Make (command-line program make) is a tool for building programs. It reads a "Makefile", expands the variables in it, and executes the rule requested when run from the commandline. If no rule is provided, make runs the first rule it finds in the makefile.

The makefile has two parts. Variables are of the form:

OBJS = foo.o bar.o baz.o blork.o
By convention, variables are in all capital letters. Rules are of the form:
clean:
rm -rf *.o

main: foo.o
gcc foo.o -o main
A rule is either a file name or a "phony" target. In either case, make looks on disk to see if there is a file with the name of the rule. If it does not exist or if a file with the rule name exists but is older than the list of files to the right of the colon, then make runs the command on the second line.

IMPORTANT! the second line starts with a tab character. If there is anything other than a tab at the start of that line, make will not run the commands.

Make has a comprehensive manual

Make: How to start

You should perform these actions in your CNETID-cs154-aut-19/lab1/testMake directory, but will not need to submit any changes.

Perform an ls and look at the files. There's a Makefile, two .c files, and two .h files. To build sources into an executable, just run:

make
You will see output from gcc compiling the two files and then linking them into a single binary. Now do another ls. You will see two .o files and an executable binary named main. Edit the file named foo.h to add a blank line someplace safe, save, and exit. Now re-run make as above.

You should see just the file foo.c rebuilt into foo.o, and then the binary main rebuilt. bar.o should not have been rebuilt. Read the Makefile to see why! When you ran make, it loaded the makefile and built the first target, main. Main depends on foo.o and bar.o. bar.o's files have not changed, so it did not need to be updated. However, foo.o's last modified date was older than foo.h's, so it was rebuilt. The important thing to take away from this is that the Makefile is what specified the dependency, not the compiler or source! If you don't keep the dependencies up to date, make will not know what to rebuild when a file is edited.

You can revert the change with the svn revert command:

svn revert foo.h

Make: Exercise

Your subversion user directory has been populated with a lab1/ex5 directory containing a Makefile and some sources. You will be editing and simplifying this project.

Part 1: If you look at the rules, they have a lot of copied code! Create variables CC for the compiler, CFLAGS for the compiler flags, etc. and move all constant statements to the top of the file as variables. As an example, if a rule looked like the following:

clean:
rm -rf a.o b.o c.o
You would turn it into:
RM = rm
RMFLAGS = -rf
OBJS = a.o b.o c.o

clean:
$(RM) $(RMFLAGS) $(OBJS)
Part 2: Listing all of those files both in the prerequisite line and on the commandline seems like a lot of redundant redundancy! Use automatic variables to simplify them. As an example, if a rule looked like the following:
frob: thing1.c thing2.c thing3.c
tweak -o frob thing1.c thing2.c thing3.c
You would turn it into:
frob: thing1.c thing2.c thing3.c
tweak -o $@ $^
Just svn commit the files when you are done. Be sure to run make clean followed by make periodically to check that you didn't break anything! There are multiple correct final solutions to this exercise.

About SSH

There is a lot of information about how to use SSH. Please see the following links for example:

Also it is convenient to set up a "passwordless" ssh (meaning where you don't have to type password everything). To set this up, please see the following links:

Finishing up

Go to https://phoenixforge.cs.uchicago.edu/projects/CNETID-cs154-aut-19/repository. Change "CNETID" with your CNETID , and look at the web page it links to. Note the web page shows you an alternate view, separate from command-line svn, of what you have in your repository.
(Based on the lab1 originally written for cs154 by Lars Bergstrom)