| # How To Setup Clang Tooling For LLVM | |
| Clang Tooling provides infrastructure to write tools that need syntactic | |
| and semantic information about a program. This term also relates to a set | |
| of specific tools using this infrastructure (e.g. `clang-check`). This | |
| document provides information on how to set up and use Clang Tooling for | |
| the LLVM source code. | |
| ## Introduction | |
| Clang Tooling needs a compilation database to figure out specific build | |
| options for each file. Currently it can create a compilation database | |
| from the `compile_commands.json` file, generated by CMake. When | |
| invoking clang tools, you can either specify a path to a build directory | |
| using a command line parameter `-p` or let Clang Tooling find this | |
| file in your source tree. In either case you need to configure your | |
| build 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 or | |
| later installed (can be found [here](https://cmake.org)). | |
| First, you need to generate Makefiles for LLVM with CMake. You need to | |
| make a build directory and run CMake from it: | |
| ```console | |
| $ mkdir your/build/directory | |
| $ cd your/build/directory | |
| $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON path/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 use `ccmake`, which provides a curses interface to configure | |
| CMake variables. | |
| As a result, the new `compile_commands.json` file should appear in the | |
| current directory. You should link it to the LLVM source tree so that | |
| Clang Tooling is able to use it: | |
| ```console | |
| $ ln -s $PWD/compile_commands.json path/to/llvm/source/ | |
| ``` | |
| Now you are ready to build and test LLVM using make: | |
| ```console | |
| $ make check-all | |
| ``` | |
| ## Setup Clang Tooling Using CMake on Windows | |
| For Windows developers, the Visual Studio project generators in CMake do | |
| not support [CMAKE_EXPORT_COMPILE_COMMANDS](https://cmake.org/cmake/help/latest/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html). | |
| However, the Ninja generator does support this variable and can be used | |
| on Windows to generate a suitable `compile_commands.json` that invokes | |
| the MSVC compiler. | |
| First, you will need to install [Ninja]. Once installed, the Ninja | |
| executable will need to be in your search path for CMake to locate it. | |
| Next, assuming you already have Visual Studio installed on your machine, you | |
| need to have the appropriate environment variables configured so that CMake | |
| will locate the MSVC compiler for the Ninja generator. The [documentation](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#path_and_environment) | |
| describes the necessary environment variable settings, but the simplest thing | |
| is to use a [developer command-prompt window](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#developer_command_prompt_shortcuts) | |
| or call a [developer command file](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#developer_command_file_locations) | |
| to set the environment variables appropriately. | |
| Now you can run CMake with the Ninja generator to export a compilation | |
| database: | |
| ```console | |
| C:\> mkdir build-ninja | |
| C:\> cd build-ninja | |
| C:\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 the | |
| Ninja build folder. This prevents the two build systems from negatively | |
| interacting with each other. | |
| Once the `compile_commands.json` file has been created by Ninja, you can | |
| use that compilation database with Clang Tooling. One caveat is that because | |
| there are indirect settings obtained through the environment variables, | |
| you may need to run any Clang Tooling executables through a command prompt | |
| window created for use with Visual Studio as described above. An | |
| alternative, e.g. for using the Visual Studio debugger on a Clang Tooling | |
| executable, is to ensure that the environment variables are also visible | |
| to the debugger settings. This can be done locally in Visual Studio's | |
| debugger configuration locally or globally by launching the Visual Studio | |
| IDE from a suitable command-prompt window. | |
| ## Using Clang Tools | |
| After you completed the previous steps, you are ready to run clang tools. If | |
| you have a recent clang installed, you should have `clang-check` in | |
| `$PATH`. Try to run it on any `.cpp` file inside the LLVM source tree: | |
| ```console | |
| $ clang-check tools/clang/lib/Tooling/CompilationDatabase.cpp | |
| ``` | |
| If you're using vim, it's convenient to have clang-check integrated. Put | |
| this 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:cmd | |
| endfunction | |
| function! 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!" | |
| endif | |
| endfunction | |
| nmap <silent> <F5> :call ClangCheck()<CR><CR> | |
| ``` | |
| When editing a .cpp/.cxx/.cc/.c file, hit F5 to reparse the file. In | |
| case the current file has a different extension (for example, .h), F5 | |
| will re-run the last clang-check invocation made from this vim instance | |
| (if any). The output will go into the error window, which is opened | |
| automatically when clang-check finds errors, and can be re-opened with | |
| `:cope`. | |
| Other `clang-check` options that can be useful when working with clang | |
| AST: | |
| - `-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` to | |
| dump/print only AST declaration nodes having a certain substring in a | |
| qualified name. Use `-ast-list` to list all filterable declaration node | |
| names. | |
| - `-ast-list` --- Build ASTs and print the list of declaration node qualified | |
| names. | |
| Examples: | |
| ```console | |
| $ clang-check tools/clang/tools/clang-check/ClangCheck.cpp -ast-dump -ast-dump-filter ActionFactory::newASTConsumer | |
| Processing: 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-check tools/clang/tools/clang-check/ClangCheck.cpp -ast-print -ast-dump-filter ActionFactory::newASTConsumer | |
| Processing: 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 the [Ninja] build system instead of make. It is | |
| aimed at making your builds faster. Currently this step will require | |
| building Ninja from sources. | |
| To take advantage of using Clang Tools along with Ninja build you need | |
| at least CMake 2.8.9. | |
| Clone the Ninja git repository and build Ninja from sources: | |
| ```console | |
| $ git clone git://github.com/martine/ninja.git | |
| $ cd ninja/ | |
| $ ./bootstrap.py | |
| ``` | |
| This will result in a single binary `ninja` in the current directory. | |
| It doesn't require installation and can just be copied to any location | |
| inside `$PATH`, say `/usr/local/bin/`: | |
| ```console | |
| $ sudo cp ninja /usr/local/bin/ | |
| $ sudo chmod a+rx /usr/local/bin/ninja | |
| ``` | |
| After doing all of this, you'll need to generate Ninja build files for | |
| LLVM with CMake. You need to make a build directory and run CMake from | |
| it: | |
| ```console | |
| $ mkdir your/build/directory | |
| $ cd your/build/directory | |
| $ cmake -G Ninja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON path/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 use `ccmake`, which provides a curses interface to configure | |
| CMake variables in an interactive manner. | |
| As a result, the new `compile_commands.json` file should appear in the | |
| current directory. You should link it to the LLVM source tree so that | |
| Clang Tooling is able to use it: | |
| ```console | |
| $ ln -s $PWD/compile_commands.json path/to/llvm/source/ | |
| ``` | |
| Now you are ready to build and test LLVM using Ninja: | |
| ```console | |
| $ ninja check-all | |
| ``` | |
| Other target names can be used in the same way as with make. | |
| [ninja]: https://ninja-build.org/ |