Android, once and for all!

I’m hoping I can get some help on how to build an android version of my app. I’ve maybe gone about this the wrong way but let me try and explain what I have so far:

  • Downloaded Urho3D
  • Exported Windows version and scaffolding project
  • Moved things around a little bit into their own folders (including moving Urho3DPlayer scaffolding files into another folder)
  • Built part of my game

Now the game was always intended for android, but I was using windows to develop it because it’s easier. Now I’ve come to the point where I need to be able to run it on android (which I should have done weeks ago).

I see Urho3D does not really support a scaffolding project for android very well. I can build Urho3D to android and run the samples. What I can’t figure out, is how to get it building for my scaffolding project with the code I already have. I’ve been trying for days with various forum posts and battling the NDK and the SDK at the same time.

Is there any good android support coming in soon? Does anyone have android working with an existing scaffolding project? Should I give up and just make windows games?

I understand the scaffolding project needs some setup. Mainly build.xml and android.manifest, but I know there’s some other steps that I still don’t know about.

Any help is appreciated.

Hey there KamiGrave, Welcome to the forums. Have you tried building the sample player / demos on Android? That seems to be a good starting scaffolding project so you can get familiar with Urho3D Android build.

I’ve gotten that far. Can run and play the samples, and even my own scripts. I’m coding in C++, so I only have a few test scripts that don’t run my main game.

But, while I can build my own project to a library, I haven’t been able to play it through the samples. I’ve been trying to use Urho3D as an external library, rather than writing my game into the engine code. Works great for PC, but it seems android has some hidden steps that I can’t find or figure out.

If I do figure it out, I might try and write a similar rake file for doing an android scaffold that will copy over res folders and whatever else it needs. First, I need to figure out how to get it running or give up on the game or switch engine again to one that’s a little bit more mobile friendly.

Have you considered importing your project to Android Studio? All you’d have to do build your project with cmake_android, passing a few build options, and import what’s build directly into Android Studio.

I attempted that but I can’t even get the scripts to run now. I’m at the point now where I’m ready to give up. It’ve wasted several days trying to get this to work and it just doesn’t, both on this existing project and a new one. Android studio doesn’t seem to import anything, the scripts now fail to run and for some reason cmake_android.bat makes it want to build for visual studio 2015.

All I need is some definitive guide to build the scaffolding project for android, and get it running using my own Urho3DPlayer.cpp, just like the windows one.

The only thing I’ve found on it is:

WARNING: As of this writing, this rake scaffolding task does not yet create a complete new project suitable for Android platform. You need to supply the missing bits manually yourself for now.

But it doesn’t tell me what bits are missing and what to do to get it running so I’ve been trying to piece information from several forum and github posts with nothing but errors from the SDK, NDK or Urho3D the entire way. The only thing I’ve been able to successfully run on android is the Urho3D samples.

Have you tried to setup an Android project before using Android Studio or what have you? If not then I suggest you learn to do that first. Although the rake task does not cover Android platform right now, you can always see how Urho3D sample app is being structured for Android platform and use that as the prototype.

I don’t even really want to use android studio at all. I’m fine building using ant and make, as it seems a lot simpler than importing the existing urho3D project as android-studio does not to a good job of it and then fails to recognise it as something it can build or run. It seems no matter what I do there’s hoops I need to jump through to get anything working.

I’ve seen how the sample app works too and had a go at modifying it so I could build a different application. But now my entire project is messed up because of some conflict between the version of Urho3D I’ve built for android and the original windows version (URHO3D_HOME is now pointing at the wrong version and my existing windows application now fails to build). Now nothing builds so I’m actually further away from a working solution than what I was when I started.
I’m giving up on it now because clearly no one has an answer how to actually solve this. There’s plenty of suggestions of things to try, or things to look at, but nothing on how to actually get it running.

Importing your build into Android Studio is really simple, takes less than 5 mins. Here’s the steps:

  1. make your build to a clean folder, I’m specifying my tool chain from android-ndk-r15c
cmake_android PathToCleanBuildFolder -DANDROID_TOOLCHAIN_NAME=x86-4.9 -DURHO3D_LUA=0 -DURHO3D_PACKAGING=0 -DURHO3D_TOOLS=0
  1. go into your build folder and build
make
  1. open your Android Studio and import your build
  • File -> New -> Import Project – and select your build folder

That simple. In Android Studio create an emulation device compatible with what’s defined in Urho3D/AndroidManifest.xml, and this example is a build for x86 device -> choose x86 emulation device.

OK. Fair enough, I didn’t know about specifying the toolchain, so that’s new to me.
But even after doing that, I end up with the android project I can already get working but now it’s in android-studio. I don’t see what advantage that gives me with trying to set up the scaffolding project for android. I just want a single codebase for windows and android with a bit of extra java to start the activity and call the C++ code.

Or even, what does the calling cmake_android on the scaffolding project actually do? Can I even support multiple platforms such as windows and android? Or do I need separate Urho3D builds and app folders?
It seems the only way I will be able to get it to work is to get the Urho3D samples calling my library (like it can do with the Urho3DPlayer) and copy and paste my code from windows into another project that’ll build it into a library that can be called from the Urho3D Activity.

I don’t mention scaffolding in my steps because it’s not used.
edit: to be honest, I never considered using scaffolding method nor did I even try because I wanted to focus on running my builds on Android Studio from the onset of discovering this engine.

Obviously, you’ll need a separate build folder for each platform.
edit2: and different build folder for each build options, e.g. build folder for winOpenGL, winDX9, androidArm, androidX86, etc.

@Lumak your instructions are very clear,however I have run into a problem while building against android-ndk-r16
Cmake seems to build fine and creates the new android build. However when I go to folder and make I run into this issue where it seems to run into trouble with the header files.

CreateProcess(C:\Users\Daniel\AppData\Local\Temp\make2440-1.bat,C:\Users\Daniel\AppData\Local\Temp\make2440-1.bat,…)
Live child 00000000026467E0 (Source/ThirdParty/FreeType/CMakeFiles/FreeType.dir/src/autofit/autofit.c.o) PID 40093120
In file included from C:/local/android-ndk-r16/sources/cxx-stl/llvm-libc++/include/limits.h:58:0,
from C:/local/Urho3D/Source/ThirdParty/FreeType/include/freetype/config/ftstdlib.h:59,
from C:/local/Urho3D/Source/ThirdParty/FreeType/include/freetype/config/ftconfig.h:43,
from C:/local/Urho3D/Source/ThirdParty/FreeType/include/freetype/freetype.h:33,
from C:/local/Urho3D/Source/ThirdParty/FreeType/src/autofit/aftypes.h:37,
from C:/local/Urho3D/Source/ThirdParty/FreeType/src/autofit/afangles.c:20,
from C:/local/Urho3D/Source/ThirdParty/FreeType/src/autofit/autofit.c:22:
c:\local\android-ndk-r16\toolchains\x86-4.9\prebuilt\windows-x86_64\lib\gcc\i686-linux-android\4.9.x\include-fixed\limits.h:168:61: error: no include path in which to search for limits.h
#include_next <limits.h> /* recurse down to the real one */
^
In file included from C:/local/Urho3D/Source/ThirdParty/FreeType/include/freetype/config/ftstdlib.h:78:0,
from C:/local/Urho3D/Source/ThirdParty/FreeType/include/freetype/config/ftconfig.h:43,
from C:/local/Urho3D/Source/ThirdParty/FreeType/include/freetype/freetype.h:33,
from C:/local/Urho3D/Source/ThirdParty/FreeType/src/autofit/aftypes.h:37,
from C:/local/Urho3D/Source/ThirdParty/FreeType/src/autofit/afangles.c:20,
from C:/local/Urho3D/Source/ThirdParty/FreeType/src/autofit/autofit.c:22:
C:/local/android-ndk-r16/sources/cxx-stl/llvm-libc++/include/string.h:61:25: fatal error: string.h: No such file or directory
#include_next <string.h>
^
compilation terminated.

I am not experienced using make files and don’t really know how to debug this. does anyone have any ideas?
I will try downloading ndk 15c and see if that is the problem.

I have downgraded to the ndk 15c and things are working much better. Perhaps this is something to report as a bug to the ndk repo?

@Lumak is it possible to list multiple toolchains arguments in a single call? I need armeabi for my device, but mips and x86 would also be desirable.

Yes, if you could report the compile error due to <string.h> not being found would be beneficial for all of us.

This was my very first post on the forum over two years ago, Deploying Urho3D to Android Studio in Windows
And at the time, you could specify multiple android targets, but that option got removed since then (don’t know which ndk version).

Easiest way to support multiple targets is by copying the alternate .so file from your build folder into android’s build jni folder. Search for how to deploy to multiple targets at the android studio website and you should get the answer, but the gist is:

  1. import your 1st build into android studio, let’s say it’s in urho3d/builds/androidx86
  2. build your 2nd target device, e.g. urho3d/builds/androidArm – don’t import this.
  3. In the urho3d/builds/androidArm/libs there is a folder specifying the target build, e.g ./armeabi-v7a. Copy the entire folder to the project that was imported in 1) under app\src\main\jniLibs. There should already be a target folder for x86.

That’s it. Now you support multiple devices.

Did you check how many users are out there using mips?

You know I didn’t, looks to be on death’s door. Which makes things simpler.

1

I tried Android Studio 3.01 and 2.3.3 and recive this error every time

Call the gradle task from CLI to get more information on the error.

Sorry, I’m noob. Explain in more detail what I should type (and where)

with -s option show more info, but that this will help

1

Executing tasks: [:app:assembleDebug]

Configuration on demand is an incubating feature.
Incremental java compilation is an incubating feature.
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:checkDebugManifest
:app:prepareDebugDependencies
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:processDebugManifest UP-TO-DATE
:app:processDebugResources UP-TO-DATE
:app:generateDebugSources UP-TO-DATE
:app:incrementalDebugJavaCompilationSafeguard UP-TO-DATE
:app:compileDebugJavaWithJavac UP-TO-DATE
:app:compileDebugNdk UP-TO-DATE
:app:compileDebugSources UP-TO-DATE
:app:mergeDebugShaders UP-TO-DATE
:app:compileDebugShaders UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:transformClassesWithDexForDebug UP-TO-DATE
:app:mergeDebugJniLibFolders UP-TO-DATE
:app:transformNative_libsWithMergeJniLibsForDebug UP-TO-DATE
:app:transformNative_libsWithStripDebugSymbolForDebug UP-TO-DATE
:app:processDebugJavaRes UP-TO-DATE
:app:transformResourcesWithMergeJavaResForDebug UP-TO-DATE
:app:validateSigningDebug
:app:packageDebug FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:packageDebug'.
> Self-suppression not permitted

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:packageDebug'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
	at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
	at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
	at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
	at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
	at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:153)
	at org.gradle.internal.Factories$1.create(Factories.java:22)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:150)
	at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
	at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
	at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
	at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
	at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
	at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:46)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:58)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
	at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
	at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:237)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
	at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
Caused by: java.lang.IllegalArgumentException: Self-suppression not permitted
	at com.android.build.gradle.tasks.PackageAndroidArtifact.doTask(PackageAndroidArtifact.java:467)
	at com.android.build.gradle.tasks.PackageAndroidArtifact.doFullTaskAction(PackageAndroidArtifact.java:321)
	at com.android.build.gradle.tasks.PackageApplication.doFullTaskAction(PackageApplication.java:75)
	at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:88)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
	at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:245)
	at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:221)
	at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:232)
	at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:210)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
	... 70 more
Caused by: java.lang.OutOfMemoryError: Java heap space


BUILD FAILED

Total time: 9.323 secs

EDIT:

with -s --debug option
https://pastebin.com/g1wLFgR2

If you are building on windows, check this