What it is
Clang is a C, C++, and Objective-C compiler that provides fast compilation, rich diagnostics, and a flexible architecture for building and analyzing code.
Installation
Linux (Debian/Ubuntu)
sudo apt update
sudo apt install clang
Linux (Fedora)
sudo dnf install clang
macOS
Clang is included with Xcode. Install Xcode from the App Store, then open Xcode and accept the license agreement. The command-line tools can be installed separately:
xcode-select --install
Windows
Clang can be installed as part of the LLVM project. Download the installer from the official LLVM releases page: https://releases.llvm.org/. Alternatively, it can be installed via package managers like Chocolatey:
choco install llvm
Ensure the LLVM bin directory is added to your system’s PATH.
Core Concepts
- Frontend: Parses the source code, performs semantic analysis, and generates an intermediate representation (IR).
- Optimizer: Transforms the IR to improve performance and reduce code size.
- Backend (Code Generator): Translates the optimized IR into machine code for a specific target architecture.
- Intermediate Representation (IR): An abstract representation of the program code that is independent of the source language and the target machine. LLVM IR is commonly used.
- Diagnostics: Clang’s advanced error and warning messages, often providing suggestions and highlighting the exact location of issues.
Commands / Usage
Compiling and Linking
Compiling a single C file
clang hello.c -o hello
Compiles hello.c and creates an executable named hello.
Compiling a single C++ file
clang++ main.cpp -o my_program
Compiles main.cpp using the C++ frontend and creates an executable named my_program.
Compiling multiple source files
clang main.c utils.c -o my_app
Compiles main.c and utils.c and links them into a single executable my_app.
Creating an object file
clang -c main.c -o main.o
Compiles main.c into an object file main.o without linking.
Linking object files
clang main.o utils.o -o my_app
Links pre-compiled object files main.o and utils.o into an executable my_app.
Specifying C standard
clang -std=c11 my_code.c -o c11_app
Compiles my_code.c using the C11 standard. Other common standards include c99, c++14, c++17, c++20.
Specifying C++ standard
clang++ -std=c++17 my_cpp_code.cpp -o cpp17_app
Compiles my_cpp_code.cpp using the C++17 standard.
Enabling C++ exceptions
clang++ -fexceptions my_cpp_code.cpp -o cpp_exceptions_app
Enables C++ exception handling. This is usually enabled by default for C++ but can be explicitly set.
Disabling C++ exceptions
clang++ -fno-exceptions my_cpp_code.cpp -o cpp_no_exceptions_app
Disables C++ exception handling.
Enabling C++ RTTI (Run-Time Type Information)
clang++ -frtti my_cpp_code.cpp -o cpp_rtti_app
Enables RTTI, necessary for dynamic_cast and typeid.
Disabling C++ RTTI
clang++ -fno-rtti my_cpp_code.cpp -o cpp_no_rtti_app
Disables RTTI.
Specifying optimization level
clang -O2 my_code.c -o optimized_app
Compiles with optimization level 2. Common levels:
-O0: No optimization (default).-O1: Basic optimization.-O2: More optimization.-O3: Aggressive optimization.-Os: Optimize for size.-Oz: Optimize aggressively for size.-Ofast:-O3plus aggressive floating-point optimizations.
Debugging information
clang -g my_code.c -o debug_app
Includes debugging information in the executable, allowing debuggers like GDB or LLDB to be used effectively.
Warning flags
clang -Wall -Wextra -pedantic my_code.c -o warnings_app
Enables a wide range of warnings (-Wall), extra warnings (-Wextra), and pedantic warnings (-pedantic) to catch potential issues.
Treat warnings as errors
clang -Werror my_code.c -o error_on_warning_app
Treats all compiler warnings as errors, causing compilation to fail if any warnings are issued.
Include paths
clang main.c -I/usr/local/include -o app_with_includes
Adds /usr/local/include to the list of directories searched for header files.
Library paths
clang main.c -L/usr/local/lib -lmylib -o app_with_libs
Adds /usr/local/lib to the list of directories searched for libraries and links against libmylib.so (or .a).
Linking a specific library
clang main.c -lm -o math_app
Links the math library (libm.so or .a).
Generating a shared library
clang -shared -fPIC my_lib.c -o libmylib.so
Compiles my_lib.c into a position-independent code shared library libmylib.so.
Generating a static library
clang -c my_lib.c
clang -static -cr libmylib.a my_lib.o
Compiles my_lib.c to my_lib.o, then creates a static library libmylib.a from it.
Specifying target architecture
clang --target=arm64-apple-ios14.0 main.c -o ios_app
Compiles main.c for the specified target architecture and OS version.
Language Features and Extensions
Enabling Objective-C ARC (Automatic Reference Counting)
clang -fobjc-arc main.m -o arc_app
Enables ARC for Objective-C code.
Enabling Objective-C garbage collection (deprecated)
clang -fobjc-gc main.m -o gc_app
Enables garbage collection for Objective-C code.
Enabling GNU extensions
clang -std=gnu11 main.c -o gnu_app
Enables GNU extensions for the specified standard (e.g., gnu11 for C).
Preprocessing
Preprocessing only
clang -E main.c -o main.i
Runs only the preprocessor on main.c, outputting the result to main.i.
Assembling only
clang -S main.c -o main.s
Compiles main.c to assembly code (main.s) without assembling it into machine code.
Generating LLVM IR
clang -emit-llvm main.c -S -o main.ll
Emits LLVM IR in human-readable format (.ll) instead of machine code.
Generating bitcode
clang -emit-llvm -c main.c -o main.bc
Emits LLVM IR in a compact, binary format (bitcode, .bc) suitable for later linking or optimization.
Analysis and Diagnostics
Generating a compilation database (for IDEs like VS Code, CLion)
clang -MJ compile_commands.json main.c -c
Generates a compile_commands.json file that IDEs can use to understand your project’s build settings.
Suppressing specific warnings
clang -Wno-unused-variable my_code.c -o no_unused_var_app
Disables warnings about unused variables. To suppress other warnings, replace unused-variable with the specific warning name (e.g., unused-function, shadow).
Verbose output
clang -v main.c -o verbose_app
Shows the commands being executed by Clang, including the compiler, assembler, and linker invocations.
Showing internal passes
clang -mllvm -debug-pass=Arguments my_code.c -o debug_passes_app
Prints the optimization passes that LLVM runs during compilation.
Linking
Creating an executable from object files and libraries
clang main.o utils.o -L/path/to/libs -lmylib -o final_app
Links main.o and utils.o, searching for libraries in /path/to/libs and linking against libmylib.
Creating a dynamic executable (default on most systems)
clang main.c -o dynamic_exe
Creating a static executable
clang main.c -static -o static_exe
Attempts to link all libraries statically. This may not be possible for all libraries.
Linking against a specific C++ standard library
clang++ main.cpp -stdlib=libc++ -o cpp_libcxx_app
Links against the libc++ standard library (common on macOS and FreeBSD).
clang++ main.cpp -stdlib=libstdc++ -o cpp_libstdcxx_app
Links against the libstdc++ standard library (common on Linux).
Miscellaneous
Print version
clang --version
Displays the Clang compiler version.
Help
clang --help
Shows a summary of available command-line options.
Common Patterns
Building a simple C project with multiple files:
# Compile each file into an object file
clang -c main.c -o main.o
clang -c utils.c -o utils.o
# Link object files into an executable
clang main.o utils.o -o my_program
Building a C++ project with flags:
clang++ -std=c++17 -Wall -Wextra -O2 main.cpp utils.cpp -o my_cpp_app
Debugging a segfault:
# Compile with debug symbols
clang -g my_program.c -o my_program_debug
# Run the program and inspect the crash with a debugger
gdb ./my_program_debug
# Inside gdb: run, then bt (backtrace) on crash
Or using LLDB on macOS:
# Compile with debug symbols
clang -g my_program.c -o my_program_debug
# Run the program and inspect the crash with a debugger
lldb ./my_program_debug
# Inside lldb: run, then bt (backtrace) on crash
Generating a static library and using it:
# Create object files for the library
clang -c mylib_part1.c -o mylib_part1.o
clang -c mylib_part2.c -o mylib_part2.o
# Create the static library
ar rcs libmylib.a mylib_part1.o mylib_part2.o
# Compile and link your main program, using the static library
clang main.c -L. -lmylib -o my_app
# Note: -L. tells the linker to look in the current directory for libraries.
Generating a shared library and using it:
# Create object files with position-independent code
clang -fPIC -c mylib_part1.c -o mylib_part1.o
clang -fPIC -c mylib_part2.c -o mylib_part2.o
# Create the shared library
clang -shared mylib_part1.o mylib_part2.o -o libmylib.so
# Compile and link your main program, using the shared library
clang main.c -L. -lmylib -o my_app
# On Linux, you might need to set LD_LIBRARY_PATH to find the shared library at runtime:
# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
# ./my_app
Using clang-tidy for static analysis (requires separate installation or build from source):
# Install clang-tidy (e.g., on Ubuntu)
sudo apt install clang-tidy
# Run clang-tidy on a file
clang-tidy -checks='*' main.c -- -std=c11
This runs all available checks on main.c and uses -std=c11 as compiler arguments to understand the code context.
Gotchas
clangvsclang++: Always useclang++when compiling C++ code. Whileclangcan sometimes compile C++ files,clang++ensures the correct C++ standard library and headers are used by default.- Linking C++ standard library: When mixing C and C++ code, or when explicitly controlling linking, you might need to tell Clang to link the C++ standard library. For example,
clang main.c my_cpp_code.o -lstdc++ -o my_app. arfor static libraries: Clang itself doesn’t create static libraries (.afiles). You need to use thear(archiver) utility after creating object files.LD_LIBRARY_PATH(Linux): When developing and testing shared libraries, the runtime linker might not findlibmylib.sounless you add its directory toLD_LIBRARY_PATH. This is generally not recommended for production deployment.- System headers: Clang searches for system headers in standard locations. If you’re using custom system headers, you’ll need to specify their path using
-I. --targetfor cross-compilation: When cross-compiling (e.g., compiling for ARM on an x86 machine), correctly specifying the--targetflag is crucial. The format is typicallyarchitecture-vendor-os-abi.- Warning flags:
-Wallis comprehensive but doesn’t enable all warnings.-Wextraadds more, and-pedanticenforces strict ISO standard compliance. Using-Werrorcan be useful for CI but can be frustrating during initial development.