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