How To Setup Clang Tooling For LLVM

Clang Tooling provides infrastructure to write tools that need syntacticand semantic information about a program. This term also relates to a setof specific tools using this infrastructure (e.g.clang-check). Thisdocument provides information on how to set up and use Clang Tooling forthe LLVM source code.

Introduction

Clang Tooling needs a compilation database to figure out specific buildoptions for each file. Currently it can create a compilation databasefrom thecompile_commands.json file, generated by CMake. Wheninvoking clang tools, you can either specify a path to a build directoryusing a command line parameter-p or let Clang Tooling find thisfile in your source tree. In either case you need to configure yourbuild using CMake to use clang tools.

Setup Clang Tooling Using CMake and Make

If you intend to use make to build LLVM, you should have CMake 2.8.6 orlater installed (can be foundhere).

First, you need to generate Makefiles for LLVM with CMake. You need tomake a build directory and run CMake from it:

$mkdiryour/build/directory$cdyour/build/directory$cmake-DCMAKE_EXPORT_COMPILE_COMMANDS=ONpath/to/llvm/sources

If you want to use clang instead of GCC, you can add-DCMAKE_C_COMPILER=/path/to/clang-DCMAKE_CXX_COMPILER=/path/to/clang++.You can also useccmake, which provides a curses interface to configureCMake variables.

As a result, the newcompile_commands.json file should appear in thecurrent directory. You should link it to the LLVM source tree so thatClang Tooling is able to use it:

$ln-s$PWD/compile_commands.jsonpath/to/llvm/source/

Now you are ready to build and test LLVM using make:

$makecheck-all

Setup Clang Tooling Using CMake on Windows

For Windows developers, the Visual Studio project generators in CMake donot supportCMAKE_EXPORT_COMPILE_COMMANDS.However, the Ninja generator does support this variable and can be usedon Windows to generate a suitablecompile_commands.json that invokesthe MSVC compiler.

First, you will need to installNinja. Once installed, the Ninjaexecutable will need to be in your search path for CMake to locate it.

Next, assuming you already have Visual Studio installed on your machine, youneed to have the appropriate environment variables configured so that CMakewill locate the MSVC compiler for the Ninja generator. Thedocumentationdescribes the necessary environment variable settings, but the simplest thingis to use adeveloper command-prompt windowor call adeveloper command fileto set the environment variables appropriately.

Now you can run CMake with the Ninja generator to export a compilationdatabase:

C:\> mkdir build-ninjaC:\> cd build-ninjaC:\build-ninja> cmake -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON path/to/llvm/sources

It is best to keep your Visual Studio IDE build folder separate from theNinja build folder. This prevents the two build systems from negativelyinteracting with each other.

Once thecompile_commands.json file has been created by Ninja, you canuse that compilation database with Clang Tooling. One caveat is that becausethere are indirect settings obtained through the environment variables,you may need to run any Clang Tooling executables through a command promptwindow created for use with Visual Studio as described above. Analternative, e.g. for using the Visual Studio debugger on a Clang Toolingexecutable, is to ensure that the environment variables are also visibleto the debugger settings. This can be done locally in Visual Studio’sdebugger configuration locally or globally by launching the Visual StudioIDE from a suitable command-prompt window.

Using Clang Tools

After you completed the previous steps, you are ready to run clang tools. Ifyou have a recent clang installed, you should haveclang-check in$PATH. Try to run it on any.cpp file inside the LLVM source tree:

$clang-checktools/clang/lib/Tooling/CompilationDatabase.cpp

If you’re using vim, it’s convenient to have clang-check integrated. Putthis into your.vimrc:

function! ClangCheckImpl(cmd)  if &autowrite | wall | endif  echo "Running " . a:cmd . " ..."  let l:output = system(a:cmd)  cexpr l:output  cwindow  let w:quickfix_title = a:cmd  if v:shell_error != 0    cc  endif  let g:clang_check_last_cmd = a:cmdendfunctionfunction! ClangCheck()  let l:filename = expand('%')  if l:filename =~ '\.\(cpp\|cxx\|cc\|c\)$'    call ClangCheckImpl("clang-check " . l:filename)  elseif exists("g:clang_check_last_cmd")    call ClangCheckImpl(g:clang_check_last_cmd)  else    echo "Can't detect file's compilation arguments and no previous clang-check invocation!"  endifendfunctionnmap <silent> <F5> :call ClangCheck()<CR><CR>

When editing a .cpp/.cxx/.cc/.c file, hit F5 to reparse the file. Incase the current file has a different extension (for example, .h), F5will re-run the last clang-check invocation made from this vim instance(if any). The output will go into the error window, which is openedautomatically when clang-check finds errors, and can be re-opened with:cope.

Otherclang-check options that can be useful when working with clangAST:

  • -ast-print — Build ASTs and then pretty-print them.

  • -ast-dump — Build ASTs and then debug dump them.

  • -ast-dump-filter=<string> — Use with-ast-dump or-ast-print todump/print only AST declaration nodes having a certain substring in aqualified name. Use-ast-list to list all filterable declaration nodenames.

  • -ast-list — Build ASTs and print the list of declaration node qualifiednames.

Examples:

$clang-checktools/clang/tools/clang-check/ClangCheck.cpp-ast-dump-ast-dump-filterActionFactory::newASTConsumerProcessing: tools/clang/tools/clang-check/ClangCheck.cpp.Dumping ::ActionFactory::newASTConsumer:clang::ASTConsumer *newASTConsumer() (CompoundStmt 0x44da290 </home/alexfh/local/llvm/tools/clang/tools/clang-check/ClangCheck.cpp:64:40, line:72:3>  (IfStmt 0x44d97c8 <line:65:5, line:66:45>    <<<NULL>>>      (ImplicitCastExpr 0x44d96d0 <line:65:9> '_Bool' <UserDefinedConversion>...$clang-checktools/clang/tools/clang-check/ClangCheck.cpp-ast-print-ast-dump-filterActionFactory::newASTConsumerProcessing: tools/clang/tools/clang-check/ClangCheck.cpp.Printing <anonymous namespace>::ActionFactory::newASTConsumer:clang::ASTConsumer *newASTConsumer() {    if (this->ASTList.operator _Bool())        return clang::CreateASTDeclNodeLister();    if (this->ASTDump.operator _Bool())        return clang::CreateASTDumper(nullptr /*Dump to stdout.*/,                                      this->ASTDumpFilter);    if (this->ASTPrint.operator _Bool())        return clang::CreateASTPrinter(&llvm::outs(), this->ASTDumpFilter);    return new clang::ASTConsumer();}

Using Ninja Build System

Optionally you can use theNinja build system instead of make. It isaimed at making your builds faster. Currently this step will requirebuilding Ninja from sources.

To take advantage of using Clang Tools along with Ninja build you needat least CMake 2.8.9.

Clone the Ninja git repository and build Ninja from sources:

$gitclonegit://github.com/martine/ninja.git$cdninja/$./bootstrap.py

This will result in a single binaryninja in the current directory.It doesn’t require installation and can just be copied to any locationinside$PATH, say/usr/local/bin/:

$sudocpninja/usr/local/bin/$sudochmoda+rx/usr/local/bin/ninja

After doing all of this, you’ll need to generate Ninja build files forLLVM with CMake. You need to make a build directory and run CMake fromit:

$mkdiryour/build/directory$cdyour/build/directory$cmake-GNinja-DCMAKE_EXPORT_COMPILE_COMMANDS=ONpath/to/llvm/sources

If you want to use clang instead of GCC, you can add-DCMAKE_C_COMPILER=/path/to/clang-DCMAKE_CXX_COMPILER=/path/to/clang++.You can also useccmake, which provides a curses interface to configureCMake variables in an interactive manner.

As a result, the newcompile_commands.json file should appear in thecurrent directory. You should link it to the LLVM source tree so thatClang Tooling is able to use it:

$ln-s$PWD/compile_commands.jsonpath/to/llvm/source/

Now you are ready to build and test LLVM using Ninja:

$ninjacheck-all

Other target names can be used in the same way as with make.