diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..36a52c9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/out
+/build
diff --git a/LICENSE.TXT b/LICENSE.TXT
new file mode 100644
index 0000000..b87729b
--- /dev/null
+++ b/LICENSE.TXT
@@ -0,0 +1,229 @@
+==============================================================================
+The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
+==============================================================================
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ 1. Definitions.
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+ END OF TERMS AND CONDITIONS
+ APPENDIX: How to apply the Apache License to your work.
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+ Copyright [yyyy] [name of copyright owner]
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---- LLVM Exceptions to the Apache 2.0 License ----
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+==============================================================================
+Software from third parties included in the LLVM Project:
+==============================================================================
+The LLVM Project contains third party software which is under different license
+terms. All such code will be identified clearly using at least one of two
+mechanisms:
+1) It will be in a separate directory tree with its own `LICENSE.txt` or
+ `LICENSE` file at the top containing the specific license and restrictions
+ which apply to that software, or
+2) It will contain specific license and restriction terms at the top of every
+ file.
+==============================================================================
+Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign.
+All rights reserved.
+Developed by:
+ LLVM Team
+ University of Illinois at Urbana-Champaign
+ http://llvm.org
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a8b25da
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+**Android ndk for Termux(only supports aarch64 and Android 9 or above)**
+
+The source code from AOSP [llvm-toolchain](https://android.googlesource.com/toolchain/llvm-project), which is consistent with the official NDK version.
+
+At first, we don‘t need to rebuild the whole NDK, since google already built most of it.
+so we only need to build the llvm toolchain, then replace the llvm inside NDK.
+
+Building the `android-ndk`, please refer to [Android Clang/LLVM Toolchain Readme Doc](https://android.googlesource.com/toolchain/llvm_android/+/master/README.md)
+
+Packaging and testing the `android-ndk`, please refer to [Ndk Toolchains Readme Doc](https://android.googlesource.com/platform/ndk/+/master/docs/Toolchains.md)
+
+Building `android app` with termux-ndk, please refer to [build-app](https://github.com/Lzhiyong/termux-ndk/tree/master/build-app)
diff --git a/build-app/GL2/README.md b/build-app/GL2/README.md
new file mode 100644
index 0000000..62e18e1
--- /dev/null
+++ b/build-app/GL2/README.md
@@ -0,0 +1,56 @@
+Hello GL2
+=========
+Hello GL2 is an Android C++ sample that draws a triangle using GLES 2.0 API.
+
+It uses JNI to do the rendering in C++ over a
+[GLSurfaceView](http://developer.android.com/reference/android/opengl/GLSurfaceView.html)
+created from a regular Android Java Activity.
+
+This sample uses the new [Android Studio CMake plugin](http://tools.android.com/tech-docs/external-c-builds) with C++ support.
+
+Pre-requisites
+--------------
+- Android Studio 2.2 preview+ with [NDK](https://developer.android.com/ndk/) bundle.
+
+Getting Started
+---------------
+1. [Download Android Studio](http://developer.android.com/sdk/index.html)
+1. Launch Android Studio.
+1. Open the sample directory.
+1. Open *File/Project Structure...*
+ - Click *Download* or *Select NDK location*.
+1. Click *Tools/Android/Sync Project with Gradle Files*.
+1. Click *Run/Run 'app'*.
+
+Screenshots
+-----------
+![screenshot](gles2.jpg)
+
+Support
+-------
+If you've found an error in these samples, please [file an issue](https://github.com/googlesamples/android-ndk/issues/new).
+
+Patches are encouraged, and may be submitted by [forking this project](https://github.com/googlesamples/android-ndk/fork) and
+submitting a pull request through GitHub. Please see [CONTRIBUTING.md](../CONTRIBUTING.md) for more details.
+
+- [Stack Overflow](http://stackoverflow.com/questions/tagged/android-ndk)
+- [Android Tools Feedbacks](http://tools.android.com/feedback)
+
+License
+-------
+Copyright 2015 Google, Inc.
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements. See the NOTICE file distributed with this work for
+additional information regarding copyright ownership. The ASF licenses this
+file to you under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
diff --git a/build-app/GL2/app/build.gradle b/build-app/GL2/app/build.gradle
new file mode 100644
index 0000000..4b6b461
--- /dev/null
+++ b/build-app/GL2/app/build.gradle
@@ -0,0 +1,40 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 31
+ buildToolsVersion "34.0.0"
+ namespace = "com.android.gles2"
+
+ defaultConfig {
+ applicationId 'com.android.gl2'
+ minSdkVersion 21
+ targetSdkVersion 28
+ externalNativeBuild {
+ cmake {
+ // Available arguments are inside ${SDK}/cmake/.../android.toolchain.cmake file
+ arguments '-DANDROID_STL=c++_static'
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled = false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'),
+ 'proguard-rules.pro'
+ }
+ }
+
+ externalNativeBuild {
+ cmake {
+ version '3.18.5+'
+ path 'src/main/cpp/CMakeLists.txt'
+ }
+ }
+
+ //externalNativeBuild {
+ // ndkBuild {
+ // path 'src/main/cpp/Android.mk'
+ // }
+ //}
+}
diff --git a/build-app/GL2/app/proguard-rules.pro b/build-app/GL2/app/proguard-rules.pro
new file mode 100644
index 0000000..418646a
--- /dev/null
+++ b/build-app/GL2/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in E:\Android\sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/build-app/GL2/app/src/main/AndroidManifest.xml b/build-app/GL2/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6004e1c
--- /dev/null
+++ b/build-app/GL2/app/src/main/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build-app/GL2/app/src/main/cpp/Android.mk b/build-app/GL2/app/src/main/cpp/Android.mk
new file mode 100644
index 0000000..48634e2
--- /dev/null
+++ b/build-app/GL2/app/src/main/cpp/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_EXTENSION := .cpp .cc
+LOCAL_CFLAGS += -Wall
+LOCAL_CPPFLAGS += -std=c++11 -Wall
+
+LOCAL_MODULE := gl2
+LOCAL_SRC_FILES := gl_code.cpp
+
+ifeq ($(TARGET_ARCH_ABI),x86)
+ LOCAL_CFLAGS += -ffast-math -mtune=atom -mssse3 -mfpmath=sse
+endif
+
+LOCAL_LDLIBS := -lGLESv2 -lEGL -llog -landroid
+
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/build-app/GL2/app/src/main/cpp/Application.mk b/build-app/GL2/app/src/main/cpp/Application.mk
new file mode 100644
index 0000000..eed9c96
--- /dev/null
+++ b/build-app/GL2/app/src/main/cpp/Application.mk
@@ -0,0 +1,3 @@
+APP_ABI := all
+APP_STL := c++_static
+APP_PLATFORM := android-28
\ No newline at end of file
diff --git a/build-app/GL2/app/src/main/cpp/CMakeLists.txt b/build-app/GL2/app/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000..1407e1a
--- /dev/null
+++ b/build-app/GL2/app/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.14.2)
+
+# now build app's shared lib
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
+
+add_library(gl2 SHARED gl_code.cpp)
+
+# add lib dependencies
+target_link_libraries(gl2
+ android
+ log
+ EGL
+ GLESv2)
+
diff --git a/build-app/GL2/app/src/main/cpp/gl_code.cpp b/build-app/GL2/app/src/main/cpp/gl_code.cpp
new file mode 100644
index 0000000..737c4b9
--- /dev/null
+++ b/build-app/GL2/app/src/main/cpp/gl_code.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// OpenGL ES 2.0 code
+
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#define LOG_TAG "libgl2jni"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+
+static void printGLString(const char *name, GLenum s) {
+ const char *v = (const char *) glGetString(s);
+ LOGI("GL %s = %s\n", name, v);
+}
+
+static void checkGlError(const char* op) {
+ for (GLint error = glGetError(); error; error
+ = glGetError()) {
+ LOGI("after %s() glError (0x%x)\n", op, error);
+ }
+}
+
+auto gVertexShader =
+ "attribute vec4 vPosition;\n"
+ "void main() {\n"
+ " gl_Position = vPosition;\n"
+ "}\n";
+
+auto gFragmentShader =
+ "precision mediump float;\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+ GLuint shader = glCreateShader(shaderType);
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ glCompileShader(shader);
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ LOGE("Could not compile shader %d:\n%s\n",
+ shaderType, buf);
+ free(buf);
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ }
+ return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+ if (!vertexShader) {
+ return 0;
+ }
+
+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+ if (!pixelShader) {
+ return 0;
+ }
+
+ GLuint program = glCreateProgram();
+ if (program) {
+ glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ LOGE("Could not link program:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+}
+
+GLuint gProgram;
+GLuint gvPositionHandle;
+
+bool setupGraphics(int w, int h) {
+ printGLString("Version", GL_VERSION);
+ printGLString("Vendor", GL_VENDOR);
+ printGLString("Renderer", GL_RENDERER);
+ printGLString("Extensions", GL_EXTENSIONS);
+
+ LOGI("setupGraphics(%d, %d)", w, h);
+ gProgram = createProgram(gVertexShader, gFragmentShader);
+ if (!gProgram) {
+ LOGE("Could not create program.");
+ return false;
+ }
+ gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+ checkGlError("glGetAttribLocation");
+ LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
+ gvPositionHandle);
+
+ glViewport(0, 0, w, h);
+ checkGlError("glViewport");
+ return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f };
+
+void renderFrame() {
+ static float grey;
+ grey += 0.01f;
+ if (grey > 1.0f) {
+ grey = 1.0f;
+ }
+ glClearColor(grey, grey, grey, 1.0f);
+ checkGlError("glClearColor");
+ glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ checkGlError("glClear");
+
+ glUseProgram(gProgram);
+ checkGlError("glUseProgram");
+
+ glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(gvPositionHandle);
+ checkGlError("glEnableVertexAttribArray");
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
+}
+
+extern "C" {
+ JNIEXPORT void JNICALL Java_com_android_gl2_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
+ JNIEXPORT void JNICALL Java_com_android_gl2_GL2JNILib_step(JNIEnv * env, jobject obj);
+};
+
+JNIEXPORT void JNICALL Java_com_android_gl2_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height)
+{
+ setupGraphics(width, height);
+}
+
+JNIEXPORT void JNICALL Java_com_android_gl2_GL2JNILib_step(JNIEnv * env, jobject obj)
+{
+ renderFrame();
+}
diff --git a/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNIActivity.java b/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNIActivity.java
new file mode 100644
index 0000000..71cabbe
--- /dev/null
+++ b/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNIActivity.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gl2;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GL2JNIActivity extends Activity {
+
+ GL2JNIView mView;
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mView = new GL2JNIView(getApplication());
+ setContentView(mView);
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+}
diff --git a/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNILib.java b/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNILib.java
new file mode 100644
index 0000000..5154e9f
--- /dev/null
+++ b/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNILib.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gl2;
+
+// Wrapper for native library
+
+public class GL2JNILib {
+
+ static {
+ System.loadLibrary("gl2");
+ }
+
+ /**
+ * @param width the current view width
+ * @param height the current view height
+ */
+ public static native void init(int width, int height);
+ public static native void step();
+}
diff --git a/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNIView.java b/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNIView.java
new file mode 100644
index 0000000..eda07d2
--- /dev/null
+++ b/build-app/GL2/app/src/main/java/com/android/gl2/GL2JNIView.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gl2;
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A simple GLSurfaceView sub-class that demonstrate how to perform
+ * OpenGL ES 2.0 rendering into a GL Surface. Note the following important
+ * details:
+ *
+ * - The class must use a custom context factory to enable 2.0 rendering.
+ * See ContextFactory class definition below.
+ *
+ * - The class must use a custom EGLConfigChooser to be able to select
+ * an EGLConfig that supports 2.0. This is done by providing a config
+ * specification to eglChooseConfig() that has the attribute
+ * EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag
+ * set. See ConfigChooser class definition below.
+ *
+ * - The class must select the surface's format, then choose an EGLConfig
+ * that matches it exactly (with regards to red/green/blue/alpha channels
+ * bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
+ */
+class GL2JNIView extends GLSurfaceView {
+ private static String TAG = "GL2JNIView";
+ private static final boolean DEBUG = false;
+
+ public GL2JNIView(Context context) {
+ super(context);
+ init(false, 0, 0);
+ }
+
+ public GL2JNIView(Context context, boolean translucent, int depth, int stencil) {
+ super(context);
+ init(translucent, depth, stencil);
+ }
+
+ private void init(boolean translucent, int depth, int stencil) {
+
+ /* By default, GLSurfaceView() creates a RGB_565 opaque surface.
+ * If we want a translucent one, we should change the surface's
+ * format here, using PixelFormat.TRANSLUCENT for GL Surfaces
+ * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.
+ */
+ if (translucent) {
+ this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+ }
+
+ /* Setup the context factory for 2.0 rendering.
+ * See ContextFactory class definition below
+ */
+ setEGLContextFactory(new ContextFactory());
+
+ /* We need to choose an EGLConfig that matches the format of
+ * our surface exactly. This is going to be done in our
+ * custom config chooser. See ConfigChooser class definition
+ * below.
+ */
+ setEGLConfigChooser( translucent ?
+ new ConfigChooser(8, 8, 8, 8, depth, stencil) :
+ new ConfigChooser(5, 6, 5, 0, depth, stencil) );
+
+ /* Set the renderer responsible for frame rendering */
+ setRenderer(new Renderer());
+ }
+
+ private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
+ private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+ public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+ Log.w(TAG, "creating OpenGL ES 2.0 context");
+ checkEglError("Before eglCreateContext", egl);
+ int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
+ EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
+ checkEglError("After eglCreateContext", egl);
+ return context;
+ }
+
+ public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
+ egl.eglDestroyContext(display, context);
+ }
+ }
+
+ private static void checkEglError(String prompt, EGL10 egl) {
+ int error;
+ while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
+ Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
+ }
+ }
+
+ private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {
+
+ public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {
+ mRedSize = r;
+ mGreenSize = g;
+ mBlueSize = b;
+ mAlphaSize = a;
+ mDepthSize = depth;
+ mStencilSize = stencil;
+ }
+
+ /* This EGL config specification is used to specify 2.0 rendering.
+ * We use a minimum size of 4 bits for red/green/blue, but will
+ * perform actual matching in chooseConfig() below.
+ */
+ private static int EGL_OPENGL_ES2_BIT = 4;
+ private static int[] s_configAttribs2 =
+ {
+ EGL10.EGL_RED_SIZE, 4,
+ EGL10.EGL_GREEN_SIZE, 4,
+ EGL10.EGL_BLUE_SIZE, 4,
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_NONE
+ };
+
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+
+ /* Get the number of minimally matching EGL configurations
+ */
+ int[] num_config = new int[1];
+ egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);
+
+ int numConfigs = num_config[0];
+
+ if (numConfigs <= 0) {
+ throw new IllegalArgumentException("No configs match configSpec");
+ }
+
+ /* Allocate then read the array of minimally matching EGL configs
+ */
+ EGLConfig[] configs = new EGLConfig[numConfigs];
+ egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);
+
+ if (DEBUG) {
+ printConfigs(egl, display, configs);
+ }
+ /* Now return the "best" one
+ */
+ return chooseConfig(egl, display, configs);
+ }
+
+ public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
+ EGLConfig[] configs) {
+ for(EGLConfig config : configs) {
+ int d = findConfigAttrib(egl, display, config,
+ EGL10.EGL_DEPTH_SIZE, 0);
+ int s = findConfigAttrib(egl, display, config,
+ EGL10.EGL_STENCIL_SIZE, 0);
+
+ // We need at least mDepthSize and mStencilSize bits
+ if (d < mDepthSize || s < mStencilSize)
+ continue;
+
+ // We want an *exact* match for red/green/blue/alpha
+ int r = findConfigAttrib(egl, display, config,
+ EGL10.EGL_RED_SIZE, 0);
+ int g = findConfigAttrib(egl, display, config,
+ EGL10.EGL_GREEN_SIZE, 0);
+ int b = findConfigAttrib(egl, display, config,
+ EGL10.EGL_BLUE_SIZE, 0);
+ int a = findConfigAttrib(egl, display, config,
+ EGL10.EGL_ALPHA_SIZE, 0);
+
+ if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)
+ return config;
+ }
+ return null;
+ }
+
+ private int findConfigAttrib(EGL10 egl, EGLDisplay display,
+ EGLConfig config, int attribute, int defaultValue) {
+
+ if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
+ return mValue[0];
+ }
+ return defaultValue;
+ }
+
+ private void printConfigs(EGL10 egl, EGLDisplay display,
+ EGLConfig[] configs) {
+ int numConfigs = configs.length;
+ Log.w(TAG, String.format("%d configurations", numConfigs));
+ for (int i = 0; i < numConfigs; i++) {
+ Log.w(TAG, String.format("Configuration %d:\n", i));
+ printConfig(egl, display, configs[i]);
+ }
+ }
+
+ private void printConfig(EGL10 egl, EGLDisplay display,
+ EGLConfig config) {
+ int[] attributes = {
+ EGL10.EGL_BUFFER_SIZE,
+ EGL10.EGL_ALPHA_SIZE,
+ EGL10.EGL_BLUE_SIZE,
+ EGL10.EGL_GREEN_SIZE,
+ EGL10.EGL_RED_SIZE,
+ EGL10.EGL_DEPTH_SIZE,
+ EGL10.EGL_STENCIL_SIZE,
+ EGL10.EGL_CONFIG_CAVEAT,
+ EGL10.EGL_CONFIG_ID,
+ EGL10.EGL_LEVEL,
+ EGL10.EGL_MAX_PBUFFER_HEIGHT,
+ EGL10.EGL_MAX_PBUFFER_PIXELS,
+ EGL10.EGL_MAX_PBUFFER_WIDTH,
+ EGL10.EGL_NATIVE_RENDERABLE,
+ EGL10.EGL_NATIVE_VISUAL_ID,
+ EGL10.EGL_NATIVE_VISUAL_TYPE,
+ 0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
+ EGL10.EGL_SAMPLES,
+ EGL10.EGL_SAMPLE_BUFFERS,
+ EGL10.EGL_SURFACE_TYPE,
+ EGL10.EGL_TRANSPARENT_TYPE,
+ EGL10.EGL_TRANSPARENT_RED_VALUE,
+ EGL10.EGL_TRANSPARENT_GREEN_VALUE,
+ EGL10.EGL_TRANSPARENT_BLUE_VALUE,
+ 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
+ 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
+ 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
+ 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
+ EGL10.EGL_LUMINANCE_SIZE,
+ EGL10.EGL_ALPHA_MASK_SIZE,
+ EGL10.EGL_COLOR_BUFFER_TYPE,
+ EGL10.EGL_RENDERABLE_TYPE,
+ 0x3042 // EGL10.EGL_CONFORMANT
+ };
+ String[] names = {
+ "EGL_BUFFER_SIZE",
+ "EGL_ALPHA_SIZE",
+ "EGL_BLUE_SIZE",
+ "EGL_GREEN_SIZE",
+ "EGL_RED_SIZE",
+ "EGL_DEPTH_SIZE",
+ "EGL_STENCIL_SIZE",
+ "EGL_CONFIG_CAVEAT",
+ "EGL_CONFIG_ID",
+ "EGL_LEVEL",
+ "EGL_MAX_PBUFFER_HEIGHT",
+ "EGL_MAX_PBUFFER_PIXELS",
+ "EGL_MAX_PBUFFER_WIDTH",
+ "EGL_NATIVE_RENDERABLE",
+ "EGL_NATIVE_VISUAL_ID",
+ "EGL_NATIVE_VISUAL_TYPE",
+ "EGL_PRESERVED_RESOURCES",
+ "EGL_SAMPLES",
+ "EGL_SAMPLE_BUFFERS",
+ "EGL_SURFACE_TYPE",
+ "EGL_TRANSPARENT_TYPE",
+ "EGL_TRANSPARENT_RED_VALUE",
+ "EGL_TRANSPARENT_GREEN_VALUE",
+ "EGL_TRANSPARENT_BLUE_VALUE",
+ "EGL_BIND_TO_TEXTURE_RGB",
+ "EGL_BIND_TO_TEXTURE_RGBA",
+ "EGL_MIN_SWAP_INTERVAL",
+ "EGL_MAX_SWAP_INTERVAL",
+ "EGL_LUMINANCE_SIZE",
+ "EGL_ALPHA_MASK_SIZE",
+ "EGL_COLOR_BUFFER_TYPE",
+ "EGL_RENDERABLE_TYPE",
+ "EGL_CONFORMANT"
+ };
+ int[] value = new int[1];
+ for (int i = 0; i < attributes.length; i++) {
+ int attribute = attributes[i];
+ String name = names[i];
+ if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
+ Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
+ } else {
+ // Log.w(TAG, String.format(" %s: failed\n", name));
+ while (egl.eglGetError() != EGL10.EGL_SUCCESS);
+ }
+ }
+ }
+
+ // Subclasses can adjust these values:
+ protected int mRedSize;
+ protected int mGreenSize;
+ protected int mBlueSize;
+ protected int mAlphaSize;
+ protected int mDepthSize;
+ protected int mStencilSize;
+ private int[] mValue = new int[1];
+ }
+
+ private static class Renderer implements GLSurfaceView.Renderer {
+ public void onDrawFrame(GL10 gl) {
+ GL2JNILib.step();
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ GL2JNILib.init(width, height);
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ // Do nothing.
+ }
+ }
+}
diff --git a/build-app/GL2/app/src/main/res/mipmap-hdpi/ic_launcher.png b/build-app/GL2/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/build-app/GL2/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/build-app/GL2/app/src/main/res/mipmap-mdpi/ic_launcher.png b/build-app/GL2/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/build-app/GL2/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/build-app/GL2/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/build-app/GL2/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/build-app/GL2/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/build-app/GL2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/build-app/GL2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/build-app/GL2/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/build-app/GL2/app/src/main/res/values/strings.xml b/build-app/GL2/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..b0d1a20
--- /dev/null
+++ b/build-app/GL2/app/src/main/res/values/strings.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+ GL2
+
+
+
diff --git a/build-app/GL2/build.gradle b/build-app/GL2/build.gradle
new file mode 100644
index 0000000..500155d
--- /dev/null
+++ b/build-app/GL2/build.gradle
@@ -0,0 +1,17 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:8.1.0'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
diff --git a/build-app/GL2/gles2.jpg b/build-app/GL2/gles2.jpg
new file mode 100644
index 0000000..81cf25e
Binary files /dev/null and b/build-app/GL2/gles2.jpg differ
diff --git a/build-app/GL2/gradlew b/build-app/GL2/gradlew
new file mode 100644
index 0000000..2fe81a7
--- /dev/null
+++ b/build-app/GL2/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/build-app/GL2/gradlew.bat b/build-app/GL2/gradlew.bat
new file mode 100644
index 0000000..24467a1
--- /dev/null
+++ b/build-app/GL2/gradlew.bat
@@ -0,0 +1,100 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/build-app/GL2/local.properties b/build-app/GL2/local.properties
new file mode 100644
index 0000000..e40ceaf
--- /dev/null
+++ b/build-app/GL2/local.properties
@@ -0,0 +1,18 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+
+# location of the SDK. This is only used by Ant
+# For customization when using a Version Control System, please read the
+# header note
+
+# android-sdk location
+sdk.dir=/data/data/com.termux/files/home/opt/android-sdk
+
+# android-ndk location
+ndk.dir=/data/data/com.termux/files/home/opt/android-ndk-r26b
+
+# cmake location
+cmake.dir=/data/data/com.termux/files/home/opt/android-sdk/cmake
diff --git a/build-app/GL2/settings.gradle b/build-app/GL2/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/build-app/GL2/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/build-app/GL3/README.md b/build-app/GL3/README.md
new file mode 100644
index 0000000..9d67607
--- /dev/null
+++ b/build-app/GL3/README.md
@@ -0,0 +1,61 @@
+gles3
+=========
+gles3 is an Android C++ sample that demonstrates how to use OpenGL ES 3.0 from JNI/native code.
+
+The OpenGL ES 3.0 rendering path uses a few new features compared to the
+OpenGL ES 2.0 path:
+- Instanced rendering and vertex attribute divisor to reduce the number of
+ draw calls and uniform changes.
+- Vertex array objects to reduce the number of calls required to set up
+ vertex attribute state on each frame.
+- Explicit assignment of attribute locations, eliminating the need to query
+ assignments.
+
+This sample uses the new [Android Studio CMake plugin](http://tools.android.com/tech-docs/external-c-builds) with C++ support.
+
+Pre-requisites
+--------------
+- Android Studio 1.3+ with [NDK](https://developer.android.com/ndk/) bundle.
+
+Getting Started
+---------------
+1. [Download Android Studio](http://developer.android.com/sdk/index.html)
+1. Launch Android Studio.
+1. Open the sample directory.
+1. Open *File/Project Structure...*
+ - Click *Download* or *Select NDK location*.
+1. Click *Tools/Android/Sync Project with Gradle Files*.
+1. Click *Run/Run 'app'*.
+
+Screenshots
+-----------
+![screenshot](gles3.jpg)
+
+Support
+-------
+If you've found an error in these samples, please [file an issue](https://github.com/googlesamples/android-ndk/issues/new).
+
+Patches are encouraged, and may be submitted by [forking this project](https://github.com/googlesamples/android-ndk/fork) and
+submitting a pull request through GitHub. Please see [CONTRIBUTING.md](../CONTRIBUTING.md) for more details.
+
+- [Stack Overflow](http://stackoverflow.com/questions/tagged/android-ndk)
+- [Android Tools Feedbacks](http://tools.android.com/feedback)
+
+License
+-------
+Copyright 2015 Google, Inc.
+
+Licensed to the Apache Software Foundation (ASF) under one or more contributor
+license agreements. See the NOTICE file distributed with this work for
+additional information regarding copyright ownership. The ASF licenses this
+file to you under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
diff --git a/build-app/GL3/app/build.gradle b/build-app/GL3/app/build.gradle
new file mode 100644
index 0000000..f434cbd
--- /dev/null
+++ b/build-app/GL3/app/build.gradle
@@ -0,0 +1,44 @@
+apply plugin: 'com.android.application'
+
+def platformVersion = 24 // openGLES 3.2 min api level
+// def platformVersion = 18 //openGLES 3 min api level
+// def platformVersion = 12 //openGLES 2 min api level
+
+android {
+ compileSdkVersion 31
+ buildToolsVersion "34.0.0"
+ namespace = "com.android.gles3"
+
+ defaultConfig {
+ applicationId 'com.android.gles3'
+ minSdkVersion "${platformVersion}"
+ targetSdkVersion 28
+
+ externalNativeBuild {
+ cmake {
+ arguments '-DANDROID_STL=c++_static'
+ }
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled = false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'),
+ 'proguard-rules.pro'
+ }
+ }
+
+ //externalNativeBuild {
+ // cmake {
+ // version '3.18.5+'
+ // path 'src/main/cpp/CMakeLists.txt'
+ // }
+ //}
+
+ externalNativeBuild {
+ ndkBuild {
+ path 'src/main/cpp/Android.mk'
+ }
+ }
+}
diff --git a/build-app/GL3/app/proguard-rules.pro b/build-app/GL3/app/proguard-rules.pro
new file mode 100644
index 0000000..418646a
--- /dev/null
+++ b/build-app/GL3/app/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in E:\Android\sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/build-app/GL3/app/src/main/AndroidManifest.xml b/build-app/GL3/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..947300a
--- /dev/null
+++ b/build-app/GL3/app/src/main/AndroidManifest.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build-app/GL3/app/src/main/cpp/Android.mk b/build-app/GL3/app/src/main/cpp/Android.mk
new file mode 100644
index 0000000..4524343
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPP_EXTENSION := .cpp .cc
+LOCAL_CFLAGS += -Wall
+LOCAL_CPPFLAGS += -std=c++11 -fno-rtti -fno-exceptions -Wall
+
+LOCAL_MODULE := gles3
+LOCAL_SRC_FILES := gles3jni.cpp \
+ RendererES2.cpp \
+ RendererES3.cpp
+
+ifeq ($(TARGET_ARCH_ABI),x86)
+ LOCAL_CFLAGS += -ffast-math -mtune=atom -mssse3 -mfpmath=sse
+endif
+
+LOCAL_LDLIBS := -lGLESv3 -lEGL -landroid -llog
+
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/build-app/GL3/app/src/main/cpp/Application.mk b/build-app/GL3/app/src/main/cpp/Application.mk
new file mode 100644
index 0000000..eed9c96
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/Application.mk
@@ -0,0 +1,3 @@
+APP_ABI := all
+APP_STL := c++_static
+APP_PLATFORM := android-28
\ No newline at end of file
diff --git a/build-app/GL3/app/src/main/cpp/CMakeLists.txt b/build-app/GL3/app/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000..de2b585
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,47 @@
+cmake_minimum_required(VERSION 3.14.2)
+# set targetPlatform, will be passed in from gradle when this sample is completed
+# openGL Supportability
+# platform status
+# (0 12) ES2/ES3 not supported
+# [12, 18) ES2 only; for ES3, app do dynamic load/detection
+# this applies to the situations that:
+# - minimum API is set to less than 18. In this case
+# there is no ES3 header/lib support inside NDK
+# - the built APK might be running on newer API phones
+# with dynamic loading of ES3, the same APK would still be able
+# to use ES3. Otherwise, app would stuck with ES2 even phone is
+# is newer than the minimum API level (for example, Android-27 etc).
+#
+# [18, 24) ES2 & ES3
+# If app is built to only support API-18 or later,
+# set minimum api level to 18 is good enough, NDK supprts ES3
+# with the right header and lib files. No need to use ES3 dynamic
+# detection.
+# [24, infinite) ES2 & ES3 & Vulkan
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -Wall")
+if (${ANDROID_PLATFORM_LEVEL} LESS 12)
+ message(FATAL_ERROR "OpenGL 2 is not supported before API level 11 \
+ (currently using ${ANDROID_PLATFORM_LEVEL}).")
+ return()
+elseif (${ANDROID_PLATFORM_LEVEL} LESS 18)
+ add_definitions("-DDYNAMIC_ES3")
+ set(GL3STUB_SRC gl3stub.c)
+ set(OPENGL_LIB GLESv2)
+else ()
+ set(OPENGL_LIB GLESv3)
+endif (${ANDROID_PLATFORM_LEVEL} LESS 12)
+
+add_library(gles3 SHARED
+ ${GL3STUB_SRC}
+ gles3jni.cpp
+ RendererES2.cpp
+ RendererES3.cpp)
+
+# Include libraries needed for gles3 lib
+target_link_libraries(gles3
+ ${OPENGL_LIB}
+ android
+ EGL
+ log)
diff --git a/build-app/GL3/app/src/main/cpp/RendererES2.cpp b/build-app/GL3/app/src/main/cpp/RendererES2.cpp
new file mode 100644
index 0000000..6ce4e0a
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/RendererES2.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gles3jni.h"
+#include
+
+static const char VERTEX_SHADER[] =
+ "#version 100\n"
+ "uniform mat2 scaleRot;\n"
+ "uniform vec2 offset;\n"
+ "attribute vec2 pos;\n"
+ "attribute vec4 color;\n"
+ "varying vec4 vColor;\n"
+ "void main() {\n"
+ " gl_Position = vec4(scaleRot*pos + offset, 0.0, 1.0);\n"
+ " vColor = color;\n"
+ "}\n";
+
+static const char FRAGMENT_SHADER[] =
+ "#version 100\n"
+ "precision mediump float;\n"
+ "varying vec4 vColor;\n"
+ "void main() {\n"
+ " gl_FragColor = vColor;\n"
+ "}\n";
+
+class RendererES2: public Renderer {
+public:
+ RendererES2();
+ virtual ~RendererES2();
+ bool init();
+
+private:
+ virtual float* mapOffsetBuf();
+ virtual void unmapOffsetBuf();
+ virtual float* mapTransformBuf();
+ virtual void unmapTransformBuf();
+ virtual void draw(unsigned int numInstances);
+
+ const EGLContext mEglContext;
+ GLuint mProgram;
+ GLuint mVB;
+ GLint mPosAttrib;
+ GLint mColorAttrib;
+ GLint mScaleRotUniform;
+ GLint mOffsetUniform;
+
+ float mOffsets[2*MAX_INSTANCES];
+ float mScaleRot[4*MAX_INSTANCES]; // array of 2x2 column-major matrices
+};
+
+Renderer* createES2Renderer() {
+ RendererES2* renderer = new RendererES2;
+ if (!renderer->init()) {
+ delete renderer;
+ return NULL;
+ }
+ return renderer;
+}
+
+RendererES2::RendererES2()
+: mEglContext(eglGetCurrentContext()),
+ mProgram(0),
+ mVB(0),
+ mPosAttrib(-1),
+ mColorAttrib(-1),
+ mScaleRotUniform(-1),
+ mOffsetUniform(-1)
+{}
+
+bool RendererES2::init() {
+ mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+ if (!mProgram)
+ return false;
+ mPosAttrib = glGetAttribLocation(mProgram, "pos");
+ mColorAttrib = glGetAttribLocation(mProgram, "color");
+ mScaleRotUniform = glGetUniformLocation(mProgram, "scaleRot");
+ mOffsetUniform = glGetUniformLocation(mProgram, "offset");
+
+ glGenBuffers(1, &mVB);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
+
+ ALOGV("Using OpenGL ES 2.0 renderer");
+ return true;
+}
+
+RendererES2::~RendererES2() {
+ /* The destructor may be called after the context has already been
+ * destroyed, in which case our objects have already been destroyed.
+ *
+ * If the context exists, it must be current. This only happens when we're
+ * cleaning up after a failed init().
+ */
+ if (eglGetCurrentContext() != mEglContext)
+ return;
+ glDeleteBuffers(1, &mVB);
+ glDeleteProgram(mProgram);
+}
+
+float* RendererES2::mapOffsetBuf() {
+ return mOffsets;
+}
+
+void RendererES2::unmapOffsetBuf() {
+}
+
+float* RendererES2::mapTransformBuf() {
+ return mScaleRot;
+}
+
+void RendererES2::unmapTransformBuf() {
+}
+
+void RendererES2::draw(unsigned int numInstances) {
+ glUseProgram(mProgram);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB);
+ glVertexAttribPointer(mPosAttrib, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
+ glVertexAttribPointer(mColorAttrib, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
+ glEnableVertexAttribArray(mPosAttrib);
+ glEnableVertexAttribArray(mColorAttrib);
+
+ for (unsigned int i = 0; i < numInstances; i++) {
+ glUniformMatrix2fv(mScaleRotUniform, 1, GL_FALSE, mScaleRot + 4*i);
+ glUniform2fv(mOffsetUniform, 1, mOffsets + 2*i);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ }
+}
diff --git a/build-app/GL3/app/src/main/cpp/RendererES3.cpp b/build-app/GL3/app/src/main/cpp/RendererES3.cpp
new file mode 100644
index 0000000..df71a85
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/RendererES3.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gles3jni.h"
+#include
+
+#define STR(s) #s
+#define STRV(s) STR(s)
+
+#define POS_ATTRIB 0
+#define COLOR_ATTRIB 1
+#define SCALEROT_ATTRIB 2
+#define OFFSET_ATTRIB 3
+
+static const char VERTEX_SHADER[] =
+ "#version 300 es\n"
+ "layout(location = " STRV(POS_ATTRIB) ") in vec2 pos;\n"
+ "layout(location=" STRV(COLOR_ATTRIB) ") in vec4 color;\n"
+ "layout(location=" STRV(SCALEROT_ATTRIB) ") in vec4 scaleRot;\n"
+ "layout(location=" STRV(OFFSET_ATTRIB) ") in vec2 offset;\n"
+ "out vec4 vColor;\n"
+ "void main() {\n"
+ " mat2 sr = mat2(scaleRot.xy, scaleRot.zw);\n"
+ " gl_Position = vec4(sr*pos + offset, 0.0, 1.0);\n"
+ " vColor = color;\n"
+ "}\n";
+
+static const char FRAGMENT_SHADER[] =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "in vec4 vColor;\n"
+ "out vec4 outColor;\n"
+ "void main() {\n"
+ " outColor = vColor;\n"
+ "}\n";
+
+class RendererES3: public Renderer {
+public:
+ RendererES3();
+ virtual ~RendererES3();
+ bool init();
+
+private:
+ enum {VB_INSTANCE, VB_SCALEROT, VB_OFFSET, VB_COUNT};
+
+ virtual float* mapOffsetBuf();
+ virtual void unmapOffsetBuf();
+ virtual float* mapTransformBuf();
+ virtual void unmapTransformBuf();
+ virtual void draw(unsigned int numInstances);
+
+ const EGLContext mEglContext;
+ GLuint mProgram;
+ GLuint mVB[VB_COUNT];
+ GLuint mVBState;
+};
+
+Renderer* createES3Renderer() {
+ RendererES3* renderer = new RendererES3;
+ if (!renderer->init()) {
+ delete renderer;
+ return NULL;
+ }
+ return renderer;
+}
+
+RendererES3::RendererES3()
+: mEglContext(eglGetCurrentContext()),
+ mProgram(0),
+ mVBState(0)
+{
+ for (int i = 0; i < VB_COUNT; i++)
+ mVB[i] = 0;
+}
+
+bool RendererES3::init() {
+ mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+ if (!mProgram)
+ return false;
+
+ glGenBuffers(VB_COUNT, mVB);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+ glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 4*sizeof(float), NULL, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+ glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 2*sizeof(float), NULL, GL_STATIC_DRAW);
+
+ glGenVertexArrays(1, &mVBState);
+ glBindVertexArray(mVBState);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
+ glVertexAttribPointer(POS_ATTRIB, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
+ glVertexAttribPointer(COLOR_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
+ glEnableVertexAttribArray(POS_ATTRIB);
+ glEnableVertexAttribArray(COLOR_ATTRIB);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+ glVertexAttribPointer(SCALEROT_ATTRIB, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
+ glEnableVertexAttribArray(SCALEROT_ATTRIB);
+ glVertexAttribDivisor(SCALEROT_ATTRIB, 1);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+ glVertexAttribPointer(OFFSET_ATTRIB, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0);
+ glEnableVertexAttribArray(OFFSET_ATTRIB);
+ glVertexAttribDivisor(OFFSET_ATTRIB, 1);
+
+ ALOGV("Using OpenGL ES 3.0 renderer");
+ return true;
+}
+
+RendererES3::~RendererES3() {
+ /* The destructor may be called after the context has already been
+ * destroyed, in which case our objects have already been destroyed.
+ *
+ * If the context exists, it must be current. This only happens when we're
+ * cleaning up after a failed init().
+ */
+ if (eglGetCurrentContext() != mEglContext)
+ return;
+ glDeleteVertexArrays(1, &mVBState);
+ glDeleteBuffers(VB_COUNT, mVB);
+ glDeleteProgram(mProgram);
+}
+
+float* RendererES3::mapOffsetBuf() {
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+ return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
+ 0, MAX_INSTANCES * 2*sizeof(float),
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+}
+
+void RendererES3::unmapOffsetBuf() {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+float* RendererES3::mapTransformBuf() {
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+ return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
+ 0, MAX_INSTANCES * 4*sizeof(float),
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+}
+
+void RendererES3::unmapTransformBuf() {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+void RendererES3::draw(unsigned int numInstances) {
+ glUseProgram(mProgram);
+ glBindVertexArray(mVBState);
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, numInstances);
+}
diff --git a/build-app/GL3/app/src/main/cpp/gl3stub.c b/build-app/GL3/app/src/main/cpp/gl3stub.c
new file mode 100644
index 0000000..67bf70c
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/gl3stub.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include "gl3stub.h"
+
+GLboolean gl3stubInit() {
+ #define FIND_PROC(s) s = (void*)eglGetProcAddress(#s)
+ FIND_PROC(glReadBuffer);
+ FIND_PROC(glDrawRangeElements);
+ FIND_PROC(glTexImage3D);
+ FIND_PROC(glTexSubImage3D);
+ FIND_PROC(glCopyTexSubImage3D);
+ FIND_PROC(glCompressedTexImage3D);
+ FIND_PROC(glCompressedTexSubImage3D);
+ FIND_PROC(glGenQueries);
+ FIND_PROC(glDeleteQueries);
+ FIND_PROC(glIsQuery);
+ FIND_PROC(glBeginQuery);
+ FIND_PROC(glEndQuery);
+ FIND_PROC(glGetQueryiv);
+ FIND_PROC(glGetQueryObjectuiv);
+ FIND_PROC(glUnmapBuffer);
+ FIND_PROC(glGetBufferPointerv);
+ FIND_PROC(glDrawBuffers);
+ FIND_PROC(glUniformMatrix2x3fv);
+ FIND_PROC(glUniformMatrix3x2fv);
+ FIND_PROC(glUniformMatrix2x4fv);
+ FIND_PROC(glUniformMatrix4x2fv);
+ FIND_PROC(glUniformMatrix3x4fv);
+ FIND_PROC(glUniformMatrix4x3fv);
+ FIND_PROC(glBlitFramebuffer);
+ FIND_PROC(glRenderbufferStorageMultisample);
+ FIND_PROC(glFramebufferTextureLayer);
+ FIND_PROC(glMapBufferRange);
+ FIND_PROC(glFlushMappedBufferRange);
+ FIND_PROC(glBindVertexArray);
+ FIND_PROC(glDeleteVertexArrays);
+ FIND_PROC(glGenVertexArrays);
+ FIND_PROC(glIsVertexArray);
+ FIND_PROC(glGetIntegeri_v);
+ FIND_PROC(glBeginTransformFeedback);
+ FIND_PROC(glEndTransformFeedback);
+ FIND_PROC(glBindBufferRange);
+ FIND_PROC(glBindBufferBase);
+ FIND_PROC(glTransformFeedbackVaryings);
+ FIND_PROC(glGetTransformFeedbackVarying);
+ FIND_PROC(glVertexAttribIPointer);
+ FIND_PROC(glGetVertexAttribIiv);
+ FIND_PROC(glGetVertexAttribIuiv);
+ FIND_PROC(glVertexAttribI4i);
+ FIND_PROC(glVertexAttribI4ui);
+ FIND_PROC(glVertexAttribI4iv);
+ FIND_PROC(glVertexAttribI4uiv);
+ FIND_PROC(glGetUniformuiv);
+ FIND_PROC(glGetFragDataLocation);
+ FIND_PROC(glUniform1ui);
+ FIND_PROC(glUniform2ui);
+ FIND_PROC(glUniform3ui);
+ FIND_PROC(glUniform4ui);
+ FIND_PROC(glUniform1uiv);
+ FIND_PROC(glUniform2uiv);
+ FIND_PROC(glUniform3uiv);
+ FIND_PROC(glUniform4uiv);
+ FIND_PROC(glClearBufferiv);
+ FIND_PROC(glClearBufferuiv);
+ FIND_PROC(glClearBufferfv);
+ FIND_PROC(glClearBufferfi);
+ FIND_PROC(glGetStringi);
+ FIND_PROC(glCopyBufferSubData);
+ FIND_PROC(glGetUniformIndices);
+ FIND_PROC(glGetActiveUniformsiv);
+ FIND_PROC(glGetUniformBlockIndex);
+ FIND_PROC(glGetActiveUniformBlockiv);
+ FIND_PROC(glGetActiveUniformBlockName);
+ FIND_PROC(glUniformBlockBinding);
+ FIND_PROC(glDrawArraysInstanced);
+ FIND_PROC(glDrawElementsInstanced);
+ FIND_PROC(glFenceSync);
+ FIND_PROC(glIsSync);
+ FIND_PROC(glDeleteSync);
+ FIND_PROC(glClientWaitSync);
+ FIND_PROC(glWaitSync);
+ FIND_PROC(glGetInteger64v);
+ FIND_PROC(glGetSynciv);
+ FIND_PROC(glGetInteger64i_v);
+ FIND_PROC(glGetBufferParameteri64v);
+ FIND_PROC(glGenSamplers);
+ FIND_PROC(glDeleteSamplers);
+ FIND_PROC(glIsSampler);
+ FIND_PROC(glBindSampler);
+ FIND_PROC(glSamplerParameteri);
+ FIND_PROC(glSamplerParameteriv);
+ FIND_PROC(glSamplerParameterf);
+ FIND_PROC(glSamplerParameterfv);
+ FIND_PROC(glGetSamplerParameteriv);
+ FIND_PROC(glGetSamplerParameterfv);
+ FIND_PROC(glVertexAttribDivisor);
+ FIND_PROC(glBindTransformFeedback);
+ FIND_PROC(glDeleteTransformFeedbacks);
+ FIND_PROC(glGenTransformFeedbacks);
+ FIND_PROC(glIsTransformFeedback);
+ FIND_PROC(glPauseTransformFeedback);
+ FIND_PROC(glResumeTransformFeedback);
+ FIND_PROC(glGetProgramBinary);
+ FIND_PROC(glProgramBinary);
+ FIND_PROC(glProgramParameteri);
+ FIND_PROC(glInvalidateFramebuffer);
+ FIND_PROC(glInvalidateSubFramebuffer);
+ FIND_PROC(glTexStorage2D);
+ FIND_PROC(glTexStorage3D);
+ FIND_PROC(glGetInternalformativ);
+ #undef FIND_PROC
+
+ if (!glReadBuffer ||
+ !glDrawRangeElements ||
+ !glTexImage3D ||
+ !glTexSubImage3D ||
+ !glCopyTexSubImage3D ||
+ !glCompressedTexImage3D ||
+ !glCompressedTexSubImage3D ||
+ !glGenQueries ||
+ !glDeleteQueries ||
+ !glIsQuery ||
+ !glBeginQuery ||
+ !glEndQuery ||
+ !glGetQueryiv ||
+ !glGetQueryObjectuiv ||
+ !glUnmapBuffer ||
+ !glGetBufferPointerv ||
+ !glDrawBuffers ||
+ !glUniformMatrix2x3fv ||
+ !glUniformMatrix3x2fv ||
+ !glUniformMatrix2x4fv ||
+ !glUniformMatrix4x2fv ||
+ !glUniformMatrix3x4fv ||
+ !glUniformMatrix4x3fv ||
+ !glBlitFramebuffer ||
+ !glRenderbufferStorageMultisample ||
+ !glFramebufferTextureLayer ||
+ !glMapBufferRange ||
+ !glFlushMappedBufferRange ||
+ !glBindVertexArray ||
+ !glDeleteVertexArrays ||
+ !glGenVertexArrays ||
+ !glIsVertexArray ||
+ !glGetIntegeri_v ||
+ !glBeginTransformFeedback ||
+ !glEndTransformFeedback ||
+ !glBindBufferRange ||
+ !glBindBufferBase ||
+ !glTransformFeedbackVaryings ||
+ !glGetTransformFeedbackVarying ||
+ !glVertexAttribIPointer ||
+ !glGetVertexAttribIiv ||
+ !glGetVertexAttribIuiv ||
+ !glVertexAttribI4i ||
+ !glVertexAttribI4ui ||
+ !glVertexAttribI4iv ||
+ !glVertexAttribI4uiv ||
+ !glGetUniformuiv ||
+ !glGetFragDataLocation ||
+ !glUniform1ui ||
+ !glUniform2ui ||
+ !glUniform3ui ||
+ !glUniform4ui ||
+ !glUniform1uiv ||
+ !glUniform2uiv ||
+ !glUniform3uiv ||
+ !glUniform4uiv ||
+ !glClearBufferiv ||
+ !glClearBufferuiv ||
+ !glClearBufferfv ||
+ !glClearBufferfi ||
+ !glGetStringi ||
+ !glCopyBufferSubData ||
+ !glGetUniformIndices ||
+ !glGetActiveUniformsiv ||
+ !glGetUniformBlockIndex ||
+ !glGetActiveUniformBlockiv ||
+ !glGetActiveUniformBlockName ||
+ !glUniformBlockBinding ||
+ !glDrawArraysInstanced ||
+ !glDrawElementsInstanced ||
+ !glFenceSync ||
+ !glIsSync ||
+ !glDeleteSync ||
+ !glClientWaitSync ||
+ !glWaitSync ||
+ !glGetInteger64v ||
+ !glGetSynciv ||
+ !glGetInteger64i_v ||
+ !glGetBufferParameteri64v ||
+ !glGenSamplers ||
+ !glDeleteSamplers ||
+ !glIsSampler ||
+ !glBindSampler ||
+ !glSamplerParameteri ||
+ !glSamplerParameteriv ||
+ !glSamplerParameterf ||
+ !glSamplerParameterfv ||
+ !glGetSamplerParameteriv ||
+ !glGetSamplerParameterfv ||
+ !glVertexAttribDivisor ||
+ !glBindTransformFeedback ||
+ !glDeleteTransformFeedbacks ||
+ !glGenTransformFeedbacks ||
+ !glIsTransformFeedback ||
+ !glPauseTransformFeedback ||
+ !glResumeTransformFeedback ||
+ !glGetProgramBinary ||
+ !glProgramBinary ||
+ !glProgramParameteri ||
+ !glInvalidateFramebuffer ||
+ !glInvalidateSubFramebuffer ||
+ !glTexStorage2D ||
+ !glTexStorage3D ||
+ !glGetInternalformativ)
+ {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/* Function pointer definitions */
+GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode);
+GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id);
+GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target);
+GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array);
+GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array);
+GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync);
+GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync);
+GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler);
+GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
diff --git a/build-app/GL3/app/src/main/cpp/gl3stub.h b/build-app/GL3/app/src/main/cpp/gl3stub.h
new file mode 100644
index 0000000..de35cc9
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/gl3stub.h
@@ -0,0 +1,509 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __gl3_h_
+#define __gl3_h_
+
+/*
+ * stub gl3.h for dynamic loading, based on:
+ * gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $
+ *
+ * Changes:
+ * - Added #include
+ * - Removed duplicate OpenGL ES 2.0 declarations
+ * - Converted OpenGL ES 3.0 function prototypes to function pointer
+ * declarations
+ * - Added gl3stubInit() declaration
+ */
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2013 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Call this function before calling any OpenGL ES 3.0 functions. It will
+ * return GL_TRUE if the OpenGL ES 3.0 was successfully initialized, GL_FALSE
+ * otherwise. */
+GLboolean gl3stubInit();
+
+/*-------------------------------------------------------------------------
+ * Data type definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+typedef unsigned short GLhalf;
+#if __ANDROID_API__ <= 19
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
+/*-------------------------------------------------------------------------
+ * Token definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_3_0 1
+
+/* OpenGL ES 3.0 */
+
+#define GL_READ_BUFFER 0x0C02
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_RED 0x1903
+#define GL_RGB8 0x8051
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_HALF_FLOAT 0x140B
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER
+#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_RGB10_A2UI 0x906F
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+
+/*-------------------------------------------------------------------------
+ * Entrypoint definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+extern GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode);
+extern GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+extern GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+extern GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target);
+extern GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+extern GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+extern GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+extern GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+extern GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+extern GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+extern GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+extern GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array);
+extern GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+extern GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array);
+extern GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+extern GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+extern GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+extern GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+extern GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+extern GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+extern GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+extern GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+extern GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+extern GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+extern GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+extern GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+extern GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+extern GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+extern GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+extern GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+extern GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+extern GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+extern GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+extern GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+extern GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync);
+extern GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync);
+extern GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+extern GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+extern GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+extern GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+extern GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+extern GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler);
+extern GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+extern GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+extern GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+extern GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+extern GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+extern GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+extern GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+extern GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/build-app/GL3/app/src/main/cpp/gles3jni.cpp b/build-app/GL3/app/src/main/cpp/gles3jni.cpp
new file mode 100644
index 0000000..01dbe4d
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/gles3jni.cpp
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include
+#include
+#include
+
+#include "gles3jni.h"
+
+const Vertex QUAD[4] = {
+ // Square with diagonal < 2 so that it fits in a [-1 .. 1]^2 square
+ // regardless of rotation.
+ {{-0.7f, -0.7f}, {0x00, 0xFF, 0x00}},
+ {{ 0.7f, -0.7f}, {0x00, 0x00, 0xFF}},
+ {{-0.7f, 0.7f}, {0xFF, 0x00, 0x00}},
+ {{ 0.7f, 0.7f}, {0xFF, 0xFF, 0xFF}},
+};
+
+bool checkGlError(const char* funcName) {
+ GLint err = glGetError();
+ if (err != GL_NO_ERROR) {
+ ALOGE("GL error after %s(): 0x%08x\n", funcName, err);
+ return true;
+ }
+ return false;
+}
+
+GLuint createShader(GLenum shaderType, const char* src) {
+ GLuint shader = glCreateShader(shaderType);
+ if (!shader) {
+ checkGlError("glCreateShader");
+ return 0;
+ }
+ glShaderSource(shader, 1, &src, NULL);
+
+ GLint compiled = GL_FALSE;
+ glCompileShader(shader);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLogLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
+ if (infoLogLen > 0) {
+ GLchar* infoLog = (GLchar*)malloc(infoLogLen);
+ if (infoLog) {
+ glGetShaderInfoLog(shader, infoLogLen, NULL, infoLog);
+ ALOGE("Could not compile %s shader:\n%s\n",
+ shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment",
+ infoLog);
+ free(infoLog);
+ }
+ }
+ glDeleteShader(shader);
+ return 0;
+ }
+
+ return shader;
+}
+
+GLuint createProgram(const char* vtxSrc, const char* fragSrc) {
+ GLuint vtxShader = 0;
+ GLuint fragShader = 0;
+ GLuint program = 0;
+ GLint linked = GL_FALSE;
+
+ vtxShader = createShader(GL_VERTEX_SHADER, vtxSrc);
+ if (!vtxShader)
+ goto exit;
+
+ fragShader = createShader(GL_FRAGMENT_SHADER, fragSrc);
+ if (!fragShader)
+ goto exit;
+
+ program = glCreateProgram();
+ if (!program) {
+ checkGlError("glCreateProgram");
+ goto exit;
+ }
+ glAttachShader(program, vtxShader);
+ glAttachShader(program, fragShader);
+
+ glLinkProgram(program);
+ glGetProgramiv(program, GL_LINK_STATUS, &linked);
+ if (!linked) {
+ ALOGE("Could not link program");
+ GLint infoLogLen = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
+ if (infoLogLen) {
+ GLchar* infoLog = (GLchar*)malloc(infoLogLen);
+ if (infoLog) {
+ glGetProgramInfoLog(program, infoLogLen, NULL, infoLog);
+ ALOGE("Could not link program:\n%s\n", infoLog);
+ free(infoLog);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+
+exit:
+ glDeleteShader(vtxShader);
+ glDeleteShader(fragShader);
+ return program;
+}
+
+static void printGlString(const char* name, GLenum s) {
+ const char* v = (const char*)glGetString(s);
+ ALOGV("GL %s: %s\n", name, v);
+}
+
+// ----------------------------------------------------------------------------
+
+Renderer::Renderer()
+: mNumInstances(0),
+ mLastFrameNs(0)
+{
+ memset(mScale, 0, sizeof(mScale));
+ memset(mAngularVelocity, 0, sizeof(mAngularVelocity));
+ memset(mAngles, 0, sizeof(mAngles));
+}
+
+Renderer::~Renderer() {
+}
+
+void Renderer::resize(int w, int h) {
+ auto offsets = mapOffsetBuf();
+ calcSceneParams(w, h, offsets);
+ unmapOffsetBuf();
+
+ // Auto gives a signed int :-(
+ for (auto i = (unsigned)0; i < mNumInstances; i++) {
+ mAngles[i] = drand48() * TWO_PI;
+ mAngularVelocity[i] = MAX_ROT_SPEED * (2.0*drand48() - 1.0);
+ }
+
+ mLastFrameNs = 0;
+
+ glViewport(0, 0, w, h);
+}
+
+void Renderer::calcSceneParams(unsigned int w, unsigned int h,
+ float* offsets) {
+ // number of cells along the larger screen dimension
+ const float NCELLS_MAJOR = MAX_INSTANCES_PER_SIDE;
+ // cell size in scene space
+ const float CELL_SIZE = 2.0f / NCELLS_MAJOR;
+
+ // Calculations are done in "landscape", i.e. assuming dim[0] >= dim[1].
+ // Only at the end are values put in the opposite order if h > w.
+ const float dim[2] = {fmaxf(w,h), fminf(w,h)};
+ const float aspect[2] = {dim[0] / dim[1], dim[1] / dim[0]};
+ const float scene2clip[2] = {1.0f, aspect[0]};
+ const int ncells[2] = {
+ static_cast(NCELLS_MAJOR),
+ (int)floorf(NCELLS_MAJOR * aspect[1])
+ };
+
+ float centers[2][MAX_INSTANCES_PER_SIDE];
+ for (int d = 0; d < 2; d++) {
+ auto offset = -ncells[d] / NCELLS_MAJOR; // -1.0 for d=0
+ for (auto i = 0; i < ncells[d]; i++) {
+ centers[d][i] = scene2clip[d] * (CELL_SIZE*(i + 0.5f) + offset);
+ }
+ }
+
+ int major = w >= h ? 0 : 1;
+ int minor = w >= h ? 1 : 0;
+ // outer product of centers[0] and centers[1]
+ for (int i = 0; i < ncells[0]; i++) {
+ for (int j = 0; j < ncells[1]; j++) {
+ int idx = i*ncells[1] + j;
+ offsets[2*idx + major] = centers[0][i];
+ offsets[2*idx + minor] = centers[1][j];
+ }
+ }
+
+ mNumInstances = ncells[0] * ncells[1];
+ mScale[major] = 0.5f * CELL_SIZE * scene2clip[0];
+ mScale[minor] = 0.5f * CELL_SIZE * scene2clip[1];
+}
+
+void Renderer::step() {
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ auto nowNs = now.tv_sec*1000000000ull + now.tv_nsec;
+
+ if (mLastFrameNs > 0) {
+ float dt = float(nowNs - mLastFrameNs) * 0.000000001f;
+
+ for (unsigned int i = 0; i < mNumInstances; i++) {
+ mAngles[i] += mAngularVelocity[i] * dt;
+ if (mAngles[i] >= TWO_PI) {
+ mAngles[i] -= TWO_PI;
+ } else if (mAngles[i] <= -TWO_PI) {
+ mAngles[i] += TWO_PI;
+ }
+ }
+
+ float* transforms = mapTransformBuf();
+ for (unsigned int i = 0; i < mNumInstances; i++) {
+ float s = sinf(mAngles[i]);
+ float c = cosf(mAngles[i]);
+ transforms[4*i + 0] = c * mScale[0];
+ transforms[4*i + 1] = s * mScale[1];
+ transforms[4*i + 2] = -s * mScale[0];
+ transforms[4*i + 3] = c * mScale[1];
+ }
+ unmapTransformBuf();
+ }
+
+ mLastFrameNs = nowNs;
+}
+
+void Renderer::render() {
+ step();
+
+ glClearColor(0.2f, 0.2f, 0.3f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ draw(mNumInstances);
+ checkGlError("Renderer::render");
+}
+
+// ----------------------------------------------------------------------------
+
+static Renderer* g_renderer = NULL;
+
+extern "C" {
+ JNIEXPORT void JNICALL Java_com_android_gles3_GLES3JNILib_init(JNIEnv* env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_gles3_GLES3JNILib_resize(JNIEnv* env, jobject obj, jint width, jint height);
+ JNIEXPORT void JNICALL Java_com_android_gles3_GLES3JNILib_step(JNIEnv* env, jobject obj);
+};
+
+#if !defined(DYNAMIC_ES3)
+static GLboolean gl3stubInit() {
+ return GL_TRUE;
+}
+#endif
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3_GLES3JNILib_init(JNIEnv* env, jobject obj) {
+ if (g_renderer) {
+ delete g_renderer;
+ g_renderer = NULL;
+ }
+
+ printGlString("Version", GL_VERSION);
+ printGlString("Vendor", GL_VENDOR);
+ printGlString("Renderer", GL_RENDERER);
+ printGlString("Extensions", GL_EXTENSIONS);
+
+ const char* versionStr = (const char*)glGetString(GL_VERSION);
+ if (strstr(versionStr, "OpenGL ES 3.") && gl3stubInit()) {
+ g_renderer = createES3Renderer();
+ } else if (strstr(versionStr, "OpenGL ES 2.")) {
+ g_renderer = createES2Renderer();
+ } else {
+ ALOGE("Unsupported OpenGL ES version");
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3_GLES3JNILib_resize(JNIEnv* env, jobject obj, jint width, jint height) {
+ if (g_renderer) {
+ g_renderer->resize(width, height);
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3_GLES3JNILib_step(JNIEnv* env, jobject obj) {
+ if (g_renderer) {
+ g_renderer->render();
+ }
+}
diff --git a/build-app/GL3/app/src/main/cpp/gles3jni.h b/build-app/GL3/app/src/main/cpp/gles3jni.h
new file mode 100644
index 0000000..0b03e0d
--- /dev/null
+++ b/build-app/GL3/app/src/main/cpp/gles3jni.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GLES3JNI_H
+#define GLES3JNI_H 1
+
+#include
+#include
+
+#if DYNAMIC_ES3
+#include "gl3stub.h"
+#else
+// Include the latest possible header file( GL version header )
+#if __ANDROID_API__ >= 24
+#include
+#elif __ANDROID_API__ >= 21
+#include
+#else
+#include
+#endif
+
+#endif
+
+#define DEBUG 1
+
+#define LOG_TAG "GLES3JNI"
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#if DEBUG
+#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
+#else
+#define ALOGV(...)
+#endif
+
+// ----------------------------------------------------------------------------
+// Types, functions, and data used by both ES2 and ES3 renderers.
+// Defined in gles3jni.cpp.
+
+#define MAX_INSTANCES_PER_SIDE 16
+#define MAX_INSTANCES (MAX_INSTANCES_PER_SIDE * MAX_INSTANCES_PER_SIDE)
+#define TWO_PI (2.0 * M_PI)
+#define MAX_ROT_SPEED (0.3 * TWO_PI)
+
+// This demo uses three coordinate spaces:
+// - The model (a quad) is in a [-1 .. 1]^2 space
+// - Scene space is either
+// landscape: [-1 .. 1] x [-1/(2*w/h) .. 1/(2*w/h)]
+// portrait: [-1/(2*h/w) .. 1/(2*h/w)] x [-1 .. 1]
+// - Clip space in OpenGL is [-1 .. 1]^2
+//
+// Conceptually, the quads are rotated in model space, then scaled (uniformly)
+// and translated to place them in scene space. Scene space is then
+// non-uniformly scaled to clip space. In practice the transforms are combined
+// so vertices go directly from model to clip space.
+
+struct Vertex {
+ GLfloat pos[2];
+ GLubyte rgba[4];
+};
+extern const Vertex QUAD[4];
+
+// returns true if a GL error occurred
+extern bool checkGlError(const char* funcName);
+extern GLuint createShader(GLenum shaderType, const char* src);
+extern GLuint createProgram(const char* vtxSrc, const char* fragSrc);
+
+// ----------------------------------------------------------------------------
+// Interface to the ES2 and ES3 renderers, used by JNI code.
+
+class Renderer {
+public:
+ virtual ~Renderer();
+ void resize(int w, int h);
+ void render();
+
+protected:
+ Renderer();
+
+ // return a pointer to a buffer of MAX_INSTANCES * sizeof(vec2).
+ // the buffer is filled with per-instance offsets, then unmapped.
+ virtual float* mapOffsetBuf() = 0;
+ virtual void unmapOffsetBuf() = 0;
+ // return a pointer to a buffer of MAX_INSTANCES * sizeof(vec4).
+ // the buffer is filled with per-instance scale and rotation transforms.
+ virtual float* mapTransformBuf() = 0;
+ virtual void unmapTransformBuf() = 0;
+
+ virtual void draw(unsigned int numInstances) = 0;
+
+private:
+ void calcSceneParams(unsigned int w, unsigned int h, float* offsets);
+ void step();
+
+ unsigned int mNumInstances;
+ float mScale[2];
+ float mAngularVelocity[MAX_INSTANCES];
+ uint64_t mLastFrameNs;
+ float mAngles[MAX_INSTANCES];
+};
+
+extern Renderer* createES2Renderer();
+extern Renderer* createES3Renderer();
+
+#endif // GLES3JNI_H
diff --git a/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNIActivity.java b/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNIActivity.java
new file mode 100644
index 0000000..5b9bcba
--- /dev/null
+++ b/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNIActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gles3;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+public class GLES3JNIActivity extends Activity {
+
+ GLES3JNIView mView;
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mView = new GLES3JNIView(getApplication());
+ setContentView(mView);
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+}
diff --git a/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNILib.java b/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNILib.java
new file mode 100644
index 0000000..bfda687
--- /dev/null
+++ b/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNILib.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gles3;
+
+// Wrapper for native library
+
+public class GLES3JNILib {
+
+ static {
+ System.loadLibrary("gles3");
+ }
+
+ public static native void init();
+ public static native void resize(int width, int height);
+ public static native void step();
+}
diff --git a/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNIView.java b/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNIView.java
new file mode 100644
index 0000000..6fc902b
--- /dev/null
+++ b/build-app/GL3/app/src/main/java/com/android/gles3/GLES3JNIView.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gles3;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+class GLES3JNIView extends GLSurfaceView {
+ private static final String TAG = "GLES3JNI";
+ private static final boolean DEBUG = true;
+
+ public GLES3JNIView(Context context) {
+ super(context);
+ // Pick an EGLConfig with RGB8 color, 16-bit depth, no stencil,
+ // supporting OpenGL ES 2.0 or later backwards-compatible versions.
+ setEGLConfigChooser(8, 8, 8, 0, 16, 0);
+ setEGLContextClientVersion(3);
+ setRenderer(new Renderer());
+ }
+
+ private static class Renderer implements GLSurfaceView.Renderer {
+ public void onDrawFrame(GL10 gl) {
+ GLES3JNILib.step();
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ GLES3JNILib.resize(width, height);
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ GLES3JNILib.init();
+ }
+ }
+}
diff --git a/build-app/GL3/app/src/main/res/mipmap-hdpi/ic_launcher.png b/build-app/GL3/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/build-app/GL3/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/build-app/GL3/app/src/main/res/mipmap-mdpi/ic_launcher.png b/build-app/GL3/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/build-app/GL3/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/build-app/GL3/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/build-app/GL3/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/build-app/GL3/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/build-app/GL3/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/build-app/GL3/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/build-app/GL3/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/build-app/GL3/app/src/main/res/values/strings.xml b/build-app/GL3/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..d4c84e6
--- /dev/null
+++ b/build-app/GL3/app/src/main/res/values/strings.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ GLES3
+
+
diff --git a/build-app/GL3/build.gradle b/build-app/GL3/build.gradle
new file mode 100644
index 0000000..500155d
--- /dev/null
+++ b/build-app/GL3/build.gradle
@@ -0,0 +1,17 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:8.1.0'
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
diff --git a/build-app/GL3/gles3.jpg b/build-app/GL3/gles3.jpg
new file mode 100644
index 0000000..3850287
Binary files /dev/null and b/build-app/GL3/gles3.jpg differ
diff --git a/build-app/GL3/gradlew b/build-app/GL3/gradlew
new file mode 100644
index 0000000..2fe81a7
--- /dev/null
+++ b/build-app/GL3/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/build-app/GL3/gradlew.bat b/build-app/GL3/gradlew.bat
new file mode 100644
index 0000000..24467a1
--- /dev/null
+++ b/build-app/GL3/gradlew.bat
@@ -0,0 +1,100 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/build-app/GL3/local.properties b/build-app/GL3/local.properties
new file mode 100644
index 0000000..e40ceaf
--- /dev/null
+++ b/build-app/GL3/local.properties
@@ -0,0 +1,18 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+
+# location of the SDK. This is only used by Ant
+# For customization when using a Version Control System, please read the
+# header note
+
+# android-sdk location
+sdk.dir=/data/data/com.termux/files/home/opt/android-sdk
+
+# android-ndk location
+ndk.dir=/data/data/com.termux/files/home/opt/android-ndk-r26b
+
+# cmake location
+cmake.dir=/data/data/com.termux/files/home/opt/android-sdk/cmake
diff --git a/build-app/GL3/settings.gradle b/build-app/GL3/settings.gradle
new file mode 100644
index 0000000..e7b4def
--- /dev/null
+++ b/build-app/GL3/settings.gradle
@@ -0,0 +1 @@
+include ':app'
diff --git a/build-app/README.md b/build-app/README.md
new file mode 100644
index 0000000..584d7cc
--- /dev/null
+++ b/build-app/README.md
@@ -0,0 +1,118 @@
+### How to use termux-ndk to build android app
+
+Download the `android-ndk` and `android-sdk` from [release](https://github.com/Lzhiyong/termux-ndk/releases)
+```bash
+# install openjdk-17
+pkg install openjdk-17
+
+# install gradle
+pkg install gradle
+
+```
+
+Add a `local.properties` file to the root of the project as below
+```local.properties
+# modify the local.properties file
+# although ndk.dir has been deprecated, but it still works
+sdk.dir=/path/to/android-sdk
+ndk.dir=/path/to/android-ndk
+cmake.dir=/path/to/cmake
+# for example:
+sdk.dir=/data/data/com.termux/files/home/opt/android-sdk
+ndk.dir=/data/data/com.termux/files/home/opt/android-ndk-r26b
+cmake.dir=/data/data/com.termux/files/home/opt/android-sdk/cmake
+```
+Modify the `project/build.gradle` file
+```build.gradle
+// set the Android gradle plugin version
+dependencies {
+ classpath 'com.android.tools.build:gradle:8.1.0'
+}
+```
+Modify the project `app/build.gradle` file
+```build.gradle
+
+android {
+ // set the build tools version
+ buildToolsVersion "34.0.0"
+
+ externalNativeBuild {
+ cmake {
+ path "src/main/cpp/CMakeLists.txt"
+ // If your cmake version >= 3.21, you must specify a version
+ // 3.18.5+ or 3.25.1 and so on
+ version "3.18.5+"
+ }
+ }
+}
+```
+
+Execute the `gradle build` command to start building the android app, when building for the first time,
+the exec format error will occur, because the aapt2 is x86_64 architecture not aarch64, so we need to replace it
+
+```bash
+# replace the aapt2 with your own
+# note: it's /path/to not /path/to/aapt2
+find ~/.gradle -name 'aapt2-*-linux.jar' -type f | xargs -I{} jar -uvf {} -C /path/to aapt2
+```
+If an error occurs during the build app, this may be a network problem, please execute the `gradle build` again or execute the `gradle build --info` for more information.
+
+****
+
+### Building termux-app with termux
+```gradle.properties
+# clone the termux-app
+git clone --depth=1 https://github.com/termux/termux-app
+
+# add a local.properties file
+sdk.dir=/path/to/android-sdk
+ndk.dir=/path/to/android-ndk
+cmake.dir=/path/to/cmake
+
+# modify gradle.properties file
+minSdkVersion=24
+targetSdkVersion=28
+ndkVersion=26.1.10909125
+compileSdkVersion=33
+buildToolsVersion=34.0.0
+
+# modify the build.gradle file
+# termux-app/app/build.gradle
+# terminal-emulator/build.gradle
+# terminal-view/build.gradle
+# termux-shared/build.gradle
+# set the buildToolsVersion
+android {
+ ...
+ compileSdkVersion project.properties.compileSdkVersion.toInteger()
+ // set the build tools version
+ buildToolsVersion project.properties.buildToolsVersion.toString()
+ ...
+}
+
+# start building
+gradle assembleDebug
+
+```
+
+
+
+
+****
+### Building example
+```bash
+# GL2
+cd GL2 && gradle installDebug
+
+# GL3
+cd GL3 && gradle installDebug
+
+```
+
+
+
+
+****
+
+### Known issues
+Using proot or chroot linux is not recommended, this may have some problems, the building speed is much slower than the native Termux.
diff --git a/build-app/screenshot/build_termux_app1.jpg b/build-app/screenshot/build_termux_app1.jpg
new file mode 100644
index 0000000..b7d0ce7
Binary files /dev/null and b/build-app/screenshot/build_termux_app1.jpg differ
diff --git a/build-app/screenshot/build_termux_app2.jpg b/build-app/screenshot/build_termux_app2.jpg
new file mode 100644
index 0000000..b6eccb3
Binary files /dev/null and b/build-app/screenshot/build_termux_app2.jpg differ
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 0000000..e2e7327
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1 @@
+/out
diff --git a/docs/BuildSystemMaintainers.md b/docs/BuildSystemMaintainers.md
new file mode 100644
index 0000000..4513236
--- /dev/null
+++ b/docs/BuildSystemMaintainers.md
@@ -0,0 +1,597 @@
+# Build System Maintainers Guide
+
+The latest version of this document is available at
+https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md.
+Ensure that you are using the version that corresponds to your NDK. Replace
+`master` in the URL with the appropriate NDK release branch. For example, the NDK
+r19 version of this document is located at
+https://android.googlesource.com/platform/ndk/+/ndk-release-r19/docs/BuildSystemMaintainers.md.
+
+The purpose of this guide is to instruct third-party build system maintainers in
+adding NDK support to their build systems. This guide will not be useful to most
+NDK users. NDK users should start with [Building Your Project].
+
+Note: This guide is written assuming Linux is the host OS. Mac should be no
+different, and the only difference on Windows is that file extensions for
+executables and scripts will differ.
+
+[Building Your Project]: https://developer.android.com/ndk/guides/build
+
+[TOC]
+
+## Introduction
+
+The NDK uses the [LLVM] family of tools for building C/C++ code. These include
+[Clang] for compilation, [LLD] for linking, and other [LLVM tools] for other
+tasks. Historically [Binutils] was used and remains available during the
+transition but is deprecated and will soon be removed from the NDK.
+
+[Binutils]: https://www.gnu.org/software/binutils
+[Clang]: https://clang.llvm.org/
+[LLD]: https://lld.llvm.org/
+[LLVM tools]: https://llvm.org/docs/CommandGuide/
+[LLVM]: https://llvm.org/
+
+### Architectures
+[Architectures]: #architectures
+
+Note: In general an architecture may have multiple ABIs. An ABI (application
+binary interface) is different from an architecture in that it also specifies a
+calling convention, size and alignment of types, and other implementation
+details. For Android, each architecture supports only one ABI.
+
+Android supports multiple architectures: ARM32, ARM64, x86, and x86_64. NDK
+applications must build libraries for every architecture they support. 64-bit
+devices usually also support the 32-bit variant of their architecture, but this
+may not always be the case. While in general this means that an app with only
+32-bit libraries can run on 64-bit capable devices, the 64-bit ABI will have
+improved performance.
+
+This document will make use of ``, ``, and `` in describing
+paths and arguments. The values of these variables for each architecture are as
+follows except where otherwise noted:
+
+| Name | arch | ABI | triple |
+| ------------ | ------- | ----------- | --------------------- |
+| 32-bit ARMv7 | arm | armeabi-v7a | arm-linux-androideabi |
+| 64-bit ARMv8 | aarch64 | aarch64-v8a | aarch64-linux-android |
+| 32-bit Intel | x86 | x86 | i686-linux-android |
+| 64-bit Intel | x86_64 | x86_64 | x86_64-linux-android |
+
+Note: Strictly speaking ARMv7 with [NEON] is a different ABI from ARMv7 without
+NEON, but it is not a *system* ABI. Both NEON and non-NEON ARMv7 code uses the
+ARMv7 system and toolchains.
+
+To programatically determine the list of supported ABIs, their bitness, as well
+as their deprecation status and whether or not it is recommended to build them
+by default, use `/meta/abis.json`.
+
+### Thumb
+
+32-bit ARM can be built using either the [Thumb] or ARM instruction sets. Thumb
+code is smaller but may perform worse than ARM. However, smaller code makes more
+effective use of a processor's instruction cache, so benchmarking is necessary
+to determine which is more effective for a given application. ndk-build and the
+NDK's CMake toolchain file generate Thumb code by default.
+
+The ARM or Thumb instruction sets are selected by passing `-marm` or `-mthumb`
+to Clang respectively. By default, Clang will generate ARM code as opposed to
+Thumb for the `armv7a-linux-androideabi` target.
+
+Note: For ARMv7, Thumb-2 is used. Android no longer supports ARMv5, but if your
+build system mistakenly targets ARMv5 the less efficient Thumb-1 will be used.
+
+[Thumb]: https://en.wikipedia.org/wiki/ARM_architecture#Thumb-2
+
+### NEON
+
+Most ARM Android devices support [NEON]. This is supported by all 64-bit ARM
+devices and nearly all 32-bit ARM devices running at least Android Marshmallow
+(API 23). The [Android CDD] has required NEON support since that version, but it
+is possible that extant devices that were upgraded to Marshmallow do not include
+NEON support.
+
+NEON can significantly improve application performance.
+
+Clang automatically enables NEON for all API levels. ARM devices without NEON
+are uncommon. To support non-NEON devices, pass `-mfpu=vfpv3-d16` when
+compiling. Alternatively, use the Play Console to [exclude CPUs] without NEON
+to disallow your app from being installed on those devices.
+
+[Android CDD]: https://source.android.com/compatibility/cdd
+[NEON]: https://developer.arm.com/technologies/neon
+[exclude CPUs]: https://support.google.com/googleplay/android-developer/answer/7353455?hl=en
+
+### OS Versions
+[OS Versions]: #os-versions
+
+As users are distributed over a wide variety of Android OS versions (see the
+[Distribution dashboard]), applications have a minimum and maximum supported
+version, as well as a targeted version. These are `minSdkVersion`,
+`maxSdkVersion`, and `targetSdkVersion` respectively. See the [uses-sdk]
+documentation for more information.
+
+For NDK code, the only relevant value is the minimum supported version. Any time
+this doc refers to an API level, OS version, or target version, it is referring
+to the application's `minSdkVersion`.
+
+The API level targeted by an NDK application determines which APIs will be
+exposed for use by the application. APIs that are not present in the targeted
+API level cannot be linked directly, but may be accessed via `dlsym`. An NDK
+application running on a device with an API level lower than the target will
+often not load at all. If it does load, it may not behave as expected. This is
+not a supported configuration.
+
+The major/minor version number given to an Android OS has no meaning when it
+comes to determining its API level. See the table in the [Build numbers]
+document to map Android code names and version numbers to API levels.
+
+Note: Not every API level includes new NDK APIs. If there were no new NDK APIs
+for the given API level, there is no library directory for that API level. In
+that case, the build system should select the closest available API that is
+below the target API level. For example, applications with a `minSdkVersion` of
+20 should use API 19 for their NDK target.
+
+To programatically determine the list of supported API levels as well as aliases
+that are accepted by ndk-build and CMake, see `/meta/platforms.json`.
+
+Note: In some contexts the API level may be referred to as a platform. In this
+document an API level is always an integer, and a platform takes the form of
+`android-`. The latter format is not specifically used anywhere in
+the NDK toolchain, but is used to specify target API levels for ndk-build and
+CMake.
+
+Note: As a new version of the Android OS approaches release, previews and betas
+of that OS will be released and an NDK will be released that can make use of the
+new APIs. Targeting a preview API level is no different than targeting a
+released API level, with the exception that applications built targeting preview
+releases should not be shipped to production. Consult
+`/meta/platforms.json` to determine the API level for a preview release.
+
+[Build numbers]: https://source.android.com/setup/start/build-numbers
+[Distribution dashboard]: https://developer.android.com/about/dashboards/
+[uses-sdk]: https://developer.android.com/guide/topics/manifest/uses-sdk-element
+
+## Clang
+
+Clang is installed to `/toolchains/llvm/prebuilt//bin/clang`.
+The C++ compiler is installed as `clang++` in the same directory. `clang++` will
+make C++ headers available when compiling and will automatically link the C++
+runtime libraries when linking.
+
+`clang` should be used when compiling C source files, and `clang++` should be
+used when compiling C++ source files. When linking, `clang` should be used if
+the binary being linked contains no C++ code (i.e. none of the object files
+being linked were generated from C++ files) and `clang++` should be used
+otherwise. Using `clang++` ensures that the C++ standard library is linked.
+
+### Target Selection
+
+[Cross-compilation] targets can be selected in one of two ways.
+
+First, the `--target` flag can be used (see the [Clang User Manual] for more
+details on Clang's supported arguments). The value passed is a Clang target
+triple suffixed with an Android API level. For example, to target API 26 for
+32-bit ARM, use `--target armv7a-linux-androideabi26`.
+
+Note: "armv7a" should be used rather than simply "arm" when specifying targets
+for Clang to generate ARMv7 code rather than the slower ARMv5 code. Specifying
+ARMv5 and thumb code generation will result in Thumb-1 being generated rather
+than Thumb-2, which is less efficient.
+
+Second, a target-specific Clang can be used. In addition to the `clang` and
+`clang++` binaries, there are also `-clang` and
+`-clang++` scripts. For example, to target API 26 32-bit ARM,
+invoke `armv7a-linux-androideabi26-clang` or
+`armv7a-linux-androideabi26-clang++` instead of `clang` or `clang++`.
+
+Note: Target specific Clangs are currently implemented as shell scripts. Linux
+and Mac NDKs have Bash scripts, Windows includes Bash scripts to support Cygwin
+and WSL but also batch scripts (with `.cmd` extensions) for Windows command
+line support. For large numbers of relatively small source files, the additional
+overhead caused by these scripts may be noticably slower than using `--target`,
+especially on Windows where `CreateProcess` is slower than `fork`.
+
+For more information on Android targets, see the [Architectures] and [OS
+Versions] sections.
+
+[Clang User Manual]: https://clang.llvm.org/docs/UsersManual.html
+[Cross-compilation]: https://en.wikipedia.org/wiki/Cross_compiler
+
+## Linkers
+
+LLD is the default linker.
+
+Gold is the fallback linker for most architectures, but BFD is used for AArch64
+as Gold previously emitted broken debug information for that architecture (see
+[Issue 70838247] for more details).
+
+The linker used by Clang can be selected with the `-fuse-ld=` argument,
+passed during linking. For example, to use gold instead of LLD, pass
+`-fuse-ld=gold` when linking. No argument is required to use LLD.
+
+The default linkers are installed to
+`/toolchains/llvm/prebuilt//bin/-ld` and
+`/toolchains/llvm/prebuilt///bin/ld`. BFD and gold are
+installed as `ld.bfd` or `ld.gold` in the same locations. The triple-prefixed
+executables in the common bin directory should be preferred to the
+triple-specific bin directory because the triple-specific directory will be
+removed when binutils is removed from the NDK.
+
+Note: It is usually not necessary to invoke the linkers directly since Clang
+will do so automatically. Clang will also automatically link CRT objects and
+default libraries and set up other target-specific options, so it is generally
+better to use Clang for linking.
+
+Warning: Using LLD with GNU `strip` or `objcopy` breaks RelRO. LLVM `strip` and
+`objcopy` must be used with LLD. See [Issue 843] and the [Binutils] section of
+this document for more information.
+
+[Issue 70838247]: https://issuetracker.google.com/70838247
+[Issue 843]: https://github.com/android-ndk/ndk/issues/843
+
+## Binutils
+
+LLVM's binutils tools are installed to the NDK at
+`/toolchains/llvm/prebuilt//bin/llvm-`. These include but
+are not limited to:
+
+* llvm-ar
+* llvm-objcopy
+* llvm-objdump
+* llvm-readelf
+* llvm-strip
+
+Note that `llvm-as` is **not** an equivalent of GNU `as`, but rather a tool for
+assembling LLVM IR. If you are currently using `as` directly, you will need to
+migrate to using `clang` as a driver for building assembly.
+
+GNU Binutils remains available for now but is deprecated and will be removed in
+an upcoming release of the NDK. Those tools are installed to
+`/toolchains/llvm/prebuilt//bin/-` and
+`/toolchains/llvm/prebuilt///bin/`.
+
+Note that binutils `as` is used by Clang if the `-fno-integrated-as` argument is
+used.
+
+## Sysroot
+
+The Android sysroot is installed to
+`/toolchains/llvm/prebuilt//sysroot` and contains the headers,
+libraries, and CRT object files for each Android target.
+
+Headers can be found in the `usr/include` directory of the sysroot. Target
+specific include files are installed to `usr/include/`. When using
+Clang, it is not necessary to include these directories explicitly; Clang will
+automatically select the sysroot. If using a compiler other than Clang, ensure
+that the target-specific include directory takes precedence over the
+target-generic directory.
+
+Libraries are found in the `usr/lib/` directory of the sysroot.
+Version-specific libraries are installed to `usr/lib//`. As
+with the header files, when using Clang it is not necessary to include these
+directories explicitly; the sysroot will be automatically selected. If using a
+compiler other than Clang, ensure that the version-specific library directory
+takes precedence over the version-generic directory.
+
+## Libraries
+
+The NDK contains three types of libraries. Static libraries have a .a file
+extension and are linked directly into app binaries. Shared libraries have a .so
+file extension and must be included in the app's APK if used. System stub
+libraries are a special type of shared library that should not be included in
+the APK. The system stub libraries define the interface of a library that is
+provided by the Android OS but contain no implementation. They can be identified
+by their .so file extension and their presence in `/meta/system_libs.json`.
+The entries in this file are a key/value pair that maps library names to the
+first API level the library is introduced.
+
+[Issue 801]: https://github.com/android-ndk/ndk/issues/801
+
+## STL
+
+### libc++
+
+The STL provided by the NDK is [libc++]. Its headers are installed to
+`/sysroot/usr/include/c++/v1`. This STL is used by default. This STL comes
+in both a static and shared variant. The shared variant is used by default. To
+use the static variant, pass `-static-libstdc++` when linking. If using the
+shared variant, libc++_shared.so must be included in the APK. This library is
+installed to `/sysroot/usr/lib/`.
+
+Warning: There are a number of things to consider when selecting between the
+shared and static STLs. See the [Important Considerations] section of the C++
+Support document for more details.
+
+There are version-specific libc++.so and libc++.a libraries installed to
+`/sysroot/usr/lib//`. These are not true libraries but
+[implicit linker scripts]. They inform the linker how to properly link the STL
+for the given version. Older OS versions may require that a compatibility
+library (libandroid_support) be linked with libc++ to provide APIs not available
+in those versions. These scripts also handle the inclusion of any libc++
+dependencies if necessary. Linker scripts should not be included in the APK.
+
+Build systems should prefer to let Clang link the STL. If not using Clang, the
+version scripts should be used. Linking libc++ and its dependencies manually
+should only be used as a last resort.
+
+Note: Linking libc++ and its dependencies explicitly may be necessary to defend
+against exception unwinding bugs caused by improperly built dependencies on
+ARM32 (see [Issue 379]). If not dependent on stack unwinding (the usual reason
+being that the application does not make use of C++ exceptions) or if no
+dependencies were improperly built, this is not necessary. If needed, link the
+libraries as listed in the linker script and be sure to follow the instructions
+in [Unwinding].
+
+[Important Considerations]: https://developer.android.com/ndk/guides/cpp-support#important_considerations
+[Issue 379]: https://github.com/android-ndk/ndk/issues/379
+[implicit linker scripts]: https://sourceware.org/binutils/docs/ld/Scripts.html
+[libc++]: https://libcxx.llvm.org/
+
+### System STL
+
+The legacy "system STL" is also included, but it will be removed in a future NDK
+release. It is not in fact an STL; it contains only the barest C++ library
+support: the C++ versions of the C library headers and basic C++ runtime support
+like `new` and `delete`. Its headers are installed to
+`/toolchains/llvm/prebuilt//include/c++/4.9.x` and its library is
+the libstdc++.so system stub library. To use this STL, use the
+`-stdlib=libstdc++` flag.
+
+TODO: Shouldn't it be installed to sysroot like libc++?
+
+Note: The system STL will likely be removed in a future NDK release.
+
+### No STL
+
+To avoid using the STL at all, pass `-nostdinc++` when compiling and
+`-nostdlib++` when linking. This is not necessary when using `clang`, only when
+using `clang++`.
+
+## Sanitizers
+
+The NDK supports [Address Sanitizer] (ASan). This tool is similar to Valgrind in
+that it diagnoses memory bugs in a running application, but ASan is much faster
+than Valgrind (roughly 50% performance compared to an unsanitized application).
+
+To use ASan, pass `-fsanitize=address` when both compiling and linking. The
+sanitizer runtime libraries are installed to
+`/toolchains/llvm/prebuilt//lib64/clang//lib/linux`.
+The library is named `libclang_rt.asan--android.so`. This library must be
+included in the APK. A [wrap.sh] file must also be included in the APK. A
+premade wrap.sh file for ASan is installed to `/wrap.sh`.
+
+Note: wrap.sh is only available for [debuggable] APKs running on Android Oreo
+(API 26) or higher. ASan can still be used devices prior to Oreo but at least
+Lollipop (API 21) if the device has been rooted. Direct users to the
+[AddressSanitizerOnAndroid] document for instructions on using this method.
+
+[Address Sanitizer]: https://clang.llvm.org/docs/AddressSanitizer.html
+[AddressSanitizerOnAndroid]: https://github.com/google/sanitizers/wiki/AddressSanitizerOnAndroid#run-time-flags
+[debuggable]: https://developer.android.com/guide/topics/manifest/application-element#debug
+[wrap.sh]: https://developer.android.com/ndk/guides/wrap-script
+
+## Additional Required Arguments
+
+Note: It is a bug that any of these need to be specified by the build system.
+All flags discussed in this section should be automatically selected by Clang,
+but they are not yet. Check back in a future NDK release to see if any can be
+removed from your build system.
+
+For x86 targets prior to Android Nougat (API 24), `-mstackrealign` is needed to
+properly align stacks for global constructors. See [Issue 635].
+
+Android requires [Position-independent executables] beginning with API 21. Clang
+builds PIE executables by default. If invoking the linker directly or not using
+Clang, use `-pie` when linking.
+
+Clang does not properly set the ARMv7 architecture for the non-integrated
+assembler. If using `-fno-integrated-as`, you must explicitly pass
+`-march=armv7-a` when compiling for 32-bit ARM. Note that by default Clang will
+use the integrated assembler, and this flag is not needed in that case. See
+[Issue 906].
+
+Android Studio's LLDB debugger uses a binary's build ID to locate debug
+information. To ensure that LLDB works with a binary, pass an option like
+`-Wl,--build-id=sha1` to Clang when linking. Other `--build-id=` modes are OK,
+but avoid a plain `--build-id` argument when using LLD, because Android Studio's
+version of LLDB doesn't recognize LLD's default 8-byte build ID. See [Issue
+885].
+
+The unwinder used for crash handling on Android devices prior to API 29 cannot
+correctly unwind binaries built with `-Wl,--rosegment`. This flag is enabled by
+default when using LLD, so if using LLD and targeting devices older than API 29
+you must pass `-Wl,--no-rosegment` when linking for correct stack traces in
+logcat. See [Issue 1196].
+
+[Issue 635]: https://github.com/android-ndk/ndk/issues/635
+[Issue 885]: https://github.com/android-ndk/ndk/issues/885
+[Issue 906]: https://github.com/android-ndk/ndk/issues/906
+[Issue 1196]: https://github.com/android/ndk/issues/1196
+[Position-independent executables]: https://en.wikipedia.org/wiki/Position-independent_code#Position-independent_executables
+
+## Useful Arguments
+
+### Dependency Management
+
+It is recommended that `-Wl,--exclude-libs,` be used for each
+static library linked. This causes the linker to give symbols imported from a
+static library hidden [visibility]. This prevents a binary from unintentionally
+re-exporting an API other than its own. If the intent is to re-export all the
+symbols in a static library, `-Wl,--whole-archive
+-Wl,--no-whole-archive` should be used to ensure that the whole archive is
+preserved. By default, only symbols in used sections will be included in the
+linked binary.
+
+If this behavior is not desired for your build system, ensure that these flags
+are at least used for `libgcc.a` (`libgcc_real.a` on Arm32, where `libgcc.a` is
+a linker script, as `--exclude-libs` does not have any effect on the contents of
+linker scripts) and `libunwind.a` (libunwind is only used for ARM32). This is
+necessary to avoid unwinding bugs on Arm32. See [Unwinding] for more
+information.
+
+[visibility]: https://gcc.gnu.org/wiki/Visibility
+
+### Controlling Binary Size
+
+To minimize the size of an APK, it may be desirable to use the `-Oz`
+optimization mode. This will generate somewhat slower code than `-O2` or `-O3`,
+but it will be smaller.
+
+Note: `-Os` behavior is not the same with Clang as it is with GCC. Clang's `-Oz`
+behaves similarly to GCC's `-Os`. `-Os` with Clang is a middle ground between
+size and speed optimizations.
+
+To aid the linker in removing as much unused code as possible, the compiler
+flags `-ffunction-sections` and `-fdata-sections` may be used. These flags
+should only be used in conjunction with the `-Wl,--gc-sections` linker flag.
+Failing to use `-Wl,--gc-sections` will cause the former flags to *increase*
+output size. The linker is only able to discard unused sections, so it can only
+discard at per-function or per-variable granularity if each is in its own
+section.
+
+While `-Wl,--gc-sections` should always be used, whether or not to enable
+`-ffunction-sections` and `-fdata-sections` depends on how the object file being
+compiled is expected to be used. If it will be used in a shared library then all
+of its [public symbols] will be preserved and the additional overhead of placing
+each item in its own section may make the shared library *larger* rather than
+smaller. If it will be used only in a static library or an executable then it
+will depend on how much of the resulting object file is expected to be unused.
+
+[public symbols]: #dependency-management
+
+### Helpful Warnings
+
+It is recommended that build systems promote the following warnings to errors.
+These warnings indicate either a bug or undefined behavior, the latter of which
+Clang will usually turn into a bug.
+
+ * `-Werror=return-type`: A non-void function is missing a return statement.
+ Clang may "optimize" this function to fall through into the next one.
+ * `-Werror=int-to-pointer-cast` and `-Werror=pointer-to-int-cast`: These
+ indicate bugs that will affect the 64-bit version of the application.
+ * `-Werror=implicit-function-declaration`: Undeclared functions may be inferred
+ to have a return type of `int` in C. For functions that return a pointer, the
+ return type will be silently truncated to a 32-bit `int`, resulting in bugs
+ that will affect the 64-bit version of the application.
+
+For more information on Clang's supported arguments, see the [Clang User
+Manual].
+
+### Hardening
+
+#### Stack protectors
+
+It is recommented to build all code with `-fstack-protector-strong`. This causes
+the compiler to emit stack guards to protect against security vulnerabilities
+caused by buffer overruns.
+
+Note: ndk-build and the NDK's CMake toolchain file enable this option by
+default.
+
+#### Fortify
+
+FORTIFY is a set of extensions to the C standard library that tries to catch the
+incorrect use of standard functions, such as `memset`, `sprintf`, and `open`.
+Where possible, runtime bugs will be diagnosed as errors at compile-time. If not
+provable at compile-time, a run-time check is used. Note that the specific set
+of APIs checked depends on the `minSdkVersion` used, since run-time support is
+required. See [FORTIFY in Android] for more details.
+
+To enable this feature in your build define `_FORTIFY_SOURCE=2` when compiling.
+
+Note: ndk-build and the NDK's CMake toolchain file enable this option by
+default.
+
+[FORTIFY in Android]: https://android-developers.googleblog.com/2017/04/fortify-in-android.html
+
+## Common Issues
+
+### Unwinding
+[Unwinding]: #unwinding
+
+For 32-bit ARM the NDK makes use of two unwinders: libgcc and LLVM's libunwind.
+libunwind is needed to provide C++ exception handling support. libgcc is needed
+to provide compiler runtime support and as such its unwinder is also seen by the
+linker.
+
+These two unwinders are not ABI compatible but do use the same names, so caution
+is required to avoid ODR bugs. For 32-bit ARM, the libgcc.a in the NDK is a
+linker script that ensures that libunwind is linked before libgcc, causing the
+linker to prefer symbols from libunwind to those from libgcc.
+
+As these are static libraries, the symbols will be included in the linked
+binary. By default they will be linked with public visibility. If used in a
+build system that does not strictly adhere to only linking shared libraries
+after all objects and static libraries, the binary being linked may instead load
+these symbols from a shared library. If this library was built with the wrong
+unwinder, it is possible for one unwinder to call into the other. As they are
+not compatible, this will likely result in either a crash or a failed unwind. To
+avoid this problem, libraries should always be built with
+`-Wl,--exclude-libs,libgcc.a`, `-Wl,--exclude-libs,libgcc_real.a` and
+`-Wl,--exclude-libs,libunwind.a` (the latter is only necessary for 32-bit Arm)
+to ensure that unwind symbols are not re-exported from shared libraries. Note
+that `libgcc_real.a` is needed because on some architectures (currently only
+32-bit Arm) `libgcc.a` is a linker script and `--exclude-libs` does not extend
+to the contents of linker scripts.
+
+Even with the above precautions, it is still possible for an improperly built
+external dependency to provide an incorrect unwind implementation as described
+in the above paragraph. The only way to guarantee protection against this for
+libraries built in your build system is to ensure that objects are linked in the
+following order:
+
+ 1. crtbegin
+ 2. object files
+ 3. static libraries
+ 4. libgcc
+ 5. shared libraries
+ 6. crtend
+
+Unless using `-nostdlib` when linking, crtend and crtbegin will be linked
+automatically by Clang. Linking libraries in the order above will require
+`-nostdlib++` when using libc++.
+
+## Windows Specific Issues
+
+### Command Line Length Limits
+
+Command line length limits on Windows are short enough that they can pose
+problems when building large projects. Commands executed via cmd.exe are limited
+to [8,191 characters] and commands executed with `CreateProcess` are limited to
+[32,768 characters].
+
+To work around these issues, Clang, the linkers, and the archiver all accept a
+response file that specifies the input files in place of specifying each input
+explicitly on the command line. Response files are identified on the command
+line with a "@" prefix and are formatted as space separated arguments. For
+example:
+
+ $ ar crsD liba.a @inputs.rsp
+
+If the contents of `inputs.rsp` are `a.o b.o c.o` then `ar` will insert `a.o`,
+`b.o`, and `c.o` into `liba.a`.
+
+[8,191 characters]: https://support.microsoft.com/en-us/help/830473/command-prompt-cmd-exe-command-line-string-limitation
+[32,768 characters]: https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessa
+
+### Path Length Limits
+
+Windows paths are limited to 260 characters, including the drive letter, colon,
+backslash, and terminating null. See Microsoft's documentation on [path length
+limits] for possible solutions.
+
+[path length limits]: https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file#maximum-path-length-limitation
+
+### Performance Differences
+
+Our experience shows that builds on Windows are generally slower than they are
+on Linux. The cost of `CreateProcess` in comparison to `fork` accounts for much
+of the difference, so it is best to minimize process creation in your build
+system.
+
+File system performance can also make a large difference. This also appears to
+be the reason that Mac, while it has better build performance than Windows,
+still underperforms Linux.
+
+Windows and Mac users will see optimum build performance in a Linux VM.
diff --git a/docs/Building.md b/docs/Building.md
new file mode 100644
index 0000000..7f1977f
--- /dev/null
+++ b/docs/Building.md
@@ -0,0 +1,76 @@
+# Building the NDK
+
+The latest version of this document is available at
+https://android.googlesource.com/platform/ndk/+/master/docs/Building.md.
+
+Both Linux and Windows NDKs are built on Linux machines. Windows host binaries
+are cross-compiled with MinGW.
+
+Building the NDK for Mac OS X requires at least 10.9.
+
+## Prerequisites
+
+* [AOSP NDK Repository](http://source.android.com/source/downloading.html)
+ * Check out the branch `master-ndk`
+
+ ```bash
+ repo init -u https://android.googlesource.com/platform/manifest \
+ -b master-ndk
+
+ # Googlers, use
+ repo init -u \
+ persistent-https://android.git.corp.google.com/platform/manifest \
+ -b master-ndk
+ ```
+
+If you wish to rebuild a given release of the NDK, the release branches can also
+be checked out. They're named `ndk-release-r${RELEASE}` for newer releases, but
+`ndk-r{RELEASE}-release` for older releases. For example, to check out the r19
+release branch, use the `-b ndk-release-r19` flag instad of `-b master-ndk`.
+
+Linux dependencies are listed in the [Dockerfile]. You can use docker to build
+the NDK:
+
+```bash
+docker build -t ndk-dev infra/docker
+docker run -it -u $UID -v `realpath ..`:/src -w /src/ndk ndk-dev ./checkbuild.py
+```
+
+Building on Mac OS X has similar dependencies as Linux, but also requires Xcode.
+
+Running tests requires that `adb` is in your `PATH`. This is provided as part of
+the [Android SDK].
+
+[Dockerfile]: ../infra/docker/Dockerfile
+[Android SDK]: https://developer.android.com/studio/index.html#downloads
+
+## Building the NDK
+
+### For Linux or Darwin:
+
+```bash
+$ python checkbuild.py
+```
+
+### For Windows, from Linux:
+
+```bash
+$ python checkbuild.py --system windows64 # Or "windows", for a 32-bit host.
+```
+
+`checkbuild.py` will also build all of the NDK tests. This takes about as long
+as building the NDK itself, so pass `--no-build-tests` to skip building the
+tests. They can be built later with `python run_tests.py --rebuild`.
+
+Note: The NDK's build and test scripts are implemented in Python 3 (currently
+3.6). `checkbuild.py` will bootstrap by building Python 3.6 from source before
+running, but `run_tests.py` does not do this yet. `run_tests.py` also can be run
+outside of a complete development environment (as it is when it is run on
+Windows), so a Python 3.6 virtualenv is recommended.
+
+## Packaging
+
+By default, `checkbuild.py` will also package the NDK. To skip the packaging
+step, use the `--no-package` flag. To avoid packaging an incomplete NDK,
+packaging will not be run if `--module` was passed unless `--force-package` was
+also provided.
diff --git a/docs/ClangMigration.md b/docs/ClangMigration.md
new file mode 100644
index 0000000..8f4be4a
--- /dev/null
+++ b/docs/ClangMigration.md
@@ -0,0 +1,100 @@
+# Clang Migration Notes
+
+The Android OS switched to clang several years ago. Future versions of
+the NDK will remove GCC, so the sooner you start testing your project
+with clang the better!
+
+## How to switch to clang
+
+For `ndk-build`, remove lines setting `NDK_TOOLCHAIN` or
+`NDK_TOOLCHAIN_VERSION`.
+
+For cmake, remove lines setting `ANDROID_TOOLCHAIN`.
+
+For standalone toolchains, use the `clang`/`clang++` binaries instead of
+`gcc`/`g++`.
+
+For other build systems, ask the owners of that build system.
+
+## How to fix common problems
+
+When moving to Clang from GCC, you may notice some differences.
+
+### `-Oz` versus `-Os`
+
+[Clang Optimization Flags](https://clang.llvm.org/docs/CommandGuide/clang.html#code-generation-options)
+has the full details, but if you used `-Os` to optimize your
+code for size with GCC, you probably want `-Oz` when using
+Clang. Although `-Os` attempts to make code small, it still
+enables some optimizations that will increase code size (based on
+https://stackoverflow.com/a/15548189/632035). For the smallest possible
+code with Clang, prefer `-Oz`. With `-Oz`, Chromium actually saw both
+size *and* performance improvements when moving to Clang compared to
+`-Os` with GCC.
+
+### `__attribute__((__aligned__))`
+
+Normally the `__aligned__` attribute is given an explicit alignment,
+but with no value means “maximum alignment”. The interpretation of
+“maximum” differs between GCC and Clang: Clang includes vector types
+too so for ARM GCC thinks the maximum alignment is 8 (for `uint64_t`), but
+Clang thinks it’s 16 (because there are NEON instructions that require
+16-byte alignment). Normally this shouldn’t matter because malloc is
+always at least 16-byte aligned, and mmap regions are page (4096-byte)
+aligned. Most code should either specify an explicit alignment or use
+[alignas](http://en.cppreference.com/w/cpp/language/alignas) instead.
+
+### `-Bsymbolic`
+
+When targeting Android (but no other platform), GCC passed
+[-Bsymbolic](ftp://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html)
+to the linker by default. This is not a good default, so Clang does not
+do that. `-Bsymbolic` causes the following behavior change:
+
+```c++
+// foo.cpp
+#include
+
+void foo() {
+ std::cout << "Goodbye, world" << std::endl;
+}
+
+void bar() {
+ foo();
+}
+```
+
+```c++
+// main.cpp
+#include
+
+extern void bar();
+
+void foo() {
+ std::cout << "Hello, world\n";
+}
+
+int main(int, char**) {
+ foo(); // Prints “Hello, world!”
+ bar(); // Without -Bsymbolic, prints “Hello, world!” With -Bsymbolic, prints “Goodbye, world!”
+}
+```
+
+In addition to not being the "expected" default behavior on all other
+platforms, this prevents symbol interposition (used by tools such
+as asan).
+
+You might however wish to add manually `-Bsymbolic` back because it can
+result in smaller ELF files because fewer relocations are needed. If you
+do want the non-`-Bsymbolic` behavior but would like fewer relocations,
+that can be achieved via `-fvisibility=hidden` (and manually exporting
+the symbols you want to be public, using the `JNI_EXPORT` macro in JNI
+code or `__attribute__ ((visibility("default")))` otherwise. Linker
+version scripts are an even more powerful mechanism for controlling
+exported symbols, but harder to use.
+
+### `-fno-integrated-as`
+
+Especially for ARM and ARM64, Clang is much stricter about assembler
+rules than GCC/GAS. Use `-fno-integrated-as` if Clang reports errors in
+inline assembly or assembly files that you don't wish to modernize.
diff --git a/docs/ContinuousBuilds.md b/docs/ContinuousBuilds.md
new file mode 100644
index 0000000..2f63f9b
--- /dev/null
+++ b/docs/ContinuousBuilds.md
@@ -0,0 +1,26 @@
+# Continuous Builds
+
+The NDK's continuous builds can be accessed by anyone at
+https://ci.android.com/builds/branches/aosp-master-ndk/grid. aosp-master-ndk is
+the development branch, and release branches can be selected with the branch
+name field at the top of the page.
+
+**Disclaimer**: These builds are **not** suitable for production use. This is
+just a continuous build. The amount of testing these builds have been put
+through is minimal. A successful build only means that our test suite *built*
+successfully on Linux and Darwin. Windows is not covered (the Windows build bots
+are actually Linux), and none of the tests have actually been run yet.
+
+## NDK Branches
+
+### NDK Canary
+
+This is the master (development) branch of the NDK. Corresponds to
+https://android.googlesource.com/platform/manifest/+/master-ndk.
+
+### NDK rSOMETHING Release
+
+Release branches of the NDK. You can find the build number for the official
+release by examining the source.properties file in your NDK. The `Pkg.Revision`
+entry is in the format MAJOR.MINOR.BUILD (with beta information being appended
+if appropriate).
diff --git a/docs/HardFloatAbi.md b/docs/HardFloatAbi.md
new file mode 100644
index 0000000..dfc2659
--- /dev/null
+++ b/docs/HardFloatAbi.md
@@ -0,0 +1,42 @@
+ARM Hard Float ABI Removal
+==========================
+
+We're removing support for the armeabi-v7a-hard ABI. Anyone targeting this ABI
+should target armeabi-v7a instead.
+
+Why?
+
+1. People often use it because they think it's required to get
+ floating point instructions, which is incorrect.
+2. Most of the cases where people do see a performance improvement
+ here are likely bugs/missed optimizations in either the compiler or
+ the user's code, and hiding those means they won't get fixed.
+3. It's full of bugs and fixing them and keeping them fixed isn't
+ worth the benefit, especially in a world where you can avoid the
+ problem entirely by making your app 64-bit.
+
+armeabi-v7a-hard is not a real ABI. No devices are built with this.
+Hard float code generation is already used in the armeabi-v7a ABI.
+The "hard float" variant only changes the function call ABI. That is,
+the floating point registers are used to pass floating point
+arguments rather than the integer registers.
+
+This ABI should only be beneficial if the workload consists of many
+math function calls, the math function is cheap enough that the call
+itself is expensive, and it's not being inlined. The bug here is that
+the call is not being inlined.
+
+There is a cost to keeping this functionality. The way this "ABI"
+works is by having an `__attribute__((pcs("aapcs")))` on every
+function that is part of the Android ABI and has floating point
+parameters (anything that is in the system libraries or zygote). If we
+miss one (and we do, often), the function will not be called
+correctly.
+
+I should note that the GCC docs explicitly state that linking
+-mfloat-abi=softfp and -mfloat-abi=hard is invalid:
+https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
+
+> Note that the hard-float and soft-float ABIs are not
+> link-compatible; you must compile your entire program with the same
+> ABI, and link with a compatible set of libraries.
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..c71fa10
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,35 @@
+TEMPLATE=user/dac_template.jd
+INPUT_FORMAT=markdown_github-hard_line_breaks+yaml_metadata_block
+OUTPUT_FORMAT=html5
+
+SRCS := $(wildcard user/*.md)
+INTERMEDIATES := $(patsubst user/%.md,.build/%.md,$(SRCS))
+OUTPUTS := $(patsubst user/%.md,html/user/%.jd,$(SRCS))
+
+$(info SRCS=$(SRCS))
+$(info INTERMEDIATES=$(INTERMEDIATES))
+$(info OUTPUTS=$(OUTPUTS))
+
+.SECONDARY: $(INTERMEDIATES)
+
+all: $(OUTPUTS) Makefile
+
+clean:
+ rm -rf html
+ rm -rf .build
+
+.build/%.md: user/%.md .build Makefile
+ echo "---" > $@
+ echo "title: '$(shell head -n1 $<)'" >> $@
+ echo "..." >> $@
+ tail -n +3 $< >> $@
+
+html/user/%.jd: .build/%.md $(TEMPLATE) html/user .build Makefile
+ pandoc --template $(TEMPLATE) --from $(INPUT_FORMAT) --to $(OUTPUT_FORMAT) \
+ --toc --toc-depth=2 $< --output $@ --standalone
+
+html/user: Makefile
+ mkdir -p html/user
+
+.build: Makefile
+ mkdir -p .build
diff --git a/docs/NdkGdbTesting.md b/docs/NdkGdbTesting.md
new file mode 100644
index 0000000..e097ea0
--- /dev/null
+++ b/docs/NdkGdbTesting.md
@@ -0,0 +1,36 @@
+ndk-gdb testing
+===============
+
+Setup steps
+-----------
+1. Sync the Android.mk samples with `git clone -b android-mk
+ https://github.com/googlesamples/android-ndk.git`
+2. Pick a sample app (e.g. Teapot), cd into its directory, and compile and
+ install it to a device with `android update project -p . --target &&
+ ndk-build && ant clean debug install`, where `` is an SDK target such
+ as `android-23`.
+3. Run ndk-gdb.py. This can be done in three ways:
+ 1. Launch the application, and then run `ndk-gdb` from the app directory to
+ attach the debugger.
+ 2. Run `ndk-gdb --launch` to have ndk-gdb start the application's main
+ activity.
+ 3. Run `ndk-gdb --launch-activity ` to have ndk-gdb start a
+ specific activity.
+4. Test things!
+
+Relevant things to test
+-----------------------
+1. Verify that backtraces are sensible.
+2. Verify that breakpoints set before and after library load both work.
+ (Using --launch vs. attaching after the application is running helps here.)
+3. Verify that C++ stdlib pretty printers work (stlport and gnustl only).
+4. Verify that ndk-gdb works with all valid combinations of app ABI support
+ (defined in `APP_ABI` in Application.mk) and device ABI support.
+ For example, test with the following combinations:
+ 1. 32-bit device:
+ 1. `APP_ABI := armeabi`
+ 2. `APP_ABI := armeabi arm64-v8a`
+ 2. 64-bit device:
+ 1. `APP_ABI := armeabi`
+ 2. `APP_ABI := armeabi arm64-v8a`
+ 3. `APP_ABI := arm64-v8a`
diff --git a/docs/PlatformApis.md b/docs/PlatformApis.md
new file mode 100644
index 0000000..f4e0685
--- /dev/null
+++ b/docs/PlatformApis.md
@@ -0,0 +1,209 @@
+# Platform APIs
+
+The latest version of this document is available at
+https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md.
+
+## Implications of Adding a New Platform API
+
+Before adding a platform API to the NDK, there are some guarantees and
+restrictions that need to be considered.
+
+### ABI Compatibility
+
+The NDK ABI must be forward compatible. Apps that are in the Play Store must
+continue to function on new devices. This means that once something becomes NDK
+ABI, it must continue to be exposed and behavior must be preserved by the
+platform for the lifetime of the ABI (for all intents and purposes, forever).
+The NDK ABI includes but is not limited to:
+
+ * Exposed functions and global data.
+ * Layout and size of publicly visible data structures.
+ * Values of constants (such as enums).
+
+### Source Compatibility
+
+Source compatibility should be maintained, though exceptions have been made.
+When appropriate, source compatibility breaking features can be limited to only
+breaking when the user is targeting at least the API level that broke the change
+(e.g. `#if __ANDROID_API__ >= 24`), which ensures that any currently building
+app will continue building until the developer chooses to upgrade to a new
+platform level.
+
+Note that the definition of target API level in the NDK differs from the SDK.
+For the NDK, the target API level is the minimum supported API level for the
+app. If any non-ABI features are guarded by the target API level, they will only
+be available to apps with a minimum target that includes that API level.
+
+As a practical example of this, the NDK historically did not expose the `ALOG*`
+log macros, only the `__android_log_*` functions. If the macros were to be added
+but only exposed for API levels android-24 and newer, these helper macros that
+could otherwise be available to Gingerbread would only be usable by developers
+that chose to forfeit all Android users on devices older than android-24.
+
+### API Restrictions
+
+NDK APIs are C APIs only. This restriction may be lifted in the future, but at
+the moment Android's C++ ABI is not guaranteed to be stable. Note that this does
+not restrict the implementation of the API to C, only the interface that is
+exposed in the headers.
+
+NDK API headers can only depend on other NDK API headers. Platform headers from
+android-base, libcutils, libnativehelper, etc are not available to the NDK.
+
+## For Platform Developers
+
+To get your API into the NDK you'll generally need to define the two pieces that
+implement it: the headers and the libraries. Often the library is libandroid.so
+and you won't need to add a new library, but you'll need to modify an existing
+one. For this reason, libraries and the headers for those libraries are defined
+separately.
+
+### Headers
+
+To add headers to the NDK, create an `ndk_headers` module in your Android.bp.
+Examples of this module type can be found in [bionic/libc/Android.bp].
+
+These module definitions are as follows:
+
+```
+// Will install $MODULE_PATH/include/foo/bar/baz.h to qux/bar/baz.h (relative to
+// $NDK_OUT/sysroot/usr/include).
+ndk_headers {
+ name: "foo",
+
+ // Base directory of the headers being installed. This path will be stripped
+ // when installed.
+ from: "include/foo",
+
+ // Install path within the sysroot.
+ to: "qux",
+
+ // List of headers to install. Relative to the Android.bp. Glob compatible.
+ // The common case is "include/**/*.h".
+ srcs: ["include/foo/bar/baz.h"],
+
+ // If true, makes the headers available to the platform but hides them from
+ // the NDK release. When actively developing an NDK API, `draft` should be
+ // set to true so the API isn't released until it is ready. It can still be
+ // used within the platform and CTS even if it is a draft.
+ //
+ // Note that false is the default, so when releasing an API this line may
+ // simply be removed.
+ draft: true,
+}
+```
+
+### Libraries
+
+To add a library to the NDK, create an `ndk_library` module in your Android.bp.
+An example of this module type can be found in [bionic/libc/Android.bp].
+
+These module defintions are as follows:
+
+```
+// The name of the generated file will be based on the module name by stripping
+// the ".ndk" suffix from the module name. Module names must end with ".ndk"
+// (as a convention to allow soong to guess the NDK name of a dependency when
+// needed). "libfoo.ndk" will generate "libfoo.so.
+ndk_library {
+ name: "libfoo.ndk",
+
+ // A version script with some metadata that encodes version and arch
+ // mappings so that only one script is needed instead of one per API/arch.
+ // An example of this file can be found at [bionic/libc/libc.map.txt].
+ //
+ // For a new library, this is something you'll need to create yourself.
+ // These should *not* be generated by `readelf -sW`ing your library. The
+ // purpose of these files is to explicitly list your APIs so you never
+ // accidentally expose private API that you'll need to support forever.
+ symbol_file: "libfoo.map.txt",
+
+ // The first API level a library was available. A library will be generated
+ // for every API level beginning with this one.
+ first_version: "9",
+
+ // Same behavior as the `draft` property in `ndk_headers`.
+ draft: true,
+}
+```
+
+### Linker namespaces' public libraries list
+
+You wouldn't be adding a library to the NDK unless you actually wanted apps to
+be able to use your library, but in Android N or later, apps are only allowed
+to access libraries that are part of the NDK API surface. The list of libraries
+available to apps is stored in:
+- `system/core/rootdir/etc/public.libraries.android.txt` for main Android
+- `system/core/rootdir/etc/public.libraries.wear.txt` for Android Wear
+devices
+- `system/core/rootdir/etc/public.libraries.iot.txt` for Android Things devices
+
+If a library is specific to either 32 or 64-bit ABI, append `32` or `64` to the
+line (with space) to specify the bitness. e.g. `libfoo.so 32`. If neither 32 nor
+64 is specified, the library is considered to be available for all ABIs of the
+device.
+
+By default, all the libraries listed in the above text file are preloaded when the
+app process is started. This behavior can be controlled per library by appending
+`nopreload` option. e.g. `libfoo.so nopreload`. Libraries with the option won't be
+preloaded, but will be loaded on demand.
+
+The `nopreload` option and the bitness option can be used together as in
+`libfoo.so 32 nopreload`.
+
+### CTS
+
+There's also a CTS test to ensure that non-NDK libraries don't get added to
+the public libraries list. This test can be found at
+`cts/tests/tests/jni/src/android/jni/cts/LinkerNamespacesHelper.java`. Simply
+add your library to the `PUBLIC_SYSTEM_LIBRARIES` list in that file.
+
+[bionic/libc/Android.bp]: https://android.googlesource.com/platform/bionic/+/master/libc/Android.bp
+
+### Making sure it works
+
+The best way to make sure you've set everything up properly is to add a test to
+CTS. Make sure this test is built using the NDK (make sure `LOCAL_SDK_VERSION`
+is set, `sdk_version` if you're using Android.bp). If your test passes in CTS
+when it is built with the NDK, then everything has been set up properly.
+
+Note that without this step, it is possible that one of the above steps will
+have been done incorrectly and you wouldn't know without inspecting everything
+yourself. If the `ndk_library` rule ends up in an Android.bp that never gets
+parsed and there are no tests built with the NDK that use that library, your
+build will still pass.
+
+## For NDK Developers
+
+The platform APIs reach the NDK via the "toolchain" module of the NDK (currently
+via the intermediates of "sysroot" and "platforms". The sysroot currently is
+just the headers, whereas the libraries are in platforms and CRT objects are
+built as part of the NDK (an ELF note is added to the CRT objects so NDK
+binaries contain NDK version information).
+
+### Updating the Sysroot
+
+The NDK sysroot is provided as prebuilts in prebuilts/ndk/platform. To update
+these, use prebuilts/ndk/update\_platform.py. Prebuilts suitable for check-in
+must be taken from the build servers. However, to test changes that have not yet
+been submitted to the platform, do the following:
+
+```bash
+$ cd path/to/platform
+$ OUT_DIR=ndk-out DIST_DIR=ndk-dist build/soong/scripts/build-ndk-prebuilts.sh
+$ cd path/to/ndk/prebuilts/ndk
+$ ./update_platform.py --no-download \
+ path/to/platform/ndk-dist/ndk_platform.tar.bz2
+```
+
+Note that most branches will include at least one codenamed release in the
+sysroot artifacts. Clang only handles integer API levels, so these will cause an
+error when updating the prebuilts if any codenames are found. To avoid such
+errors, use either `--remove-platform` or `--rename-codename` when updating.
+Whether the platform should be removed or renamed depends on the status of the
+release. For releases accompanying an Android developer preview the platform
+should be renamed, but for other releases the APIs should be removed.
+
+For example, prior to the Android R developer previews being available
+`--remove-platform R` was used. To include R API previews
+`--rename-codename R=30` was used.
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..349b4dd
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,215 @@
+Android Clang/LLVM Toolchain
+============================
+
+For the latest version of this doc, please make sure to visit:
+[Android Clang/LLVM Toolchain Readme Doc](https://android.googlesource.com/toolchain/llvm_android/+/master/README.md)
+
+You can also visit the
+[Android Clang/LLVM Prebuilts Readme Doc](https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/master/README.md)
+for more information about our prebuilt toolchains (and what versions they are based upon).
+
+Build Instructions
+------------------
+
+```
+$ mkdir llvm-toolchain && cd llvm-toolchain
+$ repo init -u https://android.googlesource.com/platform/manifest -b llvm-toolchain
+$ repo sync -c
+$ python toolchain/llvm_android/build.py
+```
+
+If building on Linux, pass `--no-build windows` to `build.py` to skip
+building Clang for Windows.
+
+If you have an additional llvm tree built and present in your `$PATH`, then
+`build.py` might fail during the Windows build of libcxxabi with the error
+`'libstdc++ version must be at least 4.8.'`. The solution is to remove that
+path from your `$PATH` before invoking `build.py`.
+
+
+Instructions to rebuild a particular toolchain release
+------------------------------------------------------
+
+To rebuild a particular toolchain, find the manifest file for that release:
+
+```
+$ $TOOLCHAIN_DIR/bin/clang -v
+Android (6317467 based on r365631c1) clang version 9.0.8...
+```
+
+The build number for that toolchain is `6317467` and the manifest is found in
+`$TOOLCHAIN_DIR/manifest_6317467.xml`
+
+Rebuild the toolchain with that manifest:
+
+```
+$ mkdir llvm-toolchain && cd llvm-toolchain
+$ repo init -u https://android.googlesource.com/platform/manifest -b llvm-toolchain
+$ cp $TOOLCHAIN_DIR/manifest_6317467.xml .repo/manifests
+$ repo init -m manifest_6317467.xml
+$ repo sync -c
+
+# Optional: Apply any LLVM/Clang modifications to toolchain/llvm-project
+
+$ python toolchain/llvm_android/build.py
+```
+
+Compiler Update Steps
+---------------------
+
+### Step 1: Update source code
+
+1. Download source code.
+
+We can use either llvm-toolchain or master-plus-llvm branch. master-plus-llvm branch is a
+combination of llvm-toolchain and aosp-master, which can test building platform and create the
+build switch CL in the same tree. llvm-toolchain is more suitable when trying to reproduce a
+toolchain from a different release.
+
+```sh
+$ mkdir master-plus-llvm && cd master-plus-llvm
+$ repo init -u https://android.googlesource.com/platform/manifest -b master-plus-llvm
+$ repo sync -c
+```
+
+2. Update toolchain/llvm-project.
+
+```sh
+# replace r407598 with the update version
+$ export NEW_REVISION=r407598
+$ cd toolchain/llvm_android
+$ ./merge_from_upstream.py --rev $NEW_REVISION
+```
+
+3. Update build version.
+
+In android_version.py:
+ _patch_level = '1'
+ _svn_revision = $NEW_REVISION
+
+4. Test build.
+
+```sh
+$ ./build.py
+```
+
+5. Submit CLs in toolchain/llvm_android and toolchain/llvm-project together.
+
+Examples are in aosp/1515350 and aosp/1515697.
+
+
+### Step 2. Update profdata
+
+It is to speed up compile time for the new compiler.
+The profdata is generated in [go/ab/aosp-master-plus-llvm](https://ci.android.com/builds/branches/aosp-master-plus-llvm/grid),
+target Clang-PGO.
+
+An example is in [aosp/1513058](https://android-review.googlesource.com/c/platform/prebuilts/clang/host/linux-x86/+/1513058/).
+
+
+### Step 3: Cherry pick patches
+
+Use cherrypick_cl.py to cherry pick upstream patches:
+```sh
+$ ./cherrypick_cl.py --sha ... --verify-merge --create-cl
+```
+
+We want to find all patches before $NEW_REVISION but reverted after $NEW_REVISION in upstream.
+Search "revert-checker/android" emails to find candidates, and cherry pick them.
+
+We may revert upstream patches locally or add local patches. Put patch files in patches/, and add
+patch info at the end of patches/PATCHES.json.
+
+An example is in [aosp/1556717](https://android-review.googlesource.com/c/toolchain/llvm_android/+/1556717/).
+
+
+### Step 4: Generate prebuilts
+
+Clang prebuilts are generated in [go/ab/aosp-llvm-toolchain](https://ci.android.com/builds/branches/aosp-llvm-toolchain/grid).
+Use update-prebuilts.py to download them.
+
+```sh
+$ ./update-prebuilts.py
+```
+
+Then upload clang prebuilts in prebuilts/clang/host/linux-x86, prebuilts/clang/host/darwin-x86, and
+prebuilts/clang/host/windows-x86 for testing.
+
+An example is in [aosp/1532505](https://android-review.googlesource.com/c/platform/prebuilts/clang/host/linux-x86/+/1532505/).
+
+
+### Step 5: Test prebuilts
+
+1. Upload switch CL in build/soong.
+
+In build/soong/cc/config/global.go:
+ ClangDefaultVersion = "clang-$NEW_VERSION"
+ ClangDefaultShortVersion = ".0.1"
+
+If ther are new compiler warnings we need to suppress, add them at the end of
+ClangExtraNoOverrideCflags in build/soong/cc/config/clang.go.
+
+If there are new sanitizer flags we need to suppress, add them in build/soong/cc/sanitize.go.
+
+An example is in [aosp/1541244](https://android-review.googlesource.com/c/platform/build/soong/+/1541244/).
+
+2. Put clang linux-x86 prebuilt CL and soong CL in the same topic. Run presubmit check.
+
+3. Cherry pick the prebuilt and soong CLs to internal main, and run presubmit check. Some tests
+(like bionic fortify tests) only run there.
+
+4. Use toolchain/llvm_android/test/scripts/test_prebuilts.py.
+
+```sh
+$ test/scripts/test_prebuilts.py --prebuilt_cl --soong_cl \
+ --tag "test_clang_${NEW_VERSION}_v1" --test_kind platform --build \
+ --verbose
+```
+
+The test results are shown in go/forrest.
+After all tests complete. Run `test/scripts/update_results.py` to upload results to
+go/android-llvm-testing-dashboard.
+
+Some device_boot_health_check tests are flaky. So it is unlikely to get fully green results.
+
+5. Manually test on linux.
+
+Below tests have been affected by compiler updates. It's better to test them manually on all
+architectures (arm, arm64, x86, x86_64).
+ bionic_unit_tests or CtsBionicTestCases
+ CtsNNAPITestCases
+ CtsMediaV2TestCases
+
+6. Manually test on windows.
+
+Run on wine using test/platform/run_windows_tests.sh.
+
+7. Manually test on darwin.
+
+We used to build platform on darwin. But probably we will change to only build and run selected
+tests.
+
+
+### Step 6: Submit prebuilts
+
+Currently we submit prebuilts before the soong CL. This usually needs the soong CL to wait for
+at least six hours to pass presubmit check. Maybe we can submit them together if that is supported
+by RBE.
+
+
+### Step 7: Switch to the new compiler
+
+All places need to switch to the new compiler are listed in
+https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/master/README.md.
+
+The updates in the kernel and NDK are done separately.
+
+After switching, we also need to update the doc.
+
+
+More Information
+----------------
+
+We have a public mailing list that you can subscribe to:
+[android-llvm@googlegroups.com](https://groups.google.com/forum/#!forum/android-llvm)
+
diff --git a/docs/Roadmap.md b/docs/Roadmap.md
new file mode 100644
index 0000000..b7e83ef
--- /dev/null
+++ b/docs/Roadmap.md
@@ -0,0 +1,324 @@
+# NDK Roadmap
+
+**Note**: If there's anything you want to see done in the NDK, [file a bug]!
+Nothing here is set in stone, and if there's something that we haven't thought
+of that would be of more use, we'd be happy to adjust our plans for that.
+
+[file a bug]: https://github.com/android-ndk/ndk/issues
+
+**Disclaimer**: Everything here is subject to change. The further the plans are
+in the future, the less stable they will be. Things in the upcoming release are
+fairly certain, and the second release is quite likely. Beyond that, anything
+written here is what we would like to accomplish in that release assuming things
+have gone according to plan until then.
+
+**Note**: For release timing, see our [release schedule] on our wiki.
+
+[release schedule]: https://github.com/android-ndk/ndk/wiki#release-schedule
+
+---
+
+## Regular maintenance
+
+Every NDK release aims to include a new toolchain, new headers, and a new
+version of libc++.
+
+We also maintain [GitHub Projects](https://github.com/android/ndk/projects)
+to track the bugs we intend to fix in any given NDK release.
+
+### Toolchain updates
+
+The NDK and the Android OS use the same toolchain. Android's toolchain team is
+constantly working on updating to the latest upstream LLVM for the OS. It can
+take a long time to investigate issues when compiling -- or issues that the
+newer compiler finds in -- OS code or OEM code, for all 4 supported
+architectures, so these updates usually take a few months.
+
+Even then, a new OS toolchain may not be good enough for the NDK. In the OS, we
+can work around compiler bugs by changing our code, but for the NDK we want to
+make compiler updates cause as little disruption as possible. We also don't want
+to perform a full compiler update late in the NDK release cycle for the sake of
+stability.
+
+The aim is that each NDK will have a new toolchain that's as up to date as
+feasible without sacrificing stability, but we err on the side of stability when
+we have to make a choice. If an NDK release doesn't include a new compiler, or
+that compiler isn't as new as you'd hoped, trust us --- you wouldn't want
+anything newer that we have just yet!
+
+## Current work
+
+Most of the team's work is currently focused outside the NDK proper, so while
+the NDK release notes may seem a bit sparse, there are still plenty of
+improvements coming for NDK users:
+
+* Improving NDK and Android Gradle Plugin documentation.
+* Improving the OS (in particular the linker).
+* Getting an up to date LLDB for Android Studio. We'll be adding LLDB support to
+ ndk-gdb after this is done.
+* Working with the Android frameworks teams to get new NDK APIs.
+* Improving the workflow and tooling for supporting Android preview releases so
+ we don't lose so much time to them in the future.
+
+### NDK r22
+
+#### C++ File System API
+
+[Issue 609](https://github.com/android-ndk/ndk/issues/609)
+
+libc++'s `std::filesystem` is now ported and included in the NDK.
+
+#### Default to LLD and LLVM binutils
+
+NDK r18 [made LLD available](https://github.com/android-ndk/ndk/issues/683),
+r20 made it more usable, and r22 has made it the default.
+
+r22 also migrates from GNU `ar` and `strip` to `llvm-ar` and `llvm-strip`. No
+GNU binutils tools are used by the NDK with the default configuration. GNU
+binutils will be removed in a future release of the NDK.
+
+#### lldb debugger
+
+LLDB is now included alongside the toolchain in the NDK, and `ndk-gdb` supports
+the `--lldb` option. GDB will be removed in a future release of the NDK.
+
+## Future work
+
+The following projects are listed in order of their current priority.
+
+Note that some of these projects do not actually affect the contents of the NDK
+package. The samples, documentation, etc are all NDK work but are separate from
+the NDK package. As such they will not appear in any specific release, but are
+noted here to show where the team's time is being spent.
+
+### Migrate remaining architectures to LLVM's unwinder
+
+[Issue 1230]: https://github.com/android/ndk/issues/1230
+
+Right now only 32-bit Arm uses the LLVM unwinder for exception handling, and the
+remaining architectures rely on libgcc. Using the same unwinder across all
+architectures will give more predictable behavior, and consolidating on a single
+unwinder reduces duplicated upkeep costs so we can work on other improvements.
+
+### Migrate from libgcc to libclang_rt
+
+[Issue 1231]: https://github.com/android/ndk/issues/1231
+
+These two libraries provide the runtime support the compiler relies on. While
+similar, LLVM's `libclang_rt.builtins` includes many things that libgcc does
+not. We've been working around inconsistencies for a while by using both, but it
+would be best to just finish the migration.
+
+One blocker here is that most architectures currently rely on libgcc for
+exception handling support. Once we've migrated to LLVM's unwinder for all
+architectures this will be easier.
+
+### Remove GNU binutils
+
+We've switched to LLD and the rest of the LLVM tools by default as of r22. We
+should consolidate on the supported tools after they have been given some soak
+time to discover and fix any remaining issues.
+
+### CMake
+
+CMake added their own NDK support about the same time we added our
+toolchain file. The two often conflict with each other, and a toolchain
+file is a messy way to implement this support. However, fully switching to
+the integrated support puts NDK policy decisions (default options, NDK layout,
+etc) fully into the hands of CMake, which makes them impossible to update
+without the user also updating their CMake version.
+
+We will reorganize our toolchain file to match the typical implementation of a
+CMake platform integration (like `$CMAKE/Modules/Platform/Android-*.cmake`) and
+CMake will be modified to load the implementation from the NDK rather than its
+own.
+
+Preferably, most of this work will actually involve improving Clang's defaults
+so that the toolchain file doesn't need to do anything aside from setting up
+toolchain paths.
+
+See [Issue 463](https://github.com/android-ndk/ndk/issues/463) for discussion.
+
+---
+
+## Unscheduled Work
+
+The following projects are things we intend to do, but have not yet been
+scheduled into the sections above.
+
+### Better documentation
+
+We should probably add basic doc comments to the bionic headers:
+
+* One-sentence summary.
+* One paragraph listing any Android differences. (Perhaps worth upstreaming this
+ to man7.org too.)
+* Explain any "flags" arguments (at least giving some idea of which flags)?
+* Explain the return value: what does a `char*` point to? Who owns it? Are
+ errors -1 (as for most functions) or `` values (for
+ `pthread_mutex_lock`)?
+* A "See also" pointing to man7.org?
+
+Should these be in the NDK API reference too? If so, how will we keep
+them from swamping the "real" NDK API?
+
+vim is ready, Android Studio now supports doxygen comments (but seems
+to have gained a new man page viewer that takes precedence),
+and Visual Studio Code has nothing but feature requests.
+
+Beyond writing the documentation, we also should invest some time in improving
+the presentation of the NDK API reference on developer.android.com.
+
+### Better samples
+
+The samples are low-quality and don't necessarily cover interesting/difficult
+topics.
+
+### Better tools for improving code quality
+
+The NDK has long included `gtest` and clang supports various sanitiziers,
+but there are things we can do to improve the state of testing/code quality:
+
+* Test coverage support.
+* Add `gmock`.
+* Make [GTestJNI] available to developers via Maven so developers can integrate
+ their C++ tests into Studio.
+
+[GTestJNI]: https://github.com/danalbert/GTestJNI
+
+### C++ wrappers for NDK APIs
+
+NDK APIs are C-only for ABI stability reasons.
+
+We should offer C++ wrappers as part of an NDK support library (possibly as part
+of JetPack), even if only to offer the benefits of RAII. Examples include
+[Bitmap](https://github.com/android-ndk/ndk/issues/822),
+[ATrace](https://github.com/android-ndk/ndk/issues/821), and
+[ASharedMemory](https://github.com/android-ndk/ndk/issues/820).
+
+### JNI helpers
+
+Complaints about basic JNI handling are common. We should make libnativehelper
+available as an AAR.
+
+### Improve automation in ndkports so we can take on more packages
+
+Before we can take on maintenance for additional packages we need to improve the
+tooling for ndkports. Automation for package updates, testing, and the release
+process would make it possible to expand.
+
+### NDK icu4c wrapper
+
+For serious i18n, `icu4c` is too big too bundle, and non-trivial to use
+the platform. We have a C API wrapper prototype, but we need to make it
+easily available for NDK users.
+
+### More automated libc++ updates
+
+We still need to update libc++ twice: once for the platform, and once
+for the NDK. We also still have two separate test runners.
+
+### Weak symbols for API additions
+
+iOS developers are used to using weak symbols to refer to function that
+may be present in their equivalent of `targetSdkVersion` but not in their
+`minSdkVersion`. We could potentially do something similar. See
+[issue 1003](https://github.com/android-ndk/ndk/issues/1003).
+
+### C++ Modules
+
+By Q2 2019 Clang may have a complete enough implementation of the modules TS and
+Android may have a Clang with those changes available.
+
+At least for the current spec (which is in the process of merging with the Clang
+implementation, so could change), the NDK will need to:
+
+ 1. Support compiling module interfaces.
+ 2. Support either automated discovery (currently very messy) or specification
+ of module dependencies.
+ 3. Begin creating module interfaces for system libraries. Frameworks, libc,
+ libc++, etc.
+
+---
+
+## Historical releases
+
+Full [history] is available, but this section summarizes major changes
+in recent releases.
+
+[history]: https://developer.android.com/ndk/downloads/revision_history.html
+
+### Package management
+
+We shipped [Prefab] and the accompanying support for the Android Gradle Plugin
+to support native dependencies. AGP 4.0 includes the support for importing these
+packages, and 4.1 includes the support for creating AARs that support them.
+
+We also maintain a few packages as part of [ndkports]. Currently just curl,
+OpenSSL, and JsonCpp.
+
+[Prefab]: https://github.com/google/prefab
+[ndkports]: https://android.googlesource.com/platform/tools/ndkports/
+
+### NDK r21 LTS
+
+Updated Clang, LLD, libc++, make, and GDB. Much better LLD behavior on Windows.
+32-bit Windows support removed. Neon by default for all API levels. OpenMP now
+available as both a static and shared library.
+
+### NDK r20
+
+Updated Clang and libc++, added Q APIs. Improved out-of-the-box Clang behavior.
+
+### NDK r19
+
+Reorganized the toolchain packaging and modified Clang so that standalone
+toolchains are now unnecessary. Clang can now be invoked directly from its
+installed location in the NDK.
+
+C++ compilation defaults to C++14.
+
+### NDK r18
+
+Removed GCC and gnustl/stlport. Added lld.
+
+Added `compile_commands.json` for better tooling support.
+
+### NDK r17
+
+Defaulted to libc++.
+
+Removed ARMv5 (armeabi), MIPS, and MIPS64.
+
+### NDK r16
+
+Fixed libandroid\_support, libc++ now the recommended STL (but still
+not the default).
+
+Removed non-unified headers.
+
+### NDK r15
+
+Defaulted to [unified headers] (opt-out).
+
+Removed support for API levels lower than 14 (Android 4.0).
+
+### NDK r14
+
+Added [unified headers] (opt-in).
+
+[unified headers]: https://android.googlesource.com/platform/ndk/+/master/docs/UnifiedHeaders.md
+
+### NDK r13
+
+Added [simpleperf].
+
+[simpleperf]: https://developer.android.com/ndk/guides/simpleperf.html
+
+### NDK r12
+
+Removed [armeabi-v7a-hard].
+
+Removed support for API levels lower than 9 (Android 2.3).
+
+[armeabi-v7a-hard]: https://android.googlesource.com/platform/ndk/+/ndk-r12-release/docs/HardFloatAbi.md
diff --git a/docs/Testing.md b/docs/Testing.md
new file mode 100644
index 0000000..3d03b69
--- /dev/null
+++ b/docs/Testing.md
@@ -0,0 +1,201 @@
+# Testing the NDK
+
+The latest version of this document is available at
+https://android.googlesource.com/platform/ndk/+/master/docs/Testing.md.
+
+The NDK tests are built as part of a normal build (with `checkbuild.py`) and run
+with `run_tests.py`. See [Building.md] for more instructions on building the
+NDK.
+
+From the NDK source directory (`./ndk` within the directory you ran `repo init`
+in, or the root of the cloned directory if you cloned only the NDK project).
+
+```bash
+$ ./checkbuild.py # Build the NDK and tests.
+$ ./run_tests.py
+```
+
+Running the tests requires `adb` in your path and compatible devices attached.
+If you're having trouble with the version from the SDK manager, try a version
+built fresh from AOSP.
+
+The test runner will look for any attached devices that match the
+requirements listed in the `devices` section of the test configuration file (see
+[qa\_config.json] for the defaults, or use `--config` to choose your own). Each
+test will be run on all devices compatible with that test.
+
+The full QA configuration takes roughly 6 minutes to run (P920 Linux host, 4
+Galaxy Nexūs for Jelly Bean, 2 Pixels for Pie, 1 emulator for x86-64 Pie).
+Attaching multiple devices will allow the test runner to shard tests among those
+devices.
+
+The tests can be rebuilt without running `checkbuild.py` (which is necessary in
+the case of not having a full NDK checkout, as you might when running the
+Windows tests on a release from the build server) with `run_tests.py --rebuild`.
+
+[qa\_config.json]: ../qa_config.json
+[Building.md]: Building.md
+
+
+## Restricting Test Configurations
+
+By default, all of the configurations we test are built from both
+`checkbuild.py` and `run_tests.py --rebuild`. This runs tens of thousands of
+test executables. Each test is built in 4 different configurations (once for
+each ABI) at time of writing. The set of configurations built can be restricted
+in two ways.
+
+First, `run_tests.py --config myconfig.json` will use an alternate test
+configuration file (the default is `qa_config.json`).
+
+Second, and simpler for a development workflow, the following flag can be used
+to restrict the configurations (the presence of any of this flag will override
+the matching entry in the config file, but otherwise the config file is obeyed):
+
+```bash
+$ ./run_tests.py --rebuild --abi armeabi-v7a
+```
+
+Configuration filtering flags are repeatable. For example, `--abi armeabi-v7a
+--abi x86` will build both armeabi-v7a and x86 tests.
+
+Beyond restricting test configurations, the tests themselves can be filtered
+with the `--filter` flag:
+
+```bash
+$ ./run_tests.py --filter test-googletest-full
+```
+
+Test filters support wildcards (as implemented by Python's `fnmatch.fnmatch`).
+The filter flag may be combined with the build configuration flags.
+
+Putting this all together, a single test can be rebuilt and run for just
+armeabi-v7a, with the following command:
+
+```bash
+$ ./run_tests.py --rebuild \
+ --abi armeabi-v7a \
+ --filter test-googletest-full
+```
+
+
+## Testing Releases
+
+When testing a release candidate, your first choice should be to run the test
+artifacts built on the build server for the given build. This is the
+ndk-tests.tar.bz2 artifact in the same directory as the NDK tarball. Extract the
+tests somewhere, and then run:
+
+```bash
+$ ./run_tests.py path/to/extracted/tests
+```
+
+For Windows, test artifacts are not available since we cross compile the NDK
+from Linux rather than building on Windows. We want to make sure the Windows
+binaries we build work *on* Windows (using wine would only tell us that they
+work on wine, which may not be bug compatible with Windows), so those must be
+built on the test machine before they can be run. To use the fetched NDK to
+build the tests, run:
+
+```bash
+$ ./run_tests.py --rebuild --ndk path/to/extracted/ndk out
+```
+
+
+## Broken and Unsupported Tests
+
+To mark tests as currently broken or as unsupported for a given configuration,
+add a `test_config.py` to the test's root directory (in the same directory as
+`jni/`).
+
+Unsupported tests will not be built or run.
+
+Broken tests will be built and run, and the result of the test will be inverted.
+A test that fails will become an "EXPECTED FAILURE" and not be counted as a
+failure, whereas a passing test will become an "UNEXPECTED SUCCESS" and count as
+a failure.
+
+By default, `run_tests.py` will hide expected failures from the output since the
+user is most likely only interested in seeing what effect their change had. To
+see the list of expected failures, pass `--show-all`.
+
+Here's an example `test_config.py` that marks this test as broken when building
+for arm64 and unsupported when running on a pre-Lollipop device:
+
+```python
+def build_broken(abi, platform):
+ if abi == 'arm64-v8a':
+ return abi, 'https://github.com/android-ndk/ndk/issues/foo'
+ return None, None
+
+
+def run_unsupported(abi, device_api, name):
+ if device_api < 21:
+ return device_api
+ return None
+```
+
+The `*_broken` checks return a tuple of `(broken_configuration, bug_url)` if the
+given configuration is known to be broken, else `(None, None)`.
+
+The `*_unsupported` checks return `broken_configuration` if the given
+configuration is unsupported, else `None`.
+
+The configuration is specified by the following arguments:
+
+* `abi`: The ABI being built for.
+* `platform`: The platform version being *built* for. Not necessarily the
+ platform version that the test will be run on.
+* `device_api`: The API level of the device the test will be run on.
+* `name`: This is the name of the test executable being run. For libc++ tests
+ built by LIT, the executable will be `foo.pass.cpp.exe`, but `name` will be
+ `foo.pass`.
+
+
+## Devices and Emulators
+
+For testing a release, make sure you're testing against the released user builds
+of Android.
+
+For Nexus/Pixel devices, factory images are available here:
+https://developers.google.com/android/nexus/images.
+
+For emulators, use emulator images from the SDK rather than from a platform
+build, as these are what our users will be using. Note that the emulators are
+known to break some NDK tests from update to update (namely test-googletest-full
+and asan-smoke).
+
+After installing the emulator images from the SDK manager, they can be
+configured and launched for testing with (assuming the SDK tools directory is in
+your path):
+
+```bash
+$ android create avd --name $NAME --target android-$LEVEL --abi $ABI
+$ emulator -avd $NAME -no-window
+```
+
+This will create a new virtual device and launch it in a headless state. Note
+that SIGINT will not stop the emulator, and SIGTERM might leave it in a broken
+state. To shut down an emulator, use `adb shell reboot -p`.
+
+Note that there are no ARM64 emulators whatsoever in the SDK manager. Testing
+ARM64 will require a physical device.
+
+
+## Windows VMs
+
+Windows testing can be done on Windows VMs in Google Compute Engine. To create
+one:
+
+ * Install the [Google Cloud SDK](https://cloud.google.com/sdk/).
+ * Run `scripts/create_windows_instance.py $PROJECT_NAME $INSTANCE_NAME`
+ * The project name is the name of the project you configured for the VMs.
+ * The instance name is whatever name you want to use for the VM.
+
+This process will create a `secrets.py` file in the NDK project directory that
+contains the connection information.
+
+The VM will have Chrome and Git installed and WinRM will be configured for
+remote command line access.
+
+TODO: Implement `run_tests.py --remote-build`.
diff --git a/docs/Toolchains.md b/docs/Toolchains.md
new file mode 100644
index 0000000..93ef478
--- /dev/null
+++ b/docs/Toolchains.md
@@ -0,0 +1,124 @@
+# Working with the NDK Toolchains
+
+The latest version of this document is available at
+https://android.googlesource.com/platform/ndk/+/master/docs/Toolchains.md.
+
+The toolchains shipped in the NDK are not built as a part of the NDK build
+process. Instead they are built separately and checked into git as prebuilts
+that are repackaged when shipped in the NDK. This applies to both Clang and
+binutils.
+
+Both toolchains are built separately. An artifact of the build is a tarball of
+the compiler for distribution. That artifact is unpacked into a location in the
+Android tree and checked in. The NDK build step for the toolchain copies that
+directory into the NDK and makes minor modifications to make the toolchains suit
+the NDK rather than the platform.
+
+Note: Any changes to either toolchain need to be tested in the platform *and*
+the NDK. The platform and the NDK both get their toolchains from the same build.
+
+TODO: This process is far too manual. `checkbuild.py` should be updated (or
+additional scripts added) to ease this process.
+
+## Clang
+
+Clang's build process is described in the [Android LLVM Readme]. Note that Clang
+cannot be built from the NDK tree. The output tarball is extracted to
+`prebuilts/clang/host/$HOST/clang-$REVISION`. `checkbuild.py clang` repackages
+this into the NDK out directory.
+
+[Android Clang Readme]: https://android.googlesource.com/toolchain/llvm_android/+/master/README.md
+
+### Testing Local Changes
+
+To test a Clang you just built:
+
+```bash
+$ export CLANG_PREBUILTS=`realpath ../prebuilts/clang/host/linux-x86`
+$ rm -r $CLANG_PREBUILTS/clang-dev
+$ tar xf path/to/clang-dev-linux-x86_64.tar.bz2 -C $CLANG_PREBUILTS
+# Update CLANG_VERSION in ndk/toolchains.py.
+$ ./checkbuild.py
+# Run tests. To run the NDK test suite, you will need to attach the
+# appropriately configured devices. The test tool will print warnings for
+# missing configurations.
+$ ./run_tests.py
+```
+
+For details about running tests, see [Testing.md].
+
+[Testing.md]: Testing.md
+
+This installs the new Clang into the prebuilts directory so it can be included
+in the NDK. The `symlink-clang.py` line updates the symlinks in prebuilts NDK to
+point at the new Clang. The Clang in `prebuilts/ndk` is used by legacy NDK build
+scripts in ndk/build/tools. The difference between it and `prebuilts/clang` is
+the directory layout, which differs so that `ndk-build` can use it.
+
+If you need to make changes to Clang after running the above steps, future
+updates can be done more quickly with:
+
+```bash
+$ rm -r $CLANG_PREBUILTS/clang-dev
+$ tar xf path/to/clang-dev-linux-x86_64.bz2 -C $CLANG_PREBUILTS
+$ ./checkbuild.py toolchain --force-package
+# Run tests.
+```
+
+We don't need to rebuild the whole NDK since we've already built most of it.
+
+### Updating to a New Clang
+
+These steps need to be run after installing the new prebuilt from the build
+server to `prebuilts/clang` (see the [update-prebuilts.py]).
+
+[update-prebuilts.py]: https://android.googlesource.com/toolchain/llvm_android/+/master/update-prebuilts.py
+
+```bash
+# Edit ndk/toolchains.py and update `CLANG_VERSION`. When you modify this value,
+also follow the instructions in the comment.
+# Update the VERSION variable in get_llvm_toolchain_binprefix in
+# build/tools/prebuilt-common.sh.
+$ ./checkbuid.py # `--module clang` to build just Clang.
+# Run tests.
+```
+
+## Binutils
+
+Binutils is built using the [build.py] script in the toolchain/binutils.
+
+Unlike Clang, binutils can be built from the NDK tree. The output tarball is
+extracted to `prebuilts/ndk/binutils/$HOST/binutils-$ARCH-$HOST`. Like Clang,
+this is built with `checkbuild.py toolchain`.
+
+[build.py]: https://android.googlesource.com/toolchain/binutils/+/master/build.py
+
+### Testing Local Changes
+
+To test a GCC you just built:
+
+```bash
+$ export INSTALL_DIR=`realpath ../prebuilts/ndk/binutils/$HOST`
+$ rm -r INSTALL_DIR/binutils-$ARCH-$HOST
+$ unzip ../out/dist/binutils-$ARCH-$HOST.zip -d $INSTALL_DIR
+$ ./checkbuild.py
+# Run tests.
+```
+
+For details about running tests, see [Testing.md].
+
+Since the NDK is already built, additional changes will not require a full
+`checkbuild.py`. Instead:
+
+```bash
+$ ./checkbuild.py toolchain
+# Run tests.
+```
+
+### Updating to a New Binutils
+
+```bash
+$ ../prebuilts/ndk/update_binutils.py $BUILD_NUMBER
+$ ./checkbuild.py
+# Run tests.
+```
diff --git a/docs/UnifiedHeaders.md b/docs/UnifiedHeaders.md
new file mode 100644
index 0000000..2ae0024
--- /dev/null
+++ b/docs/UnifiedHeaders.md
@@ -0,0 +1,27 @@
+# Unified Headers
+
+[Issue #120](https://github.com/android-ndk/ndk/issues/120)
+
+Before NDK r14, we had a set of libc headers for each API version. In many cases
+these headers were incorrect. Many exposed APIs that didn't exist, and others
+didn't expose APIs that did.
+
+In NDK r14 (as an opt in feature) we unified these into a single set of headers,
+called unified headers. This single header path is used for *every* platform
+level. API level guards are handled with `#ifdef`. These headers can be found in
+[prebuilts/ndk/platform/sysroot].
+
+Unified headers are built directly from the Android platform, so they are up to
+date and correct (or at the very least, any bugs in the NDK headers will also be
+a bug in the platform headers, which means we're much more likely to find them).
+
+In r15 unified headers are used by default. In r16, the old headers have been
+removed.
+
+[prebuilts/ndk/headers]: https://android.googlesource.com/platform/prebuilts/ndk/+/dev/platform/sysroot/usr/include
+
+## Supporting Unified Headers in Your Build System
+
+See the [Build System Maintainers] doc.
+
+[Build System Maintainers]: BuildSystemMaintainers.md
diff --git a/docs/UnifiedHeadersMigration.md b/docs/UnifiedHeadersMigration.md
new file mode 100644
index 0000000..5affb40
--- /dev/null
+++ b/docs/UnifiedHeadersMigration.md
@@ -0,0 +1,261 @@
+Unified Headers Migration Notes
+===============================
+
+When moving to unified headers, you may notice some differences. The unified
+headers represent nearly ten years of progress in the bionic header files, and
+in that time there have been a large number of cleanups (largely done for the
+sake of better compile times or better compatibility with other C libraries).
+
+To get an idea of what has changed, we can generate a standalone toolchain using
+both the unified headers and the deprecated headers, and then diff the list of
+files in `sysroot/usr/include`.
+
+List generated with:
+
+```bash
+$ android-ndk-r15/build/tools/make_standalone_toolchain.py \
+ --arch arm --api 26 --install-dir unified-toolchain
+$ android-ndk-r15/build/tools/make_standalone_toolchain.py \
+ --arch arm --api 26 --deprecated-headers --install-dir deprecated-toolchain
+$ (cd unified-toolchain/sysroot/usr/include/ && find . -type f) | \
+ grep -v 'linux-android' | sort > unified-include
+$ (cd deprecated-toolchain/sysroot/usr/include/ && find . -type f) | \
+ sort > arm-26-include
+$ diff -u0 arm-26-include unified-include | grep -vP '^@@'
+```
+
+The list below has been reorganized to group logical changes together for
+explanation.
+
+The same steps can be repeated with your target architecure or API level to get
+information tailored for your application.
+
+Note that the diff of the file contents themselves will be very large. Anything
+in the `linux/` directory will be very difficult to read, as those files contain
+an "AUTOGENERATED" warning every five lines. Those headers are the Linux UAPI
+headers, so they shouldn't contain any surprises.
+
+If your build is failing because a header has disappeared, use grep to search
+for the functions you're missing; they've likely only moved. If anything is
+actually missing, that may have been intentional, but could be an oversight.
+Search our [bugtracker] for both the name of the header and the functions you
+need. If you don't find anything (make sure you're searching *all* bugs, not
+just open ones), file a bug. It may be intentional, but the bug serves as
+documentation either way.
+
+One such header that was intentionally removed is ``. This was
+already not available for newer API levels when using the deprecated headers,
+but with unified headers it is not available for any API level. The NDK has
+support for C11 ``, so you should migrate to that.
+
+[bugtracker]: https://github.com/android-ndk/ndk/issues
+
+
+New APIs
+--------
+
+```diff
++./aaudio/AAudio.h
++./android/hardware_buffer.h
++./android/hardware_buffer_jni.h
++./android/sharedmem.h
++./android/sync.h
++./GLES/egl.h
+```
+
+The headers for these APIs will exist regardless of your target API level so you
+can access constants, prototypes, or types when conditionally accessing the API
+behind version checks with `dlsym`.
+
+
+Legacy Support
+--------------
+
+```diff
++./android/legacy_errno_inlines.h
++./android/legacy_fenv_inlines_arm.h
++./android/legacy_fenv_inlines_mips.h
++./android/legacy_signal_inlines.h
++./android/legacy_stdlib_inlines.h
++./android/legacy_sys_stat_inlines.h
++./android/legacy_sys_wait_inlines.h
++./android/legacy_termios_inlines.h
+```
+
+Many functions in older bionic headers were provided as inline functions. This
+is not standards compliant, so this has been fixed in later releases. These
+headers provide those inlines if you're targeting an older release.
+
+
+Linux UAPI Headers
+------------------
+
+```diff
++linux/...
+-linux/...
+```
+
+These are all changes in the Linux UAPI headers. These are the headers provided
+by the Linux kernel as a backward compatible kernel API. Any changes here are
+due to changes upstream.
+
+
+Everything Else
+---------------
+
+The rest of the list is just the usual additions and cleanups to libc headers.
+Many headers were added, some were removed. Headers that were removed were
+typically removed because they were unique to Android, and we moved the contents
+to match other C libraries.
+
+```diff
++./android/set_abort_message.h
++./android/versioning.h
+-./asm/a.out.h
++./asm/unistd-common.h
++./asm/unistd-eabi.h
++./asm/unistd-oabi.h
++./bits/auxvec.h
++./bits/elf_arm64.h
++./bits/elf_arm.h
++./bits/elf_mips.h
++./bits/elf_x86_64.h
++./bits/elf_x86.h
++./bits/fcntl.h
++./bits/getopt.h
++./bits/glibc-syscalls.h
++./bits/ioctl.h
++./bits/lockf.h
++./bits/mbstate_t.h
++./bits/posix_limits.h
++./bits/pthread_types.h
++./bits/sa_family_t.h
++./bits/seek_constants.h
++./bits/strcasecmp.h
++./bits/struct_file.h
++./bits/sysconf.h
++./bits/timespec.h
++./bits/wchar_limits.h
++./bits/wctype.h
++./cpio.h
++./drm/amdgpu_drm.h
++./drm/armada_drm.h
++./drm/drm_fourcc.h
++./drm/drm.h
++./drm/drm_mode.h
++./drm/drm_sarea.h
++./drm/etnaviv_drm.h
++./drm/exynos_drm.h
++./drm/i810_drm.h
++./drm/i915_drm.h
++./drm/mga_drm.h
++./drm/msm_drm.h
++./drm/nouveau_drm.h
++./drm/omap_drm.h
++./drm/qxl_drm.h
++./drm/r128_drm.h
++./drm/radeon_drm.h
++./drm/savage_drm.h
++./drm/sis_drm.h
++./drm/tegra_drm.h
++./drm/vc4_drm.h
++./drm/vgem_drm.h
++./drm/via_drm.h
++./drm/virtgpu_drm.h
++./drm/vmwgfx_drm.h
++./error.h
++./ifaddrs.h
++./langinfo.h
+-./machine/elf_machdep.h
+-./machine/endian.h
+-./machine/exec.h
+-./machine/ieee.h
+-./machine/wchar_limits.h
++./misc/cxl.h
++./mtd/inftl-user.h
++./mtd/mtd-abi.h
++./mtd/mtd-user.h
++./mtd/nftl-user.h
++./mtd/ubi-user.h
+-./net/ethertypes.h
+-./net/if_ether.h
+-./net/if_ieee1394.h
+-./net/if_types.h
+-./nsswitch.h
++./nl_types.h
+-./pathconf.h
++./pty.h
++./rdma/cxgb3-abi.h
++./rdma/cxgb4-abi.h
++./rdma/hfi/hfi1_user.h
++./rdma/hns-abi.h
++./rdma/ib_user_cm.h
++./rdma/ib_user_mad.h
++./rdma/ib_user_sa.h
++./rdma/ib_user_verbs.h
++./rdma/mlx4-abi.h
++./rdma/mlx5-abi.h
++./rdma/mthca-abi.h
++./rdma/nes-abi.h
++./rdma/ocrdma-abi.h
++./rdma/qedr-abi.h
++./rdma/rdma_netlink.h
++./rdma/rdma_user_cm.h
++./rdma/rdma_user_rxe.h
++./rdma/vmw_pvrdma-abi.h
++./scsi/cxlflash_ioctl.h
++./scsi/fc/fc_els.h
++./scsi/fc/fc_fs.h
++./scsi/fc/fc_gs.h
++./scsi/fc/fc_ns.h
++./scsi/scsi_bsg_fc.h
++./scsi/scsi.h
++./scsi/scsi_ioctl.h
++./scsi/scsi_netlink_fc.h
++./scsi/scsi_netlink.h
++./scsi/scsi_proto.h
++./scsi/sg.h
+-./sgtty.h
++./sound/asequencer.h
++./sound/asoc.h
++./sound/asound_fm.h
++./sound/asound.h
++./sound/compress_offload.h
++./sound/compress_params.h
++./sound/emu10k1.h
++./sound/firewire.h
++./sound/hdsp.h
++./sound/hdspm.h
++./sound/sb16_csp.h
++./sound/sfnt_info.h
++./sound/snd_sst_tokens.h
++./sound/tlv.h
++./sound/usb_stream.h
++./stdio_ext.h
++./syscall.h
+-./sys/cdefs_elf.h
++./sysexits.h
++./sys/fcntl.h
+-./sys/glibc-syscalls.h
+-./sys/ioctl_compat.h
++./sys/quota.h
+-./sys/socketcalls.h
+-./sys/syslimits.h
++./sys/syslog.h
++./sys/_system_properties.h
+-./sys/ttychars.h
+-./sys/ttydev.h
++./sys/unistd.h
+-./sys/utime.h
++./tar.h
+-./thread_db.h
+-./util.h
++./video/edid.h
++./video/sisfb.h
++./video/uvesafb.h
++./wait.h
++./xen/evtchn.h
++./xen/gntalloc.h
++./xen/gntdev.h
++./xen/privcmd.h
+```
diff --git a/docs/UpdatingDocumentation.md b/docs/UpdatingDocumentation.md
new file mode 100644
index 0000000..ed9b43d
--- /dev/null
+++ b/docs/UpdatingDocumentation.md
@@ -0,0 +1,19 @@
+Updating Documentation
+======================
+
+The documentation in [docs/user](user) is a subset of the guides that are
+present on the [developer website]. It will some day be all the guides, but
+we're doing this piece by piece.
+
+[developer website]: https://developer.android.com/ndk/guides/index.html
+
+To update the documentation, edit the appropriate Markdown file. For
+https://developer.android.com/ndk/guides/StandaloneToolchain.html, edit
+[docs/user/StandaloneToolchain.md](user/StandaloneToolchain.md). The page layout
+is handled by [docs/user/dac\_template.jd](user/dac_template.jd), but that
+should not be altered unless the layout of DAC is changed.
+
+The docs are not automatically pushed to the website. A Googler will need to run
+`scripts/update_dac.py` to publish changes. Googlers: simply run this script
+with the path to the root of your docs tree as the argument, make the commit,
+and upload the patch.
diff --git a/docs/changelogs/Changelog-r19.md b/docs/changelogs/Changelog-r19.md
new file mode 100644
index 0000000..c01e4a9
--- /dev/null
+++ b/docs/changelogs/Changelog-r19.md
@@ -0,0 +1,196 @@
+Changelog
+=========
+
+Report issues to [GitHub].
+
+For Android Studio issues, follow the docs on the [Android Studio site].
+
+[GitHub]: https://github.com/android-ndk/ndk/issues
+[Android Studio site]: http://tools.android.com/filing-bugs
+
+Announcements
+-------------
+
+ * Developers should begin testing their apps with [LLD](https://lld.llvm.org/).
+ AOSP has switched to using LLD by default and the NDK will use it by default
+ in the next release. BFD and Gold will be removed once LLD has been through a
+ release cycle with no major unresolved issues (estimated r21). Test LLD in
+ your app by passing `-fuse-ld=lld` when linking.
+
+ Note: lld does not currently support compressed symbols on Windows. See
+ [Issue 888]. Clang also cannot generate compressed symbols on Windows, but
+ this can be a problem when using artifacts built from Darwin or Linux.
+
+ * The Play Store will require 64-bit support when uploading an APK beginning in
+ August 2019. Start porting now to avoid surprises when the time comes. For
+ more information, see [this blog post](https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html).
+
+ * [Issue 780]: [Standalone toolchains] are now unnecessary. Clang, binutils,
+ the sysroot, and other toolchain pieces are now all installed to
+ `$NDK/toolchains/llvm/prebuilt/` and Clang will automatically find
+ them. Instead of creating a standalone toolchain for API 26 ARM, instead
+ invoke the compiler directly from the NDK:
+
+ $ $NDK/toolchains/llvm/prebuilt//bin/armv7a-linux-androideabi26-clang++ src.cpp
+
+ For r19 the toolchain is also installed to the old path to give build systems
+ a chance to adapt to the new layout. The old paths will be removed in r20.
+
+ The `make_standalone_toolchain.py` script will not be removed. It is now
+ unnecessary and will emit a warning with the above information, but the
+ script will remain to preserve existing workflows.
+
+ If you're using ndk-build, CMake, or a standalone toolchain, there should be
+ no change to your workflow. This change is meaningful for maintainers of
+ third-party build systems, who should now be able to delete some
+ Android-specific code. For more information, see the [Build System
+ Maintainers] guide.
+
+ * ndk-depends has been removed. We believe that [ReLinker] is a better
+ solution to native library loading issues on old Android versions.
+
+ * [Issue 862]: The GCC wrapper scripts which redirected to Clang have been
+ removed, as they are not functional enough to be drop in replacements.
+
+[Build System Maintainers]: https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md
+[Issue 780]: https://github.com/android-ndk/ndk/issues/780
+[Issue 862]: https://github.com/android-ndk/ndk/issues/862
+[ReLinker]: https://github.com/KeepSafe/ReLinker
+[Standalone toolchains]: https://developer.android.com/ndk/guides/standalone_toolchain
+
+r19c
+----
+
+ * [Issue 912]: Prevent the CMake toolchain file from clobbering a user
+ specified `CMAKE_FIND_ROOT_PATH`.
+ * [Issue 920]: Fix clang wrapper scripts on Windows.
+
+[Issue 912]: https://github.com/android-ndk/ndk/issues/912
+[Issue 920]: https://github.com/android-ndk/ndk/issues/920
+
+r19b
+----
+
+ * [Issue 855]: ndk-build automatically disables multithreaded linking for LLD
+ on Windows, where it may hang. It is not possible for the NDK to detect this
+ situation for CMake, so CMake users and custom build systems must pass
+ `-Wl,--no-threads` when linking with LLD on Windows.
+ * [Issue 849]: Fixed unused command line argument warning when using standalone
+ toolchains to compile C code.
+ * [Issue 890]: Fixed `CMAKE_FIND_ROOT_PATH`. CMake projects will no longer
+ search the host's sysroot for headers and libraries.
+ * [Issue 906]: Explicitly set `-march=armv7-a` for 32-bit ARM to workaround
+ Clang not setting that flag automatically when using `-fno-integrated-as`.
+ This fix only affects ndk-build and CMake. Standalone toolchains and custom
+ build systems will need to apply this fix themselves.
+ * [Issue 907]: Fixed `find_path` for NDK headers in CMake.
+
+[Issue 849]: https://github.com/android-ndk/ndk/issues/849
+[Issue 890]: https://github.com/android-ndk/ndk/issues/890
+[Issue 907]: https://github.com/android-ndk/ndk/issues/907
+
+Changes
+-------
+
+ * Updated Clang to r339409.
+ * C++ compilation now defaults to C++14.
+ * [Issue 780]: A complete NDK toolchain is now installed to the Clang
+ directory. See the announcements section for more information.
+ * ndk-build no longer removes artifacts from `NDK_LIBS_OUT` for ABIs not
+ present in `APP_ABI`. This enables workflows like the following:
+
+ ```bash
+ for abi in armeabi-v7a arm64-v8a x86 x86_64; do
+ ndk-build APP_ABI=$abi
+ done
+ ```
+
+ Prior to this change, the above workflow would remove the previously built
+ ABI's artifacts on each successive build, resulting in only x86_64 being
+ present at the end of the loop.
+ * ndk-stack has been rewritten in Python.
+ * [Issue 776]: To better support LLD, ndk-build and CMake no longer pass
+ `-Wl,--fix-cortex-a8` by default.
+ * CPUs that require this fix are uncommon in the NDK's supported API range
+ (16+).
+ * If you need to continue supporting these devices, add
+ `-Wl,--fix-cortex-a8` to your `APP_LDFLAGS` or `CMAKE_C_FLAGS`, but note
+ that LLD will not be adding support for this workaround.
+ * Alternatively, use the Play Console to [exclude] Cortex-A8 CPUs to
+ disallow your app from being installed on those devices.
+ * [Issue 798]: The ndk-build and CMake options to disable RelRO and noexecstack
+ are now ignored. All code is built with RelRO and non-executable stacks.
+ * [Issue 294]: All code is now built with a subset of [compiler-rt] to provide
+ a complete set of compiler built-ins for Clang.
+
+[Issue 294]: https://github.com/android-ndk/ndk/issues/294
+[Issue 776]: https://github.com/android-ndk/ndk/issues/776
+[Issue 798]: https://github.com/android-ndk/ndk/issues/798
+[exclude]: https://support.google.com/googleplay/android-developer/answer/7353455?hl=en
+[compiler-rt]: https://compiler-rt.llvm.org/
+
+Known Issues
+------------
+
+ * This is not intended to be a comprehensive list of all outstanding bugs.
+ * [Issue 888]: lld does not support compressed symbols on Windows. Clang also
+ cannot generate compressed symbols on Windows, but this can be a problem when
+ using artifacts built from Darwin or Linux.
+ * [Issue 360]: `thread_local` variables with non-trivial destructors will cause
+ segfaults if the containing library is `dlclose`ed on devices running M or
+ newer, or devices before M when using a static STL. The simple workaround is
+ to not call `dlclose`.
+ * [Issue 70838247]: Gold emits broken debug information for AArch64. AArch64
+ still uses BFD by default.
+ * [Issue 855]: LLD may hang on Windows when using multithreaded linking.
+ ndk-build will automatically disable multithreaded linking in this situation,
+ but CMake users and custom build systems should pass `-Wl,--no-threads` when
+ using LLD on Windows. The other linkers and operating systems are unaffected.
+ * [Issue 884]: Third-party build systems must pass `-fno-addrsig` to Clang for
+ compatibility with binutils. ndk-build, CMake, and standalone toolchains
+ handle this automatically.
+ * [Issue 906]: Clang does not pass `-march=armv7-a` to the assembler when using
+ `-fno-integrated-as`. This results in the assembler generating ARMv5
+ instructions. Note that by default Clang uses the integrated assembler which
+ does not have this problem. To workaround this issue, explicitly use
+ `-march=armv7-a` when building for 32-bit ARM with the non-integrated
+ assembler, or use the integrated assembler. ndk-build and CMake already
+ contain these workarounds.
+ * [Issue 988]: Exception handling when using ASan via wrap.sh can crash. To
+ workaround this issue when using libc++_shared, ensure that your
+ application's libc++_shared.so is in `LD_PRELOAD` in your `wrap.sh` as in the
+ following example:
+
+ ```bash
+ #!/system/bin/sh
+ HERE="$(cd "$(dirname "$0")" && pwd)"
+ export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1
+ ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so)
+ if [ -f "$HERE/libc++_shared.so" ]; then
+ # Workaround for https://github.com/android-ndk/ndk/issues/988.
+ export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so"
+ else
+ export LD_PRELOAD="$ASAN_LIB"
+ fi
+ "$@"
+ ```
+
+ There is no known workaround for libc++_static.
+
+ Note that because this is a platform bug rather than an NDK bug this
+ workaround will be necessary for this use case to work on all devices until
+ at least Android R.
+ * This version of the NDK is incompatible with the Android Gradle plugin
+ version 3.0 or older. If you see an error like
+ `No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android`,
+ update your project file to [use plugin version 3.1 or newer]. You will also
+ need to upgrade to Android Studio 3.1 or newer.
+
+[Issue 360]: https://github.com/android-ndk/ndk/issues/360
+[Issue 70838247]: https://issuetracker.google.com/70838247
+[Issue 855]: https://github.com/android-ndk/ndk/issues/855
+[Issue 884]: https://github.com/android-ndk/ndk/issues/884
+[Issue 888]: https://github.com/android-ndk/ndk/issues/888
+[Issue 906]: https://github.com/android-ndk/ndk/issues/906
+[Issue 988]: https://github.com/android-ndk/ndk/issues/988
+[use plugin version 3.1 or newer]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin
diff --git a/docs/changelogs/Changelog-r20.md b/docs/changelogs/Changelog-r20.md
new file mode 100644
index 0000000..602b336
--- /dev/null
+++ b/docs/changelogs/Changelog-r20.md
@@ -0,0 +1,103 @@
+# Changelog
+
+Report issues to [GitHub].
+
+For Android Studio issues, follow the docs on the [Android Studio site].
+
+[GitHub]: https://github.com/android-ndk/ndk/issues
+[Android Studio site]: http://tools.android.com/filing-bugs
+
+## Announcements
+
+ * [LLD](https://lld.llvm.org/) is now available for testing. AOSP is in the
+ process of switching to using LLD by default and the NDK will follow
+ (timeline unknown). Test LLD in your app by passing `-fuse-ld=lld` when
+ linking.
+
+ * The Play Store will require 64-bit support when uploading an APK beginning in
+ August 2019. Start porting now to avoid surprises when the time comes. For
+ more information, see [this blog post](https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html).
+
+## Changes
+
+ * Updated Clang to r346389c.
+ * Updated libc++ to r350972.
+ * [Issue 908]: `LOCAL_LDFLAGS` now take precedence over `APP_LDFLAGS`.
+
+[Issue 908]: https://github.com/android-ndk/ndk/issues/908
+
+## Known Issues
+
+ * This is not intended to be a comprehensive list of all outstanding bugs.
+ * [Issue 360]: `thread_local` variables with non-trivial destructors will cause
+ segfaults if the containing library is `dlclose`ed on devices running M or
+ newer, or devices before M when using a static STL. The simple workaround is
+ to not call `dlclose`.
+ * [Issue 70838247]: Gold emits broken debug information for AArch64. AArch64
+ still uses BFD by default.
+ * [Issue 855]: LLD may hang on Windows when using multithreaded linking.
+ ndk-build will automatically disable multithreaded linking in this situation,
+ but CMake users and custom build systems should pass `-Wl,--no-threads` when
+ using LLD on Windows. The other linkers and operating systems are unaffected.
+ * [Issue 884]: Third-party build systems must pass `-fno-addrsig` to Clang for
+ compatibility with binutils. ndk-build, CMake, and standalone toolchains
+ handle this automatically.
+ * [Issue 888]: lld does not support compressed symbols on Windows. Clang also
+ cannot generate compressed symbols on Windows, but this can be a problem when
+ using artifacts built from Darwin or Linux.
+ * [Issue 906]: Clang does not pass `-march=armv7-a` to the assembler when using
+ `-fno-integrated-as`. This results in the assembler generating ARMv5
+ instructions. Note that by default Clang uses the integrated assembler which
+ does not have this problem. To workaround this issue, explicitly use
+ `-march=armv7-a` when building for 32-bit ARM with the non-integrated
+ assembler, or use the integrated assembler. ndk-build and CMake already
+ contain these workarounds.
+ * [Issue 906]: Clang does not pass `-march=armv7-a` to the assembler when using
+ `-fno-integrated-as`. This results in the assembler generating ARMv5
+ instructions. Note that by default Clang uses the integrated assembler which
+ does not have this problem. To workaround this issue, explicitly use
+ `-march=armv7-a` when building for 32-bit ARM with the non-integrated
+ assembler, or use the integrated assembler. ndk-build and CMake already
+ contain these workarounds.
+ * [Issue 988]: Exception handling when using ASan via wrap.sh can crash. To
+ workaround this issue when using libc++_shared, ensure that your
+ application's libc++_shared.so is in `LD_PRELOAD` in your `wrap.sh` as in the
+ following example:
+
+ ```bash
+ #!/system/bin/sh
+ HERE="$(cd "$(dirname "$0")" && pwd)"
+ export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1
+ ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so)
+ if [ -f "$HERE/libc++_shared.so" ]; then
+ # Workaround for https://github.com/android-ndk/ndk/issues/988.
+ export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so"
+ else
+ export LD_PRELOAD="$ASAN_LIB"
+ fi
+ "$@"
+ ```
+
+ There is no known workaround for libc++_static.
+
+ Note that because this is a platform bug rather than an NDK bug this
+ workaround will be necessary for this use case to work on all devices until
+ at least Android R.
+ * [Issue 1004]: Clang outputs debug info with bad line number info when
+ compiling for ARM64 and `-O0` (no optimizations). Third-party build systems
+ can pass `-fno-experimental-isel` to Clang to work around this issue.
+ * This version of the NDK is incompatible with the Android Gradle plugin
+ version 3.0 or older. If you see an error like
+ `No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android`,
+ update your project file to [use plugin version 3.1 or newer]. You will also
+ need to upgrade to Android Studio 3.1 or newer.
+
+[Issue 360]: https://github.com/android-ndk/ndk/issues/360
+[Issue 70838247]: https://issuetracker.google.com/70838247
+[Issue 855]: https://github.com/android-ndk/ndk/issues/855
+[Issue 884]: https://github.com/android-ndk/ndk/issues/884
+[Issue 888]: https://github.com/android-ndk/ndk/issues/888
+[Issue 906]: https://github.com/android-ndk/ndk/issues/906
+[Issue 988]: https://github.com/android-ndk/ndk/issues/988
+[Issue 1004]: https://github.com/android-ndk/ndk/issues/1004
+[use plugin version 3.1 or newer]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin
diff --git a/docs/changelogs/Changelog-r21.md b/docs/changelogs/Changelog-r21.md
new file mode 100644
index 0000000..73dda09
--- /dev/null
+++ b/docs/changelogs/Changelog-r21.md
@@ -0,0 +1,271 @@
+# Changelog
+
+Report issues to [GitHub].
+
+For Android Studio issues, follow the docs on the [Android Studio site].
+
+[GitHub]: https://github.com/android-ndk/ndk/issues
+[Android Studio site]: http://tools.android.com/filing-bugs
+
+## Announcements
+
+ * 32-bit Windows is no longer supported. This does not affect the vast majority
+ of users. If you do still need to build NDK apps from 32-bit versions of
+ Windows, continue using NDK r20.
+
+ For more information on this change within Android Developer tools, see the
+ [blog post] on the topic.
+
+[blog post]: https://android-developers.googleblog.com/2019/06/moving-android-studio-and-android.html
+
+ * macOS 10.8 is no longer supported as of r21b (r21 supports 10.8). macOS 10.15
+ requires that binaries be notarized, and notarization is only supported for
+ binaries built for 10.9 or newer.
+
+ * [LLD](https://lld.llvm.org/) is now available for testing. AOSP has switched
+ to using LLD by default and the NDK will follow (timeline unknown). Test LLD
+ in your app by passing `-fuse-ld=lld` when linking. Note that [Issue 843]
+ will affect builds using LLD with binutils strip and objcopy as opposed to
+ llvm-strip and llvm-objcopy.
+
+ * The legacy toolchain install paths will be removed over the coming releases.
+ These paths have been obsolete since NDK r19 and take up a considerable
+ amount of space in the NDK. The paths being removed are:
+
+ * platforms
+ * sources/cxx-stl
+ * sysroot
+ * toolchains (with the exception of toolchains/llvm)
+
+ In general this change should only affect build system maintainers, or those
+ using build systems that are not up to date. ndk-build and the CMake
+ toolchain users are unaffected, and neither are
+ `make_standalone_toolchain.py` users (though that script has been unnecessary
+ since r19).
+
+ For information on migrating away from the legacy toolchain layout, see the
+ [Build System Maintainers Guide] for the NDK version you're using.
+
+ * The Play Store will require 64-bit support when uploading an APK beginning in
+ August 2019. Start porting now to avoid surprises when the time comes. For
+ more information, see [this blog post](https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html).
+
+[Build System Maintainers Guide]: https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md
+
+## r21e
+
+ * [Issue 147772940]: Passing `APP_BUILD_SCRIPT` to ndk-build with a file named
+ something other than Android.mk works again.
+
+[Issue 147772940]: https://issuetracker.google.com/147772940
+
+## r21c
+
+ * [Issue 1060]: A macOS app bundle that is signed and notarized is now
+ available for download from our wiki and our website. Note that because only
+ bundles may use RPATHs and pass notarization, the traditional NDK package for
+ macOS **cannot* be notarized. The SDK will continue to use the traditional
+ package as the app bundle requires layout changes that would make it
+ incompatible with Android Studio. The NDK is not quarantined when it is
+ downloaded via the SDK manager, so is curently allowed by Gatekeeper.
+
+ **The SDK manager is currently the most reliable way to get the NDK for
+ macOS.**
+
+ * [Issue 1207]: Fix fatal error in clang when building with -O2 on arm64.
+
+ * [Issue 1239]: Fix network drive issues for clang.
+
+ * [Issue 1229]: README.md turned back to ordinary file.
+
+[Issue 1060]: https://github.com/android/ndk/issues/1060
+[Issue 1207]: https://github.com/android/ndk/issues/1207
+[Issue 1239]: https://github.com/android/ndk/issues/1239
+[Issue 1229]: https://github.com/android/ndk/issues/1229
+
+## r21b
+
+ * Fixed debugging processes containing Java with gdb. Cherrypicked
+ "gdb: Don't fault for 'maint print psymbols' when using an index", which
+ fixes a bug that caused gdb to fail when debugging a process with Java.
+ Pure C/C++ executables were fine, but this effectively broke all app
+ debugging. The error from gdb that confirms you were affected by this was
+ `gdb-8.3/gdb/psymtab.c:316: internal-error: sect_index_text not initialized`.
+ * [Issue 1166]: Rehid unwinder symbols all architectures.
+ * [Issue 1173]: Fix gdb python symbol missing issue on Darwin.
+ * [Issue 1176]: Fix strip failing with "File truncated" errors on Windows.
+ * [Issue 1178]: Revert changes to stdatomic.h to maintain compatibility with
+ C's `_Atomic` type qualifier. Note that the C++ standard will likely mandate
+ this breakage in the future. See [P0943R4] for more details.
+ * [Issue 1184]: Fix Clang crash for x86_64.
+ * [Issue 1198]: Fix incorrect constant folding of long doubles on Windows.
+ * [Issue 1201]: Fixed issue in ndk-build that was causing `APP_PLATFORM` to be
+ corrupted for API 30+ with LP64 ABIs.
+ * [Issue 1203]: libc++ prebuilts and CRT objects are no longer built as Neon.
+ * [Issue 1205]: Potential fixes for relocation out of range issues with LLD.
+ * [Issue 1206]: LLD support for --fix-cortex-a8.
+
+[Issue 1166]: https://github.com/android/ndk/issues/1166
+[Issue 1173]: https://github.com/android/ndk/issues/1173
+[Issue 1176]: https://github.com/android/ndk/issues/1176
+[Issue 1178]: https://github.com/android/ndk/issues/1178
+[Issue 1184]: https://github.com/android/ndk/issues/1184
+[Issue 1198]: https://github.com/android/ndk/issues/1198
+[Issue 1201]: https://github.com/android/ndk/issues/1201
+[Issue 1203]: https://github.com/android/ndk/issues/1203
+[Issue 1205]: https://github.com/android/ndk/issues/1205
+[Issue 1206]: https://github.com/android/ndk/issues/1206
+[P0943R4]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0943r4.html
+
+## Changes
+
+ * Updated Clang and LLD to r365631.
+ * [Issue 855]: LLD no longer hangs when using multithreaded linking on
+ Windows.
+ * [Issue 884]: Clang no longer passes `-faddrsig` by default.
+ * [Issue 859]: Clang now default to using Neon for all 32-bit Android Arm
+ targets.
+ * If your minSdkVersion is 23 or higher, or if you were already
+ enabling Neon manually, this change does not affect you.
+ * CPUs that do not support this feature are uncommon.
+ * If you need to continue supporting these devices you can disable
+ Neon explicitly by setting `LOCAL_ARM_NEON := false` in ndk-build or
+ passing `-DANDROID_ARM_NEON=false` to CMake.
+ * Alternatively, use the Play Console to [exclude CPUs] without
+ Neon to disallow your app from being installed on those devices.
+ * [Issue 1004]: Fixed bug with bad line number information when building
+ Arm64 with `-O0`.
+ * [Issue 1028]: OpenMP is now available in both static and shared variants.
+ Note that shared is the default behavior, but in prior NDK releases the
+ static library would be used because there was no shared library. To keep
+ the old behavior, link with `-static-openmp`.
+ * Updated libc++ to r369764.
+ * Updated make to 4.2.1.
+ * Modified ndk-build to supply `-O` for more readable errors with parallel
+ builds.
+ * `abspath` now works properly with Windows drive letters, so if you're
+ using the [workaround] similar to what's found in the NDK samples, you'll
+ need to either drop the workaround or make sure it's only used prior to
+ r21.
+ * Updated glibc to 2.17.
+ * Updated gdb to 8.3.
+ * [Issue 885]: For LLD+LLDB compatibility, the NDK build systems now pass
+ `-Wl,--build-id=sha1` instead of `-Wl,--build-id` when using LLD. Note that
+ the CMake toolchain does not have access to flags set in CMakeLists.txt, so
+ using an explicit `-fuse-ld=lld` instead of `ANDROID_LD=lld` will produce
+ output that cannot be debugged with Android Studio. Third-party build systems
+ need to apply the workaround manually. For more details, see the [Build
+ System Maintainers Guide][maintainer_linkers].
+ * Fixed ndk-build to use Clang's default C++ standard version (currently C++14)
+ when using libc++.
+ * Removed the `cxx-stl/system` module from ndk-build. The system STL is still
+ available (for now, see [Issue 744]); only an implementation detail has been
+ removed. If you were explicitly linking libstdc++ or importing
+ `cxx-stl/system`, remove that and ensure that `APP_STL` is set to `system`
+ instead.
+ * [Issue 976]: ndk-build and the CMake toolchain file now enable
+ `_FORTIFY_SOURCE` by default. See [FORTIFY in Android] for more details.
+ * Added `NDK_GRADLE_INJECTED_IMPORT_PATH` support to ndk-build. This is to
+ support import of dependencies from AAR dependencies. See [Issue 916] for
+ more information.
+ * Added `NDK_MAJOR`, `NDK_MINOR`, `NDK_BETA`, `NDK_CANARY`, and
+ `ndk-major-at-least` APIs to ndk-build. These can be used to check what
+ version of the NDK you are using from within ndk-build (CMake already has
+ equivalent APIs). The first three are integers, `NDK_CANARY` is either `true`
+ or `false`, and `ndk-major-at-least` is a function that takes a single
+ integer. For example, to check if your build is being performed with NDK r21
+ or newer:
+
+ ```makefile
+ # This check works even on pre-r21 NDKs. The function is undefined pre-r21,
+ # and calling an undefined function in make returns the empty string, which
+ # is not equal to "true", so the else branch will be taken.
+ ifeq ($(call ndk-major-at-least,21),true)
+ # Using at least NDK r21.
+ else
+ # Using something earlier than r21.
+ endif
+ ```
+
+ Note that because this API was not available before r21, it cannot be used to
+ determine *which* NDK version earlier than 21 is being used.
+ * [Issue 1092]: Fixed hiding of unwinder symbols in outputs of ndk-build and
+ CMake. Maintainers of third-party build systems should apply similar fixes
+ when using NDK r19 and above to guard against possible future compatibility
+ issues.
+
+[FORTIFY in Android]: https://android-developers.googleblog.com/2017/04/fortify-in-android.html
+[Issue 1004]: https://github.com/android-ndk/ndk/issues/1004
+[Issue 1028]: https://github.com/android/ndk/issues/1028
+[Issue 1092]: https://github.com/android/ndk/issues/1092
+[Issue 744]: https://github.com/android/ndk/issues/744
+[Issue 855]: https://github.com/android-ndk/ndk/issues/855
+[Issue 859]: https://github.com/android-ndk/ndk/issues/859
+[Issue 884]: https://github.com/android-ndk/ndk/issues/884
+[Issue 885]: https://github.com/android-ndk/ndk/issues/885
+[Issue 916]: https://github.com/android-ndk/ndk/issues/916
+[Issue 976]: https://github.com/android/ndk/issues/976
+[exclude CPUs]: https://support.google.com/googleplay/android-developer/answer/7353455?hl=en
+[maintainer_linkers]: https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#Linkers
+[workaround]: https://github.com/android/ndk-samples/blob/2c97a9eb5b9b5de233b7ece4dd0d0d28fa4cb4c2/other-builds/ndkbuild/common.mk#L26
+
+## Known Issues
+
+ * This is not intended to be a comprehensive list of all outstanding bugs.
+ * [Issue 360]: `thread_local` variables with non-trivial destructors will cause
+ segfaults if the containing library is `dlclose`ed on devices running M or
+ newer, or devices before M when using a static STL. The simple workaround is
+ to not call `dlclose`.
+ * [Issue 70838247]: Gold emits broken debug information for AArch64. AArch64
+ still uses BFD by default.
+ * [Issue 906]: Clang does not pass `-march=armv7-a` to the assembler when using
+ `-fno-integrated-as`. This results in the assembler generating ARMv5
+ instructions. Note that by default Clang uses the integrated assembler which
+ does not have this problem. To workaround this issue, explicitly use
+ `-march=armv7-a` when building for 32-bit ARM with the non-integrated
+ assembler, or use the integrated assembler. ndk-build and CMake already
+ contain these workarounds.
+ * [Issue 906]: Clang does not pass `-march=armv7-a` to the assembler when using
+ `-fno-integrated-as`. This results in the assembler generating ARMv5
+ instructions. Note that by default Clang uses the integrated assembler which
+ does not have this problem. To workaround this issue, explicitly use
+ `-march=armv7-a` when building for 32-bit ARM with the non-integrated
+ assembler, or use the integrated assembler. ndk-build and CMake already
+ contain these workarounds.
+ * [Issue 988]: Exception handling when using ASan via wrap.sh can crash. To
+ workaround this issue when using libc++_shared, ensure that your
+ application's libc++_shared.so is in `LD_PRELOAD` in your `wrap.sh` as in the
+ following example:
+
+ ```bash
+ #!/system/bin/sh
+ HERE="$(cd "$(dirname "$0")" && pwd)"
+ export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1
+ ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so)
+ if [ -f "$HERE/libc++_shared.so" ]; then
+ # Workaround for https://github.com/android-ndk/ndk/issues/988.
+ export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so"
+ else
+ export LD_PRELOAD="$ASAN_LIB"
+ fi
+ "$@"
+ ```
+
+ There is no known workaround for libc++_static.
+
+ Note that because this is a platform bug rather than an NDK bug this
+ workaround will be necessary for this use case to work on all devices until
+ at least Android R.
+ * This version of the NDK is incompatible with the Android Gradle plugin
+ version 3.0 or older. If you see an error like
+ `No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android`,
+ update your project file to [use plugin version 3.1 or newer]. You will also
+ need to upgrade to Android Studio 3.1 or newer.
+ * [Issue 843]: Using LLD with binutils `strip` or `objcopy` breaks RelRO.
+
+[Issue 360]: https://github.com/android-ndk/ndk/issues/360
+[Issue 70838247]: https://issuetracker.google.com/70838247
+[Issue 843]: https://github.com/android-ndk/ndk/issues/843
+[Issue 906]: https://github.com/android-ndk/ndk/issues/906
+[Issue 988]: https://github.com/android-ndk/ndk/issues/988
+[use plugin version 3.1 or newer]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin
diff --git a/docs/changelogs/Changelog-r22.md b/docs/changelogs/Changelog-r22.md
new file mode 100644
index 0000000..a63f49e
--- /dev/null
+++ b/docs/changelogs/Changelog-r22.md
@@ -0,0 +1,169 @@
+# Changelog
+
+Report issues to [GitHub].
+
+For Android Studio issues, follow the docs on the [Android Studio site].
+
+[GitHub]: https://github.com/android/ndk/issues
+[Android Studio site]: http://tools.android.com/filing-bugs
+
+## Announcements
+
+* GNU binutils is deprecated and will be removed in an upcoming NDK release.
+ Note that the GNU assembler (`as`) **is** a part of this. If you are building
+ with `-fno-integrated-as`, file bugs if anything is preventing you from
+ removing that flag. If you're using `as` directly, use `clang` instead.
+
+* [LLD](https://lld.llvm.org/) is now the default linker. ndk-build and our
+ CMake toolchain file have also migrated to using llvm-ar and llvm-strip.
+
+ See the Changes section below for more information.
+
+## Changes
+
+* Updated LLVM to r399163b, based on LLVM 11 development.
+ * [Issue 829]: Fixed issue with `__attribute__((visibility("hidden")))`
+ symbols sometimes not being hidden.
+ * [Issue 1149]: Fixed Clang crash with `#pragma detect_mismatch`.
+ * [Issue 1212]: Fixed llvm-strip to match GNU behavior for removing file
+ symbols.
+ * [Issue 1248]: Fixed LLD Neon crash.
+ * [Issue 1303]: Fixed Neon intrinsic optimizer crash.
+
+* Updated make to 4.3.
+
+* Updated libc++, libc++abi, and libunwind to
+ https://github.com/llvm/llvm-project/commit/52ec983895436089c5be0b0c4d967423db16045b.
+
+* [Issue 609]: `std::filesystem` support is now included. There are two known
+ issues:
+ * [Issue 1258]: `std::filesystem::perm_options::nofollow` may not be
+ honored on old devices.
+ * [Issue 1260]: `std::filesystem:canonical` will incorrectly succeed when
+ passed a non-existent path on old devices.
+
+* [Issue 843]: `llvm-strip` is now used instead of `strip` to avoid breaking
+ RelRO with LLD. Note that the Android Gradle Plugin performs its own
+ stripping, so most users will need to upgrade to Android Gradle Plugin
+ version 4.0 or newer to get the fix.
+
+* [Issue 929]: `find_library` now prefers shared libraries from the sysroot over
+ static libraries.
+
+* [Issue 1130]: Fixed undefined references to new that could occur when building
+ for APIs prior to 21 and the static libc++. Note that LLD appears to have been
+ unaffected, but the problem is still present for ndk-build when using the
+ deprecated linkers.
+
+* [Issue 1139]: `native_app_glue` now hooks up the `APP_CMD_WINDOW_RESIZED`,
+ `APP_CMD_WINDOW_REDRAW_NEEDED`, and `APP_CMD_CONTENT_RECT_CHANGED` messages.
+
+* [Issue 1196]: Backtraces for crashes on devices older than API 29 are now
+ correct when using LLD if using ndk-build or the CMake toolchain file. If
+ using a different system and targeting devices older than API 29, use
+ `-Wl,--no-rosegment` when linking. See the [Build System Maintainers Guide]
+ for more information.
+
+* The deprecated `/platforms` and `/sysroot` directories have been
+ removed. These directories were merged and relocated into the toolchain during
+ r19. The location of these contents should not be relevant to anyone,
+ including build systems, since the toolchain handles them implicitly. If you
+ are using a build system that hasn't adapted to the changes introduced in NDK
+ r19, file a bug with your build system maintainer. See the [Build System
+ Maintainers Guide] for information on using the NDK in your own build system.
+
+* `llvm-ar` is now used instead of `ar`.
+
+* [Issue 1200]: Fixed an issue with using `dlclose` with libraries using
+ `thread_local` with non-trivial destructors and the static libc++.
+
+* The legacy libc++ linker scripts in `/sources/cxx-stl/llvm-libc++` have
+ been removed. The linkers scripts in the toolchain should be used instead as
+ described by the [Build System Maintainers Guide].
+
+* LLD is now used by default. If your build is not yet compatible with LLD, you
+ can continue using the deprecated linkers, set `APP_LD=deprecated` for
+ ndk-build, `ANDROID_LD=deprecated` for CMake, or use an explicit
+ `-fuse-ld=gold` or `-fuse-ld=bfd` in your custom build system. If you
+ encounter issues be sure to file a bug, because this will not be an option in
+ a subsequent release.
+
+ Note that [Issue 843] will affect builds using LLD with binutils strip and
+ objcopy as opposed to llvm-strip and llvm-objcopy.
+
+* ndk-gdb now uses lldb as the debugger. gdb is deprecated and will be removed in
+ a future release. To fall back to gdb, use --no-lldb option. But please
+ [file a bug] explaining why you couldn't use lldb.
+
+[Build System Maintainers Guide]: https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md
+[Issue 609]: https://github.com/android/ndk/issues/609
+[Issue 829]: https://github.com/android/ndk/issues/829
+[Issue 929]: https://github.com/android/ndk/issues/929
+[Issue 1139]: https://github.com/android/ndk/issues/1139
+[Issue 1149]: https://github.com/android/ndk/issues/1149
+[Issue 1196]: https://github.com/android/ndk/issues/1196
+[Issue 1200]: https://github.com/android/ndk/issues/1200
+[Issue 1212]: https://github.com/android/ndk/issues/1212
+[Issue 1248]: https://github.com/android/ndk/issues/1248
+[Issue 1258]: https://github.com/android/ndk/issues/1258
+[Issue 1260]: https://github.com/android/ndk/issues/1260
+[Issue 1303]: https://github.com/android/ndk/issues/1303
+[file a bug]: https://github.com/android/ndk/issues/new/choose
+
+## Known Issues
+
+* This is not intended to be a comprehensive list of all outstanding bugs.
+* [Issue 360]: `thread_local` variables with non-trivial destructors will cause
+ segfaults if the containing library is `dlclose`ed on devices running M or
+ newer, or devices before M when using a static STL. The simple workaround is
+ to not call `dlclose`.
+* [Issue 906]: Clang does not pass `-march=armv7-a` to the assembler when using
+ `-fno-integrated-as`. This results in the assembler generating ARMv5
+ instructions. Note that by default Clang uses the integrated assembler which
+ does not have this problem. To workaround this issue, explicitly use
+ `-march=armv7-a` when building for 32-bit ARM with the non-integrated
+ assembler, or use the integrated assembler. ndk-build and CMake already
+ contain these workarounds.
+* [Issue 988]: Exception handling when using ASan via wrap.sh can crash. To
+ workaround this issue when using libc++_shared, ensure that your
+ application's libc++_shared.so is in `LD_PRELOAD` in your `wrap.sh` as in the
+ following example:
+
+ ```bash
+ #!/system/bin/sh
+ HERE="$(cd "$(dirname "$0")" && pwd)"
+ export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1
+ ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so)
+ if [ -f "$HERE/libc++_shared.so" ]; then
+ # Workaround for https://github.com/android/ndk/issues/988.
+ export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so"
+ else
+ export LD_PRELOAD="$ASAN_LIB"
+ fi
+ "$@"
+ ```
+
+ There is no known workaround for libc++_static.
+
+ Note that because this is a platform bug rather than an NDK bug this
+ workaround will be necessary for this use case to work on all devices until
+ at least Android R.
+* [Issue 1130]: When using `c++_static` and the deprecated linker with ndk-build
+ with an `APP_PLATFORM` below 21, undefined references to operator new may
+ occur. The fix is to use LLD.
+* This version of the NDK is incompatible with the Android Gradle plugin
+ version 3.0 or older. If you see an error like
+ `No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android`,
+ update your project file to [use plugin version 3.1 or newer]. You will also
+ need to upgrade to Android Studio 3.1 or newer.
+* [Issue 843]: Using LLD with binutils `strip` or `objcopy` breaks RelRO. Use
+ `llvm-strip` and `llvm-objcopy` instead. This issue has been resolved in
+ Android Gradle Plugin version 4.0 (for non-Gradle users, the fix is also in
+ ndk-build and our CMake toolchain file), but may affect other build systems.
+
+[Issue 360]: https://github.com/android/ndk/issues/360
+[Issue 843]: https://github.com/android/ndk/issues/843
+[Issue 906]: https://github.com/android/ndk/issues/906
+[Issue 988]: https://github.com/android/ndk/issues/988
+[Issue 1130]: https://github.com/android/ndk/issues/1130
+[use plugin version 3.1 or newer]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin
diff --git a/docs/changelogs/Changelog-r23.md b/docs/changelogs/Changelog-r23.md
new file mode 100644
index 0000000..df87ff0
--- /dev/null
+++ b/docs/changelogs/Changelog-r23.md
@@ -0,0 +1,78 @@
+# Changelog
+
+Report issues to [GitHub].
+
+For Android Studio issues, follow the docs on the [Android Studio site].
+
+[GitHub]: https://github.com/android/ndk/issues
+[Android Studio site]: http://tools.android.com/filing-bugs
+
+## Announcements
+
+* GNU binutils is deprecated and will be removed in an upcoming NDK release.
+ Note that the GNU assembler (`as`) **is** a part of this. If you are building
+ with `-fno-integrated-as`, file bugs if anything is preventing you from
+ removing that flag.
+
+* [LLD](https://lld.llvm.org/) is now the default linker. ndk-build and our
+ CMake toolchain file have also migrated to using llvm-ar and llvm-strip.
+
+## Changes
+
+## Known Issues
+
+* This is not intended to be a comprehensive list of all outstanding bugs.
+* [Issue 360]: `thread_local` variables with non-trivial destructors will cause
+ segfaults if the containing library is `dlclose`ed on devices running M or
+ newer, or devices before M when using a static STL. The simple workaround is
+ to not call `dlclose`.
+* [Issue 906]: Clang does not pass `-march=armv7-a` to the assembler when using
+ `-fno-integrated-as`. This results in the assembler generating ARMv5
+ instructions. Note that by default Clang uses the integrated assembler which
+ does not have this problem. To workaround this issue, explicitly use
+ `-march=armv7-a` when building for 32-bit ARM with the non-integrated
+ assembler, or use the integrated assembler. ndk-build and CMake already
+ contain these workarounds.
+* [Issue 988]: Exception handling when using ASan via wrap.sh can crash. To
+ workaround this issue when using libc++_shared, ensure that your
+ application's libc++_shared.so is in `LD_PRELOAD` in your `wrap.sh` as in the
+ following example:
+
+ ```bash
+ #!/system/bin/sh
+ HERE="$(cd "$(dirname "$0")" && pwd)"
+ export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1
+ ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so)
+ if [ -f "$HERE/libc++_shared.so" ]; then
+ # Workaround for https://github.com/android/ndk/issues/988.
+ export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so"
+ else
+ export LD_PRELOAD="$ASAN_LIB"
+ fi
+ "$@"
+ ```
+
+ There is no known workaround for libc++_static.
+
+ Note that because this is a platform bug rather than an NDK bug this
+ workaround will be necessary for this use case to work on all devices until
+ at least Android R.
+* [Issue 1130]: When using `c++_static` and the deprecated linker with ndk-build
+ with an `APP_PLATFORM` below 21, undefined references to operator new may
+ occur. The fix is to use LLD.
+* This version of the NDK is incompatible with the Android Gradle plugin
+ version 3.0 or older. If you see an error like
+ `No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android`,
+ update your project file to [use plugin version 3.1 or newer]. You will also
+ need to upgrade to Android Studio 3.1 or newer.
+* [Issue 843]: Using LLD with binutils `strip` or `objcopy` breaks RelRO. Use
+ `llvm-strip` and `llvm-objcopy` instead. This issue has been resolved in
+ Android Gradle Plugin version 4.0 (for non-Gradle users, the fix is also in
+ ndk-build and our CMake toolchain file), but may affect other build systems.
+
+[Issue 360]: https://github.com/android/ndk/issues/360
+[Issue 843]: https://github.com/android/ndk/issues/843
+[Issue 906]: https://github.com/android/ndk/issues/906
+[Issue 988]: https://github.com/android/ndk/issues/988
+[Issue 1130]: https://github.com/android/ndk/issues/1130
+[use plugin version 3.1 or newer]: https://developer.android.com/studio/releases/gradle-plugin#updating-plugin
diff --git a/docs/user/common_problems.md b/docs/user/common_problems.md
new file mode 100644
index 0000000..4778a60
--- /dev/null
+++ b/docs/user/common_problems.md
@@ -0,0 +1,179 @@
+# Common Problems and Solutions
+
+This document lists common issues that users encounter when using the NDK. It is
+by no means complete, but represents some of the most common non-bugs we see
+filed.
+
+
+## Using `_FILE_OFFSET_BITS=64` With Early API Levels
+
+Prior to [Unified Headers], the NDK did not support `_FILE_OFFSET_BITS=64`. If
+you defined it when building, it was silently ignored. With [Unified Headers]
+the `_FILE_OFFSET_BITS=64` option is now supported, but on old versions of
+Android very few of the `off_t` APIs were available as an `off64_t` variant, so
+using this feature with old API levels will result in fewer functions being
+available.
+
+This problem is explained in detail in the [r16 blog post] and in the [bionic
+documentation].
+
+[Unified Headers]: ../UnifiedHeaders.md
+[r16 blog post]: https://android-developers.googleblog.com/2017/09/introducing-android-native-development.html
+[bionic documentation]: https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md
+
+**Problem**: Your build is asking for APIs that do not exist in your
+`minSdkVersion`.
+
+**Solution**: Disable `_FILE_OFFSET_BITS=64` or raise your `minSdkVersion`.
+
+### Undeclared or implicit definition of `mmap`
+
+In C++:
+
+> error: use of undeclared identifier 'mmap'
+
+In C:
+
+> warning: implicit declaration of function 'mmap' is invalid in C99
+
+Using `_FILE_OFFSET_BITS=64` instructs the C library to use `mmap64` instead of
+`mmap`. `mmap64` was not available until android-21. If your `minSdkVersion`
+value is lower than 21, the C library does not contain an `mmap` that is
+compatible with `_FILE_OFFSET_BITS=64`, so the function is unavailable.
+
+**Note**: `mmap` is only the most common manifestation of this problem. The same
+is true of any function in the C library that has an `off_t` parameter.
+
+**Note**: As of r16 beta 2, the C library exposes `mmap64` as an inline function
+to mitigate this instance of this issue.
+
+TODO: Update this section once we know what the next most common problem is.
+
+
+## Target API Set Higher Than Device API
+
+The target API level in the NDK has a very different meaning than
+`targetSdkVersion` does in Java. The NDK target API level is your app's
+**minimum** supported API level. In ndk-build, this is your `APP_PLATFORM`
+setting.
+
+Since references to functions are (typically) resolved when a library is
+loaded rather than when they are first called, you cannot reference APIs that
+are not always present and guard their use with API level checks. If they are
+referred to at all, they must be present.
+
+**Problem**: Your target API level is higher than the API supported by your
+device.
+
+**Solution**: Set your target API level (`APP_PLATFORM`) to the minimum version
+of Android your app supports.
+
+Build System | Setting
+---------------------|-------------------
+ndk-build | `APP_PLATFORM`
+CMake | `ANDROID_PLATFORM`
+Standalone Toolchain | `--api`
+Gradle | TODO: No idea
+
+### Cannot Locate `__aeabi` Symbols
+
+> UnsatisfiedLinkError: dlopen failed: cannot locate symbol "`__aeabi_memcpy`"
+
+Note that these are *runtime* errors. These errors will appear in the log when
+you attempt to load your native libraries. The symbol might be any of
+`__aeabi_*` (`__aeabi_memcpy` and `__aeabi_memclr` seem to be the most common).
+
+This problem is documented at https://github.com/android-ndk/ndk/issues/126.
+
+### Cannot Locate Symbol `rand`
+
+> UnsatisfiedLinkError: dlopen failed: cannot locate symbol "`rand`"
+
+This problem was explained very well on Stack Overflow:
+http://stackoverflow.com/a/27338365/632035
+
+There are a handful of other symbols that are also affected by this.
+TODO: Figure out what the other ones were.
+
+
+## Undefined Reference to `__atomic_*`
+
+**Problem**: Some ABIs (particularly armeabi) need libatomic to provide some
+implementations for atomic operations.
+
+**Solution**: Add `-latomic` when linking.
+
+> error: undefined reference to '`__atomic_exchange_4`'
+
+The actual symbol here might be anything prefixed with `__atomic_`.
+
+Note that ndk-build, cmake, and libc++ standalone toolchains handle this for
+you. For non libc++ standalone toolchains or a different build system, you may
+need to do this manually.
+
+
+## RTTI/Exceptions Not Working Across Library Boundaries
+
+**Problem**: Exceptions are not being caught when thrown across shared library
+boundaries, or `dynamic_cast` is failing.
+
+**Solution**: Add a [key function] to your types. A key function is the first
+non-pure, out-of-line virtual function for a type. For an example, see the
+discussion on [Issue 533].
+
+The [C++ ABI] states that two objects have the same type if and only if their
+`type_info` pointers are identical. Exceptions may only be caught if the
+`type_info` for the catch matches the thrown exception. The same rule applies
+for `dynamic_cast`.
+
+When a type does not have a key function, its typeinfo is emitted as a weak
+symbol and matching type infos are merged when libraries are loaded. When
+loading libraries dynamically after the executable has been loaded (i.e. via
+`dlopen` or `System.loadLibrary`), it may not be possible for the loader to
+merge type infos for the loaded libraries. When this happens, the two types are
+not considered equal.
+
+Note that for non-polymorphic types, the type cannot have a key function. For
+non-polymorphic types, RTTI is unnecessary, as `std::is_same` can be used to
+determine type equality at compile time.
+
+[C++ ABI]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#rtti
+[Issue 533]: https://github.com/android-ndk/ndk/issues/533#issuecomment-335977747
+[key function]: https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vague-vtable
+
+
+## Using Mismatched Prebuilt Libraries
+
+Using prebuilt libraries (third-party libraries, typically) in your application
+requires a bit of extra care. In general, the following rules need to be
+followed:
+
+* The resulting app's minimum API level is the maximum of all API levels
+ targeted by all libraries.
+
+ If your target API level is android-9, but you're using a prebuilt library
+ that was built against android-16, the resulting app's minimum API level is
+ android-16. Failure to adhere to this will be visible at build time if the
+ prebuilt library is static, but may not appear until run time for prebuilt
+ shared libraries.
+
+* All libraries should be generated with the same NDK version.
+
+ This rule is a bit more flexible than most, but in general NDK code is only
+ guaranteed to be compatible with code generated with the same version of the
+ NDK (minor revision mismatches generally okay).
+
+* All libraries must use the same STL.
+
+ A library using libc++ will not interoperate with one using stlport. All
+ libraries in an application must use the same STL.
+
+ Strictly speaking this can be made to work, but it's a very fragile
+ configuration. Avoid it.
+
+* Apps with multiple shared libraries must use a shared STL.
+
+ https://developer.android.com/ndk/guides/cpp-support.html#sr
+
+ As with mismatched STLs, the problems caused by this can be avoided if great
+ care is taken, but it's better to just avoid the problem.
diff --git a/docs/user/middleware_vendors.md b/docs/user/middleware_vendors.md
new file mode 100644
index 0000000..215403c
--- /dev/null
+++ b/docs/user/middleware_vendors.md
@@ -0,0 +1,92 @@
+# Advice for Middleware Vendors
+
+Distributing middleware built with the NDK imposes some additional problems that
+app developers do not need to worry about. Prebuilt libraries impose some of
+their implementation choices on their users.
+
+## Choosing API levels and NDK versions
+
+Your users cannot use a `minSdkVersion` lower than yours. If your users' apps
+need to run on Android 16, you cannot build for Android 21.
+
+NDK versions are largely compatible with each other, but occasionally there are
+changes that break compatibility. If you know that all of your users are using
+the same version of the NDK, it's best to use the same version that they do.
+Otherwise, use the newest version.
+
+## Using the STL
+
+If you're writing C++ and using the STL, your choice between libc++_shared and
+libc++_static affects your users if you distribute a shared library. If you
+distribute a shared library, you must either use libc++_shared or ensure that
+libc++'s symbols are not exposed by your library. The best way to do this is to
+explicitly declare your ABI surface with a version script (this also helps keep
+your implementation details private). For example, a simple arithmetic library
+might have the following version script:
+
+Note: If you distribute a static library, it does not matter whether you choose
+a static or shared STL because nothing is linked in a static library. The user
+can link whichever they choose in their application. They must link *something*,
+even for C-only consumers, so be sure to document that it is required and which
+version of the NDK was used to build in case of incompatibility in STL versions.
+
+```txt
+LIBMYMATH {
+global:
+ add;
+ sub;
+ mul;
+ div;
+ # C++ symbols in an extern block will be mangled automatically. See
+ # https://stackoverflow.com/a/21845178/632035 for more examples.
+ extern "C++" {
+ "pow(int, int)";
+ }
+local:
+ *;
+};
+```
+
+A version script should be the preferred option because it is the most robust
+way to control symbol visibility. Another, less robust option is to use
+`-Wl,--exclude-libs,libc++_static.a -Wl,--exclude-libs,libc++abi.a` when
+linking. This is less robust because it will only hide the symbols in the
+libraries that are explicitly named, and no diagnostics are reported for
+libraries that are not used (a typo in the library name is not an error, and the
+burden is on the user to keep the library list up to date).
+
+## For Java Middleware with JNI Libraries
+
+Java libraries that include JNI libraries (i.e. use `jniLibs`) need to be
+careful that the JNI libraries they include will not collide with other
+libraries in the user's app. For example, if the AAR includes
+`libc++_shared.so`, but a different version of `libc++_shared.so` than the app
+uses, only one will be installed to the APK and that may lead to unreliable
+behavior.
+
+Warning: [Bug 141758241]: The Android Gradle Plugin does not currently diagnose
+this error condition. One of the identically named libraries will be arbitrarily
+chosen for packaging in the APK.
+
+[Bug 141758241]: https://issuetracker.google.com/141758241
+
+The most reliable solution is for Java libraries to include no more than **one**
+JNI library. All dependencies including the STL should be statically linked into
+the implementation library, and a version script should be used to enforce the
+ABI surface. For example, a Java library com.example.foo that includes the JNI
+library libfooimpl.so should use the following version script:
+
+```txt
+LIBFOOIMPL {
+global:
+ JNI_OnLoad;
+local:
+ *;
+};
+```
+
+Note that this example uses `registerNatives` via `JNI_OnLoad` as described in
+[JNI Tips] to ensure that the minimal ABI surface is exposed and library load
+time is minimized.
+
+[JNI Tips]: https://developer.android.com/training/articles/perf-jni#native-libraries
diff --git a/patches/cmake/Android-Clang.cmake.patch b/patches/cmake/Android-Clang.cmake.patch
new file mode 100644
index 0000000..9fe439c
--- /dev/null
+++ b/patches/cmake/Android-Clang.cmake.patch
@@ -0,0 +1,13 @@
+--- a/cmake/share/cmake-3.22/Modules/Platform/Android-Clang.cmake 2021-11-18 23:51:22.000000000 +0800
++++ b/cmake/share/cmake-3.22/Modules/Platform/Android-Clang.cmake 2021-12-05 10:55:02.941248123 +0800
+@@ -46,7 +46,9 @@
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ macro(__android_compiler_clang lang)
+ endmacro()
+- return()
++ if(NOT CMAKE_ANDROID_NDK)
++ return()
++ endif()
+ endif()
+
+ include(Platform/Android-Common)
diff --git a/patches/cmake/Android-Determine.cmake.patch b/patches/cmake/Android-Determine.cmake.patch
new file mode 100644
index 0000000..498f264
--- /dev/null
+++ b/patches/cmake/Android-Determine.cmake.patch
@@ -0,0 +1,22 @@
+--- a/cmake/share/cmake-3.22/Modules/Platform/Android-Determine.cmake 2021-11-18 23:51:22.000000000 +0800
++++ b/cmake/share/cmake-3.22/Modules/Platform/Android-Determine.cmake 2021-12-05 10:56:02.534731135 +0800
+@@ -26,7 +26,7 @@
+
+ # Natively compiling on an Android host doesn't use the NDK cross-compilation
+ # tools.
+-if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
++if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android" AND NOT CMAKE_ANDROID_NDK)
+ return()
+ endif()
+
+@@ -268,7 +268,9 @@
+
+ if(CMAKE_ANDROID_NDK)
+ # Identify the host platform.
+- if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
++ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
++ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "linux-aarch64")
++ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+ if(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "64")
+ set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "darwin-x86_64")
+ else()
diff --git a/patches/cmake/Android-Initialize.cmake.patch b/patches/cmake/Android-Initialize.cmake.patch
new file mode 100644
index 0000000..7b77ea5
--- /dev/null
+++ b/patches/cmake/Android-Initialize.cmake.patch
@@ -0,0 +1,11 @@
+--- a/cmake/share/cmake-3.22/Modules/Platform/Android-Initialize.cmake 2021-11-18 23:51:22.000000000 +0800
++++ b/cmake/share/cmake-3.22/Modules/Platform/Android-Initialize.cmake 2021-12-05 10:57:34.498031789 +0800
+@@ -77,7 +77,7 @@
+
+ # Natively compiling on an Android host doesn't use the NDK cross-compilation
+ # tools.
+-if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
++if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android" AND NOT CMAKE_ANDROID_NDK)
+ return()
+ endif()
+
diff --git a/patches/cmake/Android.cmake.patch b/patches/cmake/Android.cmake.patch
new file mode 100644
index 0000000..795e842
--- /dev/null
+++ b/patches/cmake/Android.cmake.patch
@@ -0,0 +1,11 @@
+--- a/cmake/share/cmake-3.22/Modules/Platform/Android.cmake 2021-11-18 23:51:22.000000000 +0800
++++ b/cmake/share/cmake-3.22/Modules/Platform/Android.cmake 2021-12-05 10:55:49.174568422 +0800
+@@ -9,7 +9,7 @@
+ set(ANDROID 1)
+
+ # Natively compiling on an Android host doesn't need these flags to be reset.
+-if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
++if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android" AND NOT CMAKE_ANDROID_NDK)
+ return()
+ endif()
+
diff --git a/patches/cmake/Determine-Compiler.cmake.patch b/patches/cmake/Determine-Compiler.cmake.patch
new file mode 100644
index 0000000..7fc484a
--- /dev/null
+++ b/patches/cmake/Determine-Compiler.cmake.patch
@@ -0,0 +1,14 @@
+--- a/cmake/share/cmake-3.22/Modules/Platform/Android/Determine-Compiler.cmake 2021-11-18 23:51:22.000000000 +0800
++++ b/cmake/share/cmake-3.22/Modules/Platform/Android/Determine-Compiler.cmake 2021-12-05 10:58:18.118071997 +0800
+@@ -46,7 +46,10 @@
+ if(NOT CMAKE_CXX_COMPILER_NAMES)
+ set(CMAKE_CXX_COMPILER_NAMES c++)
+ endif()
+- return()
++ set(_ANDROID_HOST_EXT "")
++ if(NOT CMAKE_ANDROID_NDK)
++ return()
++ endif()
+ else()
+ message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.")
+ endif()
diff --git a/patches/crypt.h b/patches/crypt.h
new file mode 100644
index 0000000..38be23e
--- /dev/null
+++ b/patches/crypt.h
@@ -0,0 +1,12 @@
+#ifndef CRYPT_H_INCLUDED
+#define CRYPT_H_INCLUDED
+
+#include
+
+__BEGIN_DECLS
+
+char* crypt(const char* key, const char* salt);
+
+__END_DECLS
+
+#endif
diff --git a/patches/llvm_android/base_builders.py.patch b/patches/llvm_android/base_builders.py.patch
new file mode 100644
index 0000000..d87d8b4
--- /dev/null
+++ b/patches/llvm_android/base_builders.py.patch
@@ -0,0 +1,39 @@
+--- a/llvm_android/base_builders.py 2022-06-19 16:20:36.597518279 +0800
++++ b/llvm_android/base_builders.py 2022-06-20 08:32:12.190524611 +0800
+@@ -156,7 +156,7 @@
+ @property
+ def cflags(self) -> List[str]:
+ """Additional cflags to use."""
+- return []
++ return ['--target=aarch64-linux-android28']
+
+ @property
+ def cxxflags(self) -> List[str]:
+@@ -169,7 +169,7 @@
+ ldflags = []
+ # When cross compiling, toolchain libs won't work on target arch.
+ if not self._is_cross_compiling():
+- ldflags.append(f'-L{self.toolchain.lib_dir}')
++ pass #ldflags.append(f'-L{self.toolchain.lib_dir}')
+ return ldflags
+
+ @property
+@@ -609,9 +609,16 @@
+
+ defines['LLVM_ENABLE_PROJECTS'] = ';'.join(sorted(self.llvm_projects))
+
+- defines['LLVM_TARGETS_TO_BUILD'] = ';'.join(sorted(self.llvm_targets))
++ defines['LLVM_TARGETS_TO_BUILD']= 'all'
++ defines['CLANG_DEFAULT_LINKER'] = 'lld'
+ defines['LLVM_BUILD_LLVM_DYLIB'] = 'ON'
+-
++ defines['LLVM_ENABLE_PIC'] = 'ON'
++ defines['CMAKE_BUILD_WITH_INSTALL_RPATH'] = 'ON'
++ defines['CMAKE_POLICY_DEFAULT_CMP0116'] = 'OLD'
++ defines['LLVM_TARGET_ARCH'] = 'AArch64'
++ defines['LLVM_HOST_TRIPLE'] = 'aarch64-unknown-linux-android'
++ defines['CMAKE_BUILD_TYPE'] = 'Release'
++
+ if self.build_tags:
+ tags_str = ''.join(tag + ', ' for tag in self.build_tags)
+ else:
diff --git a/patches/llvm_android/builders.py.patch b/patches/llvm_android/builders.py.patch
new file mode 100644
index 0000000..e0f0674
--- /dev/null
+++ b/patches/llvm_android/builders.py.patch
@@ -0,0 +1,31 @@
+--- a/llvm_android/builders.py 2022-06-19 16:20:36.597518279 +0800
++++ b/llvm_android/builders.py 2022-07-08 08:06:17.721316290 +0800
+@@ -87,7 +87,9 @@
+ # avoids specifying self.toolchain.lib_dir in rpath to find libc++ at
+ # runtime.
+ # [1] libc++ in our case, despite the flag saying -static-libstdc++.
+- ldflags.append('-static-libstdc++')
++ resource_dir = self.toolchain.resource_dir
++ ldflags.append(str(resource_dir / 'libclang_rt.builtins-aarch64-android.a'))
++ ldflags.append('-lc++_static -lc++abi -lunwind -ldl')
+ return ldflags
+
+ @property
+@@ -154,13 +156,15 @@
+ @property
+ def ldflags(self) -> List[str]:
+ ldflags = super().ldflags
++ resource_dir = self.toolchain.resource_dir
++ ldflags.append(str(resource_dir / 'libclang_rt.builtins-aarch64-android.a'))
++ ldflags.append('-lunwind -ldl')
+ if self.build_instrumented:
+ # Building libcxx, libcxxabi with instrumentation causes linker errors
+ # because these are built with -nodefaultlibs and prevent libc symbols
+ # needed by libclang_rt.profile from being resolved. Manually adding
+ # the libclang_rt.profile to linker flags fixes the issue.
+- resource_dir = self.toolchain.resource_dir
+- ldflags.append(str(resource_dir / 'libclang_rt.profile-x86_64.a'))
++ ldflags.append(str(resource_dir / 'libclang_rt.profile-aarch64.a'))
+ return ldflags
+
+ @property
diff --git a/patches/llvm_android/configs.py.patch b/patches/llvm_android/configs.py.patch
new file mode 100644
index 0000000..129d310
--- /dev/null
+++ b/patches/llvm_android/configs.py.patch
@@ -0,0 +1,17 @@
+--- a/llvm_android/configs.py 2022-06-19 16:20:36.600851613 +0800
++++ b/llvm_android/configs.py 2022-06-19 16:22:45.520864456 +0800
+@@ -162,10 +162,10 @@
+ """Configuration for Linux targets."""
+
+ target_os: hosts.Host = hosts.Host.Linux
+- sysroot: Optional[Path] = (paths.GCC_ROOT / 'host' / 'x86_64-linux-glibc2.17-4.8' / 'sysroot')
+- gcc_root: Path = (paths.GCC_ROOT / 'host' / 'x86_64-linux-glibc2.17-4.8')
+- gcc_triple: str = 'x86_64-linux'
+- gcc_ver: str = '4.8.3'
++ sysroot: Optional[Path] = (paths.GCC_ROOT / 'sysroot')
++ gcc_root: Path = (paths.GCC_ROOT)
++ gcc_triple: str = 'aarch64-linux-android'
++ gcc_ver: str = '4.9.x'
+
+ @property
+ def ldflags(self) -> List[str]:
diff --git a/patches/llvm_android/do_build.py.patch b/patches/llvm_android/do_build.py.patch
new file mode 100644
index 0000000..7cffa5e
--- /dev/null
+++ b/patches/llvm_android/do_build.py.patch
@@ -0,0 +1,14 @@
+--- a/llvm_android/do_build.py 2022-07-08 08:03:45.707967813 +0800
++++ b/llvm_android/do_build.py 2022-07-08 08:02:51.947962458 +0800
+@@ -55,9 +55,10 @@
+ tar = paths.pgo_profdata_tar()
+ if not tar:
+ return None
+- utils.check_call(['tar', '-jxC', str(paths.OUT_DIR), '-f', str(tar)])
+ profdata_file = paths.OUT_DIR / paths.pgo_profdata_filename()
+ if not profdata_file.exists():
++ utils.check_call(['tar', '-jxC', str(paths.OUT_DIR), '-f', str(tar)])
++ if not profdata_file.exists():
+ raise RuntimeError(
+ f'Failed to extract profdata from {tar} to {paths.OUT_DIR}')
+ return profdata_file
diff --git a/patches/llvm_android/paths.py.patch b/patches/llvm_android/paths.py.patch
new file mode 100644
index 0000000..5769b91
--- /dev/null
+++ b/patches/llvm_android/paths.py.patch
@@ -0,0 +1,11 @@
+--- a/llvm_android/paths.py 2022-06-19 16:20:36.630851616 +0800
++++ b/llvm_android/paths.py 2022-06-21 16:53:43.975462683 +0800
+@@ -56,7 +56,8 @@
+ NDK_LIBCXXABI_HEADERS: Path = NDK_BASE / 'sources' / 'cxx-stl' / 'llvm-libc++abi' / 'include'
+ NDK_SUPPORT_HEADERS: Path = NDK_BASE / 'sources' / 'android' / 'support' / 'include'
+
+-GCC_ROOT: Path = PREBUILTS_DIR / 'gcc' / hosts.build_host().os_tag
++GCC_ROOT :Path = CLANG_PREBUILT_DIR
+ MINGW_ROOT: Path = PREBUILTS_DIR / 'gcc' / 'linux-x86' / 'host' / 'x86_64-w64-mingw32-4.8'
+
+ _WIN_ZLIB_PATH: Path = (PREBUILTS_DIR / 'clang' / 'host' / 'windows-x86' /
diff --git a/patches/llvm_project/Editline.h.patch b/patches/llvm_project/Editline.h.patch
new file mode 100644
index 0000000..25d861c
--- /dev/null
+++ b/patches/llvm_project/Editline.h.patch
@@ -0,0 +1,11 @@
+--- a/llvm-project/lldb/include/lldb/Host/Editline.h 2021-11-30 13:34:49.653844615 +0800
++++ b/llvm-project/lldb/include/lldb/Host/Editline.h 2021-12-05 11:24:17.261484415 +0800
+@@ -43,7 +43,7 @@
+
+ #if defined(_WIN32)
+ #include "lldb/Host/windows/editlinewin.h"
+-#elif !defined(__ANDROID__)
++#else
+ #include
+ #endif
+
diff --git a/patches/llvm_project/IOHandlerCursesGUI.cpp.patch b/patches/llvm_project/IOHandlerCursesGUI.cpp.patch
new file mode 100644
index 0000000..4542dcf
--- /dev/null
+++ b/patches/llvm_project/IOHandlerCursesGUI.cpp.patch
@@ -0,0 +1,14 @@
+--- a/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp 2021-11-30 13:34:50.967178079 +0800
++++ b/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp 2021-12-05 11:20:25.151196833 +0800
+@@ -9,6 +9,11 @@
+ #include "lldb/Core/IOHandlerCursesGUI.h"
+ #include "lldb/Host/Config.h"
+
++#ifdef CURSES_HAVE_NCURSES_CURSES_H
++#undef CURSES_HAVE_NCURSES_CURSES_H
++#endif
++#define CURSES_HAVE_NCURSES_CURSES_H 1
++
+ #if LLDB_ENABLE_CURSES
+ #if CURSES_HAVE_NCURSES_CURSES_H
+ #include
diff --git a/patches/llvm_project/vis.c.patch b/patches/llvm_project/vis.c.patch
new file mode 100644
index 0000000..2dc1542
--- /dev/null
+++ b/patches/llvm_project/vis.c.patch
@@ -0,0 +1,12 @@
+--- a/external/libedit/src/vis.c 2020-11-28 16:17:05.333521910 +0800
++++ b/external/libedit/src/vis.c 2021-12-05 11:18:29.889675857 +0800
+@@ -85,6 +85,9 @@
+ #include
+ #include
+
++#ifndef NBBY
++#define NBBY 8
++#endif
+
+ /*
+ * The reason for going through the trouble to deal with character encodings
diff --git a/patches/ndk/android-legacy.toolchain.cmake.patch b/patches/ndk/android-legacy.toolchain.cmake.patch
new file mode 100644
index 0000000..103538f
--- /dev/null
+++ b/patches/ndk/android-legacy.toolchain.cmake.patch
@@ -0,0 +1,13 @@
+--- a/build/cmake/android-legacy.toolchain.cmake 2021-09-15 10:11:41.882220792 +0800
++++ b/build/cmake/android-legacy.toolchain.cmake 2021-09-15 20:05:55.892587467 +0800
+@@ -351,7 +351,9 @@
+ message(FATAL_ERROR "Invalid Android STL: ${ANDROID_STL}.")
+ endif()
+
+-if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
++if(CMAKE_HOST_SYSTEM_NAME STREQUAL Android)
++ set(ANDROID_HOST_TAG linux-aarch64)
++elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
+ set(ANDROID_HOST_TAG linux-x86_64)
+ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
+ set(ANDROID_HOST_TAG darwin-x86_64)
diff --git a/patches/ndk/android.toolchain.cmake.patch b/patches/ndk/android.toolchain.cmake.patch
new file mode 100644
index 0000000..31d68c5
--- /dev/null
+++ b/patches/ndk/android.toolchain.cmake.patch
@@ -0,0 +1,13 @@
+--- a/build/cmake/android.toolchain.cmake 2021-12-05 11:11:08.815701947 +0800
++++ b/build/cmake/android.toolchain.cmake 2021-12-05 15:17:45.158153568 +0800
+@@ -256,7 +256,9 @@
+ # Exports compatible variables defined in exports.cmake.
+ set(_ANDROID_EXPORT_COMPATIBILITY_VARIABLES TRUE)
+
+-if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
++if(CMAKE_HOST_SYSTEM_NAME STREQUAL Android)
++ set(ANDROID_HOST_TAG linux-aarch64)
++elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
+ set(ANDROID_HOST_TAG linux-x86_64)
+ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
+ set(ANDROID_HOST_TAG darwin-x86_64)
diff --git a/patches/ndk/ndk_bin_common.sh.patch b/patches/ndk/ndk_bin_common.sh.patch
new file mode 100644
index 0000000..b50bfa8
--- /dev/null
+++ b/patches/ndk/ndk_bin_common.sh.patch
@@ -0,0 +1,10 @@
+--- a/build/tools/ndk_bin_common.sh 2023-11-08 22:49:27.656718542 +0800
++++ b/build/tools/ndk_bin_common.sh 2023-11-08 11:06:05.000000000 +0800
+@@ -27,6 +27,7 @@ esac
+
+ HOST_ARCH=$(uname -m)
+ case $HOST_ARCH in
++ aarch64) HOST_ARCH=aarch64;;
+ arm64) HOST_ARCH=arm64;;
+ i?86) HOST_ARCH=x86;;
+ x86_64|amd64) HOST_ARCH=x86_64;;