# How to add a pre compile task into cpp plugin

**URL:** <https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113>\
**Category:** Help/Discuss\
**Tags:** plugins\
**Created:** [December 7, 2015, 9:02pm UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113 "2015-12-07T21:02:40Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mccwi](https://avatars.discourse-cdn.com/v4/letter/m/e47774/32.png) [@mccwi](https://discuss.gradle.org/u/mccwi)\
**Post date:** [December 7, 2015, 9:02pm UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/1 "2015-12-07T21:02:40Z")

</div>

Hello Folks,

I have a Qt based cpp application and I want to migrate the build scripts from qmake to gradle.  
To do so I need to run the Qt moc tool over all header files that contain the Q\_OBJECT key word.

I’ve done some research on how to achieve that, but I’m struggling.  
Can someone give me a hint?

Should I extend the cpp plugin, and if so, where can I inject my task.  
I looked at the sources of the cpp plugin, but didn’t see a point to extend it.

Or should I do it in the model space or with the rule mechanism?

Thank you in advance  
Christian

---

<div class="post-metadata">

**Author:** ![mccwi](https://avatars.discourse-cdn.com/v4/letter/m/e47774/32.png) [@mccwi](https://discuss.gradle.org/u/mccwi)\
**Post date:** [December 22, 2015, 9:23pm UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/2 "2015-12-22T21:23:19Z")

</div>

So, after a long journey I found a solution by myself.

```gradle
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.SourceTask
import org.gradle.api.tasks.TaskAction

class QtMocTask extends SourceTask {
    @OutputDirectory
    File destinationDir
        
    @TaskAction
    void generateMocFile() {
         source.filter { x -> x.isFile() && x.text.contains('Q_OBJECT') }.each {
             def mocFileName = "${destinationDir}/moc_${it.name}.cpp"
             def process = "moc -o ${mocFileName} ${it.path}".execute()
             process.waitFor()
             if (process.exitValue()) {
                 println process.err.text
             } 
         }
    }
}

```

```gradle
import org.apache.commons.lang.StringUtils
import org.gradle.model.Defaults
import org.gradle.model.Mutate
import org.gradle.model.ModelMap
import org.gradle.model.Path
import org.gradle.model.RuleSource
import org.gradle.platform.base.BinarySpec
import org.gradle.language.cpp.CppSourceSet
import org.gradle.language.cpp.tasks.CppCompile

class QtPlugin extends RuleSource {

    @Defaults
    void createQtMocTask(ModelMap<BinarySpec> binaries, final @Path("buildDir") File buildDir) {
        binaries.beforeEach { binary ->
            binary.inputs.withType(CppSourceSet.class) { sourceSet ->
                def taskName = "${binary.getNamingScheme().getTaskName('qtMoc')}${StringUtils.capitalize(sourceSet.parentName)}${StringUtils.capitalize(sourceSet.name)}"
                binary.tasks.create(taskName, QtMocTask) { task ->
                    task.source = sourceSet.source
                    task.destinationDir = new File(buildDir, "generated/${binary.name}/moc")
                    task.description = "Creates qt moc-files for ${binary.displayName}"
                }

                sourceSet.source.srcDir(new File(buildDir, "generated/${binary.name}/moc"))
                binary.tasks.withType(CppCompile.class) { compileTask ->
                    compileTask.dependsOn(taskName)
                }
            }
        }
    }
}

```

Would be nice to here some comments.  
Christian

---

<div class="post-metadata">

**Author:** ![starshipjc](https://avatars.discourse-cdn.com/v4/letter/s/f4b2a3/32.png) [@starshipjc](https://discuss.gradle.org/u/starshipjc)\
**Post date:** [June 1, 2016, 8:19pm UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/3 "2016-06-01T20:19:10Z")

</div>

Hi Christian,

I don’t know if you are still using this, but I’d like to try it out (not knowing anything about extending Gradle…).

Do you have an example script?

---

<div class="post-metadata">

**Author:** ![mccwi](https://avatars.discourse-cdn.com/v4/letter/m/e47774/32.png) [@mccwi](https://discuss.gradle.org/u/mccwi)\
**Post date:** [June 2, 2016, 11:05am UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/4 "2016-06-02T11:05:01Z")

</div>

Hello Jason,

what exactly do you want to know? Currently I’m not working with gradle any more because I had no time in the last months, but I still do have the sources.

---

<div class="post-metadata">

**Author:** ![starshipjc](https://avatars.discourse-cdn.com/v4/letter/s/f4b2a3/32.png) [@starshipjc](https://discuss.gradle.org/u/starshipjc)\
**Post date:** [June 2, 2016, 2:39pm UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/5 "2016-06-02T14:39:53Z")

</div>

Hi Christian, thanks for getting back to me…

I take it you have to build the two Java snippets (or does Groovy interpret them?)

What does the build.gradle file look like for a simple Qt project (i.e. how do I inject the plugins)?

---

<div class="post-metadata">

**Author:** ![mccwi](https://avatars.discourse-cdn.com/v4/letter/m/e47774/32.png) [@mccwi](https://discuss.gradle.org/u/mccwi)\
**Post date:** [June 3, 2016, 5:24am UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/6 "2016-06-03T05:24:11Z")

</div>

This how my build.gradle looks like:

```gradle
apply plugin: 'cpp'

model {
    repositories {
        libs(PrebuiltLibraries) {
          QtHeaders {
            headers.srcDir "/usr/include/qt4/"
          }

          ["QtCore", "QtGui"].each { libName -> "${libName}" {
                // You have to locate where qt installed the header files
                headers.srcDir "/usr/include/qt4/${libName}"
                binaries.withType(SharedLibraryBinary) {
                    // You have to locate where qt installed the libs
                    sharedLibraryFile = file("/usr/lib/lib${libName}.so")
                }
              }
          }
        }
    }

    components {
        main(NativeExecutableSpec) {
          sources {
              cpp {
                  lib library: 'QtHeaders', linkage: 'api'
                  lib library: 'QtCore', linkage: 'shared'
                  lib library: 'QtGui', linkage: 'shared'
              }
          }
        }
    }

}

import my.gradle.qt.QtPlugin
apply plugin: QtPlugin

task wrapper(type: Wrapper) {
    gradleVersion = '2.10'
}

```

I do not know if it still works with the new gradle versions.

---

<div class="post-metadata">

**Author:** ![mccwi](https://avatars.discourse-cdn.com/v4/letter/m/e47774/32.png) [@mccwi](https://discuss.gradle.org/u/mccwi)\
**Post date:** [June 3, 2016, 9:05am UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/7 "2016-06-03T09:05:33Z")

</div>

I created a repo with the whole source code here:  
[https://github.com/nesayus/gradle.qt](https://github.com/nesayus/gradle.qt)

---

<div class="post-metadata">

**Author:** ![starshipjc](https://avatars.discourse-cdn.com/v4/letter/s/f4b2a3/32.png) [@starshipjc](https://discuss.gradle.org/u/starshipjc)\
**Post date:** [June 3, 2016, 11:19am UTC](https://discuss.gradle.org/t/how-to-add-a-pre-compile-task-into-cpp-plugin/13113/8 "2016-06-03T11:19:27Z")

</div>

Awesome, I will give it a try!
