Android用にMonoをbuildする
AndroidでスタンドアロンのMonoを使いたかったのでMonoをbuildしました。
その手順を忘れないように書いておきます。
対象となるMonoのバージョンは2.10.5です。
2.10.5の理由は手元のUbuntuのapt-getでinstallされたのが2.10.5だったからです。
以下の手順でbuildを行います。
- Androidのソースツリーを取得
- externalの下に「androidmono」という名前でディレクトリを作成
- external/androidmonoの中でgit cloneなりtarを展開するなりしてMonoのソースを展開
- 展開したMonoのディレクトリを「mono」という名前に変更
- Android.mkとApplication.mkを作成
- パッチを適用する
- ビルドに必要なヘッダファイル群を展開する
という感じです。
Android.mkの中身はこんな感じですね。
LOCAL_PATH := $(call my-dir) MONO_PATH := $(LOCAL_PATH)/mono MONO_ASSEMBLY_DIR := \"/data/local/mono/lib/\" MONO_CONFIG_DIR := \"/data/local/mono/bin/\" MONO_BINARY_DIR := \"/data/local/mono/bin/\" MONO_CFLAGS := -DMONO_ASSEMBLIES=$(MONO_ASSEMBLY_DIR) \ -DMONO_CFG_DIR=$(MONO_CONFIG_DIR) \ -DMONO_BINDIR=$(MONO_BINARY_DIR) \ -DHAVE_CONFIG_H -DARM_FPU_VFP -D_REENTRANT \ -DPAGE_SIZE=4096 -DS_IWRITE=S_IWUSR \ -DPLATFORM_ANDROID -D__linux__ -DREDIRECT_MALLOC=GC_malloc \ -DHAVE_BOEHM_GC -DHAVE_GC_H -DUSE_INCLUDED_LIBGC -DHAVE_GC_GCJ_MALLOC -DHAVE_GC_ENABLE \ -D_GNU_SOURCE -DUSE_MMAP -DUSE_MUNMAP -D_FILE_OFFSET_BITS=64 -DNO_UNALIGNED_ACCESS \ -D__environ=environ MONO_LIBGC_CFLAGS := -DPACKAGE_NAME=\"libgc-mono\" -DPACKAGE_VERSION=\"6.6\" -DPACKAGE_STRING=\"libgc-mono\ 6.6\" \ -DGC_LINUX_THREADS=1 -D_REENTRANT=1 \ -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 \ -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 \ -DLT_OBJDIR=\".libs/\" -DSILENT=1 -DNO_SIGNALS=1 -DNO_EXECUTE_PERMISSION=1 \ -DGC_GCJ_SUPPORT=1 -DJAVA_FINALIZATION=1 -DATOMIC_UNCOLLECTABLE=1 -D_IN_LIBGC=1 \ MONO_INCLUDES := $(MONO_PATH)/ \ $(MONO_PATH)/mono/ \ $(MONO_PATH)/eglib/src/ \ $(MONO_PATH)/mono/mini/ \ $(MONO_PATH)/libgc/include \ $(LOCAL_PATH)/configs \ $(LOCAL_PATH)/configs/eglib \ $(LOCAL_PATH)/configs/mono/mini \ $(LOCAL_PATH)/configs/mono/arch/arm \ bionic/linker MONO_LDLIBS := -ldl # build 'libeglib' include $(CLEAR_VARS) LOCAL_MODULE := eglib LOCAL_MODULE_TAGS := eng LOCAL_PATH := $(MONO_PATH)/eglib/src LOCAL_SRC_FILES := garray.c gerror.c ghashtable.c gmem.c goutput.c \ gstr.c gslist.c gstring.c gptrarray.c glist.c gqueue.c gpath.c \ gshell.c gspawn.c gfile.c gfile-posix.c gpattern.c gmarkup.c \ gutf8.c gunicode.c gdate-unix.c gdir-unix.c gfile-unix.c \ gmisc-unix.c gmodule-unix.c gtimer-unix.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libmonoutils' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := monoutils LOCAL_MODULE_TAGS := eng LOCAL_PATH := $(MONO_PATH)/mono/utils LOCAL_SRC_FILES := mono-semaphore.c mono-md5.c \ mono-sha1.c mono-logger.c mono-codeman.c dlmalloc.h dlmalloc.c \ mono-counters.c mono-compiler.h mono-dl.c mono-dl.h \ mono-internal-hash.c mono-internal-hash.h \ mono-io-portability.c mono-io-portability.h monobitset.c \ mono-math.c mono-mmap.c mono-mmap.h mono-proclib.c \ mono-proclib.h mono-time.c mono-time.h strtod.h strtod.c \ strenc.h strenc.c mono-uri.c mono-poll.c mono-path.c \ mono-stdlib.c mono-property-hash.h mono-property-hash.c \ mono-value-hash.h mono-value-hash.c freebsd-elf_common.h \ freebsd-elf32.h freebsd-elf64.h freebsd-dwarf.h dtrace.h \ mono-filemap.c mono-networkinterfaces.c mono-error.c \ mono-publib.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -ldl include $(BUILD_STATIC_LIBRARY) # build 'libmonoruntime' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := monoruntime LOCAL_PATH := $(MONO_PATH)/mono/metadata LOCAL_SRC_FILES := runtime.c \ mono-basic-block.c mono-wsq.c mono-hash.c reflection.c object.c object-internals.h \ icall.c icall-def.h char-conversions.h decimal.c decimal.h \ boehm-gc.c sgen-gc.c sgen-gc.h gc.c gc-internal.h method-builder.h method-builder.c \ mono-mlist.c mono-mlist.h tabledefs.h threads-types.h threadpool-internals.h \ file-io.c file-io.h socket-io.c socket-io.h exception.c exception.h \ debug-mono-symfile.h debug-mono-symfile.c mono-debug.h mono-debug.c \ mono-debug-debugger.h mono-debug-debugger.c profiler-private.h attach.h attach.c \ rand.h rand.c security.c security.h security-core-clr.c security-core-clr.h \ string-icalls.c string-icalls.h sysmath.h sysmath.c process.c process.h \ environment.c environment.h locales.c locales.h normalization-tables.h \ filewatcher.c filewatcher.h culture-info.h culture-info-tables.h \ security-manager.c security-manager.h console-io.h console-unix.c \ coree.c coree.h domain.c domain-internals.h opcodes.c cil-coff.h \ metadata.c metadata-internals.h number-formatter.h verify.c verify-internals.h \ mono-endian.c mono-endian.h mono-config.c loader.c \ class.c class-internals.h wrapper-types.h mempool.c \ mono-perfcounters.c mono-perfcounters.h mono-perfcounters-def.h \ debug-helpers.c mempool-internals.h metadata-verify.c \ mono-cq.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libmonoruntimearm' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := monoruntimearm LOCAL_MODULE_TAGS := eng LOCAL_PATH := $(MONO_PATH)/mono/metadata LOCAL_SRC_FILES := \ monitor.c marshal.c threadpool.c threads.c appdomain.c \ profiler.c cominterop.c assembly.c image.c null-gc.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libwapi' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := wapi LOCAL_MODULE_TAGS := eng LOCAL_PATH := $(MONO_PATH)/mono/io-layer LOCAL_SRC_FILES := access.h atomic.c atomic.h \ collection.h context.c context.h critical-sections.c \ critical-sections.h critical-section-private.h error.c error.h \ events.c events.h event-private.h handles.h \ handles-private.h io.h io-portability.c io-portability.h \ io-private.h io-layer.h macros.h messages.c messages.h misc.c \ misc-private.h mutexes.c mutexes.h mutex-private.h \ mono-mutex.c mono-mutex.h mono-spinlock.h processes.c \ processes.h process-private.h security.c security.h \ semaphores.c semaphores.h semaphore-private.h shared.c \ shared.h sockets.c sockets.h socket-private.h \ socket-wrappers.h status.h system.c system.h \ threads.h thread-private.h timefuncs.c timefuncs.h \ timefuncs-private.h types.h uglify.h versioninfo.c \ versioninfo.h wait.c wait.h wapi_glob.h wapi_glob.c locking.c posix.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libwapiarm' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := wapiarm LOCAL_MODULE_TAG := eng LOCAL_PATH := $(MONO_PATH)/mono/io-layer LOCAL_SRC_FILES := collection.c io.c wthreads.c handles.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libgc' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := gc LOCAL_MODULE_TAG := eng LOCAL_PATH := $(MONO_PATH)/libgc LOCAL_SRC_FILES := allchblk.c blacklst.c \ checksums.c dyn_load.c \ headers.c mark.c \ new_hblk.c pcr_interface.c \ ptr_chck.c real_malloc.c solaris_pthreads.c \ solaris_threads.c specific.c stubborn.c backgraph.c \ win32_threads.c pthread_stop_world.c \ darwin_stop_world.c mach_dep.c LOCAL_CFLAGS := $(MONO_CFLAGS) $(MONO_LIBGC_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libgcarm' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := gcarm LOCAL_MODULE_TAG := eng LOCAL_PATH := $(MONO_PATH)/libgc LOCAL_SRC_FILES := alloc.c dbg_mlc.c finalize.c gc_dlopen.c gcj_mlc.c malloc.c \ mallocx.c mark_rts.c obj_map.c os_dep.c misc.c reclaim.c pthread_support.c typd_mlc.c LOCAL_CFLAGS := $(MONO_CFLAGS) $(MONO_LIBGC_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libmini' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := mini LOCAL_MODULE_TAG := eng LOCAL_PATH := $(MONO_PATH)/mono/mini LOCAL_SRC_FILES := mini.c method-to-ir.c \ xdebug.c decompose.c \ jit-icalls.c trace.c \ mini-arch.h dominators.c cfold.c regalloc.c \ helpers.c liveness.c ssa.c abcremoval.c ssapre.c \ local-propagation.c driver.c debug-mini.c \ linear-scan.c aot-runtime.c \ graph.c mini-exceptions.c mini-codegen.c mini-trampolines.c \ declsec.c wapihandles.c branch-opts.c \ mini-generic-sharing.c regalloc2.c simd-intrinsics.c \ unwind.h unwind.c mini-posix.c \ mini-arm.c exceptions-arm.c tramp-arm.c image-writer.c \ dwarfwriter.c mini-gc.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libminiarm' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := miniarm LOCAL_MODULE_TAG := eng LOCAL_PATH := $(MONO_PATH)/mono/mini LOCAL_SRC_FILES := aot-compiler.c debugger-agent.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) include $(BUILD_STATIC_LIBRARY) # build 'libmono' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := libmono LOCAL_MODULE_TAGS := eng LOCAL_PATH := $(MONO_PATH)/mono/mini LOCAL_SRC_FILES := mini.c method-to-ir.c \ xdebug.c decompose.c \ jit-icalls.c trace.c \ mini-arch.h dominators.c cfold.c regalloc.c \ helpers.c liveness.c ssa.c abcremoval.c ssapre.c \ local-propagation.c driver.c debug-mini.c \ linear-scan.c aot-runtime.c \ graph.c mini-exceptions.c mini-codegen.c mini-trampolines.c \ declsec.c wapihandles.c branch-opts.c \ mini-generic-sharing.c regalloc2.c simd-intrinsics.c \ unwind.h unwind.c mini-posix.c \ mini-arm.c exceptions-arm.c tramp-arm.c image-writer.c \ dwarfwriter.c mini-gc.c LOCAL_PRELINK_MODULE := false LOCAL_CFLAGS := $(MONO_CFLAGS) -fPIC LOCAL_C_INCLUDES := $(MONO_INCLUDES) LOCAL_WHOLE_STATIC_LIBRARIES := monoutils gcarm monoruntime LOCAL_STATIC_LIBRARIES := wapiarm monoruntimearm eglib gc wapi mini miniarm LOCAL_LDFLAGS := -Wall -L$(SYSROOT)/usr/lib -llog -ldl -lm -lc #LOCAL_STRIP_MODULE := false include $(BUILD_SHARED_LIBRARY) # build 'mono' include $(CLEAR_VARS) LOCAL_ARM_MODE := arm LOCAL_MODULE := mono LOCAL_MODULE_TAGS := eng LOCAL_PATH := $(MONO_PATH)/mono/mini LOCAL_SRC_FILES := main.c LOCAL_CFLAGS := $(MONO_CFLAGS) LOCAL_C_INCLUDES := $(MONO_INCLUDES) LOCAL_SHARED_LIBRARIES := libmono LOCAL_LDFLAGS := -llog -ldl -lm -lc include $(BUILD_EXECUTABLE)
長いですね・・・。あとでgithubかなんかに突っ込んで終わりにしたいですね。
Application.mkは適当に
APP_ABI := armeabi armeabi-v7a
とか書いておけば良いです。
あてるパッチはこんな感じです。
diff --git a/libgc/dyn_load.c b/libgc/dyn_load.c index e4be3c7..d8ce7ec 100644 --- a/libgc/dyn_load.c +++ b/libgc/dyn_load.c @@ -99,7 +99,9 @@ # if !defined(OPENBSD) # include <elf.h> # endif +# if defined(HAVE_LINK_H) # include <link.h> +# endif #endif /* Newer versions of GNU/Linux define this macro. We diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index a3c5746..867e437 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -38,8 +38,12 @@ #endif #ifdef HAVE_DL_ITERATE_PHDR +#ifdef PLATFORM_ANDROID +#include <linker.h> +#else #include <link.h> #endif +#endif #include <mono/metadata/tabledefs.h> #include <mono/metadata/class.h> @@ -59,6 +63,21 @@ #include "mono/utils/mono-compiler.h" #include <mono/utils/mono-counters.h> +#if defined(PLATFORM_ANDROID) +#ifdef PSR_c +#undef PSR_c +#endif +#ifdef PSR_x +#undef PSR_x +#endif +#ifdef PSR_s +#undef PSR_s +#endif +#ifdef PSR_f +#undef PSR_f +#endif +#endif + #include "mini.h" #include "version.h" diff --git a/mono/mini/mini-posix.c b/mono/mini/mini-posix.c index c15b098..92aa901 100644 --- a/mono/mini/mini-posix.c +++ b/mono/mini/mini-posix.c @@ -631,7 +631,7 @@ mono_runtime_syscall_fork () return (pid_t) syscall (SYS_fork); #else g_assert_not_reached (); - return; + return -1; #endif }
これもあとでどっかにファイルおくだけにしたいですね・・・。
さて残りはヘッダなんですが、ソースをそのまま貼り付けるとえらいことになるので、
あとでgithubにでも突っ込んでおきます。
突っ込んだらこの記事も更新するつもりです。