Skip to content
This repository was archived by the owner on Apr 25, 2023. It is now read-only.

Simplify cmake #16

Merged
merged 9 commits into from
Sep 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 18 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,30 @@ project(LSIFClang)
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set (search_paths
$ENV{PATH_TO_LLVM}
$ENV{PATH_TO_LLVM}/lib/cmake
$ENV{PATH_TO_LLVM}/lib/cmake/llvm
$ENV{PATH_TO_LLVM}/lib/cmake/clang
$ENV{PATH_TO_LLVM}/share/clang/cmake/
$ENV{PATH_TO_LLVM}/share/llvm/cmake/
)
if (PATH_TO_LLVM)
set (search_paths
${PATH_TO_LLVM}
${PATH_TO_LLVM}/lib/cmake
${PATH_TO_LLVM}/lib/cmake/llvm
${PATH_TO_LLVM}/lib/cmake/clang
${PATH_TO_LLVM}/share/clang/cmake/
${PATH_TO_LLVM}/share/llvm/cmake/
)
endif()

message(STATUS "${search_paths}")

find_package(LLVM REQUIRED CONFIG
PATHS ${search_paths}
NO_DEFAULT_PATH)
find_package(Clang REQUIRED CONFIG
PATHS ${search_paths}
NO_DEFAULT_PATH)
PATHS ${search_paths})

message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message(STATUS "Using ClangConfig.cmake in: ${CLANG_CMAKE_DIR}")

include_directories(${LLVM_INCLUDE_DIRS})

Expand Down
119 changes: 88 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,72 +4,129 @@ This project is a fork of [clangd](https://clangd.llvm.org/) with patches to add

This project has only been tested extensively on C++ projects, but C and Objective C projects should both be supported as well following the same instructions.

# Installation
# Alternatives for C++ Projects

If you can't get `lsif-clang` working with your project, first file an issue! We want this to work everywhere.
But the C++ ecosystem is fragmented, and it's possible that your project simply won't play nice with the `clang` toolchain.
[lsif-cpp](https://github.com/sourcegraph/lsif-cpp) is also available, which acts as a plugin for arbitrary C++ compilers and might therefore be compatible.
But it has several major defects compared to `lsif-clang` (it is much slower and does not provide hovers), and is not the recommended option.

## Dependencies
# Usage

This project depends on LLVM and Clang. The code builds against LLVM and Clang version 10, but can index a wide variety of code. Please file an issue if you need to build against a different version of LLVM or Clang and we can start adding some version pragmas! You can try finding the location of your llvm installation by running `readlink -f $(which clang)`. On my computer, this returns `/usr/lib/llvm-10/bin/clang`, so the installation path is `/usr/lib/llvm-10`.
There are 4 steps, and instructions for each can vary by platform and build system.

## Building
The project builds with CMake, so if you know what you're doing you can configure it yourself. For sensible defaults:
1. Install dependencies
1. Build lsif-clang
1. Generate a compilation database.
1. Run lsif-clang.

## Quick example
Here's how you would build an index of the lsif-clang tool on Ubuntu 20.04.

```sh
PATH_TO_LLVM=<path> ./config.sh build
cd build
make -j8
sudo make install
apt install llvm-10 clang clang-10 libclang-10-dev cmake `# install dependencies`
git clone https://github.com/sourcegraph/lsif-clang && cd lsif-clang `# get the code`
cmake -B build `# configure lsif-clang`
make -C build -j8 `# build lsif-clang`
ln -s $(pwd)/build/compile_commands.json ./ `# link the compilation database to the project root`
./build/bin/lsif-clang --project-root=$(pwd) --executor=all-TUs compile_commands.json > dump.lsif `# generate an index`
```

`PATH_TO_LLVM` should point to the llvm installation path from the previous step. The `8` in `make -j8` should be the number of threads you wish to allocate to the build (it's fairly small so it shouldn't matter much, but `make` is single threaded by default).
The following sections provide detailed explanations of each step and variations on the commands for different platforms and build systems.

## Install dependencies

## Give it a whirl!
This project depends on LLVM and Clang. lsif-clang itself should be built against LLVM and Clang version 10, and can index any code Clang 10 can compile. Work is ongoing to compile against other versions of LLVM. Here are instructions to get the dependencies on a few platforms:

Assuming you followed the steps above, do the following from this project's root directory:
### Ubuntu 20.04

```sh
ln -s $(pwd)/build/compile_commands.json ./
lsif-clang --project-root=$(pwd) --executor=all-TUs compile_commands.json > dump.lsif
apt install llvm-10 clang clang-10 libclang-10-dev cmake
```

Inspect the file when it's done, you should see lots of glorious JSON!
### MacOS

# Usage
```sh
brew install llvm cmake
```

## Compilation Database
## Build lsif-clang
Here is a minimal example, known extra steps for specific platforms follow:

```sh
cmake -B build
make -C build -j8
```

### MacOS
Add the following extra argument to the `cmake` step:
```sh
cmake -B build -DPATH_TO_LLVM=/usr/local/opt/lib
```

## Generate a compilation database

`lsif-clang` itself is configured to do this automatically, so to test the that the tool built properly you can simply sym-link it to the project root from the build directory and skip to [running lsif-clang]().

From the project root:
```sh
ln -s $(pwd)/build/compile_commands.json ./
```

The tool depends on having a [JSON compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) available, which is generated differently depending on what build system is in use. Please get in touch if you're having trouble generating a compilation database, we'd be happy to help troubleshoot!
Instructions for generating this compilation database for various build systems follows:

### CMake

Add `-DCMAKE_EXPORT_COMPILE_COMMANDS=ON` to your `cmake` invocation. The database will get generated in your build directory, so you should symlink it to the source root.
If a project builds with CMake, you can ensure that a compilation database is generated in the build directory with the following flag:
```sh
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
```

### Make and others
For some projects, we've noticed that CMake generates a faulty database, but that the actual build step can output more sensible values. The Ninja build tool provides a convenient mechanism for this. Assuming Ninja is installed:

Install the [Bear](https://github.com/rizsotto/Bear) tool and run `bear make`, or `bear <your-build-command>`. This tool is build system agnostic so it's a good fallback option.
```sh
cmake <normal args> -G Ninja
cd <build dir>
ninja -t compdb > compile_commands.json
```

This database will also contain irrelevant entries which will make lsif-clang output quite noisy but still functional. To filter the irrelevant entries, inspect the `compile_commands.json` and find an entry for an actual c++ compile command. Here's an example for me:
```json
{
"directory": "/home/arrow/sourcegraph/lsif-clang/build2",
"command": "/usr/bin/c++ -I../ -I/usr/lib/llvm-10/include -std=gnu++17 -o CMakeFiles/clangDaemonFork.dir/AST.cpp.o -c /home/arrow/sourcegraph/lsif-clang/AST.cpp",
"file": "/home/arrow/sourcegraph/lsif-clang/AST.cpp"
}
```

I can then use the "command" value of `/usr/bin/c++` in the following jq snippet:
```sh
ninja -t compdb | jq '[ .[] | select(.command | startswith("/usr/bin/c++")) ] > compile_commands.json'
```

### Bazel

Use the [bazel-compilation-database](https://github.com/grailbio/bazel-compilation-database) tool.

## Indexing
### Make and others

Install the [Bear](https://github.com/rizsotto/Bear) tool and run `bear make`, or `bear <your-build-command>`. This tool is build system agnostic so it's a good fallback option.

## Run lsif-clang

Once you have `compile_commands.json` at the root of your source tree, you can invoke `lsif-clang` like so:
Once you have a `compile_commands.json` in the root of your project's source, you can use the following command to index the entire project:

```sh
lsif-clang --project-root=$(pwd) --executor=all-TUs compile_commands.json > dump.lsif
```

This will index the entire project. To index only some files, run:
To index individual files, use:

```sh
lsif-clang --project-root=$(pwd) file1.cpp file2.cpp ... > dump.lsif
```

Note that this will still include lots of data about other files to properly supply hovers and such.

### Platform-specific instructions

#### On MacOS
### MacOS

The indexer may fail to find system header files on MacOS (and possibly other systems) resulting in console error messages such as `fatal error: stdarg.h not found`.

Expand All @@ -85,6 +142,6 @@ $ lsif-clang \
compile_commands.json > dump.lsif
```

# Alternatives for C++ Projects
## Test the output

If you can't get `lsif-clang` working with your project, first file an issue! We want this to work everywhere. But the C++ ecosystem is fragmented, and it's possible that your project simply won't play nice with the `clang` toolchain. [lsif-cpp](https://github.com/sourcegraph/lsif-cpp) is also available, which acts as a plugin for arbitrary C++ compilers and might therefore be compatible. But it has several major defects compared to `lsif-clang` (it is much slower and does not provide hovers), and is not the recommended option.
You can use the [lsif-validate]() tool for basic sanity checking, or [upload the index to a Sourcegraph instance]() to see the hovers, definitions, and references in action.
4 changes: 3 additions & 1 deletion config.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/bin/sh

cmake -B $1 -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release
cmake -B build -S . \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DPATH_TO_LLVM=$PATH_TO_LLVM