Nim icon indicating copy to clipboard operation
Nim copied to clipboard

compile_commands.json support

Open miguelmartin75 opened this issue 7 months ago • 0 comments

Motivation

A compile_command.json enables your LSP to use appropriate compile flags for the C/C++/Objective-C files you're compiling in your project.

In a mixed Nim and C/C++/Objective-C project you have two options to integrate your C/C++/ObjC sources into your project:

  1. Compile the set of C/C++/Objective-C sources into an object or library file (static, dynamic, or framework) and link it to your nim executable or library
  2. Use {.compile.} pragmas in your nim files directly, i.e. use Nim as a frontend to your C compiler (clang/GCC/etc.)

If you opt to choose (2): then you miss out on the generation of compile_commands.json - unless you do it yourself in NimScript. If you choose option (1) then you're probably going to use CMake (or an alternative) to generate a compile_commands.json.

The compile_commands.json can be generated from NimScript by post-processing the build JSON for the Nim project/root file, but with a catch: this JSON file's "compile" field (which is what is required to generate the compile_commands.json) produced by the compiler is dependent on what files are in or out of the build cache - thus you need to handle this (by merging files you generate). In Nim/NimScript this looks something like this: https://gist.github.com/miguelmartin75/298a8b39664a89a69abd8b23a5a805a8 (this is taken from my codebase). Doing this task in NimScript is error-prone and buggy, e.g. if you remove a C file: it stays in your cache & there's a lot of LOC for something so simple.

To summarize, there are two motivating points stemming from the use-case of having LSP support (via a compile_commands.json) for mixed Nim & C/C++/ObjC projects:

  1. LSP support for your C/C++/ObjC files compiled with Nim
  2. Potentially enable developers to remove CMake as a dependency for their build toolchain. This is because this feature removes a feature CMake offers. Thus this could enable your build toolchain to be written in Nim/NimScript.

Implementation

To add support, I've added the following compiler flags:

  • --compileCmdsJson:<bool> (default off)
    • enables the generation of a compile_commands.json file
    • by default, this will output your compile commands JSON file to: <nimcache>/compile_commands.json
  • --projectCompileCmdJson:<bool> (default off)
    • if on: this will output your compile commands JSON file to: <nimcache>/compile_commands_<projectname>.json
  • --rootCompileCmdsJson:<bool> (default off)
    • copies the compile command JSON file to the root directory of your project, i.e. to quickly spit out compile_commands.json file for simpler projects (one binary file produced). Naming convention is respected by projectCompileCmdJson flag.

Testing

TODO

miguelmartin75 avatar Mar 23 '25 00:03 miguelmartin75