巴克 - 构建具有多种Gradle风格/构建类型和清单的Android应用程序

时间:2014-10-13 11:37:49

标签: android build gradle android-manifest

我正在开发一个项目,我们有几个模块,每个模块都有许多依赖于其他模块的模块,依此类推。我们之前将项目迁移到Gradle(并且还改变了结构以适应Gradle的默认值),因为我们在构建应用程序的不同版本时需要多功能性:免费与付费,调试(无程序)与发布(proguard)等当我们完成迁移时,我们感到非常激动,但是当构建时间开始成为一种痛苦时,这种快乐很快就会在泥浆中被稀释。对代码进行相当简单的更改并在手机上部署应用程序需要90-120秒,这简直是不可接受的。

所以我们决定尝试一下巴克,因为除了其他开发者的好话之外,我们什么都没听到。经过很短的时间(比使用Gradle的方式少)我们成功地构建了我们的应用程序(不幸的是,这并不意味着“正确生成APK”,但至少它已构建)。问题是,作为一般规则,我们每种口味都有一个清单文件,除非我忽略了一些基本的东西,否则Buck只允许您在使用规则android_binary时指定清单文件。结果是生成的APK的清单文件只包含Gradle的构建链从其开始的第一级模块的样板代码:

main -> debug -> free/paid -> common

也就是说,清单文件只包含main的清单。此规则位于顶级BUCK文件中,该文件包含.buckconfig中指定的别名。

我很确定我做错了什么。没有任何意义,巴克不允许你没有多个清单。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

弗朗西斯·托特(https://stackoverflow.com/users/1873643/francis-toth)在巴克讨论小组中提出了一个非常全面的解释:

  

为了给你上下文,我有一个由不同库模块组成的应用程序,每个模块都有一个Android-Manifest,一些资源,资产等......以及一个看起来像这样的BUCK文件:

android_library(
  name = 'src',
  srcs = glob(['src/main/java/**/*.java']),
  deps = DEPENDENCIES + [':res'],
  visibility = [ 'PUBLIC' ],
  exported_deps = DEPENDENCIES
)

android_resource(
  name = 'manifest',
  manifest = 'src/main/AndroidManifest.xml',
  deps = ['//othermodule:manifest'],
  visibility = [ 'PUBLIC' ],
)

android_resource(
  name = 'assets',
  assets = 'src/main/assets',
  visibility = [ 'PUBLIC' ],
)

android_resource(
  name = 'res',
  res = 'src/main/res',
  package = 'com.sherpa.android',
  visibility = [ 'PUBLIC' ],
)

project_config(
  src_target = ':src',
  src_roots = ['src/main/java']
)
  

我的应用程序BUCK文件如下所示:

android_binary (
  name = 'bin',
  manifest = ':manifest', # Here I make a reference on the android_manifest build rule described below
  target = 'Google Inc.:Google APIs:19',
  keystore = ':debug_keystore',
  deps = BINARY_DEPENDENCIES
)

MANIFEST_DEPENDENCIES = ['//module1:manifest', '//module2:manifest']
android_manifest (
  name = 'manifest',
  skeleton = 'AndroidManifest.xml', # The app's base manifest
  deps = MANIFEST_DEPENDENCIES # App's manifest will be merged with all its dependencies (module1 and module2's manifest)
)
  

据我所知,你的问题似乎很相似。为了合并清单,你必须创建一个android_resource构建规则,它告诉你的模块库在哪里以及必须与它合并的清单。

这解决了我的问题: - )

答案 1 :(得分:0)

在清单中,清单合并将永远不会覆盖清单标记中的任何内容。这包括package属性,debuggable属性等。

android_binary中有一个manifest_entries的功能没有记录,但它是OKBuck构建风格的方式。在打包清单之前,manifest_entries中的任何占位符都将替换AndroidManifest.xml中的任何表达式

因此,如果您的清单标记看起来像这样:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package = "com.whatever${flavor}"
   android:debuggable = "${debuggable}"
>

你android_binary中的manifest_entries看起来像这样:

  manifest_entries = {
    'placeholders': {
      'flavor': '.test',
      'debuggable': 'true',
    },
  },

生成的清单将如下所示:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package = "com.whatever.test"
   android:debuggable = "true"
>

然后你可以使用字典操作和flatten_dicts()来构建manifest_entries占位符