COMP 2103 Linux Tutorial - gcc - Self-study material

This file was last updated: September 4, 2006

Introduction

These notes discuss topics needed for submitting assignments:
gcc the C compiler
cat one way to display the contents of a text file
script used to create a listing record of what you did at the console
make run an automated session to compile a program

Using gcc:

gcc is the most common Unix C compiler; but it is available on many non-Unix systems as well: VMS, DOS, various version of MS windows, etc... Because of this, many "portable" applications are written using it.

gcc is a command line compiler; that is, gcc does not itself have a GUI. There are various Interactive Development Environments (IDEs) that bundle an editor, file manager, and execution control along with the compiler. Many programmers enjoy the flexibility that comes from simply using gcc at the command line. There are several gcc introductions available on the web; do a web search for "gcc introduction" and you will find a number of articles.

If you wish to compile C code to an executable, use the following syntax:

gcc -Wall -o <executable-name> <.c files>

For example, to compile a "main" program found in main.c and a library found in list.c into an executable program called "assign1prob1", I could use the command line:

gcc -Wall -o assign1prob1 main.c list.c
The -Wall option specifies that you want all warning messages to be reported to you.

The more common way of compiling executables using gcc (at least for big projects) is to compile each C file separately and then link them together afterwards. This is usually done using Makefiles (see below), but here is the syntax. Use the -c switch to compile each .c file to a .o file. Afterwards, use a gcc line referring to the .o files to link them together. (Note that, by default, with the "-c" option gcc will compile xyz.c into xyz.o, so, for example, the first line below could be written with the "-o main.o" arguments.)

Example using gcc to compile two files and then link them separately:

gcc -Wall -o main.o -c main.c
gcc -Wall -o list.o -c list.c
gcc -Wall -o assign1prob1 main.o list.o
See man gcc and info gcc for more information on gcc.

Concatenate and display files:

$ cat <file>

See  man cat  for more information.

Example 1: The command:     $ cat myfile
writes the contents of the file myfile to standard output. Standard output is usually your computer screen, but standard output can be "redirected" to a file or "piped" into another program.

Example 2: Concatenate two files into one.
The command:     $ cat doc1 doc2 > doc.all
concatenates the files doc1 and doc2 and writes the result to doc.all. The ">" is how output redirection is specified to the command interpreter (shell).

Example 3: Concatenate two arbitrary pieces of input with a single invocation.
The command:    $ cat start - middle - end > file
when standard input is a terminal, gets two arbitrary pieces of input from the terminal with a single invocation of cat.
Note, however, that if standard input for this command line is a regular file, this would be equivalent to the command:
cat start - middle /dev/null end > file
because the entire contents of the file would be consumed by cat the first time `-' was used as a file operand and an end-of-file condition would be detected immediately when `-' was referenced the second time. (Note: "/dev/null" is a "file" on every Unix (and Unix-like) system which is always empty, and to which programs can send their output if it is desired to discard the output.)

As with any redirection, redirecting the output of cat onto one of the files being read will cause the loss of the data originally in the file being read. For example,
$ cat filename1 filename2 >filename3
causes the original data in filename3 to be lost.

Create a typescript:

The script program makes a record of everything printed on your screen as you work.

The record is written to a file. If you don't provide a file name, the script file is saved as typescript.

The script session ends when CTRL-D is typed at the beginning of a line, or when the exit command is used.

script [-a] [filename]

(in the above, the optional "-a" would mean to append the session listing to filename rather than discarding the old contents of filename).

E.g.:

$ ./script a1.txt 
$ ./ls 
  ...
$ ./exit

creates a script a1.txt.

Makefiles:

"make" is a very useful utility program that can automate the process of compiling your programs. You use "make" by creating a file named Makefile that describes the steps you want done. You then run "make" to carry out the steps listed in your Makefile. Here is a straightforward Makefile that describes the way an executable file called edit depends on eight object files which, in turn, depend on eight C source and three header files.

In this example, all the C files #include defs.h, but only those defining editing commands #include command.h, and only low level files that change the editor buffer #include buffer.h.

edit: main.o kbd.o command.o display.o \
                insert.o search.o files.o utils.o
        gcc -o edit main.o kbd.o command.o display.o \
                insert.o search.o files.o utils.o

main.o: main.c defs.h
        gcc -c -Wall main.c

kbd.o : kbd.c defs.h command.h
        gcc -c -Wall kbd.c

command.o: command.c defs.h command.h
        gcc -c -Wall command.c

display.o : display.c defs.h buffer.h
        gcc -c -Wall display.c

insert.o: insert.c defs.h buffer.h
        gcc -c -Wall insert.c

search.o: search.c defs.h buffer.h
        gcc -c -Wall search.c

files.o: files.c defs.h buffer.h command.h
        gcc -c -Wall files.c

utils.o: utils.c defs.h
        gcc -c -Wall utils.c


clean:
        rm edit main.o kbd.o command.o display.o \
           insert.o search.o files.o utils.o
We split each long line into two lines using backslash-newline; this is like using one long line, but is easier to read. IMPORTANT: the lines describing the "actions" for each "target" must start with a tab character, not a bunch of spaces.

Simply executing make will use this Makefile to create the executable file called edit; simply type:

$ make
The "clean" rule from this same Makefile could be used to delete the executable file and all the object files from the directory. To do that, type:
$ make clean
In the example Makefile, the targets include the executable file edit and the object files main.o and kbd.o. The dependencies are files such as main.c and defs.h. In fact, each ".o" file is both a target and a dependency (depending on which rule you are looking at). Commands include gcc -c -Wall main.c and gcc -c -Wall kbd.c.

When a target is a file, it needs to be recompiled or re-linked if any of its dependencies change. In addition, any dependencies that are themselves automatically generated should be updated first. In this example, edit depends on each of the eight object files; the object file main.o depends on the source file main.c and on the header file defs.h.

A shell command follows each line that contains a target and dependencies. These shell commands say how to update the target file. As mentioned above, a tab character must come at the beginning of every command line to distinguish command lines from other lines in the Makefile. (Bear in mind that make does not know anything about how the commands work. It is up to you to supply commands that will update the target file properly. All make does is execute the commands in the rule you have specified when the target file needs to be updated.)

The target clean is not a file, but merely the name of an action. Since you normally do not want to carry out the actions in this rule, clean is not a dependency of any other rule. Consequently, make never does anything with it unless you tell it specifically. Note that this rule not only is not a dependency, it also does not have any dependencies, so the only purpose of the rule is to run the specified commands. Targets that do not refer to files but are just actions are called phony targets; do a web search on "phone targets" to learn more about them. Do a web search on "Errors in commands" (and use quotes around those words!) to see how to cause make to ignore errors from rm or any other command.