My plugins for C++ (integration with Eclipse/QtCreator/NetBeans/KDevelop)

Recently, I have investigated modern tools to build and edit C++ projects.
I want to share my results. Probably it might be helpful for somebody.

I had requirements for tools:

  • Free.
  • Cross-platform (at least Windows and Linux).

Build system:

  • Same commands to build on different platforms.
  • Incremental building.
  • No dependency on other build tools (like on low-level make).
  • Support of different toolchains (at least GCC, Visual C++, CLang).
  • Possibility to change toolchain without many efforts.
  • Build system should provide some abstraction layer over compiler and linker: for example, if I want to define macros I don’t need think about command line parameter for this - /D or -D.
  • The build system should be extendable by plugins.
  • Possibility of integration with IDE.
  • Build script should be on high-level language or DSL to change build logic in place.

IDE:

  • Provide good parsing/indexing of C++ code and default libraries headers (std etc).
  • IDE code parser should might take into account a list of custom include directories and list of defines.
  • Code assistant to suggest completion variants.
  • Code navigation within the project and find of usage.
  • Refactoring: rename, a template of methods implementation, getter/setters, override and etc.
  • Support of code documentation tags like Doxygen.
  • Good wizard to create a new class.

A short summary of each build tool which I have time to try:

make/ninja - the low-level tool which allows doing what you want at the cost of huge efforts to create a build script. Also, you will need to bear the cost to support scripts up to date. Difficult to reuse pieces of build logic in other projects.

CMake - it the good mature instrument. But I don’t like the approach where make is used as an engine. CMake just generates low-level make files according to the high-level build script file. In addition, CMake behavior goes against my initial requirements: for Visual C++ it generates NMake build files which means build commands depends on the platform.

SCons - good build system is written on Python. Initially, I thought that is what I need. But when I started to learn Scons architecture I understood that custom builders exist isolated. There is no sharing of any build logic between builders. There is no abstraction for the C++ compiler and linker settings like defines/macros. Also, I didn’t found a simple way to extends existing builder logic by a user defines a plugin.

Ant/Maven - I didn’t spend enough time to investigate these tools but I had an impression that ability to build C++ projects is optional and hadn’t developed enough.

Gradle - I had a positive experience to use Gradle in Java/Kotlin projects. And I had great hopes for Gradle. I like Gradle ideology with build dependency on artifacts from the repository (e.g. Maven) which resolved during building. If they did something like this for C++ it great I thought.
At first, I tried the “old” plugin named ‘cpp’… And was disappointed: model, components, nativespec, mixin several type of binaries (library, exec) in one build script. I got the sense that ‘cpp’ plugin was written by another team of Gradle developers than Java plugin. But when I found ‘cpp-application’, ‘cpp-library’ and ‘cpp-unit-test’ new plugins I understood that found that I want. Plugins work perfectly on Windows with Visual C++ and on Linux with GCC. Incremental build works fine with headers file dependencies. There is a possibility to upload C++ binaries to Maven repository. You can’t publish C++ binary to MavenCentral - it doesn’t pass mandatory validations but you can publish it to own maven repository - local or remote and use binary artifact as build dependency — great!

My choose is Gradle with ‘cpp-application’, ‘cpp-library’ and ‘cpp-unit-test’ plugins.

IDE:

Eclipse CDT - is good mature software with good abilities to search, refactor and code generation. But C++ parser fails sometimes on default headers: it doesn’t like Visual C++/Windows SDK headers and I couldn’t make it work with Android native layer although I have provided to parser all required include directories and defines. Also, I didn’t find how to force the code completer show suggestions during I typing. It triggered only on . or :: or ->. So I have to press Ctrl + Space every time - it’s very boring.

NetBeans - lightweight software with good functionality for Java. But for C++ there is a strict dependency of code parser with the build system. Customization with other build systems is difficult. I didn’t find a simple thing: when I do a declaration of the new method in header file NetBeans can’t generate method definition in cpp file.

KDevelop - initially developed for KDE (Linux) is cross-platform now. You can download Windows version for free. I like its code highlight and editor possibility but KDevelop fails on a simple action: generate a template of the new class. It has a good wizard for this but It doesn’t work for me on Windows (KDevelop v5.3.1) and on Linux (KDevelop v5.0.3). Also, code parser fails with std::map and auto iterator over it.

QtCreator - guess when you hear QtCreator you think about huge software giant which designed to work with Qt library. But I was talking about a light version for generic C++ projects. Distributive is very tiny just about 150Mb: QtCreator
In settings of a generic project, you simply can configure required for the project include directories and defines.
The code editor is fast and comfortable for me. The parser works fine in most cases and IDE has a good ability for refactoring and code navigation.
Also, it’s not difficult to configure a customized build system for the project.

My choose is QtCreator open source edition.

The time had come to tell you about the functionality what I didn’t find in Gradle:
Integration with IDEs: Gradle has good built-in integration with Visual Studio and XCode but this is not enough for me. And the second thing is the build adjusting according to target variant: Debug or Release.
But I made sure that there is nothing complicated to extend any Gradle plugin as you want!
So I have made and publish on Gradle plugin portal two plugins for cpp-xxx plugins:

cpp-ide-generator - the plugin generates Eclipse/QtCreator/NetBeans/KDevelop project files for C++ applications and libraries.
The plugin works with ‘cpp-application’, ‘cpp-library’ and ‘cpp-unit-test’ plugins.

plugins {
id ‘cpp-library’
id ‘maven-publish’
id ‘cpp-unit-test’
id ‘org.bitbucket.akornilov.cpp-ide-generator’ version ‘0.3’
}

// Configuration block of plugin:
ide {
autoGenerate = false
eclipse = true
qtCreator = true
netBeans = true
kdevelop = true
}

You can switch on/off the ability of a project files generation for each IDE.
If ‘autoGenerate’ is switched on all enabled IDEs projects will be generated/updated (if required) on each project compilation. Also, all IDE projects files will be cleaned during the ‘clean’ task.

Tasks:
generateIde - generates all enabled IDE.
cleanIde - cleans all enabled IDE.
generateIde - generate specified enabled IDE (e.g. generateIdeQtCreator).
cleanIde - cleans specified enabled IDE (e.g. cleanIdeQtCreator).

cpp-build-tuner - the plugin performs C++ build tunning according to current build variant: debug or release.
The plugin works with ‘cpp-application’, ‘cpp-library’ and ‘cpp-unit-test’ plugins.
It doesn’t have any settings in build script you just need apply it:
plugins {
id ‘cpp-library’
id ‘maven-publish’
id ‘cpp-unit-test’
id ‘org.bitbucket.akornilov.cpp-build-tuner’ version ‘0.3’
}

Build adjusting especially required for Visual C++ toolchain because by default you will have a huge binary on Release build variant with debug information and statically linked default C/C++ libraries.

2 Likes

Very interesting @akornilov!

Thank you!

A small note about build-in ‘visual-studio’ plugin: it works fine with old ‘cpp’ plugin and generates solution and project per each binary in the build. But for new ‘cpp-library’ plugin it generates the only project for ‘src/main/cpp’, but test executable with sources in ‘src/test/cpp’ is ignored.
Would be great to have a Visual Studio solution with two projects: the main library (‘cpp-library’) and test executable (‘cpp-unit-test’). What do you think about it?

As C++ unit test framework I use GTest.
Gradle provides an ability to use binary artifacts in C++ projects like in Java.
In my opinion, it is more comfortable than building each project dependency from sources.

For example GTest:
I took sources of GTest v1.8.1 changed files structure according to Gradle rules, creates build.gradle and built it by 'cpp-library' plugin as a static library for Windows and Linux (sources: https://bitbucket.org/akornilov/tools/src).

  • Windows: x86_64, VS2015
  • Linux: x86_64, g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516

The binary artifact I published on my Maven repository: org.bitbucket.akornilov.tools:gtest:1.8.1

Example of using from build script:

plugins {
    id 'cpp-library'
    id 'cpp-unit-test'
    id 'org.bitbucket.akornilov.cpp-build-tuner' version '0.3'
}

repositories {
    maven {
        url = 'https://akornilov.bitbucket.io/maven'
    }
}

library {
    linkage = [Linkage.STATIC]
}

unitTest {
    dependencies {
        implementation 'org.bitbucket.akornilov.tools:gtest:1.8.1'
    }
}

The new version 1.0 of the plugin cpp-build-tuner was released.

  1. The plugin configuration block was implemented:

    buildTuner {
    
     lto = false
    
     gtest = '1.8.1'
    
     libraries {
         common = ['cutils.lib']
         windows = ['ole32', 'user32']
         linux = ['pthread', 'z']
     }
    
     libDirs.common = ['../build/debug', '../release']
    

    }

lto (boolean) - disable or enable LTO (link time optimizations) on Release. By default LTO is enabled.

gtest (string) - the version of Google Test for test binary. At the moment only version 1.8.1 for GCC, MinGW-W64, and MSVC is supported.

libraries (container) - the list of libraries for the linker. The field has three parameters (list of strings) inside: common - libraries which will be used on any platform, windows - only on Windows and linux - only on Linux.

libDirs (container) - the list of directories on the local file system to search the linker libraries. Inside has the same platform-specific structure as the libraries container (see above).

  1. Run application ability for cpp-application was implemented. For application projects a plugin adds tasks: run, runDebug (same as run) and runRelease. Those tasks depends on assemble, assembleDebug and assembleRelease correspondently.
    Also, you can pass command-line arguments as in “Java Application plugin”:
    gradle run --args="arg1 arg2 ...".

In connection with changing project’s hosting the plugins were moved in another group:

plugins {
    id 'loggersoft.cpp-build-tuner' version '1.1'
    id 'loggersoft.cpp-ide-generator' version '0.5'
}

Project URL: https://gradle-cpp.sourceforge.io
Documentation:
cpp-build-tuner
cpp-ide-generator