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