web-dev-qa-db-ja.com

'debug'および 'release'JARファイルをビルドするための慣用的なGradleスクリプト

Java .jarファイルを「リリース」または「デバッグ」モードでビルドするGradleビルドスクリプトを作成しようとしていますが、スクリプトのパラメーター化に問題があります。

質問は次のとおりです:Javaプラグイン?()を使用して、Gradleスクリプトでこれを行う慣用的な方法は何ですか?または、慣用的な方法がない場合、実際に機能するハッキーなソリューションは何ですか?)

コマンドラインとIDE呼び出しが2つの出力オプションから簡単に選択できる限り、パラメーター化の方法は気にしません。jarファイルは他のライブラリとして使用されます。プロジェクト、たとえばAndroidアプリとJavaFXアプリなので、パラメーター化の方法を独自のGradleスクリプトから呼び出し可能/依存させる必要があります。

理想的には、すべてのタスクのデバッグ/リリースバージョンを持つAndroid gradleプラグインの機能を「エミュレート」したいと思います。

$ ./gradlew build    
$ ./gradlew assembleRelease
$ ./gradlew checkDebug

しかし、それが失敗した場合でも、トップレベルのbuildDebugとbuildReleaseが適しています。


私が試したもの

このセクションは、質問とはあまり関係がありません。

出発点

私は次のgradleファイル/プロジェクトを持っています:

group 'TestGradleProjectGroup'
apply plugin: 'Java'
sourceCompatibility = 1.8

version '1.0-release'
compileJava {
    options.debug = false
}

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

これは正常に機能し、jarファイルを生成します。

$ ls TestGradleModule/build/libs/
TestGradleModule-1.0-release.jar

抽出されたクラスをjavapで検査すると、デバッグ情報は含まれません。万歳。いいえ、デバッグバージョンを作成する方法は必要ありません。

デバッグおよびリリースタスクを追加する

version '1.0-release'
compileJava {
    options.debug = false
}

task buildRelease(type: GradleBuild, dependsOn: build) {
    project.version = '1.0-release'
    compileJava {
        options.debug = false
    }
}

task buildDebug(type: GradleBuild, dependsOn: build) {
    project.version = '1.0-debug'
    compileJava {
        options.debug = true
    }
}

BuildReleaseがコマンドラインで指定されたタスクであっても、デバッグプロジェクトは常にビルドされるため、これは機能しませんでした。これは、両方のタスクのコードが構成時に実行されるためだと思います( Gradleビルドライフサイクル )が、1つだけ実行したいのです。だから私は実行時にそれらを実行したいと思いますか?

いくつかのdoLastタスクを追加します

version '1.0-release'
compileJava {
    options.debug = false
}

task buildRelease(type: GradleBuild, dependsOn: build) {
    doLast {
        project.version = '1.0-release'
        compileJava {
            options.debug = false

        }
    }
}

task buildDebug(type: GradleBuild, dependsOn: build) {
    doLast {
        project.version = '1.0-debug'
        compileJava {
            options.debug = true
        }
    }
}

これはさらに悪いことです。出力ファイルは常に1.0リリースです。これは、トップレベルの「デフォルト」が原因です。コメントすると、バージョン管理されたjarは作成されず、代わりにデフォルトのTestGradleModule.jarが作成されます。 doLastブロックの内容は、compileJavaタスクへの影響ではまったく役に立たないようです(ただし、これについての警告はありませんか?)。これらの変更は実行時に実行するには遅すぎると思いますか、それともcompileJavaタスクを別の方法で「構成」するために実行する必要がある何かが他にあると思いますか?

構成を使用していますか?

Javaプラグイン のマニュアルにbuildConfigNameuploadConfigNameへの参照が含まれていることに気づき、それらは「タスクこれは、構成ConfigNameでアーティファクトを生成します。」。構成時にデータのパラメーター化に失敗していたことを考えると、プラグインがそれを実行する機能は有望に見えました。

group 'TestGradleProjectGroup'
apply plugin: 'Java'
sourceCompatibility = 1.8

configurations {
    debug
    release
}

version '1.0-release'
compileJava {
    options.debug = false
}

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

だが:

  1. 予想どおり、これは./gradlew tasks --allの出力にbuildReleaseまたはbuildDebugを追加しませんでした。しかし、私はそれらのタスクを実行することができました。
  2. buildReleasebuildDebugを作成するだけのようで、たとえばassembleReleaseなど
  3. buildReleaseは実行時に何にも依存していないようだったため、有用な効果はありませんでした。

タスクを繰り返す?

最後の試みとして、適切なタスクをすべて作成し、すべての依存関係をリンクしようとしました。タスクを繰り返して依存関係を追加してみました。

gradle.taskGraph.whenReady { taskGraph ->

    taskGraph.allTasks.each { taskIter ->

        println("iterating" + taskIter)

        def releaseTask = project.task(taskIter.name + "Release")
        def debugTask = project.task(taskIter.name + "Debug")

        taskIter.dependsOn += [releaseTask, debugTask].toSet()
        println("new taskIter.dependsOn:" + taskIter.dependsOn)

        /*
            set debug mode here,
            copy over effects of task to debug/release
            disable effects of task
        */
    }
}

だが

  1. これはタスクを適切に作成していないようで、コマンドラインからアクセスできず、「build」を実行しても「buildRelease」などは実行されませんでした。
  2. また、それぞれの効果が重複しないように、現在の既存のタスクからデバッグタスクとリリースタスクにすべての「アクション」を「移動」する必要があります。そして、私はそれを行う方法がわかりません。

要するに、私は自分が何をしているのか分かりません。最後の手段として、すべてのタスクを手動で作成することもできますが、それはJavaプラグインを使用するという点を無効にしているようで、非常にスパムですか?

9
Pod

何時間も検索した後...

「ビルドスクリプトの基本」Gradleチュートリアルの「DAGによる構成」セクションでは、これを行う方法について説明しています。

https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#configure-by-dag

チュートリアルからの引用

「Gradleには構成フェーズと実行フェーズがあります。構成フェーズの後、Gradleは実行する必要のあるすべてのタスクを認識します。Gradleはこの情報を利用するためのフックを提供します。このユースケースは、リリースかどうかを確認することです。タスクは実行されるタスクの1つです。これに応じて、いくつかの変数に異なる値を割り当てることができます。」

buildRelease()およびbuildDebug()タスクを使用してgradle.taskGraph.whenReady{}を適用する例を次に示します。

gradle.taskGraph.whenReady { taskGraph ->
    if (taskGraph.hasTask(buildRelease)) {
        compileJava.options.debug = false
        project.version = '1.0-release'
    } else if (taskGraph.hasTask(buildDebug)) {
        compileJava.options.debug = true
        project.version = '1.0-debug'
    }
}

task buildRelease(type: GradleBuild, dependsOn: build) {
}

task buildDebug(type: GradleBuild, dependsOn: build) {
}

IMO、Gradleは学ぶべき完全なクマです。私は確かに古き良きメイクを逃します。

5
beyeriii

1回のgradleで両方のjarを作成する必要がありますか?そうでない場合は、gradleに追加の引数を使用するのと同じくらい簡単です。

compileJava {
    options.debug = project.hasProperty('debugBuild')
}

gradle assemble -PdebugBuild

ドキュメントについては、こちらをご覧ください: https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_properties_and_system_properties

また、gradleフォーラムでより良いヘルプが得られるかもしれないというわけではありません。

4
tkruse

問題を詳細に分析したので、質問は詳細になります。もっと簡単に考えれば、この問題は解決できると思いますが。
したがって、単純だと思う場合、あなたのケースに対する可能な解決策は、リリースが完了した後にデバッグタスクを実行することです。以下の例を参照してください。

compileJava {
    options.debug = false
}

task buildRelease(type: GradleBuild, dependsOn: build) {
    doLast {
        project.version = '1.0-release'
        compileJava {
            options.debug = false

        }
    }
}

task buildDebug(type: GradleBuild, dependsOn: build) {
    doLast {
        project.version = '1.0-debug'
        compileJava {
            options.debug = true
        }
    }
}

// Here you are telling the buildDebug task to be executed right after the 
// buildRelease task is finalized.
buildDebug.mustRunAfter buildRelease

上記の方法では、タスクの間に明示的な依存関係を導入することなく、タスクの実行順序を制御します。

確かではありませんが、おそらく私の gradle-Java-flavours プラグインがここで役立つ可能性があります。例えば:

plugins {
    id "com.lazan.javaflavours" version "1.2"
}
javaFlavours {
    flavour 'debug'
    flavour 'release'
}
debugJar {
    version = "${project.version}-debug"
}
releaseJar {
    version = "${project.version}-release"
}

各フレーバーには、独自のJarおよびJavaCompileタスクなどがあり、各フレーバーのカスタムソース、リソース、テスト、依存関係も指定できます。

使用可能なタスク、ディレクトリ、および構成の概要については here を、機能をカバーするテストについては here を参照してください。

このアプローチは、GradleBuildスタイルとは異なります。これは、「フレーバー」が2つの異なるパラメーターでプロジェクトを2回実行するのではなく、複数のアーティファクトを構築する単一のプロジェクトで一緒に幸せに暮らせるためです。

1
lance-java