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.