Home / Alt manpages / clang-20(1)

  • clang-20(1)
  • User command
  • linux

Compile and Check C and C++ with clang-20

You will use the installed clang-20 driver to check a source file, produce an object file, and link a runnable program. The same workflow also shows where assembly, debug information and preprocessor output fit. Allow about 10 minutes for the first run. You need the clang-20 package, a shell, and a writable working directory; none of the commands below needs elevated privileges.

Checkpoint: confirm the compiler

  1. Check that the command resolves to Clang 20.

    clang-20 --version
    dpkg-query -W -f='${Package} ${Version}\n' clang-20

On the machine described by this guide, the installed package is clang-20 version 1:20.1.8~++20250804090239+87f0227cb601-1~exp1~20250804210352.139. The compiler identifies itself as Clang 20.1.8 and targets x86_64-pc-linux-gnu. Package versions and the target can differ on another machine, so keep this check with build notes when reproducibility matters.

Checkpoint: check source without creating a program

  1. Create a small C source file in a scratch directory.

    mkdir -p "$HOME/clang-20-example"
    cd "$HOME/clang-20-example"
    cat > hello.c <<'EOF'
    #include <stdio.h>
    
    int main(void)
    {
        puts("hello from clang");
        return 0;
    }
    EOF
  2. Run only preprocessing, parsing and semantic analysis.

    clang-20 -std=c17 -Wall -Wextra -fsyntax-only hello.c

A successful check prints nothing and returns status 0. -fsyntax-only does not write an object or executable. -Wall -Wextra enables useful warning groups, but warnings are still not failures unless you add -Werror. If Clang reports a source location and an error, fix that diagnostic before moving on. A frequent distraction is a missing header: check the include path and the selected language before changing unrelated flags.

Checkpoint: build an executable

  1. Compile and link in one command, naming the output explicitly.

    clang-20 -std=c17 -Wall -Wextra -O0 -g hello.c -o hello
    ./hello

The expected program output is:

hello from clang

With no stage-selection option, the driver compiles the source, assembles the result and invokes the linker. -o hello avoids the less helpful default output name a.out. The -g option adds debug information, and -O0 keeps optimisation off, which makes source-level debugging easier. Neither option makes a program safe or correct; they only change the generated artefact and its diagnostics.

Use the stages separately when diagnosing a build

  1. Produce an object file without linking.

    clang-20 -std=c17 -Wall -Wextra -c hello.c -o hello.o
    file hello.o
  2. Link that object file into a new executable.

    clang-20 hello.o -o hello-from-object
    ./hello-from-object
  3. Inspect the generated assembly when code generation itself is the question.

    clang-20 -std=c17 -O0 -S hello.c -o hello.s
    sed -n '1,40p' hello.s

The stages are deliberately cumulative: -E stops after preprocessing, -fsyntax-only stops after semantic analysis, -S emits assembly, and -c emits an object file. Do not confuse a successful -fsyntax-only check with a successful link: missing libraries and duplicate symbols appear later.

Build a C++ file with an explicit standard

  1. Choose the C++ standard and invoke the same driver.

    cat > hello.cpp <<'EOF'
    #include <iostream>
    
    int main()
    {
        std::cout << "hello from C++\n";
    }
    EOF
    clang-20 -std=c++20 -Wall -Wextra -O0 -g hello.cpp -o hello-cpp
    ./hello-cpp

The installed manpage says the default C++ mode is gnu++17. An explicit -std=c++20 makes this build independent of that default and disables GNU language extensions for the selected standard. Use -std=gnu++20 when the source intentionally depends on GNU extensions. The available standard-library choice is platform-dependent; -stdlib=libstdc++ and -stdlib=libc++ are the documented choices when both are installed.

Inspect a failing or surprising command

  1. Ask the driver to show the commands it would run without running them.

    clang-20 -### -std=c17 -Wall hello.c -o hello
  2. Show include and linker search paths when a dependency cannot be found.

    clang-20 -v -print-search-dirs

-### is useful for seeing the assembler and linker stages without changing files. -v prints the tools and paths used during a real invocation. Keep the output when reporting a build problem: it records the selected target and toolchain assumptions. Avoid copying a -Wl, or -Xlinker argument from another machine without checking its linker and target first.

Common traps and safe recovery

  • Wrong input language: use a meaningful suffix such as .c or .cpp. For generated or extensionless input, select it explicitly with -x c or -x c++; the setting applies to subsequent input files.
  • Unexpected include files: -I/path adds an include directory, while CPATH and language-specific include-path environment variables also affect lookup. Check them when a build works in one shell but not another.
  • Overwriting an existing output: -o hello replaces that path. Before using it in a script, confirm it is the intended file. To undo this guide's changes, remove only the scratch directory with rm -rf -- "$HOME/clang-20-example" after checking its contents; that removal is irreversible and must not be pointed at a directory containing other work.
  • Optimisation assumptions: -O3 can produce larger code and take longer than -O2. The manpage marks -Ofast as deprecated in Clang 19 because it can enable behaviour that violates strict language standards; use an explicit, justified fast floating-point setting only when its changed rules are acceptable.

Done means

  • clang-20 --version reports the expected installed compiler.
  • -fsyntax-only checks the source without producing a binary.
  • -c produces an object and a separate link command produces the executable.
  • The executable runs and prints the expected line.
  • The selected language standard, warning level, optimisation level and output path are explicit.