How to handle multiple manifests for multiple flavors/build variants?

1,523 views
Skip to first unread message

Eduardo López

unread,
Oct 15, 2014, 12:01:59 PM10/15/14
to buck-...@googlegroups.com
Hi,

We are currently using Gradle in our project, but we need to speed up things, so we are thinking about switching to Buck. We have tried to set it up, but for some reason we cannot get the manifests to merge correctly. We have multiple flavors (free, paid) and build types (debug, release). We have one manifest file per flavor/build type, as some flavors have certain functionality we don't want to have under certain scenarios (no ads in the paid, no maps in free, etc).

Our approach is to use Buck just for speeding up developing time, which means we don't have to deal with build debug vs release issues, but flavors are still important. It seems one can only specify a manifest file when using the "android_binary" rule, but (please, correct me if I am wrong) this is only used for generating the final .apk file. The issue we are facing is that the manifest included in the final .apk file is missing all the other flavors' manifests used in the build (that is, they don't get merged), despite the dependencies between different modules are correctly established.

As an example, our app has a "shared" module, which has the core functions of the app (this module is used by all flavors). Then we have an "app" module, which contains different flavors (free, paid) and as many manifests as flavors. If we now wanted to build the free app (in Gradle this would result into merging main -top level boilerplate-, debug -debug stuff-, free, and core manifests, in that precise order), the manifest in the generated .apk would only have the contents of free's manifest, ignoring shared's manifest, though shared has been correctly added as a dependency.

What are we missing? How can we get Buck to merge all manifests correctly?

Thanks in advance.

Francis Toth

unread,
Oct 15, 2014, 3:49:49 PM10/15/14
to buck-...@googlegroups.com
Hi !

I've faced recently the same problem. Here is how I've resolved it. Just to give you the context, I have an application composed of different library modules, each having an Android-Manifest, some resources, assets etc... and a BUCK file which pretty much look like this :

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']
)

My app BUCK 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',
  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)
)


Your problem, as far as I understand seems to be pretty similar. In order to merge the manifest, you have to create a android_resource build rule which tells where is your module library along with the manifests it has to be merged with. Is this answering your question ?

++

Francis.

Eduardo López

unread,
Oct 15, 2014, 4:30:05 PM10/15/14
to buck-...@googlegroups.com
Yes, it does answer my question. Thanks a lot for the comprehensive explanation!
Reply all
Reply to author
Forward
0 new messages