#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import subprocess
import shutil
def main():
sdk_path = os.getenv('ANDROID_HOME')
ndk_path = os.getenv('NDK_HOME')
standalone_path = os.getenv('NDK_STANDALONE')
directory = build_directory(sdk_path, args.output.filestem_str , native_shared_libs)
# // Copy the additional native libs into the libs directory.
for name, path in native_shared_libs.items():
shutil.copy( path, os.path.join( directory, "libs/", "armeabi/",name)
# compile android_native_app_glue.c
cmd = os.path.join( standalone_path , "bin/" , "arm-linux-androideabi-gcc ")
arg1 = os.path.join( ndk_path, "sources/" , "android/" ,"native_app_glue/", "android_native_app_glue.c ")
arg2 = " -c "
arg3 = " -o "
arg4 = directory + "android_native_app_glue.o"
os.system(cmd + arg1 + arg2 + arg3 + arg4)
"""
calling gcc to link a shared object
"""
cmd = os.path.join(standalone_path , "bin/", "arm-linux-androideabi-gcc ")
arg1 = passthrough
arg2 = os.path.join( directory , "android_native_app_glue.o")
arg3 = " -o " + os.path.join( directory ,"libs", "armeabi", "libmain.so")
arg4 = " -shared"
arg5 = " -Wl,-E"
os.system(cmd + arg1 + arg2 + arg3 + arg4 + arg5 )
"""
call ant debug
"""
ant_command = "ant debug"
os.system(ant_command )
#copy apk file to required dest
shutil.copy( os.path.join( directory, "bin/", "rust-android-debug.apk"), output)
def find_native_libs(args: &Args) -> HashMap {
"""
args HashMap
"""
base_path = os.path.join( args, "native");
native_shared_libs = {}
#for dirpath, dirname, filenames in os.walk(base_path):
for dirs in os.listdir(base_path):
if os.path.isdir(dirs):
for dir in dirs:
path = os.path.join(base_path, dirs,dir )
for file in os.listdir(path):
if file.starts_with("lib") and file.endwith(".so"):
native_shared_libs.update(file, path)
return native_shared_libs
def build_directory(sdk_dir, crate_name, libs):
"""
sdk_dir : Path
crate_name : str
libs: HashMap
return: Tempdir
"""
temp_dir = "android-rs-glue-rust-to-apk"
build_directory = os.mkdir( temp_dir )
if len(libs) > 0:
src_path = os.path.join(temp_dir ,"src/rust/glutin");
os.mkdirs(src_path )
java_file = open(os.path.join( src_path, "MainActivity.java") ,"rw")
java_file.write( (java_src(libs) )
activity_name = "rust.glutin.MainActivity"
java_file.flush()
java_file.close()
else:
activity_name = "android.app.NativeActivity"
manifest_file=os.path.join(build_directory, "AndroidManifest.xml")
manifest_file = open( manifest_file, "rw")
manifest_file.write(build_manifest(crate_name, activity_name))
manifest_file.close()
build_xml = os.path.join(build_directory, "build.xml")
build_xml = open( build.xml, "rw")
build_xml.write( build_build_xml() )
build_xml.close()
local_pro = os.path.join(build_directory, "local.properties")
local_pro = open(local_pro, "rw")
local_pro.write(build_local_properties())
local_pro.close()
project_pro = os.path.join(build_directory, "project.properties")
project_pro = open(project_pro, "rw")
project_pro.write(build_project_properties())
project_pro.close()
libs_path = os.path.join(build_directory, "libs/", "armeabi")
os.makedirs(libs_path)
return build_directory
def java_src(libs) {
"""
libs: HashMap,
returns string
"""
libs_string = ""
for name, _ in libs.items():
"""
// Strip off the 'lib' prefix and ".so" suffix. This is safe since libs only get added
// to the hash map if they start with lib.
"""
line = " System.loadLibrary(\\"{}\\");\\n".format( name[3:len(name)-3]);
libs_string = libs_string + line;
ret = """package rust.glutin;
public class MainActivity extends android.app.NativeActivity {{
static {{
{0}
}}
}}""".format(libs_string)
return ret
def build_manifest(crate_name , activity_name):
return """<?xml version="1.0" encoding="utf-8"?>
package="com.example.native_activity"
android:versionCode="1"
android:versionName="1.0">
android:label="{0}"
android:configChanges="orientation|keyboardHidden">
""".format(crate_name, activity_name)
def build_build_xml():
return """<?xml version="1.0" encoding="UTF-8"?>
"""
def build_local_properties(sdk_dir):
return "sdk.dir={0}".format(os.path.abspath(sdk_dir))
def build_project_properties():
return "target=android-19"
main()