smeeb
smeeb

Reputation: 29537

Versioning Gradle native plugin builds

Here's my first attempt at a C program built with Gradle's C plugin:

apply plugin: 'c'

model {
    components {
        derpus(NativeExecutableSpec) {
            sources {
                c(CSourceSet) {
                    source {
                        srcDir "src/derpus/c"
                        include "**/*.c"
                    }
                    exportedHeaders {
                        srcDir "src/derpus/headers"
                    }
                }
            }
        }
    }
}

This produces an executable called derpus.exe. I would like, if at all possible, to version these executables (derpus-1.0.0.exe, derpus-1.0.1.exe, etc.). When I change the derpus closure to derpus-1.0.0 like so:

derpus-1.0.0(NativeExecutableSpec) {

And run gradle clean build I get:

D:\workspace\derp\20150505\derpus>gradlew clean build

FAILURE: Build failed with an exception.

* Where:
Build file 'D:\derpus\build.gradle' line: 6

* What went wrong:
Could not compile build file 'D:\derpus\build.gradle'.
> startup failed:
    build file 'D:\derpus\build.gradle': 6: unexpected tok
    en: 0 @ line 6, column 20.
                    derpus-1.0.0(NativeExecutableSpec) {
                               ^

    1 error

Does anybody know of a way to version these executables?


Update

Now this is really weird! Taking Amnon's advice, I added a gradle.properties file that defined version=1.0.0. I then modified my model closure to:

model {
    components {
        derpus(NativeExecutableSpec) {
            sources {
                c(CSourceSet) {
                    source {
                        srcDir "src/derpus/c"
                        include "**/*.c"
                    }
                    exportedHeaders {
                        srcDir "src/derpus/headers"
                    }
                }
            }

            baseName = "derpus-${version}"
        }
    }
}

This produces an executable named derpus-1 (what?!?!)!

So then I modified model again:

version = "3.4"

model {
    components {
        derpus(NativeExecutableSpec) {
            sources {
                c(CSourceSet) {
                    source {
                        srcDir "src/derpus/c"
                        include "**/*.c"
                    }
                    exportedHeaders {
                        srcDir "src/derpus/headers"
                    }
                }
            }

            baseName = "derpus-${version}"
        }
    }
}

As you can see, this should overrdide the version set in gradle.properties, however after running gradle clean build, it produces derpus-3!

So I modified model yet again:

model {
    components {
        derpus(NativeExecutableSpec) {
            sources {
                c(CSourceSet) {
                    source {
                        srcDir "src/derpus/c"
                        include "**/*.c"
                    }
                    exportedHeaders {
                        srcDir "src/derpus/headers"
                    }
                }
            }

            baseName = "derpus-3.4.5"
        }
    }
}

This produces derpus-3.4!!! What is going on here?!? Does the C plugin have a bug in it that doesn't honor the full version variable?

Upvotes: 0

Views: 186

Answers (1)

Amnon Shochot
Amnon Shochot

Reputation: 9376

In your example above the problem with derpus-1.0.0 is the gradle things that the dash character is a minus which is unexpected in a component spec name, thus the failure. You can overcome this by wrapping derpus-1.0.0 with inverted commas. A better approach, however, would be to apply the version to the baseName property of the component spec, i.e. add the following line under derpus component definition:

baseName = "derpus-1.0.0"

or

baseName = "derpus-$version"

Where in the second case the version property $version is taken from the project object.

Update

Per smeeb comments below another workaround that can be applied is to directly rename the target binaries:

afterEvaluate {
    RenameNativeBinaries()
}

def RenameNativeBinaries() {
    binaries.all { b ->
        if (b instanceof SharedLibraryBinarySpec) {
            b.sharedLibraryFile = ReconstructFileName(b.sharedLibraryFile)
        } else if (b instanceof StaticLibraryBinarySpec) {
            b.staticLibraryFile = ReconstructFileName(b.staticLibraryFile)
        } 
    }
}

def ReconstructFileName(File originalFile) {
    def originalFileName = originalFile.absolutePath
    def filePath = FilenameUtils.getFullPath(originalFileName)
    def baseName = FilenameUtils.getBaseName(originalFileName)
    def extension = FilenameUtils.getExtension(originalFileName)

    def newName = "$baseName-$version.$extension"
    def newFile = new File(filePath, newName)
    newFile
}

Where FilenameUtils is taken from commons-io:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath group: 'commons-io', name: 'commons-io', version: '2.4'
    }
}

Upvotes: 1

Related Questions