rules_kotlin icon indicating copy to clipboard operation
rules_kotlin copied to clipboard

Cannot use compiler plugins on Android

Open refi64 opened this issue 4 years ago • 6 comments

I have the following in my BUILD file:

kt_compiler_plugin(
    name = "serialization_plugin",
    deps = [
        "@com_github_jetbrains_kotlin//:kotlinx-serialization-compiler-plugin",
    ],
)

# ...

kt_android_library(
    name = "%s_lib" % mode, 
    plugins = [":serialization_plugin"],
    # ...
)

When built, this results in:

in deps attribute of android_binary rule //app:cloverplay_paid: Dependencies on .jar artifacts are not allowed in Android binaries, please use a java_import to depend on external/com_github_jetbrains_kotlin/lib/kotlinx-serialization-compiler-plugin.jar. If this is an implicit dependency then the rule that introduces it will need to be fixed to account for it correctly.. Since this rule was created by the macro 'android_binary', the error might have been caused by the macro implementation

If I use java_import to import the JAR file, then I get:

in jars attribute of java_import rule //app:serialization_plugin_jar: should not refer to Java rules

At a glance I can tell this commit is related, but beyond that I'm not sure what's going on. I guess the plugin's jar file is ending up in the deps, but somehow differently than kt_jvm_import normally does?

refi64 avatar Apr 22 '20 00:04 refi64

You need to use a kt_jvm_import against the raw jar, and then depend on the import target in the kt_compiler_plugin() statement.

cgruber avatar Jun 03 '20 18:06 cgruber

The "use a java_import" is a default bazel message, which doesn't account for kotlin, sadly. Try using kt_jvm_import.

cgruber avatar Jun 03 '20 18:06 cgruber

Sorry for the super delayed reply, but the :kotlinx-serialization-compiler-plugin target is already using kt_jvm_import, so I'm not sure how this is actually supposed to work out then?

refi64 avatar Aug 21 '20 19:08 refi64

I'm experiencing the same issue trying to add Anvil to our project. I've tried both referencing the anvil-compiler jar directly, and referencing as a maven dependency. In this case I think we'll need to ultimately reference as a maven dependency, since Anvil has several dependencies of its own.

In my closest attempt, I have the anvil_compiler_plugin rule building, but the plugin doesn't run.

kt_jvm_import(
    name = "anvil_compiler",
    jar = "kotlin/kotlinc/lib/anvil-compiler-2.0.0.jar",
    neverlink = True
)

kt_compiler_plugin(
    name = "anvil_compiler_plugin",
    id = "com.squareup.anvil.compiler",
    options = {
    },
    deps = [
        ":anvil_compiler",
    ],
    visibility = ["//visibility:public"],
)

kt_android_library(
    name = "bindings",
    srcs = glob([
        ...
    ]),
    plugins = [
        '//libs:anvil_compiler_plugin'
    ],

bjdodson avatar Aug 26 '20 16:08 bjdodson

Still the same issue on 1.4.0-legacy-RC4. Doesn't work even on predefined plugins like allopen:

kt_compiler_plugin(
    name = "open_for_testing_plugin",
    id = "org.jetbrains.kotlin.allopen",
    options = {
        "annotation": "com.example.OpenForTesting", # my custom annotation here
    },
    deps = [
        "@com_github_jetbrains_kotlin//:allopen-compiler-plugin",
    ],
)

kt_android_library(
    name = "custom_library"
    [...]
    plugins = [
        ":open_for_testing_plugin",
    ],
    [...]
)

android_binary(
     [...]
     deps = [
          ":custom_library",
          [...]
     ],
)

Dependencies on .jar artifacts are not allowed in Android binaries, please use a java_import to depend on external/com_github_jetbrains_kotlin/lib/allopen-compiler-plugin.jar. . Sounds really like a jar from the plugin is only intended to work on host jvm (e.g. kt_jvm_binary or android_local_test), but not on android binaries. Is there a way to set a plugin binary dependency to not be included as a library dependency on which a plugin is run? Like maybe runtime_deps etc?

Nikolas-LFDesigns avatar Nov 24 '20 22:11 Nikolas-LFDesigns