3

I am interested in trying to compile an android application from the command line using aapt2. I am having a problem linking the constraint-layout library when I try to perform the aapt2 link command. This program builds successfully from Android studio/gradle. How can I make gradle command line invocation show me the aapt2 command it is running?

For the record, I have tried to run ./gradlew assembleDebug --debug and all I can see is the calls to the aapt2-proto library.

Derek
  • 11,715
  • 32
  • 127
  • 228

1 Answers1

6

Link

The command will be a bit complicated and will depend on many things (like your resources, the project's dependencies, flags used etc), so the easiest way to get the full command is to actually "break" a resource.
Edit your res/values/strings.xml file to contain:

<string name="incorrect">@string/idontexist</string>

Go to the project's directory and run "gradlew clean assembleDebug". AAPT2 will fail during linking and Android Gradle Plugin will print out the full command used.
I'm using version 3.2.0-alpha13 and it gives me the command in full:

error: failed linking references.
Command: <path>/.gradle/caches/transforms-1/files-1.1/aapt2-3.2.0-alpha13-4662957-linux.jar/cbe84ab07c48b199e5fe8d202dd5845e/aapt2-3.2.0-alpha13-4662957-linux/aapt2 link -I\
      <path>/Android/Sdk/platforms/android-27/android.jar\
      --manifest\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/merged_manifests/debug/processDebugManifest/merged/AndroidManifest.xml\
      -o\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/processed_res/debug/processDebugResources/out/resources-debug.ap_\
      -R\
      @<path>/AndroidStudioProjects/Library/app/build/intermediates/incremental/processDebugResources/resources-list-for-resources-debug.ap_.txt\
      --auto-add-overlay\
      --java\
      <path>/AndroidStudioProjects/Library/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r\
      --proguard-main-dex\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/legacy_multidex_aapt_derived_proguard_rules/debug/processDebugResources/manifest_keep.txt\
      --custom-package\
      com.example.foo.bar\
      -0\
      apk\
      --output-text-symbols\
      <path>/AndroidStudioProjects/Library/app/build/intermediates/symbols/debug/R.txt\
      --no-version-vectors
Daemon:  AAPT2 aapt2-3.2.0-alpha13-4662957-linux Daemon #0

The flags used here for AAPT2:

  • -I: path to the platform's android.jar
  • --manifest: the manifest file (AGP uses the merged manifest, not simply the one in your sources)
  • -o: output file
  • -R: resources. Normally you'd pass one by one, but since there are many here, they're written to a file and then that file is passed to AAPT2 (that's why there's the "@" symbol before the path)
  • --auto-add-overlay: allow overlays
  • --java: output directory for the R.java
  • --proguard-main-dex: output file for Proguard rules for main dex
  • --custom-package: package for the R class
  • -0: do not compress these extensions
  • --output-text-symbols: output file for the R.txt
  • --no-version-vectors: no automatic versioning of vector drawables

Other flags that might be useful to you:

  • -v: verbose logging
  • -A: directory containing assets you want placed in your APK file, they will not be processed or compressed, just put as-is into the output file
  • -h: print out help

Compile

Compile command is pretty straightforward. You basically tell AAPT2 which single file to compile and where to output it.

<path>aapt2 compile -o /path/to/output/dir /path/to/file/to/compile.xml

The flags for compile are:

  • -o: the directory where the compiled files will be placed
  • --pseudo-localize: generate sources for pseudo-locales
  • --legacy: causes AAPT2 to be more lenient and treat some errors as warnings (like AAPT1 did)
  • -v: verbose logging
  • -h: print out help

One thing to keep in mind is that the compiled files are binary .flat files and the output name is based in the input name and the file's parent directory name. That means if an input file was res/drawable-450dpi/img.pngthe output file will be drawable-450dpi_img.png.flat. Compiled values files get the extension "arsc.flat" instead of just ".flat", so a file res/values-en/strings.xml will be compiled to values-en_strings.arsc.flat. This is done automatically by AAPT2 so you don't need to worry about it, but it's good to know in case you need to find the compiled file later on.

Another fun fact about compile is that it's nifty when it comes to remembering what the input file was (and the line numbers for XML files), so if linking fails the error won't point to the .flat file, but to the original input file instead.

Izabela Orlowska
  • 7,431
  • 2
  • 20
  • 33
  • Great - That worked. I did have to update to the alpha version of the gradle plugin to get the actual compile command. The 3.1 version I was on only printed the parameters, but not the command. Do you have a similar trick for the compile step? I can see the aapt daemons being started, but no commands. – Derek May 03 '18 at 20:06
  • Compile is actually very simple. I'll edit the post with the info. – Izabela Orlowska May 04 '18 at 08:42
  • Do you happen to know anything about building projects in the AOSP? Specifically, I was going to try to do a custom build of the Android Gradle plugin - but I can find almost no up to date docs on it. – Derek May 07 '18 at 21:29
  • @Derek are you saying you want to rewrite the Android Gradle plugin from scratch? – Izabela Orlowska May 09 '18 at 08:38
  • I wouldn't say re-write, but make some minor modifications to the plugin. I have been struggling to get the "repo" tool to pull a buildable version of the plugin from AOSP – Derek May 09 '18 at 13:51
  • I would highly advise against modifying the code for personal use. Did you consider maybe adding your own tasks to the existing ones? What is it that you're trying to do? – Izabela Orlowska May 09 '18 at 18:25
  • I am interested in adding some additional parameters to the aapt2 compile and link steps. As far as I can tell, not everything is a configurable option in aaptOptions – Derek May 09 '18 at 21:25
  • 1
    The Gradle plugin already supports that. For additional parameters for the 'link' command add 'android.aaptOptions.additionalParameters "param1", "param2"' to your 'build.gradle' file. As for compile, everything is already used when needed. Crunching is disabled by default for debug, enabled by default for release (you can modify it in the build.gradle if you wish). Similarly with pseudo localization, you can set it in the same file for build type. "Legacy" is used by default. For passing additional files you can add them as a sourceset to the merge resources task. – Izabela Orlowska May 10 '18 at 09:00