├── .gitignore ├── LICENSE.md ├── README.md ├── RustLib ├── .cargo │ └── config ├── Cargo.toml └── src │ └── lib.rs ├── app ├── .gitignore ├── build.gradle ├── libs │ └── jna.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── pacoworks │ │ └── hellorust │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── pacoworks │ │ └── hellorust │ │ ├── MainActivity.java │ │ └── ThingLibrary.java │ ├── jni │ ├── Android.mk │ ├── Application.mk │ ├── NDKBUG.c │ ├── librust.a │ ├── thing.c │ └── unwind │ │ ├── include │ │ ├── asm-generic │ │ │ └── portability.h │ │ └── portability.h │ │ └── unwind.c │ ├── jniLibs │ ├── armeabi-v7a │ │ └── libjnidispatch.so │ ├── armeabi │ │ ├── libHelloRust.so │ │ └── libjnidispatch.so │ └── x86 │ │ └── libjnidispatch.so │ ├── libs │ └── armeabi │ │ └── libHelloRust.so │ ├── obj │ └── local │ │ └── armeabi │ │ ├── libHelloRust.so │ │ └── librust.so │ └── res │ ├── layout │ └── activity_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── device-2015-05-01-205416.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | /obj 9 | target 10 | Cargo.lock 11 | .idea 12 | *.iml -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License, Version 2.0 2 | =========================== 3 | 4 | Copyright 2015 pakoito 5 | 6 | Licensed under the Apache License, Version 2.0 (the "License"); 7 | you may not use this file except in compliance with the License. 8 | You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | Unless required by applicable law or agreed to in writing, software 13 | distributed under the License is distributed on an "AS IS" BASIS, 14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | See the License for the specific language governing permissions and 16 | limitations under the License.n 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Rusty Android 2 | ========== 3 | 4 | Proof of Concept for interfacing Rust and Java-Android via JNA. Built on rustc 1.1.0-dev (aecf3d8b6 2015-05-01) 5 | 6 | 7 | What works 8 | ========== 9 | 10 | Hacked jna library ready for gradle use. See https://github.com/pakoito/jna 11 | 12 | C and Java interop via JNA 13 | 14 | C and Rust interop via static linkage 15 | 16 | Put it all together and you get RustyAndroid. 17 | 18 | 19 | How to 20 | ========== 21 | 22 | Follow [this guide](https://github.com/rust-lang/rust-wiki-backup/blob/master/Doc-building-for-android.md) through steps 1-4 to get your toolchain running 23 | 24 | *In case you're on an OSX, on step 3 your configure command is* 25 | 26 | ../configure --host=x86_64-apple-darwin --target=arm-linux-androideabi --android-cross-path="$ANDROID_TOOLCHAIN" 27 | 28 | *In case you're on Windows-MinGW, on step 3 your configure command is* 29 | 30 | ../configure --host=i686-pc-windows-gnu --target=arm-linux-androideabi --android-cross-path="$ANDROID_TOOLCHAIN" 31 | 32 | Clone this repository 33 | 34 | git clone https://github.com/pakoito/RustyAndroid/ 35 | 36 | Import into Android Studio 37 | 38 | Setup your ```ndk.dir``` in ```local.properties``` 39 | 40 | Create your .rs files with pub extern functions like the examples in the RustLib folder, and compile them using rustc 41 | 42 | rustc --target=arm-linux-androideabi -C linker=$ANDROID_TOOLCHAIN/bin/arm-linux-androideabi-gcc -C link-args=-pie -C ar=$ANDROID_TOOLCHAIN/bin/arm-linux-androideabi-ar --crate-type=staticlib src/lib.rs 43 | 44 | *Cargo was giving me hell for Android on OSX, go the rustc route for now* 45 | 46 | Rename your .a output and copy it to /app/src/main/jni 47 | 48 | Create your C glue layer bringing Rust through extern functions as in /app/src/main/jni/thing.c 49 | 50 | See ```build.gradle```, ```Android.mk``` and ```Application.mk``` for how it all is tied together on Android 51 | 52 | For JNA integration, see ```ThingLibrary.java``` and ```MainActivity.java``` 53 | 54 | 55 | Known Issues 56 | ============= 57 | 58 | Plenty of them. This shouldn't even work but it does. 59 | 60 | There is a requirement for the unwind library found by @skligys to solve some missing dependencies. 61 | 62 | For now it builds only armeabi libraries. You can reuse them for armeabi-v7a too just by copying ```libHelloRust.so``` from /app/src/main/jniLibs/armeabi to /app/src/main/jniLibs/armeabi-v7a. 63 | 64 | It can be built on Linux and OSX effortlesly. I can be built on Windows using an updated MinGW, but only if you have LLVM/Clang versions from June '15 onwards. It may require to have Visual Studio installed (?) ~~Building rust static libraries only works on linux and OSX. Windows doesn't have first class LLVM/Clang support.~~ 65 | 66 | 67 | Jnaenerator 68 | ============ 69 | 70 | You can autogenerate your java glue files using Jnaenerator with a variation of 71 | 72 | java -jar jnaerator-shaded.jar -library thing thing.c -o . -v -noJar -noComp -runtime JNA 73 | 74 | 75 | License 76 | ========== 77 | 78 | See LICENSE.md 79 | 80 | 81 | References (in no special order) 82 | ========== 83 | 84 | http://blog.rust-lang.org/2015/04/24/Rust-Once-Run-Everywhere.html 85 | 86 | http://users.rust-lang.org/t/rust-nightly-for-android/645/3 87 | 88 | https://github.com/rust-lang/rust-wiki-backup/blob/master/Doc-building-for-android.md 89 | 90 | https://github.com/rust-lang/rust/issues/17437 91 | 92 | http://harkablog.com/calling-rust-from-c-and-python.html 93 | 94 | http://stackoverflow.com/questions/28161628/linking-shared-object-library-without-headers-with-ndk-in-android-studio 95 | 96 | https://ubuntuincident.wordpress.com/2014/12/24/getting-started-with-the-rust-programming-language/ 97 | 98 | http://www.sureshjoshi.com/mobile/android-ndk-in-android-studio-with-swig/ 99 | 100 | http://sdgsystems.com/blog/using-android-ndk-android-studio/ 101 | 102 | http://www.eshayne.com/jnaex/example01.html 103 | 104 | https://code.google.com/p/jnaerator/wiki/JNAeratorFAQ 105 | 106 | https://github.com/rust-lang/rust/issues/25032#issuecomment-98176414 107 | 108 | http://stackoverflow.com/questions/15241869/pthread-error-in-ndk-build 109 | 110 | https://github.com/skligys/rusty-cardboard/tree/fc999e0385de7ab5d32a319ca523225a7e0d673f/jni 111 | 112 | http://sourceforge.net/p/mingw/bugs/2043/ 113 | 114 | 115 | Screenshot 116 | ========== 117 | 118 | ![First run](https://github.com/pakoito/RustyAndroid/blob/master/device-2015-05-01-205416.png) 119 | -------------------------------------------------------------------------------- /RustLib/.cargo/config: -------------------------------------------------------------------------------- 1 | [target.arm-linux-androideabi] 2 | linker = "arm-linux-androideabi-gcc" -------------------------------------------------------------------------------- /RustLib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "RustLib" 3 | version = "0.1.0" 4 | authors = ["pakoito "] 5 | 6 | [lib] 7 | name = "rust" 8 | crate-type = ["staticlib"] -------------------------------------------------------------------------------- /RustLib/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![crate_type = "staticlib"] 2 | 3 | #[no_mangle] 4 | pub extern fn double_input(input: i32) -> i32 { 5 | input * 4 6 | } -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /obj 8 | target 9 | Cargo.lock 10 | .idea 11 | *.iml -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | import org.apache.tools.ant.taskdefs.condition.Os 2 | 3 | def getPlatformNdkBuildCommand() { 4 | def rootDir = project.rootDir 5 | def localProperties = new File(rootDir, "local.properties") 6 | if (localProperties.exists()) { 7 | Properties properties = new Properties() 8 | localProperties.withInputStream { 9 | instr -> properties.load(instr) 10 | } 11 | def ndkDir = properties.getProperty('ndk.dir') 12 | if (ndkDir == null) { 13 | throw new GradleException("The ndk.dir property in local.propeties is not set") 14 | } 15 | def ndkBuild = Os.isFamily(Os.FAMILY_WINDOWS) ? "$ndkDir/ndk-build.cmd" : "$ndkDir/ndk-build" 16 | return ndkBuild 17 | } else { 18 | throw new GradleException("The local.properties file does not exist") 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.application' 23 | 24 | android { 25 | compileSdkVersion 22 26 | buildToolsVersion "22.0.1" 27 | 28 | defaultConfig { 29 | applicationId "com.pacoworks.hellorust" 30 | minSdkVersion 17 31 | targetSdkVersion 22 32 | versionCode 1 33 | versionName "1.0" 34 | } 35 | buildTypes { 36 | release { 37 | minifyEnabled false 38 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 39 | } 40 | } 41 | 42 | sourceSets.main { 43 | jniLibs.srcDir 'src/main/jniLibs' 44 | jni.srcDirs = [] //disable automatic ndk-build call 45 | } 46 | 47 | // call regular ndk-build(.cmd) script from app directory 48 | task ndkBuild(type: Exec) { 49 | def ndkBuild = getPlatformNdkBuildCommand() 50 | commandLine "$ndkBuild", '-j8', '-C', file('src/main/jni').absolutePath 51 | } 52 | 53 | // Copy shared libs into jniLibs folder (Hacky workaround) 54 | task copySharedLibs(type: Copy) { 55 | from 'src/main/libs' 56 | into 'src/main/jniLibs' 57 | } 58 | 59 | tasks.withType(JavaCompile) { 60 | compileTask -> compileTask.dependsOn ndkBuild 61 | } 62 | 63 | copySharedLibs.dependsOn ndkBuild 64 | copySharedLibs.execute() 65 | } 66 | 67 | 68 | dependencies { 69 | compile fileTree(dir: 'libs', include: ['*.jar']) 70 | compile 'com.android.support:appcompat-v7:22.1.1' 71 | // compile 'net.java.dev.jna:jna:4.1.0' 72 | } 73 | -------------------------------------------------------------------------------- /app/libs/jna.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/libs/jna.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in S:\android-sdk-windows/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/pacoworks/hellorust/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.pacoworks.hellorust; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/pacoworks/hellorust/MainActivity.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pacoworks.hellorust; 3 | 4 | import android.os.Bundle; 5 | import android.support.v7.app.ActionBarActivity; 6 | import android.view.Menu; 7 | import android.view.MenuItem; 8 | import android.widget.TextView; 9 | 10 | public class MainActivity extends ActionBarActivity { 11 | @Override 12 | protected void onCreate(Bundle savedInstanceState) { 13 | super.onCreate(savedInstanceState); 14 | setContentView(R.layout.activity_main); 15 | TextView dump = (TextView)findViewById(R.id.dump_txv); 16 | int n = 14; 17 | dump.setText("Rust thinks that quadruple of " + n + " is " + ThingLibrary.INSTANCE.dupli(n) 18 | + " and the native invoke is " 19 | + ThingLibrary.JNA_NATIVE_LIB.getFunction("dupli").invokeInt(new Object[] { 20 | n 21 | }) + " and its address is " 22 | + ThingLibrary.JNA_NATIVE_LIB.getGlobalVariableAddress("dupli")); 23 | } 24 | 25 | @Override 26 | public boolean onCreateOptionsMenu(Menu menu) { 27 | // Inflate the menu; this adds items to the action bar if it is present. 28 | getMenuInflater().inflate(R.menu.menu_main, menu); 29 | return true; 30 | } 31 | 32 | @Override 33 | public boolean onOptionsItemSelected(MenuItem item) { 34 | // Handle action bar item clicks here. The action bar will 35 | // automatically handle clicks on the Home/Up button, so long 36 | // as you specify a parent activity in AndroidManifest.xml. 37 | int id = item.getItemId(); 38 | // noinspection SimplifiableIfStatement 39 | if (id == R.id.action_settings) { 40 | return true; 41 | } 42 | return super.onOptionsItemSelected(item); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/pacoworks/hellorust/ThingLibrary.java: -------------------------------------------------------------------------------- 1 | 2 | package com.pacoworks.hellorust; 3 | 4 | import com.sun.jna.Library; 5 | import com.sun.jna.Native; 6 | import com.sun.jna.NativeLibrary; 7 | 8 | /** 9 | * JNA Wrapper for library thing
10 | * This file was autogenerated by JNAerator,
11 | * a tool written by Olivier Chafik that uses a few opensource 13 | * projects..
14 | * For help, please visit NativeLibs4Java , Rococoa, or JNA. 16 | */ 17 | public interface ThingLibrary extends Library { 18 | public static final String JNA_LIBRARY_NAME = "HelloRust"; 19 | 20 | public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary 21 | .getInstance(ThingLibrary.JNA_LIBRARY_NAME); 22 | 23 | public static final ThingLibrary INSTANCE = (ThingLibrary)Native.loadLibrary( 24 | ThingLibrary.JNA_LIBRARY_NAME, ThingLibrary.class); 25 | 26 | int dupli(int input); 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_MODULE := rust_prebuilt 5 | LOCAL_SRC_FILES := librust.a 6 | include $(PREBUILT_STATIC_LIBRARY) 7 | 8 | # A workaround for missing symbols: _Unwind_GetIP, _Unwind_SetIP, _Unwind_SetGR. 9 | include $(CLEAR_VARS) 10 | LOCAL_MODULE := unwind 11 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/unwind/include 12 | LOCAL_SRC_FILES := unwind/unwind.c 13 | include $(BUILD_STATIC_LIBRARY) 14 | 15 | 16 | include $(CLEAR_VARS) 17 | LOCAL_MODULE := HelloRust 18 | LOCAL_SRC_FILES := thing.c 19 | LOCAL_STATIC_LIBRARIES += rust_prebuilt unwind 20 | 21 | include $(BUILD_SHARED_LIBRARY) -------------------------------------------------------------------------------- /app/src/main/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_PLATFORM := android-14 -------------------------------------------------------------------------------- /app/src/main/jni/NDKBUG.c: -------------------------------------------------------------------------------- 1 | // According to the StackOverflow post below, Android NDK can't compile a single source file, so a 2 | // solution is to add an empty file... 3 | // Yeah... Seriously... This ACTUALLY fixed my compilation error 4 | 5 | //https://stackoverflow.com/questions/22465933/no-rule-to-make-target-when-compiling-ndk-sources-on-windows-with-gradle -------------------------------------------------------------------------------- /app/src/main/jni/librust.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/jni/librust.a -------------------------------------------------------------------------------- /app/src/main/jni/thing.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int32_t double_input(int32_t input); 4 | 5 | int dupli(int num){ 6 | return double_input(num); 7 | } -------------------------------------------------------------------------------- /app/src/main/jni/unwind/include/asm-generic/portability.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _ASM_PORTABILITY_H_ 18 | #define _ASM_PORTABILITY_H_ 19 | 20 | #if !defined(__HOST__) 21 | #define WRAP(f) f ## _portable 22 | #define REAL(f) f 23 | #else 24 | /* On host app link with libpportable.a with -Wl,--wrap=symbol, which resolves undefined symbol to __wrap_symbol, 25 | * and undefined __real_symbol to the original symbol 26 | */ 27 | #define WRAP(f) __wrap_ ## f 28 | #define REAL(f) __real_ ## f 29 | #endif 30 | 31 | #if defined(__mips__) && !defined(END) 32 | #define END(f) .cfi_endproc; .end f 33 | #endif 34 | 35 | #endif /* _ASM_PORTABILITY_H_ */ 36 | -------------------------------------------------------------------------------- /app/src/main/jni/unwind/include/portability.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _PORTABILITY_H_ 18 | #define _PORTABILITY_H_ 19 | 20 | #include "asm-generic/portability.h" 21 | /* 22 | * Common portability helper routines 23 | */ 24 | 25 | /* 26 | * Check a portable pointer before we access it 27 | * Well behaved programs should not be passing bad pointers 28 | * to the kernel but this routine can be used to check a pointer 29 | * if we need to use it before calling the kernel 30 | * 31 | * It does not catch every possible case but it is sufficient for LTP 32 | */ 33 | inline static int invalid_pointer(void *p) 34 | { 35 | return p == 0 36 | || p == (void *)-1 37 | #ifdef __mips__ 38 | || (int)p < 0 39 | #endif 40 | ; 41 | } 42 | 43 | /* 44 | * Hidden functions are exposed while linking the libportable shared object 45 | * but are not exposed thereafter. 46 | */ 47 | #define __hidden __attribute__((visibility("hidden"))) 48 | 49 | #endif /* _PORTABILITY_H_ */ 50 | -------------------------------------------------------------------------------- /app/src/main/jni/unwind/unwind.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | 20 | struct _Unwind_Context; 21 | 22 | typedef enum { 23 | _UVRSC_CORE = 0, // integer register 24 | _UVRSC_VFP = 1, // vfp 25 | _UVRSC_WMMXD = 3, // Intel WMMX data register 26 | _UVRSC_WMMXC = 4 // Intel WMMX control register 27 | } _Unwind_VRS_RegClass; 28 | 29 | typedef enum { 30 | _UVRSD_UINT32 = 0, 31 | _UVRSD_VFPX = 1, 32 | _UVRSD_UINT64 = 3, 33 | _UVRSD_FLOAT = 4, 34 | _UVRSD_DOUBLE = 5 35 | } _Unwind_VRS_DataRepresentation; 36 | 37 | typedef enum { 38 | _UVRSR_OK = 0, 39 | _UVRSR_NOT_IMPLEMENTED = 1, 40 | _UVRSR_FAILED = 2 41 | } _Unwind_VRS_Result; 42 | 43 | _Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *context, 44 | _Unwind_VRS_RegClass regclass, 45 | uint32_t regno, 46 | _Unwind_VRS_DataRepresentation representation, 47 | void* valuep); 48 | 49 | _Unwind_VRS_Result _Unwind_VRS_Set(struct _Unwind_Context *context, 50 | _Unwind_VRS_RegClass regclass, 51 | uint32_t regno, 52 | _Unwind_VRS_DataRepresentation representation, 53 | void* valuep); 54 | 55 | #define UNWIND_POINTER_REG 12 56 | #define UNWIND_STACK_REG 13 57 | #define UNWIND_IP_REG 15 58 | 59 | uint64_t _Unwind_GetGR(struct _Unwind_Context* ctx, int index) { 60 | uint32_t val; 61 | _Unwind_VRS_Get(ctx, _UVRSC_CORE, index, _UVRSD_UINT32, &val); 62 | return (uint64_t)val; 63 | } 64 | 65 | void _Unwind_SetGR(struct _Unwind_Context* ctx, int index, uint64_t new_value) { 66 | uint32_t val = (uint32_t)new_value; 67 | _Unwind_VRS_Set(ctx, _UVRSC_CORE, index, _UVRSD_UINT32, &val); 68 | } 69 | 70 | uint64_t _Unwind_GetIP(struct _Unwind_Context* ctx) { 71 | return _Unwind_GetGR(ctx, UNWIND_IP_REG) & ~1; // thumb bit 72 | } 73 | 74 | void _Unwind_SetIP(struct _Unwind_Context* ctx, uintptr_t new_value) { 75 | uint32_t val = (uint32_t)new_value; 76 | // Propagate thumb bit to instruction pointer 77 | uint32_t thumbState = _Unwind_GetGR(ctx, UNWIND_IP_REG) & 1; 78 | uint64_t new_val = (uint64_t)(val | thumbState); 79 | _Unwind_SetGR(ctx, UNWIND_IP_REG, new_val); 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi-v7a/libjnidispatch.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/jniLibs/armeabi-v7a/libjnidispatch.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libHelloRust.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/jniLibs/armeabi/libHelloRust.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/armeabi/libjnidispatch.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/jniLibs/armeabi/libjnidispatch.so -------------------------------------------------------------------------------- /app/src/main/jniLibs/x86/libjnidispatch.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/jniLibs/x86/libjnidispatch.so -------------------------------------------------------------------------------- /app/src/main/libs/armeabi/libHelloRust.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/libs/armeabi/libHelloRust.so -------------------------------------------------------------------------------- /app/src/main/obj/local/armeabi/libHelloRust.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/obj/local/armeabi/libHelloRust.so -------------------------------------------------------------------------------- /app/src/main/obj/local/armeabi/librust.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/obj/local/armeabi/librust.so -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HelloRust 3 | 4 | Hello world! 5 | Settings 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.1.0' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /device-2015-05-01-205416.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/device-2015-05-01-205416.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pakoito/RustyAndroid/4fde4a96248d8611dc540ed5d441e9455be0185d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 10 15:27:10 PDT 2013 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------