资讯详情

grpc gradle_Gradle,Bazel和gRPC:《冰与火之歌》

grpc gradle

对不起。 没有权力游戏的笑话。 诺言。

所以,你在用Bazel 。 可能是因为你以前有过monorepo。 或者,也许你只是认为你的Android项目中模块太多。 或者仅仅因为很难管理你GitHub上整齐分离的存储库中拥有的所有那些微服务。 没关系 现在,你坚持用Bazel。

当您切换到Bazel丢失的一件事是丰富的插件生态系统,它提供了Maven和Gradle等工具。

此外,Gradle还允许您在Kotlin中编写DSL甚至定制任务。 这些善良永远消失了吗? 也许不会。

让我们看看如何使用一个Gradle插件(本例为KrotoPlus)并使其与Bazel一起使用。

在开始之前,让我们大致介绍一下KrotoPlus插件和gRPC 。

所有gRPC库都将.proto以您选择的语言输出文件为输入:

  • 留言内容
  • 客户群
  • 服务器接口

为便于讨论, 消息只是你的纯数据对象。 它们会有一些字段,这些字段会有类型。 这就是你现在需要知道的一切。

客户端 (也称存根)用于调用gRPC服务对象。 要创建客户端,通常需要指定gRPC服务器的主机和端口,然后调用一种方法择消息传递给这种方法。

服务器实现生成的服务器接口 ,然后开始调查正确的主机和端口,为客户提供服务。

如下:

gRPC Library:( proto files ) => (generated classes)

Gradle喜欢使用定义明确的项目结构,即:

your-gradle-project   src     main       proto

当您运行Gradle当插件简单工作时,这是因为Gradle足够聪明,可以识别您的源集并将插件应用到它们中。

所以,如果你的话proto有一些目录.proto文件,我们的Gradle在build在目录中生成一些Java和Kotlin文件:

your-gradle-project   build <-- your generated files will appear there   src     main       proto

另一方面,Bazel对这种干净的结构一无所知。

此外,您的proto文件将位于your-gradle-project除目录外,如下所示:

some-proto-project    proto <-- some proto files ... your-gradle-project   src     main       proto <-- empty ... other-proto-project   api     proto <-- more proto files

我们想做的是使用它Bazel下的Gradle作为一个函数,该函数将被获得.proto文件的路径就像它们是它们Source Set部分相同,然后根据这些文件生成类。

有几种方法可以实现Gradle但这就是其中之一:

import com.google.protobuf.gradle.* ... protobuf {     ...     generatedFilesBaseDir = " $buildDir /generated-sources"     ...     dependencies {         protobuf(files(project.properties[ "protoDir" ].toString()))     }     generateProtoTasks {         ...     } }

重要部分是dependencies块。 在这里,我们没有像往常一样硬编码依赖项,而是从命令行获取它们:

project.properties["protoDir" ].toString()

这意味着当我们运行Gradle包装时,我们现在将相对路径传输到.proto文件:

./gradlew generateProto -PprotoDir=../path/to/protos

我们的Gradle现在就可以出发了。 接下来,让我们开始使用它Bazel。

想要使用Bazel入侵时,你的主要工具之一是gerule 。

这是表达您想在Bash shell中运行某些东西的基本方法。

但是那是什么“东西”? 它应该是gradlew ,与我们之前使用的包装相同。 但是问题是,Bazel并没有意识到这一点。

因此,让我们在gradlew所在的目录中创建一个名为BUILD的文件,并添加以下代码块:

filegroup(
    name ="gradle" ,
    srcs = [ "gradlew" ],
)

这样我们告诉Bazel:嘿,这是您应该知道的新文件。

但是,如果您尝试以这种方式运行它,Gradle会抱怨它找不到其配置。

那是因为我们只告诉Bazel将gradlew复制到它的沙箱,而不是其他任何东西。

让我们通过添加另一个保存配置的filegroup来解决此问题:

filegroup(
    name ="gradle_config" ,
    srcs = [ "build.gradle.kts" , "krotoPlusConfig.asciipb" , "settings.gradle" ]
            + glob([ "gradle/**/*" ])
            + glob([ "scripts/**/*" ]),
    visibility = [ "//visibility:public" ]
)

如您所见,我们获取了build.gradle.kts以及build.gradle.kts配置文件以及Gradle包装器本身(位于/gradle目录下)。

现在,到规则本身。 起初,它看起来令人生畏,但我们将逐行将其分解。

genrule(
    name ="run_gradle" ,
    cmd = """
    ./$(location gradlew) -p $$(dirname ./$(location gradlew)) generateProto -PprotoDir=../proto/ &&
    cp -R $$(dirname ./$(location gradlew))/build/generated-sources  $(@D)
    """ ,
    outs = [ "build/generated-sources" ],
    message = "Generating protos" ,
    srcs = [],
    tools = [ ":gradle" ] + [ ":gradle_config" ],
)
  • name是在指定库的依赖项时要引用的标签
  • cmd是将在Shell中运行的命令。 我们待会再分解
  • outs是此命令产生的。 Bazel尝试跟踪脚本的每个输出,因此您需要在执行cmd之后告诉它您希望在文件系统中更改的内容。 如果目录build / generated-sources保持不变,Bazel将抱怨。
  • message是您等待时将显示的内容
  • srcs是您要在其上运行脚本的输入文件。 理想情况下,这些文件将是您的.proto文件。 但是在这种情况下,我们将其保留为空,因为我们使用-PprotoDir
  • tools是生成输出所需使用的文件列表。 在我们的例子中,它是Gradle Wrapper和所有配置。

现在,让我们回到cmd并了解内部发生了什么。

启动Bazel时,其根目录位于WORKSPACE文件位置,而不是gradlew所在的目录。 因此,我们使用$(location gradlew)将标签扩展到其相对位置。 在我们的示例中,它将类似于./your-gradle-project

找到Gradle Wrapper可执行文件后,我们需要告诉它在哪里可以找到其配置。 我们使用-p ,这是标准的Gradle标志。 我们知道该目录还是相对于我们的WORKSPACE ,因此是./$(location gradlew) 。 但是这次,它必须是目录,并且位置将扩展为文件的路径,因此我们使用$(dirname) 。 但是Bazel已经将$用作$(location) 。 因此,我们最终筛选了以下命令: $$(dirname)

找到配置后,我们需要告诉Gradle要运行哪个任务。 那是generateProto

现在,我们需要将Gradle指向.proto文件的位置。 但是上下文在这里从Bazel切换到Gradle,因此路径现在相对于gradlew位置: -PprotoDir=../proto/

现在Gradle和KrotoPlus努力工作来生成我们的gRPC类。 问题是,它们是在Gradle目录中生成的,而不是在Bazel沙箱中生成的。

因此,我们需要复制它们。 cp -R是一个标准的shell命令,我们已经介绍了$$dirname()含义。 您还不熟悉的唯一部分是$(@D)

那就是我们用outs指定的输出目录,因此,将生成的文件复制到我们想要的位置。

结论和下一步

如果比较麻烦,可以将Bazel和Gradle组合以生成文件。

如果您想走这条路,那么下一步应该是:

  • 记得自己清理一下。 rm -rf $$gradleDir/build会很好
  • 您可能想利用这种genrule的功能。 语法几乎保持不变,但是在函数内部时,您需要在genrule加上nativenative.genrule
  • 从长远来看,像使用-PprotoDir一样使用相对路径不是正确的选择。 尽管对于测试KrotoPlus插件很有用。 更好的选择是依靠标签。

希望,如果您已经在使用Bazel,那么本文将使您走上正确的道路。

翻译自: https://hackernoon.com/gradle-bazel-and-grpc-a-song-of-ice-and-fire-n04w330hh

grpc gradle

标签: 5w330r碳膜电阻5w330kr碳膜电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台