Compiling C and Java Code

Table of Contents

This page does not try to be an exhaustive introduction to compiling C and Java programs. Instead, it focuses on the most common compilation incantations (and options) in the course. Please suggest improvements!

1 Compiling C Code

1.1 Compiling a Single Souce File into an Executable

The following command uses the gcc C compiler to compile a program contained in a single file (modulo standard libraries) called single-file.c into an executable called output-file.

$ gcc -pedantic -Wall -g single-file.c -o output-file

The flag -Wall “enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros” (quoting from man gcc).

If you want, you can replace -Wall with -Wextra which enables even more warning flags. Use man gcc to search for -Wall and -Wextra for more information.

The -g flag inserts debugging information in the operating system’s native format into the program (executable or object code) that lets programs like gdb at the source level, e.g., give you line numbers for a crash, display the line of code executed etc.

The -pedantic flag turns on warnings demanded by strict ISO C and reject all programs that use forbidden extensions, and some other programs that do not follow ISO C+.

1.2 Compiling Several Source Files into an Executable

Like a single source file, but input all source file names:

$ gcc -pedantic -Wall -g file1.c file2.c ... fileN.c -o output-file

1.3 Compiling a One or More Source File(s) into Object Code(s) (Separate Compilation)

To compile into object code, and output .o files and do not perform any linking, insert the flag -c. This will make the input files produce .o files instead.

$ gcc -pedantic -Wall -g file1.c file2.c ... fileN.c -c

1.4 Linking Object Code into an Executable

Simply use the .o files as if they were .c files. You can mix .c and .o files in this step.

$ gcc -pedantic -Wall -g file1.o file2.o ... fileN.o -o output-file

1.5 Linking Against Additional Standard Libraries

Common linker options that you may need to use are -lm which means link with the math library and -lcunit which means link with the cunit libraries. Note that you must include e.g. math.h or CUnit/CUnit.h etc. to be able to compile against these APIs.

1.6 Adding Profiling Information

The gcc flag -pg generates extra code to write profile information suitable for the gprof program. Use this option for compiling all the source files you want to profile, and you must also use it when linking. (If you compile everything from source to executable in one go like Section 1.1, simply add -pg once and you are done).

1.7 TODO Adding Code Coverage Information

--coverage and -ftest-coverage

1.8 A Complete Example

Let a program “bread” consist of the files flour.c, water.c and misc.c. To compile an executable bread from these files, the simplest way possible is:

$ gcc -pedantic -Wall -g flour.c misc.c water.c -o bread

This compiles the program into object code, links the object code files together into an executable called bread, and throws away the object code.

To compile each file into object code separately, and finally link it into bread we could instead do:

$ gcc -pedantic -Wall -g flour.c -c
$ gcc -pedantic -Wall -g misc.c -c
$ gcc -pedantic -Wall -g water.c -c

This produces the object code files flour.o, misc.o and water.o. These can now be linked together to create bread:

$ gcc -pedantic -Wall -g flour.o misc.o water.o -o bread

The advantage of the latter approach is that if we make an internal change to misc.c and want to recompile, we only need to recompile misc.c into misc.o and relink. If compiling flour.c and water.c takes a lot of time (many program has 1000’s of .c files that can take seconds to compile), we probably shaved off a lot of time by only redoing the necessary steps.

If you use a Makefile, it is easy to always use the fancy latter option.

2 TODO Compiling and Running Java Code

In contrast to the C compiler, the Java compiler will find dependencies on files other than the one given as argument to the javac command.

  • Differences between Java 1.8 and Java 9; what’s on the Ubuntu 18.04 machines?
  • -Xlint, -Xlint:unchecked
  • -ea
  • -d
  • -cp

Questions about stuff on these pages? Use our Piazza forum.

Want to report a bug? Please place an issue here. Pull requests are graciously accepted (hint, hint).

Nerd fact: These pages are generated using org-mode in Emacs, a modified ReadTheOrg template, and a bunch of scripts.

Ended up here randomly? These are the pages for a one-semester course at 67% speed on imperative and object-oriented programming at the department of Information Technology at Uppsala University, ran by Tobias Wrigstad.

Author: Tobias Wrigstad

Created: 2019-04-19 Fri 17:39