COMP 1020 Lab-1
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
COMP 1020
Lab-1
Evil Hangman
Prerequisite Knowledge:
This lab assumes you have completed Computing I at UMass Lowell and that you already have a CS account. If you do not have a CS account then please fill out the appropriate form and give it to your TA. The corresponding lab from Computing I that has bearing on this lab is given in full at the end of this document in case you need to review.
Directory structure:
1. Make a directory called “Spring2020” in your login directory and change to that directory. (relevant commands mkdir and cd).
2. Inside the Spring2020 directory make another directory called “COMP1020” and change to that directory.
3. Finally, make one more directory called “HANGMAN” and change to that directory. Type the command “pwd” and hit enter. pwd stands for print working directory. If you have done the previous steps correctly you should see something like the following but your directory structure will replace the /usr/cs/fac1/dbadams portion:
/usr/cs/fac1/dbadams/Spring2020/COMP1020/HANGMAN
The make utility:
In this portion of the lab we will begin setting up our environment so that we can quickly compile, clean up, test and run our lab project. We will begin by making a simple hello world program. Use your favorite editor (vi or emacs) to create and edit a file named “main.c”.
#include
int main(int argc, char* argv[]) { printf("Hello world!\n"); return 0; } |
We could compile the program from the command line using the command “gcc main.c” which would create an executable named a.out in the current working directory. Do this now and you should be able to execute the file simply by typing its name with the current directory before it as in “./a.out”. The resulting output should look like:
dbadams@cs3:~/Spring2017/COMP1020/HANGMAN$ ./a.out Hello world! |
Remove the executable file using the command “rm a.out” .
For most of the semester we will want to run gcc with the -Wall and --std=c99 options at a minimum. The following command line will create an executable named hello instead of one named a.out.
gcc -Wall --std=c99 -o hello main.c
We can use a utility program called make to make the compilation process much easier than typing everything out every time. It will especially help as we start moving towards projects that use multi-file compilation.
Use your favorite editor to create and edit a file named “Makefile” . Be sure that the name of your file begins with a capital letter M. Edit your Makefile so that it looks like the following:
hello: main.c gcc -Wall --std=c99 main.c -o hello |
This forms what the make utility calls a rule. The following is an edited excerpt from the gnu make utility manual:
A simple makefile consists of “rules” with the following shape:
target … : prerequisites … recipe … … A target is usually the name of a file that is generated by a program; examples oftargets are executable or object files. A target can also be the name of an action to carry out, such as ‘clean’ A prerequisite is a file that is used as input to create the target. A target often depends on several files. A recipe is an action that make carries out. A recipe may have more than one command, either on the same line or each on its own line. Please note: you need to put a tab character at the beginning of every recipe line! This is an obscurity that catches the unwary. Usually a recipe is in a rule with prerequisites and serves to create a target file if any ofthe prerequisites change. However, the rule that specifies a recipe for the target need not have prerequisites. |
If you have created and saved your Makefile correctly you can now type “make” at the command line and it will build the executable named hello which you can run by typing “./hello”.
One of the great features of having a Makefile is that it allows you to only compile the parts of the
project that need to be compiled because changes have been made since the last compilation. For large projects this can be a significant savings in time. You can witness this effect by typing make again after you have already built the project and it will tell you that hello is up to date.
dbadams@cs3:~/Spring2017/COMP1020/HANGMAN$ make gcc -Wall --std=c99 main.c -o hello dbadams@cs3:~/Spring2017/COMP1020/HANGMAN$ make make: `hello' is up to date. |
Let’s modify the Makefile so that it can split the compilation phase of a file from the linking phase of making an executable. We can do this by asking that the make utility first compile our source code into object code and then make a new rule to turn that object code into an executable. Modify your Makefile so that it looks like the following but remember to use tabs before all of your recipe lines.
hello: main.o gcc -Wall --std=c99 -o hello main.o main.o: main.c gcc -Wall --std=c99 -c main.c -o main.o |
The make utility, by default, will attempt to make the first target in the Makefile. In our case it will attempt to build the target hello. Since we have changed the rule to say that hello relies on a file named main.o (an object file, not an executable) then it will attempt to build it but since main.o does not yet exist it will look for a rule that describes how to make the target file main.o first. The main difference in the rule logic is that we use the compiler flag -c to tell the compiler that we want to create only object code from the main.c file. The object code for main.c can be compiled independently of all other source files and then linked together at some later time as needed. Type make and give the new Makefile a test run. Once you validate that it is working, let’s clean up the space a little. Right now if I type “ls -l", where the l is a lower case ‘L’, then I get the following output:
dbadams@cs3:~/Spring2017/COMP1020/HANGMAN$ ls -l total 11 -rwx------ 1 dbadams fac 8550 Jan 18 14:33 hello -rw------- 1 dbadams fac 99 Jan 18 13:35 main.c -rw------- 1 dbadams fac 1504 Jan 18 14:33 main.o -rw------- 1 dbadams fac 107 Jan 18 14:41 Makefile |
The important information shown is the number in the 5th column. It tells me how many bytes that particular file is taking up on our file system. Notice that my main.c file is fairly small but the executable,
hello, is quite a bit larger and, in practice, can be huge for large projects. If we are not currently testing
or running our code then we should do the rest of the users on our system a favor and clean up the files until we need to rebuild. We could do this by typing “rm hello main.o”. This will remove the executable named hello and the object file main.o to save space.
Instead of typing the command manually though each time, let’s make a rule in our Makefile called clean that will allow us to do this any time we want. Modify your Makefile so that it looks like the
following:
hello: main.o gcc -Wall --std=c99 -o hello main.o main.o: main.c gcc -Wall --std=c99 -c main.c -o main.o clean: rm hello main.o |
Since the make utility will, by default, try to make the first target in the file each time we can ask it to select a specific target by simply naming it. Type “make clean” at the command prompt now and it will automatically remove the appropriate files. You can type make followed by any of your target names and it will try to make just that.
We can use variables in a Makefile to make writing the rules easier. It is common practice to make a variable for your compiler, your compiler flags, and the object files used in your executable. Modify your Makefile so that it looks like the following:
CC = gcc CFLAGS = -Wall --std=c99 OBJECTS = main.o
hello: $(OBJECTS) $(CC) $(CFLAGS) -o hello $(OBJECTS) main.o: main.c $(CC) $(CFLAGS) -c main.c -o main.o clean: rm hello $(OBJECTS) |
Notice how creating the variable is as simple as giving it a name, an equals sign, and assigning a value. Later in the Makefile you can replace the variable name with its value simply by putting the name in parenthesis and putting a dollar sign in front of it as shown.
TA CHECKPOINT 1: Demonstrate to your TA the following:
A. Display your Makefile for your TA.
B. Demonstrate that you can build the project using make with no arguments and then run the executable.
C. Demonstrate that you can clean up the directory by typing make clean and then show the
directory using “ls -l”.
Valgrind:
We will be using a tool called valgrind throughout the term to help us test for memory leaks and understand memory management better in C. In order to make use of the tool we have to turn on debugging options for our compiler. We can do this simply by adding the -g option to our CFLAGS variable in our Makefile. Notice that after adding the -g flag to the compiler options that the object code and the executable are slightly bigger.
2022-03-23