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 | |