{"id":368,"date":"2010-07-21T14:14:26","date_gmt":"2010-07-21T20:14:26","guid":{"rendered":"http:\/\/www.philhassey.com\/blog\/?p=368"},"modified":"2010-07-28T14:16:59","modified_gmt":"2010-07-28T20:16:59","slug":"android-day-2-the-ndk","status":"publish","type":"post","link":"https:\/\/www.philhassey.com\/blog\/2010\/07\/21\/android-day-2-the-ndk\/","title":{"rendered":"Android Day 2: The NDK"},"content":{"rendered":"<p>The goal today is to get the Galcon codebase to compile using the NDK. \u00a0This will create a single .so file which will be accessed via JNI.<\/p>\n<p><strong>Step 1 &#8211; Downloading the NDK:<\/strong><\/p>\n<p>Download the NDK for native C\/C++ code. \u00a0I plan on doing as little Java as possible, so I&#8217;m going to find out how well this stuff works.<\/p>\n<p><a href=\"http:\/\/developer.android.com\/sdk\/ndk\/index.html\">http:\/\/developer.android.com\/sdk\/ndk\/index.html<\/a><\/p>\n<p><strong>Step 2 &#8211; Building a NDK sample:<\/strong><\/p>\n<p>Trying to build an NDK sample. \u00a0I went into ndk\/samples\/&lt;whatever&gt; and ran ..\/..\/ndk-build (as per instructions in previous link). \u00a0This worked fine.<\/p>\n<p>But when running in Eclipse, I had some trouble with some examples, but not with some of the other ones. \u00a0I&#8217;m not sure what that is about, but for now I&#8217;m going to forge on and not worry about it.<\/p>\n<p><strong>Step 3 &#8211; Preparing my project for the NDK:<\/strong><\/p>\n<p>I&#8217;ve created an android folder in my Galcon project for storing all this ports info. \u00a0I&#8217;ve created<\/p>\n<p>android\/jni\/ # a folder<\/p>\n<p>android\/jni\/Android.mk # a makefile containing<\/p>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">LOCAL_PATH := $(call my-dir)<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">include $(CLEAR_VARS)<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">LOCAL_MODULE := igalcon2<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">SRCDIR := ..\/..\/src<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">LOCAL_CFLAGS := -DANDROID_NDK \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">-DDISABLE_IMPORTGL \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">-DHAS_SOCKETLEN_T \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">-DBUILD_IGALCON2 \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">-DBUILD_ANDROID \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">-DGC_BUILD_ANDROID<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">LOCAL_C_INCLUDES := \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(LOCAL_PATH)\/..\/..\/src \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(LOCAL_PATH)\/..\/..\/src\/igalcon1 \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(LOCAL_PATH)\/..\/..\/src\/igalcon1\/enet<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">LOCAL_SRC_FILES := \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">importgl.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/main.cpp $(SRCDIR)\/data.cpp $(SRCDIR)\/driver-sdl.cpp $(SRCDIR)\/timer.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/game2.cpp $(SRCDIR)\/level.cpp $(SRCDIR)\/mygl.cpp \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/menu.cpp $(SRCDIR)\/theme.cpp $(SRCDIR)\/myview.cpp $(SRCDIR)\/pause.cpp \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/settings.cpp $(SRCDIR)\/multi.cpp $(SRCDIR)\/help.cpp \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/server.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/game.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/level.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/states.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/engine.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/menu.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/missions.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/net.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/multi.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/client.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/web.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/timer.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/md5.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/viewgl.c \\<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">$(SRCDIR)\/igalcon1\/enet\/*.c<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog<\/div>\n<div id=\"_mcePaste\" style=\"position: absolute; left: -10000px; top: 290px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;\">include $(BUILD_SHARED_LIBRARY)<\/div>\n<p style=\"padding-left: 30px;\">LOCAL_PATH := $(call my-dir)<\/p>\n<p style=\"padding-left: 30px;\">include $(CLEAR_VARS)<\/p>\n<p style=\"padding-left: 30px;\">LOCAL_MODULE := igalcon2<\/p>\n<p style=\"padding-left: 30px;\">LOCAL_CFLAGS := #VARIOUS C FLAGS for define hacks<\/p>\n<p style=\"padding-left: 30px;\">LOCAL_C_INCLUDES := \u00a0#VARIOUS INCLUDE FOLDERS, RELATIVE TO android\/jni\/, so ..\/..\/src<\/p>\n<p style=\"padding-left: 30px;\">LOCAL_SRC_FILES := #The c files, ..\/..\/src\/whatever.c<\/p>\n<p style=\"padding-left: 30px;\">LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog<\/p>\n<p style=\"padding-left: 30px;\">include $(BUILD_SHARED_LIBRARY)<\/p>\n<p>android\/default.properties # a file needed to build properly<\/p>\n<p>this file must contain:<\/p>\n<p>&#8220;target=android-4&#8221; for GLES<\/p>\n<p>It instructs ndk-build which platform we&#8217;re using. \u00a0Without it, the NDK can&#8217;t find the GLES headers.<\/p>\n<p>Then I was able to run ndk-build while in the android folder and it started building my project.<\/p>\n<p><strong>Step 4 &#8211; OpenGL Includes:<\/strong><\/p>\n<p>I had to manage some various quirks in the C code and whatnot as I went.<\/p>\n<p>The includes for GLES:<\/p>\n<p>#include &lt;GLES\/gl.h&gt;<\/p>\n<p>#include &lt;GLES\/glext.h&gt;<\/p>\n<p><strong>Step 5 &#8211; Installing a port of STL for the NDK:<\/strong><\/p>\n<p>Then I found that STL is not supported in the NDK. \u00a0So I grabbed stlport from www.stlport.org .. Not needing iostream, etc myself, I just moved the stlport folder over so I could include templates from it. \u00a0This gave endianess and compiler unrecognized type errors. \u00a0Found this android specific STL port (should be patched into newer versions of stlport eventually.)<\/p>\n<p><a href=\"http:\/\/www.anddev.org\/viewtopic.php?p=29939\">http:\/\/www.anddev.org\/viewtopic.php?p=29939<\/a><\/p>\n<p>I had to add this to my CPPFLAGS:\u00a0-D_STLP_USE_SIMPLE_NODE_ALLOC to avoid having it complain &#8220;stlport\/stl\/_alloc.h:210: undefined reference to `std::__node_alloc::_M_allocate(unsigned int&amp;)&#8221;<\/p>\n<p>&#8212;<\/p>\n<p>From here it looks like a long way till I have a port working though. \u00a0I need to get graphics rendering, touch input, keyboard input, music handling, and other little things that just make the game work. \u00a0If anyone can give me tips on this tonight, feel free \ud83d\ude42 \u00a0I&#8217;m not excited about using JNI for all this. \u00a0I&#8217;ve heard there are SDL ports, which I&#8217;m going to be considering. \u00a0I also hear I&#8217;ve got to download all the game assets separately from the game itself, which seems painful. \u00a0Time will tell on if this port will work out.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The goal today is to get the Galcon codebase to compile using the NDK. \u00a0This will create a single .so file which will be accessed via JNI. Step 1 &#8211; Downloading the NDK: Download the NDK for native C\/C++ code. \u00a0I plan on doing as little Java as possible, so I&#8217;m going to find out [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[112,20],"tags":[],"class_list":["post-368","post","type-post","status-publish","format-standard","hentry","category-android","category-galcon"],"_links":{"self":[{"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/posts\/368","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/comments?post=368"}],"version-history":[{"count":10,"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/posts\/368\/revisions"}],"predecessor-version":[{"id":429,"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/posts\/368\/revisions\/429"}],"wp:attachment":[{"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/media?parent=368"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/categories?post=368"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.philhassey.com\/blog\/wp-json\/wp\/v2\/tags?post=368"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}