Managing Makefile Projects
The example below shows how to construct a meta build system that monitors changes in Makefiles, then regenerates and reloads the compilation database accordingly. This way, it lets you manage a Makefile project to a full extent from within CLion. Moreover, you can build and run/debug such projects with the help of custom build targets and custom Run/Debug configurations.
Suppose we have a simple Makefile project consisting of three modules, general, io_lib, and math_lib, each stored in a separate directory that contains a Makefile, and in the root directory, the main Makefile that builds all the targets:
Now let's take the following steps:
1. Create a compilation database
First of all, we need to create a JSON compilation database for our test project. The tool we'll use for this is compiledb-generator. Having installed the tool, we can run
compiledb make from the project root and get the compile_commands.json file:
2. Install the Makefile Support plugin
This is an optional step, yet quite helpful for our task: with the Makefile Support plugin installed, the GNU Makefile file type becomes recognizable in CLion, and we get the syntax highlighting and editing features for the Makefiles.
3. Open and configure the compilation database in CLion
The next step is to open the compilation database that we created in step 1 as a project in CLion. After the import has finished successfully, we can start working with the project files.
4. Install the File Watchers plugin
Go to Marketplace, search for File Watchers, and install the plugin., switch to
5. Create a File Watcher for the Makefiles
Now we can create a File Watcher to follow up the changes in the Makefiles. Let's navigate to custom watcher.and add () a new
In the File to Watch section we need to assign the watcher to GNU Makefile and set the Scope to Project files.
The Tool to Run on Changes section controls the program to be called,
-n makearguments in our case.
The watcher's scope includes sub-directory Makefiles, so the tool will be triggered upon the changes in them as well. As we need only the top-level compilation database, let's set Working directory to the project root (notice the
6. Modify the Makefiles
Now, let's change something in our Makefiles. We can do this outside the IDE (since the Trigger the watcher on external changes checkbox is set), or right from the CLion editor.
For example, we can add a new source file to the math_lib module and put it to the list of sources in the corresponding Makefile:
Right after that change, the Makefile_watcher is triggered to run
compiledb -n make. This command regenerates the compilation database without performing the actual build, and CLion automatically reloads it so the project gets synchronized with the modified Makefile.
Now there are four entries in compile_commands.json:
Similarly, if we then decide not to include the io_funcs library into the build, we can remove the
Io target from the main Makefile:
7. Make the File Watcher global
The final thing that we might want to do is make the Makefile_watcher global. With this setting enabled, the watcher becomes available across all projects so we'll easily reuse it for other Makefile applications that we manage in CLion:
This way, the combination of a File Watcher and a compilation database creates a mechanism to work with Make-based projects without leaving CLion to edit the Makefiles or recreate the compilation database manually. Moreover, you can apply this approach to any build system that has complementary tools for generating compilation databases.
Note that currently, in this scheme, CLion reloads the entire compilation database for each change in the Makefile that triggers the File Watcher. Due to that, you may experience performance problems when applying this workflow to large code bases.