Thanks for the blog post https://blog.gradle.org/introducing-the-new-cpp-plugins and helping us understand the progress on the new C++ plugins. From the post, Gradle will be supporting variants associated with different operating systems and architectures. My question is about flavors.
Will the new C++ plugins support the flavor concept (or some type of variant of it) that exists in the current software model? If so, are there any plans to improve it w.r.t dependency management?
For example, if an application needs English and French flavors, it would be great to be able to communicate which dependencies of the application need to have these flavors. A math library could then be depended on without requiring these flavors since English and French may be meaningless. A logging library, on the other hand, should probably have these flavors. I understand why the software model doesn’t do this now since it simplifies dependency management (e.g., how is Gradle supposed to know that the English flavor of the application should not require the English flavor of the math library?)
The above toy example aside, in real life I have only used flavors to make variants of applications with OpenMP. I had to define two flavors: OMP and NMP (no OpenMP). But like the example above, I had many libraries that didn’t use OpenMP that required to have the OpenMP flavor, so it unnecessarily exploded the number variants in the project. At one point we thought we need more flavors like English and French (not the actual flavors but used for illustration), so we toyed around with having OMP_ENGLISH, OMP_FRENCH, NOMP_ENGLISH, and NOMP_FRENCH. Thankfully, we didn’t need to go down this route, but it did make flavors feel clunky.
Long story short, I love that Gradle is rekindling its investment in the world of native builds, and I’m interested in hearing about how variants (such as flavors in the current software model) will be described in the new C++ plugins.
I should have also inquired about buildTypes. We currently use three: release, debug, and codeCoverage. Alongside operating system and architecture variants, will buildTypes (or some form of it) be carried into the new C++ plugins?
With regards to flavors and build types, we are trying to present a stronger model of the native domain. Too often we see build authors hop onto available concepts as a way to fill a gap in the modeling. Instead of offering generic dimensions, we are looking at providing a way to specify your custom dimensions. In that line of work, we are improving the dependency management system to understand those ad-hoc dimensions and allow the build author to specify what is the relation between them.
For a code coverage “build type”, you will be able to specify a dimension that represents your code coverage data. Some tools may need to exchange coverage information between project to work correctly which is where the deeper modeling will help.
The French and English flavors example from the software model would become, with the new plugins, a custom dimension most likely called language. You can then use that dimension with your component and inside the dependency management. Conflict resolution rules when resolving the dependency would apply as normal, meaning, in case the French language would be missing, we can default to English.
The same applies to request regarding compiling source code with a specific toolchain. What the request is really about is specifying information about the target ABI which, most of the time, happens only to be satisfied by a single toolchain. Having more in-depth model for the native domain will allow everyone to model their build better as well as share build logic easily.
What code coverage tool are you using? We will be looking at making Gradle behave appropriately with code coverage tool are gathering candidate. Don’t hesitate to ask more question regarding the native domain or open feature request on GitHub.
Thanks for the detailed response! All of that sounds interesting and useful, and it’ll be exciting to see it come together.
We are using gcov and lcov to measure and generate code coverage reports, and we are using Catch for unit testing (https://github.com/catchorg/Catch2).
Using the current software model, the codeCoverage build type is used to modify the cppCompiler and linker args such that gcov files are produced (*.gcno):
Once the codeCoverage variant is built, we can then run a series of tasks that:
Run the test driver application to produce *.gcda files
Run lcov on those files to produce the lcov tracefile
Run lcov again to filter the tracefile such that system and 3rd-party source files are excluded from the coverage data
Run genhtml on the tracefile to produce the HTML report
We haven’t found a good open-source tool on Windows to generate C++ code coverage data, so the above process is limited to running on Linux with GCC installed. Also, we haven’t tried this with Clang since we don’t use Clang on the project.
I know that was more information than you asked for, but I figured it may be beneficial for you to have additional insight into how people (at least, we) are currently using the software model with native code.
By all means, this is the kind of information we need to get a feel for the pain point and tools used by native developers. As for open source C++ code coverage tool on Windows, I had lots of success with OpenCppCoverage in the past.