This page describes build changes added to AOSP to reduce unnecessary file changes between builds. Device implementers who maintain their own build system can use this information as a guide for reducing over-the-air (OTA) update size.
Android OTAs occasionally contain changed files that do not correspond to code changes but are instead artifacts of the build system. This can occurs when the same code built at different times, from different directories, or on different machines, produces a large number of changed files. These excess files not only increase the size of an OTA, but make it difficult to determine which code is changed in the OTA.
To make the contents of an OTA more transparent, AOSP includes build system changes designed to reduce OTA size by eliminating unnecessary file changes between builds. The aim is to reduce the size of OTAs to include only the files that relate to the patches contained in the OTA. AOSP also includes a build diff tool that filters out common build-related file changes and provides a cleaner build file diff.
The build system can create unnecessary file diffs in several ways. The following sections discuss some of these issues and solutions, providing examples of fixes in AOSP when possible).
Problem: Filesystems don’t guarantee a file order when asked for a list of files
in a directory, though it’s commonly the same for the same checkout. Tools such as ls
sort the results by default, but the wildcard function used by commands such as find
and make
do not. Before using these tools, you must sort the outputs.
Solution: Users of tools such as find
and make
with
wildcard must sort the output of these commands before using them. Use of
$(wildcard )
or $(shell find )
in Android.mk files should also be
sorted. Some tools, such as Java, do sort inputs so verify sorting is necessary.
Examples: Many instances were fixed in the core build system using the builtin
all-*-files-under
macro, which includes all-cpp-files-under
(as several
definitions were spread out in other makefiles). For details, refer to the following CLs:
Problem: Changing the directory in which things are built can cause the binaries
to be different. Most paths in the Android build are relative paths so __FILE__
in
C/C++ isn’t a problem. However, the debug symbols encode the full pathname by default, and the
.note.gnu.build-id
is generated from hashing the pre-stripped binary, so it will
change if the debug symbols change.
Solution: AOSP now makes debug paths relative. For details, refer to CL: https://android.googlesource.com/platform/build/+/6a66a887baadc9eb3d0d60e26f748b8453e27a02.
Problem: Timestamps in the build output result in unnecessary file changes. This is likely to happen in the following locations:
__DATE__/__TIME__/__TIMESTAMP__
macros in C or C++ code.Solutions/Examples: To remove timestamps from the build output, use the instructions in the sections below.
These macros always produce different outputs for different builds, so they shouldn’t be used. Here are a few options on how to eliminate these macros:
ro.build.date
(should work for everything
except incremental builds, which may not update this date). For an example, refer to
https://android.googlesource.com/platform/external/libchrome/+/8b7977eccc94f6b3a3896cd13b4aeacbfa1e0f84Note:We turned on -Werror=date-time
so using
timestamps is a build error.
We fixed the problem of embedded timestamps in zip archives by adding -X
to all uses
of the zip
command, so the UID/GID of the builder and the extended Unix timestamp are
not embedded in the zip file.
A new tool, ziptime
(located in
/platform/build/+/master/tools/ziptime/
)
resets the normal timestamps in the zip headers. For details, refer to the
README
file.
The signapk
tool sets timestamps for the APK files that may vary depending on the
server timezone. For details, refer to the CL
https://android.googlesource.com/platform/build/+/6c41036bcf35fe39162b50d27533f0f3bfab3028.
Problem: APK version strings often had the BUILD_NUMBER appended to the hardcoded version. Even if nothing else changed in the APK, the APK would still be different.
Solution: Remove the build number from the APK version string.
Examples:
Problem: Tools that generate installed files must be consistent (the same input should always produce the same output).
Solutions/Examples: Changes were required in the following build tools:
/system/lib/libpac.so
file because the V8 snapshot changes for each build. The
solution is to remove the snapshot. Refer to CL:
https://android.googlesource.com/platform/external/v8/+/e537f38c36600fd0f3026adba6b3f4cbcee1fb29For cases where it is not possible to eliminate build-related file changes, we supply a build
diff tool,
target_files_diff.py
for use in comparing two file packages. This tool performs a recursive diff between two builds,
excluding common build-related file changes, such as:
To use the build diff tool, run the following command:
target_files_diff.py dir1 dir2
dir1
and dir2
are base directories that contain the extracted target
files for each build.