From: Alexis Laferrière Date: Tue, 25 Feb 2014 05:09:57 +0000 (-0500) Subject: android: adds support for the android platform X-Git-Tag: v0.6.5~50^2~2 X-Git-Url: http://nitlanguage.org?ds=sidebyside android: adds support for the android platform Signed-off-by: Alexis Laferrière --- diff --git a/lib/android.nit b/lib/android.nit new file mode 100644 index 0000000..7f7883e --- /dev/null +++ b/lib/android.nit @@ -0,0 +1,22 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# 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. + +# Targets the Android platform +# +# To use this module and compile for Android, you must install the +# Android SDK (with API level 10) and NDK (with the API level 9). +# The tools `android`, `ndk-build` and `ant` must be in your PATH. +# +# Will, in the near future, provide services specific to Android. +module android is platform diff --git a/src/android_platform.nit b/src/android_platform.nit new file mode 100644 index 0000000..60d4ca0 --- /dev/null +++ b/src/android_platform.nit @@ -0,0 +1,179 @@ +# This file is part of NIT ( http://www.nitlanguage.org )t +# +# Copyright 2014 Alexis Laferrière +# +# 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. + +# Compile program for the Android platform +module android_platform + +import platform +import abstract_compiler + +redef class ToolContext + redef fun platform_from_name(name) + do + if name == "android" then return new AndroidPlatform + return super + end + + fun exec_and_check(args: Array[String]) + do + var prog = args.first + args.remove_at 0 + + # Is the wanted program available? + var proc_which = new IProcess.from_a("which", [prog]) + proc_which.wait + var res = proc_which.status + if res != 0 then + print "Android project error: executable \"{prog}\" not found" + exit 1 + end + + # Execute the wanted program + var proc = new Process.from_a(prog, args) + proc.wait + res = proc.status + if res != 0 then + print "Android project error: execution of \"{prog} {args.join(" ")}\" failed" + exit 1 + end + end +end + +class AndroidPlatform + super Platform + + redef fun toolchain(toolcontext) do return new AndroidToolchain(toolcontext) +end + +class AndroidToolchain + super MakefileToolchain + + var android_project_root: String + + redef fun compile_dir + do + var normal_compile_dir = super + android_project_root = normal_compile_dir + return "{normal_compile_dir}/jni/" + end + + redef fun write_files(compiler, compile_dir, cfiles) + do + var app_name = compiler.mainmodule.name + var app_package = "org.nitlanguage.{app_name}" + var app_version = "0.1" + + var args = ["android", "-s", "create", "project", "--name", app_name, + "--target", "android-10", "--path", android_project_root, + "--package", app_package, "--activity", app_name] + toolcontext.exec_and_check(args) + + # create compile_dir + var dir = "{android_project_root}/jni/" + if not dir.file_exists then dir.mkdir + + # compile normal C files + super(compiler, compile_dir, cfiles) + + # Gather extra C files generated elsewhere than in super + for f in compiler.extern_bodies do + if f isa ExternCFile then cfiles.add(f.filename.basename("")) + end + + ### generate makefile into "{compile_dir}/Android.mk" + if not dir.file_exists then dir.mkdir + var file = new OFStream.open("{dir}/Android.mk") + file.write """ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_CFLAGS := -D ANDROID +LOCAL_MODULE := main +LOCAL_SRC_FILES := \\ +{{{cfiles.join(" \\\n")}}} +LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM -lz +LOCAL_STATIC_LIBRARIES := android_native_app_glue + +include $(BUILD_SHARED_LIBRARY) + +$(call import-module,android/native_app_glue) +""" + file.close + + ### generate AndroidManifest.xml + dir = android_project_root + file = new OFStream.open("{dir}/AndroidManifest.xml") + file.write """ + + + + + + + + + + + + + + + + + + + + + + +""" + file.close + + ### generate res/values/strings.xml + dir = "{android_project_root}/res/" + if not dir.file_exists then dir.mkdir + dir = "{dir}/values/" + if not dir.file_exists then dir.mkdir + file = new OFStream.open("{dir}/strings.xml") + file.write """ + + {{{app_name}}} +""" + file.close + end + + redef fun write_makefile(compiler, compile_dir, cfiles) + do + # Do nothing, already done in `write_files` + end + + redef fun compile_c_code(compiler, compile_dir) + do + # Compile C code (and thus Nit) + toolcontext.exec_and_check(["ndk-build", "-s", "-j", "4", "-C", android_project_root]) + + # Generate the apk + toolcontext.exec_and_check(["ant", "-q", "debug", "-f", android_project_root+"/build.xml"]) + end +end diff --git a/src/nitg.nit b/src/nitg.nit index 47f6373..f575b91 100644 --- a/src/nitg.nit +++ b/src/nitg.nit @@ -24,6 +24,7 @@ import rapid_type_analysis import global_compiler import separate_erasure_compiler import separate_compiler +import android_platform # Create a tool context to handle options and paths var toolcontext = new ToolContext