Browse Source

Misc. fixes and enhancement for Android platform.
- Add initial support for ndk-gdb. Enable via new 'URHO3D_NDK_GDB' build option.
- Enhance rake android task: more effective loop to wait for Android device, ability to pick library to run from SampleLauncher from the adb shell.
- Fix "buildvm" tool name for Android to derive from the correct NDK ABI CMake's variable.
- Fix Android toolchain to copy shared STL library to the correct Android library output directory.

Yao Wei Tjong 姚伟忠 11 years ago
parent
commit
0fb99af9e4

+ 1 - 0
Docs/GettingStarted.dox

@@ -172,6 +172,7 @@ A number of build options can be defined explicitly when invoking the above cmak
 |URHO3D_STATIC_RUNTIME|0|Use static C/C++ runtime libraries and eliminate the need for runtime DLLs installation (VS only)|
 |URHO3D_STATIC_RUNTIME|0|Use static C/C++ runtime libraries and eliminate the need for runtime DLLs installation (VS only)|
 |URHO3D_LIB_TYPE      |*|Specify Urho3D library type, possible values are STATIC (\*default) and SHARED|
 |URHO3D_LIB_TYPE      |*|Specify Urho3D library type, possible values are STATIC (\*default) and SHARED|
 |URHO3D_SCP_TO_TARGET |-|Use scp to transfer executables to target system (non-Android cross-compiling build only), SSH digital key must be setup first for this to work, typical value has a pattern of usr@tgt:remote-loc|
 |URHO3D_SCP_TO_TARGET |-|Use scp to transfer executables to target system (non-Android cross-compiling build only), SSH digital key must be setup first for this to work, typical value has a pattern of usr@tgt:remote-loc|
+|URHO3D_NDK_GDB       |0|Enable ndk-gdb for debugging (Android build only)|
 |CMAKE_BUILD_TYPE     |*|Specify CMake build configuration to be generated (Makefile generator only), possible values are Release (\*default), Debug, and RelWithDebInfo|
 |CMAKE_BUILD_TYPE     |*|Specify CMake build configuration to be generated (Makefile generator only), possible values are Release (\*default), Debug, and RelWithDebInfo|
 |CMAKE_OSX_DEPLOYMENT_TARGET|-|Specify Mac OS X deployment target (OSX build only); default to current running OS X if not specified|
 |CMAKE_OSX_DEPLOYMENT_TARGET|-|Specify Mac OS X deployment target (OSX build only); default to current running OS X if not specified|
 |IPHONEOS_DEPLOYMENT_TARGET|-|Specify iPhone OS deployment target (iOS build only); default to latest installed iOS SDK if not specified|
 |IPHONEOS_DEPLOYMENT_TARGET|-|Specify iPhone OS deployment target (iOS build only); default to latest installed iOS SDK if not specified|

+ 33 - 41
Rakefile

@@ -51,22 +51,22 @@ task :scaffolding do
   end
   end
 end
 end
 
 
-# Usage: rake android [intent=.SampleLauncher] [package=com.github.urho3d] [success_indicator='Initialized engine'] [payload='input tap 10 200'] [timeout=30] [api=19] [abi=armeabi-v7a] [avd=test] [retries=10] [retry_interval=10]
+# Usage: rake android [parameter='--es pickedLibrary Urho3DPlayer'] [intent=.SampleLauncher] [package=com.github.urho3d] [success_indicator='Initialized engine'] [payload='sleep 30'] [api=19] [abi=armeabi-v7a] [avd=test_#{api}_#{abi}] [retries=10] [retry_interval=10]
 desc 'Test run already installed APK in Android (virtual) device, default to Urho3D Samples APK if no parameter is given'
 desc 'Test run already installed APK in Android (virtual) device, default to Urho3D Samples APK if no parameter is given'
 task :android do
 task :android do
+  parameter = ENV['parameter'] || '--es pickedLibrary Urho3DPlayer'
   intent = ENV['intent'] || '.SampleLauncher'
   intent = ENV['intent'] || '.SampleLauncher'
   package = ENV['package'] || 'com.github.urho3d'
   package = ENV['package'] || 'com.github.urho3d'
-  success_indicator = ENV['success_indicator'] || (intent == '.SampleLauncher' ? 'Initialized engine' : '')
-  payload = ENV['payload'] || (intent == '.SampleLauncher' ? 'input tap 10 200' : '')
-  timeout = ENV['timeout'] || 30
+  success_indicator = ENV['success_indicator'] || 'Initialized engine'
+  payload = ENV['payload'] || 'sleep 30'
   api = ENV['api'] || 19
   api = ENV['api'] || 19
   abi = ENV['abi'] || 'armeabi-v7a'
   abi = ENV['abi'] || 'armeabi-v7a'
-  avd = ENV['avd'] || 'test'
+  avd = ENV['avd'] || "test_#{api}_#{abi}"
   retries = ENV['retries'] || 10 # minutes
   retries = ENV['retries'] || 10 # minutes
   retry_interval = ENV['retry_interval'] || 10 # seconds
   retry_interval = ENV['retry_interval'] || 10 # seconds
   android_prepare_device api, abi, avd or abort 'Failed to prepare Android (virtual) device for test run'
   android_prepare_device api, abi, avd or abort 'Failed to prepare Android (virtual) device for test run'
   android_wait_for_device retries, retry_interval or abort 'Failed to start Android (virtual) device'
   android_wait_for_device retries, retry_interval or abort 'Failed to start Android (virtual) device'
-  android_test_run intent, package, success_indicator, payload, timeout or abort "Failed to test run #{package}/#{intent}, make sure the APK has been installed"
+  android_test_run parameter, intent, package, success_indicator, payload or abort "Failed to test run #{package}/#{intent}, make sure the APK has been installed"
 end
 end
 
 
 # Usage: NOT intended to be used manually (if you insist then try: rake ci)
 # Usage: NOT intended to be used manually (if you insist then try: rake ci)
@@ -356,13 +356,15 @@ def makefile_ci
   end
   end
 end
 end
 
 
-def android_find_device api = $specific_api, abi = $specific_abi
-  $specific_api = api
-  $specific_abi = abi
-  $specific_device = nil
-  for i in `adb devices |tail -n +2`.split "\n"
+def android_find_device api = nil, abi = nil
+  # Return the previously found matching device or if not found yet then try to find the matching device now
+  return $specific_device if $specific_device
+  wait = api ? '' : 'wait-for-device'
+  $specific_api = api.to_s if api
+  $specific_abi = abi.to_s if abi
+  for i in `adb #{wait} devices |tail -n +2`.split "\n"
     device = i.split.first
     device = i.split.first
-    if api.to_s == `adb -s #{device} wait-for-device shell getprop ro.build.version.sdk`.chomp && abi.to_s == `adb -s #{device} shell getprop ro.product.cpu.abi`.chomp
+    if `adb -s #{device} wait-for-device shell getprop ro.build.version.sdk`.chomp == $specific_api && `adb -s #{device} shell getprop ro.product.cpu.abi`.chomp == $specific_abi
       return $specific_device = device
       return $specific_device = device
     end
     end
   end
   end
@@ -376,39 +378,33 @@ def android_prepare_device api, abi = 'armeabi-v7a', name = 'test'
     if !system "android list avd |grep -cq 'Name: #{name}$'"
     if !system "android list avd |grep -cq 'Name: #{name}$'"
       system "echo 'no' |android create avd -n #{name} -t android-#{api} --abi #{abi}" or abort "Failed to create '#{name}' Android virtual device"
       system "echo 'no' |android create avd -n #{name} -t android-#{api} --abi #{abi}" or abort "Failed to create '#{name}' Android virtual device"
     end
     end
-    system "if [ $CI ]; then export OPTS='-no-skin -no-audio -no-window -no-boot-anim -gpu off'; else export OPTS='-gpu on'; fi; ANDROID_TMP=~ emulator -avd #{name} $OPTS &"
+    system "if [ $CI ]; then export OPTS='-no-skin -no-audio -no-window -no-boot-anim -gpu off'; else export OPTS='-gpu on'; fi; emulator -avd #{name} $OPTS &"
   end
   end
   return 0
   return 0
 end
 end
 
 
-def android_wait_for_device retries = -1, retry_interval = 10, package = 'com.android.launcher'
+def android_wait_for_device retries = -1, retry_interval = 10, package = 'android.process.acore'  # Waiting for HOME by default
   # Wait until the indicator process is running or it is killed externally by user via Ctrl+C or when it exceeds the number of retries (if the retries parameter is provided)
   # Wait until the indicator process is running or it is killed externally by user via Ctrl+C or when it exceeds the number of retries (if the retries parameter is provided)
-  print "\nWaiting for device..."; $stdout.flush
-  # Find the specific device in case it is not found earlier
-  $specific_device = android_find_device unless $specific_device
-  if $specific_device
-    # Capture adb's stdout and interpret it because adb does not return exit code from its last shell command
-    thread = Thread.new { `adb -s #{$specific_device} shell 'until ps |grep -c #{package} >/dev/null; do sleep #{retry_interval}; done; while ps |grep -c bootanimation >/dev/null; do sleep 1; done'` }
-    sleep 1
-    retries = retries * 60 / retry_interval unless retries == -1
-    until retries == 0
-      if thread.status == false
-        thread.join
-        break
-      end
-      sleep retry_interval
-      print '.'; $stdout.flush  # Flush the standard output stream in case it is buffered to prevent Travis-CI into thinking that the build/test has stalled
-      retries -= 1 if retries > 0
+  str = "\nWaiting for device..."
+  thread = Thread.new { android_find_device }; sleep 0.5
+  process_ready = false
+  retries = retries * 60 / retry_interval unless retries == -1
+  until retries == 0
+    if thread.status == false
+      thread.join
+      break if process_ready
+      process_ready = thread = Thread.new { `adb -s #{$specific_device} shell 'until ps |grep -c #{package} >/dev/null; do sleep #{retry_interval}; done; while ps |grep -c bootanimation >/dev/null; do sleep 1; done'` }; sleep 0.5
+      next
     end
     end
-  else
-    # No matching device found
-    retries = 0
+    print str; str = '.'; $stdout.flush   # Flush the standard output stream in case it is buffered to prevent Travis-CI into thinking that the build/test has stalled
+    sleep retry_interval
+    retries -= 1 if retries > 0
   end
   end
-  puts "\n\n"; $stdout.flush
+  puts "\n\n" if str == '.'; $stdout.flush
   return retries == 0 ? nil : 0
   return retries == 0 ? nil : 0
 end
 end
 
 
-def android_test_run intent = '.SampleLauncher', package = 'com.github.urho3d', success_indicator = 'Added resource path /apk/CoreData/', payload = 'input tap 10 200', timeout = 30
+def android_test_run parameter = '--es pickedLibrary Urho3DPlayer', intent = '.SampleLauncher', package = 'com.github.urho3d', success_indicator = 'Added resource path /apk/CoreData/', payload = 'sleep 30'
   # The device should have been found at this point
   # The device should have been found at this point
   return nil unless $specific_device
   return nil unless $specific_device
   # Capture adb's stdout and interpret it because adb neither uses stderr nor returns proper exit code on error
   # Capture adb's stdout and interpret it because adb neither uses stderr nor returns proper exit code on error
@@ -419,15 +415,11 @@ input keyevent 82; input keyevent 4
 # Clear the log
 # Clear the log
 logcat -c
 logcat -c
 # Start the app
 # Start the app
-am start -a android.intent.action.MAIN -n #{package}/#{intent}
+am start -a android.intent.action.MAIN -n #{package}/#{intent} #{parameter}
 # Wait until the process is running
 # Wait until the process is running
 until ps |grep -c #{package} 1>/dev/null; do sleep 1; done
 until ps |grep -c #{package} 1>/dev/null; do sleep 1; done
-# Make sure the app is on the foreground
-sleep 3 && am start -n #{package}/#{intent} && sleep 3
-# Execute the payload, the default payload is a single tap to launch Urho3DPlayer which in turn runs NinjaSnowWar.as
+# Execute the payload
 #{payload}
 #{payload}
-# Let it runs for a while
-sleep #{timeout}
 # Exit and stop the app
 # Exit and stop the app
 input keyevent 4 && am force-stop #{package}
 input keyevent 4 && am force-stop #{package}
 # Dump the log
 # Dump the log

+ 1 - 0
Readme.txt

@@ -489,6 +489,7 @@ cmake_xxxx batch files or shell scripts.
 |                     | | Android cross-compiling build only), SSH digital key |
 |                     | | Android cross-compiling build only), SSH digital key |
 |                     | | must be setup first for this to work, typical value  |
 |                     | | must be setup first for this to work, typical value  |
 |                     | | has a pattern of usr@tgt:remote-loc                  |
 |                     | | has a pattern of usr@tgt:remote-loc                  |
+|URHO3D_NDK_GDB       |0|Enable ndk-gdb for debugging (Android build only)     |
 |CMAKE_BUILD_TYPE     |*|Specify CMake build configuration to be generated     |
 |CMAKE_BUILD_TYPE     |*|Specify CMake build configuration to be generated     |
 |                     | | (Makefile generator only), possible values are       |
 |                     | | (Makefile generator only), possible values are       |
 |                     | | Release (*default), Debug, and RelWithDebInfo        |
 |                     | | Release (*default), Debug, and RelWithDebInfo        |

+ 2 - 1
Source/Android/res/layout/samples_list_text_view.xml

@@ -5,6 +5,7 @@
     android:layout_height="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="center_vertical"
     android:gravity="center_vertical"
     android:paddingBottom="14dp"
     android:paddingBottom="14dp"
-    android:paddingLeft="24dp"
     android:paddingTop="14dp"
     android:paddingTop="14dp"
+    android:paddingLeft="14dp"
+    android:paddingRight="14dp"
     android:textSize="22sp" />
     android:textSize="22sp" />

+ 4 - 4
Source/Android/src/com/github/urho3d/SampleLauncher.java

@@ -33,16 +33,16 @@ import android.widget.ListView;
 
 
 public class SampleLauncher extends ListActivity {
 public class SampleLauncher extends ListActivity {
 
 
-    public static final String LIBRARY_NAMES = "LIBRARY_NAMES";
-    public static final String PICKED_LIBRARY = "PICKED_LIBRARY";
+    public static final String LIBRARY_NAMES = "libraryNames";
+    public static final String PICKED_LIBRARY = "pickedLibrary";
     private static final int OBTAINING_LIBNAMES = 1;
     private static final int OBTAINING_LIBNAMES = 1;
 
 
     @Override
     @Override
     public void onCreate(Bundle savedInstanceState) {
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         super.onCreate(savedInstanceState);
 
 
-        // Start Urho3D activity with the intention for obtaining the library name(s)
-        startActivityForResult(new Intent(this, Urho3D.class), OBTAINING_LIBNAMES);
+        // Start Urho3D activity with the intention for obtaining the library name(s), except when a library is already being picked externally
+        startActivityForResult(new Intent(this, Urho3D.class).putExtra(PICKED_LIBRARY, getIntent().getStringExtra(PICKED_LIBRARY)), OBTAINING_LIBNAMES);
 
 
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

+ 8 - 1
Source/Android/src/org/libsdl/app/SDLActivity.java

@@ -3,6 +3,7 @@
 package org.libsdl.app;
 package org.libsdl.app;
 
 
 import java.io.File;
 import java.io.File;
+import java.io.FilenameFilter;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Collections;
@@ -88,7 +89,13 @@ public class SDLActivity extends Activity {
         String libraryPath = getApplicationInfo().nativeLibraryDir;
         String libraryPath = getApplicationInfo().nativeLibraryDir;
         //Log.v(TAG, "library path: " + libraryPath);
         //Log.v(TAG, "library path: " + libraryPath);
         if (!mIsSharedLibraryLoaded) {
         if (!mIsSharedLibraryLoaded) {
-            File[] files = new File(libraryPath).listFiles();
+            File[] files = new File(libraryPath).listFiles(new FilenameFilter() {
+                @Override
+                public boolean accept(File dir, String filename) {
+                    // Only list libraries, i.e. exclude gdbserver when it presents
+                    return filename.matches("^lib.*\\.so$");
+                }
+            });
             Arrays.sort(files, new Comparator<File>() {
             Arrays.sort(files, new Comparator<File>() {
                 @Override
                 @Override
                 public int compare(File lhs, File rhs) {
                 public int compare(File lhs, File rhs) {

+ 35 - 4
Source/CMake/Modules/Urho3D-CMake-common.cmake

@@ -53,7 +53,7 @@ if (NOT MSVC)
         string (REGEX MATCH "#define +__arm__ +1" matched "${PREDEFINED_MACROS}")
         string (REGEX MATCH "#define +__arm__ +1" matched "${PREDEFINED_MACROS}")
         if (matched)
         if (matched)
             # Set the CMake variable here instead of in raspberrypi.toolchain.cmake because Raspberry Pi can be built natively too
             # Set the CMake variable here instead of in raspberrypi.toolchain.cmake because Raspberry Pi can be built natively too
-            set (RASPI TRUE)
+            set (RASPI TRUE CACHE STRING "Setup build for Raspberry Pi platform")
         endif ()
         endif ()
     endif ()
     endif ()
 endif ()
 endif ()
@@ -115,9 +115,12 @@ else ()
     unset (URHO3D_SCP_TO_TARGET CACHE)
     unset (URHO3D_SCP_TO_TARGET CACHE)
 endif ()
 endif ()
 if (ANDROID)
 if (ANDROID)
-    set (ANDROID_ABI armeabi-v7a CACHE STRING "Specify ABI for native code (Android build only), possible values are armeabi-v7a (default) and armeabi")
+    set (ANDROID TRUE CACHE STRING "Setup build for Android platform")  # Cache the CMake variable
+    set (ANDROID_ABI armeabi-v7a CACHE STRING "Specify ABI for native code (Android build only), possible values are armeabi, armeabi-v7a (default), armeabi-v7a with NEON, armeabi-v7a with VFPV3, armeabi-v6 with VFP, arm64-v8a, x86, and x86_64")
+    cmake_dependent_option (URHO3D_NDK_GDB "Enable ndk-gdb for debugging (Android build only)" FALSE "CMAKE_BUILD_TYPE STREQUAL Debug" FALSE)
 else ()
 else ()
     unset (ANDROID_ABI CACHE)
     unset (ANDROID_ABI CACHE)
+    unset (URHO3D_NDK_GDB CACHE)
     if (ANDROID_ABI)
     if (ANDROID_ABI)
         # Just reference it to suppress "unused variable" CMake warning on non-Android project
         # Just reference it to suppress "unused variable" CMake warning on non-Android project
         # Due to the design of cmake_gcc.sh currently, the script can be used to configure/generate Android project and other non-Android projects in one go
         # Due to the design of cmake_gcc.sh currently, the script can be used to configure/generate Android project and other non-Android projects in one go
@@ -375,6 +378,24 @@ elseif (CMAKE_CROSSCOMPILING)
 endif ()
 endif ()
 set_output_directories (${PROJECT_ROOT_DIR}/${PLATFORM_PREFIX}Bin RUNTIME PDB)
 set_output_directories (${PROJECT_ROOT_DIR}/${PLATFORM_PREFIX}Bin RUNTIME PDB)
 
 
+# Enable Android ndk-gdb
+if (URHO3D_NDK_GDB)
+    set (NDK_GDB_SOLIB_PATH ${PROJECT_BINARY_DIR}/obj/local/${ANDROID_NDK_ABI_NAME}/)
+    file (MAKE_DIRECTORY ${NDK_GDB_SOLIB_PATH})
+    set (NDK_GDB_JNI ${PROJECT_BINARY_DIR}/jni)
+    set (NDK_GDB_MK "# This is a generated file. DO NOT EDIT!\n\nAPP_ABI := ${ANDROID_NDK_ABI_NAME}\n")
+    foreach (MK Android.mk Application.mk)
+        if (NOT EXISTS ${NDK_GDB_JNI}/${MK})
+            file (WRITE ${NDK_GDB_JNI}/${MK} ${NDK_GDB_MK})
+        endif ()
+    endforeach ()
+    get_directory_property (INCLUDE_DIRECTORIES DIRECTORY ${PROJECT_SOURCE_DIR} INCLUDE_DIRECTORIES)
+    string (REPLACE ";" " " INCLUDE_DIRECTORIES "${INCLUDE_DIRECTORIES}")   # Note: need to always "stringify" a variable in list context for replace to work correctly
+    set (NDK_GDB_SETUP "# This is a generated file. DO NOT EDIT!\n\nset solib-search-path ${NDK_GDB_SOLIB_PATH}\ndirectory ${INCLUDE_DIRECTORIES}\n")
+    file (WRITE ${ANDROID_LIBRARY_OUTPUT_PATH}/gdb.setup ${NDK_GDB_SETUP})
+    file (COPY ${ANDROID_NDK}/prebuilt/android-${ANDROID_ARCH_NAME}/gdbserver/gdbserver DESTINATION ${ANDROID_LIBRARY_OUTPUT_PATH})
+endif ()
+
 # Override builtin macro and function to suit our need, always generate header file regardless of target type...
 # Override builtin macro and function to suit our need, always generate header file regardless of target type...
 macro (_DO_SET_MACRO_VALUES TARGET_LIBRARY)
 macro (_DO_SET_MACRO_VALUES TARGET_LIBRARY)
     set (DEFINE_DEPRECATED)
     set (DEFINE_DEPRECATED)
@@ -532,6 +553,9 @@ macro (setup_library)
         if (URHO3D_LIB_TYPE STREQUAL SHARED)
         if (URHO3D_LIB_TYPE STREQUAL SHARED)
             set_target_properties (${TARGET_NAME} PROPERTIES COMPILE_DEFINITIONS URHO3D_EXPORTS)
             set_target_properties (${TARGET_NAME} PROPERTIES COMPILE_DEFINITIONS URHO3D_EXPORTS)
         endif ()
         endif ()
+    elseif (URHO3D_SCP_TO_TARGET)
+        add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND scp $<TARGET_FILE:${TARGET_NAME}> ${URHO3D_SCP_TO_TARGET} || exit 0
+            COMMENT "Scp-ing ${TARGET_NAME} library to target system")
     endif ()
     endif ()
 endmacro ()
 endmacro ()
 
 
@@ -553,8 +577,9 @@ macro (setup_executable)
     
     
     if (IOS)
     if (IOS)
         set_target_properties (${TARGET_NAME} PROPERTIES XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2")
         set_target_properties (${TARGET_NAME} PROPERTIES XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2")
-    elseif (CMAKE_CROSSCOMPILING AND NOT ANDROID AND URHO3D_SCP_TO_TARGET)
-        add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND scp $<TARGET_FILE:${TARGET_NAME}> ${URHO3D_SCP_TO_TARGET} || exit 0)
+    elseif (URHO3D_SCP_TO_TARGET)
+        add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND scp $<TARGET_FILE:${TARGET_NAME}> ${URHO3D_SCP_TO_TARGET} || exit 0
+            COMMENT "Scp-ing ${TARGET_NAME} executable to target system")
     endif ()
     endif ()
     if (DEST_RUNTIME_DIR)
     if (DEST_RUNTIME_DIR)
         # Need to check if the variable is defined first because this macro could be called by CMake project outside of Urho3D that does not wish to install anything
         # Need to check if the variable is defined first because this macro could be called by CMake project outside of Urho3D that does not wish to install anything
@@ -620,6 +645,12 @@ macro (setup_main_executable)
                     COMMENT "Copying ${NAME} to library output directory")
                     COMMENT "Copying ${NAME} to library output directory")
             endif ()
             endif ()
         endforeach ()
         endforeach ()
+        if (URHO3D_NDK_GDB)
+            # Copy the library while it still has debug symbols for ndk-gdb
+            add_custom_command (TARGET ${TARGET_NAME} POST_BUILD
+                COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${TARGET_NAME}> ${NDK_GDB_SOLIB_PATH}
+                COMMENT "Copying lib${TARGET_NAME}.so with debug symbols to ${NDK_GDB_SOLIB_PATH} directory")
+        endif ()
         # Strip target main shared library
         # Strip target main shared library
         add_custom_command (TARGET ${TARGET_NAME} POST_BUILD
         add_custom_command (TARGET ${TARGET_NAME} POST_BUILD
             COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${TARGET_NAME}>
             COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${TARGET_NAME}>

+ 5 - 4
Source/CMake/Toolchains/android.toolchain.cmake

@@ -1540,12 +1540,13 @@ if(NOT _CMAKE_IN_TRY_COMPILE)
  set( ANDROID_LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" FORCE )
  set( ANDROID_LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" FORCE )
 endif()
 endif()
 
 
-# copy shaed stl library to build directory
+# Urho3D: Copy shared STL library to final Android library output path pointed by ANDROID_LIBRARY_OUTPUT_PATH variable as CMake's LIBRARY_OUTPUT_PATH still points to its default
+# copy shared stl library to build directory
 if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" )
 if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" )
  get_filename_component( __libstlname "${__libstl}" NAME )
  get_filename_component( __libstlname "${__libstl}" NAME )
- execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess )
- if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}")
-  message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" )
+ execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${ANDROID_LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess )
+ if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${ANDROID_LIBRARY_OUTPUT_PATH}/${__libstlname}")
+   message( SEND_ERROR "Failed copying of ${__libstl} to the ${ANDROID_LIBRARY_OUTPUT_PATH}/${__libstlname}" )
  endif()
  endif()
  unset( __fileCopyProcess )
  unset( __fileCopyProcess )
  unset( __libstlname )
  unset( __libstlname )

+ 10 - 5
Source/Engine/CMakeLists.txt

@@ -268,13 +268,18 @@ if (URHO3D_LIB_TYPE STREQUAL SHARED)
 endif ()
 endif ()
 
 
 # Define post build steps
 # Define post build steps
-# Strip the output shared library for embedded devices
-if (URHO3D_LIB_TYPE STREQUAL SHARED AND (CMAKE_CROSSCOMPILING OR IOS))
+if (URHO3D_NDK_GDB)
+    # Copy the library while it still has debug symbols for ndk-gdb
+    add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:${TARGET_NAME}> ${NDK_GDB_SOLIB_PATH}
+        COMMENT "Copying Urho3D library with debug symbols to ${NDK_GDB_SOLIB_PATH} directory")
+endif ()
+if (URHO3D_LIB_TYPE STREQUAL SHARED AND (ANDROID OR RASPI OR IOS))
+    # Strip the output shared library for embedded devices
     add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${TARGET_NAME}>
     add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${TARGET_NAME}>
-        COMMENT "Stripping shared library")
+        COMMENT "Stripping Urho3D shared library")
 endif ()
 endif ()
-if (CMAKE_CROSSCOMPILING AND NOT ANDROID AND URHO3D_SCP_TO_TARGET)
+if (URHO3D_SCP_TO_TARGET)
     # Ensure SCP is the last command
     # Ensure SCP is the last command
     add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND scp $<TARGET_FILE:${TARGET_NAME}> ${URHO3D_SCP_TO_TARGET} || exit 0
     add_custom_command (TARGET ${TARGET_NAME} POST_BUILD COMMAND scp $<TARGET_FILE:${TARGET_NAME}> ${URHO3D_SCP_TO_TARGET} || exit 0
-        COMMENT "Scp-ing library to target system")
+        COMMENT "Scp-ing Urho3D library to target system")
 endif ()
 endif ()

+ 1 - 1
Source/ThirdParty/LuaJIT/CMakeLists.txt

@@ -155,7 +155,7 @@ if (CMAKE_CROSSCOMPILING OR IOS)
     If (IOS)
     If (IOS)
         set (BUILDVM_X buildvm-ios)
         set (BUILDVM_X buildvm-ios)
     elseif (ANDROID)
     elseif (ANDROID)
-        set (BUILDVM_X buildvm-android-${ANDROID_ABI})
+        set (BUILDVM_X buildvm-android-${ANDROID_NDK_ABI_NAME})
     elseif (RASPI)
     elseif (RASPI)
         set (BUILDVM_X buildvm-raspi)
         set (BUILDVM_X buildvm-raspi)
     elseif (MINGW)
     elseif (MINGW)

+ 1 - 1
cmake_android.bat

@@ -42,7 +42,7 @@ if "%use_mklink%" == "1" (
     set "build=android-Build"
     set "build=android-Build"
     set "source=..\Source"
     set "source=..\Source"
     for %%d in (CoreData Data) do if not exist "Source\Android\assets\%%d". mklink /D "Source\Android\assets\%%d" "..\..\..\Bin\%%d"
     for %%d in (CoreData Data) do if not exist "Source\Android\assets\%%d". mklink /D "Source\Android\assets\%%d" "..\..\..\Bin\%%d"
-    for %%d in (src res assets) do if not exist "android-Build\%%d". mklink /D "android-Build\%%d" "..\Source\Android\%%d"
+    for %%d in (src res assets jni) do if exist "Source\Android\%%d" if not exist "android-Build\%%d". mklink /D "android-Build\%%d" "..\Source\Android\%%d"
     for %%f in (AndroidManifest.xml build.xml) do if not exist "android-Build\%%f". mklink "android-Build\%%f" "..\Source\Android\%%f"
     for %%f in (AndroidManifest.xml build.xml) do if not exist "android-Build\%%f". mklink "android-Build\%%f" "..\Source\Android\%%f"
 ) else (
 ) else (
     if exist android-Build\CMakeCache.txt. del /F android-Build\CMakeCache.txt
     if exist android-Build\CMakeCache.txt. del /F android-Build\CMakeCache.txt

+ 2 - 2
cmake_gcc.sh

@@ -57,8 +57,8 @@ if [ $ANDROID_NDK ]; then
     for dir in CoreData Data; do
     for dir in CoreData Data; do
         cmake -E create_symlink ../../../Bin/$dir Source/Android/assets/$dir
         cmake -E create_symlink ../../../Bin/$dir Source/Android/assets/$dir
     done
     done
-    for f in AndroidManifest.xml build.xml src res assets; do
-        cmake -E create_symlink ../Source/Android/$f android-Build/$f
+    for f in AndroidManifest.xml build.xml src res assets jni; do
+        if [ -e Source/Android/$f ]; then cmake -E create_symlink ../Source/Android/$f android-Build/$f; fi
     done
     done
 fi
 fi