Home | History | Annotate | Download | only in ota
      1 <html devsite>
      2   <head>
      3     <title>Reducing OTA Size</title>
      4     <meta name="project_path" value="/_project.yaml" />
      5     <meta name="book_path" value="/_book.yaml" />
      6   </head>
      7   <body>
      8   <!--
      9       Copyright 2017 The Android Open Source Project
     10 
     11       Licensed under the Apache License, Version 2.0 (the "License");
     12       you may not use this file except in compliance with the License.
     13       You may obtain a copy of the License at
     14 
     15           http://www.apache.org/licenses/LICENSE-2.0
     16 
     17       Unless required by applicable law or agreed to in writing, software
     18       distributed under the License is distributed on an "AS IS" BASIS,
     19       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     20       See the License for the specific language governing permissions and
     21       limitations under the License.
     22   -->
     23 
     24 
     25 <p>This page describes build changes added to AOSP to reduce unnecessary file changes between
     26   builds. Device implementers who maintain their own build system can use this information as a
     27   guide for reducing over-the-air (OTA) update size.</p>
     28 
     29 <p>Android OTAs occasionally contain changed files that do not correspond to code changes but are
     30   instead artifacts of the build system. This can occurs when the same code built at different
     31   times, from different directories, or on different machines, produces a large number of changed
     32   files. These excess files not only increase the size of an OTA, but make it difficult to
     33   determine which code is changed in the OTA.</p>
     34 
     35 <p>To make the contents of an OTA more transparent, AOSP includes build system changes designed to
     36   reduce OTA size by eliminating unnecessary file changes between builds. The aim is to reduce
     37   the size of OTAs to include only the files that relate to the patches contained in the OTA. AOSP
     38   also includes a <a href="#the_build_diff_tool">build diff tool</a> that filters out common
     39   build-related file changes and provides a cleaner build file diff.</p>
     40 
     41 <p>The build system can create unnecessary file diffs in several ways. The following sections
     42   discuss some of these issues and solutions, providing examples of fixes in AOSP when possible).</p>
     43 
     44 <h2 id=file_order>File order</h2>
     45 
     46 <p><strong>Problem</strong>: Filesystems dont guarantee a file order when asked for a list of files
     47   in a directory, though its commonly the same for the same checkout. Tools such as <code>ls</code>
     48   sort the results by default, but the wildcard function used by commands such as <code>find</code>
     49   and <code>make</code> do not. Before using these tools, you must sort the outputs.</p>
     50 
     51 <p><strong>Solution</strong>: Users of tools such as <code>find</code> and <code>make</code> with
     52   wildcard must sort the output of these commands before using them. Use of
     53   <code>$(wildcard )</code> or <code>$(shell find )</code> in Android.mk files should also be
     54   sorted. Some tools, such as Java, do sort inputs so verify sorting is necessary.</p>
     55 
     56 <p><strong>Examples:</strong> Many instances were fixed in the core build system using the builtin
     57   <code>all-*-files-under</code> macro, which includes <code>all-cpp-files-under</code> (as several
     58   definitions were spread out in other makefiles). For details, refer to the following CLs:</p>
     59 
     60 <ul>
     61   <li><a href="https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f">https://android.googlesource.com/platform/build/+/4d66adfd0e6d599d8502007e4ea9aaf82e95569f</a>
     62   <li><a href="https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410">https://android.googlesource.com/platform/build/+/379f9f9cec4fe1c66b6d60a6c19fecb81b9eb410</a>
     63   <li><a href="https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653">https://android.googlesource.com/platform/build/+/7c3e3f8314eec2c053012dd97d2ae649ebeb5653</a>
     64   <li><a href="https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c">https://android.googlesource.com/platform/build/+/5c64b4e81c1331cab56d8a8c201f26bb263b630c</a>
     65 </ul>
     66 
     67 <h2 id=build_directory>Build directory</h2>
     68 
     69 <p><strong>Problem:</strong> Changing the directory in which things are built can cause the binaries
     70   to be different. Most paths in the Android build are relative paths so <code>__FILE__</code> in
     71   C/C++ isnt a problem. However, the debug symbols encode the full pathname by default, and the
     72   <code>.note.gnu.build-id</code> is generated from hashing the pre-stripped binary, so it will
     73   change if the debug symbols change.</p>
     74 
     75 <p><strong>Solution:</strong> AOSP now makes debug paths relative. For details, refer to CL:
     76   <a href="https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02">https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02</a>.</p>
     77 
     78 <h2 id=timestamps>Timestamps</h2>
     79 
     80 <p><strong>Problem:</strong> Timestamps in the build output result in unnecessary file changes. This
     81   is likely to happen in the following locations:</p>
     82 
     83 <ul>
     84   <li><code> __DATE__/__TIME__/__TIMESTAMP__ </code> macros in C or C++ code.</li>
     85   <li>Timestamps embedded in zip-based archives.</li>
     86 </ul>
     87 
     88 <p><strong>Solutions/Examples:</strong> To remove timestamps from the build output, use the
     89   instructions in the sections below.</p>
     90 
     91 <h3 id=date_time_timestamp_in_c_c>__DATE__/__TIME__/__TIMESTAMP__ in C/C++</h3>
     92 
     93 <p>These macros always produce different outputs for different builds, so they shouldnt be used.
     94   Here are a few options on how to eliminate these macros:</p>
     95 
     96 <ul>
     97   <li>Just remove them, they often arent necessary. For an example, refer to
     98     <a href="https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f">https://android.googlesource.com/platform/system/core/+/30622bbb209db187f6851e4cf0cdaa147c2fca9f</a></li>
     99   <li>To uniquely identify the running binary, read the build-id from the ELF header.</li>
    100   <li>To know when the OS was built, read the <code>ro.build.date</code> (should work for everything
    101     except incremental builds, which may not update this date). For an example, refer to
    102     <a href="https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84">https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84</a></li>
    103 </ul>
    104 
    105     <p class="note"><strong>Note:</strong>We turned on <code>-Werror=date-time</code> so using
    106       timestamps is a build error.</p>
    107 
    108 <h3 id=embedded_timestamps_in_zip-based_archives_zip_jar>Embedded timestamps in archives (zip, jar)</h3>
    109 
    110 <p>We fixed the problem of embedded timestamps in zip archives by adding <code>-X</code> to all uses
    111   of the <code>zip</code> command, so the UID/GID of the builder and the extended Unix timestamp are
    112   not embedded in the zip file.</p>
    113 
    114 <p>A new tool, <code>ziptime</code> (located in <code>
    115   <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/">/platform/build/+/master/tools/ziptime/</a></code>)
    116   resets the normal timestamps in the zip headers. For details, refer to the
    117   <a href="https://android.googlesource.com/platform/build/+/master/tools/ziptime/README.txt">README
    118     file</a>.</p>
    119 
    120 <p>The <code>signapk</code> tool sets timestamps for the APK files that may vary depending on the
    121   server timezone. For details, refer to the CL
    122   <a href="https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028">https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028</a>.</p>
    123 
    124 <h2 id=version_strings>Version strings</h2>
    125 
    126 <p><strong>Problem:</strong> APK version strings often had the BUILD_NUMBER appended to the
    127   hardcoded version. Even if nothing else changed in the APK, the APK would still be different.</p>
    128 
    129 <p><strong>Solution:</strong> Remove the build number from the APK version string.</p>
    130 
    131 <p><strong>Examples:</strong></p>
    132 
    133 <ul>
    134   <li><a href="https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27">https://android.googlesource.com/platform/packages/apps/Camera2/+/5e0f4cf699a4c7c95e2c38ae3babe6f20c258d27</a></li>
    135   <li><a href="https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c">https://android.googlesource.com/platform/build/+/d75d893da8f97a5c7781142aaa7a16cf1dbb669c</a></li>
    136 </ul>
    137 
    138 <h2 id=consistent_build_tools>Consistent build tools</h2>
    139 
    140 <p><strong>Problem:</strong> Tools that generate installed files must be consistent (the same input
    141   should always produce the same output).</p>
    142 
    143 <p><strong>Solutions/Examples:</strong> Changes were required in the following build tools:</p>
    144 
    145 <ul>
    146   <li><strong>NOTICE file creator</strong>. The NOTICE file creator needed the changes. Refer to CL:
    147     <a href="https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64">https://android.googlesource.com/platform/build/+/8ae4984c2c8009e7a08e2a76b1762c2837ad4f64</a></li>
    148   <li><strong>Java Android Compiler Kit (Jack)</strong>. The Jack toolchain required an update to
    149     handle an occasional change in generated constructor ordering. Refer to CL:
    150     <a href="https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b">https://android.googlesource.com/toolchain/jack/+/056a5425b3ef57935206c19ecb198a89221ca64b</a></li>
    151   <li><strong>ART AOT compiler (dex2oat)</strong>. The ART compiler binary required an update to
    152     create a deterministic image. Refer to CL:
    153     <a href="https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9">https://android.googlesource.com/platform/art/+/ace0dc1dd5480ad458e622085e51583653853fb9</a></li>
    154   <li><strong>The libpac.so file (V8)</strong>Every build creates a different
    155     <code>/system/lib/libpac.so</code> file because the V8 snapshot changes for each build. The
    156     solution is to remove the snapshot. Refer to CL:
    157     <a href="https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29">https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29</a></li>
    158   <li><strong>Application pre-dexoptd (.odex) files</strong>. The pre-dexoptd (.odex) files
    159     contained uninitialized padding on 64-bit systems. Refer to CL:
    160     <a href="https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029">https://android.googlesource.com/platform/art/+/34ed3afc41820c72a3c0ab9770be66b6668aa029</a></li>
    161 </ul>
    162 
    163 <h2 id=the_build_diff_tool>Using the build diff tool</h2>
    164 
    165 <p>For cases where it is not possible to eliminate build-related file changes, we supply a build
    166   diff tool,
    167   <code><a href="https://android.googlesource.com/platform/build/+/master/tools/releasetools/target_files_diff.py">target_files_diff.py</a></code>
    168   for use in comparing two file packages. This tool performs a recursive diff between two builds,
    169   excluding common build-related file changes, such as:</p>
    170 
    171 <ul>
    172   <li>Expected changes in the build output (for example, due to a build number change).</li>
    173   <li>Changes due to known issues in the current build system.</li>
    174 </ul>
    175 
    176 <p>To use the build diff tool, run the following command:</p>
    177 
    178 <pre class="devsite-terminal devsite-click-to-copy">
    179 target_files_diff.py dir1 dir2
    180 </pre>
    181 
    182 <p><code>dir1</code> and <code>dir2</code> are base directories that contain the extracted target
    183   files for each build.</p>
    184 
    185   </body>
    186 </html>
    187