cancel
Showing results for 
Search instead for 
Did you mean: 

Native Standalone app

elwesties
Honored Guest
Hi all

I am currently starting development on a new Native Gear VR app. I have been trying to create a new Android studio project that is not tied to the SDK sample path. Eg running the make_new_project script creates a subdirectory in the VrSamples folder. However, trying to move that project out of that folder is impossible as it is tied to the structure of the SDK.

Does anyone have a sample project that manually imports the libs from the SDK and will compile independently of the SDK directory structure.
8 REPLIES 8

mduffor
Protege
Hehehe.... yeah, this is a giant pain in the ass, and one of the problems with the Mobile SDK I've griped about on here before.

I don't have a complete guide for you, since I'm still working out all the issues myself. I'm also building directly from the command line, not through Android Studio, and am on a Linux system. In general what I've done is:

* Copy VrSamples/Native/VrCubeWorld_NativeActivity into its own $HOME/workspace directory, where $HOME is my home directory on Linux. This is the sample code I'll get working outside of the sdk directory.

* Copy VrApi and VrAppSupport out of the SDK directory and into $HOME/workspace. This is cheating, but I haven't gotten setting the projectDir in settings.gradle to work for these projects yet.

* Go into VrCubeWorld_NativeActivity/Projects/Android/build.py and lobotomize the logic in init(). This is where it searches back up the tree from the current directory until it can find the "bin/scripts/build" path. I just comment everything out except the sys.path.append() line, and add "root = os.environ['OCULUS_SDK_PATH']" before it. I've defined OCULUS_SDK_PATH in my own environment variables to let the scripts know where I installed the Mobile SDK.

* In the $OCULUS_SDK_PATH/bin/scripts/build/ovrbuild.py file, comment out the build_sdk_libs() call in build(). There is no reason to build every mobile sdk library every time you compile. ovrbuild.py is where all the logic happens for how the gradle system is called, and then launching on the device if everything compiled correctly. The gradle build system will be called with "assembleDebug" or "assembleRelease" as the task to run.

* I copied Application.mk, build.gradle, and cflags.mk out of the $OCULUS_SDK_PATH and into my $HOME/workspace/VrCubeWorld_NativeActivity directory to make them local to my build. In Application.mk I comment out the lines that set ROOT_DIR and NDK_MODULE_PATH since I'm not using the libraries they reference.

* In $HOME/workspace/VrCubeWorld_NativeActivity/Projects/Android/settings.gradle I changed the rootProject.projectDir setting to only go back three directory levels instead of five. This is because I have the three projects (VrApi, VrAppSupport, and VrCubeWorld_NativeActivity) relative to my $HOME/workspace/ directory instead of $OCULUS_SDK_PATH. Also remove the "VrSamples:Native:" text from the start of the VrCubeWorld_NativeActivity since we are no longer nested so deeply. Finally, make sure the project is spelled VrCubeWorld_NativeActivity instead of VrCubeworld_NativeActivity because capitalization matters.

* In $HOME/workspace/VrCubeWorld_NativeActivity/Projects/Android/jni/Android.mk you can set which source files you are compiling from. If you are using CPP instead of C, remove the "-std=c99" setting or it will break the compiles. I don't think the Oculus samples actually ever make use of the cflags.mk file, but if you like you can add "include $(LOCAL_PATH)/../../../cflags.mk" after the LOCAL_PATH line. Just be sure that your LOCAL_CFLAGS and LOCAL_CPPFLAGS calls in Android.mk add instead of replace (use "+=" instead of ":=")

* Finally, in $HOME/workspace/VrCubeWorld_NativeActivity/Projects/Android/jni/Application.mk set your ROOT_DIR to go back three levels instead of six, because the Application.mk file we copied over is in our VrCubeWorld_NativeActivity directory instead of the Mobile SDK root directory.

I've probably missed something, since there are a lot of little things that need to be messed with. I'm also in the process of figuring out how to build my own static libraries and include them in the build. This requires a level of gradle dickery I'm not at all pleased with.

Once I have things 100% figured out and find some time (some time in 2016 no doubt), I'll try to put together some sort of tutorial / guide for this stuff. In the meantime, I'll do what I can to answer any questions here on the forums.

Cheers,
mduffor

elwesties
Honored Guest
Thanks for the response! I am working on it now and will report back if I can get it working.

mduffor
Protege
Some further notes for you:

The build system is composed of three levels: ndk-build which is based on make, Gradle, and build.py which calls ovrbuild.py. Each of these layers can be tested independently.

Call ndk-build from your Projects/Android directory to see if it can build the shared library .so files. This level uses the jni/Android.mk and jni/Application.mk files, as well as any other files included from those .mk files whether through an "include" directive or a $(call import-module) command. The NDK_MODULE_PATH used by import-module can be set in either the Android.mk or Application.mk file.

Note that the suggested approach in the NDK docs for including static library files does not work. You need to declare -L flags in LOCAL_EXPORT_LDFLAGS and -l for LOCAL_EXPORT_LDLIBS in any static libraries you build that you want to be included in the shared library. Maybe this won't affect you, but it wasted days of my time.

The Gradle level can be tested by calling "gradle assembleDebug" from your Projects/Android directory. It uses the settings.gradle, gradle.properties, and build.gradle files. It will also call ndk-build directly, so make sure you've tested that layer first. The suggested Gradle approach for building sub projects is rather broken. If you need to use Gradle for building libraries, then you need to set up an Exec type task to call gradle directly, and then set up a dependency so it runs. That would look something like this:


task buildCrowComponent(type: Exec) {
commandLine 'gradle', 'assembleRelease'
workingDir project(':crow:component:Projects:Android').projectDir
}

project.afterEvaluate {
assembleRelease.dependsOn 'buildCrowComponent'
}

I think I was finally able to get gradle to recognize the external path to the Mobile SDK directory by defining OCULUS_SDK_PATH in gradle.properties (as well as my environment variables), then including OCULUS_SDK_PATH in my NDK_MODULE_PATH in Application.mk so ndk-build could find it. I haven't had a chance to go back to my sample project to test it out, but it seems to be working in my main project now.

The build.py level calls "gradle assembleDebug", "gradle clean", or "gradle assembleRelease" based on the flags you pass it. It also handles all the adb commands for installing and running on your attached phone upon a successful build. As mentioned in my previous post, you can control where ovrbuild.py is located by changing the logic in build.py

Hope this helps,
mduffor

elwesties
Honored Guest
Thank you for all your help. I managed to get it working and the only real thing missing was that I had to also copy the VrAppFramework lib into my project directory as well. I have run out of time to mess with the build to much but in the future I hope to fully like all the files to the sdk directory rather than manually copy them.

8bit
Protege
Hello @elwesties

I created a base project, based on VrCubeWorld_Framework, where I separated out the actual VrCubeWorld stuff from the main application code. I also moved all Oculus libraries into a Vendor folder, and I load the shaders from asset files instead of inlining in code.
Best of all, you can get some Intellisense with a working Visual Studio 2015 project and solution. You can't build with VS but Intellisense seems to be working perfectly thus far. You write your C++ code in VS, then build and do Java stuff in Android Studio - not ideal but better than being without Intellisense.

I have been working on two machines and syncing back and forth so chances of this working your machine should be pretty good.

https://github.com/8BitRick/GearVRNative

Take a look and see if this is helpful for you.

elwesties
Honored Guest
Hey 8bit that worked a treat! Thanks, I have forked your repo and if I encounter any issues i'll see what I can do. For anyone reading this in the future, this is the place to start. 😄

8bit
Protege
@elwesties,

I found that sometimes it will crash on start in BuildProgram, while trying to build shaders. It sometimes pulls in garbage characters when reading the shader files. I'm not sure why this happens but it is random. Just run again if this happens. I will eventually get around to looking into this and fixing it. Just letting you know.

hiteshsarsava
Honored Guest
I am facing the issue for finding OCULUS_SDK_PATH. Please see the below time stacktree of errors in android studio. Please help me to sort out this problem

BUILD FAILED in 6s
Traceback (most recent call last):

  File "/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/bin/scripts/build/ovrbuild_sdklibs.py", line 38, in <module>

    build_sdk_libs()
building in /Users/admin/Downloads/ovr_sdk_mobile_1.29.0
  File "/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/bin/scripts/build/ovrbuild_sdklibs.py", line 34, in build_sdk_libs
/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/bin/scripts/build/../../../gradlew assembleDebug --no-daemon -quiet -Pdisable_sig_check --build-cache --configure-on-demand --parallel
    ovrbuild.build_in_dir(os.environ['OCULUS_SDK_PATH'])
/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/bin/scripts/build/../../../gradlew assembleDebug --no-daemon -quiet -Pdisable_sig_check --build-cache --configure-on-demand --parallel

FAILURE: Build failed with an exception.

* What went wrong:
  File "/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/bin/scripts/build/ovrbuild.py", line 308, in build_in_dir
Could not create service of type ScriptPluginFactory using BuildScopeServices.createScriptPluginFactory().
    run_gradle_task(command_options, 'assembleDebug', args)
> Could not create service of type PluginResolutionStrategyInternal using BuildScopeServices.createPluginResolutionStrategy().
  File "/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/bin/scripts/build/ovrbuild.py", line 296, in run_gradle_task

    call(command)
* Try:
  File "/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/bin/scripts/build/ovrbuild.py", line 226, in call
    raise BuildFailedException(error_string)
ovrbuild.BuildFailedException
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.


> Task :VrSamples:Vr360PhotoViewer:Projects:Android:buildSdkLibsDebug FAILED

FAILURE: Build failed with an exception.

* Where:
Script '/Users/admin/Downloads/ovr_sdk_mobile_1.29.0/VrApp.gradle' line: 368

* What went wrong:
Execution failed for task ':VrSamples:Vr360PhotoViewer:Projects:Android:buildSdkLibsDebug'.
> Process 'command 'python'' finished with non-zero exit value 1

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.


Deprecated Gradle features were used in this build, making it incompatible with Gradle 6.0.
Use '--warning-mode all' to show the individual deprecation warnings.


BUILD FAILED in 8s
1 actionable task: 1 executed