CS1010 Compilation Guide
We have automated the steps to compile C programs for all CS1010 assignments and exercises by providing Makefile
and compile_flags.txt
. The following guide explains how one can compile a C program with clang
directly, without using Makefile
. This information is useful once students graduated from CS1010 and go to other modules/scenarios where Makefile
is not provided.
1. Compiling a standalone C program
Suppose we have a standalone C program teh.c
that does not use any external libraries. We can compile the program using the command
1 |
|
This command should create an executable called a.out
in the current directory, which you can then run with:
1 |
|
2. Renaming an executable file
The name a.out
is an abbreviation for assembler output, a name that many compilers kept as the default output name since the 60s. We should, however, give our executable more descriptive name, by using the -o
flag. (o
is the mnemonic for output).
1 |
|
or
1 |
|
The command above would create an executable called teh
.
Beware of the order
If you are not careful and run the following command instead:
1 |
|
clang
would overwrite your code teh.c
-- all your hard work will be gone!!
3. Warning for possible bugs
The clang
checks for syntax errors in your C files -- i.e., things that violate the C syntax rules. The compiler, however, is smart enough to identify possible bugs -- errors that will cause your program to behave incorrectly, even if the syntax follows C's rules. You can ask clang
to warn you about this, using the -W
flag (W
is the mnemonic for warning -- note the capital W). The manual for clang
lists different types of warnings that clang
can warn you about. For instance, we can ask clang
to warn us by enabling -Wall
warnings. The command to do so is:
1 |
|
For beginners, it is highly recommended that you always compile with at least -Wall
, -Wextra
, and the -Wpedantic
flag.
clang warning flags
-Wall
in clang
does not catually enable all warnings.
-Weverything
enables every warning but it could be overwhelming
for beginners. In CS1010 assignments, we will provide a Makefile
so that you can use make
to automate the compilation process.
Appropriate warning flags will be enabled for you.
4. Generating additional information for debugging
In order to use the debugger lldb
to trace through and debug your program, clang
needs to generate additional information and store them in the executable file. We can instruct clang
to generate them with the flag -g
(g
for generate).
1 |
|
It is recommended that you always compile with -g
flags during the development phase. If you need to measure the performance (e.g., how fast it runs) of your program or when you are releasing the program to the public, you can remove the -g
flag and compile with the optimization flags (e.g., -O
) instead.
5. Linking with the standard library
To link with a standard library, we use the -l
flag to specify the name of the library to link. For instance, to link with the C standard math library (abbreviated as m
), you issue the command:
1 |
|
6. Linking with 3rd party library
By default, clang
looks for headers and libraries in the systems directories (/usr/include
, /usr/lib
, etc) and the current working directory.
If you use a third-party library, you usually need to tell clang
where to look for the corresponding headers and libraries. You can use the -I
flag and the -L
flag for these purposes. For instance, if you have a library installed under your home called citadel
, and the file citadel.h
can be found under ~/citadel/include
and the file libcitadel.a
can be found under ~/citadel/lib
, to tell clang
where to find these files, you can compile with:
1 |
|
For instance, to link with the CS1010 I/O library on the PE nodes, you can run
1 |
|
7. The file compile_flags.txt
The list of compilation flags can get lengthy. For CS1010 assignments/exercises, we have included all the necessary flags in a file called compile_flags.txt
. We can then pass this file with the @
prefix to clang
. clang
will read the flags from the file.
1 |
|
8. Combining multiple source files into an executable
Sometimes it is useful to separate the source code for an executable into multiple files. For instance, you may have a file main.c
that contains the main
function, and another file foo.c
that contains the function foo
. You can compile these two files into an executable with the command:
1 |
|
Alternatively, you can compile the C files separately into object files and then link them together:
1 2 3 |
|
The flag -c
tells clang
to compile the source file into an object file. The object file is a binary file that contains the machine code for the functions in the source file. The object file has the same name as the source file, but with the extension .o
. The flag -c
does not produce an executable.
Finally, the last command (without the -c
flag) links the object files together into an executable. Linking cross references the function names in the object files and resolves them, ensuring that every function that is invoked is defined somewhere in the object files. If a function is not defined, clang
will issue an error message.
Note that you can mix C files and object files in one compilation command:
1 2 |
|