CLion 2020.1 Help

Managing Makefile Projects

Although currently Makefiles are not supported as a project format in CLion, you can use the following workaround to manage Makefile projects with the help of File Watchers and compilation database.

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:

TARGETS = Math Io General all: $(TARGETS) Math: @$(MAKE) -C math_lib -f Makefile Io: @$(MAKE) -C io_lib -f Makefile General: @$(MAKE) -C general -f Makefile clean: @$(MAKE) -C io_lib -f Makefile clean @$(MAKE) -C math_lib -f Makefile clean @$(MAKE) -C general -f Makefile clean

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:

cl filewatcher compiledb output png

    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.

      loaded compilation database project

        4. Install the File Watchers plugin

        Go to Settings / Preferences | Plugins, switch to Marketplace, search for File Watchers, and install the plugin.

          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 Settings / Preferences | Tools | File Watchers and add (icons.welcome.createNewProject.png) a new custom watcher.

          • 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, compiledb with the -n make arguments 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 $ProjectFileDir$ macro).

          File watcher for the makefiles

            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:

            Adding a source file to a 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:

            compilation database regenerated

            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:

            TARGETS = Math General
            In response to this change, the Makefile_watcher triggers again, and the compilation database gets reloaded accordingly:
            cl filewatchers makefilechange example2result png

              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:

              global File Watcher

                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.

                As next steps, you can build and run/debug Makefile projects with the help of custom build targets and custom Run/Debug configurations.

                Last modified: 29 July 2020