Use llvm-config-18 to Build Against LLVM 18
llvm-config-18 hands you the compiler and linker settings for the LLVM actually installed here. You will use those settings in a small C++ build. Allow about 15 minutes if your source file is ready. The examples are ordinary user commands and do not need sudo.
The route
Jump straight to the step you need, or tick off Done means at the end.
1. Confirm the installed LLVM version
This guide describes the Debian or Ubuntu package installation checked here: llvm-18, version 18.1.3. Start by confirming which executable your shell will run:
$ command -v llvm-config-18
/usr/bin/llvm-config-18
$ llvm-config-18 --version
18.1.3
Checkpoint
If the command is missing, stop here and install the LLVM package through your normal package-management process. Do not replace it with an unversioned llvm-config until you have checked that it belongs to the LLVM release you intend to use.
2. Inspect the installation paths
Ask the command where this installation keeps its prefix, headers and libraries. These values are machine-specific, so use them in build scripts instead of hard-coding a path from another host:
$ llvm-config-18 --prefix
/usr/lib/llvm-18
$ llvm-config-18 --includedir
/usr/lib/llvm-18/include
$ llvm-config-18 --libdir
/usr/lib/llvm-18/lib
The package's prefix is not necessarily /usr. The separate include and library queries are useful when you need to inspect files, configure another build tool, or diagnose a missing header or library.
3. Get the flags for compiling C++
Use --cxxflags for a C++ translation unit. On this installation it prints the include directory, the C++ language mode, and LLVM's feature macros:
$ llvm-config-18 --cxxflags
-I/usr/lib/llvm-18/include -std=c++17 -fno-exceptions -funwind-tables -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
Warning
Keep the output as shell words when expanding it in a command. Do not quote the whole command substitution as one argument, because the compiler would then receive one long, invalid option. --cppflags supplies preprocessor flags, while --cflags is the corresponding query for C.
4. Ask for the libraries you actually use
Components describe the LLVM facilities required by your program. The manpage lists engine as a useful virtual component for a JIT or interpreter, and all is the default when no component is supplied. Check the available names before writing a build rule:
$ llvm-config-18 --components | tr ' ' '\n' | grep -E '^(engine|all)$'
all
engine
For a small program using the execution engine, query the library and system-library flags together with the link flags:
$ llvm-config-18 --ldflags
-L/usr/lib/llvm-18/lib
$ llvm-config-18 --libs engine
-lLLVM-18
$ llvm-config-18 --system-libs engine
$
An empty --system-libs result is valid here: this installation reports no additional system libraries for that component. The component argument must be one printed by --components. For example, the older-looking combination bcreader is not accepted by this installed binary, even though similar names may appear in examples for another LLVM build.
5. Compile and link without changing the system
Suppose example.cpp contains your LLVM code and you want the executable example. A direct build combines the three relevant queries:
$ c++ $(llvm-config-18 --cxxflags) example.cpp \
$(llvm-config-18 --ldflags --libs engine --system-libs) \
-o example
The command substitution is intentionally unquoted so each returned flag is passed separately. It writes only example in the current directory and does not install anything. If compilation fails, read the first diagnostic: a missing header usually means the wrong llvm-config was selected, and an unresolved symbol can mean the component list does not match the APIs used by the source.
Verify the output before running it:
$ test -x example && echo "built: example"
built: example
$ ldd ./example | grep LLVM
libLLVM-18.so => /lib/x86_64-linux-gnu/libLLVM-18.so.1 (...)
Warning
The library path and the rest of the ldd line depend on the host. If the program is untrusted, do not execute it merely because it links to LLVM. Inspect or sandbox it according to your normal software-review process.
6. Choose shared or static linking deliberately
This installation reports a shared linking mode for the selected components:
$ llvm-config-18 --shared-mode
shared
$ llvm-config-18 --link-shared --libs engine
-lLLVM-18
--link-shared asks for shared component libraries. --link-static asks for component libraries instead, and can produce a much longer list of dependencies:
$ llvm-config-18 --link-static --libs engine
-lLLVMInterpreter -lLLVMExecutionEngine ... -lLLVMDemangle
The displayed ellipsis is explanatory only; the real command prints every library name. Static linking can increase build time and output size, and it may expose additional platform dependencies. Use it because your deployment requires it, not as a general repair for a shared-library problem.
7. Diagnose a mismatch
Compare the key facts from the command before changing compiler or linker settings:
$ llvm-config-18 --version --host-target --build-mode --build-system --has-rtti
18.1.3
x86_64-pc-linux-gnu
RelWithDebInfo
cmake
YES
- One fact per option. Options that print one fact at a time are easier to capture in a script.
- Check RTTI before you assume it. This output also tells you whether LLVM was built with RTTI. A project that depends on RTTI must account for a
NOresult rather than assuming the compiler flags will enable it after the LLVM libraries were built. - Check the target list too. When a target-specific build matters, check
--targets-built. It reports names such asX86,AArch64andWebAssemblyfor this package. A target absent from that list is not made available by adding a linker flag; you need an LLVM build that includes it.
Done means
- Version matches.
llvm-config-18 --versionreports the LLVM release you intend to use. - Paths came from the tool. You obtained include and library paths from the installed command.
- Components are real. Your component names came from
--components, not from an unrelated example. - Flags passed separately. The compiler received
--cxxflags,--ldflags,--libsand any reported system libraries as separate options. - Output checked, system untouched. The resulting executable was checked before it was run, and no system files or services were changed.