This chapter discusses integration of CMake and the Balau test framework with Maven via the Balau Maven plugins.
The primary aim of the Balau Maven plugins is to facilitate the integration of CMake projects within a Maven based SDLC infrastructure, whilst maintaining CMake project build configurations for developers.
A typical Maven based SDLC infrastructure includes:
In order to integrate non-Maven projects into a primarily Maven based infrastructure, there are a variety of possible approaches. Different approaches place non-Maven SDLC configuration into different places in the SDLC chain.
The approach of the Balau Maven plugins is to integrate CMake specific configuration at the project level from within project pom files. This allows the whole of the SDLC chain to be based purely on Maven projects. In addition, project specific build configuration is restricted to being in the same version control repository as the source code it is working on.
The result of such an approach is a simplification of the configuration of SDLC components outside of project version control repositories. For example, a single build configuration template could be used for all projects in the build automation server, simplifying build configuration creation and maintenance.
The Balau Maven plugins allow configuration of the following activities to be placed within project specific pom files inside CMake projects:
Once these aspects of a project's configuration are in place, further SDLC tasks required for projects (artifact assembly, artifact upload, etc.) can be handled via standard Maven plugins such as the Maven Assembly Plugin and the Maven Release Plugin.
The Balau Maven plugins are primarily aimed at SDLC automation rather than project building during development. Developers may thus continue to use their CMake based development environment and build mechanisms. Once changes are pushed to remote VCS, the Maven based build configuration is then used for automated build, test and release processes.
The Balau cmake-maven-plugin provides a mechanism for driving CMake executions via Maven. The plugin allows a simple and concise way of integrating CMake projects into a Maven based SDLC infrastructure.
The minimum version of CMake that is supported by the plugin is v3.12.
The following Maven goals are defined:
The clean goal binds by default to the clean Maven phase. The configure goal binds by default to the validate Maven phase. The compile goal binds by default to the compile Maven phase, and the test-compile goal binds by default to the test-compile Maven phase.
Three of the goals are similar to the standard Maven goals for cleaning build files, compiling production code, and compiling test code.
The configure goal executes CMake to create the project build system before compilation. For enterprise applications, the created build system will typically be Make based.
<plugin> <groupId>com.borasoftware.balau</groupId> <artifactId>cmake-maven-plugin</artifactId> <version>19.7.1</version> <executions> <execution> <goals> <goal>clean</goal> <goal>configure</goal> <goal>compile</goal> <goal>test-compile</goal> </goals> </execution> </executions> </plugin>
A common requirement for a CMake based project is to pass CMake defines from the command line. In order to achieve this via the CMake Maven plugin, each required define can be added as a Maven property in the pom. For example, the Balau project's pom includes the following properties.
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.borasoftware.balau</groupId> <artifactId>balau</artifactId> <version>19.7.1</version> <packaging>pom</packaging> <properties> <CMAKE_PREFIX_PATH /> <CMAKE_INSTALL_PREFIX /> <CMAKE_CXX_COMPILER /> <CMAKE_C_COMPILER /> </properties> </project>
All properties in the Balau pom are empty by default.
Once a Maven property is defined (either empty or with a default value), then it can be added to the <cmakeDefines> property list in the CMake Maven plugin configuration. The Balau project's pom thus includes the following properties within the <cmakeDefines> property list.
<plugin> <groupId>com.borasoftware.balau</groupId> <artifactId>cmake-maven-plugin</artifactId> <version>19.7.1</version> <configuration> <cmakeDefines> <CMAKE_PREFIX_PATH>${CMAKE_PREFIX_PATH}</CMAKE_PREFIX_PATH> <CMAKE_INSTALL_PREFIX>${CMAKE_INSTALL_PREFIX}</CMAKE_INSTALL_PREFIX> <CMAKE_CXX_COMPILER>${CMAKE_CXX_COMPILER}</CMAKE_CXX_COMPILER> <CMAKE_C_COMPILER>${CMAKE_C_COMPILER}</CMAKE_C_COMPILER> </cmakeDefines> </configuration> </plugin>
Once the properties are added to the CMake Maven plugin configuration, the CMake define can then be specified as a Maven property on the command line. The following example specifies the CMAKE_PREFIX_PATH CMake define via the Maven command line.
mvn validate -DCMAKE_PREFIX_PATH="${HOME}/libs/boost.1.68.0"
In a similar way, the make targets can be driven by the Maven command line if desired.
Configuration entries are placed within the <configuration> element in the plugin's XML. All configuration entries are optional.
Explicitly specify the generator to be used in the configure goal.
The default is to use the default generator on Unix like platforms and "NMake Makefiles" on Windows platforms.
<generator>Unix Makefiles</generator>
The root of the source code. If not absolute, the directory is relative to the project base directory. Defaults to ${project.basedir}.
<cmakeSourceDirectory>${project.basedir}</cmakeSourceDirectory>
The folder in which the CMake build will be made. If not absolute, the directory is relative to the project base directory. Defaults to ${project.build.directory}/cmake.
<cmakeBinaryDirectory>${project.build.directory}/cmake</cmakeBinaryDirectory>
Optional path to CMake binary. If not specified, the path is searched for the cmake executable.
<cmakePath>/opt/cmake/cmake-3.12.4/bin/cmake</cmakePath>
Additional command line definitions specified when running CMake.
<cmakeDefines> <-- Some example CMake command line definitions. --> <CMAKE_INSTALL_PREFIX>/opt/usr</CMAKE_INSTALL_PREFIX> <CMAKE_CXX_COMPILER>/usr/bin/g++</CMAKE_CXX_COMPILER> <CMAKE_C_COMPILER>/usr/bin/gcc</CMAKE_C_COMPILER> </cmakeDefines>
Additional command line options to be passed to the native Make tool when running cmake --build.
<makeOptions> <makeOption>-d</makeOption> </makeOptions>
The concurrency value specified to make. Defaults to the number of logical cpu cores.
<concurrency>4</concurrency>
Attach Make targets to the Maven compile phase. If no targets are defined, Make will be run with its default target.
<compileTargets> <-- Some example Make targets. --> <compileTarget>Lib</compileTarget> <compileTarget>App</compileTarget> </compileTargets>
Attach Make targets to the Maven test-compile phase. If no targets are defined, no Make targets will be run.
When using the balau-unit-test-maven-plugin and balau-integration-test-maven-plugin, the same Balau based test application executable can be used for both unit and integration tests. By default, the balau-unit-test-maven-plugin and balau-integration-test-maven-plugin plugins will run different sets of tests groups (*Test::* for unit tests, *IT::* for integration tests). There is thus no need to define two CMake targets/executables.
<testCompileTargets> <-- Example Make target to build a test application. --> <testCompileTarget>Tests</testCompileTarget> </testCompileTargets>
Extra evironment variables to be defined for the CMake process. Note that this does not set the environment variables prior to calling the CMake executable.
Use of existing environment variables within new environment variables can be achieved via the %ENV_VAR_NAME% syntax. This syntax avoids clashes with the Maven ${ENV_VAR_NAME} syntax.
<environmentVariables> <ABC>123</ABC> <PATH>/opt/cppcheck/bin:%PATH%</PATH> </environmentVariables>
The balau-unit-test-maven-plugin provides a mechanism for driving unit test executions based on the Balau test framework. The plugin allows a simple and concise way of integrating the execution of Balau style unit tests into a Maven based SDLC infrastructure.
The balau-unit-test-maven-plugin includes configuration specific to the Balau test framework, allowing test applications to be configured from within the project's pom files.
The following Maven goal is defined:
This goal binds by default to the test Maven phase.
The single test goal executes the default or specified Balau based test application(s). The Balau test framework configuration options specified in the plugin's configuration are passed to the applications.
By default, test group classes matching the *Test::* glob are run.
<plugin> <groupId>com.borasoftware.balau</groupId> <artifactId>balau-unit-test-maven-plugin</artifactId> <version>19.8.1</version> <executions> <execution> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin>
Configuration entries are placed within the <configuration> element in the plugin's XML. All configuration entries are optional.
The folder in which the CMake build was made. If not absolute, the directory is relative to the project base directory. Defaults to ${project.build.directory}/cmake.
<cmakeBinaryDirectory>${project.build.directory}/cmake</cmakeBinaryDirectory>
Unit test report directory. If not absolute, the directory is relative to the CMake build directory. Defaults to ${project.build.directory}/cmake/unitTestReports.
<reportDirectory>${project.build.directory}/cmake/unitTestReports</reportDirectory>
Specify a single test application path relative to the CMake build directory. If neither an appPath element nor appPaths element is defined, the test application will default to bin/Tests if an executable exists in that path, then Tests otherwise.
<appPath>bin/Tests</appPath>
Specify multiple test application paths relative to the CMake build directory. If neither an appPath element nor appPaths element is defined, the test application will default to bin/Tests if an executable exists in that path, then Tests otherwise.
<appPaths> <appPath>bin/App1Tests</appPath> <appPath>bin/App2Tests</appPath> </appPaths>
Balau test framework execution model. Defaults to SingleThreaded.
<executionModel>SingleThreaded</executionModel>
Test name globs to run. Defaults to *Test::*.
<patterns> <pattern>*Test::*</pattern> </patterns>
Custom LD_LIBRARY_PATH to use when running the test application. Defaults to empty LD_LIBRARY_PATH.
<ldLibraryPath>/opt/a:/opt/b</ldLibraryPath>
The balau-integration-test-maven-plugin provides a mechanism for driving integration test executions based on the Balau test framework. The plugin allows a simple and concise way of integrating the execution of Balau style integration tests into a Maven based SDLC infrastructure.
The balau-integration-test-maven-plugin includes configuration specific to the Balau test framework, allowing test applications to be configured from within the project's pom files.
The balau-integration-test-maven-plugin is similar to the balau-unit-test-maven-plugin, and contains similar configuration options.
The following Maven goal is defined:
This goal binds by default to the integration-test Maven phase.
The single test goal executes the default or specified Balau based test application. The Balau test framework configuration options specified in the plugin's configuration are passed to the application.
By default, test group classes matching the *IT::* glob are run.
<plugin> <groupId>com.borasoftware.balau</groupId> <artifactId>balau-integration-test-maven-plugin</artifactId> <version>19.8.1</version> <executions> <execution> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin>
Configuration entries are placed within the <configuration> element in the plugin's XML. All configuration entries are optional.
The folder in which the CMake build was made. If not absolute, the directory is relative to the project base directory. Defaults to ${project.build.directory}/cmake.
<cmakeBinaryDirectory>${project.build.directory}/cmake</cmakeBinaryDirectory>
Integration test report directory. If not absolute, the directory is relative to the CMake build directory. Defaults to ${project.build.directory}/cmake/integrationTestReports.
<reportDirectory>${project.build.directory}/cmake/integrationTestReports</reportDirectory>
Specify a single test application path relative to the CMake build directory. If neither an appPath element nor appPaths element is defined, the test application will default to bin/Tests if an executable exists in that path, then Tests otherwise.
<appPath>bin/Tests</appPath>
Specify multiple test application paths relative to the CMake build directory. If neither an appPath element nor appPaths element is defined, the test application will default to bin/Tests if an executable exists in that path, then Tests otherwise.
<appPaths> <appPath>bin/App1Tests</appPath> <appPath>bin/App2Tests</appPath> </appPaths>
Balau test framework execution model. Defaults to SingleThreaded.
<executionModel>SingleThreaded</executionModel>
Test name globs to run. Defaults to *IT::*.
<patterns> <pattern>*IT::*</pattern> </patterns>
Custom LD_LIBRARY_PATH to use when running the test application. Defaults to empty LD_LIBRARY_PATH.
<ldLibraryPath>/opt/a:/opt/b</ldLibraryPath>