How do both use my custom Gradle plugins in my project and publish them to other projects?

I have a set of plugins that I would like to use in several projects, including subprojects of the project that currently contains them.

Originally they were built like a standard project ‘:plugins’ and had other projects load it from a known location using

buildscript { dependencies { classpath files(url) } }

. I then wanted to use the plugins from another subproject ‘:xyz’ of the same project containing ‘:plugins’, but I found that I could not get my plugins to build before they were used by ‘:xyz’ using

buildscript { dependencies { classpath project(':plugins') } }

on the root project. I then tried to move ‘:plugins’ into ‘:buildSrc’ to have them built first for the entire project. As I can’t address ‘:buildSrc’ from the project code, I thought I would have the buildSrc build assemble the jar for me, but the jar I create comes out empty.

apply plugin: 'groovy'
  dependencies {
    compile gradleApi()
    compile localGroovy()
  jar {
    archiveName = 'plugins.jar'
    from sourceSets.main.output
    manifest {
        attributes 'Implementation-Title': 'my.helicopter.plugins'
  defaultTasks 'assemble'

What is the build of buildSrc doing differently from a regular Groovy project build that prevents this from working?

If you want to reuse a binary plugin in multiple builds, the only safe solution is to have a separate build for the plugin.

What is the “unsafe” way of doing it then, and what is the danger? Why is it not possible for ‘:buildSrc’, which has its own buildscript, to assemble a jar to a known location, in addition appearing on the classpath of the containing master project?

If you just want to grab the Jar, can’t you just grab ‘buildSrc/libs/buildSrc.jar’? I don’t know why the Jar comes out empty for you, but maybe ‘from sourceSets.main.output’ or ‘defaultTasks ‘assemble’’ causes troubles, and you shouldn’t need either of them.