1page.title=Reducing OTA Size 2@jd:body 3 4<!-- 5 Copyright 2016 The Android Open Source Project 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18--> 19 20<div id="qv-wrapper"> 21 <div id="qv"> 22 <h2>In this document</h2> 23 <ol id="auto-toc"> 24 </ol> 25 </div> 26</div> 27 28<p>A common problem with Android over-the-air updates (OTAs) is that they contain 29changed files that do not correspond to code changes, but instead are artifacts 30of the build system. This happens whenever the same code, built at different 31times, from different directories, or on different machines, produces a large 32number of changed files. The excess files not only increase the size of an 33OTA, but make it difficult to determine which code is changed in the OTA.</p> 34 35<p>To make the contents of an OTA more transparent, we have added a number of 36build system changes that reduce the size of an OTA by eliminating unnecessary 37file changes between builds. The aim is to reduce the size of OTAs to include 38only the files that relate to the patches contained in the OTA. We have also 39introduced a build diff tool that filters out common build-related file changes 40and provides a cleaner build file diff (see below).</p> 41 42<p>This document provides an explanation of some of the build changes that have 43been added to AOSP to reduce unnecessary file changes between builds. For 44device implementers who maintain their own build system, it provides a guide 45to some of the changes that need to be made to reduce OTA size.</p> 46 47<h3 id=the_build_diff_tool>The build diff tool</h3> 48 49 50<p>Since there are cases where it is not possible to eliminate build-related file 51changes, we have supplied a build diff tool, <code><a href="https://android.googlesource.com/platform/build/+/master/tools/releasetools/target_files_diff.py">target_files_diff.py</a></code>, that can be used to compare two target file packages. </p> 52 53<p>The build diff tool does a recursive diff between two builds, excluding common 54build-related file changes. Excluded changes include the following:</p> 55 56<ul> 57 <li> Expected changes in the build output (for example, due to build number 58changing). 59 <li> Changes due to known issues in the current build system. 60</ul> 61 62<p>To use the build diff tool, run the following command:</p> 63 64<pre class=prettyprint> 65$ target_files_diff.py dir1 dir2 66</pre> 67 68 69<p>where <code>dir1</code> and <code>dir2</code> are base directories that contain the extracted target files for each build.</p> 70 71<h2 id=changes_to_reduce_ota_size>Changes to reduce OTA size</h2> 72 73 74<p>There are several ways that the build system can create unnecessary file diffs. 75 In the following sections, we discuss some of these issues, discuss solutions, 76 and, where possible, show examples of the fixes in AOSP.</p> 77 78<h3 id=file_order>File Order</h3> 79 80 81<p><strong>Problem</strong>: Filesystems don’t guarantee a file order when asked for a list of files in a 82directory, though it’s commonly the same for the same checkout. Tools such as <code>ls </code>sort the results by default, but the wildcard function used by commands such as <code>find</code> and <code>make </code>do not. So when any of these tools are used, you need to sort the outputs 83before using them.</p> 84 85<p><strong>Solution</strong>: Users of tools such as <code>find</code> and <code>make</code> with wildcard need to sort the output of these commands before using them. In 86fact, any uses of $(wildcard ) or $(shell find ) in Android.mk files should be 87sorted. (Some tools (like java) will sort their inputs, so in some cases it may 88not actually necessary.)</p> 89 90<p><strong>Examples:</strong> Many instances of this were fixed in the core build system, especially when 91you use the builtin <code>all-*-files-under</code> macros (and <code>all-cpp-files-under</code> was added, since there were several definitions spread out in other 92makefiles):</p> 93 94<ul> 95 <li> <a href="https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f">https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f</a> 96 <li> <a href="https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410">https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410</a> 97 <li> <a href="https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653">https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653</a> 98 <li> <a href="https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c">https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c</a> 99</ul> 100 101<h3 id=build_directory>Build Directory</h3> 102 103 104<p><strong>Problem: </strong>Changing the directory in which things are built can cause the binaries to be 105different. Most paths in the android build are relative paths, so <code>__FILE__</code> in C/C++ isn’t a problem. </p> 106 107<p>But the debug symbols encode the full pathname by default. Then the <code>.note.gnu.build-id</code> is generated from hashing the pre-stripped binary, so it will change if the 108debug symbols change. </p> 109 110<p><strong>Solution: </strong>To fix this, AOSP master has been changed to make the debug paths relative, as 111shown here: </p> 112 113<ul> 114 <li> <a href="https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02">https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02</a> 115</ul> 116 117<h3 id=timestamps>Timestamps</h3> 118 119 120<p><strong>Problem: </strong>Timestamps in the build output result in unnecessary file changes. Two places 121this is likely to happen are the following:</p> 122 123<ul> 124 <li> <code> __DATE__/__TIME__/__TIMESTAMP__ </code> macros in C or C++ code. 125 <li> Timestamps embedded in zip-based archives. 126</ul> 127 128<p><strong>Solutions/Examples:</strong></p> 129 130<p>To remove timestamps from the build output in each of these instances, see the 131instructions in the sections below.</p> 132 133<h4 id=date_time_timestamp_in_c_c>__DATE__/__TIME__/__TIMESTAMP__ in C/C++</h4> 134 135 136<p>These macros always produce different outputs for different builds, so they 137shouldn’t be used. </p> 138 139<p>Here are a few options on how to eliminate these macros:</p> 140 141<ul> 142 <li> Just remove them, they often aren’t necessary.<br> 143Example:<br><a href="https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f">https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f</a> 144 <li> If you just need to be able to uniquely identify the running binary, read the 145build-id from the ELF header. (No example, we didn’t run into this problem.) 146 <li> If you just want to know when the OS was built, you can read the ro.build.date 147-- this should work for everything except incremental builds, which may not 148update this date.<br> 149Example:<br><a href="https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84">https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84</a> 150</ul> 151 152<p>We have turned on <code>-Werror=date-time</code>, so that using timestamps is a build error.</p> 153 154<h4 id=embedded_timestamps_in_zip-based_archives_zip_jar>Embedded Timestamps in Zip-based archives (zip, jar)</h4> 155 156 157<p>We fixed the problem of embedded timestamps in zip archives by adding <code>-X</code> to all uses of the <code>zip</code> command, so that the UID/GID of the builder, and the extended Unix timestamp 158weren’t embedded in the zip file. </p> 159 160<p>A new tool, <code>ziptime</code>, resets the normal timestamps in the zip headers:</p> 161 162<ul> 163 <li> <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/">https://android.googlesource.com/platform/build/+/master/tools/ziptime/</a> 164</ul> 165 166<p>For more information, see the <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/README.txt">README file</a>.</p> 167 168<p>The <code>signapk</code> tool sets timestamps for the APK files that may vary depending on the server 169timezone. This problems was fixed in the following CL:</p> 170 171<ul> 172 <li> <a href="https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028">https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028</a> 173</ul> 174 175<h3 id=version_strings>Version Strings</h3> 176 177 178<p><strong>Problem:</strong> APK version strings often had the BUILD_NUMBER appended to the hardcoded 179version. So even if nothing else changed in the APK, the APK would still be 180different. </p> 181 182<p><strong>Solution:</strong> Remove the build number from the APK version string.</p> 183 184<p><strong>Examples: </strong></p> 185 186<ul> 187 <li> <a href="https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27">https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27</a> 188 <li> <a href="https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c">https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c</a> 189</ul> 190 191<h3 id=consistent_build_tools>Consistent build tools</h3> 192 193 194<p><strong>Problem:</strong> Any tools that generate installed files need to be consistent, that is, the 195same input should always produce the same output. </p> 196 197<p><strong>Solutions/Examples: </strong>Changes were required in the following build tools:</p> 198 199<ul> 200 <li> <strong>NOTICE file creator </strong><br> 201The NOTICE file creator needed the following changes: 202 <ul> 203 <li> <a href="https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64">https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64</a> 204 </ul> 205 <li> <strong>Java Android Compiler Kit (Jack) </strong><br> 206The Jack toolchain required an update to handle an occasional change in 207generated constructor ordering: 208 <ul> 209 <li> <a href="https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b">https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b</a> 210 </ul> 211 <li><strong>ART AOT compiler (dex2oat)</strong><br>The ART compiler binary required an update to create a deterministic image: 212 <ul> 213 <li> <a href="https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9">https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9</a> 214 </ul> 215 <li> <strong>The libpac.so file (V8)</strong><br> 216Every build creates a different /system/lib/libpac.so file, because the V8 217snapshot changes for each build. The solution is to remove the snapshot:</p> 218 <ul> 219 <li> <a href="https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29">https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29</a> 220 </ul> 221 <li> <strong>Application pre-dexopt’d (.odex) files 222</strong><br>The pre-dexopt’d (.odex) files contained uninitialized padding on 64-bit 223systems, requiring the following fix:</p> 224 <ul> 225 <li> <a href="https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029">https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029</a> 226 </ul> 227</ul> 228