| Gina Dimino | 761ee0a | 2015-02-27 14:37:02 -0800 | [diff] [blame] | 1 | page.title=Android Platform 64-bit Build Instructions | 
 | 2 | @jd:body | 
 | 3 |  | 
 | 4 | <!-- | 
 | 5 |     Copyright 2015 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 | <div id="qv-wrapper"> | 
 | 20 |   <div id="qv"> | 
 | 21 |     <h2>In this document</h2> | 
 | 22 |     <ol id="auto-toc"> | 
 | 23 |     </ol> | 
 | 24 |   </div> | 
 | 25 | </div> | 
 | 26 |  | 
 | 27 | <h2 id=overview>Overview</h2> | 
 | 28 |  | 
 | 29 | <p>From the build system’s perspective, the most prominent change is that now it | 
 | 30 | supports building binaries for two target CPU architectures (64-bit and 32-bit) | 
 | 31 | in the same build. That’s also known as <em>Multilib build</em>.</p> | 
 | 32 |  | 
 | 33 | <p>For native static libraries and shared libraries, the build system sets up | 
 | 34 | rules to build binaries for both architectures. The product configuration | 
 | 35 | (PRODUCT_PACKAGES), together with the dependency graph, determines which | 
 | 36 | binaries are built and installed to the system image.</p> | 
 | 37 |  | 
 | 38 | <p>For executables and apps, the build system builds only the 64-bit version by | 
 | 39 | default, but you can override this setting by using a global | 
 | 40 | <code>BoardConfig.mk</code> variable or a module-scoped variable.</p> | 
 | 41 |  | 
 | 42 | <p class="caution"><strong>Caution:</strong> If an app exposes an API to other | 
 | 43 | apps that can be either 32- or 64-bit, the app must have the | 
 | 44 | <code>android:multiarch</code> property set to a value of <code>true</code> | 
 | 45 | within its manifest to avoid potential errors.</p> | 
 | 46 |  | 
 | 47 | <h2 id=product_configuration>Product Configuration</h2> | 
 | 48 |  | 
 | 49 |  | 
 | 50 | <p>In <code>BoardConfig.mk</code>, we added the following variables to | 
 | 51 | configure the second CPU architecture and ABI:</p> | 
 | 52 |  | 
 | 53 | <pre class=prettyprint> | 
 | 54 | TARGET_2ND_ARCH | 
 | 55 | TARGET_2ND_ARCH_VARIANT | 
 | 56 | TARGET_2ND_CPU_VARIANT | 
 | 57 | TARGET_2ND_CPU_ABI | 
 | 58 | TARGET_2ND_CPU_ABI2 | 
 | 59 | </pre> | 
 | 60 |  | 
 | 61 |  | 
 | 62 | <p>You can see an example in <code>build/target/board/generic_arm64/BoardConfig.mk</code>.</p> | 
 | 63 |  | 
 | 64 | <p>If you want the build system to build 32-bit executables and apps by default, | 
 | 65 | set the following variable:</p> | 
 | 66 |  | 
 | 67 | <pre class=prettyprint> | 
 | 68 | TARGET_PREFER_32_BIT := true | 
 | 69 | </pre> | 
 | 70 |  | 
 | 71 | <p>However, you can override this setting  by using module-specific variables in | 
 | 72 | <code>Android.mk</code>.</p> | 
 | 73 |  | 
 | 74 | <p>In a Multilib build, module names in <code>PRODUCT_PACKAGES</code> cover | 
 | 75 | both the 32-bit and 64-bit binaries, as long as they are defined by the build | 
 | 76 | system. For libraries pulled in by dependency, a 32-bit library is installed | 
 | 77 | only if it’s required by another 32-bit library or executable. The same is true | 
 | 78 | for 64-bit libraries.</p> | 
 | 79 |  | 
 | 80 | <p>However, module names on the <code>make</code> command line cover only the | 
 | 81 | 64-bit version. For example, after running <code>lunch | 
 | 82 | aosp_arm64-eng</code>,<code>make libc</code> builds only the 64-bit libc. To | 
 | 83 | build the 32-bit libc, you need to run <code>make libc_32</code>.</p> | 
 | 84 |  | 
 | 85 | <h2 id=module_definition_in_android_mk>Module Definition in Android.mk</h2> | 
 | 86 |  | 
 | 87 | <p>You can use the <code>LOCAL_MULTILIB</code> variable to configure your build | 
 | 88 | for 32-bit and/or 64-bit and override the global | 
 | 89 | <code>TARGET_PREFER_32_BIT</code>.</p> | 
 | 90 |  | 
 | 91 | <p>Set <code>LOCAL_MULTILIB</code> to one of the following:</p> | 
 | 92 |  | 
 | 93 | <ul> | 
 | 94 |   <li>"both”: build both 32-bit and 64-bit.</li> | 
 | 95 |   <li>“32”: build only 32-bit.</li> | 
 | 96 |   <li>“64”: build only 64-bit.</li> | 
 | 97 |   <li>“first”: build for only the first arch (32-bit in 32-bit devices and 64-bit | 
 | 98 | in 64-bit devices).</li> | 
 | 99 |   <li>“”: the default; the build system decides what arch to build based on the | 
 | 100 | module class and other LOCAL_ variables, such as LOCAL_MODULE_TARGET_ARCH, | 
 | 101 | LOCAL_32_BIT_ONLY, etc.</li> | 
 | 102 | </ul> | 
 | 103 |  | 
 | 104 | <p>In a Multilib build, conditionals like <code>ifeq $(TARGET_ARCH)</code> don’t work any | 
 | 105 | more. </p> | 
 | 106 |  | 
 | 107 | <p>If you want to build your module for some specific arch(s), the following | 
 | 108 | variables can help you:</p> | 
 | 109 |  | 
 | 110 | <ul> | 
 | 111 |   <li>LOCAL_MODULE_TARGET_ARCH<br>It can be set to a list of archs, something | 
 | 112 | like “arm x86 arm64”. Only if the arch being built is among that list will the | 
 | 113 | current module be included by the build system.</li> | 
 | 114 |  | 
 | 115 |   <li>LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH<br>The opposite of | 
 | 116 | LOCAL_MODULE_TARGET_ARCH. Only if the arch being built is not among the list, | 
 | 117 | the current module will be included.</li> | 
 | 118 | </ul> | 
 | 119 |  | 
 | 120 | <p>There are minor variants of the above two variables:</p> | 
 | 121 |  | 
 | 122 | <ul> | 
 | 123 |   <li>LOCAL_MODULE_TARGET_ARCH_WARN</li> | 
 | 124 |   <li>LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN</li> | 
 | 125 | </ul> | 
 | 126 |  | 
 | 127 | <p>The build system will give warning if the current module is skipped due to | 
 | 128 | archs limited by them.</p> | 
 | 129 |  | 
 | 130 | <p>To set up arch-specific build flags, use the arch-specific LOCAL_ variables. An | 
 | 131 | arch-specific LOCAL_ variable is a normal LOCAL_ variable with an arch suffix, | 
 | 132 | for example:</p> | 
 | 133 |  | 
 | 134 | <ul> | 
 | 135 |   <li> <code>LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,</code> | 
 | 136 |   <li> <code>LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,</code> | 
 | 137 |   <li> <code>LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,</code> | 
 | 138 | </ul> | 
 | 139 |  | 
 | 140 | <p>Those variables will be applied only if a binary is  currently being built for | 
 | 141 | that arch.</p> | 
 | 142 |  | 
 | 143 | <p>Sometimes it’s more convenient to set up flags based on whether the binary is | 
 | 144 | currently being built for 32-bit or 64-bit. In that case you can use the LOCAL_ | 
 | 145 | variable with a _32 or _64 suffix, for example:</p> | 
 | 146 |  | 
 | 147 | <ul> | 
 | 148 |   <li> <code>LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,</code> | 
 | 149 |   <li> <code>LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,</code> | 
 | 150 |   <li> <code>LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,</code> | 
 | 151 | </ul> | 
 | 152 |  | 
 | 153 | <p>Note that not all of the LOCAL_ variables support the arch-specific variants. | 
 | 154 | For an up-to-date list of such variables, refer to <code>build/core/clear_vars.mk</code>.</p> | 
 | 155 |  | 
 | 156 | <h2 id=install_path>Install path</h2> | 
 | 157 |  | 
 | 158 |  | 
 | 159 | <p>In the past, you could use LOCAL_MODULE_PATH to install a library to a | 
 | 160 | location other than the default one. For example, <code>LOCAL_MODULE_PATH := | 
 | 161 | $(TARGET_OUT_SHARED_LIBRARIES)/hw</code>.</p> | 
 | 162 |  | 
 | 163 | <p>In Multilib build, use LOCAL_MODULE_RELATIVE_PATH instead:</p> | 
 | 164 |  | 
 | 165 | <pre class=prettyprint> | 
 | 166 | LOCAL_MODULE_RELATIVE_PATH := hw | 
 | 167 | </pre> | 
 | 168 |  | 
 | 169 |  | 
 | 170 | <p>so that both the 64-bit and 32-bit libraries can be installed to the right | 
 | 171 | place.</p> | 
 | 172 |  | 
 | 173 | <p>If you build an executable as both 32-bit and 64-bit, you’ll need to use one of | 
 | 174 | the following variables to distinguish the install path:</p> | 
 | 175 |  | 
 | 176 | <ul> | 
 | 177 |   <li><code>LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64</code><br>Specifies the installed file name. | 
 | 178 |   <li><code>LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64</code><br>Specifies the install path. | 
 | 179 | </ul> | 
 | 180 |  | 
 | 181 | <h2 id=generated_sources>Generated sources </h2> | 
 | 182 |  | 
 | 183 | <p>In a Multilib build,  if you generate source files to | 
 | 184 | <code>$(local-intermediates-dir)</code> (or <code>$(intermediates-dir-for) | 
 | 185 | </code>with explicit variables), it won’t reliably work any more. That’s | 
 | 186 | because the intermediate generated sources will be required by both 32-bit and | 
 | 187 | 64-bit build, but <code>$(local-intermediates-dir)</code> only points to one of | 
 | 188 | the two intermediate directories.</p> | 
 | 189 |  | 
 | 190 | <p>Happily, the build system now provides a dedicated, Multilib-friendly, | 
 | 191 | intermediate directory for generating sources. You can call<code> | 
 | 192 | $(local-generated-sources-dir)</code> or | 
 | 193 | <code>$(generated-sources-dir-for)</code> to get the directory’s path. Their | 
 | 194 | usages are similar to <code>$(local-intermediates-dir)</code> and | 
 | 195 | <code>$(intermediates-dir-for)</code>. </p> | 
 | 196 |  | 
 | 197 | <p>If a source file is generated to the new dedicated directory and picked up | 
 | 198 | by <code>LOCAL_GENERATED_SOURCES</code>, it is built for both 32-bit and 64-bit | 
 | 199 | in multilib build.</p> | 
 | 200 |  | 
 | 201 | <h2 id=prebuilts>Prebuilts</h2> | 
 | 202 |  | 
 | 203 |  | 
 | 204 | <p>In Multilib, you can’t use <code>TARGET_ARCH</code> (or together with | 
 | 205 | <code>TARGET_2ND_ARCH</code>) to tell the build system what arch the prebuilt | 
 | 206 | binary is targeted for. Use the aforementioned <code>LOCAL_</code> variable | 
 | 207 | <code>LOCAL_MODULE_TARGET_ARCH</code> or | 
 | 208 | <code>LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH</code> instead.</p> | 
 | 209 |  | 
 | 210 | <p>With these variables, the build system can choose the corresponding 32-bit | 
 | 211 | prebuilt binary even if it’s currently doing a 64-bit Multilib build.</p> | 
 | 212 |  | 
 | 213 | <p>If you want to use the chosen arch to compute the source path for the prebuilt | 
 | 214 | binary , you can call<code> $(get-prebuilt-src-arch)</code>.</p> | 
 | 215 |  | 
 | 216 | <h2 id=dex-preopt>Dex-preopt</h2> | 
 | 217 |  | 
 | 218 |  | 
 | 219 | <p>For 64-bit devices, by default we generate both 32-bit and 64-bit odex files | 
 | 220 | for the boot image and any Java libraries. For APKs, by default we generate | 
 | 221 | odex only for the primary 64-bit arch. If an app will be launched in both | 
 | 222 | 32-bit and 64-bit processes, please use <code>LOCAL_MULTILIB := both</code> to make sure | 
 | 223 | both 32-bit and 64-bit odex files are generated. That flag also tells the build | 
 | 224 | system to include both 32-bit and 64-bit JNI libraries, if the app has any.</p> | 
 | 225 |  |