protobuf系列-gradle下的protobuf插件使用

配置pb编译

pb 插件默认认为 .proto文件跟 java文件组织结构相同,在sourceSets中,在一个sourceSet下的文件使用单独的protoc命令来编译,并将生成的java文件添加到java的sourceSet下作为java编译的输入。

自定义pb文件位置

插件会自动添加proto(跟java并列)下的源码块到对应的sourceSet下。protoc插件默认从src/$sourceSetName/proto读取并编译,你也可以想自定义java源码所在文件夹一样自定义pb文件所在的文件夹。

java项目配置如下:

sourceSets {
  main {
    proto {
      // In addition to the default 'src/main/proto'
      srcDir 'src/main/protobuf'
      srcDir 'src/main/protocolbuffers'
      // In addition to the default '**/*.proto' (use with caution).
      // Using an extension other than 'proto' is NOT recommended,
      // because when proto files are published along with class files, we can
      // only tell the type of a file from its extension.
      include '**/*.protodevel'
    }
    java {
      ...
    }
  }
  test {
    proto {
      // In addition to the default 'src/test/proto'
      srcDir 'src/test/protocolbuffers'
    }
  }
}

android项目配置如下:

android {
  sourceSets {
    main {
      proto {
        ...
      }
      java {
        ...
      }
    }
  }
}
自定义protoc编译器

所有跟 protoc 相关的配置均放在 protobuf 模块下

指定protoc编译器位置

在没有任何配置的场景下,插件默认会从path中寻找protoc编译器,但是我们推荐直接使用Maven Central上已经编译好的protoc编译器,配置如下:

protobuf {
  ...
  // Configure the protoc executable
  protoc {
    // Download from repositories
    artifact = 'com.google.protobuf:protoc:3.0.0'
  }
  ...
}

你也可以指定本地已经安装的protoc编译器,配置如下:

protobuf {
  ...
  protoc {
    path = '/usr/local/bin/protoc'
  }
  ...
}

protoc 模块下,可以指定多个配置,但是会以最后一个配置为准。

指定protoc运行插件

protoc在指定plugin名称为foo 时,会默认从path中寻找protoc-gen-foo来编译。在gradle插件中我们可以跟指定编译器一样在plugins模块下配置artifact或者path

protobuf {
  ...
  // Locate the codegen plugins
  plugins {
    // Locate a plugin with name 'grpc'. This step is optional.
    // If you don't locate it, protoc will try to use "protoc-gen-grpc" from
    // system search path.
    grpc {
      artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0-pre2'
      // or
      // path = 'tools/protoc-gen-grpc-java'
    }
    // Any other plugins
    ...
  }
  ...
}

注意: 此处仅仅只是声明,在此处配置了在protoc运行时并不会应用插件,如果要想真正的使用,我门需要在generateProtoTasks模块下使用此处配置的插件。

自定义代码生成任务

插件会为每一个执行的protoc(执行个数根据sourceSet确定)生成一个任务,每个任务都有 配置输出类型、插件以及protoc参数的接口。所有的配置都放在generateProtoTasks模块下。

protobuf {
  ...
  generateProtoTasks {
    // all() returns the collection of all protoc tasks
    all().each { task ->
      // Here you can configure the task
    }

    // In addition to all(), you may select tasks by various criteria:

    // (Java-only) returns tasks for a sourceSet
    ofSourceSet('main')

    // (Android-only selectors)
    // Returns tasks for a flavor
    ofFlavor('demo')
    // Returns tasks for a buildType
    ofBuildType('release')
    // Returns tasks for a variant
    ofVariant('demoRelease')
    // Returns non-androidTest tasks
    ofNonTest()
    // Return androidTest tasks
    ofTest()
  }
}

注意:

  1. 不要使用task的名称,因为task名称不是固定的,很有可能会发生改变

  2. 不要在generateProtoTasks 外部配置任务,因为配置的任务是有时序性的

每个task下有两个集合:

builtins protoc编译配置,如果配置生成java、cpp、python等语言

plugins protoc编译插件配置,如配置grpc插件等。 此处配置的插件必须在 protobuf.plugins 中预先定义

配置生成指定语言的代码

protoc会根据builtinsplugins中的配置来生成代码。每个builtin/plugin会生成一种确定格式的代码。添加或者配置只需要列出名称并且后面跟上大括号即可,把配置选项填入大括号内即可。示例:

task.builtins {
  // This yields
  // "--java_out=example_option1=true,example_option2:/path/to/output"
  // on the protoc commandline, which is equivalent to
  // "--java_out=/path/to/output --java_opt=example_option1=true,example_option2"
  // with the latest version of protoc.
  java {
    option 'example_option1=true'
    option 'example_option2'
  }
  // Add cpp output without any option.
  // DO NOT omit the braces if you want this builtin to be added.
  // This yields
  // "--cpp_out=/path/to/output" on the protoc commandline.
  cpp { }
}

task.plugins {
  // Add grpc output without any option.  grpc must have been defined in the
  // protobuf.plugins block.
  // This yields
  // "--grpc_out=/path/to/output" on the protoc commandline.
  grpc { }
}
编辑器默认配置

Java 项目

插件默认在builtin中指定生成java语言,当使用默认配置时,编译器会自动生成java类

Python项目

在builtin中配置python即可,示例代码:

protobuf {
  generatedFilesDir = "$projectDir/generated"

  generateProtoTasks {
    all().each { task ->
      task.builtins {
        // Generates Python code in the output folder:
        python { }

        // If you wish to avoid generating Java files:
        remove java
      }
    }
  }
}

Android项目

插件中没有添加默认生成配置,推荐配置java lite库。

在Protobuf 3.0.x-3.7.x版本上,lite代码生成是通过protoc插件方式提供,示例:

dependencies {
  // You need to depend on the lite runtime library, not protobuf-java
  compile 'com.google.protobuf:protobuf-lite:3.0.0'
}

protobuf {
  protoc {
    // You still need protoc like in the non-Android case
    artifact = 'com.google.protobuf:protoc:3.7.0'
  }
  plugins {
    javalite {
      // The codegen for lite comes as a separate artifact
      artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
    }
  }
  generateProtoTasks {
    all().each { task ->
      task.builtins {
        // In most cases you don't need the full Java output
        // if you use the lite output.
        remove java
      }
      task.plugins {
        javalite { }
      }
    }
  }
}

从Protobuf 3.8.0版本之后,lite代码生成器可以直接通过 java 输出选项配置,示例:

dependencies {
  // You need to depend on the lite runtime library, not protobuf-java
  compile 'com.google.protobuf:protobuf-javalite:3.8.0'
}

protobuf {
  protoc {
    artifact = 'com.google.protobuf:protoc:3.8.0'
  }
  generateProtoTasks {
    all().each { task ->
      task.builtins {
        java {
          option "lite"
        }
      }
    }
  }
}
更改编译代码输出位置

默认生成的java代码输出位置为 $generatedFilesBaseDir/$sourceSet/$builtinPluginName ,其中:

$generatedFilesBaseDir = $buildDir/generated/source/proto ,更改输出配置如下:

protobuf {
  ...
  generatedFilesBaseDir = "$projectDir/src/generated"
}

子目录 $builtinPluginName 可以在builtins或者 plugins模块下配置 outputSubDir属性来修改,示例:

  task.plugins {
    grpc {
      // Write the generated files under
      // "$generatedFilesBaseDir/$sourceSet/grpcjava"
      outputSubDir = 'grpcjava'
    }
  }
}

Protos依赖

如果java项目中包含proto文件,他们将跟编译的类一起打包到jar包中。可以通过compile或者protobuf来配置protos依赖。

如果通过compile配置,proto文件将会被提取到extracted-include-protos 目录下,并将此目录添加到protoc命令行运行编译时 --proto_path 参数下,这样就可以把依赖的文件导入到当前工程下。因为导入的proto文件已经在他们原来的工程中编译了,所以当前工程编译时不会编译依赖的proto文件。示例:

dependencies {
  compile project(':someProjectWithProtos')
  testCompile files("lib/some-testlib-with-protos.jar")
}

如果通过protobuf配置,proto文件会被提取到 extracted-protos 目录下,并被添加到protoc编译文件范围之内,跟编译当前工程的proto文件相同的处理,也就是说此处配置的proto文件依赖会被编译。示例:

dependencies {
  // protos can be from a local package,
  protobuf files('lib/protos.tar.gz')
  // ... a local directory,
  protobuf files('ext/')   // NEVER use fileTree(). See issue #248.
  // ... or an artifact from a repository
  testProtobuf 'com.example:published-protos:1.0.0'
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值