Включить зависимость для настраиваемого набора источников - PullRequest
1 голос
/ 19 июня 2020

У меня есть build.gradle.kts для небольшого чистого проекта kotlin (я знаю, что использую несколько нестандартные исходные пути):

plugins {
    kotlin("jvm") version "1.3.72"
}

repositories { mavenCentral() }

dependencies {
    implementation(kotlin("stdlib-jdk8"))
    testImplementation("org.jetbrains.kotlin:kotlin-test")
    testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
}

sourceSets["main"].java.srcDir("src")
sourceSets["test"].java.srcDirs("test")
sourceSets {
    create("demo")?.let {
        it.java.srcDir("demo")
        // Also tried:  it.java.srcDirs("src", "demo")
        it.compileClasspath += main.get().output
        it.runtimeClasspath += main.get().output
    }
}

tasks {
    compileKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
    compileTestKotlin {
        kotlinOptions.jvmTarget = "1.8"
    }
}

listOf("InteractiveClient", "LockingBufferDemo").forEach {
    tasks.register<Jar>(it) {
        manifest { attributes["Main-Class"] = "${it}Kt" }
        from(sourceSets.main.get().output)
        from(sourceSets["demo"].output) {
            include("**/${it}Kt.class")
        }
        dependsOn(configurations.runtimeClasspath)
        from({
            configurations.runtimeClasspath.get().filter {
                it.name.endsWith("jar") }.map { zipTree(it) }
        })
    }

}

Когда я пытаюсь запустить один из "демонстрационные" задачи jar на основе sourceSet ("InteractiveClient" и "LockingBufferDemo"), 1 Я получаю длинный список ошибок «Невозможно получить доступ к встроенному ...», указывающий, что kotlin stdlib не является

Фактическая неудачная задача - compileDemoKotlin, поэтому я попытался миметически добавить в блок tasks:

withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    this.kotlinOptions.jvmTarget = "1.8"
}

Что не имеет значения.

Что для меня странно, так это то, что демонстрационный материал изначально был в test sourceSet, и изменив приведенное выше обратно на это (удалив определение, изменив from(sourceSets["demo"]... на from(sourceSets.test... в задачах jar и переместив исходный файл) устраняет проблему. Это работает.

Я не хочу, чтобы это было в автоматических тестах. Думаю, я мог бы поместить их в ветки набора main или test, а затем использовать шаблон from() { exclude(... при создании банок, но это кажется неудобным и ненужным.

Как мне сделать получить настраиваемый исходный код для компиляции с учетом зависимостей проекта по умолчанию?

  1. См. этот другой мой недавний вопрос о from(... include( в задачах jar.

Ответы [ 2 ]

1 голос
/ 23 июня 2020

Мне кажется, что вам не хватает конфигураций, которые заставят демонстрационные исходные наборы использовать те же зависимости, что и основной набор. Примерно так:

configurations["demoImplementation"].extendsFrom(configurations.implementation.get())
configurations["demoRuntimeOnly"].extendsFrom(configurations.runtimeOnly.get())

В руководстве пользователя есть пример здесь , который, похоже, имеет очень похожий вариант использования, что и ваш.

Кроме того, из проблема , которую вы создали в репозитории Gradle, вы упомянули, что она не удалась:

Неразрешенная ссылка: printlin

Я почти уверен, что это опечатка из println.

1 голос
/ 20 июня 2020

Я не совсем уверен, что вы пытаетесь сделать со своими файлами jar, но я обнаружил несколько проблем в вашем сценарии сборки:

  • Вы установили свои исходные наборы вот так:

    sourceSets["main"].java.srcDir("src")
    sourceSets["test"].java.srcDirs("src", "test")
    sourceSets {
        create("demo")?.let {
            it.java.srcDir("demo")
        }
    }
    

    Это означает, что у вас должна быть следующая структура каталогов:

    - <module root>
      - src     <-- Belongs to both 'main' and a 'test' source sets!
      - test    <-- Belongs to the 'test' source set
      - demo    <-- Belongs to the 'demo' source set
    

    Как видите, есть каталог, который принадлежит двум исходным наборам. Не знаю, как это получается на практике, наверное, одно или другое отброшено. Вот более стандартная структура каталогов:

    - <module root>
      - src
        - main
        - test
        - demo
    

    Вы настраиваете это так:

    sourceSets {
        main {
            java.srcDir("src/main")
        }
        test {
            java.srcDir("src/test")
        }
        create("demo") {
            java.srcDir("src/demo")
        }
    }
    
  • Задача compileDemoKotlin действительно существует, но вы не можете получить доступ к нему просто так. Если вы посмотрите на исходный код функций расширения compileKotlin и compileTestKotlin, они будут выглядеть так:

    val TaskContainer.`compileKotlin`: TaskProvider<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>
        get() = named<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileKotlin")
    

    Таким образом, хитрость заключается в использовании named для получения задачи вместо:

    named<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>("compileDemoKotlin") {
        kotlinOptions.jvmTarget = "1.8"
    }
    

Не знаю, отвечает ли это на ваш вопрос. Если я что-то пропустил, дайте мне знать.

...