Buck - Build Android Application with Multiple Gradle Types and Appearances

I am working on a project where we have multiple modules, each with multiple dependencies on other modules, etc. etc. We moved our project to Gradle (and also changed the structure to accommodate the default Gradle) a while ago because we needed flexibility when building different versions of the application: free vs paid, debug (no proguard) vs release (proguard), and etc. We were really thrilled when we completed the migration, but that happiness quickly dissipated into a puddle of mud when the build time hurt. It takes 90-120 seconds to make fairly simple changes to the code and deploy the app to the phone, and that's just not acceptable.

So we decided to give Buck a try, as we hadn't heard anything other than good words from other developers. After very little time (less than with Gradle), we were able to successfully build our application (which unfortunately does not mean โ€œbuilding the APK correctlyโ€, but at least it is built). The thing is, usually, we have one manifest file per flavor, and if I'm not missing something fundamental, Buck allows us to specify manifest files when using a rule android_binary

. The upshot of this is that the generated APK manifest file only contains the first level module template code from which the Gradle build chain starts:

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


That is, the manifest file only contains the main manifest. This rule is found in the top-level BUCK file, which is the alias specified in the .buckconfig.

I'm pretty sure I am doing something wrong. This makes no sense. Buck does not allow you to have multiple manifestations.

Any ideas?


source to share

1 answer

Francis Toth ( https://stackoverflow.com/users/1873643/francis-toth ) came up with a very detailed explanation on the Buck discussion group:

Just to give you context, I have an app made up of different library modules, each with an Android manifest, some resources, assets, etc ... and a BUCK file that looks something like this:

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

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

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

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

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


My BUCK app file looks like this:

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',

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


Your problem, as I understand it, seems to be quite similar. To merge the manifest, you need to create an android_resource build rule that specifies where your module library is located, as well as the manifest with which it should be merged.

And that solved my problem :-)



All Articles