Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing output directives error when executing Android build.gradle.kts #491

Closed
pueffl opened this issue Apr 23, 2021 · 4 comments
Closed

Comments

@pueffl
Copy link

pueffl commented Apr 23, 2021

I' trying to setup protobuf for Android, but I get "> protoc: stdout: . stderr: Missing output directives." I think that is just a configuration issue, but the message is not very helpful and I'm stuck at the moment. The gradle code looks as follows:

import com.eight.build.*
import com.google.protobuf.gradle.*

plugins {
    `android-base-lib`
}

apply(plugin = "com.google.protobuf")

dependencies {
...
    implementation("com.google.protobuf:protobuf-lite:3.0.0")
...
}

protobuf {
    generatedFilesBaseDir = "$projectDir/src/generated"
    protoc {
        artifact = "com.google.protobuf:protoc:3.15.8"
    }
    plugins {
        id("javalite") {
            artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
        }
    }
    generateProtoTasks {
        ofSourceSet("main").forEach {
            it.plugins {
                id("java") {
                    option("lite")
                }
            }
        }
    }
}

@voidzcy
Copy link
Collaborator

voidzcy commented Apr 23, 2021

If you are using protobuf version before 3.8, protoc-gen-javalite is provided as a protoc plugin. So you need to configure the "javalite" plugin for GenerateProtoTask:

protobuf {
    ...

    protoc {
        artifact = "com.google.protobuf:protoc:3.0.0"
    }
    plugins {
        id("javalite") {
            artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
        }
    }
    generateProtoTasks {
        ofSourceSet("main").forEach {
            task.builtins {
               remove java  // you probably do not need full java
            }
            it.plugins {
                id("javalite") { }
            }
        }
    }
}

If you are using protobuf 3.8+ (as 3.15.8 is used in your buildscript), the lite runtime is built into protoc's Java codegen. So you need to configure the "java" builtin for GenerateProtoTask:

protobuf {
    ...

    protoc {
        artifact = "com.google.protobuf:protoc:3.15.8"
    }
    generateProtoTasks {
        ofSourceSet("main").forEach {
            it.builtins {
                id("java") {
                  option("lite")
                }
            }
        }
    }
}

You can see details in Default outputs section of README for Android projects.

@pueffl
Copy link
Author

pueffl commented Apr 24, 2021

You where right that there was a mixup with some artefacts, but unfortunately, correcting that doesn't change a thing:

apply(plugin = "com.google.protobuf")

dependencies {
    implementation("com.google.protobuf:protobuf-javalite:3.15.8")
}

protobuf {

    protoc {
        artifact = "com.google.protobuf:protoc:3.15.8"
    }
    generateProtoTasks {
        ofSourceSet("main").forEach {
            it.builtins {
                id("java") {
                    option("lite")
                }
            }
        }
    }
}

Same error:
Execution failed for task ':preferences_app:generateDebugProto'.

protoc: stdout: . stderr: Missing output directives.

@voidzcy
Copy link
Collaborator

voidzcy commented Apr 25, 2021

I forgot to mention the difference for Android builds...

In Android projects the minimum compilation unit is variant (compared to sourceSet in normal Java projects), so proto generation tasks are associated with each variant.

protobuf {
    ...

    generateProtoTasks {
        // You probably just want to configure for all variants. Although we provide 
        // `ofFlavor()`/`ofBuildType()`/`ofVariant()`/`ofNonTest()`/etc API, in most
        // cases users do not have customized per buildType/flavor configurations (it
        // tends to be very use-case specific).
        all().forEach {
            it.builtins {
                id("java") {
                    option("lite")
                }
            }
        }
    }
}

@voidzcy voidzcy closed this as completed May 5, 2021
@guness
Copy link

guness commented Oct 7, 2021

For Android developers who uses full version of protobuf, but not lite, this is the solution that works for me:

generateProtoTasks {
    all().forEach { task ->
        task.builtins {
            id("java") {
                java { }
            }
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants