<!--
  ~ Copyright 2010 the original author or authors.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<chapter id='cpp'>
    <title>C++ Support</title>

    <note>
        <para>
            The Gradle C++ support is currently <link linkend="feature_lifecycle">incubating</link>. Please be aware that the DSL and other configuration may change in later Gradle versions.
        </para>
    </note>

    <para>
        The C++ plugins add support for building software comprised of C++ source code, and managing the process of building “native” software in general.
        While many excellent build tools exist for this space of software development, Gradle offers C++ developers it's trademark power and flexibility
        together with the dependency management practices more traditionally found in the JVM development space.
    </para>
    <para>
        Gradle offers the ability to execute the same build using different tool chains. At present, you control which tool chain will be used to build
        by changing the operating system PATH to include the desired tool chain compiler. The following tool chains are supported:
    </para>
    <table>
        <thread>
            <tr><td>Operating System</td><td>Tool Chain</td><td>Notes</td></tr>
        </thread>
        <tr>
            <td>Linux</td><td><ulink url="http://gcc.gnu.org/">GCC</ulink></td><td></td>
        </tr>
        <tr>
            <td>Mac OS X</td><td><ulink url="http://gcc.gnu.org/">GCC</ulink></td><td>Using GCC distributed with XCode.</td>
        </tr>
        <tr>
            <td>Windows</td><td><ulink url="http://gcc.gnu.org/">GCC</ulink></td><td>Windows XP and later, using GCC distributed with Cygwin.</td>
        </tr>
        <tr>
            <td>Windows</td><td><ulink url="http://www.microsoft.com/visualstudio/en-us">Visual C++</ulink></td><td>Windows XP and later, Visual C++ 2010 and later.</td>
        </tr>
        <tr>
            <td>Windows</td><td><ulink url="http://www.mingw.org/">MinGW</ulink></td><td>Windows XP and later.</td>
        </tr>
    </table>
    <para>
        Currently, there is no direct support for creating multiple variants of the same binary (e.g. 32 bit vs. 64 bit) and there is no direct
        support for cross platform source configuration (à la <ulink url="http://www.gnu.org/s/autoconf/">autoconf</ulink>) at this time. Support for different
        compiler chains, managing multiple variants and cross platform source configuration will be added over time, making Gradle a fully capable build tool for C++
        (and other “native” language) projects.
    </para>

    <section>
        <title>Source code locations</title>
        <para>
            A C++ project may define a number of source sets, each of which may contain source files and header files.
            By default, a named <apilink class="org.gradle.nativecode.language.cpp.CppSourceSet"/> contains
            <filename>.cpp</filename> and <filename>.c</filename> source files in <filename>src/${name}/cpp</filename>,
            and header files in <filename>src/${name}/headers</filename>.
        </para>
        <sample id="cppSourceSets" dir="cpp/cpp" title="Defining 'cpp' source sets">
            <sourcefile file="build.gradle" snippet="sourceSets"/>
        </sample>
        <para>
            For a library named 'main', files in <filename>src/main/headers</filename> are considered the “public” or “exported” headers.
            Header files that should not be exported (but are used internally) should be placed inside the <filename>src/main/cpp</filename> directory (though be aware that
            such header files should always be referenced in a manner relative to the file including them).
        </para>
        <para>
            While the <literal>cpp</literal> plugin defines these default locations for each <apilink class="org.gradle.nativecode.language.cpp.CppSourceSet"/>,
            it is possible to extend or override these defaults to allow for a different project layout.
        </para>
    </section>

    <section>
        <title>Component model</title>
        <para>
            A C++ project defines a set of <apilink class="org.gradle.nativecode.base.Executable"/> and <apilink class="org.gradle.nativecode.base.Library"/> components,
            each of which Gradle maps to a number of <apilink class="org.gradle.nativecode.base.NativeBinary"/> outputs.
            Each <literal>executable</literal> or <literal>library</literal> is associated with a particular <literal>CppSourceSet</literal>, which contains C++ source files as well as header files.
        </para>
        <para>
            To build either a static or shared native library binary,
            a <apilink class="org.gradle.nativecode.base.Library"/> component is added to the <literal>libraries</literal>
            container and associated with a <literal>CppSourceSet</literal>.
            Each <literal>library</literal> component can produce at least one <apilink class="org.gradle.nativecode.base.SharedLibraryBinary"/> and
            at least one <apilink class="org.gradle.nativecode.base.StaticLibraryBinary"/>.
        </para>
        <sample id="cppLibraries" dir="cpp/cpp" title="Defining a library component">
            <sourcefile file="build.gradle" snippet="libraries"/>
        </sample>
        <para>
            To build an executable binary,
            an <apilink class="org.gradle.nativecode.base.Executable"/> component is added to the <literal>executables</literal> container
            and associated with a <literal>CppSourceSet</literal>.
        </para>
        <para>
            Each <literal>executable</literal> component added can produce at least one <apilink class="org.gradle.nativecode.base.ExecutableBinary"/>.
            If the executable requires a library for compiling and/or linking, then that library can be provided directly to a <literal>binary</literal>.
        </para>        <sample id="cppExecutables" dir="cpp/cpp" title="Defining executable components">
            <sourcefile file="build.gradle" snippet="executables"/>
        </sample>
        <para>
            Alternatively, the library dependency can be specified at the level of the the <literal>CppSourceSet</literal> associated with an <literal>executable</literal> component:
        </para>
        <sample id="cppSourceLibrary" dir="cpp/cpp" title="Specifying a source-level library">
            <sourcefile file="build.gradle" snippet="source-library"/>
        </sample>
    </section>

    <section>
        <title>Plugins</title>
        <para>
            All build scripts DSLs, model elements and tasks used to manage C++ projects are added by the <literal>cpp</literal> plugin.
        </para>
        <sample id="cppLibraries" dir="cpp/cpp" title="Applying the 'cpp' plugin">
            <sourcefile file="build.gradle" snippet="apply-plugin"/>
        </sample>
        <para>
            The <literal>cpp</literal> plugin allows you to configure any number of <literal>libraries</literal> and <literal>executables</literal> for your project.
            However, at times it is more convenient to use either the <literal>cpp-lib</literal> or <literal>cpp-exe</literal> plugins that sit on top of the <literal>cpp</literal>
            plugin and pre-configure the project to build a single native library or executable respectively.
        </para>
        <sample id="useCppExePlugin" dir="cpp/cpp-exe" title="Using the 'cpp-exe' plugin">
            <sourcefile file="build.gradle" snippet="use-plugin"/>
        </sample>
        <sample id="useCppLibPlugin" dir="cpp/cpp-lib" title="Using the 'cpp-lib' plugin">
            <sourcefile file="build.gradle" snippet="use-plugin"/>
        </sample>
        <para>
            The <literal>cpp-exe</literal> plugin configures the project to build a single executable named <literal>main</literal>,
            and the <literal>cpp-lib</literal> plugin configures the project to build a shared and static version of a single library named <literal>main</literal>.
        </para>
        <para>
            In both cases, a single source set (<literal>src/main</literal>) containing C++ sources is assumed to exist.
        </para>
    </section>

    <section>
        <title>Tasks</title>
        <para>
            For each <apilink class="org.gradle.nativecode.base.NativeBinary"/> that can be produced by a build, the <literal>cpp</literal> plugin
            creates a single <literal>lifecycle task</literal> that can be used to create that binary, together with a set of sub-tasks that do the actual
            work of compiling, linking or assembling the binary.
        </para>
        <table>
            <thread>
                <tr><td>Component Type</td><td>Native Binary Type</td><td>Lifecycle task</td><td>Location of created binary</td></tr>
            </thread>
            <tr>
                <td><apilink class="org.gradle.nativecode.base.Executable"/></td><td><apilink class="org.gradle.nativecode.base.ExecutableBinary"/></td><td><literal>mainExecutable</literal></td><td><filename><replaceable>$buildDir</replaceable>/binaries/<replaceable>$project.name</replaceable></filename></td>
            </tr>
            <tr>
                <td><apilink class="org.gradle.nativecode.base.Library"/></td><td><apilink class="org.gradle.nativecode.base.SharedLibraryBinary"/></td><td><literal>mainSharedLibrary</literal></td><td><filename><replaceable>$buildDir</replaceable>/binaries/lib<replaceable>$project.name</replaceable>.so</filename></td>
            </tr>
            <tr>
                <td><apilink class="org.gradle.nativecode.base.Library"/></td><td><apilink class="org.gradle.nativecode.base.StaticLibraryBinary"/></td><td><literal>mainStaticLibrary</literal></td><td><filename><replaceable>$buildDir</replaceable>/binaries/<replaceable>$project.name</replaceable>.a</filename></td>
            </tr>
        </table>
    </section>

    <section>
        <title>Building</title>
        <section>
            <title>Compiling on UNIX</title>
            <para>
                The UNIX C++ support is currently based on the <literal>g++</literal> tool which must be installed and on the <literal>PATH</literal>
                for the Gradle process.
            </para>
        </section>
        <section>
            <title>Compiling on Windows</title>
            <para>
                The Windows C++ support can use either the MinGW <literal>g++</literal> or the Microsoft Visual C++ <literal>cl</literal> tool, either of which must be installed and on the
                <literal>PATH</literal> for the Gradle process. Gradle searches first for Microsoft Visual C++, and then MinGW.
            </para>
        </section>
    </section>

    <section>
        <title>Configuring the compiler and linker</title>
        <para>
            Each binary to be produced is associated with a set of compiler and linker settings, which include command-line arguments as well as macro definitions.
            These settings can be applied to all binaries, an individual binary, or selectively to a group of binaries based on some criteria.
        </para>
        <sample id="allBinarySettings" dir="cpp/cpp" title="Settings that apply to all binaries">
            <sourcefile file="build.gradle" snippet="all-binaries"/>
        </sample>
        <para>
            Each binary is associated with a particular <apilink class="org.gradle.nativecode.base.ToolChain"/>, allowing settings to be targeted based on
            this value.
        </para>
        <para>
            It is easy to apply settings to all binaries of a particular type:
        </para>
        <sample id="allSharedLibraryBinarySettings" dir="cpp/cpp" title="Settings that apply to all shared libraries">
            <sourcefile file="build.gradle" snippet="all-shared-libraries"/>
        </sample>
        <para>
            Furthermore, it is possible to specify settings that apply to all binaries produces for a particular <literal>executable</literal>
            or <literal>library</literal> component:
        </para>
        <sample id="componentBinarySettings" dir="cpp/cpp-exe" title="Settings that apply to all binaries produced for the 'main' executable component">
            <sourcefile file="build.gradle" snippet="args"/>
        </sample>
        <para>
            The above example will apply the supplied configuration to all <literal>executable</literal> binaries built.
        </para>
        <para>
            Similarly, settings can be specified to target binaries for a component that are of a particular type:
            eg all <literal>shared libraries</literal> for the <literal>main library</literal> component.
        </para>
        <sample id="sharedLibraryArgs" dir="cpp/cpp-lib" title="Settings that apply only to shared libraries produced for the 'main' library component">
            <sourcefile file="build.gradle" snippet="args"/>
        </sample>
    </section>

    <section>
        <title>Working with shared libraries</title>
        <para>
            For each executable binary produced, the <literal>cpp</literal> plugin provides an <literal>install${binary.name}</literal> task,
            which creates a development install of the executable, along with the shared libraries it requires.
            This allows you to run the executable without needing to install the shared libraries in their final locations.
        </para>
    </section>

    <section>
        <title>Dependencies</title>
        <para>
            Dependencies for C++ projects are binary libraries that export header files. The header files are used during compilation, with the compiled
            binary dependency being used during the linking.
        </para>
        <section>
            <title>External Dependencies</title>
            <para>
                External dependencies (i.e. from a repository, not a subproject) must be specified using the following syntax:
            </para>
            <sample id="gppArgs" dir="cpp/dependencies" title="Declaring dependencies">
                <sourcefile file="build.gradle" snippet="declaring-dependencies"/>
            </sample>
            <para>
                Each dependency must be specified with the <literal>dependency</literal> method as above and must be declared as part of the source set. The
                <literal>group</literal>, <literal>name</literal> and <literal>version</literal> arguments <emphasis>must</emphasis> be supplied.
            </para>
            <para>
                For each declared dependency, two actual dependencies are created. One with the classifier “<literal>headers</literal>” and extension
                “<literal>zip</literal>” which is a zip file of the exported headers, and another with the classifier “<literal>so</literal>” and extension
                “<literal>so</literal>” which is the compiled library binary to link against (which is supplied as a direct input to the g++ link operation).
            </para>
        </section>
        <section>
            <title>Project Dependencies</title>
            <para>
                The notation for project dependencies is slightly different.
            </para>
            <sample id="cppProjectDependencies" dir="cpp/multi-project" title="Declaring project dependencies">
                <sourcefile file="build.gradle" snippet="project-dependencies"/>
            </sample>
        </section>
    </section>

    <section>
        <title>Publishing</title>
        <para>
            The <literal>cpp-exe</literal> and <literal>cpp-lib</literal> plugins configure their respective output binaries to be publishable as part of the
            <literal>archives</literal> configuration. To publish, simply configure the <literal>uploadArchives</literal> task as per usual.
        </para>
        <sample id="cppPublish" dir="cpp/dependencies" title="Uploading exe or lib">
            <sourcefile file="build.gradle" snippet="upload"/>
        </sample>
        <para>
            The <literal>cpp-exe</literal> plugin publishes a single artifact with extension “<literal>exe</literal>”. The <literal>cpp-lib</literal> plugin
            publishes two artifacts; one with classifier “<literal>headers</literal>” and extension “<literal>zip</literal>”, and one with classifier
            “<literal>so</literal>” and extension “<literal>so</literal>” (which is the format used when consuming dependencies).
        </para>
        <note>
            <para>
                Currently, there is no support for publishing the dependencies of artifacts in POM or Ivy files. Future versions will support this.
            </para>
        </note>
    </section>

</chapter>