CS 3130 Fall 2025
Study MaterialsMain/ReadingsOffice HoursPoliciesHWs+LabsQuizzesSubmissionSchedule
This website may change (perhaps significantly) before the semester starts.
  • 1 (review?) clang/gcc modes
  • 2 selected other clang/gcc options
  • 3 producing and using libraries
    • 3.1 producing and using static libraries (on Unix-like systems)
    • 3.2 producing and using dynamic libraries (on Linux)
  • 4 Glossary
  • 5 Additional resources

Changelog:

  • 17 Jan 2024: merge text previously in glossary under makefiles into here; mention explicitly that standard library is linked by default
  • 20 Jan 2025: note re: clang availabiity
  • 21 Jan 2025: adjust note re: clang availability

1 (review?) clang/gcc modes

Note: to enable using clang on portal, you can run module load gcccore/13.2.0 clang

The clang program (or the gcc or cc programs, which work essentially the same way) can perform assembly, linking, and compilation, depending on how it is invoked:

  • compile only: clang -S foo.c — compile the source file foo.c into the assembly file foo.s. Note that this also uses any files foo.c #includes.
  • assemble only: clang -c foo.s — assemble foo.s into the object file foo.o
  • link only (executable): clang foo.o bar.o quux.o — link the object files foo.o, bar.o, and quux.o into an executable a.out1. By default this also links in the standard library (which contains functions like printf and malloc) to the executable.
  • link only (shared library): clang -shared foo.o bar.o quux.o — link the object files foo.o, bar.o, and quux.o into a shared library a.out

Or you can perform multiple at once:

  • compile+assemble: clang -c foo.c — compile and assemble foo.c, to produce the object file foo.o.
  • compile+assemble+link: clang foo.c bar.c — compile and assemble foo.c, and compile and assemble bar.c, and link them together to generate a.out.

You can specify a different output file for any of these commands with -o FILENAME, for example:

  • clang -o exec foo.o bar.o quux.o -or- clang foo.o bar.o quux.o -o exec — link foo.o, bar.o, and quux.o into the executable exec (instead of a.out)

2 selected other clang/gcc options

  • -Wall: enable all warnings
  • -g: generate information for debuggers
  • -Og, -O1, -O2, -O3, -Os, -O: enable various amounts/types of compiler optimizations. -Og optimizes for debugging; -Os optimizes for size; otherwise, 1 or 2 or 3 set various levels of aggressiveness with which to apply optimizations
  • -std=c11, -std=c99, -ansi, …: ask the compiler/standard library to follow a particular version of the C standard
  • -fsanitize=address, -fsanitize=undefined, -fsanitize=thread, -fsanitize=leak: enable various sanitizers that check for certain types of errors/bugs as the resulting executables run (must be supplied both when compiling and linking)

3 producing and using libraries

A library is a collection of related implementations. For C or C++, a libary is generally provided as a library file and (one or more) header files.

There are two types of library files:

  • dynamic libraries, which are loaded from the library file while an executable is running. These most commonly use the extension .so (Linux), .dylib (OS X), or .dll (Windows).

  • static libraries, which are embedded into an executable when it is linked. These most commonly use the extension .a (Linux, OS X), .lib (Windows).

3.1 producing and using static libraries (on Unix-like systems)

Static libraries on most Unix-like systems are archives of object files produced with the ar command. After generating object files,

ar -rcs libfoo.a quux.o bar.o

will create a library libfoo.a.2

Then, if the resulting libfoo.a is placed in one of the standard system directories3 a command like

clang -o exec main.o -lfoo

will create an executable linking main.o and the library together. You should usually put the -lXXX flags last on the command line: the linker processes the files listed in order and, when adding a static library, by default only includes parts that appear to be needed by files it has already processed.

If libfoo.a is not placed in one the standard system directory, then add -L:

clang -o exec main.o -LdirectoryContainingLibFoo -lfoo

3.2 producing and using dynamic libraries (on Linux)

On Linux, files that will be used in a dynamic library need to be compiled specially so they can be loaded anywhere in memory. This can be done by using the -fPIC option when compilng.

Then, you can generate a library by linking with -shared as in:

clang -shared -o libfoo.so bar.o quux.o

Then, like static libraries, if the resulting libfoo.so is placed in one of the standard system directories4 a command like

clang -o exec main.o -lfoo

will create an executable exec that loads libfoo.so at runtime.

If libfoo.so is not placed in one these directories, then you will need to:

  • tell the compiler how to find the library when generating the executable by adding -Ldirectory to specify the directory where libfoo.so is:

    clang -o exec main.o -LdirectoryWithLibFoo -lfoo
  • tell the executable how to find the library when it runs by either:

    • specifying an rpath (runtime path) when generating the executable specifying an additional directory to search:

       clang -o exec main.o ... -Wl,-rpath,directoryWithLibFoo

      (-Wl,X says to pass an option to the linker program, which is typically ld on Linux.)

      This is specifies separately from the -L option so you can have libraries in different locations when executables are generated versus when executables are run.

    • setting the LD_LIBRARY_PATH environment variable to contain the directory containing the library when the executable is run. So instead of running the shell command ($ represents a shell prompt):

       $ ./exec ...

      you could do

       $ LD_LIBRARY_PATH=directoryWithLibFoo ./exec ...

      or

       $ export LD_LIBRARY_PATH=directoryWithLibFoo
       ...
       $ ./exec ...

      You can also use syntax like LD_LIBRARY_PATH=directory1:directory2:directory3 to specify multiple directories.

4 Glossary

Header File

A file (.h for C; .h, .hpp, .H or .hh for C++) that provides

  • the signatures of functions, but not their definitions
  • the names and types of global variables, but not where in memory they go
  • typedefs and #defines
Object File
A file (.o on most systems, .obj on Windows) that contains assembled binary code in the target ISA, with metadata to allow the linker to place it in various locations in memory depending on what other files it is linked with.
Standard Library

A library to which every program is linked by default. Virtually every language has a standard library, which does much to define the character of the language.

The C language’s standard library is typically called libc and is defined by the C standard (see https://en.wikipedia.org/wiki/C_standard_library); there are several implementations of it, but glibc is probably the most pervasive on Linux.

Static Library
A file (.a on most Unix-like systems, .lib on Windows) that contains one more more object files together with metadata needed to connect them into a running code system by the linker. This compile-time linkage means that each executable has its own copy of the library stored internally to the file, without external dependencies.
Source File

A file (.c for C, .cpp, .C, or .cc for C++) that provides

  • the implementation of functions
  • the declaration and implementation of provided helper functions
  • the memory in which to store global variables

5 Additional resources

On Clang and GCC options:

  • Clang manual section on options
  • GCC manual section on options

On linking and libraries:

  • Ulrich Drepper, How To Write Shared Libraries (2011) (also provides an explanation of how dynamic linking works on Linux)
  • toolchains.net — index of references on compiler toolchains, including many references about what linkers do

  1. This is the default name on Unix-like systems; on native Windows, it may be a.exe.↩︎

  2. The c option says to create a new archive silently if one does not exist; the r option to add to or update the archive; and the s option to create an index of the object files for the linker to use. Sometimes you might see the index creation done by a separate ranlib command.↩︎

  3. clang -print-search-dirs lists these↩︎

  4. clang -print-search-dirs lists the directories that are searched when the executable is geneated. For loading libraries when an executable runs, the system searches /lib, /usr/lib, and directories specified by the configuration file /etc/ld.so.conf.↩︎

CS 3130 Fall 2025

  • Charles Reiss and Kevin Skadron
  • creiss@virginia.edu
By Charles Reiss. Released under the Creative Commons License CC-BY-NC-SA 4.0.