From 95adae6f12fa3ba06e1387748d0106959d969d48 Mon Sep 17 00:00:00 2001
From: "smain@google.com" Select, from the table above, the NDK package for your development platform. For information
- about the changes in the newest version of the NDK, see Release Notes. For
- information about earlier revisions, see
- NDK Revision History.
- Android NDK, Revision 12 (June 2016)
- This page provides information on previous releases of the NDK, enumerating the changes that
-took place in each new version.
-
-
-
-
-
- For more detailed information, see Important bug fixes below. When migrating from projects using GCC, you can use
-
-
-
-
- This is a bug-fix-only release.
-
- Note:
- The {@code -Wunused-local-typedefs} option is enabled by {@code -Wall}. Be
- sure to add {@code __attribute__((unused))} if you use compile-time asserts like
- {@code sources/cxx-stl/stlport/stlport/stl/config/features.h}, line #311. For more
- information, see
- Change 55460 Note:
- In the GCC 4.7 release and later, ARM compilers generate unaligned access code by
- default for ARMv6 and higher build targets. You may need to add the
- {@code -mno-unaligned-access} build option when building for kernels that do not support
- this feature. Note:
- Both GCC 4.4.3 and Clang 3.1 are deprecated, and will be removed from the next NDK
- release. Note:
- This feature requires jdb and produces warning about pending breakpoints.
- Specify the {@code --nowait} option to restore previous behavior.
- Note:
- In GCC 4.7, {@code monotonic_clock} and {@code is_monotonic} have been renamed to
- {@code steady_clock} and {@code is_steady}, respectively.
-
-
- Note: This feature is experimental. Please try it and
- report any issues.
- Note: This feature is experimental and works better with the GCC
- 4.6/4.7 compilers than with GCC 4.4.3 or Clang 3.1. Please try it and
- report any issues.
- Note: The {@code -mstack-protector-guard} setting itself does not
- enable any {@code -fstack-protector*} options.
- Note: This feature is experimental. Please try it and
- report any issues.
- Note: All API levels above 14 still link against {@code
- platforms/android-14} and no new {@code platforms/android-N} have been added.
- If your project is linked with the {@code -nostdlib -Wl,--no-undefined} options, you
- must provide your own {@code __dso_handle} because {@code crtbegin_so.o} is not linked in
- this case. The content of {@code __dso_handle} does not matter, as shown in the following
- example code: The previous branding options in section {@code .note.ABI-tag} are deprecated.
- The main features of this release are a new GNU Compiler Collection (GCC) 4.6 toolchain and
-GNU Debugger (GDB) 7.3.x which adds debugging support for the Android 4.1 (API Level 16) system
-image. See {@code docs/ANDROID-MK.html} for more details.
- This release of the NDK includes support for MIPS ABI and a few additional fixes. By default, code is generated for ARM-based devices. You can add {@code mips} to
- your {@code APP_ABI} definition in your {@code Application.mk} file to build
- for MIPS platforms. For example, the following line instructs {@code ndk-build}
- to build your code for three distinct ABIs: Unless you rely on architecture-specific assembly sources, such as ARM assembly
- code, you should not need to touch your {@code Android.mk} files to build MIPS
- machine code. Note: To ensure that your applications are available
-to users only if their devices are capable of running them, Google Play filters applications based
-on the instruction set information included in your application ? no action is needed on your part
-to enable the filtering. Additionally, the Android system itself also checks your application at
-install time and allows the installation to continue only if the application provides a library that
-is compiled for the device's CPU architecture.
- This release of the NDK includes an important fix for Tegra2-based devices, and a few
-additional fixes and improvements: This change forces the NDK build system to put most linker or archiver options
- into list files, as a work-around for command-line length limitations.
- See {@code docs/ANDROID-MK.html} for details.
- This release of the NDK includes fixes for native Windows builds, Cygwin and many other
- improvements: See {@code docs/STANDALONE-TOOLCHAIN.html} for more details about this fix. If you need these features, you must do one of the following: For complete details, see the commit log.
- This release of the NDK includes new features to support the Android 4.0 platform as well
- as many other additions and improvements: Note: CCache is not included in the NDK release
- so you must have it installed prior to using it. For more information about CCache, see
- http://ccache.samba.org. This also works if you define Important: This feature is still experimental, so feel free to try it and report issues on the
- public bug database or public forum. All samples and unit tests
- shipped with the NDK succesfully compile with this feature. The extensions that are available depend on your actual device and GPU drivers,
- not the platform version the device runs on. The header changes simply add new
- constants and types to make it easier to use the extensions when they have been
- probed with
- This release of the NDK does not include any new features compared to r6. The r6b release
- addresses the following issues in the r6 release:
- This release of the NDK includes support for the x86 ABI and other minor changes.
- For detailed information describing the changes in this release, read the
- By default, code is generated for ARM-based devices, but you can add x86 to your
- Unless you rely on ARM-based assembly sources, you shouldn't need to touch
- your
- This release of the NDK does not include any new features compared to r5b. The r5c release
- addresses the following problems in the r5b release:
- This release of the NDK does not include any new features compared to r5. The r5b release
-addresses the
- following problems in the r5 release:
-
- This release of the NDK includes many new APIs, most of which are introduced to
- support the development of games and similar applications that make extensive use
- of native code. Using the APIs, developers have direct native access to events, audio,
- graphics and window management, assets, and storage. Developers can also implement the
- Android application lifecycle in native code with help from the new
- {@link android.app.NativeActivity} class. For detailed information describing the changes
-in this
- release, read the
- Includes fixes for several issues in the NDK build and debugging scripts — if
- you are using NDK r4, we recommend downloading the NDK r4b build. For detailed
- information describing the changes in this release, read the CHANGES.TXT document
- included in the downloaded NDK package.
-
- Originally released as "Android 1.6 NDK, Release 1".
- Originally released as "Android 1.5 NDK, Release 1". Different Android handsets use different CPUs, which in turn support different instruction sets.
-Each combination of CPU and instruction sets has its own Application Binary Interface, or
-ABI. The ABI defines, with great precision, how an application's machine code is supposed to
-interact with the system at runtime. You must specify an ABI for each CPU architecture you want
-your app to work with. A typical ABI includes the following information: This page enumerates the ABIs that the NDK supports, and provides information about how each ABI
-works. Each ABI supports one or more instruction sets. Table 1 provides an at-a-glance overview of
-the instruction sets each ABI supports.
- Table 1. ABIs and supported instruction sets. More detailed information about each ABI appears below. This ABI is for ARM-based CPUs that support at least
-the ARMv5TE instruction set. Please refer to the following documentation for
-more details: The AAPCS standard defines EABI as a family of similar
-but distinct ABIs. Also, Android follows the little-endian
-
-ARM GNU/Linux ABI. This ABI does not support hardware-assisted floating point
-computations. Instead, all floating-point operations use software helper
-functions from the compiler's {@code libgcc.a} static library. The armeabi ABI supports ARM’s
-
-Thumb (a.k.a. Thumb-1) instruction set. The NDK generates Thumb
-code by default unless you specify different behavior using the
- This ABI extends armeabi to include several
-
-CPU instruction set extensions. The instruction extensions that this Android-specific
-ABI supports are: Other extensions that the v7-a ARM spec describes, including
-
-Advanced SIMD (a.k.a. NEON), VFPv3-D32, and ThumbEE, are optional
-to this ABI. Since their presence is not guaranteed, the system should check at runtime
-whether the extensions are available. If they are not, you must use alternative code paths. This
-check is similar to the one that the system typically performs to check or use
-MMX,
-SSE2, and other specialized
-instruction sets on x86 CPUs. For information about how to perform these runtime checks, refer to
-The {@code cpufeatures} Library.
-Also, for information about the NDK's support for building
-machine code for NEON, see
-NEON Support. The {@code armeabi-v7a} ABI uses the {@code -mfloat-abi=softfp} switch to
-enforce the rule that the compiler must pass all double values in core register pairs during
-function calls, instead of dedicated floating-point ones. The system can perform all internal
-computations using the FP registers. Doing so speeds up the computations greatly. This ABI is for ARMv8-based CPUs that support AArch64. It also includes the NEON and
-VFPv4 instruction sets. For more information, see the
-ARMv8
-Technology Preview, and contact ARM for further details. This ABI is for CPUs supporting the instruction set commonly
-referred to as "x86" or "IA-32". Characteristics of this ABI include: These flags target the the Pentium Pro instruction set, along with the
-the MMX,
-SSE,
-SSE2,
-SSE3, and
-SSSE3 instruction set extensions.
-The generated code is an optimization balanced across the top Intel 32-bit
-CPUs. For more information on compiler flags, particularly related to performance optimization,
-refer to GCC
-x86 performance hints. The ABI does not include any other optional IA-32 instruction set
-extensions, such as: You can still use these extensions, as long as you use runtime feature-probing to
-enable them, and provide fallbacks for devices that do not support them. The NDK toolchain assumes 16-byte stack alignment before a function call. The default tools and
-options enforce this rule. If you are writing assembly code, you must make sure to maintain stack
-alignment, and ensure that other compilers also obey this rule. Refer to the following documents for more details: This ABI is for CPUs supporting the instruction set commonly referred to as
-"x86-64." It supports instructions that GCC typically generates with the following
-compiler flags: These flags target the x86-64 instruction set, according to the GCC
-documentation. along with the
-MMX,
-SSE,
-SSE2,
-SSE3,
-SSSE3,
-SSE4.1,
-SSE4.2, and
-POPCNT
-instruction-set extensions. The generated code is an optimization balanced
-across the top Intel 64-bit CPUs. For more information on compiler flags, particularly related to performance optimization,
-refer to GCC
-x86 Performance. This ABI does not include any other optional x86-64 instruction set
-extensions, such as: You can still use these extensions, as long as you use runtime feature probing to
-enable them, and provide fallbacks for devices that do not support them. Refer to the following documents for more details: This ABI is for MIPS-based CPUs that support at least the MIPS32r1 instruction set. It includes
-the following features: For more information, please refer to the following documentation: For more specific details, see
-MIPS32 Architecture.
-Answers to common questions are in the
-MIPS FAQ.
- This ABI is for MIPS64 R6. For more information, see
-MIPS64 Architecture. By default, the NDK generates machine code for the armeabi ABI. You can
-generate ARMv7-a-compatible machine code, instead, by adding the following line
-to your {@code Application.mk} file. To build machine code for two or more distinct ABIs, using spaces as delimiters. For
-example: This setting tells the NDK to build two versions of your machine code: one
-for each ABI listed on this line. For more information on the values you can specify for the
-{@code APP_ABI} variable, see Android.mk.
- When you build multiple machine-code versions, the build system copies the libraries to your
-application project path, and ultimately packages them into your APK, so creating
-a fat binary. A fat binary
-is larger than one containing only the machine code for a single system; the tradeoff is
-gaining wider compatibility, but at the expense of a larger APK. At installation time, the package manager unpacks only the most appropriate
-machine code for the target device. For details, see Automatic
-extraction of native code at install time. This section provides details about how the Android platform manages native
-code in APKs. Both the Play Store and Package Manager expect to find NDK-generated
-libraries on filepaths inside the APK matching the following pattern: Here, {@code If the system does not find the native shared libraries where it expects them, it cannot use
-them. In such a case, the app itself has to copy the libraries over, and then
-perform In a fat binary, each library resides under a directory whose name matches a corresponding ABI.
-For example, a fat binary may contain: Note: ARMv7-based Android devices running 4.0.3 or earlier
-install native libraries from the {@code armeabi} directory instead of the {@code armeabi-v7a}
-directory if both directories exist. This is because {@code /lib/armeabi/} comes after
-{@code /lib/armeabi-v7a/} in the APK. This issue is fixed from 4.0.4. The Android system knows at runtime which ABI(s) it supports, because build-specific system
-properties indicate: This mechanism ensures that the system extracts the best machine code from
-the package at installation time. For best performance, you should compile directly for the primary ABI. For example, a
-typical ARMv5TE-based device would only define the primary ABI: {@code armeabi}. By contrast, a
-typical, ARMv7-based device would define the primary ABI as {@code armeabi-v7a} and the secondary
-one as {@code armeabi}, since it can run application native binaries generated for each of them. Many x86-based devices can also run {@code armeabi-v7a} and {@code armeabi} NDK binaries. For
-such devices, the primary ABI would be {@code x86}, and the second one, {@code armeabi-v7a}. A typical MIPS-based device only defines a primary abi: {@code mips}. When installing an application, the package manager service scans the APK, and looks for any
-shared libraries of the form: If none is found, and you have defined a secondary ABI, the service scans for shared libraries of
-the form: When it finds the libraries that it's looking for, the package manager
-copies them to If there is no shared-object file at all, the application builds and installs, but crashes at
-runtime. This page describes the syntax of the {@code Android.mk} build file,
-which glues your C and C++ source files to the Android NDK. The {@code Android.mk} file resides in a subdirectory of your project's {@code jni/} directory,
-and describes your sources and shared libraries to the build system. It is really a tiny GNU
-makefile fragment that the build system parses once or more. The {@code Android.mk} file is useful
-for defining project-wide settings that {@code
-Application.mk}, the build system, and your
-environment variables leave undefined. It can also override project-wide settings for specific
-modules. The syntax of the {@code Android.mk} allows you to group your sources into
-modules. A module is either a static library, a shared library, or a standalone
-executable. You can define one or more modules in each {@code Android.mk} file, and
-you can use the same source file in multiple modules. The build system only places shared libraries
-into your application package. In addition, static libraries can generate shared libraries. In addition to packaging libraries, the build system handles a variety of other details for you.
-For example, you don't need to list header files or explicit dependencies between generated files in
-your {@code Android.mk} file. The NDK build system computes these relationships automatically for
-you. As a result, you should be able to benefit from new toolchain/platform support in future NDK
-releases without having to touch your {@code Android.mk} file. The syntax of this file is very close to that used in the {@code Android.mk} files distributed with
-the full Android Open Source Project. While the
-build system implementation that uses them is different, their similarity is an
-intentional design decision aimed at making it easier for application
-developers to reuse source code for external libraries. Before exploring the syntax in detail, it is useful to start by understanding the basics
-of what a {@code Android.mk} file contains. This section uses the {@code Android.mk} file in the
-Hello-JNI sample toward that end, explaining the role that each line in the file plays. An {@code Android.mk} file must begin by defining the {@code LOCAL_PATH} variable:
-
- This variable indicates the location of the source files in the development tree. Here, the macro
-function {@code my-dir}, provided by the build system, returns the path of the current directory
-(the directory containing the {@code Android.mk} file itself). The next line declares the {@code CLEAR_VARS} variable, whose value the build system provides.
-
- The {@code CLEAR_VARS} variable points to a special GNU Makefile that clears many
-{@code LOCAL_XXX} variables for you, such as {@code LOCAL_MODULE}, {@code LOCAL_SRC_FILES}, and
-{@code LOCAL_STATIC_LIBRARIES}. Note that it does not clear {@code LOCAL_PATH}. This variable must
-retain its value because the system parses all build control files in a single GNU Make execution
-context where all variables are global. You must (re-)declare this variable before describing each
-module. Next, the {@code LOCAL_MODULE} variable stores the name of the module that you wish to build.
-Use this variable once per module in your application. Each module name must be unique and not contain any spaces. The build system, when it
-generates the final shared-library file, automatically adds the proper prefix and suffix to
-the name that you assign to {@code LOCAL_MODULE}. For example, the example that appears above
-results in generation of a library called {@code libhello-jni.so}. Note: If your module's name already starts with {@code lib}, the
-build system does not prepend an additional {@code lib} prefix; it takes the module name as-is, and
-adds the {@code .so} extension. So a source file originally called, for example, {@code libfoo.c}
-still produces a shared-object file called {@code libfoo.so}. This behavior is to support libraries
-that the Android platform sources generate from {@code Android.mk} files; the names of all such
-libraries start with {@code lib}. The next line enumerates the source files, with spaces delimiting multiple files: The {@code LOCAL_SRC_FILES} variable must contain a list of C and/or C++ source files to build
-into a module. The last line helps the system tie everything together: The {@code BUILD_SHARED_LIBRARY} variable points to a GNU Makefile script that collects all the
-information you defined in {@code LOCAL_XXX} variables since the most recent {@code include}. This
-script determines what to build, and how to do it. There are more complex examples in the samples directories, with commented
-{@code Android.mk} files that you can look at. In addition,
-Sample: native-activity provides
-a detailed explanation of that sample's {@code Android.mk} file. Finally,
-Variables and Macros provides further information on the variables from this section.
-
-
- The build system provides many possible variables for use in the the {@code Android.mk} file.
-Many of these variables come with preassigned values. Others, you assign. In addition to these variables, you can also define your own arbitrary ones. If you do so, keep
-in mind that the NDK build system reserves the following variable names: If you need to define your own convenience variables in an {@code Android.mk} file, we
-recommend prepending {@code MY_} to their names.
-
-
- This section discusses the GNU Make variables that the build system defines before parsing your
-{@code Android.mk} file. Under certain circumstances, the NDK might parse your {@code Android.mk}
-file several times, using a different definition for some of these variables each time. This variable points to a build script that undefines nearly all {@code LOCAL_XXX} variables
-listed in the "Developer-defined variables" section below. Use this variable to include
-this script before describing a new module. The syntax for using it is: This variable points to a build script that collects all the information about the module
-you provided in your {@code LOCAL_XXX} variables, and determines how to build a target shared
-library from the sources you listed. Note that using this script requires that you have already
-assigned values to {@code LOCAL_MODULE} and {@code LOCAL_SRC_FILES}, at a minimum (for more
-information about these variables, see Module-Description Variables). The syntax for using this variable is: A shared-library variable causes the build system to generate a library file with a {@code .so}
-extension. A variant of {@code BUILD_SHARED_LIBRARY} that is used to build a static library. The build
-system does not copy static libraries into your project/packages, but it can use them to build
-shared libraries (see {@code LOCAL_STATIC_LIBRARIES} and {@code LOCAL_WHOLE_STATIC_LIBRARIES},
-below). The syntax for using this variable is: A static-library variable causes the build system to generate a library with a {@code .a}
-extension. Points to a build script used to specify a prebuilt shared library. Unlike in the case of
-{@code BUILD_SHARED_LIBRARY} and {@code BUILD_STATIC_LIBRARY}, here the value of
-{@code LOCAL_SRC_FILES} cannot be a source file. Instead, it must be a single path to a prebuilt
-shared library, such as {@code foo/libfoo.so}. The syntax for using this variable is: You can also reference a prebuilt library in another module by using the
-{@code LOCAL_PREBUILTS} variable. For more information about using prebuilts, see
-Using Prebuilt Libraries. The same as {@code PREBUILT_SHARED_LIBRARY}, but for a prebuilt static library. For more
-information about using prebuilts, see Using Prebuilt
-Libraries. The name of the target CPU architecture as the Android Open Source Project specifies it.
-For any ARM-compatible build, use {@code arm}, independent of the CPU architecture revision or
-ABI (see TARGET_ARCH_ABI, below). The value of this variable is taken from the APP_ABI variable that you define in the
-{@code Android.mk} file, which the system reads ahead of parsing the {@code Android.mk} file. The Android API level number for the build system to target.
-For example, the Android 5.1 system images correspond to Android API level 22: {@code android-22}.
-For a complete list of platform names and corresponding Android system
-images, see Android NDK Native APIs.
-The following example shows the syntax for using this variable: This variable stores the name of the CPU and architecture to target when the build system
-parses this {@code Android.mk} file. You can specify one or more of the following values, using
-a space as a delimiter between multiple targets. Table 1 shows the ABI setting to use for each
-supported CPU and architecture.
-
-
- Table 1. ABI settings for different CPUs and architectures. The following example shows how to set ARMv8 AArch64 as the target CPU-and-ABI combination: Note: Up to Android NDK 1.6_r1, this variable is defined as
-{@code arm}. For more details about architecture ABIs and associated compatibility
-issues, refer to
-ABI Management. New target ABIs in the future will have different values. A concatenation of target Android API level and ABI, it is especially useful when you want to test against
-a specific target system image for a real device. For example, to specify a 64-bit ARM device
-running on Android API level 22: Note: Up to Android NDK 1.6_r1, the default value was
-{@code android-3-arm}. The variables in this section describe your module to the build system. Each module description
-should follow this basic flow:
- This variable is used to give the path of the current file. You must define
-it at the start of your {@code Android.mk} file. The following example shows how to do so: The script to which {@code CLEAR_VARS} points does not clear this variable. Therefore, you only need
-to define it a single time, even if your {@code Android.mk} file describes multiple modules. This variable stores the name of your module. It must be unique among all module names,
-and must not contain any spaces. You must define it before including any scripts (other than
-the one for {@code CLEAR_VARS}). You need not add either the {@code lib} prefix
-or the {@code .so} or {@code .a} file extension; the build system makes these modifications
-automatically. Throughout your {@code Android.mk} and
-{@code Application.mk} files, refer to
-your module by its unmodified name. For example, the following line results in the generation of a
-shared library module called {@code libfoo.so}: If you want the generated module to have a name other than {@code lib} + the value of
-{@code LOCAL_MODULE}, you can use the {@code LOCAL_MODULE_FILENAME} variable to give the
-generated module a name of your own choosing, instead. This optional variable allows you to override the names that the build system
-uses by default for files that it generates. For example, if the name of your {@code LOCAL_MODULE}
-is {@code foo}, you can force the system to call the file it generates {@code libnewfoo}. The
-following example shows how to accomplish this: For a shared library module, this example would generate a file called {@code libnewfoo.so}. Note: You cannot override filepath or file extension. This variable contains the list of source files that the build system uses to generate the
-module. Only list the files that the build system actually passes to the compiler, since the build
-system automatically computes any associated depencies. Note that you can use both relative (to {@code LOCAL_PATH}) and absolute file paths.
-
- We recommend avoiding absolute file paths; relative paths make your {@code Android.mk} file more
-portable. Note: Always use Unix-style forward slashes (/) in build files.
-The build system does not handle Windows-style backslashes (\) properly. You can use this optional variable to indicate a file extension other than {@code .cpp} for your
-C++ source files. For example, the following line changes the extension to {@code .cxx}.
-(The setting must include the dot.)
-
- From NDK r7, you can use this variable to specify multiple extensions. For instance: You can use this optional variable to indicate that your code relies on specific C++ features.
-It enables the right compiler and linker flags during the build process. For prebuilt binaries,
-this variable also declares which features the binary depends on, thus helping ensure the final
-linking works correctly. We recommend that you use this variable instead of enabling
-{@code -frtti} and {@code -fexceptions} directly in your {@code LOCAL_CPPFLAGS} definition. Using this variable allows the build system to use the appropriate flags for each module. Using
-{@code LOCAL_CPPFLAGS} causes the compiler to use all specified flags for all modules, regardless
-of actual need.Download the Android NDK
- Release Notes
-
-
-
diff --git a/docs/html/ndk/downloads/revision_history.jd b/docs/html/ndk/downloads/revision_history.jd
deleted file mode 100644
index 211b64e5be4b2..0000000000000
--- a/docs/html/ndk/downloads/revision_history.jd
+++ /dev/null
@@ -1,3766 +0,0 @@
-page.title=NDK Revision History
-@jd:body
-
-
-
-
-ndk-build command will default to using
- Clang in an upcoming release. GCC will be removed in a later release.
- make-standalone-toolchain.sh script will be removed
- in an upcoming release. If you use this script, please plan to migrate to the
- make_standalone_toolchain.py as soon as possible.
-
-
-
-
- build/tools/make_standalone_toolchain.py. On Windows, you no longer
- need Cygwin to use this feature. Note that the bash flavor will be removed
- in an upcoming release, so please test the new one now.
- -fno-limit-debug-info
- option is enabled by default. This change enables better debugging with LLDB.
- --build-id as a default option. This option
- causes an identifier to be shown in native crash reports so you can easily
- identify which version of your code was running.
- NDK_USE_CYGPATH so that it no longer causes
- problems with libgcc
- (Issue 195486).
- -Wl,--warn-shared-textrel and -Wl,--fatal-warnings.
- If you have shared text relocations, your app does not load on Android 6.0
- (API level 23) and higher. Note that this configuration has never been
- allowed for 64-bit apps.
- INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED feature level or higher.
- For more information, see the
-
- CameraCharacteristics reference.
-
-
-
-__thread so that it works for real this time.
-
-
-
-libatomic to not use ifuncs (NDK Issue 31).
-
-
-
---long-plt to fix an internal linker error
- when linking huge arm32 binaries.
- AArch64. This problem was
- causing jump addresses to be calculated incorrectly for very large
- dynamic shared objects (DSOs).
- --no-apply-dynamic to work around
- a dynamic linker bug for earlier Android releases.
- dynamic_cast was not
- working with Clang, x86, stlport_static and optimization.
-
-
-
-ndk-gdb.py script.
-
-
-
-c++_shared does not work for ARM on
- Android 2.3 (API level 9) or Android 4.0 (API level 14).
- NdkCameraMetadataTags.h header file, the camera metadata
- tag enum value ACAMERA_STATISTICS_LENS_SHADING_CORRECTION_MAP
- was listed by accident and will be removed in next release. Use
- the ACAMERA_STATISTICS_LENS_SHADING_MAP value instead.
-
Android NDK, Revision 11c (March 2016)
-
-
-
-
-
-
-
-
Android NDK, Revision 11b (March 2016)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Android NDK, Revision 11 (March 2016)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Android NDK, Revision 10e (May 2015)
-
-
-
-
-
-
-
-
-
-
-
-
-
-in add_stores, at var-tracking.c:6000
-
-
-
-
-
-
-
-
-.../ld: warning: creating a DT_TEXTREL in a shared object
-
-
-
-
-
-
Android NDK, Revision 10d (December 2014)
-
-
-
- NDK_TOOLCHAIN_VERSION=4.6 to ndk-build, or
- add --toolchain=arm-linux-androideabi-4.6 when executing
- make-standalone-toolchain.sh on the command line. GCC 4.9 remains the
- default for 64-bit ABIs.-mstackrealign by default. The
- NDK toolchain assumes a 16-byte stack alignment. The tools and options used by default
- enforce this rule. A user writing assembly code must make sure to preserve stack
- alignment, and ensure that other compilers also comply with this rule.
- (GCC bug 38496)-fPIE -pie
- when building. In API levels 16 and higher, ndk-build uses PIE
- when building. This change has a number of implications, which are discussed in
-
- Developer Preview Issue 888.
- These implications do not apply to shared libraries.
-
-
-
-
-
- --fix-cortex-a53-835769, when
- -mfix-cortex-a53-835769 (enabled by default) is specified.
- For more information, see this
- binutils message
- and this
- binutils message.
- sscanf/vsscanf hang that occurred in API level
- 21. The fix itself had been implemented in r10c.
- (Issue 77988)-fauto-profile) crash that occurred with GCC 4.9 when
- -Os was specified. (Issue 77571)
-
-
-
-
- posix_memalign to API level 16. Also, added a prototype in
- stdlib.h to API levels 16 to 19.
- (Issue 77861)stdatomic.h so that it includes <atomic> only for
- C++11.sys/user.h, and
- gl2ext.h, dlext.h, fts.h, sgidefs.h
- for API level 21.sys/user.h to rename mxcsr_mask as mxcr_mask,
- and to change the data type for u_ar0unsigned long
- to struct user_regs_struct*.
- sysconf() return value type from int to
- long.thumb for LOCAL_ARM_MODE: In
- r10d, ndk-build adds LOCAL_LDFLAGS+=-mthumb by default, unless one of the
- following conditions applies:
-
-
- LOCAL_ARM_MODE equal to arm.APP_OPTIM=debug and
- AndroidManifest.xml containing android:debuggable="true"),
- where ARM mode is the default in order to retain compatibility with earlier toolchains.
- (Issue 74040)LOCAL_SRC_FILES in ndk-build to use Windows absolute paths.
- (Issue 74333)make-standalone-toolchain.sh.
- (Issue 74145)System.loadLibrary() transitive
- dependencies. (Issue 41790)LOCAL_PCH to improve Clang support. (Issue
- 77575)
Android NDK, Revision 10c (October 2014)
-
-
-
-
-
- Android-L to the official release
- designation: android-21.google branch
- of the GCC repository. Major differences from the upstream version of GCC 4.9 include:
-
-
- -O2 option now turns on vectorization, without loop peeling but with more
- aggressive unrolling.NDK_TOOLCHAIN_VERSION=clang
- now picks Clang 3.5. Note that:
-
-
- -fno-integrated-as as a workaround.
- -finline-functions
- option that GCC supports.-Wno-invalid-command-line-argument and -Wno-unused-command-line-argument
- to ignore the unused flags until you're able decide on what to do with them longer-term.art-on option. For more information,
- see prebuilt/common/gdb/common.setup in the directory containing the NDK.--icf option.arm_neon.h support in x86 and x86_64, attaining coverage of ~93% of
- NEON intrinsics. For more information about NEON support:
-
-
- docs/Programmers_Guide/html/), and see
- Architectures and CPUs > Neon.hello-neon sample in samples/.
- _FORTIFY_SOURCE in headers/libs/android-21,
- which appeared in r10 (when android-21 was still called Android-L),
- but had no documentation.
-
-
-
-
-
-internal compiler error: in simplify_const_unary_operation, at simplify-rtx.c:1539
-
- x = (cond) ? y : x.
- (Issue 77569)-mno-fix-cortex-a53-835769.
-
- android-21:
-
-
-
- android/keycodes.handroid/sensor.h:
- ASensorManager_getDefaultSensorEx, ASensor_getFifoMaxEventCount,
- ASensor_getFifoReservedEventCount, ASensor_getStringType,
- ASensor_getReportingMode, and ASensor_isWakeUpSensor.stdatomic.h to improve compatibility with GCC 4.6, and provide support
- for the <atomic> header.sys/ucontext.h and sys/user.h to all API levels. The
- signal.h header now includes <sys/ucontext.h>. You may
- remove any existing definition of struct ucontext.posix_memalign to API levels 17, 18, and 19.android_set_abort_message, posix_fadvise,
- posix_fadvise64, pthread_gettid_np.native-media/AndroidManifest.xml
- sample.
- (Issue 106640)clock_nanosleep and clock_settime to API level 21. (Issue
- 77372)
- get_malloc_leak_info, free_malloc_leak_info,
- __srget, __swbuf, __srefill, __swsetup,
- __sdidinit, __sflags, __sfp,
- __sinit, __smakebuf, __sflush, __sread,
- __swrite, __sseek, __sclose,
- _fwalk, __sglue, __get_thread, __wait4,
- __futex_wake, __open, __get_tls,
- __getdents64, and dlmalloc.basename_r,
- dirname_r, __isthreaded, _flush_cache (mips64).__signalfd4.size_t to int in
- the following functions: strtoll_l, strtoull_l,
- wcstoll_l, and wcstoull_l.arc4random,
- arc4random_buf, and arc4random_uniform.cxa_* and the new and delete operators back
- to libstdc++.so. This change restores r9d behavior; previous versions of r10
- contained dummy files.--toolchain= in make-standalone-toolchain.sh so that it
- now properly supports use of a suffix specifying a version of Clang.strtod() functions.docs/.
-
cpu-features to detect ARMv8 support for the following
- instruction sets: AES, CRC32, SHA2, SHA1, and 64-bit PMULL/PMULL2. (Issue
- 106360)*-gcc-ar, which is available in GCC 4.8, GCC 4.9, and
- Clang. Clang specifies it, instead of *-ar. This setting brings improved LTO
- support.include-fixed/linux/a.out.h and
- include-fixed/linux/compiler.h headers from the GCC compiler.
- (Issue 73728)-flto with GCC 4.8 on Mac OS X. The error message
- read:
-.../ld: error: .../libexec/gcc/arm-linux-androideabi/4.9/liblto_plugin.so
-Symbol not found: _environ
-
-
- build-binary.mk. (Issue
- 76992)
-
- -fauto-profile) in GCC4.9 may cause crashing.
- (Issue 77571)
Android NDK, Revision 10b (September 2014)
-
-
-
-
-
-
-
-
-
- stdio.h from the include-fixed/ directories of all versions of GCC. (Issue 73728.)platforms/android-L/arch-*/usr/include/linux/netfilter*/ directories. (Issue 73704.)docs/ and sources/third_party/googletest/README.NDK. (Issue 74069.)
-
- ctype.h and wchar.h: dn_expand(), grantpt(), inet_nsap_addr(), inet_nsap_ntoa(), insque(), nsdispatch(), posix_openpt(), __pthread_cleanup_pop(), __pthread_cleanup_push(), remque(), setfsgid(), setfsuid(), splice(), tee(), twalk() (Issue 73719), and 42 *_l() functions.cmsg_nxthdr to __cmsg_nxthdr.__libc_malloc_dispatch.ptrace() prototype to long ptrace(int, ...);.sha1.h.android_dlextinfo in android/dlext.h.__NDK_FPABI__ for functions receiving or returning float- or double-type values in stdlib.h, time.h, wchar.h, and complex.h.
-
mipsel-linux-android-4.9 and mips64el-linux-android-4.9, implementing a new multilib directory layout, and providing support for gdb-7.7cpu-features to detect more arm64 features. (Change list 100339.)
Android NDK, Revision 10 (July 2014)
-
-
-
-
- NDK_TOOLCHAIN_VERSION=clang
- may not work for arm64-v8a and mips64.all32 and all64
-settings for APP_ABI.
-
-
- APP_ABI=all32 is equivalent to
-APP_ABI=armeabi,armeabi-v7a,x86,mips.APP_ABI=all64 is equivalent to
-APP_ABI=arm64-v8a,x86_64,mips64.APP_ABI=all selects all ABIs.<tr1/cmath>
-Before defining your own math function, check _GLIBCXX_USE_C99_MATH_TR1 to see a
-function with that name already exists, in order to avoid "multiple definition" errors from the
-linker.platforms/android-L/ API directory. It includes:
-
- Android.h header for SLES/OpenSLES, enabling support for
-single-precision, floating-point audio format in AudioPlayer.libGLESv3.so.
-
- NDK_TOOLCHAIN_VERSION=4.9 to Application.mk, or exporting it as an
-environment variable from the command line.--toolchain= option in the
-make-standalone-toolchain.sh script. For example: --toolchain=arm-linux-androideabi-4.9.NDK_TOOLCHAIN_VERSION=4.8 or 4.9 to enable ndk-gdb to select GDB 7.6.-mssse3 build option to provide SSSE3 support, and made it the default for ABI x86
-(upgrading from SSE3). The image released by Google does not contain SSSE3 instructions.
-
- -fno-strict-aliasing if you use <list>, because __list_imp::_end_ breaks
- TBAA rules. (Issue 61571.)LOCAL_PCH. (Issue 25412).
-
-
-
-
-
- std::feof, etc. (Issue 66668).-O3 assert on:llvm-3.2/llvm/include/llvm/MDBuilder.h:64: llvm::MDNode*
-llvm::MDBuilder::createBranchWeights(llvm::ArrayRef (Issue 57381).
- Assertion failed: (!Fn && "cast failed but able to resolve overload expression!!"), function CheckCXXCStyleCast, file
-Volumes/data/ndk-toolchain/src/llvm-3.3/llvm/tools/clang/lib/Sema/SemaCast.cpp, line 2018.
-(Issue 66950).
-
-
-
-
- ssize_t to be int instead of long
-int.WCHAR_MIN and WCHAR_MAX so that they they take
-appropriate signs according to the architecture they're running on:
-
- -D__WCHAR_UNSIGNED__.wchar_t to be 16 bits, use -fshort-wchar.libc.so, and added pread64,
-pwrite64, ftruncate64 for
-Android API level 12 and higher. (Issue 69319). For more
-information, see the commit message accompanying AOSP change list
- 94137.putchar. Warning message reads:include/stdio.h:236:5: warning: conflicts with previous declaration here
-[-Wattributes] int putchar(int); (Change list 91185).
- make-standalone-toolchain.sh --stl=libc++ so that it:
-
- cxxabi.h. (Issue 68001).APP_PLATFORM
-environment variable.IsSystemLibrary() in crazy_linker so that it
-uses strrchr()
- instead of strchr() to find the library path's true basename.-Wl,-shared (as opposed to
--shared, which
- had no compilation issues). The problem was that Clang added -pie for Android
-targets if neither -shared nor -static existed. This behavior, which was
-incorrect, caused the linker to complain that -shared and -pie could not
-co-exist.
-
arm_neon.h to the x86 toolchain so that it now emulates ~47% of
-Neon. There is currently no support for 64-bit types. For more information, see the section on ARM
-Neon intrinsics support in the x86 documentation.$NDK/tests/build/b14811006-GOT_PREL-optimization/.--toolchain=x86_64-linux-android-4.9, which is equivalent to
---toolchain=x86_64-4.9.
Android NDK, Revision 9d (March 2014)
-
-
-
- NDK_TOOLCHAIN_VERSION=clang option now picks Clang 3.4. GCC 4.6 is
-still the default compiler.APP_ABI=armeabi-v7a-hard, with
-additional multilib option -mfloat-abi=hard. These options are for
-use with ARM GCC 4.6/4.8 and Clang 3.3/3.4 (which use 4.8's assembler, linker,
-and libs). When using these options, note the following changes:
-
- ndk-build script, add the
-following options for armeabi-v7a target:
-TARGET_CFLAGS += -mhard-float -D_NDK_MATH_NO_SOFTFP=1
-TARGET_LDFLAGS += -Wl,--no-warn-mismatch -lm_hard
-The built library is copied to libs/armeabi-v7a. For make to
-behave as expected, you cannot specify both armeabi-v7a and
-armeabi-v7a-hard as make targets (i.e., on the APP_ABI= line).
-Doing so causes one of them to be ignored. Note that APP_ABI=all
-is still equivalent to
-armeabi armeabi-v7a x86 mips.make-standalone-toolchain.sh script copies
-additional libaries under /hard directories.
- Add the above CFLAGS and LFLAGS to your
-makefile to enable GCC or Clang to link with
- libraries in /hard.LOCAL_ASMFLAGS
-and EXPORT_ASMFLAGS flags for x86
-targets. The ndk-build script uses
-prebuilts/*/bin/yasm* to build LOCAL_SRC_FILES that
-have the .asm extension.-gc-sections
-support.
-
- For more information, see
-APP_STL := c++_static or APP_STL :=
-c++_shared in Application.mk.
- You may rebuild from source via LIBCXX_FORCE_REBUILD :=
-truemake-standalone-toolchain.sh --stl=libc++
-to create a standalone toolchain with libc++ headers/lib.CPLUSPLUS-SUPPORT.html.
-(Issue 36496)
-
-
-
-
-
- zlib, bz2,
-_curses, _curses_panel, _hashlib,
-_sslzlib, nis,
-crypt, _curses, and _curses_panelevent_getmsg_helper.
-
-
-
-
-
#include <sys/types.h> in
-android/asset_manager.h for Android API level 13 and higher.
- (Issue 64988)#include in
-android/rect_manager.h for Android API level 14 and higher.JNICALL to JNI_OnLoad and
-JNI_OnUnload in jni.h. Note that JNICALL
- is defined as __NDK_FPABI__ For more information, see
-sys/cdefs.h.
-android/tts.h
-EGL/eglext.h
-fts.h
-GLES/glext.h
-GLES2/gl2ext.h
-OMXAL/OpenMAXSL_Android.h
-SLES/OpenSLES_Android.h
-sys/prctl.h
-sys/utime.h
-
- sys/cachectl.h for all architectures. MIPS
-developers can now include this header instead of writing #ifdef
-__mips__.platforms/android-18/include/android/input.h
- by adding __NDK_FPABI__ to functions taking or returning
-float or double values.struct stat, which was incorrectly set
-to its 64-bit counterpart for Android API level 12 and later. This wrong
-setting was a
-regression introduced in release r9c.__PTHREAD_MUTEX_INIT_VALUE,
-__PTHREAD_RECURSIVE_MUTEX_INIT_VALUE,
- and __PTHREAD_ERRORCHECK_MUTEX_INIT_VALUE for Android API
-level 9 and lower.scalbln, scalblnf, and
-scalblnl to x86 libm.so for APIs 18 and later.sources/android/support/include/iconv.h.
- (Issue 63806)std::unexpected() to call
-std::terminate() so that
- a user-defined std::terminate() handler has a chance to run.
-std::nullptr.
-
- SYSTEM_UI_FLAG_IMMERSIVE_STICKY. Screen rotation does not
-trigger onSystemUiVisibilityChange, and so does not restore
-immersive mode.ndk-build script to add
--rpath-link=$SYSROOT/usr/lib and
--rpath-link=$TARGET_OUT in order to use ld.bfd to
-link executables. (Issue 64266)-Bsymbolic from all STL builds.ndk-gdb-py.cmd by setting SHELL as
-an environment variable
-instead of passing it to
- python.exe, which ignores the setting.
- (Issue 63054)make-standalone-toolchain.sh script so that
-the --stl=stlport option copies the gabi++ headers instead of
-symlinking them; the cmd.exe and MinGW shells do not understand
-symlinks created by cygwin.
-
*cmd scripts
-previously intended for use only in the cmd.exe shell, in case
-developers prefer to use ndk-build.cmd in cygwin instead of the
-recommended ndk-build script.make-standalone-toolchain.sh
-script by moving instead of copying if the specified destination directory does
-not exist.
Android NDK, Revision 9c (December 2013)
-
-
-
-
- -fuse-ld=mcld, so that the following error no longer occurs:
-cc1: internal compiler error: in common_handle_option, at
-opts.c:1774
-mhard-float support for
-__builtin math functions. For ongoing information on fixes for
--mhard-float with STL, please follow Issue 61784.
-
-
-
- poll to poll(struct
-pollfd *, nfds_t, int); in poll.h.utimensat to libc.so for Android
-API levels 12 and 19. These libraries are now included for all Android API
-levels 12 through 19.futimens into libc.so, for Android API
-level 19.clock_settime() and
-clock_nanosleep() to time.h for Android API level 8
-and higher.CLOCK_MONOTONIC_RAW, CLOCK_REALTIME_COARSE,
-CLOCK_MONOTONIC_COARSE, CLOCK_BOOTTIME, CLOCK_REALTIME_ALARM, and
-CLOCK_BOOTTIME_ALARM in time.h.CLOCK_REALTIME_HR and
-CLOCK_MONOTONIC_HR.source/android/ndk_helper:
-
-
- Check_ReleaseStringUTFChars in
-/system/lib/libdvm.so that was causing crashes on x86 devices.ndk-build fails that happen in cygwin when the NDK
-package is
-referenced via symlink.ndk-build.cmd fails that happen in windows
-cmd.exe when
-LOCAL_SRC_FILES contains absolute paths. (Issue 69992)ndk-stack script to proceed even when it can't parse
-a frame due to inability to find a routine, filename, or line number. In any of
-these cases, it prints ??.ndk-stack stack for windows-x64_64 targets so that
-it no longer erroneously matches a frame line with a line in the
-stack: section that doesn't contain pc,
-eip, or ip. For example:
-I/DEBUG ( 1151): #00 5f09db68 401f01c4
-/system/lib/libc.so
-
-
-
- LOCAL_EXPORT_LDFLAGS.NDK_PROJECT_PATH=null setting for use in an
-integrated build system where options are explicitly passed to
-ndk-build. With this setting, ndk-build makes no
-attempt to look for NDK_PROJECT_PATH. This setting also prevents
-variables from deriving default settings from NDK_PROJECT_PATH. As a result,
-the following variables must now be explicitly specified (with their default
-values if such exist): NDK_OUT, NDK_LIBS_OUT, APP_BUILD_SCRIPT,
-NDK_DEBUG (optional, default to 0), and other APP_*'s
-contained in Application.mk.APP_ABI can now be enumerated in a comma-delimited list. For
-example:
-APP_ABI := "armeabi,armeabi-v7a"
android-ndk-r9c-cxx-stl-libs-with-debugging-info.zip, using the
--g option. This option
-helps the ndk-stack script provide better a stack dump across STL.
-This change should not affect the code/size of the final, stripped file.hello-jni samples to report APP_ABI at
-compilation.ar tool in Deterministic mode (option
--D) to build static libraries. (Issue 60705)
Android NDK, Revision 9b (October 2013)
-
-
-
-
- -mhard-float in the existing armeabi-v7a ABI. For more
- information and current restrictions on Clang, see
- {@code tests/device/hard-float/jni/Android.mk}.-fdiagnostics-color=auto,
- -fdiagnostics-color=always, or export {@code GCC_COLORS} as shown below:
-
-GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
-
- For more information, see
- GCC
- Language Independent Options.
-
-
- internal compiler error: verify_flow_info failed
- (Issue 58916,
- GCC Issue)
-external/icu4c/i18n/decimfmt.cpp:1322:1:
-internal compiler error: in dbx_reg_number, at dwarf2out.c:10185
-
- (GCC Patch)
-
-
-
-
-
- -integrated-as option so it can pass
- tests for {@code ssax-instructions} and {@code fenv}.CPU-ARCH-ABIS.html. For more information, see
- NDK-DEPENDS.html. (Issue 60142)
-
-
-LOCAL_CFLAGS += -fopenmp
-LOCAL_LDFLAGS += -fopenmp
-
- For code examples, see {@code tests/device/test-openmp}LOCAL_CONLYFLAGS and APP_CONLYFLAGS to specify
- options applicable to C only but not C++. The existing LOCAL_CFLAGS
- and APP_CFLAGS are also used for C++ compilation (to save trouble of
- specifying most options twice), so options such as -std=gnu99 may fail in
- g++ builds with a warning and clang++ builds with an error.-funwind-tables to allow the stack to be unwound past previously blocked
- points, such as __aeabi_idiv0.-mmxu
-option.-mldc1-sdc1 to control ldxc1/sdxc1 too
Android NDK, Revision 9 (July 2013)
-
-
-
-
-
-
-
- {@code --toolchain=arm-linux-androideabi-4.8}
-
- -O values when using Boost
- 1.52.0. (Issue 42891)
-
-
-
- clang: for the -arm-enable-ehabi option: may only occur zero or one times!
-
-
-
-
-
-
-
-
-
Android NDK, Revision 8e (March 2013)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Android NDK, Revision 8d (December 2012)
-
-
-
-
-
-
- --toolchain=arm-linux-androideabi-4.7
-
- For more information, see {@code CPLUSPLUS-SUPPORT.html}.
-
-
-
-
-dyld: lazy symbol binding failed: Symbol not found: _memmem
-Referenced from: ...../arm-linux-androideabi/bin/ld
-Expected in: /usr/lib/libSystem.B.dylib
- This problem was caused by building on Mac OS X 10.7, which produced binaries that were
- not compatible with Mac OS 10.6.x and the NDK.
-
-
-
-
-
-
-
Android NDK, Revision 8c (November 2012)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ./build/tools/make-release.sh --force --systems=linux-x86
-extern "C" {
- extern void *__dso_handle __attribute__((__visibility__ ("hidden")));
- void *__dso_handle;
-}
-
-
-
-
-
-
-
-<path>/arm-linux-androideabi/include/c++/4.6.x-google
- to:
-<path>/include/c++/4.6/
-
-
-
-static const struct {
- int32_t namesz; /* = 8, sizeof ("Android") */
- int32_t descsz; /* = 1 * sizeof(int32_t) */
- int32_t type; /* = 1, ABI_NOTETYPE */
- char name[sizeof "Android"]; /* = "Android" */
- int32_t android_api; /* = 3, 4, 5, 8, 9, 14 */
-}
-
-
Android NDK, Revision 8b (July 2012)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-LOCAL_DISABLE_NO_EXECUTE=true # disable "--noexecstack" and "-z noexecstack"
-DISABLE_RELRO=true # disable "-z relro" and "-z now"
-
-
-static const struct {
- int32_t namesz; /* = 4, sizeof ("GNU") */
- int32_t descsz; /* = 6 * sizeof(int32_t) */
- int32_t type; /* = 1 */
- char name[sizeof "GNU"]; /* = "GNU" */
- int32_t os; /* = 0 */
- int32_t major; /* = 2 */
- int32_t minor; /* = 6 */
- int32_t teeny; /* = 15 */
- int32_t os_variant; /* = 1 */
- int32_t android_api; /* = 3, 4, 5, 8, 9, 14 */
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Android NDK, Revision 8 (May 2012)
-
-
-
-
-
- APP_ABI := armeabi armeabi-v7a mips
-
- make-standalone-toolchain.sh. See
- {@code docs/STANDALONE-TOOLCHAIN.html} for more details.
-
-
-
-
-
Android NDK, Revision 7c (April 2012)
-
-
-
-
-
-
-
-
-
Android NDK, Revision 7b (February 2012)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Android NDK, Revision 7 (November 2011)
-
-
-
-
-
-
- <OMXAL/OpenMAXAL.h> and
- <OMXAL/OpenMAXAL_Android.h> headers allow applications targeting
- API level 14 to perform multimedia output directly from native code by using a new
- Android-specific buffer queue interface. For more details, see
- docs/openmaxal/index.html and http://www.khronos.org/openmax/.docs/opensles/index.html and
- http://www.khronos.org/opensles/.NDK_CCACHE environment variable to ccache (or the path to
- your ccache binary). When declared, the NDK build system automatically
- uses CCache when compiling any source file. For example:
-
-export NDK_CCACHE=ccache
-
- APP_ABI to all to indicate that
- you want to build your NDK modules for all the ABIs supported by your given NDK
- release. This means that either one of the following two lines in your
- Application.mk are equivalent with this release:
-
-APP_ABI := all
-APP_ABI := armeabi armeabi-v7a x86
-
-
- APP_ABI when calling
- ndk-build from the command-line, which is a quick way to check that your
- project builds for all supported ABIs without changing the project's
- Application.mk file. For example:
-ndk-build APP_ABI=all
-
- LOCAL_CPP_FEATURES variable in Android.mk that
- allows you to declare which C++ features (RTTI or Exceptions) your module uses. This
- ensures that the final linking works correctly if you have prebuilt modules that depend
- on these features. See docs/ANDROID-MK.html and
- docs/CPLUSPLUS-SUPPORT.html for more details.$NDK/ndk-build from your project path, the paths to the source,
- object, and binary files that are passed to the build commands are significantly
- shorter now, because they are passed relative to the current directory. This is useful
- when building projects with a lot of source files, to avoid limits on the maximum
- command line length supported by your host operating system. The behavior is unchanged
- if you invoke ndk-build from a sub-directory of your project tree, or if
- you define NDK_PROJECT_PATH to point to a specific directory.ndk-build.cmd script from the command line from your project path. The
- script takes exactly the same arguments as the original ndk-build script.
- The Windows NDK package comes with its own prebuilt binaries for GNU Make, Awk and other
- tools required by the build. You should not need to install anything else to get a
- working build system.
-
- ndk-gdb does not work on
- Windows, so you still need Cygwin to debug.
-
- libs/<abi>) if APP_MODULES is not defined in
- your Application.mk. For example, if a top-level module foo
- imports a module bar, then both libfoo.so and
- libbar.so are copied to the install location. Previously, only
- libfoo.so was copied, unless you listed bar in your
- APP_MODULES too. If you define APP_MODULES explicitly, the
- behavior is unchanged.ndk-gdb now works correctly for activities with multiple categories in
- their MAIN intent filters.foo imports static library bar that imports static
- library zoo, the libfoo.so will now be linked against both
- libbar.a and libzoo.a.
-
- docs/NATIVE-ACTIVITY.HTML: Fixed typo. The minimum API level should be
- 9, not 8 for native activities.docs/STABLE-APIS.html: Added missing documentation listing EGL as a
- supported stable API, starting from API level 9.download-toolchain-sources.sh: Updated to download the toolchain
- sources from android.googlesource.com,
- which is the new location for the AOSP servers.gabi++. More details about it
- are available in the updated docs/CPLUSPLUS-SUPPORT.html.gnustl_shared that corresponds
- to the shared library version of GNU libstdc++ v3 (GPLv3 license). See more info at
- docs/CPLUSPLUS-SUPPORT.htmlLOCAL_CPP_EXTENSION. For
- example, to compile both foo.cpp and bar.cxx as C++ sources,
- declare the following:
-
-LOCAL_CPP_EXTENSION := .cpp .cxx
-
- eglGetProcAddress() or glGetProcAddress(). The
- following list describes the newly supported extensions:
-
-
-
- GL_OES_vertex_array_objectGL_OES_EGL_image_externalGL_APPLE_texture_2D_limited_npotGL_EXT_blend_minmaxGL_EXT_discard_framebufferGL_EXT_multi_draw_arraysGL_EXT_read_format_bgraGL_EXT_texture_filter_anisotropicGL_EXT_texture_format_BGRA8888GL_EXT_texture_lod_biasGL_IMG_read_formatGL_IMG_texture_compression_pvrtcGL_IMG_texture_env_enhanced_fixed_functionGL_IMG_user_clip_planeGL_IMG_multisampled_render_to_textureGL_NV_fenceGL_QCOM_driver_controlGL_QCOM_extended_getGL_QCOM_extended_get2GL_QCOM_perfmon_global_modeGL_QCOM_writeonly_renderingGL_QCOM_tiled_rendering
-
- GL_OES_element_index_uintGL_OES_get_program_binaryGL_OES_mapbufferGL_OES_packed_depth_stencilGL_OES_texture_3DGL_OES_texture_floatGL_OES_texture_float_linearGL_OES_texture_half_float_linearGL_OES_texture_npotGL_OES_vertex_array_objectGL_OES_EGL_image_externalGL_AMD_program_binary_Z400GL_EXT_blend_minmaxGL_EXT_discard_framebufferGL_EXT_multi_draw_arraysGL_EXT_read_format_bgraGL_EXT_texture_format_BGRA8888GL_EXT_texture_compression_dxt1GL_IMG_program_binaryGL_IMG_read_formatGL_IMG_shader_binaryGL_IMG_texture_compression_pvrtcGL_IMG_multisampled_render_to_textureGL_NV_coverage_sampleGL_NV_depth_nonlinearGL_QCOM_extended_getGL_QCOM_extended_get2GL_QCOM_writeonly_renderingGL_QCOM_tiled_rendering
-
- EGL_ANDROID_recordableEGL_NV_system_time
Android NDK, Revision 6b (August 2011)
-
-
-
-
- APP_ABI="armeabi x86" is used for
- multi-architecture builds.atexit() usage in shared libraries with the x86standalone
- toolchain.make-standalone-toolchain.sh --arch=x86. It used to fail
- to copy the proper GNU libstdc++ binaries to the right location.__dso_handle symbol (ARM only).$(SYSROOT)/usr/include for x86 builds.
- See the bug for
- more information.ptrdiff_t and size_t in
- x86-specific systems when they are used with the x86 standalone toolchain.
Android NDK, Revision 6 (July 2011)
- CHANGES.HTML document included in the NDK package.
-
-
-
-
- docs/CPU-X86.html in the NDK package.
-
- APP_ABI definition in your Application.mk file to build
- for x86 platforms. For example, the following line instructs ndk-build
- to build your code for three distinct ABIs:APP_ABI := armeabi armeabi-v7a x86
-
- Android.mk files to build x86 machine code.--toolchain=x86-4.4.3
- option when calling make-standalone-toolchain.sh. See
- docs/STANDALONE-TOOLCHAIN.html for more details.
- ndk-stack tool lets you translate stack traces in
- logcat that are generated by native code. The tool translates
- instruction addresses into a readable format that contains things such
- as the function, source file, and line number corresponding to each stack frame.
- For more information and a usage example, see docs/NDK-STACK.html.
- arm-eabi-4.4.0, which had been deprecated since NDK r5, has been
- removed from the NDK distribution.
Android NDK, Revision 5c (June 2011)
-
-
-
-
- ndk-build: Fixed a rare bug that appeared when trying to perform parallel
- builds of debuggable projects.LOCAL_WHOLE_STATIC_LIBRARIES to work
- correctly with the new toolchain and added documentation for this in
- docs/ANDROID-MK.html.gnustl_static crashed when run on
- platform releases older than API level 8 (Android 2.2).ndk-gdb: Fixed a bug that caused a segmentation fault when debugging
-Android 3.0
- or newer devices.<android/input.h>: Two functions that were introduced in API level
- 9 (Android 2.3) were incorrect and are fixed. While this breaks the source API, the
- binary interface to the system is unchanged. The incorrect functions were missing a
- history_index parameter, and the correct definitions are shown below:
-
-float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event,
- size_t pointer_index,
- size_t history_index);
-
-float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event,
- size_t pointer_index,
- size_t history_index);
-
- pthread_rwlock_init).
-
- LOCAL_SRC_FILES. This was not the case previously because the files were
- grouped by source extensions instead.import-module fails, it now prints the list of directories that
- were searched. This is useful to check that the NDK_MODULE_PATH definition
- used by the build system is correct.import-module succeeds, it now prints the directory where the
- module was found to the log (visible with NDK_LOG=1).ndk-gdb: Better detection of adb shell failures and improved
- error messages.<pthread.h>: Fixed the definition of
- PTHREAD_RWLOCK_INITIALIZER for API level 9 (Android 2.3) and higher.LOCAL_ARM_NEON was set to
- true (typo in build/core/build-binary.mk)..s assembly files
- (.S files were okay).
Android NDK, Revision 5b (January 2011)
-
-
- ndk-build issues:
-
-
- cygpath -m
- from GNU Make for every source or object file, which caused problems
- with very large source trees. In case this doesn't work properly, define
-NDK_USE_CYGPATH=1 in your
- environment to use cygpath -m again.NDK_MODULE_PATH environment variable from
-working properly when
- it contained multiple directories separated with a colon. prebuilt-common.sh script contains fixes to check the compiler for 64-bit
- generated machine code, instead of relying on the host tag, which
- allows the 32-bit toolchain to rebuild properly on Snow Leopard. The toolchain rebuild scripts
-now also support
- using a 32-bit host toolchain.INET_ADDRSTRLEN was added to
-<netinet/in.h>.IN6_IS_ADDR_MC_NODELOCAL and
-IN6_IS_ADDR_MC_GLOBAL were added to <netinet/in6.h>.<asm/byteorder.h> to allow
-compilation with -std=c99.
Android NDK, Revision 5 (December 2010)
- CHANGES.HTML document included in the downloaded NDK
-package.
-
-
-
-
-
-
-
- .apk file../configure && make. See
- docs/STANDALONE-TOOLCHAIN.html for the details. The binaries for GCC 4.4.0 are still
-provided,
- but the 4.2.1 binaries were removed.cpufeatures helper library that improves
-reporting
- of the CPU type (some devices previously reported ARMv7 CPU when the device really was
-an ARMv6). We
- recommend developers that use this library to rebuild their applications then
- upload to Google Play to benefit from the improvements.native-plasma and
-native-activity,
- to demonstrate how to write a native activity.
Android NDK, Revision 4b (June 2010)
-
-
-
-
-
-
-
- ndk-build build
- command.ndk-gdb command.armeabi-v7a. The new ABI extends the existing armeabi ABI to
- include these CPU instruction set extensions:
-
-
-
- cpufeatures static library (with sources) that lets your
- app detect the host device's CPU features at runtime. Specifically, applications can
- check for ARMv7-A support, as well as VFPv3-D32 and NEON support, then provide separate
- code paths as needed.hello-neon, that illustrates how to use the
- cpufeatures library to check CPU features and then provide an optimized
- code path using NEON instrinsics, if supported by the CPU..apk.
Android NDK, Revision 3 (March 2010)
-
-
-
-
- hello-gl2, that illustrates the use of
- OpenGL ES 2.0 vertex and fragment shaders.
Android NDK, Revision 2 (September 2009)
-
-
-
-
- san-angeles, that renders 3D graphics
- through the native OpenGL ES APIs, while managing activity lifecycle with a {@link
- android.opengl.GLSurfaceView} object.
Android NDK, Revision 1 (June 2009)
-
-
-
-
- On this page
-
-
-
-
-
-Supported ABIs
-
-
-
-
-
-
-
-ABI
-Supported Instruction Set(s)
-Notes
-
-
-
-{@code armeabi}
-
-No hard float.
-
-
-
-{@code armeabi-v7a}
-
-
-Incompatible with ARMv5, v6 devices.
-
-
-
-{@code arm64-v8a}
-
-
-
-
-
-{@code x86}
-
-No support for MOVBE or SSE4.
-
-
-
-{@code x86_64}
-
-
-
-
-
-{@code mips}
-
-Uses hard-float, and assumes a CPU:FPU clock ratio of 2:1 for maximum
-compatibility. Provides neither micromips nor MIPS16.
-
-
-{@code mips64}
-
-
-armeabi
-
-
-
-LOCAL_ARM_MODE variable in your
-{@code Android.mk}
-file.armeabi-v7a
-
-
-
-arm64-v8a
-x86
-
-
-
-
--march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32
-
-
-
-
-
-
-
-x86_64
-
--march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel
-
-
-
-
-
-
-
-
-mips
-
-
-
-
-
-
-mips64
-Generating Code for a Specific ABI
-
-APP_ABI := armeabi-v7a
-
-
-
-APP_ABI := armeabi armeabi-v7a
-
-
-ABI Management on the Android Platform
-Native code in app packages
-
-/lib/<abi>/lib<name>.so
-
-
-dlopen().
-/lib/armeabi/libfoo.so
-/lib/armeabi-v7a/libfoo.so
-/lib/arm64-v8a/libfoo.so
-/lib/x86/libfoo.so
-/lib/x86_64/libfoo.so
-/lib/mips/libfoo.so
-/lib/mips64/libfoo.so
-
-
-Android Platform ABI support
-
-
-
-Automatic extraction of native code at install time
-
-
-lib/<primary-abi>/lib<name>.so
-
-
-
-lib/<secondary-abi>/lib<name>.so
-
-
-/lib/lib<name>.so, under the application's
-{@code data} directory ({@code data/data/On this page
-
-
- Overview
-Basics
-
-LOCAL_PATH := $(call my-dir)
-
-
-
-include $(CLEAR_VARS)
-
-
-
-LOCAL_MODULE := hello-jni
-
-
-
-LOCAL_SRC_FILES := hello-jni.c
-
-
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-Variables and Macros
-
-
-NDK-defined variables
-CLEAR_VARS
-
-include $(CLEAR_VARS)
-
-
-BUILD_SHARED_LIBRARY
-
-include $(BUILD_SHARED_LIBRARY)
-
-
-BUILD_STATIC_LIBRARY
-
-include $(BUILD_STATIC_LIBRARY)
-
-
-PREBUILT_SHARED_LIBRARY
-
-include $(PREBUILT_SHARED_LIBRARY)
-
-
-PREBUILT_STATIC_LIBRARY
-TARGET_ARCH
-TARGET_PLATFORM
-
-TARGET_PLATFORM := android-22
-
-
-TARGET_ARCH_ABI
-
-
-
-
-
- CPU and architecture
- Setting
-
-
- ARMv5TE
- {@code armeabi}
-
-
- ARMv7
- {@code armeabi-v7a}
-
-
- ARMv8 AArch64
- {@code arm64-v8a}
-
-
- i686
- {@code x86}
-
-
- x86-64
- {@code x86_64}
-
-
- mips32 (r1)
- {@code mips}
-
-
- mips64 (r6)
- {@code mips64}
-
-
-All
- {@code all}
-
-TARGET_ARCH_ABI := arm64-v8a
-
-
-TARGET_ABI
-
-TARGET_ABI := android-22-arm64-v8a
-
-
-Module-Description Variables
-
-
-
-
-
-LOCAL_PATH
-
-LOCAL_PATH := $(call my-dir)
-
-
-LOCAL_MODULE
-
-LOCAL_MODULE := "foo"
-
-
-LOCAL_MODULE_FILENAME
-
-LOCAL_MODULE := foo
-LOCAL_MODULE_FILENAME := libnewfoo
-
-
-LOCAL_SRC_FILES
-LOCAL_CPP_EXTENSION
-
-LOCAL_CPP_EXTENSION := .cxx
-
-
-
-LOCAL_CPP_EXTENSION := .cxx .cpp .cc
-
-
-LOCAL_CPP_FEATURES
-
-
-LOCAL_CPP_FEATURES := rtti -- -
To indicate that your code uses C++ exceptions, write:
- --LOCAL_CPP_FEATURES := exceptions -- -
You can also specify multiple values for this variable. For example:
- --LOCAL_CPP_FEATURES := rtti features -- -The order in which you describe the values does not matter. - - -
You can use this optional variable to specify a list of paths, relative to the -NDK {@code root} directory, to add to the include search path when compiling all sources -(C, C++ and Assembly). For example:
- --LOCAL_C_INCLUDES := sources/foo -- -
Or even:
- --LOCAL_C_INCLUDES := $(LOCAL_PATH)/- -/foo -
Define this variable before setting any corresponding inclusion flags via {@code LOCAL_CFLAGS} -or {@code LOCAL_CPPFLAGS}.
- -The build system also uses {@code LOCAL_C_INCLUDES} paths automatically when launching native -debugging with ndk-gdb.
- - -This optional variable sets compiler flags for the build system to pass when building C -and C++ source files. The ability to do so can be useful for specifying additional macro -definitions or compile options.
- -Try not to change the optimization/debugging level in your {@code Android.mk} file. -The build system can handle this setting automatically for you, using the relevant information -in the {@code Application.mk} file. Doing it -this way allows the build system to generate useful data files used during debugging.
- -Note: In android-ndk-1.5_r1, the corresponding flags only applied -to C source files, not C++ ones. They now match the full Android build system behavior. -(You can now use {@code LOCAL_CPPFLAGS} to specify flags for C++ sources only.)
- -It is possible to specify additional include paths by writing: - -
-LOCAL_CFLAGS += -I<path>, -- -It is better, however, to use {@code LOCAL_C_INCLUDES} for this purpose, since -doing so also makes it possible to use the paths available for native debugging with ndk-gdb. - - -
An optional set of compiler flags that will be passed when building C++ -source files only. They will appear after the LOCAL_CFLAGS on the -compiler's command-line.
- - -Note: In android-ndk-1.5_r1, the corresponding flags applied to -both C and C++ sources. This has been corrected to match the full Android build system. -To specify flags for both C and C++ sources, use {@code LOCAL_CFLAGS}.
- - -This variable stores the list of static libraries modules on which the current module depends.
- -If the current module is a shared library or an executable, this variable will force -these libraries to be linked into the resulting binary.
- -If the current module is a static library, this variable simply indicates that other -modules depending on the current one will also depend on the listed -libraries.
- -This variable is the list of shared libraries modules on which this module depends at -runtime. This information is necessary at link time, and to embed the corresponding information -in the generated file.
- -This variable is a variant of {@code LOCAL_STATIC_LIBRARIES}, and expresses that the linker -should treat the associated library modules as whole archives. For more information -on whole archives, see the GNU linker's -documentation for the -{@code --whole-archive} flag.
- -This variable is useful when there are circular dependencies among -several static libraries. When you use this variable to build a shared library, it will force -the build system to add all object files from your static libraries to the final binary. The same -is not true, however, when generating executables.
- - -This variable contains the list of additional linker flags for use in building your shared -library or executable. It enables you to use the {@code -l} prefix to pass the name of specific -system libraries. For example, the following example tells the linker to generate a module that -links to {@code /system/lib/libz.so} at load time:
- --LOCAL_LDLIBS := -lz -- -
For the list of exposed system libraries against which you can link in this NDK release, see -Android NDK Native APIs.
- -Note: If you define this variable for a static library, -the build system ignores it, and {@code ndk-build} prints a warning.
- -The list of other linker flags for the build system to use when building your shared library -or executable. For example, the following example uses the {@code ld.bfd} linker on ARM/X86 GCC -4.6+, on which {@code ld.gold} is the default
- --LOCAL_LDFLAGS += -fuse-ld=bfd -- -
Note: If you define this variable for a static library, the build -system ignores it, and ndk-build prints a warning.
- -By default, when the build system encounters an undefined reference encountered while trying to -build a shared, it will throw an undefined symbol error. This error can help you catch -catch bugs in your source code.
- -To disable this check, set this variable to {@code true}. Note that this setting may cause the -shared library to load at runtime.
- -Note: If you define this variable for a static library, -the build system ignores it, and ndk-build prints a warning.
- -By default, the build system generates ARM target binaries in thumb mode, where each -instruction is 16 bits wide and linked with the STL libraries in the {@code thumb/} directory. -Defining this variable as {@code arm} forces the build system to generate the module's object -files in 32-bit {@code arm} mode. The following example shows how to do this:
- --LOCAL_ARM_MODE := arm -- -
You can also instruct the build system to only build specific sources in {@code arm} mode by -appending {@code .arm} suffix to the the source filenames. For example, the following example -tells the build system to always compile {@code bar.c} in ARM mode, but to build -{@code foo.c} according to the value of {@code LOCAL_ARM_MODE}.
- --LOCAL_SRC_FILES := foo.c bar.c.arm -- - - -
Note: You can also force the build system to generate ARM binaries -by setting {@code APP_OPTIM} in your -{@code Application.mk} file to {@code debug}. -Specifying {@code debug} forces an ARM build because the toolchain debugger does not handle Thumb -code properly.
- - -This variable only matters when you are targeting the {@code armeabi-v7a} ABI. It allows the -use of ARM Advanced SIMD (NEON) GCC intrinsics in your C and C++ sources, as well as NEON -instructions in Assembly files.
- -Note that not all ARMv7-based CPUs support the NEON instruction set extensions. For this reason, -you must perform runtime detection to be able to safely use this code at runtime. For more -information, see NEON Support and The {@code cpufeatures} Library.
- -Alternatively, you can use the {@code .neon} suffix to specify that the build system only -compile specific source files with NEON support. In the following example, the build system compiles -{@code foo.c} with thumb and neon support, {@code bar.c} with thumb support, and -{@code zoo.c} with support for ARM and NEON:
- --LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon -- - -
If you use both suffixes, {@code .arm} must precede {@code .neon}.
- -Android NDK r4 added support for the "NX bit" security feature. It is -enabled by default, but you can disable it by setting this variable to {@code true}. We do not -recommend doing so without a compelling reason.
- -This feature does not modify the ABI, and is only enabled on kernels -targeting ARMv6+ CPU devices. Machine code with this feature enabled -will run unmodified on devices running earlier CPU architectures.
-For more information, see Wikipedia: NX bit -and The GNU stack kickstart. - -
By default, the NDK compiles code with read-only relocations and GOT -protection. This variable instructs the runtime linker to mark certain regions of memory -as read-only after relocation, making certain security exploits (such as GOT overwrites) -more difficult. Note that these protections are only effective on Android API level 16 and higher. -On lower API levels, the code will still run, but without memory protections.
- -This variable is turned on by default, but you can disable it by setting its value to -{@code true}. We do not recommend doing so without a compelling reason.
- -For more information, see -RELRO: -RELocation Read-Only and Security -enhancements in RedHat Enterprise Linux (section 6).
- -By default, the build system compiles code with format string protection. Doing so forces a -compiler error if a non-constant format string is used in a {@code printf}-style function.
-This protection is on by default, but you can disable it by setting the value of -this variable to {@code true}. We do not recommend doing so without a compelling reason.
- - -This variable records a set of C/C++ compiler flags to add to the {@code LOCAL_CFLAGS} definition -of any other module that uses this one via the {@code LOCAL_STATIC_LIBRARIES} or -{@code LOCAL_SHARED_LIBRARIES} variables.
- -For example, consider the following pair of modules: {@code foo} and {@code bar}, which depends -on {@code foo}:
- --include $(CLEAR_VARS) -LOCAL_MODULE := foo -LOCAL_SRC_FILES := foo/foo.c -LOCAL_EXPORT_CFLAGS := -DFOO=1 -include $(BUILD_STATIC_LIBRARY) - - -include $(CLEAR_VARS) -LOCAL_MODULE := bar -LOCAL_SRC_FILES := bar.c -LOCAL_CFLAGS := -DBAR=2 -LOCAL_STATIC_LIBRARIES := foo -include $(BUILD_SHARED_LIBRARY) -- -
Here, the build system passes the flags {@code -DFOO=1} and {@code -DBAR=2} to the compiler when -building {@code bar.c}. It also prepends exported flags to your your module's {@code LOCAL_CFLAGS} -so you can easily override them.
- -In addition, the relationship among modules is transitive: If {@code zoo} depends on -{@code bar}, which in turn depends on {@code foo}, then {@code zoo} also inherits all flags -exported from {@code foo}. - -Finally, the build system does not use exported flags when building locally (i.e., building the -module whose flags it is exporting). Thus, in the example above, it does not pass {@code -DFOO=1} -to the compiler when building {@code foo/foo.c}. To build locally, use {@code LOCAL_CFLAGS} -instead.
- -This variable is the same as {@code LOCAL_EXPORT_CFLAGS}, but for C++ flags only.
- -This variable is the same as {@code LOCAL_EXPORT_CFLAGS}, but for C include paths. It is useful -in cases where, for example, {@code bar.c} needs to include headers from module {@code foo}.
- -This variable is the same as {@code LOCAL_EXPORT_CFLAGS}, but for linker flags.
- -This variable is the same as {@code LOCAL_EXPORT_CFLAGS}, telling the build system to pass names -of specific system libraries to the compiler. Prepend {@code -l} to the name of each library you -specify.
- -Note that the build system appends imported linker flags to the value of your module's -{@code LOCAL_LDLIBS} variable. It does this due to the way Unix linkers work.
- -This variable is typically useful when module {@code foo} is a static library -and has code that depends on a system library. You can then use {@code LOCAL_EXPORT_LDLIBS} to -to export the dependency. For example:
- --include $(CLEAR_VARS) -LOCAL_MODULE := foo -LOCAL_SRC_FILES := foo/foo.c -LOCAL_EXPORT_LDLIBS := -llog -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := bar -LOCAL_SRC_FILES := bar.c -LOCAL_STATIC_LIBRARIES := foo -include $(BUILD_SHARED_LIBRARY) -- -
In this example, the build system puts {@code -llog} at the end of the linker command when it -builds {@code libbar.so}. Doing so tells the linker that, because {@code libbar.so} depends -on {@code foo}, it also depends on the system logging library.
- -Set this variable to {@code true} when your module has a very high -number of sources and/or dependent static or shared libraries. Doing so forces the -build system to use {@code @} syntax for archives containing intermediate object files -or linking libraries.
- -This feature can be useful on Windows, where the command line accepts a maximum of only -of 8191 characters, which can be too small for complex projects. It also impacts the compilation of -individual source files, placing nearly all compiler flags inside list files, too.
- -Note that any value other than {@code true} will revert to the -default behaviour. You can also define {@code APP_SHORT_COMMANDS} in your -{@code Application.mk} file to force this -behavior for all modules in your project.
- -We do not recommend enabling this feature by default, since it makes the build slower.
- - -Set this variable to {@code true} when building static libraries. -Doing so will generate a thin archive, a library file that does not contain -object files, but instead just file paths to the actual objects that it would normally -contain.
-This is useful to reduce the size of your build output. The drawback is that -such libraries cannot be moved to a different location (all paths -inside them are relative).
-Valid values are {@code true}, {@code false} or empty. A -default value can be set in your -{@code Application.mk} file through the {@code APP_THIN_ARCHIVE} - -variable.
-Note: This is ignored for non-static library modules, or prebuilt -static library ones.
- -Define this variable as a shell command that the build system will use to filter the -assembly files extracted or generated from the files you specified for {@code LOCAL_SRC_FILES}.
-Defining this variable causes the following things to occur:
- -For example:
- --LOCAL_SRC_FILES := foo.c bar.S -LOCAL_FILTER_ASM := - -foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o -bar.S --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o -- -
"1" corresponds to the compiler, "2" to the filter, and "3" to the assembler. The filter must -be a standalone shell command that takes the name of the input file as its first argument, and the -name of the output file as the second one. For example:
- --myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S -myasmfilter bar.S $OBJS_DIR/bar.S -- -
This section explains GNU Make function macros that the NDK provides. Use
-{@code $(call
This macro returns the path of the last included makefile, which typically is the -current {@code Android.mk}'s directory. {@code my-dir} is useful for defining -{@code LOCAL_PATH} at the start of your {@code Android.mk} file. For example:
- --LOCAL_PATH := $(call my-dir) -- -
Due to the way GNU Make works, what this macro really returns is the -path of the last makefile that the build system included when parsing the build scripts. For this -reason, you should not call {@code my-dir} after including another file.
- -For example, consider the following example:
- --LOCAL_PATH := $(call my-dir) - -# ... declare one module - -include $(LOCAL_PATH)/foo/`Android.mk` - -LOCAL_PATH := $(call my-dir) - -# ... declare another module -- -
The problem here is that the second call to {@code my-dir} defines -{@code LOCAL_PATH} as {@code $PATH/foo} instead of {@code $PATH}, because that was where its -most recent include pointed.
- -You can avoid this problem by putting additional includes after everything -else in the {@code Android.mk} file. For example:
- --LOCAL_PATH := $(call my-dir) - -# ... declare one module - -LOCAL_PATH := $(call my-dir) - -# ... declare another module - -# extra includes at the end of the Android.mk file -include $(LOCAL_PATH)/foo/Android.mk - -- -
If it is not feasible to structure the file in this way, save the value of the first -{@code my-dir} call into another variable. For example:
- --MY_LOCAL_PATH := $(call my-dir) - -LOCAL_PATH := $(MY_LOCAL_PATH) - -# ... declare one module - -include $(LOCAL_PATH)/foo/`Android.mk` - -LOCAL_PATH := $(MY_LOCAL_PATH) - -# ... declare another module -- -
Returns the list of {@code Android.mk} files located in all subdirectories of -the current {@code my-dir} path. - -
You can use this function to provide deep-nested source directory hierarchies to the build -system. By default, the NDK only looks for files in the directory containing the -{@code Android.mk} file.
- -Returns the path of the current makefile (from which the build system called the function).
- -Returns the path of the parent makefile in the inclusion tree (the path of the makefile that -included the current one).
- -Returns the path of the grandparent makefile in the inclusion tree (the path of the makefile that -included the current one).
- -A function that allows you to find and include a module's {@code Android.mk} file by the name of -the module. A typical example is as follows:
- --$(call import-module,<name>) -- -
In this example, the build system looks for the module tagged {@code
This document explains the {@code Application.mk} build file, which describes the -native modules that your app requires. A module can be a static library, a shared library, -or an executable.
- -We recommend that you read the Concepts and -Android.mk pages before this one. Doing so will -help maximize your understanding of the material on this page.
- --$NDK/apps/<myapp>/Application.mk -- -
Here, {@code
This variable stores the absolute path to your app's project-root directory. The build system -uses this information to place stripped-down versions of the generated JNI shared libraries -into a specific location known to the APK-generating tools.
- -If you place your {@code Application.mk} file under {@code $NDK/apps/ Define this optional variable as either {@code release} or {@code debug}. You use it to
-alter the optimization level when building your application's modules. Release mode is the default, and generates highly optimized binaries. Debug mode generates
-unoptimized binaries that are much easier to debug. Note that you can debug either release or debug binaries. Release binaries, however, provide less
-information during debugging. For example, the build system optimizes out some variables,
-preventing you from inspecting them. Also, code re-ordering can make it more difficult to step
-through the code; stack traces may not be reliable. Declaring {@code android:debuggable} in your application manifest's {@code This variable stores a set of C compiler flags that the build system passes to the compiler
-when compiling any C or C++ source code for any of the modules. You can use this variable to change
-the build of a given module according to the application that needs it, instead of having to modify
-the {@code Android.mk} file itself. All paths in these flags should be relative to the top-level NDK directory. For example, if you
-have the following setup: To specify in {@code foo/Android.mk} that you want to add the path to the {@code bar} sources
-during compilation, you should use:
-
- Or, alternatively: {@code -I../bar} will not work since it is equivalent to
-{@code -I$NDK_ROOT/../bar}. Note: This variable only works on C, not C++, sources in
-android-ndk-1.5_r1. In all versions after that one, {@code APP_CFLAGS} matches the full Android
-build system. This variable contains a set of C++ compiler flags that the build system passes to the compiler
-when building only C++ sources. Note: In android-ndk-1.5_r1, this variable works on both C and
-C++ sources. In all subsequent versions of the NDK, {@code APP_CPPFLAGS} now matches the full
-Android build system. For flags that apply to both C and C++ sources, use {@code APP_CFLAGS}. A set of linker flags that the build system passes when linking the application. This variable
-is only relevant when the build system is building shared libraries and executables. When the
-build system builds static libraries, it ignores these flags. By default, the NDK build system looks under {@code jni/} for a file named
-{@code Android.mk}. If you want to override this behavior, you can define {@code APP_BUILD_SCRIPT} to point to an
-alternate build script. The build system always interprets a non-absolute path as relative to the
-NDK's top-level directory. By default, the NDK build system generates machine code for the
-{@code armeabi} ABI. This machine code
-corresponds to an ARMv5TE-based CPU with software floating point operations. You can use
-{@code APP_ABI} to select a different ABI. Table 1 shows the {@code APP_ABI}
-settings for different instruction sets.
- Table 1. {@code APP_ABI} settings for different instruction sets. Note: {@code all} is available starting from NDKr7. You can also specify multiple values by placing them on the same line, delimited by spaces.
-For example: For the list of all supported ABIs and details about their usage and limitations, refer to
-ABI Management. This variable contains the name of the target Android platform. For example, {@code android-3}
-specifies the Android 1.5 system images. For a complete list of platform names and corresponding
-Android system images, see Android NDK Native APIs
-. By default, the NDK build system provides C++ headers for the minimal C++ runtime library
-({@code system/lib/libstdc++.so}) provided by the Android system. In addition, it comes with
-alternative C++ implementations that you can use or link to in your own applications.
-Use {@code APP_STL} to select one of them. For information about the supported runtimes, and the
-features they offer, see NDK Runtimes and
-Features.
-
- The equivalent of {@code LOCAL_SHORT_COMMANDS} in {@code Application.mk} for your whole project.
-For more information, see the documentation for this variable on
-{@code Android.mk}. Define this variable as either {@code 4.9} or {@code 4.8} to select a version of the GCC
-compiler. Version 4.9 is the default for 64-bit ABIs, and 4.8 is the default for 32-bit ABIs.
-To select a version of Clang, define this variable as {@code clang3.4}, {@code clang3.5}, or
-{@code clang}. Specifying {@code clang} chooses the most recent version of Clang. Starting from Android 4.1 (API level 16), Android's dynamic linker supports position-independent
-executables (PIE). From Android 5.0 (API level 21), executables require PIE.
-
-To use PIE to build your executables, set the {@code -fPIE} flag. This flag makes it harder to
-exploit memory corruption bugs by randomizing code location. By default, {@code ndk-build}
-automatically sets this value to {@code true} if your project targets {@code android-16} or higher.
-You may set it manually to either {@code true} or {@code false}. This flag applies only to executables. It has no effect when building shared or static
-libraries. Note: PIE executables cannot run on Android releases prior to 4.1.
- This restriction only applies to executables. It has no effect when building shared or static
-libraries. Sets the default value of {@code LOCAL_THIN_ARCHIVE} in the {@code Android.mk} file for all
-static library modules in this project. For more information, see the documentation for
-{@code LOCAL_THIN_ARCHIVE} on {@code Android.mk}.
- When you're working with native code, hardware matters. The NDK lets you ensure you're compiling
-for the right architectures and CPUs by giving you a variety of ABIs from which
-to choose. This section begins by explaining how to target specific
-architectures and CPUs. It then
-provides information you need to know when targeting the
-ARM
-family of CPUs and architectures. Next, it provides information about the other CPUs and
-architectures that it supports: NEON, x86
-(32-bit and
-64-bit), and
-MIPS. Finally, it explains how to use the
-{@code cpufeatures}
-library, which your app can use to query a given CPU and architecture about the optional
-features they support. Google I/O 2013 - High Performance Audio
-The Khronos Group's OpenSL ES™ standard exposes audio features
-similar to those in the {@link android.media.MediaPlayer} and {@link android.media.MediaRecorder}
-APIs in the Android Java framework. OpenSL ES provides a C language interface as well as
-C++ bindings, allowing you to call it from code written in either language.
-
-This page describes the typical use cases for these high-performance audio APIs, how to add them
-into your app's source code, and how to incorporate them into the build process.
-
-The OpenSL ES APIs are available to help you develop and improve your app's audio performance.
- Some typical use cases include the following:
-You can call OpenSL ES from both C and C++ code. To add the core OpenSL ES
-feature set to your app, include the {@code OpenSLES.h} header file:
-
-
-To add the OpenSL ES
-Android extensions as well, include the {@code OpenSLES_Android.h} header file:
-
-When you include the {@code OpenSLES_Android.h} header file, the following headers are included
-automatically:
- Note:
-These headers are not required, but are shown as an aid in learning the API.
-
-You can incorporate OpenSL ES into your build by specifying it in the
-{@code Android.mk} file that serves as one of the
-NDK build system's makefiles. Add the following line to
-{@code Android.mk}:
-
-For robust debugging, we recommend that you examine the {@code SLresult} value that most of
-the OpenSL ES APIs return. You can use
-asserts
-or more advanced error-handling logic for debugging; neither offers
-an inherent advantage for working with OpenSL ES, although one or the other might be more suitable
-for a given use case.
-
-We use asserts in our
-examples, because they help catch unrealistic conditions that would indicate a coding error. We
-have used explicit error handling for other conditions more likely to occur in production.
-
-Many API errors result in a log entry, in addition to a non-zero result code. Such log entries
-can provide additional detail that proves especially useful for relatively complex APIs such as
-
-{@code Engine::CreateAudioPlayer}.
-
-You can view the log either from the command line or from Android Studio. To examine the log from
-the command line, type the following:
-
-To examine the log from Android Studio, either click the Logcat tab in the
-Debug
-window, or click the Devices | logcat tab in the
-Android DDMS
-window.
- Constantly outputting audio incurs significant power consumption. Ensure that you stop the
- output in the
- onPause() method.
- Also consider pausing the silent output after some period of user inactivity.
-
-Supported and tested example code that you can use as a model for your own code resides both locally
-and on
-
-GitHub. The local examples are located in
-{@code platforms/android-9/samples/native-audio/}, under your NDK root installation directory.
-On GitHub, they are available from the
-{@code android-ndk}
-repository, in the
-
-{@code audio-echo} and
-
-{@code native-audio} directories.
- The Android NDK implementation of OpenSL ES differs
-from the reference specification for OpenSL ES 1.0.1 in a number of respects.
-These differences are an important reason as to why sample code that
-you copy directly from the OpenSL ES reference specification may not work in your
-Android app.
-
-For more information on differences between the reference specification and the
-Android implementation, see
-
-OpenSL ES for Android.
diff --git a/docs/html/ndk/guides/audio/floating-point.jd b/docs/html/ndk/guides/audio/floating-point.jd
deleted file mode 100644
index 76efce3f60e13..0000000000000
--- a/docs/html/ndk/guides/audio/floating-point.jd
+++ /dev/null
@@ -1,101 +0,0 @@
-page.title=Floating-Point Audio
-@jd:body
-
- Will it Float? The Glory and Shame of Floating-Point Audio Using floating-point numbers to represent audio data can significantly enhance audio
- quality in high-performance audio applications. Floating point offers the following
- advantages: While floating-point can enhance audio quality, it does present certain disadvantages:
- Formerly, floating-point was notorious for being unavailable or slow. This is
- still true for low-end and embedded processors. But processors on modern
- mobile devices now have hardware floating-point with performance that is
- similar (or in some cases even faster) than integer. Modern CPUs also support
- SIMD
- (Single instruction, multiple data), which can improve performance further.
- The following best practices help you avoid problems with floating-point calculations: For floating-point audio, the audio format encoding
- The following Wikipedia pages are helpful in understanding floating-point audio: The following article provides information on those aspects of floating-point that have a
- direct impact on designers of computer systems: The NDK package includes an Android-specific implementation of the
-OpenSL ES™ API
-specification from the Khronos Group.
-This library allows you to use C or C++ to implement high-performance, low-latency audio, whether
-you are writing a synthesizer, digital audio workstation, karaoke, game,
- or other real-time app. This section begins by providing some
-basic information about the API, including
-typical use cases and how to incorporate it into your app. It then explains what you need to know
-about the Android-specific
-implementation of OpenSL ES, focusing on the differences between this implementation and the
-reference specification. Next, you'll learn how to minimze
- input latency
- when using built-in or external microphones
-and some actions that you can take to minimize
- output latency.
- It describes the reasons that you should use
- floating-point
- numbers to represent your audio data, and it provides information that will help you choose the
-optimal sample rate. This section
- concludes with some supplemental
- programming notes to ensure proper implementation of OpenSL ES.
- This page provides guidelines to help you reduce audio input latency when recording with a
-built-in microphone or an external headset microphone. Here are a few important prerequisites: The following are some methods to help ensure low audio input latency:
-
- Be sure to take these things into account to help avoid latency issues: A consequence of potentially independent audio clocks is the need for asynchronous sample rate
-conversion. A simple (though not ideal for audio quality) technique for asynchronous sample rate
-conversion is to duplicate or drop samples as needed near a zero-crossing point. More
-sophisticated conversions are possible.
-This page provides details about how the
-NDK implementation of OpenSL
-ES™ differs from the reference specification for OpenSL ES 1.0.1. When using sample code from the
-specification, you may need to modify it to work on Android.
-
-Unless otherwise noted, all features are available at Android 2.3 (API level 9) and higher.
- Some features are only available for Android 4.0 (API level 14); these are noted.
- Note:
-The Android Compatibility Definition Document (CDD) enumerates the hardware and software
-requirements of a compatible Android device. See
-Android Compatibility
-for more information on the overall compatibility program, and
-
-CDD for the actual CDD document.
-
-OpenSL ES provides a C
-language interface that is also accessible using C++. It exposes features similar to the audio
-portions of these Android Java APIs:
-
-As with all of the Android Native Development Kit (NDK), the primary purpose of OpenSL ES for
-Android is to facilitate the implementation of shared libraries to be called using the Java Native
-Interface (JNI
-). NDK is not intended for writing pure C/C++ applications. However, OpenSL ES is a
-full-featured API, and we expect that you should be able to accomplish most of your audio needs
-using only this API, without up-calls to code running in the Android runtime.
- Note:
-Though based on OpenSL ES, the Android native audio (high-performance audio) API is not a
-conforming implementation of any OpenSL ES 1.0.1 profile (game, music, or phone). This is because
-Android does not implement all of the features required by any one of the profiles. Any known cases
-where Android behaves differently than the specification are described in the
-Android extensions section below.
-
-This section provides the information needed to get started using the OpenSL ES APIs.
-
-We recommend using supported and tested example code that is usable as a model for your own
-code, which is located in the NDK folder {@code platforms/android-9/samples/native-audio/}, as well
-as in the
-audio-echo
-and
-native-audio
-folders of the
-android-ndk GitHub
-repository.
- Caution:
-The OpenSL ES 1.0.1 specification contains example code in the appendices (see
-Khronos OpenSL ES Registry
-for more details). However, the examples in Appendix B: Sample Code and
-Appendix C: Use Case Sample Code use features that are not supported by Android. Some
-examples also contain typographical errors, or use APIs that are likely to change. Proceed with
-caution when referring to these; though the code may be helpful in understanding the full OpenSL ES
-standard, it should not be used as-is with Android.
-
-Modify your {@code Android.mk} file as follows:
-
-The following are some of the many ways to package audio content for your application:
- Note:
-Finding or creating useful audio content for your application is beyond the scope of this article.
-You can use web search terms such as interactive audio, game audio, sound
-design, and audio programming to locate more information.
- Caution: It is your responsibility
-to ensure that you are legally permitted to play or record content. There may be privacy
-considerations for recording content.
-
-The Android NDK implementation of OpenSL ES inherits much of the feature set from
-the reference specification, with certain limitations.
-
-OpenSL ES for Android supports all of the global entry points in the Android specification.
-These entry points include:
-
-Table 1 shows the objects and interfaces that the Android NDK implementation of
-OpenSL ES supports. If a Yes appears in the cell, then the feature is available in this
-implementation.
-
- Table 1. Android NDK support for objects and interfaces.
-The next section explains the limitations for some of these features.
-
-Certain limitations apply to the features in Table 1. These limitations
-represent differences from the reference specification. The rest of this section provides
-information about these differences.
-OpenSL ES for Android does not support {@code RemoveInterface} or
-{@code ResumeInterface}.
-
-You cannot have both environmental reverb and preset reverb on the same output mix.
-
-The platform might ignore effect requests if it estimates that the
-CPU load would be too high.
-
-
-Environmental reverb does not support the
-You can use the MIME data format only with the URI data locator, and only for an audio
-player. You cannot use this data format for an audio recorder.
-
-The Android implementation of OpenSL ES requires you to initialize
-OpenSL ES for Android supports the following audio formats, so long as the
-Android platform supports them as well: Note:
-For a list of audio formats that Android supports, see
-Supported Media Formats.
-
-The following limitations apply to the handling of these and other formats in this
-implementation of OpenSL ES:
-
-OpenSL ES for Android does not support the following methods for manipulating objects:
-
-PCM is the only data format you can use with buffer queues. Supported PCM
-playback configurations have the following characteristics:
-
-The configurations that OpenSL ES for Android supports for recording are
-device-dependent; usually, 16,000 Hz mono/16-bit signed is available regardless of the device.
-
-The value of the
-Android 5.0 (API level 21) and above support floating-point data.
-
-An OpenSL ES playback rate indicates the speed at which an
-object presents data, expressed in thousandths of normal speed, or per mille. For example,
-a playback rate of 1,000 per mille is 1,000/1,000, or normal speed.
-A rate range is a closed interval that expresses possible rate ranges.
-
-Support for playback-rate ranges and other capabilities may vary depending
-on the platform version and implementation. Your app can determine these capabilities at runtime by
-using
-A device typically supports the same rate range for a data source in PCM format, and a unity rate
-range of 1000 per mille to 1000 per mille for other formats: that is, the unity rate range is
-effectively a single value.
-
-OpenSL ES for Android does not support the
-The
-An audio player or recorder with a data locator for a buffer queue supports PCM data format only.
-
-OpenSL ES for Android only supports use of an I/O device data locator when you have
-specified the locator as the data source for
-OpenSL ES for Android can only use the URI data locator with MIME data format,
-and only for an audio player. You cannot use this data format for an audio recorder. It supports
-{@code http:} and {@code file:} schemes. It does not support other schemes, such as {@code https:},
-{@code ftp:}, or
-{@code content:}.
-
-We have not verified support for {@code rtsp:} with audio on the Android platform.
-
-Android supports these OpenSL ES 1.0.1 data structures:
-
-OpenSL ES for Android is designed for multi-threaded applications and is thread-safe. It supports a
-single engine per application, and up to 32 objects per engine. Available device memory and CPU may
-further restrict the usable number of objects.
-
-These engine options are recognized, but ignored by {@code slCreateEngine}:
-
-OpenMAX AL and OpenSL ES may be used together in the same application. In this case, there is
-a single shared engine object internally, and the 32 object limit is shared between OpenMAX AL
-and OpenSL ES. The application should first create both engines, use both engines, and finally
-destroy both engines. The implementation maintains a reference count on the shared engine so that
-it is correctly destroyed during the second destroy operation.
-
-The Android high-performance audio APIs are based on
-Khronos Group OpenSL ES
-1.0.1. Khronos has released a revised version 1.1 of the standard. The
-revised version includes new features, clarifications, corrections of typographical errors, and
-some incompatibilities. Most of the expected incompatibilities are relatively minor or are in
-areas of OpenSL ES that are not supported by Android.
-
-An application
-developed with this version should work on future versions of the Android platform, provided
-that you follow the guidelines that are outlined in the Planning for
-binary compatibility section below.
- Note:
-Future source compatibility is not a goal. That is, if you upgrade to a newer version of the NDK,
-you may need to modify your application source code to conform to the new API. We expect that most
-such changes will be minor; see details below.
-
-We recommend that your application follow these guidelines to improve future binary compatibility:
- Note:
-See the Buffer queue behavior section below for more details.
-
-As mentioned, source code incompatibilities are expected in the next version of OpenSL ES from
-Khronos Group. The likely areas of change include:
-
-OpenSL ES for Android extends the reference OpenSL ES specification to make it compatible with
-Android, and to take advantage of the power and flexibility of the Android platform.
-
-The definition of the API for the Android extensions resides in
-These extensions limit your application's portability to
-other OpenSL ES implementations, because they are Android-specific. You can mitigate this issue by
-avoiding use of the extensions or by using {@code #ifdef} to exclude them at compile time.
-
-Table 2 shows the Android-specific interfaces and data locators that Android OpenSL ES supports
-for each object type. The Yes values in the cells indicate the interfaces and data
-locators that are available for each object type.
-
- Table 2. Interfaces and data locators, by object type.
-The Android configuration interface provides a means to set
-platform-specific parameters for objects. This interface is different from other OpenSL ES
-1.0.1 interfaces in that your app can use it before instantiating the corresponding object; thus,
-you can configure the object before instantiating it. The
-{@code OpenSLES_AndroidConfiguration.h} header file, which resides at
-{@code platforms/android-<version>/<abi>/include/SLES},
-documents the following available configuration keys and values:
-
-The following code snippet shows an example of how to set the Android audio stream type on an audio
-player:
-
-You can use similar code to configure the preset for an audio recorder:
-
-Android's effect, effect send, and effect capabilities interfaces provide
-a generic mechanism for an application to query and use device-specific
-audio effects. Device manufacturers should document any available device-specific audio effects
-that they provide.
-
-Portable applications should use the OpenSL ES 1.0.1 APIs for audio effects instead of the Android
-effect extensions.
-
-The Android file descriptor data locator permits you to specify the source for an
-audio player as an open file descriptor with read access. The data format must be MIME.
-
-This extension is especially useful in conjunction with the native asset manager, because
-the app reads assets from the APK via a file descriptor.
-
-The Android simple buffer queue data locator and interface are
-identical to those in the OpenSL ES 1.0.1 reference specification, with two exceptions: You
-can also use Android simple buffer queues with both audio players and audio recorders. Also, PCM
-is the only data format you can use with these queues.
-In the reference specification, buffer queues are for audio players only, but they are
-compatible with data formats beyond PCM.
-
-For recording, your app should enqueue empty buffers. When a registered callback sends
-notification that the system has finished writing data to the buffer, the app can
-read the buffer.
-
-Playback works in the same way. For future source code
-compatibility, however, we suggest that applications use Android simple
-buffer queues instead of OpenSL ES 1.0.1 buffer queues.
-
-For convenience, the Android implementation of OpenSL ES 1.0.1
-permits your app to specify dynamic interfaces when it instantiates an object.
-This is an alternative to using
-The Android implementation does not include the
-reference specification's requirement that the play cursor return to the beginning
-of the currently playing buffer when playback enters the {@code SL_PLAYSTATE_STOPPED}
-state. This implementation can conform to that behavior, or it can leave the location of the play
-cursor unchanged.
-
-As a result, your app cannot assume that either behavior occurs. Therefore,
-you should explicitly call the
-Similarly, there is no specification governing whether the trigger for a buffer queue callback must
-be a transition to
-There are three methods for querying whether the platform supports the Android extensions. These
-methods are:
-
-Any of these methods returns
-This section describes a deprecated Android-specific extension to OpenSL ES 1.0.1
-for decoding an encoded stream to PCM without immediate playback.
-The table below gives recommendations for use of this extension and alternatives.
- Note:
-There is currently no documentation for the NDK version of the {@code MediaCodec} API. However,
-you can refer to the
-
-native-codec sample code for an example.
-
-A standard audio player plays back to an audio device, specifying the output mix as the data sink.
-The Android extension differs in that an audio player instead
-acts as a decoder if the app has specified the data source either as a URI or as an Android
-file descriptor data locator described in MIME data format. In such a case, the data sink is
-an Android simple buffer queue data locator with PCM data format.
-
-This feature is primarily intended for games to pre-load their audio assets when changing to a
-new game level, which is similar to the functionality that the {@link android.media.SoundPool}
-class provides.
-
-The application should initially enqueue a set of empty buffers in the Android simple
-buffer queue. After that, the app fills the buffers with PCM data. The Android simple
-buffer queue callback fires after each buffer is filled. The callback handler processes
-the PCM data, re-enqueues the now-empty buffer, and then returns. The application is responsible for
-keeping track of decoded buffers; the callback parameter list does not include
-sufficient information to indicate the buffer that contains data or the buffer that should be
-enqueued next.
-
-The data source implicitly reports the end of stream (EOS) by delivering a
-
-The sink's PCM data format typically matches that of the encoded data source
-with respect to sample rate, channel count, and bit depth. However, you can decode to a different
-sample rate, channel count, or bit depth.
-For information about a provision to detect the actual PCM format, see
-Determining the format of decoded PCM data via metadata.
-
-OpenSL ES for Android's PCM decoding feature supports pause and initial seek; it does not support
-volume control, effects, looping, or playback rate.
-
-Depending on the platform implementation, decoding may require resources
-that cannot be left idle. Therefore, we recommend that you make sure to provide
-sufficient numbers of empty PCM buffers; otherwise, the decoder starves. This may happen,
-for example, if your app returns from the Android simple buffer queue callback without
-enqueueing another empty buffer. The result of decoder starvation is
-unspecified, but may include: dropping the decoded
-PCM data, pausing the decoding process, or terminating the decoder outright.
- Note:
-To decode an encoded stream to PCM but not play back immediately, for apps running on
-Android 4.x (API levels 16–20), we recommend using the {@link android.media.MediaCodec} class.
-For new applications running on Android 5.0 (API level 21) or higher, we recommend using the NDK
-equivalent, {@code <NdkMedia*.h>}. These header files reside in
-the {@code media/} directory under your installation root.
-
-An audio player acts as a streaming decoder if the data source is an
-Android buffer queue data locator with MIME data format, and the data
-sink is an Android simple buffer queue data locator with PCM data format.
-Configure the MIME data format as follows:
-
-This feature is primarily intended for streaming media applications that
-deal with AAC audio but need to perform custom audio processing
-prior to playback. Most applications that need to decode audio to PCM
-should use the method that Decode audio to PCM describes,
-as that method is simpler and handles more audio formats. The technique described
-here is a more specialized approach, to be used only if both of these
-conditions apply:
-
-The application should initially enqueue a set of filled buffers in the Android buffer queue.
-Each buffer contains one or more complete ADTS AAC frames.
-The Android buffer queue callback fires after each buffer is emptied.
-The callback handler should refill and re-enqueue the buffer, and then return.
-The application need not keep track of encoded buffers; the callback parameter
-list includes sufficient information to indicate the buffer that should be enqueued next.
-The end of stream is explicitly marked by enqueuing an EOS item.
-After EOS, no more enqueues are permitted.
-
-We recommend that you make sure to provide full
-ADTS AAC buffers, to avoid starving the decoder. This may happen, for example, if your app
-returns from the Android buffer queue callback without enqueueing another full buffer.
-The result of decoder starvation is unspecified.
-
-In all respects except for the data source, the streaming decode method is the same as
-the one that Decode audio to PCM describes.
-
-Despite the similarity in names, an Android buffer queue is not
-the same as an Android simple buffer queue. The streaming decoder
-uses both kinds of buffer queues: an Android buffer queue for the ADTS
-AAC data source, and an Android simple buffer queue for the PCM data
-sink. For more information about the Android simple buffer queue API, see Android
-simple buffer queue data locator and interface.
-For more information about the Android buffer queue API, see the {@code index.html} file in
-the {@code docs/Additional_library_docs/openmaxal/} directory under the installation root.
-
-The
-The metadata key indices are available immediately after
-the
-Metadata key names are stable, but the key indices are not documented,
-and are subject to change. An application should not assume that indices
-are persistent across different execution runs, and should not assume that
-multiple object instances share indices within the same run.
-
-An app running on Android 5.0 (API level 21) and higher can supply data to an AudioPlayer in
-single-precision, floating-point format.
-
-In following example code, the {@code Engine::CreateAudioPlayer} method creates an audio player
-that uses floating-point data:
- OpenSL ES Programming Notes
- provides supplemental information to ensure proper implementation of OpenSL ES. Note:
-For your convenience, we have included a copy of the OpenSL ES 1.0.1 specification with the NDK in
-{@code docs/opensles/OpenSL_ES_Specification_1.0.1.pdf}.
-
-This section describes known issues in the initial platform release that supports these APIs.
-
-{@code DynamicInterfaceManagement::AddInterface} does not work. Instead, specify the interface in
-the array that is passed to Create, as shown in the example code for environmental reverb.
-
-The notes in this section supplement the
-OpenSL ES 1.0.1
-specification.
-
-Two aspects of the OpenSL ES programming model that may be unfamiliar to new developers are the
-distinction between objects and interfaces, and the initialization sequence.
-
-Briefly, an OpenSL ES object is similar to the object concept in
- programming languages such as Java
-and C++, except an OpenSL ES object is only visible via its associated interfaces.
- This includes
-the initial interface for all objects, called {@code SLObjectItf}.
- There is no handle for an object
-itself, only a handle to the {@code SLObjectItf} interface of the object.
-
-An OpenSL ES object is first created, which returns an {@code SLObjectItf}, then
-realized. This is similar to the common programming pattern of first constructing an
-object (which should never fail other than for lack of memory or invalid parameters), and then
-completing initialization (which may fail due to lack of resources). The realize step gives the
-implementation a logical place to allocate additional resources if needed.
-
-As part of the API to create an object, an application specifies an array of desired interfaces
-that it plans to acquire later. Note that this array does not automatically
- acquire the interfaces;
-it merely indicates a future intention to acquire them. Interfaces are distinguished as
-implicit or explicit. An explicit interface must be listed in the array if it
-will be acquired later. An implicit interface need not be listed in the
- object create array, but
-there is no harm in listing it there. OpenSL ES has one more kind of interface called
-dynamic, which does not need to be specified in the object
- create array and can be added
-later after the object is created. The Android implementation provides
- a convenience feature to
-avoid this complexity, which is described in
- Dynamic interfaces at object creation.
-
-After the object is created and realized, the application should acquire interfaces for each
-feature it needs, using {@code GetInterface} on the initial {@code SLObjectItf}.
-
-Finally, the object is available for use via its interfaces, though note that
- some objects require
-further setup. In particular, an audio player with URI data source needs a bit
- more preparation in
-order to detect connection errors. See the
- Audio player prefetch section for details.
-
-After your application is done with the object, you should explicitly destroy it; see the
-Destroy section below.
-
-For an audio player with URI data source, {@code Object::Realize} allocates
- resources but does not
-connect to the data source (prepare) or begin pre-fetching data. These occur once the
-player state is set to either {@code SL_PLAYSTATE_PAUSED} or {@code SL_PLAYSTATE_PLAYING}.
-
-Some information may still be unknown until relatively late in this sequence. In
-particular, initially {@code Player::GetDuration} returns {@code SL_TIME_UNKNOWN} and
-{@code MuteSolo::GetChannelCount} either returns successfully with channel count zero or the
-error result {@code SL_RESULT_PRECONDITIONS_VIOLATED}. These APIs return the proper values
-once they are known.
-
-Other properties that are initially unknown include the sample rate and
- actual media content type
-based on examining the content's header (as opposed to the
- application-specified MIME type and
-container type). These are also determined later during
- prepare/prefetch, but there are no APIs to
-retrieve them.
-
-The prefetch status interface is useful for detecting when all information
- is available, or your
-application can poll periodically. Note that some information, such as the
- duration of a streaming
-MP3, may never be known.
-
-The prefetch status interface is also useful for detecting errors. Register a callback
- and enable
-at least the {@code SL_PREFETCHEVENT_FILLLEVELCHANGE} and {@code SL_PREFETCHEVENT_STATUSCHANGE}
-events. If both of these events are delivered simultaneously, and
-{@code PrefetchStatus::GetFillLevel} reports a zero level, and
-{@code PrefetchStatus::GetPrefetchStatus} reports {@code SL_PREFETCHSTATUS_UNDERFLOW},
- then this
-indicates a non-recoverable error in the data source. This includes the inability to
- connect to the
-data source because the local filename does not exist or the network URI is invalid.
-
-The next version of OpenSL ES is expected to add more explicit support for
- handling errors in the
-data source. However, for future binary compatibility, we intend to continue
- to support the current
-method for reporting a non-recoverable error.
-
-In summary, a recommended code sequence is:
- Note:
-Preparation and prefetching occur here; during this time your callback is called with
-periodic status updates.
-
-Be sure to destroy all objects when exiting from your application.
- Objects should be destroyed in
-reverse order of their creation, as it is not safe to destroy an object that has any dependent
-objects. For example, destroy in this order: audio players and recorders, output mix, and then
-finally the engine.
-
-OpenSL ES does not support automatic garbage collection or
-reference
-counting of interfaces. After you call {@code Object::Destroy}, all extant
- interfaces that are
-derived from the associated object become undefined.
-
-The Android OpenSL ES implementation does not detect the incorrect use of such interfaces.
-Continuing to use such interfaces after the object is destroyed can cause your application to
-crash or behave in unpredictable ways.
-
-We recommend that you explicitly set both the primary object interface and all associated
-interfaces to NULL as part of your object destruction sequence, which prevents the accidental
-misuse of a stale interface handle.
-
-When {@code Volume::EnableStereoPosition} is used to enable stereo panning of a mono source,
- there is a 3-dB reduction in total
-sound power
-level. This is needed to permit the total sound power level to remain constant as
- the source is
-panned from one channel to the other. Therefore, only enable stereo positioning if you need
-it. See the Wikipedia article on
-audio panning
- for more information.
-
-Callback handlers are generally called synchronously with respect to the event. That is, at the
-moment and location that the event is detected by the implementation. This point is
-asynchronous with respect to the application, so you should use a non-blocking synchronization
-mechanism to control access to any variables shared between the application and the callback
-handler. In the example code, such as for buffer queues, we have either omitted this
-synchronization or used blocking synchronization in the interest of simplicity. However, proper
-non-blocking synchronization is critical for any production code.
-
-Callback handlers are called from internal non-application threads that are not attached to the
-Android runtime, so they are ineligible to use JNI. Because these internal threads are
-critical to
-the integrity of the OpenSL ES implementation, a callback handler should also not block
- or perform
-excessive work.
-
-If your callback handler needs to use JNI or execute work that is not proportional to the
-callback, the handler should instead post an event for another thread to process. Examples of
-acceptable callback workload include rendering and enqueuing the next output buffer
-(for an AudioPlayer), processing the just-filled input buffer and enqueueing the next
- empty buffer
-(for an AudioRecorder), or simple APIs such as most of the Get family. See the
-Performance section below regarding the workload.
-
-Note that the converse is safe: an Android application thread that has entered JNI
- is allowed to
-directly call OpenSL ES APIs, including those that block. However, blocking calls are not
-recommended from the main thread, as they may result in
- Application Not Responding (ANR).
-
-The determination regarding the thread that calls a callback handler is largely left up to the
-implementation. The reason for this flexibility is to permit future optimizations,
- especially on
-multi-core devices.
-
-The thread on which the callback handler runs is not guaranteed to have the same
- identity across
-different calls. Therefore, do not rely on the {@code pthread_t returned by pthread_self()}
- or the
-{@code pid_t returned by gettid()} to be consistent across calls. For the same reason,
- do not use
-the thread local storage (TLS) APIs such as {@code pthread_setspecific()} and
-{@code pthread_getspecific()} from a callback.
-
-The implementation guarantees that concurrent callbacks of the same kind, for the
- same object, does
-not occur. However, concurrent callbacks of different kinds for the same object are possible on
-different threads.
-
-As OpenSL ES is a native C API, non-runtime application threads that call OpenSL ES have no
-runtime-related overhead such as garbage collection pauses. With one exception described below,
-there is no additional performance benefit to the use of OpenSL ES other than this.
- In particular,
-the use of OpenSL ES does not guarantee enhancements such as lower audio latency and higher
-scheduling priority over that which the platform generally provides. On the other hand, as the
-Android platform and specific device implementations continue to evolve, an OpenSL ES application
-can expect to benefit from any future system performance improvements.
-
-One such evolution is support for reduced
-audio output latency.
-The underpinnings for reduced
-output latency were first included in Android 4.1 (API level 16), and then
-continued progress occurred in Android 4.2 (API level 17). These improvements are available via
-OpenSL ES for device implementations that
- claim feature {@code android.hardware.audio.low_latency}.
-If the device doesn't claim this feature but supports Android 2.3 (API level 9)
-or later, then you can still use the OpenSL ES APIs but the output latency may be higher.
- The lower
-output latency path is used only if the application requests a buffer size and sample rate
- that are
-compatible with the device's native output configuration. These parameters are
- device-specific and
-should be obtained as described below.
-
-Beginning with Android 4.2 (API level 17), an application can query for the
-platform native or optimal output sample rate and buffer size for the device's primary output
-stream. When combined with the feature test just mentioned, an app can now configure itself
-appropriately for lower latency output on devices that claim support.
-
-For Android 4.2 (API level 17) and earlier, a buffer count of two or more is
-required for lower latency. Beginning with Android 4.3 (API level 18), a buffer
-count of one is sufficient for lower latency.
-
-All OpenSL ES interfaces for output effects preclude the lower latency path.
-
-The recommended sequence is as follows:
- Note:
-You can use the
-
- Audio Buffer Size
-test app to determine the native buffer size and sample rate for OpenSL ES audio
-applications on your audio device. You can also visit GitHub to view
-audio-buffer-size samples.
-
-
-The number of lower latency audio players is limited. If your application requires more
-than a few
-audio sources, consider mixing your audio at the application level. Be sure to destroy your audio
-players when your activity is paused, as they are a global resource shared with other apps.
-
-To avoid audible glitches, the buffer queue callback handler must execute within a small and
-predictable time window. This typically implies no unbounded blocking on mutexes, conditions,
-or I/O operations. Instead consider try locks, locks and waits with timeouts, and
-
- non-blocking algorithms.
-
-The computation required to render the next buffer (for AudioPlayer) or consume the previous
-buffer (for AudioRecord) should take approximately the same amount of time for each callback.
-Avoid algorithms that execute in a non-deterministic amount of time or are bursty in
-their computations. A callback computation is bursty if the CPU time spent in any given callback
-is significantly larger than the average. In summary, the ideal is for the CPU execution time of
-the handler to have variance near zero, and for the handler to not block for unbounded times.
-
-Lower latency audio is possible for these outputs only:
-
-On some devices, speaker latency is higher than other paths due to digital signal processing for
-speaker correction and protection.
-
-As of API level 21,
-lower latency audio input
- is supported
-on select devices. To take advantage of
-this feature, first confirm that lower latency output is available as described above. The
-capability for lower latency output is a prerequisite for the lower latency input feature. Then,
-create an AudioRecorder with the same sample rate and buffer size as would be used for output.
-OpenSL ES interfaces for input effects preclude the lower latency path. The record preset
-{@code SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION} must be used for lower latency; this preset
-disables device-specific digital signal processing that may add latency to the input path. For
-more information on record presets, see the Android
-configuration interface section above.
-
-For simultaneous input and output, separate buffer queue completion handlers are used for each
-side. There is no guarantee of the relative order of these callbacks, or the synchronization of
-the audio clocks, even when both sides use the same sample rate. Your application
- should buffer the
-data with proper buffer synchronization.
-
-One consequence of potentially independent audio clocks is the need for asynchronous sample rate
-conversion. A simple (though not ideal for audio quality) technique for asynchronous sample rate
-conversion is to duplicate or drop samples as needed near a zero-crossing point.
- More sophisticated
-conversions are possible.
-
-As far as who can do what, security in Android is done at the process level. Java programming
-language code cannot do anything more than native code, nor can native code do anything more than
-Java programming language code. The only differences between them are the available APIs.
-
-Applications using OpenSL ES must request the permissions that they would need for similar
-non-native APIs. For example, if your application records audio, then it needs the
-{@code android.permission.RECORD_AUDIO} permission. Applications that use audio effects need
-{@code android.permission.MODIFY_AUDIO_SETTINGS}. Applications that play network URI resources
-need {@code android.permission.NETWORK}. See
-Working with System
-Permissions for more information.
-
-Depending on the platform version and implementation, media content parsers and
- software codecs may
-run within the context of the Android application that calls OpenSL ES (hardware codecs are
-abstracted but are device-dependent). Malformed content designed to exploit parser and codec
-vulnerabilities is a known attack vector. We recommend that you play media only from trustworthy
-sources or that you partition your application such that code that handles media from
-untrustworthy sources runs in a relatively sandboxed environment. For example, you could
-process media from untrustworthy sources in a separate process. Though both processes would still
-run under the same UID, this separation does make an attack more difficult.
- Audio latency: buffer sizes Building great multi-media experiences on Android This page describes how to develop your audio app for low-latency output and how to avoid
-warmup latency. Low-latency audio is currently only supported when using Android's implementation of the
-OpenSL ES™ API specification, and the Android NDK:
- Latency is the time it takes for a signal to travel through a system. These are the common
-types of latency related to audio apps:
-
- It is difficult to test audio output latency in isolation since it requires knowing exactly
-when the first sample is sent into the audio path (although this can be done using a
-
-light testing circuit and an oscilloscope). If you know the round-trip audio latency, you can
-use the rough rule of thumb: audio output latency is half the round-trip audio latency
-over paths without signal processing.
- To obtain the lowest latency, you must supply audio data that matches the device's optimal
-sample rate and buffer size. For more information, see
-
-Design For Reduced Latency. In Java, you can obtain the optimal sample rate from AudioManager as shown in the following
-code example:
- Note: The sample rate refers to the rate of each stream. If your source audio
- has two channels (stereo), then you will have one stream playing a pair of samples (frame) at
-
- PROPERTY_OUTPUT_SAMPLE_RATE.
- Once you have the optimal sample output rate, you can supply it when creating your player
-using OpenSL ES:
- Note: {@code samplesPerSec} refers to the sample rate per channel in
- millihertz (1 Hz = 1000 mHz).
- Only these interfaces are supported by the fast mixer: These interfaces are not allowed because they involve signal processing and will cause
-your request for a fast-track to be rejected: When you create your player, make sure you only add fast interfaces, as shown in
-the following example: Complete these steps to verify that you have successfully obtained a low-latency track: You can measure round-trip audio latency by creating an app that generates an audio signal,
-listens for that signal, and measures the time between sending it and receiving it.
-Alternatively, you can install this
-
-latency testing app. This performs a round-trip latency test using the
-
-Larsen test. You can also
-
-view the source code for the latency testing app. Since the lowest latency is achieved over audio paths with minimal signal processing, you may
-also want to use an
-
-Audio Loopback Dongle, which allows the test to be run over the headset connector. The lowest possible round-trip audio latency varies greatly depending on device model and
-Android build. You can measure it yourself using the latency testing app and loopback
-dongle. When creating apps for Nexus devices, you can also use the
-
-published measurements. You can also get a rough idea of audio performance by testing whether the device reports
-support for the
-
-low_latency and
-
-pro hardware features. The Android Compatibility Definition Document (CDD) enumerates the hardware and software
-requirements of a compatible Android device.
-See
-Android Compatibility for more information on the overall compatibility program, and
-
-CDD for the actual CDD document. In the CDD, round-trip latency is specified as 20 ms or lower (even though musicians
-generally require 10 ms). This is because there are important use cases that are enabled by
-20 ms. There is currently no API to determine audio latency over any path on an Android device at
-runtime. You can, however, use the following hardware feature flags to find out whether the
-device makes any guarantees for latency: The criteria for reporting these flags is defined in the CDD in sections 5.6 Audio
-Latency and 5.10 Professional Audio. Here’s how to check for these features in Java: Regarding the relationship of audio features, the {@code android.hardware.audio.low_latency}
-feature is a prerequisite for {@code android.hardware.audio.pro}. A device can implement
-{@code android.hardware.audio.low_latency} and not {@code android.hardware.audio.pro}, but not
-vice-versa. You can obtain the optimal buffer size in a similar way to the optimal frame rate, using the
-AudioManager API: The
-
-PROPERTY_OUTPUT_FRAMES_PER_BUFFER property indicates the number of audio frames
-that the HAL (Hardware Abstraction Layer) buffer can hold. You should construct your audio
-buffers so that they contain an exact multiple of this number. If you use the correct number
-of audio frames, your callbacks occur at regular intervals, which reduces jitter. It is important to use the API to determine buffer size rather than using a hardcoded value,
- because HAL buffer sizes differ across devices and across Android builds. When you enqueue audio data for the first time, it takes a small, but still significant,
-amount of time for the device audio circuit to warm up. To avoid this warmup latency, you should
-enqueue buffers of audio data containing silence, as shown in the following code example: At the point when audio should be produced, you can switch to enqueuing buffers containing
-real audio data. Sample Rates: Why Can't We All Just Agree? As of Android 5.0 (Lollipop), the audio resamplers are now entirely based
-on FIR filters derived from a Kaiser windowed-sinc function. The Kaiser windowed-sinc
-offers the following properties:
-APP_OPTIM
-APP_CFLAGS
-
-sources/foo/Android.mk
-sources/bar/Android.mk
-
-
-
-APP_CFLAGS += -Isources/bar
-
-
-
-APP_CFLAGS += -I$(LOCAL_PATH)/../bar
-
-
-APP_CPPFLAGS
-APP_LDFLAGS
-APP_BUILD_SCRIPT
-APP_ABI
-
-
-
-
-
- Instruction set
- Value
-
-
- Hardware FPU instructions on ARMv7 based devices
- {@code APP_ABI := armeabi-v7a}
-
-
- ARMv8 AArch64
- {@code APP_ABI := arm64-v8a}
-
-
- IA-32
- {@code APP_ABI := x86}
-
-
- Intel64
- {@code APP_ABI := x86_64}
-
-
- MIPS32
- {@code APP_ABI := mips}
-
-
- MIPS64 (r6)
- {@code APP_ABI := mips64}
-
-
-All supported instruction sets
- {@code APP_ABI := all}
-
-APP_ABI := armeabi armeabi-v7a x86 mips
-
-
-APP_PLATFORM
-APP_STL
-APP_SHORT_COMMANDS
-NDK_TOOLCHAIN_VERSION
-APP_PIE
-APP_THIN_ARCHIVE
-On this page
-
-
- Video
- Building Great Audio Apps
-
-
-
-
-Adding OpenSL ES to your App
-
-
-#include <SLES/OpenSLES.h>
-
-
-
-#include <SLES/OpenSLES_Android.h>
-
-
-
-#include <SLES/OpenSLES_AndroidConfiguration.h>
-#include <SLES/OpenSLES_AndroidMetadata.h>
-
-
-Building and Debugging
-
-
-LOCAL_LDLIBS += -lOpenSLES
-
-
-
-$ adb logcat
-
-
-Audio Power Consumption
-Samples
-
-On this page
-
-
- Video
-
-
-
-
-
-
-Best Practices for Floating-Point Audio
-
-
-
-Floating-Point Audio in Android SDK
-
-AudioFormat.ENCODING_PCM_FLOAT is used similarly to
- ENCODING_PCM_16_BIT or ENCODING_PCM_8_BIT for specifying
- AudioTrack data
-formats. The corresponding overloaded method AudioTrack.write()
- takes in a float array to deliver data.
- public int write(float[] audioData,
- int offsetInFloats,
- int sizeInFloats,
- int writeMode)
-
-
-For More Information
-
-
-
-
-
-
diff --git a/docs/html/ndk/guides/audio/index.jd b/docs/html/ndk/guides/audio/index.jd
deleted file mode 100644
index 12d9320c7a43f..0000000000000
--- a/docs/html/ndk/guides/audio/index.jd
+++ /dev/null
@@ -1,27 +0,0 @@
-page.title=NDK High-Performance Audio
-@jd:body
-
-On this page
-
-
- Checklist
-
-
-
-
-Ways to Reduce Audio Input Latency
-
-
-
-
-What to Avoid
-
-
-
-
-On this page
-
-
- Getting Started
-
-Example code
-
-Makefile
-
-
-LOCAL_LDLIBS += -lOpenSLES
-
-
-Audio content
-
-
-
-
-Features Inherited from the Reference Specification
-
-Global entry points
-
-
-
-
-Objects and interfaces
-
-
-
-
-
-
- Feature
- Audio player
- Audio recorder
- Engine
- Output mix
-
-
- Bass boost
- Yes
- No
- No
- Yes
-
-
- Buffer queue
- Yes
- No
- No
- No
-
-
- Dynamic interface management
- Yes
- Yes
- Yes
- Yes
-
-
- Effect send
- Yes
- No
- No
- No
-
-
- Engine
- No
- No
- Yes
- No
-
-
- Environmental reverb
- No
- No
- No
- Yes
-
-
- Equalizer
- Yes
- No
- No
- Yes
-
-
- Metadata extraction
- Yes: Decode to PCM
- No
- No
- No
-
-
- Mute solo
- Yes
- No
- No
- No
-
-
- Object
- Yes
- Yes
- Yes
- Yes
-
-
- Play
- Yes
- No
- No
- No
-
-
- Playback rate
- Yes
- No
- No
- No
-
-
- Prefetch status
- Yes
- No
- No
- No
-
-
- Preset reverb
- No
- No
- No
- Yes
-
-
- Record
- No
- Yes
- No
- No
-
-
- Seek
- Yes
- No
- No
- No
-
-
- Virtualizer
- Yes
- No
- No
- Yes
-
-
- Volume
- Yes
- No
- No
- No
-
-
- Buffer queue data locator
- Yes: Source
- No
- No
- No
-
-
- I/O device data locator
- No
- Yes: Source
- No
- No
-
-
- Output mix locator
- Yes: Sink
- No
- No
- No
-
-
- URI data locator
- Yes: Source
- No
- No
- No
- Limitations
-
-Dynamic interface management
-
-Effect combinations: environment reverb and preset reverb
-
-Effect send
-
-SetSendLevel() supports a single send level per audio player.
-Environmental reverb
-
-reflectionsDelay,
-reflectionsLevel, or reverbDelay fields of
-the SLEnvironmentalReverbSettings struct.
-MIME data format
-
-mimeType
-to either NULL or a valid UTF-8 string. You must also initialize
-containerType to a valid value.
-In the absence of other considerations, such as portability to other
-implementations or content format that an app cannot identify by header,
-we recommend that you
-set mimeType to NULL and containerType
-to SL_CONTAINERTYPE_UNSPECIFIED.
-
-
-
-
-
-
-Object-related methods
-
-
-
-
-PCM data format
-
-
-
-
-
-
samplesPerSec field is in units of milliHz, despite the misleading
-name. To avoid accidentally using the wrong value, we recommend that you initialize this field using
-one of the symbolic constants defined for this purpose, such as {@code SL_SAMPLINGRATE_44_1}.
-Playback rate
-
-PlaybackRate::GetRateRange() or
-PlaybackRate::GetCapabilitiesOfRate() to query the device.
-Record
-
-SL_RECORDEVENT_HEADATLIMIT
-or SL_RECORDEVENT_HEADMOVING events.
-Seek
-
-SetLoop() method enables whole-file looping. To enable looping,
-set the startPos parameter to 0, and the value of the endPos parameter
-to SL_TIME_UNKNOWN.
-Buffer queue data locator
-
-I/O device data locator
-
-Engine::CreateAudioRecorder().
-Initialize the device data locator using the values contained in the following code snippet.
-
-SLDataLocator_IODevice loc_dev =
- {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT,
- SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
-
-
-URI data locator
-
-Data structures
-
-
-
-
-Platform configuration
-
-
-
-
-Planning for Future Versions of OpenSL ES
-
-Planning for binary compatibility
-
-
-
-
-Planning for source compatibility
-
-
-
-
-Android Extensions
-
-OpenSLES_Android.h
-and the header files that it includes. Consult {@code OpenSLES_Android.h}
-for details about these extensions. This file is located under your installation root, in the
-{@code platforms/android-<version>/<abi>/include/SLES} directory. Unless otherwise
-noted, all interfaces are explicit.
-
-
-
-
-
- Feature
- Audio player
- Audio recorder
- Engine
- Output mix
-
-
- Android buffer queue
- Yes: Source (decode)
- No
- No
- No
-
-
- Android configuration
- Yes
- Yes
- No
- No
-
-
- Android effect
- Yes
- No
- No
- Yes
-
-
- Android effect capabilities
- No
- No
- Yes
- No
-
-
- Android effect send
- Yes
- No
- No
- No
-
-
- Android simple buffer queue
- Yes: Source (playback) or sink (decode)
- Yes
- No
- No
-
-
- Android buffer queue data locator
- Yes: Source (decode)
- No
- No
- No
-
-
- Android file descriptor data locator
- Yes: Source
- No
- No
- No
-
-
-Android simple buffer queue data locator
- Yes: Source (playback) or sink (decode)
- Yes: Sink
- No
- No
- Android configuration interface
-
-
-
-
-SL_ANDROID_STREAM_MEDIA).SL_ANDROID_RECORDING_PRESET_GENERIC).
-
-// CreateAudioPlayer and specify SL_IID_ANDROIDCONFIGURATION
-// in the required interface ID array. Do not realize player yet.
-// ...
-SLAndroidConfigurationItf playerConfig;
-result = (*playerObject)->GetInterface(playerObject,
- SL_IID_ANDROIDCONFIGURATION, &playerConfig);
-assert(SL_RESULT_SUCCESS == result);
-SLint32 streamType = SL_ANDROID_STREAM_ALARM;
-result = (*playerConfig)->SetConfiguration(playerConfig,
- SL_ANDROID_KEY_STREAM_TYPE, &streamType, sizeof(SLint32));
-assert(SL_RESULT_SUCCESS == result);
-// ...
-// Now realize the player here.
-
-
-
-// ... obtain the configuration interface as the first four lines above, then:
-SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
-result = (*playerConfig)->SetConfiguration(playerConfig,
- RECORDING_PRESET, &presetValue, sizeof(SLuint32));
-
-
-Android effects interfaces
-
-Android file descriptor data locator
-
-Android simple buffer queue data locator and interface
-
-Dynamic interfaces at object creation
-
-DynamicInterfaceManagement::AddInterface()
-to add these interfaces after instantiation.
-Buffer queue behavior
-
-BufferQueue::Clear() method after a transition to
-SL_PLAYSTATE_STOPPED. Doing so sets the buffer queue to a known state.
-SL_PLAYSTATE_STOPPED or execution of
-BufferQueue::Clear(). Therefore, we recommend that you do not create a dependency on
-one or the other; instead, your app should be able to handle both.
-Reporting of extensions
-
-
-
-Engine::QueryNumSupportedExtensions()Engine::QuerySupportedExtension()Engine::IsExtensionSupported()ANDROID_SDK_LEVEL_<API-level>,
-where {@code API-level} is the platform API level; for example, {@code ANDROID_SDK_LEVEL_23}.
-A platform API level of 9 or higher means that the platform supports the extensions.
-Decode audio to PCM
-
-
-
-
-
-
-API level
- Alternatives
-
-
-13 and below
- An open-source codec with a suitable license
-
-
-14 to 15
- An open-source codec with a suitable license
-
-
-16 to 20
-
- The {@link android.media.MediaCodec} class or an open-source codec with a suitable license
-
-
-
-21 and above
-
- NDK MediaCodec in the {@code <media/NdkMedia*.h>} header files, the
- {@link android.media.MediaCodec} class, or an open-source codec with a suitable license
-
-SL_PLAYEVENT_HEADATEND event at the end of the stream. After the app has decoded
-all of the data it received, it makes no further calls to the Android simple buffer queue callback.
-Decode streaming ADTS AAC to PCM
-
-
-
-
-
-
-
-Determining the format of decoded PCM data via metadata
-
-SLMetadataExtractionItf interface is part of the reference specification.
-However, the metadata keys that indicate the actual format of decoded PCM data are specific to
-Android. The OpenSLES_AndroidMetadata.h header file defines these metadata keys.
-This header file resides under your installation root, in the
-{@code platforms/android-<version>/<abi>/include/SLES} directory.
-Object::Realize() method finishes executing. However, the associated values are not
-available until after the app decodes the first encoded data. A good
-practice is to query for the key indices in the main thread after calling the {@code
-Object::Realize} method, and to read the PCM format metadata values in the Android simple
-buffer queue callback handler when calling it for the first time. Consult the
-example code in the
-NDK package for examples of working with this interface.
-Floating-point data
-
-
-#include <SLES/OpenSLES_Android.h>
-...
-SLAndroidDataFormat_PCM_EX pcm;
-pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
-pcm.numChannels = 2;
-pcm.sampleRate = SL_SAMPLINGRATE_44_1;
-pcm.bitsPerSample = 32;
-pcm.containerSize = 32;
-pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
-pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
-pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
-...
-SLDataSource audiosrc;
-audiosrc.pLocator = ...
-audiosrc.pFormat = &pcm;
-
-
-Programming Notes
-Platform Issues
-
-Dynamic interface management
-
-On this page
-
-
- Objects and Interface Initialization
-
-Audio Player Prefetch
-
-
-
-
-Destroy
-
-Stereo Panning
-
-Callbacks and Threads
-
-Performance
-
-
-
-
-import android.content.pm.PackageManager;
-...
-PackageManager pm = getContext().getPackageManager();
-boolean claimsFeature = pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY);
-
import android.media.AudioManager;
-...
-AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-String sampleRate = am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
-String framesPerBuffer = am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
-
- Note that {@code sampleRate} and {@code framesPerBuffer} are strings. First check for
- null and then convert to int using {@code Integer.parseInt()}.
-
-
-Security and Permissions
-
-On this page
-
-
-
- Also read
-
-
- Video
- Video
- Prerequisites
-
-
-
-
-Obtain a Low-Latency Track
-
-
-
-
-Obtain the optimal sample rate
-
-
-AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-String frameRate = am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
-int frameRateInt = Integer.parseInt(frameRate);
-if (frameRateInt == 0) frameRateInt = 44100; // Use a default value if property not found
-
-
-Use the optimal sample rate when creating your audio player
-
-
-// create buffer queue audio player
-void Java_com_example_audio_generatetone_MainActivity_createBufferQueueAudioPlayer
- (JNIEnv* env, jclass clazz, jint sampleRate, jint framesPerBuffer)
-{
- ...
- // specify the audio source format
- SLDataFormat_PCM format_pcm;
- format_pcm.numChannels = 2;
- format_pcm.samplesPerSec = (SLuint32) sampleRate * 1000;
- ...
-}
-
-
-Avoid adding output interfaces that involve signal processing
-
-
-
-
-
-
-
-
-const SLInterfaceID interface_ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME };
-
-
-Verify you're using a low-latency track
-
-
-
-
-
-adb shell ps | grep your_app_name
-
-
-
-adb shell dumpsys media.audio_flinger
-
-
- Measure round-trip latency
-
-Review the CDD and audio latency
-
-
-
-
-
-boolean hasLowLatencyFeature =
- getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY);
-
-boolean hasProFeature =
- getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_PRO);
-
-
-Use the Optimal Buffer Size When Enqueuing Audio Data
-
-
-AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-String framesPerBuffer = am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
-int framesPerBufferInt = Integer.parseInt(framesPerBuffer);
-if (framesPerBufferInt == 0) framesPerBufferInt = 256; // Use default
-
-
-Avoid Warmup Latency
-
-
-#define CHANNELS 1
-static short* silenceBuffer;
-int numSamples = frames * CHANNELS;
-silenceBuffer = malloc(sizeof(*silenceBuffer) * numSamples);
- for (i = 0; i < numSamples; i++) {
- silenceBuffer[i] = 0;
- }
-
-
-On this page
-
-
- Video
-
-
-See P.P. Vaidyanathan,
-Multirate Systems and Filter Banks, p. 50 for discussions of the
-Kaiser Window and its optimality and relationship to Prolate Spheroidal
-Windows.
The design parameters are automatically computed based on internal -quality determination and the sampling ratios desired. Based on the -design parameters, the windowed-sinc filter is generated. For music use, -the resampler for 44.1 to 48 kHz and vice versa is generated at a higher -quality than for arbitrary frequency conversion.
- -The audio resamplers provide increased quality, as well as speed -to achieve that quality. But resamplers can introduce small amounts -of passband ripple and aliasing harmonic noise, and they can cause some high -frequency loss in the transition band, so avoid using them unnecessarily.
- -This section describes some best practices to help you avoid problems with sampling rates.
-In general, it is best to choose the sampling rate to fit the device, -typically 44.1 kHz or 48 kHz. Use of a sample rate greater than -48 kHz will typically result in decreased quality because a resampler must be -used to play back the file.
- -The resampler operates in one of the following modes:
-The resampler is fastest in fixed polyphase mode, when the ratio of input -rate over output rate L/M (taking out the greatest common divisor) -has M less than 256. For example, for 44,100 to 48,000 conversion, L = 147, -M = 160.
- -In fixed polyphase mode, the sampling rate is locked for as -many samples converted and does not change. In interpolated polyphase -mode, the sampling rate is approximate. The drift is generally on the -order of one sample over a few hours of playback on a 48-kHz device. -This is not usually a concern because approximation error is much less than -frequency error of internal quartz oscillators, thermal drift, or jitter - (typically tens of ppm).
- -Choose simple-ratio sampling rates such as 24 kHz (1:2) and 32 kHz (2:3) when playing back - on a 48-kHz device, even though other sampling -rates and ratios may be permitted through AudioTrack.
- -Sampling rates can be changed on the fly. The granularity of -such change is based on the internal buffering (typically a few hundred -samples), not on a sample-by-sample basis. This can be used for effects.
- -Do not dynamically change sampling rates when -downsampling. When changing sample rates after an audio track is -created, differences of around 5 to 10 percent from the original rate may -trigger a filter recomputation when downsampling (to properly suppress -aliasing). This can consume computing resources and may cause an audible click -if the filter is replaced in real time.
- -Downsampling is typically triggered by hardware device requirements. When the - Sample Rate converter is used for downsampling, -try to limit the downsampling ratio to no more than 6:1 for good aliasing -suppression (for example, no greater downsample than 48,000 to 8,000). The filter -lengths adjust to match the downsampling ratio, but you sacrifice more -transition bandwidth at higher downsampling ratios to avoid excessively -increasing the filter length. There are no similar aliasing concerns for -upsampling. Note that some parts of the audio pipeline -may prevent downsampling greater than 2:1.
- -Resampling prevents the track from being placed in the FastMixer -path, which means that significantly higher latency occurs due to the additional, - larger buffer in the ordinary Mixer path. Furthermore, - there is an implicit delay from the filter length of the resampler, - though this is typically on the order of one millisecond or less, - which is not as large as the additional buffering for the ordinary Mixer path - (typically 20 milliseconds).
- -This section lists some additional resources about sampling and resampling.
- -- -Sampling (signal processing) at Wikipedia.
- --Sample rate conversion at Wikipedia.
- --Sample Rate Conversion at source.android.com.
- --24/192 Music Downloads ... and why they make no sense -by Christopher "Monty" Montgomery of Xiph.Org.
- --D/A and A/D | Digital Show and Tell -video by Christopher "Monty" Montgomery of Xiph.Org.
- --The Science of Sample Rates (When Higher Is Better - And When It Isn't).
- - - --192kHz/24bit vs. 96kHz/24bit "debate"- Interesting revelation
diff --git a/docs/html/ndk/guides/build.jd b/docs/html/ndk/guides/build.jd deleted file mode 100644 index 62863283c3863..0000000000000 --- a/docs/html/ndk/guides/build.jd +++ /dev/null @@ -1,18 +0,0 @@ -page.title=Building Your Project -@jd:body - -One of the NDK's core purposes is allowing you to build C and C++ source code into shared -libraries that you can use in your app.
- -This section explains how to build native binaries for use in your Android app. It begins by -explaining the -{@code Android.mk} file, which -defines properties specific to individual modules, or libraries. Then, it explains the -{@code Application.mk} file, which defines -properties for all the modules that you use in your -app. Next, it tells you how to use the -{@code ndk-build} script, which is what the NDK uses to build your sources. Last, it ventures -into advanced territory, discussing how to incorporate the NDK into your own -toolchain, if you prefer to -build that way instead of using -{@code ndk-build}.
\ No newline at end of file diff --git a/docs/html/ndk/guides/concepts.jd b/docs/html/ndk/guides/concepts.jd deleted file mode 100755 index 7879219f347b8..0000000000000 --- a/docs/html/ndk/guides/concepts.jd +++ /dev/null @@ -1,303 +0,0 @@ -page.title=Concepts -@jd:body - -This guide assumes that you are already familiar with concepts inherent in native programming and -in Android development.
- - -This section provides a high-level explanation of how the NDK works. The Android NDK is a set of -tools allowing you to embed C or C++ (“native code”) into your Android apps. The ability to use -native code in Android apps can be particularly useful to developers who wish to do one or more of -the following:
-This section introduces the main components used in building a native application for Android, -and goes on to describe the process of building and packaging.
-You should have an understanding of the following components as you build your app:
-For more information, see -ndk-build.
-When developing Java components, use the {@code native} keyword to indicate methods implemented -as native code. For example, the following function declaration tells the compiler that the -implementation is in a native library:
- - - --public native int add(int x, int y); --
Note: If two libraries implement respective methods with the same -signature, a link error occurs. In C, "signature" means method name only. In C++, "signature" means -not only method name, but also its argument names and types.
-The following two items are only required for building using the -{@code ndk-build} script, -and for debugging using the -{@code ndk-gdb} script. - -
The general flow for developing a native app for Android is as follows:
-Note: While it is possible to completely avoid Java, you are likely -to find the Android Java framework useful for tasks including controlling the display and UI.
-The Android SDK provides a helper class, {@link android.app.NativeActivity}, that allows you to -write a completely native activity. {@link android.app.NativeActivity} handles the communication -between the Android framework and your native code, so you do not have to subclass it or call its -methods. All you need to do is declare your application to be native in your -{@code AndroidManifest.xml} file, and begin creating your native application.
- -An Android application using {@link android.app.NativeActivity} still runs in its own virtual -machine, sandboxed from other applications. You can therefore still access Android framework APIs -through the JNI. In certain cases, however–such as for sensors, input events, and -assets–the NDK provides native interfaces that you can use instead of having to call -across the JNI. For more information about such support, see -Android NDK Native APIs.
- -Regardless of whether or not you are developing a native activity, we recommend that you create -your projects with the traditional Android build tools. Doing so helps ensure building and packaging -of Android applications with the correct structure.
- -The Android NDK provides you with two choices to implement your native activity:
- -The {@code
For more information on how to use this static library, examine the native-activity sample
-application and its documentation. Further reading is also available in the comments in the {@code
To implement a native activity with the -{@code native_activity.h} -interface:
- -Because your application has no Java code, set {@code android:hasCode} to {@code false}.
- --<application android:label="@string/app_name" android:hasCode="false"> -- -
You must set the {@code android:name} attribute of the activity tag to -{@link android.app.NativeActivity}.
- --<activity android:name="android.app.NativeActivity" - android:label="@string/app_name"> --
Note: You can subclass {@link android.app.NativeActivity}. If you -do, use the name of the subclass instead of {@link android.app.NativeActivity}.
-The {@code android:value} attribute of the {@code meta-data} tag specifies the name of the shared -library containing the entry point to the application (such as C/C++ {@code main}), omitting the -{@code lib} prefix and {@code .so} suffix from the library name.
- -- <meta-data android:name="android.app.lib_name" - android:value="native-activity" /> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - </intent-filter> - </activity> - </application> - </manifest> -- -
-$ cd <path>/<to>/<project> -$ <ndk>/ndk-build -- -
The Android platform provides a very minimal C++ runtime support library ({@code libstdc++}). -This minimal support does not include, for example:
- -The NDK provides headers for use with this default library. In addition, the NDK provides a -number of helper runtimes that provide additional features. This page provides information about -these helper runtimes, their characteristics, and how to use them. -
- -Table 1 provides names, brief explanations, and features of runtimes available inthe NDK.
- -- Table 1. NDK Runtimes and Features.
- -| Name | -Explanation> - | Features - |
|---|---|---|
| {@code libstdc++} (default) | -The default minimal system C++ runtime library. | -N/A | -
| {@code gabi++_static} | -The GAbi++ runtime (static). | -C++ Exceptions and RTTI | -
| {@code gabi++_shared} | -The GAbi++ runtime (shared). | -C++ Exceptions and RTTI | -
| {@code stlport_static} | -The STLport runtime (static). | -C++ Exceptions and RTTI; Standard Library | -
| {@code stlport_shared} | -The STLport runtime (shared). | -C++ Exceptions and RTTI; Standard Library | -
| {@code gnustl_static} | -The GNU STL (static). | -C++ Exceptions and RTTI; Standard Library | -
| {@code gnustl_shared} | -The GNU STL (shared). | -C++ Exceptions and RTTI; Standard Library | -
| {@code c++_static} | -The LLVM libc++ runtime (static). | -C++ Exceptions and RTTI; Standard Library | -
| {@code c++_shared} | -The LLVM libc++ runtime (shared). | -C++ Exceptions and RTTI; Standard Library | -
Use the {@code APP_STL} variable in your -{@code Application.mk} file to specify the runtime you wish to use. Use the values in -the "Name" column in Table 1 as your setting. For example:
- --APP_STL := gnustl_static -- -
You may only select one runtime for your app, and can only do in -{@code Application.mk}.
- -Even if you do not use the NDK build system, you can still use STLport, libc++ or GNU STL. -For more information on how to use these runtimes with your own toolchain, see Standalone Toolchain.
- -This runtime only provides the following headers, with no support beyond them:
-This runtime provides the same headers as the default runtime, but adds support for RTTI -(RunTime Type Information) and exception handling.
- - -This runtime is an Android port of STLport -(http://www.stlport.org). It provides a complete set of C++ -standard library headers. It also, by embedding its own instance of GAbi++, provides support for -RTTI and exception handling.
- -While shared and static versions of this runtime are avilable, we recommend using the shared -version. For more information, see Static runtimes.
- -The shared library file is named {@code libstlport_shared.so} instead of {@code libstdc++.so} -as is common on other platforms.
- -In addition to the static- and shared-library options, you can also force the NDK to -build the library from sources by adding the following line to your {@code Application.mk} -file, or setting it in your environment prior to building:
- --STLPORT_FORCE_REBUILD := true -- - -
This runtime is the GNU Standard C++ Library, ({@code libstdc++-v3}). Its shared library file is -named {@code libgnustl_shared.so}.
- - -This runtime is an Android port of LLVM libc++. Its -shared library file is named {@code libc++_shared.so}.
- -By default, this runtime compiles with {@code -std=c++11}. As with GNU {@code libstdc++}, you -need to explicitly turn on exceptions or RTTI support. For information on how to do this, see -C++ Exceptions and RTTI.
- -The NDK provides prebuilt static and shared libraries for {@code libc++}, but you can force the -NDK to rebuild {@code libc++} from sources by adding the following line to your -{@code Application.mk} file, or setting it in your environment prior to building:
- --LIBCXX_FORCE_REBUILD := true -- -
If you include {@code
-LOCAL_LDLIBS += -latomic -- -
If you are using your own toolchain, use:
- ---latomic -- - -
The NDK's libc++ is not stable. Not all the tests pass, and the test suite is not comprehensive. -Some known issues are:
- -You should also make sure to check the "Known Issues" section of the changelog for the NDK -release you are using.
- -Warning: Attempting to change to an unsupported locale will -not fail. The operation will succeed, but the locale will not change and the -following message will appear in {@code logcat}.
- --newlocale() WARNING: Trying to set locale to en_US.UTF-8 other than "", "C" or "POSIX" -- - -
In all versions of the NDK later than NDKr5, the NDK toolchain allows you to use C++ runtimes -that support exception handling. However, to ensure compatibility with earlier releases, it -compiles all C++ sources with {@code -fno-exceptions} support by default. You can enable C++ -exceptions either for your entire app, or for individual modules. - -
To enable exception-handling support for your entire app, add the following line to -your {@code Application.mk} file. -To enable exception-handling support for individual modules', add the following line to -their respective {@code Android.mk} files.
- --APP_CPPFLAGS += -fexceptions -- -
In all versions of the NDK later than NDKr5, the NDK toolchain allows you to use C++ runtimes -that support RTTI. However, to ensure compatibility with earlier releases, it compiles all C++ -sources with {@code -fno-rtti} by default. - -
To enable RTTI support for your entire app for your entire application, add the following line to -your {@code Application.mk} file: - -
-APP_CPPFLAGS += -frtti -- -To enable RTTI support for individual modules, add the following line to -their respective {@code Android.mk} files: - -
-LOCAL_CPP_FEATURES += rtti -- -Alternatively, you can use: - -
-LOCAL_CPPFLAGS += -frtti -- -
Linking the static library variant of a C++ runtime to more than one binary may result in -unexpected behavior. For example, you may experience:
- -In addition, if you link two shared libraries–or a shared library and an executable– -against the same static runtime, the final binary image of each shared library includes a copy of -the runtime's code. Having multiple instances of runtime code is problematic because of duplication -of certain global variables that the runtime uses or provides internally.
- -This problem does not apply to a project comprising a single shared library. For example, -you can link against {@code stlport_static}, and expect your app to behave correctly. If your -project requires several shared library modules, we recommend that you use the shared library -variant of your C++ runtime.
- -If your app targets a version of Android earlier than Android 4.3 (Android API level 18), -and you use the shared library variant of a given C++ runtime, you must load the shared library -before any other library that depends on it.
- -For example, an app may have the following modules:
- -You must load the libraries in reverse dependency order:
-
- static {
- System.loadLibrary("stlport_shared");
- System.loadLibrary("bar");
- System.loadLibrary("foo");
- }
-
-
-Note: Do not use the {@code lib} prefix when calling -{@code System.loadLibrary()}.
- -STLport is licensed under a BSD-style open-source license. See -{@code $NDK/sources/cxx-stl/stlport/README} for more details about STLport.
- -GNU libstdc++ is covered by the GPLv3 license, and not the LGPLv2 or LGPLv3. For -more information, see -License on the GCC website.
- -LLVM {@code libc++} -is dual-licensed under both the University of Illinois "BSD-Like" license and the MIT license.
diff --git a/docs/html/ndk/guides/cpu-arm-neon.jd b/docs/html/ndk/guides/cpu-arm-neon.jd deleted file mode 100644 index 1d12937c5fb49..0000000000000 --- a/docs/html/ndk/guides/cpu-arm-neon.jd +++ /dev/null @@ -1,109 +0,0 @@ -page.title=NEON Support -@jd:body - -The NDK supports the ARM Advanced SIMD, an optional instruction-set extension of the ARMv7 spec. -NEON provides a set of scalar/vector instructions and registers (shared with the FPU) comparable to -MMX/SSE/3DNow! in the x86 world. To function, it requires VFPv3-D32 (32 hardware FPU 64-bit -registers, instead of the minimum of 16).
- -The NDK supports the compilation of modules or even specific source files with support for NEON. -As a result, a specific compiler flag enables the use of GCC ARM NEON intrinsics and VFPv3-D32 -at the same time.
- -Not all ARMv7-based Android devices support NEON, but devices that do may benefit significantly -from its support for scalar/vector instructions. For x86 devices, the NDK can also translate NEON -instructions into SSE, although with several restrictions. For more information, see -x86 Support for ARM NEON Intrinsics.
- -To have the NDK build all its source files with NEON support, include the following line in -your module definition:
- --LOCAL_ARM_NEON := true -- -
It can be especially useful to build all source files with NEON support if you want to build a -static or shared library that specifically contains NEON code paths.
- -When listing source files for your {@code LOCAL_SRC_FILES} variable, you have the option of -using the {@code .neon} suffix to indicate that you want to build binaries with NEON support. -For example, the following example builds one file with {@code .neon} support, and another -without it:
- --LOCAL_SRC_FILES := foo.c.neon bar.c -- -
You can combine the {@code .neon} suffix with the {@code .arm} suffix, which specifies the 32-bit -ARM instruction set for non-NEON instructions. In such a definition, {@code arm} must come before -{@code neon}. For example: {@code foo.c.arm.neon} works, but {@code foo.c.neon.arm} does not.
- -NEON support only works with the {@code armeabi-v7a} and {@code x86} ABIs. If the NDK build -scripts encounter other ABIs while attempting to build with NEON support, the NDK build scripts -exit. x86 provides partial NEON support via translation header. It is -important to use checks like the following in your -{@code Android.mk} file:
- --# define a static library containing our NEON code -ifeq ($(TARGET_ARCH_ABI),$(filter $(TARGET_ARCH_ABI), armeabi-v7a x86)) -include $(CLEAR_VARS) -LOCAL_MODULE := mylib-neon -LOCAL_SRC_FILES := mylib-neon.c -LOCAL_ARM_NEON := true -include $(BUILD_STATIC_LIBRARY) -endif # TARGET_ARCH_ABI == armeabi-v7a || x86 -- -
Your app must perform runtime detection to confirm that NEON-capable machine code can be run on -the target device. This is because not all ARMv7-based Android devices support NEON. The app can -perform this check using the -{@code cpufeatures} library that comes with -this NDK.
- -You should explicitly check that {@code android_getCpuFamily()} returns {@code -ANDROID_CPU_FAMILY_ARM}, and that {@code android_getCpuFeatures()} returns a value including the -{@code ANDROID_CPU_ARM_FEATURE_NEON flag} set. For example:
- -
-#include <cpu-features.h>
-...
-...
-if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&
- (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0)
-{
- // use NEON-optimized routines
- ...
-}
-else
-{
- // use non-NEON fallback routines instead
- ...
-}
-
-...
-
-
-The source code for the NDK's hello-neon sample provides an example of how to use the -{@code cpufeatures} library and NEON intrinsics at the same time. This sample implements a tiny -benchmark for a FIR filter loop using a C version, and a NEON-optimized one for devices that -support it.
\ No newline at end of file diff --git a/docs/html/ndk/guides/cpu-features.jd b/docs/html/ndk/guides/cpu-features.jd deleted file mode 100644 index 3323efdb719db..0000000000000 --- a/docs/html/ndk/guides/cpu-features.jd +++ /dev/null @@ -1,210 +0,0 @@ -page.title=The cpufeatures Library -@jd:body - -The NDK provides a small library named {@code cpufeatures} that your app can use at runtime to -detect the target device's CPU family and the optional features it supports. It is designed to work -as-is on all official Android platform versions.
- -The {@code cpufeatures} library is available as an import module. To use it, follow the procedure -below:
- --LOCAL_STATIC_LIBRARIES := cpufeatures --
-$(call import-module,android/cpufeatures) -- -
Here is a simple example of an {@code Android.mk} file that imports the {@code cpufeatures} -library:
- --<project-path>/jni/Android.mk: -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := <your-module-name> -LOCAL_SRC_FILES := <your-source-files> -LOCAL_STATIC_LIBRARIES := cpufeatures -include $(BUILD_SHARED_LIBRARY) - -$(call import-module,android/cpufeatures) --
The {@code cpufeatures} library provides two functions. The first function returns the family to -which the device's CPU belongs. Declare it as follows:
- --AndroidCpuFamily android_getCpuFamily(); -- -
The function returns one of the following enums, representing the CPU family/architecture that -the device supports.
-For a 32-bit executable on a 64-bit system, this function returns only the 32-bit value.
- -The second function returns the set of optional features that the device's CPU supports. Declare -it as follows: - -
-uint64_t android_getCpuFeatures(); -- -
The return value takes the form of a set of bit flags, each flag representing one -CPU-family-specific feature. The rest of this section provides information on features for -the respective families.
- -The following flags are available for the 32-bit ARM CPU family:
-This value is equivalent to the {@code VFPv3-D16} instruction set, which provides provides only -16 hardware double-precision FP registers.
The following flags are available for the 64-bit ARM CPU family:
-The following flags are available for the 32-bit x86 CPU family.
-
{@code android_getCpuFeatures()} returns {@code 0} for CPU families for which there are no -listed extensions.
- -The following function returns the maximum number of CPU cores on the target device:
- --int android_getCpuCount(void); -- -
For the complete change history of this library, see the comments in -{@code $NDK/sources/android/cpufeatures/cpu-features.c}, where {@code $NDK} is the root of your -NDK installation.
\ No newline at end of file diff --git a/docs/html/ndk/guides/debug.jd b/docs/html/ndk/guides/debug.jd deleted file mode 100644 index 3c4da3be0af34..0000000000000 --- a/docs/html/ndk/guides/debug.jd +++ /dev/null @@ -1,11 +0,0 @@ -page.title=Debugging Your Project -@jd:body - -After you've built your app, you'll probably need to debug it. This section introduces you to the -NDK's debugging tools.
- -It begins by telling you how to use the -{@code ndk-gdb} tool to debug your code. It closes with an explanation of the -{@code ndk-stack} tool, which helps you use the -ADB logcat tool -as you debug.
\ No newline at end of file diff --git a/docs/html/ndk/guides/graphics/design-notes.jd b/docs/html/ndk/guides/graphics/design-notes.jd deleted file mode 100644 index 272bd2d14c54b..0000000000000 --- a/docs/html/ndk/guides/graphics/design-notes.jd +++ /dev/null @@ -1,121 +0,0 @@ -page.title=Vulkan Design Guidelines -@jd:body - --Vulkan is unlike earlier graphics APIs in that drivers do not perform certain -optimizations, such as pipeline reuse, for apps. Instead, apps using Vulkan must -implement such optimizations themselves. If they do not, they may exhibit worse -performance than apps running OpenGL ES. -
- --When apps implement these optimizations themselves, they have the potential -to do so more successfully than the driver can, because they have access to -more specific information for a given use case. As a result, skillfully -optimizing an app that uses Vulkan can yield better performance than if the -app were using OpenGL ES. -
- --This page introduces several optimizations that your Android app can implement -to gain performance boosts from Vulkan. -
- --When the upward-facing direction of an app doesn’t match the orientation of the device’s -display, the compositor rotates the application’s swapchain images so that it -does match. It performs this rotation as it displays the images, which results -in more power consumption—sometimes significantly more—than if it were not -rotating them. -
- --By contrast, rotating swapchain images while generating them results in -little, if any, additional power consumption. The -{@code VkSurfaceCapabilitiesKHR::currentTransform} field indicates the rotation -that the compositor applies to the window. After an app applies that rotation -during rendering, the app uses the {@code VkSwapchainCreateInfoKHR::preTransform} -field to report that the rotation is complete. -
- --On most mobile GPU architectures, beginning and ending a render pass is an -expensive operation. Your app can improve performance by organizing rendering operations into -as few render passes as possible. -
- --Different attachment-load and attachment-store ops offer different levels of -performance. For example, if you do not need to preserve the contents of an attachment, you -can use the much faster {@code VK_ATTACHMENT_LOAD_OP_CLEAR} or -{@code VK_ATTACHMENT_LOAD_OP_DONT_CARE} instead of {@code VK_ATTACHMENT_LOAD_OP_LOAD}. Similarly, if -you don't need to write the attachment's final values to memory for later use, you can use -{@code VK_ATTACHMENT_STORE_OP_DONT_CARE} to attain much better performance than -{@code VK_ATTACHMENT_STORE_OP_STORE}. -
- --Also, in most render passes, your app doesn’t need to load or store the -depth/stencil attachment. In such cases, you can avoid having to allocate physical memory for -the attachment by using the {@code VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT} -flag when creating the attachment image. This bit provides the same benefits as does -{@code glFramebufferDiscard} in OpenGL ES. -
- --When allocating device memory, apps must choose a memory type. Memory type -determines how an app can use the memory, and also describes caching and -coherence properties of the memory. Different devices have different memory -types available; different memory types exhibit different performance -characteristics. -
- --An app can use a simple algorithm to pick the best memory type for a given -use. This algorithm picks the first memory type in the -{@code VkPhysicalDeviceMemoryProperties::memoryTypes} array that meets two criteria: -The memory type must be allowed for the buffer -or image, and must have the minimum properties that the app requires. -
- --Mobile systems generally don’t have separate physical memory heaps for the -CPU and GPU. On such systems, {@code VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT} is not as -significant as it is on systems that have discrete GPUs with their own, dedicated -memory. An app should not assume this property is required. -
- --If you have resource bindings that change at different frequencies, use -multiple descriptor sets per pipeline rather than rebinding all resources for -each draw. For example, you can have one set of descriptors for per-scene -bindings, another set for per-material bindings, and a third set for -per-mesh-instance bindings. -
- --Use immediate constants for the highest-frequency changes, such as changes -executed with each draw call. -
- diff --git a/docs/html/ndk/guides/graphics/getting-started.jd b/docs/html/ndk/guides/graphics/getting-started.jd deleted file mode 100644 index 0c2d939f1182e..0000000000000 --- a/docs/html/ndk/guides/graphics/getting-started.jd +++ /dev/null @@ -1,201 +0,0 @@ -page.title=Vulkan Setup -@jd:body - - --This document explains how to get started with the Vulkan graphics library by downloading, -compiling, and running several sample apps. -
- --Before beginning, make sure you have the right hardware and platform version prepared. You should -be using one of the following devices, running at least Android N, Developer Preview 2: -
- --You can confirm your Android version by going to the Settings menu, and -selecting About <device> > Android Version. -Once you’ve confirmed that you have the right hardware and platform version set up, you can -download the necessary software. -
- --Before getting started, you must download several tools and other software. -
- --../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \ - APP_STL:=c++_shared APP_ABI=all libshaderc_combined -- -You can specify {@code APP_STL} as {@code gnustl_static}, -{@code gnustl_shared}, {@code c++_static}, -or {@code c++_shared}.
-$ git clone https://github.com/googlesamples/vulkan-basic-samples.git --
-$ ./update_external_sources.sh -s -g --
-To confirm that Vulkan is set up properly, you can test it with -the set of Vulkan API samples provided partly for that purpose. Follow these steps to -build and execute these samples: -
- --$ cd API-samples -$ cmake -DANDROID=ON -DANDROID_ABI=[armeabi-v7a|arm64-v8a| x86|x86_64|all(default)] --
You may see an error about missing components or missing SDK version. -Ignore this error message, and follow the installation prompts.
- -After several minutes, the Project pane should -resemble the window shown in Figure 1.
- -
-
--Figure 1. Project pane displaying samples after they've been imported. - -
To compile your project, follow these steps:
- -
-
--Figure 2. Selecting an individual project to compile. - -
Note: -Additional -tutorial samples illustrate the use of shaders compiled with off-line -compilation integrated into Android Studio. For simplicity, each tutorial -is self-contained, and builds according to standard Android Studio -build procedures. -
- -To run your project, choose an APK to run by choosing Run > Run <project-name>.
- -To debug an APK, choose Run > -Debug <project-name>. For each project, -there’s a Java version and a native (C or C++) version. Run the -native version of the app. For example, for drawcube, -run drawcube-native.
- -Most of the samples have simple functionality, and most stop -automatically after running. The drawcube example is one of -the more visually interesting examples. When you run it, it -should display the image in Figure 3
. - -
-
--Figure 3. The successfully compiled program runs and produces a display. -
- --The samples use a dynamic loader helper function defined in {@code vulkan_wrapper.h/cpp} to -retrieve Vulkan API pointers using {@code dlopen()} and {@code dlsym()}. It does this rather -than statically linking them with {@code vulkan.so}. -
- --Using this loader allows the code to link against API level 23 and earlier versions of the platform, which don’t include the {@code vulkan.so} shared library, but can run on devices that support Vulkan API. -
- --The following snippet shows how to use the dynamic loader. -
- --#include "vulkan_wrapper.h" // Include Vulkan_wrapper and dynamically load symbols. -... -// Before any Vulkan API usage, -InitVulkan(); -diff --git a/docs/html/ndk/guides/graphics/index.jd b/docs/html/ndk/guides/graphics/index.jd deleted file mode 100644 index cbd4b9ca802cd..0000000000000 --- a/docs/html/ndk/guides/graphics/index.jd +++ /dev/null @@ -1,36 +0,0 @@ -page.title=Vulkan Graphics API -@jd:body - - -
The Android platform includes an Android-specific implementation of the -Vulkan API -specification from the Khronos Group. Vulkan is a -low-overhead, cross-platform API for high-performance, 3D graphics. It provides tools -for creating high-quality, real-time graphics in -applications. Vulkan also provides advantages such as reducing -CPU overhead and providing support for the -SPIR-V Binary -Intermediate language. -
- --This section begins with information on how to -get started using Vulkan in your -Android app. Next, it provides useful information that you should know about -Vulkan design guidelines -on the Android platform. From there, it explains how -to use Vulkan's shader compilers. -Last, it teaches you how to use -validation layers -to help assure stability in apps using Vulkan. -
- --For more general information about this cross-platform API specification, see -Khronos's - -Vulkan Overview. -You can also keep up with the latest Vulkan-related developments at the -Vulkan -news page. -
diff --git a/docs/html/ndk/guides/graphics/shader-compilers.jd b/docs/html/ndk/guides/graphics/shader-compilers.jd deleted file mode 100644 index c51c21c5b7d99..0000000000000 --- a/docs/html/ndk/guides/graphics/shader-compilers.jd +++ /dev/null @@ -1,194 +0,0 @@ -page.title=Vulkan Shader Compilers on Android -@jd:body - --A Vulkan app must manage shaders differently from the way an OpenGL ES app does so: -In OpenGL ES, you provide a shader as a set of strings forming the source text of a -GLSL shader program. By contrast, the Vulkan API requires you to provide a shader in -the form of an entry point in a SPIR-V module. -
- --The NDK includes a runtime library for compiling GLSL into SPIR-V. -The runtime library is the same as the one in the -Shaderc open source project, and use the same -Glslang GLSL reference compiler as a -back end. By default, the Shaderc version of the -compiler assumes you are compiling for Vulkan. After checking whether your code is valid for -Vulkan, the compiler automatically enables the {@code KHR_vulkan_glsl} extension. The Shaderc -version of the compiler also generates Vulkan-compliant SPIR-V code. -
- --You can choose to compile SPIR-V modules into your Vulkan app during development, a -practice called ahead-of-time, or AOT, compiling. Alternatively, -you can have your app compile them from shipped or procedurally generated shader -source when needed during runtime. This practice is called runtime compiling. -
- --The rest of this page provides more detail about each practice, and then explains -how to integrate shader compilation into your Vulkan app. -
- --For AOT compilation, we recommend the glslc command-line compiler from GLSL to SPIR-V. -This compiler is available from the Shaderc -project.Many of its command-line options are similar to those of GCC and Clang, allowing -you to integrate glslc into build systems easily. -
- --The glslc tool compiles a single-source file to a SPIR-V module with a single shader -entry point. By default, the output file has the same name as that of the source file, -but with the {@code .spv} extension appended. -
- --You use filename extensions to tell the glslc tool which graphics shader stage to compile, -or whether a compute shader is being compiled. For information on how to use these filename -extensions, and options you can use with the tool, see - -Shader stage specification in the - -glslc manual. -
- --For JIT compilation of shaders during runtime, the NDK provides the libshaderc library, -which has both C and C++ APIs. -
- --C++ applications should use the C++ API. We recommend that apps in other languages -use the C API, because the C ABI is lower level, and likely to provide better stability. -
- --The following example shows how to use the C++ API: -
- -
-#include <iostream>
-#include <string>
-#include <vector>
-#include <shaderc/shaderc.hpp>
-
-std::vector<uint32_t> compile_file(const std::string& name,
- shaderc_shader_kind kind,
- const std::string& data) {
- shaderc::Compiler compiler;
- shaderc::CompileOptions options;
-
- // Like -DMY_DEFINE=1
- options.AddMacroDefinition("MY_DEFINE", "1");
-
- shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(
- data.c_str(), data.size(), kind, name.c_str(), options);
-
- if (module.GetCompilationStatus() !=
- shaderc_compilation_status_success) {
- std::cerr << module.GetErrorMessage();
- }
-
- std::vector<uint32_t> result(module.cbegin(), module.cend());
- return result;
-}
-
-
-
-
--You can integrate the Vulkan shader compiler into your app using either the project's -{@code Android.mk} file or Gradle. -
- --Perform the following steps to use your project's {@code Android.mk} -file to integrate the shader compiler. -
- --include $(CLEAR_VARS) - ... -LOCAL_STATIC_LIBRARIES := shaderc - ... -include $(BUILD_SHARED_LIBRARY) - -$(call import-module, third_party/shaderc) --
-$ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \ -APP_STL:=<stl_version> APP_ABI=all libshaderc_combined -- -
-This command places two folders in <ndk_root>/sources/third_party/shaderc/. The directory -structure is as follows: -
- -
-include/
- shaderc/
- shaderc.h
- shaderc.hpp
-libs/
- <stl_version>/
- {all of the abis}
- libshaderc.a
-
--The STL that you use to build your program must match the {@code stl} specified in -{@code stl_version}. -Only {@code c++_static}, {@code c++_shared}, {@code gnustl_static}, and -{@code gnustl_shared} are supported. -
diff --git a/docs/html/ndk/guides/graphics/validation-layer.jd b/docs/html/ndk/guides/graphics/validation-layer.jd deleted file mode 100644 index 1a7d83246d01c..0000000000000 --- a/docs/html/ndk/guides/graphics/validation-layer.jd +++ /dev/null @@ -1,433 +0,0 @@ -page.title=Vulkan Validation Layers on Android -@jd:body - --Most explicit graphics APIs do not perform error-checking, because doing so can result in a -performance penalty. Vulkan provides error-checking in a manner that lets you use this feature at -development time, but exclude it from the release build of your app, thus avoiding the penalty when -it matters most. You do this by enabling validation layers. Validation layers intercept -or hook Vulkan entry points for various debug and validation purposes. -
- --Each validation layer can contain definitions for one or more of these entry points, and -intercepts the entry points for which it contains definitions. When a validation -layer does not define an entry point, the system passes the entry point on to the next -layer. Ultimately, an entry point not defined in any layer reaches the driver, the -base level, unvalidated. -
- --The Android SDK, NDK, and Vulkan samples include Vulkan validation layers for -use during development. You can hook these validation layers into the graphics stack, allowing -them to report validation issues. This instrumentation allows you to catch and fix misuses -during development. -
- --This page explains how to: -
- NDK release 12 and higher includes pre-built validation layer binaries. At - instance and device creation time, when requested by your application, the - Vulkan loader finds them in the APK installed location and loads them. -
- -- To use the pre-built validation layer binaries, either modify the gradle build - configuration of your project or manually add the binaries into the JNI - libraries directory of your project. -
- - -- You can add the validation layer your project using either Andorid Studio's - support for CMake and Ndk-build, or using Studio's experimental plugin for - Gradle. In general, you should use the CMake and Ndk-build configuration. -
- - -- To add the libraries using Android Studio's support for CMake/Ndk-build, - add the following to your project's gradle configuration: -
- -
-sourceSets {
- main {
- jniLibs {
- srcDir "${your-ndk-dir}/sources/third_party/vulkan/src/build-android/jniLibs"
- }
- }
-}
-
-- To add the libraries using Android Studio's experimental plugin for Gradle, - add the following to your project's gradle configuration: -
- -
-sources {
- main {
- jniLibs {
- source.srcDir "${your-ndk-dir}/sources/third_party/vulkan/src/build-android/jniLibs"
- }
- }
-}
-
-
-- If configuring your project's gradle build file is not working, you can - manually add the validation layer binaries to your project's JNI libraries - directory by using the following command line options: -
- -
-$ cd ${your-app-project-root}
-$ mkdir -p app/src/main
-$ cp -fr ${your-ndk-dir}/sources/third_party/vulkan/src/build-android/jniLibs app/src/main/
-
-
-
--If your app needs the latest validation layer, you can pull the latest source from the Khronos Group - -GitHub repository and follow the build instructions there. -
- --Regardless of whether you build with NDK's prebuilt layers or you build from the latest source code, -the build process produces final file structure like the following: -
- --src/main/jniLibs/ - arm64-v8a/ - libVkLayer_core_validation.so - libVkLayer_device_limits.so - libVkLayer_image.so - libVkLayer_object_tracker.so - libVkLayer_parameter_validation.so - libVkLayer_swapchain.so - libVkLayer_threading.so - libVkLayer_unique_objects.so - armeabi-v7a/ - libVkLayer_core_validation.so - ... -- -
-The following example shows how to verify that your APK contains the validation layers -as expected: -
- --$ jar -xvf project.apk - ... - inflated: lib/arm64-v8a/libVkLayer_threading.so - inflated: lib/arm64-v8a/libVkLayer_object_tracker.so - inflated: lib/arm64-v8a/libVkLayer_swapchain.so - inflated: lib/arm64-v8a/libVkLayer_unique_objects.so - inflated: lib/arm64-v8a/libVkLayer_parameter_validation.so - inflated: lib/arm64-v8a/libVkLayer_image.so - inflated: lib/arm64-v8a/libVkLayer_core_validation.so - inflated: lib/arm64-v8a/libVkLayer_device_limits.so - ... -- - -
The Vulkan API allows an app to enable both instance layers and device layers.
- --A layer that can intercept Vulkan instance-level entry points is called an instance layer. -Instance-level entry points are those with {@code VkInstance} or {@code VkPhysicalDevice} -as the first parameter. -
- --You can call {@code vkEnumerateInstanceLayerProperties()} to list the available instance layers -and their properties. The system enables instance layers when {@code vkCreateInstace()} executes. -
- --The following code snippet shows how an app can use the Vulkan API to programmatically enable and -query an instance layer: -
- -
-// Get instance layer count using null pointer as last parameter
-uint32_t instance_layer_present_count = 0;
-vkEnumerateInstanceLayerProperties(&instance_layer_present_count, nullptr);
-
-// Enumerate instance layers with valid pointer in last parameter
-VkLayerProperties* layer_props =
- (VkLayerProperties*)malloc(instance_layer_present_count * sizeof(VkLayerProperties));
-vkEnumerateInstanceLayerProperties(&instance_layer_present_count, layer_props));
-
-// Make sure the desired instance validation layers are available
-// NOTE: These are not listed in an arbitrary order. Threading must be
-// first, and unique_objects must be last. This is the order they
-// will be inserted by the loader.
-const char *instance_layers[] = {
- "VK_LAYER_GOOGLE_threading",
- "VK_LAYER_LUNARG_parameter_validation",
- "VK_LAYER_LUNARG_object_tracker",
- "VK_LAYER_LUNARG_core_validation",
- "VK_LAYER_LUNARG_device_limits",
- "VK_LAYER_LUNARG_image",
- "VK_LAYER_LUNARG_swapchain",
- "VK_LAYER_GOOGLE_unique_objects"
-};
-
-uint32_t instance_layer_request_count =
- sizeof(instance_layers) / sizeof(instance_layers[0]);
-for (uint32_t i = 0; i < instance_layer_request_count; i++) {
- bool found = false;
- for (uint32_t j = 0; j < instance_layer_present_count; j++) {
- if (strcmp(instance_layers[i], layer_props[j].layerName) == 0) {
- found = true;
- }
- }
- if (!found) {
- error();
- }
-}
-
-// Pass desired instance layers into vkCreateInstance
-VkInstanceCreateInfo instance_info = {};
-instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
-instance_info.enabledLayerCount = instance_layer_request_count;
-instance_info.ppEnabledLayerNames = instance_layers;
-...
-
-
--A layer that can intercept device-level entry points is called a device layer. Device-level entry -points are those whose first parameter is {@code VkDevice}, {@code VkCommandBuffer}, -or {@code VkQueue}. The list of -device layers to enable is included in the {@code ppEnabledLayerNames} field of the -{@code VkDeviceCreateInfo} -struct that the app passes into {@code vkCreateDevice()}. -
- --You can call {@code vkEnumerateDeviceLayerProperties} to list the available layers -and their properties. The system enables device layers when it calls {@code vkCreateDevice()}. -
- --The following code snippet shows how an app can use the Vulkan API to programmatically enable a -device layer. -
- -
-
-// Get device layer count using null as last parameter
-uint32_t device_layer_present_count = 0;
-vkEnumerateDeviceLayerProperties(&device_layer_present_count, nullptr);
-
-// Enumerate device layers with valid pointer in last parameter
-VkLayerProperties* layer_props =
- (VkLayerProperties *)malloc(device_layer_present_count * sizeof(VkLayerProperties));
-vkEnumerateDeviceLayerProperties(physical_device, device_layer_present_count, layer_props));
-
-// Make sure the desired device validation layers are available
-// Ensure threading is first and unique_objects is last!
-const char *device_layers[] = {
- "VK_LAYER_GOOGLE_threading",
- "VK_LAYER_LUNARG_parameter_validation",
- "VK_LAYER_LUNARG_object_tracker",
- "VK_LAYER_LUNARG_core_validation",
- "VK_LAYER_LUNARG_device_limits",
- "VK_LAYER_LUNARG_image",
- "VK_LAYER_LUNARG_swapchain",
- "VK_LAYER_GOOGLE_unique_objects"
-};
-
-uint32_t device_layer_request_count =
- sizeof(device_layers) / sizeof(device_layers[0]);
-for (uint32_t i = 0; i < device_layer_request_count; i++) {
- bool found = false;
- for (uint32_t j = 0; j < device_layer_present_count; j++) {
- if (strcmp(device_layers[i],
- layer_props[j].layerName) == 0) {
- found = true;
- }
- }
- if (!found) {
- error();
- }
-}
-
-// Pass desired device layers into vkCreateDevice
-VkDeviceCreateInfo device_info = {};
-device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
-device_info.enabledLayerCount = device_layer_request_count;
-device_info.ppEnabledLayerNames = device_layers;
-...
-
-
--The Debug Report extension {@code VK_EXT_debug_report} allows your application to control -layer behavior when an event occurs.
- --Before using this extension, you must first make sure that the platform supports it. -The following example shows how to check for debug extension support and -register a callback if the extension is supported. -
- -
-// Get the instance extension count
-uint32_t inst_ext_count = 0;
-vkEnumerateInstanceExtensionProperties(nullptr, &inst_ext_count, nullptr);
-
-// Enumerate the instance extensions
-VkExtensionProperties* inst_exts =
- (VkExtensionProperties *)malloc(inst_ext_count * sizeof(VkExtensionProperties));
-vkEnumerateInstanceExtensionProperties(nullptr, &inst_ext_count, inst_exts);
-
-const char * enabled_inst_exts[16] = {};
-uint32_t enabled_inst_ext_count = 0;
-
-// Make sure the debug report extension is available
-for (uint32_t i = 0; i < inst_ext_count; i++) {
- if (strcmp(inst_exts[i].extensionName,
- VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
- enabled_inst_exts[enabled_inst_ext_count++] =
- VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
- }
-}
-
-if (enabled_inst_ext_count == 0)
- return;
-
-// Pass the instance extensions into vkCreateInstance
-VkInstanceCreateInfo instance_info = {};
-instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
-instance_info.enabledExtensionCount = enabled_inst_ext_count;
-instance_info.ppEnabledExtensionNames = enabled_inst_exts;
-
-PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT;
-PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT;
-
-vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)
- vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
-vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)
- vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT");
-
-assert(vkCreateDebugReportCallbackEXT);
-assert(vkDestroyDebugReportCallbackEXT);
-
-// Create the debug callback with desired settings
-VkDebugReportCallbackEXT debugReportCallback;
-if (vkCreateDebugReportCallbackEXT) {
- VkDebugReportCallbackCreateInfoEXT debugReportCallbackCreateInfo;
- debugReportCallbackCreateInfo.sType =
- VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
- debugReportCallbackCreateInfo.pNext = NULL;
- debugReportCallbackCreateInfo.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
- VK_DEBUG_REPORT_WARNING_BIT_EXT |
- VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
- debugReportCallbackCreateInfo.pfnCallback = DebugReportCallback;
- debugReportCallbackCreateInfo.pUserData = NULL;
-
- vkCreateDebugReportCallbackEXT(instance, &debugReportCallbackCreateInfo,
- nullptr, &debugReportCallback);
-}
-
-// Later, when shutting down Vulkan, call the following
-if (vkDestroyDebugReportCallbackEXT) {
- vkDestroyDebugReportCallbackEXT(instance, debugReportCallback, nullptr);
-}
-
-
-
--Once your app has registered and enabled the debug callback, the system routes debugging -messages to a callback that you register. An example of such a callback appears below: -
- - -
-#include <android/log.h>
-
-static VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
- VkDebugReportFlagsEXT msgFlags,
- VkDebugReportObjectTypeEXT objType,
- uint64_t srcObject, size_t location,
- int32_t msgCode, const char * pLayerPrefix,
- const char * pMsg, void * pUserData )
-{
- if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
- __android_log_print(ANDROID_LOG_ERROR,
- "AppName",
- "ERROR: [%s] Code %i : %s",
- pLayerPrefix, msgCode, pMsg);
- } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
- __android_log_print(ANDROID_LOG_WARN,
- "AppName",
- "WARNING: [%s] Code %i : %s",
- pLayerPrefix, msgCode, pMsg);
- } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
- __android_log_print(ANDROID_LOG_WARN,
- "AppName",
- "PERFORMANCE WARNING: [%s] Code %i : %s",
- pLayerPrefix, msgCode, pMsg);
- } else if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
- __android_log_print(ANDROID_LOG_INFO,
- "AppName", "INFO: [%s] Code %i : %s",
- pLayerPrefix, msgCode, pMsg);
- } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
- __android_log_print(ANDROID_LOG_VERBOSE,
- "AppName", "DEBUG: [%s] Code %i : %s",
- pLayerPrefix, msgCode, pMsg);
- }
-
- // Returning false tells the layer not to stop when the event occurs, so
- // they see the same behavior with and without validation layers enabled.
- return VK_FALSE;
-}
-
-
-
-
diff --git a/docs/html/ndk/guides/guides_toc.cs b/docs/html/ndk/guides/guides_toc.cs
deleted file mode 100644
index 09b2a120fcaa9..0000000000000
--- a/docs/html/ndk/guides/guides_toc.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/html/ndk/guides/images/NDK_build_string.png b/docs/html/ndk/guides/images/NDK_build_string.png
deleted file mode 100644
index 338378bca6f0e6feeba5d4e9674701fd6aae1f08..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 22494
zcmXtfWmFtp*DM~~-2(&&?j9s~g1fuBJA-?0cX!tW9o*f0aDqF7bIJ35_xzYOy;iT8
z?$cXpS5-$S$Vs9g5+XuCK%huVi77!qK;C_PPlJd0_;lhvbc29UFP0V)QSn$k^Zlfw
zGt~S>{l3@9DiE;;r&VsjtM3->+w%BrKT=m%B`(EP!MIHFiy_r&Ul_Haj%!p6 znq#dwns-`zcz^F&D$}EPnqCJ<(@hZ$@awq}6Cs!K$1G**<+mXH+WG#5a4g4}uIh$! z_nzbZo;K3wIS&$hg$b#kmddpS0R2|lBG@XNw@gH<%u!Pc>u;P>f|+)~24KEWDN$`n zsiCqJ&lE4-B3A`X8Qgqoz9J~J%Bp(7moup^xO!Qip*J>`GUIDp>uHdjorUp_qQN=`xo;XDlC%OdYaT#>ecj z?f;AxydU-|ecm@*#E_?x`5;R7{j%4Ll-JlW5U&j?T(qT~)%o%1clZ4N>^Cs}N)YuB zUXM@v^B aQNwn&iZUG?8j4*>E?Xv!Bj!rL410 z3t$kCWI;fr42A%nU7j9j|Kx-9r<;qD3j;xnEdu$&Em|J}(GT@^|3vai`^^Wd_xoXi z0@<{-uh7%@(}p@IM-=@Vr#4LdXl#RN{DZe!`oocTOHE_=R#Q4zpj1}1aU^l` yu;0{A4@sGl`&a+VH%6|2UXX( z+iKCo(ei^eVLT6W>9R*!+L&4s6Cyly64JH7jYAjMY_MD(yhV65EO`o921p&(906K` zP#wP42r^U3tcpC`A?-_s9+c$O?d)E#iKCYffFPYPR|D=5?;!3<5T!D>{0c)LzM(1b zf8+Ub%*&f@i0HBH$+4~ufa{`GQ2Yfot4OKrqhze%%98 mZy`nxBG z&{s_!Cei>X*wLpPii?QrN!nc(Q|yh95=BdSpBJY1PE;b1bypSsvZ8DnPP}L6dEZDo zYZ8&Eu|-KbHp|=@C0rK%2PYZR?2yR;SV)AQg_c>Idi|jxF5@0rK9-pJEmInj@r-@q zOQ#YFij;!g%KT)qo31h+CRt|Q4e-JW&eHcIq(6U^=kq;%4v_<2jt(#GXIj_dK)hL9 z&}3vz{P&(xo ?S6m1qsOX0c>OA_O;Ba(izmj*us3Xt?i4^;w0q~+DyX}P`;^PRNg!Cye zm00dzqcyl{nhV+{=jQ0S+OtBe+Yg+vhKQ@b(*KM>u(Y JNbL} !Fra}7hC$N`;$Af7@lD;Lm z{PB_O1@op{g)T_$aqoT8Rz#gt&~UP+=n^sn5~CZPi0|m`v0< RbJF!bgca0$hbpf w@|LCTsEaX(R?B4vIS-h$slpZcPJ zyksDA-xUlCrgVb33QEQI*HwP|*Vf9 fuMXeUhL#@Q zZ}Hx5hQ4j#bvH#B!ULHI?=tu(dfxWUfnMt3&?3~jd#E;jSNvPx-7r_J*>BagN%}0) z1X!qlt@VNV<^ebnr?;*~DDo-Dj$;DRi2Pb_%@ cjRp7wO0m{U0 zb&Jx?jgrW4{k=%kp~Nj);n_LWi#3 JI|rUtlCkKP2aE3^xml z@88qNEH$#wv3rTIXkeZ(d3~r8lQA-fw{Ns=*fZd>3dY5t%K153^QhU|q6CTYQsF+F zUOP#qL#~*fo)I7MmW|+v5&{mQ=Nmp^jnL7OlmJLdGzsMlba}rr o|txZh5AcQBBOHi@Q9J4hue4(eZjg~-aHp1MyT`E z=Z53v5G!Fdh1KMsh#1UMoVK_nM~xH63?}>A>oS)v0~L?_%!N&R!d+J|_ji S ziX1IbI=8obwP0E;Toy^2PNf|zS2#n<#+6#EG`#oeJPjHp Xs`WRUZy~2l>9loPQ5$h VgS+`+M}#N%Sfpum(^F6B2~G;Yhra{bz4-_mBLBswRKuSrYa zqVd+P(0da8iRU`stYV)W1M{p_qIsDq{~F4F1A|fJ<3?X!VNH#lr)E7t+O56Nv&wzm z5xg~=!aL`Ra`_({B;8mebORRr;Zcg-N|c(dk2iWg(~tdx$0WiEWSFQG)aILeKZ!*# zmFF!lqoDLOXU6`DJE`9k^WBX9j0x4^l)sKjUDH}Om9anwybTkWX2mmZ_|HK9F@JCZ zV`GI_uD)^iFwuXlu^ynf`Ie%0hxnx#*x1yRHBKB49Jf^Z$kuUY%;+j+!Jho2 0IEmDd<~MV>lW
M~xRUHjbS4OcDNr(0#1!V0Hv53_}G zTeoLuendoxLdyLyi%U2($y^Wxt*V7@6zTm_#l|nLWeI_n(_PoJII%KmdYK2G(N|*E zWi^;g1m4oO-Qlto)zyDD$$c;n``UOenU?y6%ISQP*&gfp%%G=iNgrtMvfXC9x8HTf zcPJYVErF? Wn61ofL-RMY7j9XFb)i8Qp$@IT>bm0{XpW7((-pDMD(4yHD&p zuWEbs(%DTA*+*7x2U5GbuV5xaX@vN!hWAh
+^F-otZah_R1t( zjw0LvnQC+T@u$zTKmF)z224W-K%E99R%erD&cv>$r#?3*pg_T8qR-?xC0FewPwAf! z{ICKSU;Zjs&42j>EU3Ld%f@oK`vs#_TN4RsWPM%>Z{h1xR>gDde}-au6|UW2Ycf9N zA@uW~?#tUEC#*7Zfy>8jp;EG`X#Tx#19-Mr+#tzu|Jp}044!yBW}pih+{;${HjD>< z%McCc%L+VjzYtqv;4;KX`81&^pWIT!@i-}tM~>tOH8 CWIIqX@> z=I@{H-7xN&4*p*NXcm|0n6r-Q$25*JxXg3A5Az1HwM+{2kLsZ5+%u RfKhKEubsXB*ju_Z3H5sf|RZkIB9U~hzgc$)ZKM?-yrimh)cGj$5E)isfA z1ZHl)9BOGOkFvR0s>q{vX#Z^|&0LHy*71@EK^zSLcVo|c_e9ybPa=rX-eWDrA*zn| zS1$&;48dT1pPFrZd49B`Rxxu)^`p0QIw_Z|kL!md?=>=hX83*mM*d2E=M3ZbesFYZ zMtV|Rg-RfB*yuwCv<;8#XeJKJ=3+=>!0$&s*flan|Mc^-jQSuIvuGZZ%3^_0zfavw z6O&l 6V{>))!vW!dY6bRN~z bdUT}ug$=RQ-6-+6;&|K4vR RB-FRFkc{+M7~DDe@opBQ<+NeIbv;WAN2qheX|Upoo?B(AgZd3Peusc~ zy7*mJQv(-&>t1=Co2JcV-CftnXp`99$eU)Rjg>ZbajQdeb&dJyA$^l;367rQ2;!u3 z6G8f{FJJ(_&mkN&=XeB}cejdIHF)YsEv84dCerL&WxP`ude%-;YZ^rDWV-}AUiEke z_?fU>>1Sr`-gEaoWNAsP(y$PbP{{H!81i7toe2=EqUtc-0 z%I_b&^6%IF;+@tokbddKzp1>k-vC*`7 gpKYo1mjUOuS zy{vs)<$#@kZMgC0mI0QgS7fs^t`5(}`WcY3s 1e1gvD)8!^Q{` ^ zEt9f~LZpwu^MCrnB_><84`qH V zmrVB>4u;!fmXSAJemyVfjPWH5
!IRtB8F(qO=d{0yTnqA1}XqczBeRl`SqVDx#{|I@h&76(ESEh6A#Q z`_oT =Ep62I$reHGI)Na>9cq_l z$xE_KV-ndcjOGXDmPYbz{m4MQ=MShmC9JLhYxE+rckfR5W@ZbJ-?s`~17!C+T4>pT zKs3%9l{_<$OfPVSW6#nVK|B$FegS$1=p&$~tnU6qq2}e~&CSjI!2APh1of_e`Rdm5 zJD;z78Iv?U{Pvex=8Ge^*!1GclCmWPY42#3Z7eg`nOnBYc5#nhk&LHZD;F*+u0Tz<*m4t7O^N3;)cK(V}ps0jqoGnBo(Pr~RI zEg*BFL(!4Z{mhAHmEY-Wdq7ej!zPZK+Enm+T NJ&2!OIB0(!@KerM1b zwY9b1Z&CLIpDkK@{}GwO{H~sWdKC}4{{ZVFml-tr *&8mXb4wgW<;n}HKkwoweF(A_zAi#KuH+~(Kt`&4gG5N7t~g}WQ{)4f4~T^nz9 z6C#6w34h1c`|Uk}zH3=#Z+b_{GE|gFkrj)5`*wY?Gp|c_i#{h#roUr*RcWL ^ zy&9$$=fNnUC-uPI{U4t`FT!W--L>mhZubJEst7N8_g8*gG&lxcH2U<@9j-xf8$2nF zy?FP2gR_$pBqk`2iQj8#YZliDBI^9o%70}U@wYIcEw7eZT4nax(uxM9sb(+J*0o&~ z-3*M86-Dk9#q5PF@U;T!{lWMhu8;hl{Lba{ojGk*VXf^^jE#?q @XkyJV} N*8DoZBG1ED;Ck{JjttNYU);;e)<>xTj8SNeu_mQ?M2v-!B0m3iM z>*97d0?zh!umnmkv!g0|KJHoll_mWx3Ki8j+IBBgf~;t%*~wO69sQ_r61jcJ%}?ui z-^5oVoOlPd{uyLutZV;nOG<)Wl>9~R*l3$H4s!Hg|DGo$D&E`WWpCYn*CMn^mOL{% zyWwkEnq%77L|uUV4rPl3^o|YuUR_;1J3BkGCiBb4>Eo&(r@pq~EUPyvKJK)p({z8< z=f@7A@wiJ4QLLWE*!%ZP9Q|- k0Ib@%VbNRdm{WC#|24oHw$;-Z z<@K0pU%#$vjunaQ^tB7!)q^TY$#$w)a(>68yPWn)WKyVU&gTLv@bw{ft{E8BogXo2 z9dGY4?ay*^&%qx#y^qACtGv6LGmxcWkWC!yN%gbP@u@I4dZuKMe$Gs%+*5PSCUc;- zkG#$q1-~cM6Tt~4I-V^Un6o;4X_|1?ErTp>@D1&nb+o!{ZK5@@h_n`^hJ=MhBo{37 zr`kl-&JV=ehmySP%n@YV)hZGbV2NHvyzQ-e15MM3EA`&S?W_DgcI{%yiBDedNKGC? zRy5SCfoh(RWSdMd-S^@l3%~WBaIAxRk5m@W(9@@vxgT&1&8_JnXP-ZE(P!r|yP2No zyK 1J8RnLW8A=BVpn@R*RwBLn%U^> z2~Nqp8k`~>VK^HfcMFc2n3xz7izX%}MWdq0iHXtC2WkQJKFsf1`FxY7r)O+z?DX{N zZwz(SlMl1=#!u(Ek(EzaM8LHU`qa0YW6G^W`&cx6H36`)`Bc`^JbpiY+=yOzUe%&N z@3iVr*^M(s!PoUHWc;qDU3BrBS2e{$Yj=Ts6UTuPUlr?cK9in*MfGwqxyH-zYSDn5 zo|aH{Rk()Dxpp}ZzkW|gLz|NK-`GKGjW)bit#j(Ud~-+3au3xto6LcJ>_&diUFG*k zyGvsT0tW0;gMrTB^v*!rXzZMwwNH%4xwzJm#o3uDATzU5eTmNL^rap@hb)e*zVZA} zjDb@+CeRx2yO+IHpTAKU1qrk~(xX@q1=!Xq5*h3GIqL6A$g+;QJy03G{%0`uzJ9@} zHSxS_RG#t^zVDzmw1S8SVvd} Nx1Kz;moAu8~J_f*GFEze!Zzl)|X`a1CzR962q)7 zMcEpf0*$q$3AL{(?%rjWV8tzng;QsYl*OHnsD%4pcMZ!Z@OIEMx^r~*TQ>r3YT5Xc z^S#b!fuAi0aEr)IcQ =-|#gxmuDm;#_m3C42cQKmI&w_8~DAfv`iwAh#wR%>IKKK@rmi_DXCN{8K0Px zi~+@@bV4#QDc4EI$0ujy0kKFlDV2)EW6~K}%GkJ6rXH7o{}U4N6fh+M2B$>p?1LIX zy^o#WfwZ)=D5AQW8uWsg@S<`TEn9KPEuZvs{m{0|D35~50!#aNMV>DX>8ue0LCrY< z{I}E9N_KV!zqD;MZ-J bmXOI}Lv01AgyWS^46XJ;iB(wJjoR>+8?b z{QGuWAL*7$OKK!N!4I~rGP|fCKPj ~SY|Q+-O-h4;=He){R5X%My1 z@4IW%IDsVko;rN|SVF_Fq0S}9?~e(+gXC*PRM)J5_ #05yTS# z=og@OfIb3xin7<>hwzmZmASdOdAWH%3_x9=Mo{k$wtuAbs=aMq)5hDa-(i+qaeG#N zY&~z#IseERd}PaS<3fI41Cc;3=_KDQrg-L4As`?g2Iw82kAR-?Ft`4YfcpbOe*az+ zPb6c9$UTD)5D=RH^bR8N$FaW{ `4snV)a zps6fxU=3BAIB}XHo>vsnIJvq~ZJb(f>fo+xXO9R521X{nc>YDlfCOZQbK=;sHimST zH&|01kx EJ$vJK4x7{2(b %_&_XR9ObI+c|6^_Z;{=gb4hKj%ul`{x3d(Oya784cNK5eBg zd%1_|!BgOP_Jqn5E-^^HyT~)f?*J?&3qOP(!VN({KtOCE0I>ji`5JQnZv4(*FxG<8 z L#;{R(IdX`%$rr2vSs(0}?3BrM{8LQ4y=-_xi$w8`rO=mNn8EOWcEF8f%)D zM+bX(a}&(g+wny!<79VN*G7_fVPpU(pGkg)fPjE_Quu!BXO?h%15eZKQONHQ5D<{x z;rd9(?+_3WKW={icKZWM_>Y`+`7X;NSDyHCO33dJ5D-72@w=+(u?P8j69T?%XD)uE zfl1ZlCf~RbL1D3MT0c4`>U&)no*I7Vad{6ZIRe25XEl`zTPg$u#1F^svi*SxEv_Dp zjyKb6P0WGD*4mPU&cEoW>lN3=uS`8_Z1KTcyOt0{?bw$VHrgpw! iB=e;g|F58dbH(p6BCI;3W}~g5 z!b1@KJ%7LKeD3_c@~4g8IqmtW`E5fWP@9v~+)rCwCeIVziSQHh9w2cVI@iMb%Kexa z)(F!tES9?^-#2G?WSC3q%FOJb!ln-a0r~xrqN}Mf(v%mOTi~o^$IrYPR9dQir=}(+ zIHxe(+$q&o-)Ip*?z{N#IK@tWL ;2$a3JYopsB^z9fH9BOa zxPKdb*(> 3n?;h1TC*S6k(LE0WFO!TtaN@hssxJm2)t z{ESwr=MhuSJ3HR`0z_Xzp=J@p{rHJ10p4$ZVoWRw{o 5JzW}z_R5_`qQrVdA=)2RbJEp}EHS*`IN z{!PT{u+UnDy}7 7gus=XR!14Q}kArn=QT?~tANUdT<(sKj zzUhYUR}=j|@GSgR@q3iVHT*!;3m<7Q+Y+M6n>4j;bKPxfsgjE~Ja1T9G!C(?O$-J| zBr=&=6YO3|7>V-mQSf`LhgDwd0G>$Zu-V*U;dvVa9Ij8(!G+lpZR?ju7#bQT*1G%E z5~`!ZYH1216e`R8g8ztkG{{b~5 L`#%mMAR?fmbeVuiC@nDoB_tK;n9|ZxBR7x|5KvJ%1f;ur6OfM44Wnzo z7`2U!?TfE?f8L+p_xs21+&p-kbGG|F_qqCdUe_XYv{dLWvt1@5BcoGOefElsjAEON zj9mEAh4VXR%Ed)wWJNV<&lFyJ&+MMz{TL^wNwI^F@-n1fK 2d3AsWvLsPgW*a z9?QOPw1NcJPDSwbJ5Rr5iriDm3Mi{lUitEH`Z2jhd%#8jzq-T3yNQoUlXFm8I!TS) zwouxA>1Uei{ f0LZ+|t^GGh(v6!|baYD71=RNWN9=xd}R~KOrk$?*d zB0u53)V8?Db9XUrt^8u2thUqV a@AC z!To;?Kp&2JrCM$5`h^;u`6Q(YhRfiyA^-^wGa{ZLcwQa^-F%E^jDKaW-frvX*EGAk z(CCTuwf`Jg=H%pbdQeQc3;K2CF*|&MIluycHq${m4(I)(&JFS0T^`7o`Y=E@gC1hr zLLx^uo|-w`EiRvknpkOY->81zD9l5iG^6zn##@pVAGlXNKh`*kl1JV+F!J2BEg?l9 zXUFP9yokCQ0vQ8@JgaS6n>O5J!WaYlUvB_u9Dsm2g3?TC9dWB4%TUCA2+$#P)@;;^ z9$KrPkPvT>(T)HR|DignmEgXSUqM%VOZ7Db{BzR)W{x8ffV0E^eVlN*{K?U1N0<@h z3`i>4Y}g>E%oS^J*SOOJ_b)7%tG+fcU}k29?6*=kflw#jvOs@yN2yuUBC^(L_Kj}u z#~QBbr?GlmW{qBG2mw3+Um%qk$m4dGTi~S0Mqc9CxC+ouIFDeJ A0<>hKE3r$?@091VeBC(a1esu(<>7MM^AAR_wz6ksFEc}KF(#fW_b-D zQwW6<5{OPj2%!r?z+{n#u|Q|LmN*=0>Tsh2;+4vlwpywSF(Dvp@D!{Yu$8C=5}F&? zYuw!<%kULx(wPQ9q}RZV2nwDUZx{r&;sV1RF3=OsR&dmR@c}3aE=@6(di$APA0Nde zYkLMElnJN vCf}X1c%@t6g;xdL4E%bb{WrEWrgqb_`^= zQN7AWwDLY~NuY?XDHdVpWx*GUch9^vF{1Zxn=%xB7=F_-#qh%AD*qCN_&1(Lo&!g_ zc4ohLQ-Z!do}sr-nVOnnnaZs=EZYrTsD3bm9UX+}YZT?s-Hgo9Fz6*X_?2i@O1L?3 zxt>c9_a@F|zIhQs+V}u~VipkQB1GN_grj4l_8}s`aU-1jJC^YfVQfW!X9Tz|`}LEi z2^nXo(C0M?LS~I_IHWu1G07 {8i)?P6(3xC~l}c-vHx7AlH_hd?%+f(W`M zOvDYi{5A`SC=m6d#kSA53xAd&6!w_%)_;?m#DO#^qVTfY_46UEkU0F^v}92&-o#TZ z-XVhL3ua-F(f!Tnk|(le*rDc$jLfY7?Ec%70k7>bey0aDw-jv@6cpaQD}dhiS9~r( z8R~aHI@7L-H-NtKc}MDj)c2O|P$*o03YGN-X{LC&yg93U;A^Ry%X#Yzt_Yc`);bo= z(X-NRg;uuBpwv?CrEeVTPM3(DIsOu=q8WylfIk-poQPW!YeJv_XR*p8q*@ZhY5$GL z>$8x}Sq&Ld@wJH EaR%@V>o5sN bi9V0{fZt|lgL903jgGX^gz1MmTTCn)8Lxw@X`G7eSrS)T?*+=#p z99pYxl2#x@Bnj_=4uy9D&&&wXlMy@>`$pXlNdO|;jCA%;py&R_T@4i#>YsH^v$YTs zF*!N8v$Io&Z%l#i`u@$wnB7@w$|s&wf_7%4Td42S9ooc(_eKiZdnbpKeqm8hXW=g0 zsKFXBAwP@RIGv~LKlRnwX=a@!c+PFRa>}(575(d-@gp|`vOQa`JA$hbArqncPm2;O zbx*(8QKv_TYci+&`iA3{QFThM0lMenCVj^k3<0$_M&U59%GBp6{Q$Oel_UkFlZN6q zz=YJ2RQiH0TL`WT03KwtUpVQkQkRsH_g^XCCSeOks&pQ&o(>&Yj=R+cfWvkd(Xk8O zC$T2 {u1b8RyF1V+OGs<=$NP8R}x^ z=0xo{&eR@F=WzQ>nHz8ub&9}0q0!OJZlo|<#^9+{>6B(&O%u1Ncpsg-so9bFdE-~u zjb~_s+D3=z)nAFs%`Z1+YA?HG80#j>k}?NG*i%}v4-uZ%ZB`Aqx$=N1Cndn%WRvQN z>F#w{&2j@bX-c0fr0u)NcK~9fctSJn(Zm;!Xf?*|Ic-u-q@ar|zEdUrtEP5^gn{(- zmWY=BQKznY-9 w$@ zBOJklb_v6h2r!!S+f!`m`3EeZ>RgHk&HF*RRJWCN7joN=nwf3clzc+JA81#z)q{ z6IVl4!?LWjY~TQf<}XjWfF7E#6AzW&9 ;r(=TVxwH5M%%`?&sg}hwW`c`#ZhEtUj0Q%ak;+R z4x#E+#aCm8;-9skq;=pdKh~ z^K4xkayklJmGqEsG9yS$X_H gLFIyq&u)Lp7=CK-7e7`UPkz%b3{=~Q-^&30Sb z5iKV@6%Q~IrmBLbpi683KS$A@qysfQ7gQ1kLf62~_9Hmnvh3_APe&58Var>1VIX>K zXkM7OETyNX7r+$bqPtWEK8^ZdsdKeZ=~4c|q(L3g0C2YTLH5n`$xwv#XZ)V6S<9|? zSBxH|?s`TUpz+Hm9K& AQhr;G(Ox^9 zv@Qq(6Y?Pav&TKWO YGz5Hs7wO*#$|b=n=zX!}7duc=Ji z8!O|65Zc`yv!UXFq$6gN!4YZOmMT{K>U_uN1^?n}2eB?;N6QCQKbsEPCc7U3h*4Q^ zZGZhEYQCzT(PzCk&bITknZ=e-+;D&t>Cb4yZB*|~C;mENzmfnxB1OU<|K1pk5XM>) zLZ71(!0eK8?4;>AEQBzdqXMobAxLz+b=B2&mX}`!m!(L$oZ$S)ki`sMMHgwXY*(n> zGTs=niM;n_bDw4$*zLD|oQx>hGO2jS2f~LQ50*)S5A@{k%HJRnG429yMqLim-=0-M z&yDgZb?3-T{tww%nfM_Wi^Hs4;*^Gj) >?@l@dam(I|pGWQEx57n(j*|p7a=7)^rX6kXr0{P}(z&N{w@cAyIn}*`wUk zy_X|^i5lAdNunDOyym#-%sSCA!=n`5bZ=zbA@lD;MW9MHe*FA${fx0)vA(LxcCjzF z?tI#$Pll4i&6LaoV9FgJ-Q|rzhBVM>zt8d{yS=e-%<36i@@aEz=SGoC1*Xh>ov^KA z#y56E$$w^am=LT;Y7jwmxR3@IVbib25eV+R4*`yI7l2M&7karrZ>v!JJVnbvf)?l{ zt7}r_(9|qj7RcezR(XZZtxGxm5Kx&5>+4xxHntsSVrn$5?F|G3GUPlAgJ-Uy1w|qa zv_fEPn TjtLTUHy&~-oU_dTT9R3lH%eO2cM De)X;w*m{6jzvU&m>88oR zjzr+Nb#%GdoQT*<2Rpkr!Q{aj`k!`r*dP4N6jrU$u+g~=Z7Vm*t&OPpb-A6FomZgW zI9NMB=eTYCSy5I^?l|RWC!F~7%VUyb-W1j-S-h{4D&rydc1#*XFf*sdXQH!*jpN+^ zi=?og^mG>QM(LCN@l~y9q_8%GtTbjfYozi{SAgcmoi9YKP4pEjdD2Vkj{}hTVQcpd z`G%SAiKL;fGFjZ}a$9oleeGeFb)uWPt|+^bdq?g@2EqE}nGvLQnRi3+J8#d%Tm#Ji zphvQAP)tDv4#2I3FXa9vOgfv3VQ?R^BXDH`zQi7cBZ2U+pmaR+H=)5D@sRdn%HV+$ zFDHDIz^my3F*ZtgLb8>I`y8m*eeQ?IvAe5T5XT=;C#T4T!jkaKa%1sc#2%J(gz@3H z0Wjd~c#>Jj6nm<;cyq+YXeCKFeqcOyyN6_MQx@DyXD#ycLw3z)S^Xoz9MHKmyunGw zPrDy-c!C%Ra6{Yht@4MQxIyz>Y}PWXV!RGyg2-WyL8ZG cF5WBOdjO@L*dwg3u3gsImEI(e%UBjF6?cx2lCPT#yFg2#63#+h3R8^Uz z)9!%T9--t+m!18A%>InnxUOaUP+m=i_ 9 ?#fy(~iz?Bgz}F(4jm GGi03?Ntb8saZN19+fWe73@V{( ;EdFI}uQ_8fadR=lSMSxat-2ld4_P)BVGaXZHK zDg^aWt9P`)xX;>~n)F|fr&?5H>xEZ)O}@+!k&uXo_daFjH#w%9B1>%DH+&> )h*}MW(WUbY6h!$__%+5JJEIZSwR<5R?DtUKja%Kz;lb~`E5P*l} z?IuhVgNe5oukY}-h5h8zIdLB={EP4PhrlXaXrB4hrdB%1{;Sb`!xK{Uu1X1QhVQn~ zY*6L)HltsOi`?;;?(;P(Vqc_r_)*3ICO!Xvdmc~z6Nu3Dtc5~xM_#I=^;mX!!220c z;qou8jfk1XuwNU(vd6DmH=w@>)U|OlE&;yF9-d@RveIVc!|4Q}oaIY6$pfR~U_Xo> zT JUc?1zhhS%nXuS+s2 zv|;=B8rD0arpj!%-6i|SB#*lnF+JKJYAt1qHEs1cZxM-TLhyM~AA49f05H(ir63iR zl+fuEm6qObGS>GZltBu>_>u*uj)Yi_1_JKOg41lFL3041EWYvaGWUnCfh+qoH#0+x z?RV@HmiL$1zkmO3W@gqeOhJRaoKzm+S*$0mMCTTWefwh#Dl9)mn)JK}ah+J_WI$aA zc!h6eo8*?C!Wd|ezm(`GeqtytZWj_A!phFTB0%L-DQD3hyj|>YqWi}3jp(n!ss &gm5t(#X-%sqr(htQohEk zx?qT{UyP&^8XbL{bKI=~Tlo`5F>Dg>v_SvUj_918LzIB;)>eW mh*7gZFGORL!Ga%JXWCl&^cmP^oFJ0RFIWms(ird z&UDqWE!^MN- ||Dh%P^;*e*i&yWF`?`**DHkP_ zmL3A>F%uQR=CilKIO}@cm41ji%l)i8E(pn+ z*m{nPbm1lk0Ii@m4ijSE0>x6wIy;r?jZ*;-@VNuGv&)CUxS?MGcSkLT#9qG*oi>PX z_x;c)3#YwcDj)XzWymvITi&9g0X7eykx`Eg-AqtfvG|1W>maSn({teU2Y =ux zAo?>%LCngkvaf7A`vK_sU(V5zBzfQA7XZ@EhZ{q10KTdSfW(#AINu_frI5Cb-OfU8 zPxk{-DxPZAlv!XLV1%_Y@bL&Dk{)zY^IzFlTpEP_g#2>r295p0fP+;veeOo9R>|V; zk&&0r1K=N)!s4psav>U6->+ -+2!EU@E6{WBcLAU) zgS1^Je8MSj9(o8ECg8VcLKMn_prxO=|A+e-1cJLGyVz@Ub8sr#-D 6LT9k2$*cAZy1Ti;jUOdjC)fdhLN;(Uxd zhi@ys>Rgk5%c!m--}hFqJW_}9@lp|#`Q+w{%G|^s*70xBDla^whE{S+P_olF=-_*M z%fGZ6=+n+{%*uRvF)LH@M3o)DE-ldGm9#7GXkB9{Q!E=N0r+gBYt|mtn;WWk3!<6l zw9T6oeeo{<`hOQR0C?O6@hA__g6?GBiJMLt<3X#~yL_rx>q~IJeb(x+@=Q_~M3%wm zQw;Cpt@Mtfl@$9z4*2PW@^W1mp>2VrM3MNOlMi~6Y{SVPN^j{RRoQ<|T TC4(ICOr4&L4LEkbLT^h Z9c+v#;DHZ~3^DSy|i zOFC`jq3xHcnbDkoX7JtEZf(W%B?xCoyLX~6nB(K;*~3K!W#%yO8P!a+`2U(h|7cm} zujlZM1qY%6eFH(!(b0GA-1!XkL{99^*1_<5GFQkmpj6=u^tU-)Nd0g%Tv}|q6(;td zY1Lhrm>BvuO?F}r`VQ(4;HVuu4=aa`RI#h;($)4L<$qs1c>xRF8p$avENpF62yDi$ zy-#@J(0j5oz2d~KwmP?0R |Yb+5TA@Zm-l?C&N|#@q3&q&;UgJ z4TWTH+z&ppWZAwfPN}r (@>f;e;QBOW7ZwI|0f%CxWHkm~KPWWiOAa_T?k1-NB7ETo29 z>rv!TOaO5SY5G+Tc<&R_rCmr`O2bz3$#~TYE=es%QZEB00N6VmPw^-jB+SpWaIRQj zB5Hol6*2}ehcd>-vH1k>TN}z_ur%cGuYbfxQS+Wxof`to91Qo1L`{~SSw6Vx{{Tuc za(sL|-}rs{Fu-pL3T^={mNs apX4~^7 z%j&f4KY?_tjoJU%tpqd!fo50kgQJdLkEaz#ds(3#9Qui8>A$h-5}jM|(R wlyZ1vB!-dGZ(3-c5-x|#mHgERE zpX_Rk8PwUzRT1PC9+RP%#Fwq>ZM5IMn=M&l!^a#fZk<(sY{?}(C>r0g9zW0yFWXLO zl6FmA6BT$k_fphfw;f~hCHXjFL5pFIW0oFS8e_#2<`VPO+u{=vlgh;dqD))xKXzb& zn(saYo+Ie9YqK6?;y5IR0ijWH@atc?2tgUrDq=nBcxB3qxHhElNw<{SVc9td_VB_` zMx8~&u!+KtFhUFTJ^Cyuc3ZWl*|uA=Et9^UdkTLdD#{IfsWe+WTV=7{Z|jwMOY({) z9^tp1G|5nNC1=qOcx ofoz-Or=1evZd+mK$!L0t@S|WOZDZ|&d(a>UQwA~ zo;g?TvoPP~D@L(sHHz0y>nCTR>>Dn(y!bM5+`m=ogK%k`I7X_6m%XSPscCQQ1C2*N zB{$2y<23XN?26sid?k3v`oo>NWl21!7zlZCfzqX>ej+Znl>S$_nNxypku1lxeUX)O zSr>v%`ai43plf&^`_{`9N$r6&nO}e7)fhM{bxuu;rwzo%8boZ>O$1=CNV<;>VHYq4 z5}Z@e$X6IY&x=iPm)kA!?HAtI%ijeaXdU0nImRw@U9hR21k8QG^lJQL&vIkzCtMK= z+h-@hfPEb2-ELb%9qG38{&5rJnjWlcp1jH7XSy09d=Vn;0K;{ue~N`A-wwROGp4rU z=j61Tqn^;|XLqa*3phJH0B<9qGgJX%pMJY|UBEXAG1_`bU#;J!hRrCZE!TbcU1hd; zVU|JfP{!qcjiiowBCzv=t+Vf;?!KJ-VoezwGs5<6CUgF~Ij4;BhvU$*Z<}{KSGCFg zRK;HbuDycPG=FYHtIu}o`>5`7(u;BIHGM*T3(UZk-`5RNvWXFe432y`QQA`K--;{q z%qz4nMA~cZkXbFP78Def7Ch0LR8b)LtDB7%BqxiC`ys%oDGkdkH)QnmCf&euQ=mPN z-&FqKYzFJ|{bYuW$tC=uCA#GuL&OTi|0d^QXtM29#LGY8l+1Pj>kGicdGzk+iJ)1V zOVshC^bpj!VyTCi7KeM>_lL1XY3ASf0MA`}e@R~5OFI~qsbhD3$oj*kf%!{*1pWD# zV_fN|^~te}eb~ws#9>R_b%vY^TolkaZ}z4-i1!a}$2VA;N>CFp9JOYN=H!zJLRrq9 zlLo=@7ik D;9D8{o|ap1V$0yVB4J0rgXFo{}p=OgVO0%(*v>1js>42owMDPk&>Q8 znNU<^U$(>8-5MpobE?&;4f%s-^=269()n#EpaF56opbjEck@|U?^hgKry2awlnRvV zk0n=xnSbm>kVw4zRgT`PtYwx6T205$WJJJgQLP>P%G?U?Y3BmXGrMQ!=lz(*uGoM) z$mNfznd#WB!_%?Fq@?i19~zQ$5!?)jB0gvleCC8x3H7%Z)>Yvp_6LA^j^}fN5$5vU z*Pk>b{?K?)qMN5hPTsa5)hfyigNi^$sNfn?ZpI%nZZze!V$OZLgt)j_gPS$SKJsCe zt_47|0q4d~bH_y;TTYHR+}%-lxrqI^{S) |{-1X4+TS&qKT+ zO=AJXq9@Is4GQe6NpOJl@u6ToNzb4tR+~(51=WqZ&s~Obg|hop;VgftLd!w_(1O8h z7i{5fc%hbF02DzatiUXT) Gz5Hbc6PP3T!WW~_!ELeZi^-=YbXbvCbAW*v72Fd;J37X5Btuw9RAZVrKy zSWTs_|K-p5vo6zO<_%_{XTGx_pi7ZqYpcPrXl8{Tl(>x?Y0uf0E>JO$F%AZ*Jj>Mx zLQPl8#xL@A>@kl*J@u}J3=R&WCj(%VUM8L}ilcNcs5sjP#b8_K7m~Vd-7bhm8ZVW> zT@y){=*FEYmyLKL|7&BXw!Bv^avTh$ZLOh7sX53q`iTI*w}j?BeE&_)yPG*FvNer> zZ?EK6D*$mER8{s6-FU2d-I>pe)s !e}Xc_O5b&d;UAjw`5>m-l+>pSi!$wdhx5CfoV)V@AK0EVzLO?fRaesQ zd@wRe87k9=uk?A2oF5833!i4 zosTHHe|+_M=<*vR_V1JP!&wpU=RyBoo)@rwfu6rSZxQm^o0GOO`k(t^zcBvxDlr`A zWqIP4MkD$)R~pg8dH*Y4Fs yJ?s;ix}m`mX~}KTiV{b(i93Z*OOVvP%!P_I+M;qKc`~#WZoaCMGE@uznhG`#PE1 zxWy@Z&;Q c(FE%MgvN(PCshSo0`sm}+Z7&L2+K%fW%1)jR5Ot7$u)y8lcav)S zrGv8`s$Y9l`1?858GQ-ueWg*dq3zP#e`x&?wc>+_(4BwExyU5kcW@Qn^oaQrc9M>K z`7T48tWwOVI_GgD8PG{VTqnJboxEjD1M9r#7BD; VLN9q$y%d$eqPj_#LYo&w8 zie&CZqU>`y#P05=J(d$tGm-F9mSMgGoej7(qszz9`pfS>oc@h@Z;<}z{?oYxTGw<6 zHMV7o%g^#N%p!YUm_|greVO&sISY-Bq{hm1J(u0R?s7{l=u2Zyk3gjzFVsWV?gl~+ zAm=o_xSl=aDyI0s)-5wt?y1YwZ;5yB{LlX7cChjbjVQ4bIkZ?InaDuWyqhWg)Ih}A zU7FCow|TYAKj)b<;ROf!*~ymuo}#kMa}C?=#a`^6o7rS7IXXa_@C5IR@g;6|qU1|> zv*kj5MgN P>N1F!3_`nb99P7y-&vbi#PCGU#juZsQs!U8Qn=8#8rD5&uWmz zLE1m6mH+-?_r=AF*o#-i>08fvG|%YoB0tOFc*P6k*&eIC$vjBAK|RQz@j{2v;jLhC zXiYiOM4Pc8a;bpwpLvvg=Q)KJ5Y4&AwnTp&9J>5N>LQ6Q@;~eU{!Ft^!*f~ZGMaN2 zydpCvLr;IDjp5qAx$gsZe`<1h@@JZQ{sy R*?PqZRldxM+UZv#ogrm*qWrA{i?s1i~Nd>3jdVHwKF&s_8 z*J+GYQ)#VK+-TgXt)A2S6{l_oB-knZrK{4*p_R%ReEgMm)QXaR-@Ik5Bt=yGepAyW z`d?FvK}+0O#*ZCC|D$5_tWX34N+#4^ H_0z0}la}jOB*e4K)^~rAh77w0m#uER@pBTOg1`AM8>F%DlP5a%)}u#M zBG~@pFDmN0Z071-k*LbWWvOg7j ^JFR8M!Ke-`t+^P(l>gG}A-lBI!6#=Bk(NV7pH z;vBGCv0ZZw%36Zo`nn8R0I&JTrCIPX|EgRl77W*nw-~utr2e4tuJyxg)r!Po z9)mkjfX?Nb5Lqtx-h5NtOx=f_zpVaf>y( E)@os+o`ZX*p%uXy4AT1^)R!t3GJfi3Iks7y!yL!L#wu_ZtmSJ1QiwzCKW7DPG zsUVJjmS(7JE#T6^dcXUX9s38OlHaWfz aSCl-sAu^Oag!$szw|ZuMj?gXDa) z Heq=Z`lJEPo0f`)ROPSo**!AtrZN~dO zO^OC30mtmZFoLq08G<4ZReNE!?%l5Pp@s7p(E*Lu+aRKysPG5BFY{H_9WAyNx+83? zNqmd-7 2kU7GTTf}9&1Ti&L0w!GJ5ZuodqD_2Y$cF& z{ 2*3yZ*v{78E_i)l+5K6)9vr&!MB<|Rg2kw>{ Ley^98CY?fr=ZfQ&2V6#syy0y|$Yf|zNQVS`Swg}r#QEgm>N NMi6sBbci|9P9{c*z&F zv4mus_f^SLLaG*{oMv}A- #mIUF zEIp~5bX*4M;rFT`*XjtROSq0`LM+!egwlOxlQJXloka-E>(K&*#ZfN^HVG1@job74 z*YS@*@6f+ID+3Vf?olc4WDHUg P$TRz0C3g&C%!vpj^A z&i{HZ>|{vO?q4MQMOvrHC1_?*oeo$RTMI41*<+xT>KL=H;k3-M#^(^XggIeEy<-SF zKH5>dlihSZMXYJe^pfa%HDx6wrIeBNLmbmX!~IzVkxBkm3F0EJ&jn0eE9NL6Y?#sV zkxUcQ1egw3hWY*rclgq6Jg{s_=%PCF4PRM@EgIieWB5H|+jjNX!o1Dp(aGuWdGMxh z>jP%xi^D1ii-eeOQ8C~f9j=syTdXq8NQyjzLA~&Dq*%){QzwYSo{38Hwzx(67w3Fv z6#d~#8}|)pb!AA}Hom#IONIGiqD+FR)Q^+W2H{-`lUa~pKtX-d-IJD@>hcg%IW9qh zZ~xw1;9_Zf^YMsKEnt$`t0l+0U}45H+5B{5AlAPpE>ZcI%{Nb?AR9v3PlGysUv#dm zsJQI1`pIZnX08`)@$jCg?5T17OMgkXRJotR{Gm!qhWCm3Z8tEwD*ZA%vkz3iUUmH? zWJJLTkh(3UNreo?(HHmyq2|rs$U8$^`*Vr8nq_h&M48#uT(Ws52yV+0e*!yn-_9Z( z6897;+(!FW`|k9E58^Uly3^`P@3&u=gF_r~J@5?h>X)4FW?54vxPv>wqA)OGOB3MZ ztShNDl>v61kD(jt*6wXQeW70jp~Uv|u`e=Zm35|L^N8K|T|m1hIl?Z5Ru~%Vlm#7i zXl+6I$tK=zs}FgygB9gGgu4e+XZO-+ldQ}-tk7qF+TdLln!i{WY-g<2YaU+{%m$Cf z&1I+DR^<0Eobg-h>^Nm!lAQBd>x_=-nv^}=1j4S~`63`$np#qLjYs&EQej5RB@;=x z-n9xZ)fDZCr|I!NC7^+9jsidQat-?y-D!YW8Cc`w=0=rB>I6G;(HmJG@#=slwUZp; zUjz)EDFib4#g+w)+P^FEM)%f49jCl`#ylM(yA}9op?>0WQ~B}E^Q9AkYFNoP}8 zTGF1mqb65xN0t5azl?>W>wVbw@^4j7X2t%o6rWs`10KWClPV39FP0oM7qYdTPc4vD zJB}IaiexFjBsg7e4nA3`))2Zl8B+M5QnNV7eW&Vp_2(Sz#xn0=46xa& )H08&! z4bz`V0fRS1pjS)h>#tuEHNVA+Zcntwa#gWQ#f@K{azN(~-+7zR;fSeMbM6 zfk}jYQ(ae+YPY1wxvFQ~i*ZA)^}Y0FzaFsI{(a>pTdUI}86V|M^6(@_QI?=FT}0y( zCd8U+>98W!l-}eMQ!M ExYit;s1`=)rFv#7uu zC#x(Tl(`I0ibc2BVx-mp^GQ2wEn{`Ui)P;Q-qYX0s8VWw#M9P*w7$tz%5w0}PfvYz zWjHXM@<0_om3$l0oshOnU%5F8l9i_#2&U5{oM4&Maue{fE^>Yi`6FrX_dxr(kIHx1 z+GO7;dMM~{fyqS}PvdyvMUk68V0FH*fNq@tS6Iy7i7meWaG^R@4ESnN@MxkeI7=9H zZ7Rlf&K>z8`NPd}T-xL1Jccx{1aGCd4h(X#4A|hd<`!wT4_~VHhyAd|9&WfEMmePQ zWg_k|mEZep81VJRrB!%R!(drF`&NlmeH9;M-oK_X5fEq6HFL{pP@3O-!aB0!^LG?1 zb((P6DUQ6oQIi#C#{7HTQ&ie{c#t+hSW@P#s(SLV%r(B{dTAo Lu~m_9q*=+=EtapP-rbaYO>Y^keD|N6rWmW>;Al1%P%{;;9u zR310sRQPz+St6~%u!ghGJA;EzvKQi9b4IB!dV6?yD(!&G(v^M*GcKBPi-9enClLze z$k*FjK0oKBXXtl*hX<9tUdnWb{YV?1ej{|(dPH4K9=Wb)d97~@c&S>Q>#mggv>mLc zDb7Dg-Sk*FIrG>vqJ>AWKOAY$h-(;9_3~cNS|0foiuXQ3F+%&^N~tQFM^KYV@n_!m zpE8Y^XO0MYcz5t#r`?ntLw6*{iJ|m3UTF9Om4WI o-m|}^7U5U zxE3^VQ`pJiR)yS8v!u1exuJlEY`VFuP*RAWmC^$!W)ga(>UFMi;p+=`NOKF+SmLER z4 zC9HAA8@`D!Q`V IDTk zpyFwQ)YoTIS&(a~b^0hr$CI-4*H6RU<7Wm#<3zg_{f0T0ng9@a>5_q;+^Y~#^(N(H zkm5$)tZt7VJ<=3((4r%okplF%I%DW|H4?~!7lU;pR6!4hR53JY&U2|sHhTU%blA>+ zyC83oaRkGGXvm^H8u`^aZUIJjuhBl=`JKL`SgzG_HQ)Qeb {>&OdN!czAmko><+HCs3~_wGHDgTi0KacrY;C8AM= zxsZ7cFTD|9dgq?j0i{+urt^8DgG1mqKBmzD22Id+rn39YPt>=%DZ)@U3OTPCG5JeO zDHtRUi7*^Fp&x(rVv#c8%f0F*o=+~C-70$Bap3q7pl11zJ5>tXu+SlymGs}4+of`Q zld8++4oFV&8Ydmjh6ziukB+>%#!? OtR9&yuma+`YBYH#CfW5t3KR&?wtm$m3&q^CenO80M6L~8o(g* z&>Rsx6?ppx3rk}XG~e=;{p!v(bP8? $utErCT2VPTx}ed|*4JyzP1` zN9!vf?(3_gIeB-V3V=?9@1Qp`=fDhuP+nd@=k^`N!=912-KUEeaUiO0DfXoYzjhs= zpX0|yZC-82)iu}m11sV_S aaQg# zIM!=3?6Vzx+gIXXRG*Gcqb6?Rnv}bvwO&F;wby@6LPTJjZzj8s+CcoOX5AFLvd+9Y@%;b{Hd@qZ!TauJgTb|G%eZAnK3fjzT!&O-Za1E-?x ORo1#t{DEsRi(n6 z%fNcSNm2ueUb=J#e+gAHLdF)GufgeGR#t@C+G9oKO#_?0b(X!pNRvR@!g&*aGKsnD zN0yUO1-e>T8gc<1@H*w3Cbq9mA*(f-H_b6J0JVqKqm(8MnhP;do`}vRu;LHXs4TT- zV?%rdCd?=e0lfw*Pj`ww%+%>8pHY7-#J_)kqgljEDtQl)9=fzJ%bPOM0pe) z_5;nw&U;|I4lFuNFP$sSon7Sm5S=KqAW$sM2b!{#@wIze1Tx?MJL5*wb%^Ee16{Ql zVVh12Ay7Uq;bE`k*2tRJUWohg!TOiJft;BsLlv{5^q>^rjUUjsi=nY%ZEEg=jd3#z z`m4gj4{|?Q-9>ll{)x}{oq^{K;Y}zgZH8qJ@q9-EISR3;olg(MxMcI6s6|d8j7Lo` zDZ_Eu-ZSROuOm-uJJu`L4%NQ<+g4CbSPDNm74`VlU<`|&bF&rA@!Cjzb`Bt`Vt;!4 zlo#cM@|IrPwSMk#qYt!K{q+8Gv~r)u%p6Bw XIKvTDP31IuM{kNHS?2#ulp- z{Mgb R#!Yz-4!hfG$wAAgz%acPXD(haC=e=Z%jess8?~Q5oq{wrfcE-?0 zcCdrLQXwRNzV)qW%C*{pa|ab7Yh6ZO?D_0os}-@{YfRAdpY%iEk?uyZv9fhX(y!`1 zNFAt89agb7&wpnZdy1MucWy2|m>maPv%{9sZP8C8hd|)x<&Jva 3aR zztAtnxBP#=FTq*mJLVR9rk1z8?j^()$d*XlL+g8HKjJmp@rxnu!8bo&8Y;p%kKCyY zTJ|%gnbNT2KD(Q_-T5u`t~P9Ql!^Cc8m5_k$a>gzBJ2%=rm5W7lvReHt%r(Tld%rN zz?anfPCn{*Id>>xc2dH#E?n`bMpF&tw!OW#cYTlNBISea5ANwUeZ%DhC|W=MM&o$o z=ON{h$@!FZ>sN{{AkgGI lte(1&B=Mpm(H~>?y|~kdx}@TkO>w^JigS9tZ>P^2h<>+oRxUXdp+_U*feP}q zY;s|1@jTwQ4KF$ycYRp)D(akx=h)lR&cR*Rui?6Ksrz}SIk!&7e>J4X#KgF_4|BVY zWC7_$Umg*DWMkjP5O08y4`!5z6XSlFL}*NW?rG!c5T`T>^0YPa&yQ3|<>6srch3#O zIV3pv4 0W0rZR%_r5;t|ss2rS12QMIe>*4sDsZGkjip`wt|ZEb+fv-bm)T zf8&N Sh`rb+JX-7}C9@XOj|o%IsVBK2`i!T JP za-g%|C=w?b*Slnz9hwk_HoL}YLqT2h>Hg{ES6}&6E{Mg7CZ@fdQJS)TG&@f(`c951 zp*dpmOQG41|7yw8?!`M-PZeJ*bPv5jdJ^PksWWoV!z7^Lx0!J73$dL?g;*hDslnxI z%jmyDV7^Y7OLH6l37P+{nBDm8@Lxrw^X8S9`L)VxnEG~Jn`l(Xn3H{T)6S2i$j$qY zj%?JOorT_dIecDhn(tmay*?j0@LM!v<>&zWL*TzE3Y?U1o%nUm&(+F&KW3F)Ek}%B z!IoaVT319a@&MX*p%v65{5$+(=p8GEZfCJ6k6XuXzme5nvB{>wjfiXiMdHO_y_a8Z z3(< 5?)yt)k1qg{$juXmxvo-9N20le$^8&Us`1ui %(J0Rv`z)*<=LcF1pHBN~?`{A+kQ#oGF^&q9~W{~)zR0-Z35AJ X%Z_0N|vgq&pi3`2n7K{F*nLFwvu|#2{ynl z$FqQ`5)^lO)9sP|{^aSuBUwNJc6W0lARyQ(tS;5A{}z-spe{1Fvv2-IQ40~H*r%&i zeHhHcyDa+xwmen {FE?t3 N=Aja)|e>!kyIg}jW`+WwCaKCiKflb9abBg!3SGjo+A8SINdl!M`jLS(eXji@Z zd<@2-Ll^EUvu_!Gu_1^4i@r<{K>|8ff-y)q-R_S%v9z_cW()G5x1X-ZcF}*5RNX2> zs^n(e&hmyXI=Y-2LlX*?TwKmamKiZjd)yBb-DQ-Aqm%F_#QE<%i&R{Tt;5Dj?@V9j zOreOA<({nZ@SXjOWeL5!#B|%}!^VIN4h~AsUA6W$P_!nKd!up!4`95TS3I%qRdh3C zo~>JBF;*>djSb7o9_y-3w=4nmH4}};NYszM8UbsP%LPE8Hp?xZ*yzS%dM7uQYM0Ba zY{)C>v19>%Q@6x($zOu(?d>5g9vl?_VQax7ivmM|4T<%BY+1A^ wL&@w_{_cVF}Ru`K&4TTf=G7W|yF%Dz(T9-;T6 zw@M2b_?97e#M7$*x7=q 0L=U_&}U!Vq9c5&TS4phsYF3SE|So=R6rc{0qp z$9cxsumOt-ucDL$FB|8t*`*XaERG3339Qi*!Kbt7I|1f$kY95GL@Q}RO-(b9$qhEz zp*9a+_^XkVD7V0GYWK{Q=)Azh# zgS}xR^<)CDbBZg@`yQ7T|HDAQ!Uh+nw3$>N__jU4_y ;-AVy=fZ2-q-|)Is((7W=#V#H7z&{~fsl x`DfJ&HUG(ct6jZM704>ysAl1Ej-J)*?Z9vn6 z3cN>q_QX7WxURPL+y!=ae%^tF{fF6uWvZ3YP)*`w9imz=OFNU2+FKq}B}IOc)3_ z9dtzf6HL~5tzRa!cqkP7kf?UkeZ%}%(q=3y822;AmnE85+d2(`)KDlRKU+o!ME`Wo z>=N}m{a?HgD^hk71Q0?fF-qmfmmnVam)C(7vxum9LJ7GUc)#~z+GfA%pm)BSZp807 zyc+>P_01v%!y)PL&lP&oC_L0tBTwSw4+4wWeLJsc|9(jflebe?!BD9v=Ro*sQ#eD! z4)^{<#C#TZ`ldMpOtE*E+r%s_8K0oxKVOpY7MVUe+1~HJWDUuzplv@ff@j!{jC)Z> zis*ciP6i*8RQ+toj>qLq8vY_db$p?%7cNp{l;~?(*MO;mno)COpLsm`r h8pBcKS^Fg z!WSSxm4Eo0+1@pxGIR!+EX}Yc?~?quT`ihHBA|lljhGqVawtx+@mtw{??&kPWtOpf zqm7xbMTpW5Vu<9E-nq%2Zga78pXpc|;POk^i@rM&*wY+WSkA6H&D$z3Bv_=L()zDS zxKVey``@qn4z5;c=9o(>xYjJFuz5}njvZS7Racn$a>f&60dd6R&6l!7P8oW4ejauB z|IF_Ib6%89?PYjb>p+AiAsX5&jUitsnxAnqaY7t9WWDma<(MVnJM%|Ff vGC?q0P9G%Nk0TabR~8dQxU`e$aewwEDtTL?>+-R4{UCPvgdCNXQ!Cov z8!MnhI09>Xf2NYu>GH9Scqhuk=OIaOKvUL@CkJ?xWYG9_ z&r%^8>O0f5bckO3p)6D{Z$2?dFxARICXc0eP9H7>rhBHPxxhyd;l~;#alB+8CpfZ; zo!@m@0&Epjtq}&u-8 Q@8a-;rH{}5W-#Rzu>VIB0;IwJO^N^g`Tt8>W9WjR%q3`W;)L~>bh+Q4 z1bFhQxEGW)G+dU}FJCP|Kh{4wC?ifEhtS#_uXPKIx@`I0kAh*OugGS7R!lbg0fB{J z;Y0Qvw=?5S|D-|N+y4Tr%KBUp-zM=p`4VqrnKI{KI3-E1W&p5|PS(8l*1d%Q{uK}3 zfFDV=T8W0CSaWet0iN)X*{OATYf^lC04r6EmkHpVWMyT=zb5SeC|VrUW_|f)xoH>Q zgpm$SjKpK;TL >Wv~eTivsW z&N#pdD z;eaQ-*YG!1+f#A}t}Sj<<{JB*>dPpevWtZMLU2ulXj* z3J~!6Nr=8UFN@i+yWF{*Y^k%(NcU`2r5xB5265X|1%D1-;ik_xGkeyyQkRm6x7mx1 zGw+zH=vF>sWmG$NAeMG339M3wZE%bCC&_Ja7Iw20lp-QN>(3DRA-rXZ8Y_m}++U6w zfgS)pliJN4tW6p`scmh&M>hFwWL=ckD;0F)b+O;UK>`qBSl6zLeE3axoRGafZIA>6 znj3Sk=$1d0%zHafkBud9l)@}cjV=4O< 4-|ZDCnnZWpqP&K z IyP19o8AJkU)4ra3y0 ~~({CtqmgwOF6l6sdukBmUr?1ZU{MhQ1 zuPr{YgYFpuI_MZ;5^9UDJlC?vOZW8EDXw_Ehjh*DdeOW5os$^Vh@i+ytKD9EPUm-xKEHLl0+|&0|-DKW;&0^C3 zcv^~(9TQC2r^Mo!=i#` y)%C;4d2@earm{+KOY&aNveJwZ4b=^eB9jL zZSF18?_;91jIc*?P%bh%TYB}hmTAEwsU?#yYP;H1dGU6D>Y!v~-`8MR1tN5ij|&Rg zWAukfwsS2=BR0VDT-Fk0yskU1iOm2?fsUtVaiR`={0lneqs# z{&%<~x{zMGwIAe?L3gBVBO#&3*s`*R2yhFMo^J51>7D(HC3j-a`I<7TKj2AiqgF-J z94*BnLnbiaRgv(L4E|{OGsQjwI K~gjX@c!~si(5(?3bo|tZlX~FXm(f$@hw$vyguk)Qtt(nYNL(O|@Ao z5btIP-*&rQ3$goN-rRtKp%4WV`^yVE3;vVxOCGtKI=z_q8J7(VNLK#%y9x0qZTDBC zJA!Cojp^y*Tto|k5eu_4-W-+@uH3GAEx(3Zs|{YJc(3ldH)Gt3C3m0^{X>J5I$ zjM2z bLZSe-Kst}eii7zOi*_BtjuBW8?|Kwmu;4SH8r0edu6q1 z!-x8UGoZo%0;~(xeD(92k_sLl!Rn4gE*(M*@$idE2VU{m>D=Jt(U&PYJW5&ik#Q?T zRSXJI5i7M_+A{A9M$(CQSil^D#7@RouV=H7Y5DLWtGin{_?#!?tzw}cWD{BgkV=>+ z2^}|@AMvdQ*N>aq7@yUBmtWkDk$JRGbV;rxAQKF&qybSh|9J U!*`?Vs88&GVpN z>N&^QEUgkXxRKnQFM%b81v@#NVcU_MY#*<+?#*jL29{@QR}cNH^UnkF$h=mVPe=Tk z$gV1BW|q8Lc#g|&E`D(zl&9BUD?tMkPipmEbuA@UYF9>W=@F1%@9++5S<&2%#V+~x zyoq;Ice^>|26_n41^%p#GoWSbIQ30+Fo`9;m&@FINNMn-tlNGubg;~stL^w>*TKiz znPryjtl}V2#*esl;;Cb3>LgoEI*!+_GWbr5c|jO7_A6)O()}KHV_%wsWpm}bqn)gy zKX5ZYPkl1&$vT#{jKRi^b-ehc8*yfH{yWkWG;7V`Wa4lNUFDnesf$Esh!t4Q3E9eh zNL9Yg)zjBR*A~JB`=VRJ*yueoo*bTTxdldI!%xCv3v#MW-aswQ%@rG-e{&c4K6ts& z+oMqLe*f3|bvss9@t-;AJnhVQ9~GUI;wfVp=Tzkj@;zqWO$lK(JJjBmHp j)-$)ufnVmIU%&&l|$kHmlKX*{f4z zjt75ljJA8;4ADKA9@ibRIjg;%uF7gaYW`juw76L7Ju{cI^(C712wexz{@ejvE%*mM zFpy;sgZBudI5kOEQ-aU&%uV%}VvMm~n%At 2<-2nZ03;4GK{}*kr%^;K=Ss*Vjs)n_?f65y0v? zL*{lc0|RAH7#0oBfZlNQOfO9cB6JBkom5yyOJuVy>m$O5J6(9W&d^~aTk9d-OTPQq z&$_ltN5@OeMm~n@nLO$d(s{45|J=g~Ms9IiG5A&xn1KX%csB?3K8T<;_Oe^p@ld)z zv~Hxnd)Ddw{XmIiX0K-%2sK-TwOSl=qf?E6Lu*y;wwe^Sk?vuw7g)WcFHkO~22Cf0 znOSZ}l3@2%FIEpvlkl*LBiKwFtF4ycR@7`!ef6mOCe?uO#VRXM(VR`M1k&X=lGQ5C z&6mBIwdhGe>=Wk|herVR-Sz0r{S~2_o>R)>mHYPH#|cUP@GC_n;WTxuun6;doWtAV zV)aitjqH_EQ&USRpE55w2<`9B-6f!6;(&u}h &d4w(~YAr<+$=5t_(E7^HVR zFPY-QT23d9`E8Hu=gU`PH;cgT2r#wGs)=K zQY!{F%cUhr1(=XB(+I6I7)@?$G!PRD=5-nMd&f6>)80nO3}o&@5&fWK2V~h4zixme z+RDc@hg(_ueT2B8X6xy&fGyhmSFGvV$9PRC@Vkt0r&BtA<-#cWowc z{>&Br)*kDyFz9^eRyZ8G`*{84?R;8VWBqmZ@j@*BbobW|?Rx53nlb5{<9kwU&=;@z zNb8razED6WhFsPpSmxOL $aO^+dD5(!CnewXhm?a73B$ULBr z(tUFKeREKkAWB=0PKRJH=PR0Fjl;E=g`mF78E?qC8@K*b#9uM}T4=x7KUk<~jZHA8 zI)EF=sx%(eDp^D(OnH!NiKS?bTlM(Db4%g-%%Hp`0g*6INJ(cKNO+FxmBlOiy_?T< z(xx_})I) j?HMgr;TrM&vgKEx~!xRf80eT+Stu(7v>?(Xjf-vcOr#qB1WPyfgW z8!PJ_Z-6Q8b(YF1u76v=ozn9iiogw-xn2~w(GY8_(bDt!_4-|`3L{RjdW5e&Eqiz? zM-}&Q) dI|Pgp0Nisyfp9IEwa0kT z&Uqw}&2K4H# arY~n?Z`P&tQFH$mPm|VD^5w=s5n=ayJIF{}k8kH{%j5t3s z+dR#Ut0_hu$N*b`$nMj|Uy>-N+s^WsQ9sdm4t2VQRAhz5@?>PZ&9Dd0%G3G6p<4aT ze$aD|jHJ }L_YNI5QEqf`9LMQfY=&Ac~2)YjfBqAq7lpjRDuH&Q(nS9*n zobtW~7jrDGCw5SCt$E6-n}cLth1*{$Q}-dTeHB8Xb1X@;iXR)9B(u`&P8cJgAQZN< zCu=#O;);&9z^=5^;J6Mbyz0y=u $U2+%N3-h0KxXX-|# x=pVt0~qF(_y zPPVi4Q%{Jlo~mnT0xW)b7t40U=4C6z$II1+f*UZwFkkh?(ht8k_N#Y@AHD{Eoj~ME z4uuH`PG5tYO1xk1&&%HQ?0K@)<3`(lL<(xf7Hf$iP?hu%PN2J6Tn_)Wp{dkVTW^DT zPE5!{SIKz#6N;|fMgOU>$Rn_}qL1xUO>%6()_cJ(sqPq%S}rP0E%14*)DcnSnwPNY z-m5`{SK`M`>Wm6QH{q;K@f=iWggwBtpsumO?sR+myojxar;a1!mUQd&h>ChNRPw6D z4Q&g4{&A+rnh`|+)Fy)?v#VERd|^sH 7$#4CES`?;0o()M6;ZUA*Oz-h->6PQ=& zaBmxd_>@t6OzV{BWSGR88AxQZ 3uK_DeH0irMfw$#IA$uC5hT$x{vspd|G20l?%(*GLL?iUxw9j`htF@ zEE$8Pa<%>Ushz#U<3J7e%K0x!&EMKSLGH#kN3njer|mcdb $AgVC{WJ&kW#eWH5;974WC#a?_Cf7^3gF1aseWZC%OlGkL#49 zU{&(CIyJ&Ai{==gaDFg}=7iw_`%s~KDE7kDc~WbT5PoYow@aR^-TA~z8j7L9jlrvK zt;mm9@)clWBpGVfgXq==oA sjR zaFDIs*0pqid0@g)zWze(3ZWfl?vZHah4)*cMidzyAfPZ0@aeZv-wbBFPAA~@5&iXP zzV;EPdYxS?*xFMbi9@8i#+oMm*QahHU#LTQ=s)k}IiPQvPiTj6_;K_d7VUgiEmrI3 z{@5Eu_P|U?9exIm#=XWwax*jZ!b(UWolRG493PKk-@HfytmeG!Wi5Bc^1h(Z6?x@s z_+IE{llSI4lTY|Q)Wc&m^z%(3X-dT_1$#ro)if^a 3|BklD0lp&>ph^A! 50iHI%@kZ_Wxjm}} zJmfs?>VA1+ Ij@^uW%DB;f%-=!wu3_|!km zx1#=jtJ;S$0Cu>P4cJg-xzt@{76L-<5CkuBmxb*EG9j@=@czAx)0E#zM0oggnXUjO zIH2{TXY|J<*n-M@6SU%d0MUeti))>*NN L0dc^!a zH$enE7z+!F(4M8|p?C8DLmZQxx9_(5AzDwD%+*@Y6i#A(Vh@I{KSm?{@VMm6S;-VI z<~5b ^c6dq!%IZFa=wS+XG{i;M61ibCJ4O4NUF ZG+1Iw) zr!i4NuL;P=?_Q)ksehG?QvvV|&j!5T1$uMUvix`x)L1_?p@T*MX!NmfSOWd~UGlGA zzgq51my+<<-E71w`Eu#9&UBa{@@FffjJ