C/C++ plugin suite
------------------

                 Key: MOJO-1704
                 URL: https://jira.codehaus.org/browse/MOJO-1704
             Project: Mojo
          Issue Type: New Feature
            Reporter: Daniel Franzen
         Attachments: cpp-plugins.zip

This is a suite of three plugins currently used for C/C++ projects at Ericsson, 
as previously described in [email protected].

Rationale
If I were you I'd be asking "Isn't there already a plugin for that? Why another 
one?". I hope that question is answered in detail below, but the long and the 
short of it is we felt that the need for better performance, less verbose 
configuration and built-in support for multiple targets - both common and 
exotic ones - motivated an attempt at rolling our own.
 
- Speed
What triggered the development of these plugins earlier this year were the 
problems we were having with existing plugins for native code. Perhaps the 
fault was with us not understanding how to use them properly, but it eventually 
got to a point where people started writing alternative Boost.Build scripts for 
building and unit testing. Maven was also generally perceived as slow and 
unable to compete with "real C/C++ tools". Thus the plugins were developed to 
answer the question: Can we match the speed of Boost.Build, yet bring all the 
goodness of Maven to C/C++ projects? While build benchmarking is a tricky 
business, from my experience with the projects where we have deployed the 
plugins, I would say the answer is yes. How the project is structured plays a 
role, though: sometimes Boost.Build is faster, sometimes the Maven plugins are 
faster.
 
How it works
- Three plugins
Currently the suite consists of cpp-compiler-maven-plugin (the workhorse), 
cpp-tester-maven-plugin (runs any executables produced by the compiler) and 
car-maven-plugin (zips the output into a ".car" artifact). 
cpp-compiler-maven-plugin defines a custom lifecycle for packaging type "car", 
invoking itself and the other plugins in phases compile, test-compile, test and 
package.
 
- Multi-target
Which targets to build for is controlled by putting e.g. 
<targetEnvironments>linux_32,linux_64,win_32</targetEnvironments> in the plugin 
configuration. Compilation and linking flags can then be specified per target 
and/or for all targets.
 
- Bundles
We'd like to support any combination of host to target environments, and any 
oddities of the target environment shouldn't bleed through to the POM. To this 
end we introduced "bundles", which are essentially plugins to the plugin. When 
the plugin needs to build for a given target it asks the bundles on its 
classpath: Given the current host environment, can you build for this target? 
If one and only one bundle answers yes it will get the job. This allows for 
clean configuration of multiple exotic, proprietary, in-house targets with 
custom toolchains along with standard Linux x86/Windows targets. Included in 
the donation is only our Linux 32/64 bundle using GCC.
 
- Multi-threading
The plugin spawns as many compiler threads as there are logical cores, each 
thread polling a common pool of objects to build. The pool is populated by the 
main thread, which determines what needs to be built and what's up to date. 
That is, compilation starts as soon as the first object has been put up for 
building. To reduce overhead the compiler is fed batches of files, but to avoid 
single threads overshooting the others dynamic batch sizes are used. 
Essentially each thread only picks up as many objects to build as it's 
confident to complete before the other threads have finished off the rest of 
the pool.
 
- Incremental builds
The plugin uses a mechanism determined by the responsible bundle (our Linux 
bundle uses the GCC pre-processor) to decide whether an object is up to date or 
not. Any up-to-date include dependency information left over from previous 
builds is reused to minize the incremental build time.
 
- Dependency extraction
The .car artifacts are zips of static libraries and/or headers for each 
supported target. As dependencies are needed during the project lifecycle they 
are extracted from the local repository into the target directory, but only the 
parts needed are extracted (e.g. you don't need to extract targets you yourself 
are not building for). Any existing extracted dependencies are checked before 
extraction - if the correct non-SNAPSHOT version of a dependency has already 
been extracted it will be reused. SNAPSHOT dependencies are replaced if a newer 
version exists in the local repository.
 
- Linking
Linking executables and test executables is done for separate and/or all 
targets by specifying which code files contain the main function(s). A syntax 
example of this would be:
<executables><all>myExec=src/main/cpp/MyExec.cc;myOtherExec=src/main/cpp/MyOtherExec.cc,src/main/cpp/Other*cc</all><linux_64>[]=src/linux/main/cpp/entry-points/*.cc</linux_64></executables>.
 This would create a myExec and a myOtherExec for every target. In addition, 
for linux_64 a separate executable will be linked for each file matching the 
pattern. This is very useful when doing one-executable-per-test style unit 
tests.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply via email to