hpc-primer

Compilers

Content

The two steps of compiling

Compiled languages rely on the compiler to transform source codes into an executable binary. This process involves two stages:

  1. compilation: transform the source code (usually) .c/.cpp files into object files .o
  2. linking: links the different .o together by matching the function calls, adding the libraries, etc.

The compiler

Two very common compilers exist: gcc and clang.

gcc is a GNU compiler featuring the GNU-GPL license. It used to be very common a few years ago but it has recently lost ground in favor of clang.

clang is the LLVM-based c/c++ compiler. It transforms the source code into LLVM sub-language, which is then in turn transformed into object files. The compiler is based on a permissive license, which makes is more attractive for companies than gcc. Also, the use of the LLVM-backend is shared by other languages like Julia. Due to its permissive license LLVM and clang are also used by software companies (intel, nvidia) as a basis to their own compilers.

It is common in the compilation process to define environment variables containing the compiler’s name. Usual names are CC=clang and CXX=clang. For the GNU compilers it becomes CC=gcc and CXX=g++ respectively.

To compile the code, simply enter

CXX [options] -o code.cpp

Many options are available for each compilers, see here for GNU and here for clang.

The linker

The linker is used to put together the object files into an executable or a library. Commonly called using ld every compiler suite features one. To make it easier you can link using your compiler:

CXX obj1.o obj2.o -o exe

You can also use the linker to create shared libraries using the -shared option. To create static libraries you should use ar instead.

Use external libraries

To use external libraries, after having installed them you can simply request the linker to link to it:

CXX -lfancy obj1.o obj2.o -o exe

The linker will look for a file named libfancy.so in your LIBRARY_PATH.

When linking to external libraries, the link can be dynamic or static. The former means that at the start of the exe, i.e. when typing ./exe, it will look for the different libraries (in your LIBRARY_PATH). This approach is opposed to the static linking where the library is included into the exe hence increasing its size.

The dynamic linking should be used whenever possible to ease its use, but it might also mean that sometimes the library are not found. Before starting the program you can check which library is found or missing using the tool ldd: ldd exe. Sometimes an improved version of this tool is useful, among others libtree.

However, it might be convenient to encode the path to the library that you use inside the exe as an in-between solution For example that path might be known at compile time only, or you may want to make sure that a given version of the library is used instead of the default one found in your LIBRARY_PATH. To enforce the exe to look into path/to/lib when loading the library libfancy.so you can use

CXX -Lpath/to/lib -lfancy -Wl,-rpath,path/to/lib

Advantages of clang

The compiler clang has some advantages compared to gcc, especially in the wide range of tools provided: clang-format, clang-tidy, etc.

Here is a non-exhaustive list of some features we have found useful over time:


home - compilation