What to type and how to assemble a C ++ project
Having asked this question, I first of all formulated the requirements: rigid and optional (but desirable) for the assembly system and graphical development environment.
I want to note right away that it is not about writing C ++ code for some specific platform such as Android or a framework, for example Qt, where everything is ready, both with building and editing code, but about generic code that is not tied to a specific platform or to the framework.
In the light of these "Wishlist" I have considered several assembly systems and graphical development environments. This short review does not in any way pretend to be complete and contains my subjective assessments, but perhaps it will seem to someone useful as an initial step.
Make - [antiquity]a mastodon and a well-deserved veteran of assembly systems, which everyone still doesn’t want to retire, but is forced to carry more and more new projects. This is a very low-level tool with its own specific language, where for a space instead of a tab you are immediately threatened with execution on the spot. Using make, you can do anything you want - a build of any complexity, but you will have to pay for it with efforts to write a script, as well as keep it up to date. It will also be expensive to transfer the logic of the build from project to project. There are some modern make-up substitutes: such as ninja and jam, but they don’t change the essence - these are very low-level tools. Just like in assembler, you can write anything you like, but is it worth it?
CMake - [Middle Ages]first attempt to get away from the low-level details of the make. But, unfortunately, it was not possible to go far - the engine here is the same make for which CMake generates huge make-files based on another text file with a more high-level build description. Qmake works in a similar way. This approach reminds me of the beautiful facade of an old wooden house, which was carefully sheathed with fresh plastic. CMake is a stable and well-proven system, there is even a built-in integration with Eclipse, but, unfortunately, it did not suit me because it contradicts part of the requirements set forth at the beginning of the article. Under Linux, everything seems to be fine, but if you need to build the same project on Windows using MSVC - and I prefer the native compiler to MinGW, the files for NMake will be generated. Those. dependencies on another tool and different build commands for another platform. And all this is a consequence of a bit crooked architecture, when the bulk of the work is done by other "helpers".
Ant - [renaissance] a kind of make clone for Java. Frankly, I spent quite a bit of time checking Ant (as well as Maven) as a build system for C ++. And I immediately got the feeling that C ++ support here is purely “for show” and not sufficiently developed. Moreover, even in Java projects Ant is already rarely used. As a scripting language (as well as for Maven) XML is chosen here - this vile bird language :). This fact of optimism did not add to me at all for further immersion in the topic.
SCons - [new times]A self-contained, cross-platform build system written in Python. SCons does equally well with both Java and C ++ builds. The dependencies of the headers for incremental assembly are worked out correctly (as I understand it, a certain database is created with the build metadata), and on Windows MSVC works without a tambourine. The build script language is Python. A very decent system, and I even wanted to finish my research on it, but as you know, there is no limit to perfection, and a more detailed examination revealed some disadvantages in the light of the above requirements.
There are no abstract settings for the compiler, so if, for example, you need to change the toolchain, you may need to look for places in the build script to make changes. The same macros will have to be written with nested conditions - if it's Windows then do it, if it's GCC do it, etc.
There is no support for remote artifacts and high-level dependency of one build on another.
The general architecture is designed so that the so-called user defined builders exist almost in isolation and there is no way to use the existing build logic to supplement it with your own through a simple plug-in. But overall it is a worthy choice for small projects.
Gradle [modern]- I already had positive experience using Gradle for Java and Kotlin projects and I had high hopes for it.
For JVM languages, Gradle has a very convenient concept of working with the libraries necessary for building a project (build dependencies):
At first, I checked out the “old” plugin for C ++ support - `cpp` - and was disappointed - the script structure is not intuitive: model, component, nativespec - and some kind of mishmash from various types of binaries: both executable and libraries all in one script. It is not clear where to place unit tests. This structure was very different from what I used for Java.
But it turned out that there are also “new” plugins for C ++ support: `cpp-application` - for applications,` cpp-library` for libraries: static and dynamic, and finally `cpp-unit-test` for unit testing. And that was what I was looking for! :)
The default folder structure of the project is similar to the project for Java:
Such a structure is not rigid - it can always be changed in the script, but still it is not necessary to do this without special need, it is quite reasonable.
By the way, the build script is usually build.gradle , it is a DSL of the Groovy or Kotlin language ( build.gradle.kts ) to choose from. Inside the script, the Gradle API and the APIs of the plugins added to the script are always available.
For libraries, you can choose the type: static or dynamic (or collect both options).
By default, two build options are configured: Debug ( gradle assemble ) and Release ( gradle assembleRelease ).
The principle of running unit testing is the same as in Java: gradle test will build the main component, then the tests, if they are in the foldersrc / test / cpp and then run the test application.
The notorious defines can be set in an abstract way - Gradle itself will generate the necessary compiler options. There are several more abstract settings such as optimization, debugging information, etc.
Out of the box, GCC, Microsoft Visual C ++, CLang are supported.
The plug-in system is very developed, and the extension architecture is convenient - you can take ready-made logic and decorate / expand it. There are two types of plugins: dynamic, which are written directly in Groovy and embedded in a script or written in Java (or in another language with the JVM) and compiled into binary artifacts. For plugins, there is a free Gradle artifactory in which anyone can post their plugin, which will be available to everyone. Which was successfully done by the author of this article :) but more on that later.
I would like to dwell in more detail on the system of working with binary components in Gradle for C ++: it is almost the same as in Java! Builds of dependencies work almost the same as I described above.
Take for example a composite build:
In the build.gradle file from the app folder, it is enough to write the following dependency:
Gradle will do the rest! Add a path to the compiler to search for utils header files and link the library binar.
And all this works equally well both under Linux GCC and under Windows MSVC.
Incremental build, of course, also works great, and if you change the headers in utils, the app will be rebuilt.
As it turned out, Gradle went further and realized the ability to upload C ++ artifacts to the Maven Repository! To do this, use the standard `maven-publish` plugin.
In the script, you need to specify the repository where you want to put your artifact and make gradle publish (or gradle publishToMavenLocal for local publication). Gradle will build the project and
lay out in a special format - taking into account the version, platform, architecture and build option.
The binary library files themselves and the public header files are laid out - from the src / main / public folder .
It’s clear that you cannot upload C ++ artifacts to Maven Cental - it will not pass the mandatory system checks. But raising the Maven repository on the network is not difficult at all, and you don’t need to do anything for the local repository - it's just a folder on disk.
Now if you want to use someone’s library in your project, you can write something like this in the build script:
It says here that for unit testing you need to use the gtest artifact version 1.8.1 from the Maven repository .
By the way, this is a very real repository in which my test build Google Test v1.8.1 is posted, built using Gradle for Windows and Linux x86_64.
Naturally, all the low-level work on configuring the compiler and linker to work with the external component of Gradle is undertaken. It is enough for you to declare your intentions to use such and such a library with such and such a version from such and such a repository.
For integration with the IDE, Gradle has two built-in plugins for Visual Studio and Xcode. They work well, except that the Visual Studio plugin ignores unit test code from the src / test / cpp folder and generates the project only for the main code.
Eclipse CDT (2018-12R)- a mature and quality product. If he managed to successfully parse your project, then you are lucky - it will be comfortable to edit. Most likely, he will even "understand" the most confused types of auto. But if not ... Then he will violently emphasize everything in a row with a red dotted line and swear in bad words. For example, it does not digest standard MSVC and Windows SDK header files. Even a completely harmless printf is underlined with a red dotted line and is not perceived as something meaningful. There was also std :: string. Under Linux, with his native gcc, everything is fine. But even when trying to get him to index the project from a sister Android Native, problems started. In bionic headers, he point-blank refused to see the definition of size_t, and along with all the functions that used it. Probably,
The possibilities for navigating, refactoring, and generating template code are wonderful, but there are questions to the helper when typing letters: let's say we type a few characters from some long name, why not offer completion options? No, the assistant patiently waits until the user gets to. or -> or ::. I have to constantly press Ctrl + Space - annoying. In Java, this annoying deficiency could be fixed by selecting the entire alphabet in the CDT as a trigger, but I did not find a simple solution.
NetBeans 8.1 / 10.0- I used to use this IDE for Java, I was remembered as a good and lightweight software with all the necessary functionality. For C ++, it has a plugin developed not by the community, but directly by NetBeans. For C ++ projects, there is a pretty tough dependency on make and gcc. The code editor is leisurely. I did not find a very simple thing in the template code generator: we add a new method in the class header file - you need to generate the method body in a cpp file - it does not know how. The degree of "understanding" of the code is average, it seems that something is parsing, but something is not. For example, iterating on a map with an auto-iterator is already difficult for him. He swears at macros from Google Test. Customizing the build command is problematic - on Linux with gcc and make available (this is despite the fact that another build system is already in use) it will work, on Windows it will require MinGW, but even if there is one, he refuses to build. In general, working in NetBeans with C ++ is possible, but I would not call it comfortable; I probably need to really love this environment so as not to notice its various sores.
KDevelop 5.3.1- Once conceived as a developer tool for KDE (Linux), but now there is a version for Windows. It has a fast and enjoyable code editor with beautiful syntax highlighting (based on Kate). It will not work to tamper with the left build system - for him, the main build system is CMake. It is tolerant of MSVC and Windows SDK headers, in any case printf and std :: string do not exactly lead to a stupor like an Eclipse CDT. A very quick helper for writing code - it offers good completion options almost immediately while typing. It has an interesting opportunity for generating template code: you can write your own template and put it online. When creating from a template, you can connect to the database of ready-made templates and download the one you like. The only thing that upset: the built-in template for creating a new class works crookedly under both Windows and Linux. The wizard for creating a class has several windows in which you can configure a lot of things: which constructors are needed, which members of the class, etc. But at the final stage under Windows some kind of error pops up in time to make out the text of which is impossible and two files h and cpp are created in the size of 1 byte. In Linux, for some reason, you cannot select constructors - the tab is empty, and only the header file is correctly generated on the output. In general, childhood illnesses for such a mature product look somehow frivolous. But at the final stage under Windows some kind of error pops up in time to make out the text of which is impossible and two files h and cpp are created in the size of 1 byte. In Linux, for some reason, you cannot select constructors - the tab is empty, and only the header file is correctly generated on the output. In general, childhood illnesses for such a mature product look somehow frivolous. But at the final stage under Windows some kind of error pops up in time to make out the text of which is impossible and two files h and cpp are created in the size of 1 byte. In Linux, for some reason, you cannot select constructors - the tab is empty, and only the header file is correctly generated on the output. In general, childhood illnesses for such a mature product look somehow frivolous.
QtCreator 4.8.1 (open source edition) - probably, having heard this name, you are perplexed how this monster was imprisoned here under Qt with a gigabyte distribution kit with a hook. But this is a "light" version of the environment for generic projects. Its distribution kit weighs only about 150 MB and does not carry things specific to Qt with it: download.qt.io/official_releases/qtcreator/4.8 .
Actually, he can do almost everything that I wrote about in my requirements quickly and correctly. It parses the standard headers of both Windows and Linux, customizes it to any build system, suggests completion options, conveniently generates new classes, method bodies, allows refactoring and code navigation. If you just want to work comfortably without constantly thinking about how to overcome this or that problem, it makes sense to look at QtCreator.
Actually, it remains to talk about what I did not have enough in Gradle to fully work: integration with the IDE. In order for the system to generate project files for the IDE itself, in which the commands for building the project would already be written, all the source files are listed, paths are needed to search for header files and determine.
For this purpose, I wrote a plugin for Gradle `cpp-ide-generator` and published on the Gradle Plugin Portal.
The plugin can only be used with `cpp-application`,` cpp-library` and `cpp-unit-test`.
Here is an example of its use in build.gradle :
The plugin supports integration with all of the above graphical development environments, but in the plugin configuration block - ide, you can disable support for unnecessary IDEs:
If the autoGenerate parameter is set to true, project files for all allowed IDEs will be automatically generated right during the build. Also, in automatic generation mode, project files will be deleted when the build is cleaned: gradle clean .
Incremental generation is supported, i.e. only those files that require a real update will be updated.
Here is a list of goals that the plugin adds:
During generation, the plugin “sniffs” the build and extracts from it all the necessary information to create project files. After opening the project, all the source files should be visible in the IDE, the paths to all the headers should be registered, and the basic build commands to configure / build / clear should also be configured.
The second plugin I had to do is called `cpp-build-tuner` and it also works in tandem with cpp-application`,` cpp-library` and `cpp-unit-test`.
The plugin has no settings, it’s just enough to upload it:
The plugin performs small manipulations with the settings of the toolchains (compiler and linker) for different build options - Debug and Release. MSVC, gcc, CLang are supported.
This is especially true for MSVC, because by default, as a result of the release build, you will get a "bold", not aesthetic binar with bazhdash information and a statically linked standard library. I “spied” part of the settings for MSVC in Visual Studio itself, which by default it adds to its C ++ projects. For both gcc / CLang and MSVC, link time optmizations are included in the Release profile.
Note: Plugins were tested with the latest version of Gradle v5.2.1 and were not tested for compatibility with previous versions.
The source codes of the plugins, as well as simple examples of using Gradle for libraries: static and dynamic, as well as the application that uses them can be viewed: bitbucket.org/akornilov/tools next gradle / cpp.
The examples also show how to use Google Test for unit testing libraries.
Maven Repository with Google Test v1.8.1 built in Gradle (without mock).
UPD: QtCreato r
versions for Windows older than 4.6.2 (and at least at the time of writing these lines, up to 4.10inclusive) "forgotten how" to understand the MSVC SDK. All of the std :: space is underlined in red and refuses to index. Therefore, at the moment, version 4.6.2 is most suitable for working under Windows.
A new version of the
1)
lto (boolean) - Enables or disables LTO for the release build. Enabled by default.
gtest (string) - Adds Google Test support for unit tests. Currently only version 1.8.1 is supported for GCC, MinGW-W64, and MSVC.
libraries (container) - a list of libraries for linking. Inside the container there are three fields (list of lines):
libDirs (container) - a list of folders for searching libraries with a linker. The container structure is the same as the library list.
2) Added the ability to run the application for
Similarly, a standard plugin "Java Application plugin" can transmit the command line parameters when starting:
UPD
In connection with the change of hosting plugins, the group was changed:
New project address: gradle-cpp.sourceforge.io
Documentation:
sourceforge.net/p/gradle-cpp/wiki/cpp-build-tuner
sourceforge.net/p/gradle-cpp/wiki/cpp-ide-generator
I want to note right away that it is not about writing C ++ code for some specific platform such as Android or a framework, for example Qt, where everything is ready, both with building and editing code, but about generic code that is not tied to a specific platform or to the framework.
Are common:
- Free.
- Cross-platform (at least Windows and Linux).
Build system:
- A single team to build on different platforms.
- Incremental assembly with the correct account of all dependencies: header files and third-party components used for assembly.
- The assembly script should contain only the necessary minimum configuration specific for a particular project. The general logic of the build should not wander from script to script, but is located in the build system or its plugins.
- Built-in parallel assembly.
- Support for various toolchains (at least gcc, Visual C ++, CLang).
- The ability to change the toolchain with minimal cost, without rewriting the entire build script.
- Easily switchable build options: Debug and Release.
- Dependencies on some additional low-level tools like make are completely undesirable. In a word, the assembly system should be self-sufficient.
- Integration of the build system with repositories of third-party components such as pkg-config or Maven Central for the JVM is highly desirable.
- The build system must be extensible by plugins, as the assembly procedure for each specific project may be more complicated than the standard construction concept (code generation, for example, or the assembly of some non-standard image).
- It’s convenient when the build script is some kind of high-level programming language or even better DSL. This will allow you to not very costly and expressively change the behavior of the construction directly in the script.
- When configuring the compiler and linker from the build script, it is very convenient when the system provides at least basic abstractions: for example, I would like to add a macro - why think which compiler command line parameter is responsible for this? / D on MSVC or -D on gcc - let the build system resolve these inconsequential details by itself.
- Good integration with graphical development environments (IDEs).
IDE:
- The ability of the IDE to correctly "understand" C ++ code. The IDE must be able to index all project files, as well as all third-party and system header files and definitions (defines, macro).
- The IDE should provide the ability to customize commands for building a project, as well as where to look for header files and definitions.
- It should effectively help in typing code, i.e. offer the most suitable completion options, warn about syntax errors, etc.
- Navigating a large project should be convenient, and finding use quick and easy.
- Provide ample opportunities for refactoring: renaming, etc.
- Also needed is the ability to generate boilerplate code — creating a new class framework, header file, and implementation file. Generation of getters / setters, method definitions, overloading virtual methods, implementation patterns of purely virtual classes (interfaces), etc.
- Highlighting and support for code documentation tags such as Doxygen.
In the light of these "Wishlist" I have considered several assembly systems and graphical development environments. This short review does not in any way pretend to be complete and contains my subjective assessments, but perhaps it will seem to someone useful as an initial step.
Make - [antiquity]a mastodon and a well-deserved veteran of assembly systems, which everyone still doesn’t want to retire, but is forced to carry more and more new projects. This is a very low-level tool with its own specific language, where for a space instead of a tab you are immediately threatened with execution on the spot. Using make, you can do anything you want - a build of any complexity, but you will have to pay for it with efforts to write a script, as well as keep it up to date. It will also be expensive to transfer the logic of the build from project to project. There are some modern make-up substitutes: such as ninja and jam, but they don’t change the essence - these are very low-level tools. Just like in assembler, you can write anything you like, but is it worth it?
CMake - [Middle Ages]first attempt to get away from the low-level details of the make. But, unfortunately, it was not possible to go far - the engine here is the same make for which CMake generates huge make-files based on another text file with a more high-level build description. Qmake works in a similar way. This approach reminds me of the beautiful facade of an old wooden house, which was carefully sheathed with fresh plastic. CMake is a stable and well-proven system, there is even a built-in integration with Eclipse, but, unfortunately, it did not suit me because it contradicts part of the requirements set forth at the beginning of the article. Under Linux, everything seems to be fine, but if you need to build the same project on Windows using MSVC - and I prefer the native compiler to MinGW, the files for NMake will be generated. Those. dependencies on another tool and different build commands for another platform. And all this is a consequence of a bit crooked architecture, when the bulk of the work is done by other "helpers".
Ant - [renaissance] a kind of make clone for Java. Frankly, I spent quite a bit of time checking Ant (as well as Maven) as a build system for C ++. And I immediately got the feeling that C ++ support here is purely “for show” and not sufficiently developed. Moreover, even in Java projects Ant is already rarely used. As a scripting language (as well as for Maven) XML is chosen here - this vile bird language :). This fact of optimism did not add to me at all for further immersion in the topic.
SCons - [new times]A self-contained, cross-platform build system written in Python. SCons does equally well with both Java and C ++ builds. The dependencies of the headers for incremental assembly are worked out correctly (as I understand it, a certain database is created with the build metadata), and on Windows MSVC works without a tambourine. The build script language is Python. A very decent system, and I even wanted to finish my research on it, but as you know, there is no limit to perfection, and a more detailed examination revealed some disadvantages in the light of the above requirements.
There are no abstract settings for the compiler, so if, for example, you need to change the toolchain, you may need to look for places in the build script to make changes. The same macros will have to be written with nested conditions - if it's Windows then do it, if it's GCC do it, etc.
There is no support for remote artifacts and high-level dependency of one build on another.
The general architecture is designed so that the so-called user defined builders exist almost in isolation and there is no way to use the existing build logic to supplement it with your own through a simple plug-in. But overall it is a worthy choice for small projects.
Gradle [modern]- I already had positive experience using Gradle for Java and Kotlin projects and I had high hopes for it.
For JVM languages, Gradle has a very convenient concept of working with the libraries necessary for building a project (build dependencies):
- The script registers the addresses of repositories with artifacts: maven or ivy - for example. It can also be a repository of any other type / format - if only there was a plugin for it. It can be a remote repository, some Maven Central or your personal hosting somewhere on the network or just a local rep on the file system.
- Also, in a special section of the script, the dependencies for building are indicated directly - a list of the necessary binary artifacts with versions.
- Before building, Gradle tries to resolve all the dependencies and looks for artifacts with the given versions across all repositories. Binaries are loaded into the cache and automatically added to the build. This is very convenient and I was hoping that for C ++, perhaps they did something similar.
At first, I checked out the “old” plugin for C ++ support - `cpp` - and was disappointed - the script structure is not intuitive: model, component, nativespec - and some kind of mishmash from various types of binaries: both executable and libraries all in one script. It is not clear where to place unit tests. This structure was very different from what I used for Java.
But it turned out that there are also “new” plugins for C ++ support: `cpp-application` - for applications,` cpp-library` for libraries: static and dynamic, and finally `cpp-unit-test` for unit testing. And that was what I was looking for! :)
The default folder structure of the project is similar to the project for Java:
- src / main / cpp - the root folder for the main * .cpp project files .
- src / main / headers - folder for internal header files.
- src / main / public - folder for exported headers - for libraries.
- src / test / cpp - folder for * .cpp files of the test unit.
Such a structure is not rigid - it can always be changed in the script, but still it is not necessary to do this without special need, it is quite reasonable.
By the way, the build script is usually build.gradle , it is a DSL of the Groovy or Kotlin language ( build.gradle.kts ) to choose from. Inside the script, the Gradle API and the APIs of the plugins added to the script are always available.
For libraries, you can choose the type: static or dynamic (or collect both options).
By default, two build options are configured: Debug ( gradle assemble ) and Release ( gradle assembleRelease ).
The principle of running unit testing is the same as in Java: gradle test will build the main component, then the tests, if they are in the foldersrc / test / cpp and then run the test application.
The notorious defines can be set in an abstract way - Gradle itself will generate the necessary compiler options. There are several more abstract settings such as optimization, debugging information, etc.
Out of the box, GCC, Microsoft Visual C ++, CLang are supported.
The plug-in system is very developed, and the extension architecture is convenient - you can take ready-made logic and decorate / expand it. There are two types of plugins: dynamic, which are written directly in Groovy and embedded in a script or written in Java (or in another language with the JVM) and compiled into binary artifacts. For plugins, there is a free Gradle artifactory in which anyone can post their plugin, which will be available to everyone. Which was successfully done by the author of this article :) but more on that later.
I would like to dwell in more detail on the system of working with binary components in Gradle for C ++: it is almost the same as in Java! Builds of dependencies work almost the same as I described above.
Take for example a composite build:
- utils - library folder
- app is the folder with the application that uses utils.
- settings.gradle - Gradle file for combining these two components into a composite build.
In the build.gradle file from the app folder, it is enough to write the following dependency:
dependencies {
implementation project(':utils')
}
Gradle will do the rest! Add a path to the compiler to search for utils header files and link the library binar.
And all this works equally well both under Linux GCC and under Windows MSVC.
Incremental build, of course, also works great, and if you change the headers in utils, the app will be rebuilt.
As it turned out, Gradle went further and realized the ability to upload C ++ artifacts to the Maven Repository! To do this, use the standard `maven-publish` plugin.
In the script, you need to specify the repository where you want to put your artifact and make gradle publish (or gradle publishToMavenLocal for local publication). Gradle will build the project and
lay out in a special format - taking into account the version, platform, architecture and build option.
The binary library files themselves and the public header files are laid out - from the src / main / public folder .
It’s clear that you cannot upload C ++ artifacts to Maven Cental - it will not pass the mandatory system checks. But raising the Maven repository on the network is not difficult at all, and you don’t need to do anything for the local repository - it's just a folder on disk.
Now if you want to use someone’s library in your project, you can write something like this in the build script:
repositories {
maven {
url = 'https://akornilov.bitbucket.io/maven'
}
}
unitTest {
dependencies {
implementation 'org.bitbucket.akornilov.tools:gtest:1.8.1'
}
}
It says here that for unit testing you need to use the gtest artifact version 1.8.1 from the Maven repository .
By the way, this is a very real repository in which my test build Google Test v1.8.1 is posted, built using Gradle for Windows and Linux x86_64.
Naturally, all the low-level work on configuring the compiler and linker to work with the external component of Gradle is undertaken. It is enough for you to declare your intentions to use such and such a library with such and such a version from such and such a repository.
For integration with the IDE, Gradle has two built-in plugins for Visual Studio and Xcode. They work well, except that the Visual Studio plugin ignores unit test code from the src / test / cpp folder and generates the project only for the main code.
Now it's time to talk about the IDE and how to make them friends with Gradle
Eclipse CDT (2018-12R)- a mature and quality product. If he managed to successfully parse your project, then you are lucky - it will be comfortable to edit. Most likely, he will even "understand" the most confused types of auto. But if not ... Then he will violently emphasize everything in a row with a red dotted line and swear in bad words. For example, it does not digest standard MSVC and Windows SDK header files. Even a completely harmless printf is underlined with a red dotted line and is not perceived as something meaningful. There was also std :: string. Under Linux, with his native gcc, everything is fine. But even when trying to get him to index the project from a sister Android Native, problems started. In bionic headers, he point-blank refused to see the definition of size_t, and along with all the functions that used it. Probably,
The possibilities for navigating, refactoring, and generating template code are wonderful, but there are questions to the helper when typing letters: let's say we type a few characters from some long name, why not offer completion options? No, the assistant patiently waits until the user gets to. or -> or ::. I have to constantly press Ctrl + Space - annoying. In Java, this annoying deficiency could be fixed by selecting the entire alphabet in the CDT as a trigger, but I did not find a simple solution.
NetBeans 8.1 / 10.0- I used to use this IDE for Java, I was remembered as a good and lightweight software with all the necessary functionality. For C ++, it has a plugin developed not by the community, but directly by NetBeans. For C ++ projects, there is a pretty tough dependency on make and gcc. The code editor is leisurely. I did not find a very simple thing in the template code generator: we add a new method in the class header file - you need to generate the method body in a cpp file - it does not know how. The degree of "understanding" of the code is average, it seems that something is parsing, but something is not. For example, iterating on a map with an auto-iterator is already difficult for him. He swears at macros from Google Test. Customizing the build command is problematic - on Linux with gcc and make available (this is despite the fact that another build system is already in use) it will work, on Windows it will require MinGW, but even if there is one, he refuses to build. In general, working in NetBeans with C ++ is possible, but I would not call it comfortable; I probably need to really love this environment so as not to notice its various sores.
KDevelop 5.3.1- Once conceived as a developer tool for KDE (Linux), but now there is a version for Windows. It has a fast and enjoyable code editor with beautiful syntax highlighting (based on Kate). It will not work to tamper with the left build system - for him, the main build system is CMake. It is tolerant of MSVC and Windows SDK headers, in any case printf and std :: string do not exactly lead to a stupor like an Eclipse CDT. A very quick helper for writing code - it offers good completion options almost immediately while typing. It has an interesting opportunity for generating template code: you can write your own template and put it online. When creating from a template, you can connect to the database of ready-made templates and download the one you like. The only thing that upset: the built-in template for creating a new class works crookedly under both Windows and Linux. The wizard for creating a class has several windows in which you can configure a lot of things: which constructors are needed, which members of the class, etc. But at the final stage under Windows some kind of error pops up in time to make out the text of which is impossible and two files h and cpp are created in the size of 1 byte. In Linux, for some reason, you cannot select constructors - the tab is empty, and only the header file is correctly generated on the output. In general, childhood illnesses for such a mature product look somehow frivolous. But at the final stage under Windows some kind of error pops up in time to make out the text of which is impossible and two files h and cpp are created in the size of 1 byte. In Linux, for some reason, you cannot select constructors - the tab is empty, and only the header file is correctly generated on the output. In general, childhood illnesses for such a mature product look somehow frivolous. But at the final stage under Windows some kind of error pops up in time to make out the text of which is impossible and two files h and cpp are created in the size of 1 byte. In Linux, for some reason, you cannot select constructors - the tab is empty, and only the header file is correctly generated on the output. In general, childhood illnesses for such a mature product look somehow frivolous.
QtCreator 4.8.1 (open source edition) - probably, having heard this name, you are perplexed how this monster was imprisoned here under Qt with a gigabyte distribution kit with a hook. But this is a "light" version of the environment for generic projects. Its distribution kit weighs only about 150 MB and does not carry things specific to Qt with it: download.qt.io/official_releases/qtcreator/4.8 .
Actually, he can do almost everything that I wrote about in my requirements quickly and correctly. It parses the standard headers of both Windows and Linux, customizes it to any build system, suggests completion options, conveniently generates new classes, method bodies, allows refactoring and code navigation. If you just want to work comfortably without constantly thinking about how to overcome this or that problem, it makes sense to look at QtCreator.
Actually, it remains to talk about what I did not have enough in Gradle to fully work: integration with the IDE. In order for the system to generate project files for the IDE itself, in which the commands for building the project would already be written, all the source files are listed, paths are needed to search for header files and determine.
For this purpose, I wrote a plugin for Gradle `cpp-ide-generator` and published on the Gradle Plugin Portal.
The plugin can only be used with `cpp-application`,` cpp-library` and `cpp-unit-test`.
Here is an example of its use in build.gradle :
plugins {
id ‘cpp-library’
id ‘maven-publish’
id ‘cpp-unit-test’
id ‘org.bitbucket.akornilov.cpp-ide-generator’ version ‘0.3’
}
library {
// Library specific parameters
}
// Configuration block of plugin:
ide {
autoGenerate = false
eclipse = true
qtCreator = true
netBeans = true
kdevelop = true
}
The plugin supports integration with all of the above graphical development environments, but in the plugin configuration block - ide, you can disable support for unnecessary IDEs:
kdevelop = false
If the autoGenerate parameter is set to true, project files for all allowed IDEs will be automatically generated right during the build. Also, in automatic generation mode, project files will be deleted when the build is cleaned: gradle clean .
Incremental generation is supported, i.e. only those files that require a real update will be updated.
Here is a list of goals that the plugin adds:
- generateIde - generate project files for all allowed IDEs.
- cleanIde - delete project files for all allowed IDEs.
- generateIde [name] - generate project files for the IDE with the given name (IDE must be allowed), for example generateIdeQtCreator.
- Available names: Eclipse, NetBeans, QtCreator, KDevelop.
- cleanIde [name] - delete project files for the IDE with the given name, for example cleanIdeQtCreator.
During generation, the plugin “sniffs” the build and extracts from it all the necessary information to create project files. After opening the project, all the source files should be visible in the IDE, the paths to all the headers should be registered, and the basic build commands to configure / build / clear should also be configured.
The second plugin I had to do is called `cpp-build-tuner` and it also works in tandem with cpp-application`,` cpp-library` and `cpp-unit-test`.
The plugin has no settings, it’s just enough to upload it:
plugins {
id ‘cpp-library’
id ‘maven-publish’
id ‘cpp-unit-test’
id ‘org.bitbucket.akornilov.cpp-build-tuner’ version ‘0.5’
}
The plugin performs small manipulations with the settings of the toolchains (compiler and linker) for different build options - Debug and Release. MSVC, gcc, CLang are supported.
This is especially true for MSVC, because by default, as a result of the release build, you will get a "bold", not aesthetic binar with bazhdash information and a statically linked standard library. I “spied” part of the settings for MSVC in Visual Studio itself, which by default it adds to its C ++ projects. For both gcc / CLang and MSVC, link time optmizations are included in the Release profile.
Note: Plugins were tested with the latest version of Gradle v5.2.1 and were not tested for compatibility with previous versions.
The source codes of the plugins, as well as simple examples of using Gradle for libraries: static and dynamic, as well as the application that uses them can be viewed: bitbucket.org/akornilov/tools next gradle / cpp.
The examples also show how to use Google Test for unit testing libraries.
Maven Repository with Google Test v1.8.1 built in Gradle (without mock).
UPD: QtCreato r
versions for Windows older than 4.6.2 (and at least at the time of writing these lines, up to 4.10inclusive) "forgotten how" to understand the MSVC SDK. All of the std :: space is underlined in red and refuses to index. Therefore, at the moment, version 4.6.2 is most suitable for working under Windows.
A new version of the
cpp-build-tuner
v1.0 plugin has been released (and cpp-ide-generator
v0.5 are minor improvements). 1)
cpp-build-tuner
Added configuration block.buildTuner {
lto = false
gtest = '1.8.1'
libraries {
common = ['cutils.lib']
windows = ['ole32', 'user32']
linux = ['pthread', 'z']
}
libDirs.common = ['../build/debug', '../release']
}
lto (boolean) - Enables or disables LTO for the release build. Enabled by default.
gtest (string) - Adds Google Test support for unit tests. Currently only version 1.8.1 is supported for GCC, MinGW-W64, and MSVC.
libraries (container) - a list of libraries for linking. Inside the container there are three fields (list of lines):
common
- libraries for any platform, windows
- only for Windows and linux
- only for Linux. libDirs (container) - a list of folders for searching libraries with a linker. The container structure is the same as the library list.
2) Added the ability to run the application for
cpp-application
. The plugin adds additional project tasks for this: run
.runDebug
(same as and run
) and runRelease
. Tasks depend on assemble
, assembleDebug
and, assembleRelease
respectively. Similarly, a standard plugin "Java Application plugin" can transmit the command line parameters when starting:
gradle run --args="arg1 arg2 ..."
. UPD
In connection with the change of hosting plugins, the group was changed:
plugins {
id 'loggersoft.cpp-build-tuner' version '1.1'
id 'loggersoft.cpp-ide-generator' version '0.5'
}
New project address: gradle-cpp.sourceforge.io
Documentation:
sourceforge.net/p/gradle-cpp/wiki/cpp-build-tuner
sourceforge.net/p/gradle-cpp/wiki/cpp-ide-generator