Home | History | Annotate | Download | only in source
      1 page.title=Understanding 64-bit Builds
      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 systems 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. Thats 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 its 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> dont 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 its 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, youll 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 wont reliably work any more. Thats
    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 directorys 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 cant 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 its 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 
    226