Skip to content

Instantly share code, notes, and snippets.

@gtors
Created December 10, 2018 12:57
Show Gist options
  • Select an option

  • Save gtors/effe8eef7dbe7052b22a009f3c7fc434 to your computer and use it in GitHub Desktop.

Select an option

Save gtors/effe8eef7dbe7052b22a009f3c7fc434 to your computer and use it in GitHub Desktop.

Revisions

  1. gtors renamed this gist Dec 10, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. gtors created this gist Dec 10, 2018.
    136 changes: 136 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,136 @@
    [Guillaume Papin(@Sarcasm)](https://github.com/sarcasm) has [a thorough article about compilation databases](https://sarcasm.github.io/notes/dev/compilation-database.html).

    ### [CMake](https://cmake.org/)

    ```zsh
    % mkdir build
    % (cd build; cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=YES ..)
    % ln -s build/compile_commands.json
    ```

    Caveat on Windows: CMake dumps Windows shell command line directly into `command`, depends on how ccls was built, it may confuse this field as command line from a POSIX shell, in which Windows path separator '\\' is a escape character. You can use jq to convert such entries to use `arguments` which does not have this issue:

    ```sh
    jq '[.[] | {directory: .directory, file: .file, arguments: .command | split(" ") | map(select(length > 0)) | map(sub("\\\\\""; "\""; "g"))}]' < compile_commands.json
    ```

    ### [Build EAR](https://github.com/rizsotto/Bear)

    Bear is a tool that generates a compilation database for clang tooling. It can be used for any project based on `Makefile`.

    ```zsh
    bear make
    # generates compile_commands.json
    ```

    ### [compiledb](https://github.com/nickdiego/compiledb)

    ### [scan-build](https://github.com/rizsotto/scan-build)

    scan-build is a python package that can generate a compilation database for clang tooling (uses Bear as a backend). This too can be used for any project based on a `Makefile`.

    ```zsh
    intercept-build make all # generates compile_commands.json from the `make all` ruleset
    ```

    ### [Ninja](https://ninja-build.org/)

    ```zsh
    # Format: ninja -t compdb rule_names... > compile_commands.json
    ninja -C out/Release -t compdb cxx cc > compile_commands.json
    ```

    ### [Waf](https://waf.io/)

    Load the `clang_compilation_database` tool in your wscript:

    ```python
    def configure(conf):
    conf.load('clang_compilation_database')
    ```
    ```
    ./waf configure build
    ln -s build/compile_commands.json
    ```

    ## [buck](https://buckbuild.com/)

    ```sh
    buck build :helloworld#compilation-database
    ln -s $(buck targets --show-output :helloworld#compilation-database | cut -d ' ' -f 2)
    ```

    ### stdout of an external command

    You may use the initialization option `"compilationDatabaseCommand"` to provide the JSON compilation database. ccls will read its stdout rather than read `compile_commands.json`. This may be useful when ccls cannot parse the `compile_commands.json` correctly (e.g. MSVC cl.exe, Intel C++ Compiler options)

    ```sh
    # extra command line option
    '--init={"compilationDatabaseCommand":"mycompdb"}'
    ```

    ```elisp
    (setq ccls-extra-init-params '(:compilationDatabaseCommand "mycompdb"))
    ```

    Suppose the project is at `/tmp/c`, `mycompdb /tmp/c` will be executed with stdin=initializationOptions and the stdout should be a JSON compilation database.

    You may use this shell script as a starting point:
    ```zsh
    #!/bin/zsh
    # mycompdb /tmp/c
    cat >> /tmp/initialization-options
    cat <<e
    [ { "arguments": [ "c++", "a.o", "a.cc" ],
    "directory": "/tmp/c", "file": "a.cc" } ]
    e
    ```

    An example to scrub Intel C++ Compiler options (or, even easier, check out `clang.excludeArgs` in the [Initialization options](https://github.com/MaskRay/ccls/wiki/Initialization-options)):
    ```zsh
    #!/usr/bin/env python3
    import json
    import os
    import sys
    with open(os.path.join(sys.argv[1], 'compile_commands.json')) as f:
    db = json.load(f)
    for entry in db:
    args = entry['arguments']
    try:
    # Intel C++ Compiler option that is unknown to clang
    args.remove('-xHost')
    except ValueError:
    pass
    json.dump(db, sys.stdout)
    ```

    ## Examples

    ### Linux kernel

    ```zsh
    wget 'https://git.archlinux.org/svntogit/packages.git/plain/trunk/config?h=packages/linux' -O .config
    yes '' | make config
    bear make -j bzImage modules
    ```

    ```zsh
    ccls -index ~/Dev/Linux -init='{"clang":{"excludeArgs":[
    "-falign-jumps=1","-falign-loops=1","-fconserve-stack","-fmerge-constants","-fno-code-hoisting","-fno-schedule-insns","-fno-sched-pressure","-fno-var-tracking-assignments","-fsched-pressure",
    "-mhard-float","-mindirect-branch-register","-mindirect-branch=thunk-inline","-mpreferred-stack-boundary=2","-mpreferred-stack-boundary=3","-mpreferred-stack-boundary=4","-mrecord-mcount","-mindirect-branch=thunk-extern","-mno-fp-ret-in-387","-mskip-rax-setup",
    "--param=allow-store-data-races=0","-Wa,arch/x86/kernel/macros.s","-Wa,-"
    ], "extraArgs":["--gcc-toolchain=/usr"]}}'
    ```

    ### musl

    ```zsh
    mkdir Debug; cd Debug
    ../configure --enable-optimize=no --enable-debug --prefix=~/.local/stow/musl
    bear make -j
    cd ..; ln -s Debug/compile_commands.json
    ```

    ## Misc

    `compile_commands.json` should reside in the project root. Set the initialization option `compilationDatabaseDirectory` for an alternative directory containing `compile_commands.json`.