Browse Source

Add initial build support for generic ARM platform.
Add a new build option "ARM_ABI_FLAGS" for supplying additional ABI compiler flags when targeting generic arm.
Fix Linux build from using OpenGLES instead of GLEW, fix RPI build from using wrong OpenGLES library, fix iOS build from using arm-specific compiler flags directly which would cause problem in universal binary build containing iphonesimulator archs as well.
And other minor refactoring.

Yao Wei Tjong 姚伟忠 9 years ago
parent
commit
64d975ba1a

+ 0 - 6
CMake/Modules/CheckCompilerToolchain.cmake

@@ -92,14 +92,8 @@ else ()
     endif ()
     endif ()
     # Android arm64 compiler only emits __aarch64__ while iOS arm64 emits __aarch64__, __arm64__, and __arm__; for armv7a all emit __arm__
     # Android arm64 compiler only emits __aarch64__ while iOS arm64 emits __aarch64__, __arm64__, and __arm__; for armv7a all emit __arm__
     check_native_define ("__(arm|aarch64)__" ARM)
     check_native_define ("__(arm|aarch64)__" ARM)
-    check_native_define ("__aarch64__" ARM64)
     # For completeness sake as currently we do not support PowerPC (yet)
     # For completeness sake as currently we do not support PowerPC (yet)
     check_native_define ("__(ppc|PPC|powerpc|POWERPC)(64)*__" POWERPC)
     check_native_define ("__(ppc|PPC|powerpc|POWERPC)(64)*__" POWERPC)
-    # Check if the target arm platform is currently supported
-    if (ARM AND NOT ANDROID AND NOT RPI AND NOT IOS AND NOT TVOS)
-        # TODO: check the uname of the host system for the telltale sign of RPI, just in case this is a native build on the device itself
-        message (STATUS "Unsupported arm target architecture")
-    endif ()
     # GCC/Clang and all their derivatives should understand this command line option to get the compiler version
     # GCC/Clang and all their derivatives should understand this command line option to get the compiler version
     if (NOT DEFINED COMPILER_VERSION)
     if (NOT DEFINED COMPILER_VERSION)
         execute_process (COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE COMPILER_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
         execute_process (COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE COMPILER_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)

+ 2 - 2
CMake/Modules/FindUrho3D.cmake

@@ -170,7 +170,7 @@ else ()
     set (URHO3D_LIB_TYPE_SAVED ${URHO3D_LIB_TYPE})  # We need this to reset the auto-discovered URHO3D_LIB_TYPE variable before looping
     set (URHO3D_LIB_TYPE_SAVED ${URHO3D_LIB_TYPE})  # We need this to reset the auto-discovered URHO3D_LIB_TYPE variable before looping
     foreach (ABI_64BIT RANGE ${URHO3D_64BIT} 0)
     foreach (ABI_64BIT RANGE ${URHO3D_64BIT} 0)
         # Break if the compiler is not multilib-capable and the ABI is not its native
         # Break if the compiler is not multilib-capable and the ABI is not its native
-        if ((MSVC OR MINGW OR ANDROID OR RPI OR WEB) AND NOT ABI_64BIT EQUAL NATIVE_64BIT)
+        if ((MSVC OR MINGW OR ANDROID OR ARM OR WEB) AND NOT ABI_64BIT EQUAL NATIVE_64BIT)
             break ()
             break ()
         endif ()
         endif ()
         # Set to search in 'lib' or 'lib64' based on the ABI being tested
         # Set to search in 'lib' or 'lib64' based on the ABI being tested
@@ -223,7 +223,7 @@ else ()
         if (URHO3D_COMPILE_RESULT)
         if (URHO3D_COMPILE_RESULT)
             break ()    # Use the cached result instead of redoing try_run() each time
             break ()    # Use the cached result instead of redoing try_run() each time
         elseif (URHO3D_LIBRARIES)
         elseif (URHO3D_LIBRARIES)
-            if (NOT (MSVC OR MINGW OR ANDROID OR RPI OR WEB OR XCODE) AND NOT ABI_64BIT)
+            if (NOT (MSVC OR MINGW OR ANDROID OR ARM OR WEB OR XCODE) AND NOT ABI_64BIT)
                 set (COMPILER_32BIT_FLAG -m32)
                 set (COMPILER_32BIT_FLAG -m32)
             endif ()
             endif ()
             # Below variables are loop invariant but there is no harm to keep them here
             # Below variables are loop invariant but there is no harm to keep them here

+ 49 - 35
CMake/Modules/Urho3D-CMake-common.cmake

@@ -84,14 +84,17 @@ include (CheckCompilerToolchain)
 include (CMakeDependentOption)
 include (CMakeDependentOption)
 option (URHO3D_C++11 "Enable C++11 standard")
 option (URHO3D_C++11 "Enable C++11 standard")
 cmake_dependent_option (IOS "Setup build for iOS platform" FALSE "XCODE" FALSE)
 cmake_dependent_option (IOS "Setup build for iOS platform" FALSE "XCODE" FALSE)
-cmake_dependent_option (URHO3D_64BIT "Enable 64-bit build, the default is set based on the native ABI of the chosen compiler toolchain" ${NATIVE_64BIT} "NOT MSVC AND NOT MINGW AND NOT ANDROID AND NOT RPI AND NOT WEB AND NOT POWERPC" ${NATIVE_64BIT})
+cmake_dependent_option (URHO3D_64BIT "Enable 64-bit build, the default is set based on the native ABI of the chosen compiler toolchain" ${NATIVE_64BIT} "NOT MSVC AND NOT MINGW AND NOT ANDROID AND NOT (ARM AND NOT IOS) AND NOT WEB AND NOT POWERPC" ${NATIVE_64BIT})     # Intentionally only enable the option for iOS but not for tvOS as the latter is 64-bit only
 option (URHO3D_ANGELSCRIPT "Enable AngelScript scripting support" TRUE)
 option (URHO3D_ANGELSCRIPT "Enable AngelScript scripting support" TRUE)
 option (URHO3D_LUA "Enable additional Lua scripting support" TRUE)
 option (URHO3D_LUA "Enable additional Lua scripting support" TRUE)
 option (URHO3D_NAVIGATION "Enable navigation support" TRUE)
 option (URHO3D_NAVIGATION "Enable navigation support" TRUE)
 cmake_dependent_option (URHO3D_NETWORK "Enable networking support" TRUE "NOT WEB" FALSE)
 cmake_dependent_option (URHO3D_NETWORK "Enable networking support" TRUE "NOT WEB" FALSE)
 option (URHO3D_PHYSICS "Enable physics support" TRUE)
 option (URHO3D_PHYSICS "Enable physics support" TRUE)
 option (URHO3D_URHO2D "Enable 2D graphics and physics support" TRUE)
 option (URHO3D_URHO2D "Enable 2D graphics and physics support" TRUE)
-if (IOS OR (RPI AND "${RPI_ABI}" MATCHES NEON))    # Stringify in case RPI_ABI is not set explicitly
+if (ARM AND NOT URHO3D_64BIT AND NOT ANDROID AND NOT RPI AND NOT IOS AND NOT TVOS)
+    set (ARM_ABI_FLAGS "" CACHE STRING "Specify ABI compiler flags (generic arm-linux-gnueabihf build only); e.g. Orange-Pi Mini 2 could use '-mcpu=cortex-a7 -mfpu=neon-vfpv4'")
+endif ()
+if (IOS OR (RPI AND "${RPI_ABI}" MATCHES NEON) OR (ARM AND (URHO3D_64BIT OR "${ARM_ABI_FLAGS}" MATCHES neon)))    # Stringify in case RPI_ABI/ARM_ABI_FLAGS is not set explicitly
     # The 'NEON' CMake variable is already set by android.toolchain.cmake when the chosen ANDROID_ABI uses NEON
     # The 'NEON' CMake variable is already set by android.toolchain.cmake when the chosen ANDROID_ABI uses NEON
     set (NEON TRUE)
     set (NEON TRUE)
 endif ()
 endif ()
@@ -159,10 +162,10 @@ if (CMAKE_PROJECT_NAME STREQUAL Urho3D)
     option (URHO3D_SAMPLES "Build sample applications" TRUE)
     option (URHO3D_SAMPLES "Build sample applications" TRUE)
     option (URHO3D_UPDATE_SOURCE_TREE "Enable commands to copy back some of the generated build artifacts from build tree to source tree to facilitate devs to push them as part of a commit (for library devs with push right only)")
     option (URHO3D_UPDATE_SOURCE_TREE "Enable commands to copy back some of the generated build artifacts from build tree to source tree to facilitate devs to push them as part of a commit (for library devs with push right only)")
     option (URHO3D_BINDINGS "Enable API binding generation support for script subystems")
     option (URHO3D_BINDINGS "Enable API binding generation support for script subystems")
-    cmake_dependent_option (URHO3D_CLANG_TOOLS "Build Clang tools (native only)" FALSE "NOT RPI AND NOT IOS AND NOT ANDROID AND NOT WEB" FALSE)
+    cmake_dependent_option (URHO3D_CLANG_TOOLS "Build Clang tools (native on host system only)" FALSE "NOT ANDROID AND NOT ARM AND NOT WEB" FALSE)
     mark_as_advanced (URHO3D_UPDATE_SOURCE_TREE URHO3D_BINDINGS URHO3D_CLANG_TOOLS)
     mark_as_advanced (URHO3D_UPDATE_SOURCE_TREE URHO3D_BINDINGS URHO3D_CLANG_TOOLS)
-    cmake_dependent_option (URHO3D_TOOLS "Build tools (native and RPI only)" TRUE "NOT IOS AND NOT ANDROID AND NOT WEB" FALSE)
-    cmake_dependent_option (URHO3D_EXTRAS "Build extras (native and RPI only)" FALSE "NOT IOS AND NOT ANDROID AND NOT WEB" FALSE)
+    cmake_dependent_option (URHO3D_TOOLS "Build tools (native, RPI, and generic ARM only)" TRUE "NOT IOS AND NOT ANDROID AND NOT WEB" FALSE)
+    cmake_dependent_option (URHO3D_EXTRAS "Build extras (native, RPI, and generic ARM only)" FALSE "NOT IOS AND NOT ANDROID AND NOT WEB" FALSE)
     option (URHO3D_DOCS "Generate documentation as part of normal build")
     option (URHO3D_DOCS "Generate documentation as part of normal build")
     option (URHO3D_DOCS_QUIET "Generate documentation as part of normal build, suppress generation process from sending anything to stdout")
     option (URHO3D_DOCS_QUIET "Generate documentation as part of normal build, suppress generation process from sending anything to stdout")
     option (URHO3D_PCH "Enable PCH support" TRUE)
     option (URHO3D_PCH "Enable PCH support" TRUE)
@@ -393,7 +396,7 @@ if (URHO3D_D3D11)
 endif ()
 endif ()
 
 
 # Add definitions for GLEW
 # Add definitions for GLEW
-if (NOT IOS AND NOT ANDROID AND NOT RPI AND URHO3D_OPENGL)
+if (NOT ANDROID AND NOT ARM AND NOT WEB AND URHO3D_OPENGL)
     add_definitions (-DGLEW_STATIC -DGLEW_NO_GLU)
     add_definitions (-DGLEW_STATIC -DGLEW_NO_GLU)
 endif ()
 endif ()
 
 
@@ -580,31 +583,41 @@ if (MSVC)
 else ()
 else ()
     # GCC/Clang-specific setup
     # GCC/Clang-specific setup
     set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-offsetof")
     set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-offsetof")
-    if (NOT ANDROID)    # Most of the flags are already setup in android.toolchain.cmake module
-        if (RPI)
-            # The configuration is done here instead of in raspberrypi.toolchain.cmake file because we also support native build which does not use that file at all
-            add_definitions (-DRPI)
-            set (RPI_CFLAGS "-pipe -mfloat-abi=hard -Wno-psabi")    # We only support armhf distros, so turn on hard-float by default
-            if (RPI_ABI MATCHES ^armeabi-v7a)
-                set (RPI_CFLAGS "${RPI_CFLAGS} -mcpu=cortex-a7")
-                if (RPI_ABI MATCHES NEON)
-                    set (RPI_CFLAGS "${RPI_CFLAGS} -mfpu=neon-vfpv4")
-                elseif (RPI_ABI MATCHES VFPV4)
-                    set (RPI_CFLAGS "${RPI_CFLAGS} -mfpu=vfpv4")
+    if (NOT ANDROID AND NOT IOS AND NOT TVOS)    # Most of the flags are already setup in android.toolchain.cmake module or already has correct default setup for iOS
+        if (ARM)
+            # Common compiler flags for aarch64-linux-gnu and arm-linux-gnueabihf, we do not support Windows on arm for now
+            set (ARM_CFLAGS "${ARM_CFLAGS} -pipe")
+            if (NOT URHO3D_64BIT)
+                set (ARM_CFLAGS "${ARM_CFLAGS} -mfloat-abi=hard -Wno-psabi")    # We only support armhf distros, so turn on hard-float by default
+            endif ()
+            # The configuration is done here instead of in CMake toolchain file because we also support native build which does not use toolchain file at all
+            if (RPI)
+                # RPI-specific setup
+                add_definitions (-DRPI)
+                if (RPI_ABI MATCHES ^armeabi-v7a)
+                    set (ARM_CFLAGS "${ARM_CFLAGS} -mcpu=cortex-a7")
+                    if (RPI_ABI MATCHES NEON)
+                        set (ARM_CFLAGS "${ARM_CFLAGS} -mfpu=neon-vfpv4")
+                    elseif (RPI_ABI MATCHES VFPV4)
+                        set (ARM_CFLAGS "${ARM_CFLAGS} -mfpu=vfpv4")
+                    else ()
+                        set (ARM_CFLAGS "${ARM_CFLAGS} -mfpu=vfpv4-d16")
+                    endif ()
                 else ()
                 else ()
-                    set (RPI_CFLAGS "${RPI_CFLAGS} -mfpu=vfpv4-d16")
+                    set (ARM_CFLAGS "${ARM_CFLAGS} -mcpu=arm1176jzf-s -mfpu=vfp")
                 endif ()
                 endif ()
             else ()
             else ()
-                set (RPI_CFLAGS "${RPI_CFLAGS} -mcpu=arm1176jzf-s -mfpu=vfp")
-            endif ()
-            set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${RPI_CFLAGS}")
-            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RPI_CFLAGS}")
-        elseif (ARM)
-            set (ARM_CFLAGS "${ARM_CFLAGS} -pipe")
-            if (NOT ARM64)
-                set (ARM_CFLAGS "${ARM_CFLAGS} -mfloat-abi=hard -Wno-psabi")    # We only support armhf distros, so turn on hard-float by default
-                # todo: fix asm in as for arm
-                add_definitions (-DAS_MAX_PORTABILITY)
+                # Generic ARM-specific setup
+                add_definitions (-DGENERIC_ARM)
+                if (URHO3D_64BIT)
+                    # aarch64 has only one valid arch so far, so it does not need to use ARM_ABI_FLAGS build option
+                    set (ARM_CFLAGS "${ARM_CFLAGS} -march=armv8-a")
+                elseif (ARM_ABI_FLAGS)
+                    # Instead of guessing all the possible ABIs, user would have to specify the ABI compiler flags explicitly via ARM_ABI_FLAGS build option
+                    set (ARM_CFLAGS "${ARM_CFLAGS} ${ARM_ABI_FLAGS}")
+                else ()
+                    message (FATAL_ERROR "The ARM_ABI_FLAGS build option is mandatory for targeting 32-bit generic ARM")
+                endif ()
             endif ()
             endif ()
             set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM_CFLAGS}")
             set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${ARM_CFLAGS}")
             set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM_CFLAGS}")
             set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARM_CFLAGS}")
@@ -1558,14 +1571,15 @@ macro (define_dependency_libs TARGET)
 
 
         # Graphics
         # Graphics
         if (URHO3D_OPENGL)
         if (URHO3D_OPENGL)
-            if(VIDEO_OPENGLES)
-                CheckOpenGLES()
-            endif()
-            if (WIN32)
+            if (APPLE)
+                # Do nothing
+            elseif (WIN32)
                 list (APPEND LIBS opengl32)
                 list (APPEND LIBS opengl32)
-            elseif (ANDROID OR HAVE_VIDEO_OPENGLES)
-                list (APPEND LIBS GLESv1_CM GLESv2)
-            elseif (NOT APPLE AND NOT RPI)
+            elseif (ANDROID OR ARM)
+                if (NOT RPI)
+                    list (APPEND LIBS GLESv1_CM GLESv2)
+                endif ()
+            else ()
                 list (APPEND LIBS GL)
                 list (APPEND LIBS GL)
             endif ()
             endif ()
         elseif (DIRECT3D_LIBRARIES)
         elseif (DIRECT3D_LIBRARIES)

+ 5 - 0
CMakeLists.txt

@@ -120,6 +120,8 @@ elseif (WEB)
 elseif (CPACK_SYSTEM_NAME STREQUAL Linux)
 elseif (CPACK_SYSTEM_NAME STREQUAL Linux)
     if (RPI)
     if (RPI)
         set (CPACK_SYSTEM_NAME Raspberry-Pi)
         set (CPACK_SYSTEM_NAME Raspberry-Pi)
+    elseif (ARM)
+        set (CPACK_SYSTEM_NAME Arm)     # Generic ARM
     endif ()
     endif ()
     if (NOT URHO3D_64BIT OR HAS_LIB64)
     if (NOT URHO3D_64BIT OR HAS_LIB64)
         list (APPEND CPACK_GENERATOR RPM)
         list (APPEND CPACK_GENERATOR RPM)
@@ -154,6 +156,9 @@ elseif (ANDROID AND X86)    # Take advantage of Android toolchain setting X86 va
     set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-IA)     # Stands for Intel Architecture
     set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-IA)     # Stands for Intel Architecture
 elseif (RPI AND RPI_ABI MATCHES ^armeabi-v7a)
 elseif (RPI AND RPI_ABI MATCHES ^armeabi-v7a)
     set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-v7a)
     set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-v7a)
+elseif (ARM_ABI_FLAGS)
+    string (REGEX REPLACE "^.*mcpu=([^ ]+).*$" -\\1 CPU_NAME "${ARM_ABI_FLAGS}")
+    set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}${CPU_NAME})
 endif ()
 endif ()
 if (NOT DEFINED ENV{RELEASE_TAG})
 if (NOT DEFINED ENV{RELEASE_TAG})
     set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-snapshot)
     set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-snapshot)

+ 3 - 2
Docs/GettingStarted.dox

@@ -107,8 +107,8 @@ A number of build options can be defined when invoking the build scripts or when
 |URHO3D_NAVIGATION    |1|Enable Navigation support|
 |URHO3D_NAVIGATION    |1|Enable Navigation support|
 |URHO3D_URHO2D        |1|Enable 2D rendering & physics support|
 |URHO3D_URHO2D        |1|Enable 2D rendering & physics support|
 |URHO3D_SAMPLES       |1|Build sample applications|
 |URHO3D_SAMPLES       |1|Build sample applications|
-|URHO3D_TOOLS         |1|Build tools (native and RPI only)|
-|URHO3D_EXTRAS        |0|Build extras (native and RPI only)|
+|URHO3D_TOOLS         |1|Build tools (native, RPI, and generic ARM only)|
+|URHO3D_EXTRAS        |0|Build extras (native, RPI, and generic ARM only)|
 |URHO3D_DOCS          |0|Generate documentation as part of normal build (the 'doc' builtin target can be used to generate documentation regardless of this option's value)|
 |URHO3D_DOCS          |0|Generate documentation as part of normal build (the 'doc' builtin target can be used to generate documentation regardless of this option's value)|
 |URHO3D_DOCS_QUIET    |0|Generate documentation as part of normal build, suppress generation process from sending anything to stdout|
 |URHO3D_DOCS_QUIET    |0|Generate documentation as part of normal build, suppress generation process from sending anything to stdout|
 |URHO3D_PCH           |1|Enable PCH support|
 |URHO3D_PCH           |1|Enable PCH support|
@@ -150,6 +150,7 @@ A number of build options can be defined when invoking the build scripts or when
 |RPI_PREFIX           |-|Prefix path to Raspberry Pi cross-compiler tools (RPI cross-compiling build only)|
 |RPI_PREFIX           |-|Prefix path to Raspberry Pi cross-compiler tools (RPI cross-compiling build only)|
 |RPI_SYSROOT          |-|Path to Raspberry Pi system root (RPI cross-compiling build only)|
 |RPI_SYSROOT          |-|Path to Raspberry Pi system root (RPI cross-compiling build only)|
 |RPI_ABI              |*|Specify target ABI (RPI build only), possible values are armeabi-v6 (default for RPI 1), armeabi-v7a (default for RPI 2), armeabi-v7a with NEON, and armeabi-v7a with VFPV4|
 |RPI_ABI              |*|Specify target ABI (RPI build only), possible values are armeabi-v6 (default for RPI 1), armeabi-v7a (default for RPI 2), armeabi-v7a with NEON, and armeabi-v7a with VFPV4|
+|ARM_ABI_FLAGS        |-|Specify ABI compiler flags (generic arm-linux-gnueabihf build only); e.g. Orange-Pi Mini 2 could use '-mcpu=cortex-a7 -mfpu=neon-vfpv4'|
 |EMSCRIPTEN_ROOT_PATH |-|Root path to Emscripten cross-compiler tools (Emscripten cross-compiling build only)|
 |EMSCRIPTEN_ROOT_PATH |-|Root path to Emscripten cross-compiler tools (Emscripten cross-compiling build only)|
 |EMSCRIPTEN_SYSROOT   |-|Path to Emscripten system root (Emscripten cross-compiling build only)|
 |EMSCRIPTEN_SYSROOT   |-|Path to Emscripten system root (Emscripten cross-compiling build only)|
 |EMSCRIPTEN_ALLOW_MEMORY_GROWTH|0|Enable memory growing based on application demand (Emscripten cross-compiling build only)|
 |EMSCRIPTEN_ALLOW_MEMORY_GROWTH|0|Enable memory growing based on application demand (Emscripten cross-compiling build only)|

+ 1 - 1
Rakefile

@@ -54,7 +54,7 @@ task :cmake do
   platform = 'native'
   platform = 'native'
   build_options = ''
   build_options = ''
   # TODO: Need to find a way to automatically populate the array with all the Urho3D supported build options, at the moment it only contains those being used in CI
   # TODO: Need to find a way to automatically populate the array with all the Urho3D supported build options, at the moment it only contains those being used in CI
-  ['URHO3D_64BIT', 'URHO3D_LIB_TYPE', 'URHO3D_STATIC_RUNTIME', 'URHO3D_PCH', 'URHO3D_BINDINGS', 'URHO3D_OPENGL', 'URHO3D_D3D11', 'URHO3D_TESTING', 'URHO3D_TEST_TIMEOUT', 'URHO3D_UPDATE_SOURCE_TREE', 'URHO3D_TOOLS', 'URHO3D_DEPLOYMENT_TARGET', 'URHO3D_USE_LIB64_RPM', 'CMAKE_BUILD_TYPE', 'CMAKE_OSX_DEPLOYMENT_TARGET', 'IOS', 'IPHONEOS_DEPLOYMENT_TARGET', 'WIN32', 'ANDROID', 'ANDROID_ABI', 'ANDROID_NATIVE_API_LEVEL', 'RPI', 'RPI_ABI', 'WEB', 'EMSCRIPTEN_SHARE_DATA', 'EMSCRIPTEN_EMRUN_BROWSER'].each { |var|
+  ['URHO3D_64BIT', 'URHO3D_LIB_TYPE', 'URHO3D_STATIC_RUNTIME', 'URHO3D_PCH', 'URHO3D_BINDINGS', 'URHO3D_OPENGL', 'URHO3D_D3D11', 'URHO3D_TESTING', 'URHO3D_TEST_TIMEOUT', 'URHO3D_UPDATE_SOURCE_TREE', 'URHO3D_TOOLS', 'URHO3D_DEPLOYMENT_TARGET', 'URHO3D_USE_LIB64_RPM', 'CMAKE_BUILD_TYPE', 'CMAKE_OSX_DEPLOYMENT_TARGET', 'IOS', 'IPHONEOS_DEPLOYMENT_TARGET', 'WIN32', 'ANDROID', 'ANDROID_ABI', 'ANDROID_NATIVE_API_LEVEL', 'ANDROID_TOOLCHAIN_NAME', 'RPI', 'RPI_ABI', 'WEB', 'EMSCRIPTEN_SHARE_DATA', 'EMSCRIPTEN_EMRUN_BROWSER'].each { |var|
     ARGV << "#{var}=\"#{ENV[var]}\"" if ENV[var] && !ARGV.find { |arg| /#{var}=/ =~ arg }
     ARGV << "#{var}=\"#{ENV[var]}\"" if ENV[var] && !ARGV.find { |arg| /#{var}=/ =~ arg }
   }
   }
   ARGV.each { |option|
   ARGV.each { |option|

+ 4 - 2
Source/CMakeLists.txt

@@ -101,13 +101,15 @@ if (URHO3D_PHYSICS)
     add_subdirectory (ThirdParty/Bullet)
     add_subdirectory (ThirdParty/Bullet)
 endif ()
 endif ()
 
 
-if (NOT IOS AND NOT ANDROID AND NOT RPI AND NOT WEB)
+if (NOT ANDROID AND NOT ARM AND NOT WEB)
     if (URHO3D_OPENGL)
     if (URHO3D_OPENGL)
         add_subdirectory (ThirdParty/GLEW)
         add_subdirectory (ThirdParty/GLEW)
     elseif (NOT URHO3D_D3D11)
     elseif (NOT URHO3D_D3D11)
         add_subdirectory (ThirdParty/MojoShader)
         add_subdirectory (ThirdParty/MojoShader)
     endif ()
     endif ()
-    add_subdirectory (ThirdParty/LibCpuId)
+    if (NOT CMAKE_SYSTEM_NAME STREQUAL Linux)
+        add_subdirectory (ThirdParty/LibCpuId)
+    endif ()
 endif ()
 endif ()
 
 
 # Urho3D game engine library
 # Urho3D game engine library

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

@@ -28,7 +28,7 @@ add_definitions (-DAS_IS_BUILDING)
 
 
 # Define source files
 # Define source files
 define_source_files (GLOB_CPP_PATTERNS source/*.cpp GLOB_H_PATTERNS include/*.h source/*.h)
 define_source_files (GLOB_CPP_PATTERNS source/*.cpp GLOB_H_PATTERNS include/*.h source/*.h)
-if (IOS OR ANDROID OR RPI)
+if (ARM AND NOT URHO3D_64BIT)
     enable_language (ASM)
     enable_language (ASM)
     if (IOS)
     if (IOS)
         set (ASM_FILES source/as_callfunc_arm_xcode.S)
         set (ASM_FILES source/as_callfunc_arm_xcode.S)

+ 6 - 3
Source/ThirdParty/AngelScript/source/as_config.h

@@ -846,7 +846,9 @@
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define THISCALL_PASS_OBJECT_POINTER_ON_THE_STACK
 			#define AS_X86
 			#define AS_X86
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
-		#elif defined(__LP64__) && !defined(__arm64__) && !defined(__aarch64__) && !defined(__ARM_ARCH)
+
+		// Urho3D - use __aarch64__ instead of __arm64__ because GCC only emits the former
+		#elif defined(__LP64__) && !defined(__aarch64__)
 			#define AS_X64_GCC
 			#define AS_X64_GCC
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#undef AS_NO_THISCALL_FUNCTOR_METHOD
 			#define HAS_128_BIT_PRIMITIVES
 			#define HAS_128_BIT_PRIMITIVES
@@ -856,12 +858,13 @@
 			// STDCALL is not available on 64bit Linux
 			// STDCALL is not available on 64bit Linux
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL
-		#elif (defined(__arm64__) || defined(__aarch64__))
+
+		// Urho3D - Add support for aarch64-linux-gnu
+		#elif defined(__aarch64__)
 			// AngelScript currently doesn't support native calling
 			// AngelScript currently doesn't support native calling
 			// for 64bit ARM processors so it's necessary to turn on
 			// for 64bit ARM processors so it's necessary to turn on
 			// portability mode
 			// portability mode
 			#define AS_MAX_PORTABILITY
 			#define AS_MAX_PORTABILITY
-
 			// STDCALL is not available on ARM
 			// STDCALL is not available on ARM
 			#undef STDCALL
 			#undef STDCALL
 			#define STDCALL
 			#define STDCALL

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

@@ -247,7 +247,7 @@ if (NOT LUAJIT_CACHE STREQUAL "${URHO3D_64BIT}-${LUAJIT_DISABLE_FFI}-${LUAJIT_DI
     # Makefile: Target system detection
     # Makefile: Target system detection
     if (IOS)
     if (IOS)
         set (TARGET_SYS iOS)
         set (TARGET_SYS iOS)
-    elseif (ANDROID OR RPI)
+    elseif (CMAKE_SYSTEM_NAME STREQUAL Linux)
         set (TARGET_SYS Linux)
         set (TARGET_SYS Linux)
     elseif (MINGW)
     elseif (MINGW)
         set (TARGET_SYS Windows)
         set (TARGET_SYS Windows)

+ 1 - 1
Source/Urho3D/CMakeLists.txt

@@ -490,7 +490,7 @@ if (ANDROID_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}
     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")
         COMMENT "Copying Urho3D library with debug symbols to ${NDK_GDB_SOLIB_PATH} directory")
 endif ()
 endif ()
-if (URHO3D_LIB_TYPE STREQUAL SHARED AND (ANDROID OR RPI OR IOS))
+if (URHO3D_LIB_TYPE STREQUAL SHARED AND (ANDROID OR ARM))
     # Strip the output shared library for embedded devices
     # 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 Urho3D shared library")
         COMMENT "Stripping Urho3D shared library")

+ 60 - 41
Source/Urho3D/Core/ProcessUtils.cpp

@@ -35,13 +35,16 @@
 #if defined(IOS)
 #if defined(IOS)
 #include "../Math/MathDefs.h"
 #include "../Math/MathDefs.h"
 #include <mach/mach_host.h>
 #include <mach/mach_host.h>
-#elif !defined(ANDROID) && !defined(RPI) && !defined(__EMSCRIPTEN__)
+#elif !defined(__linux__) && !defined(__EMSCRIPTEN__)
 #include <LibCpuId/libcpuid.h>
 #include <LibCpuId/libcpuid.h>
 #endif
 #endif
 
 
 #ifdef _WIN32
 #ifdef _WIN32
 #include <windows.h>
 #include <windows.h>
 #include <io.h>
 #include <io.h>
+#if defined(_MSC_VER)
+#include <float.h>
+#endif
 #else
 #else
 #include <unistd.h>
 #include <unistd.h>
 #endif
 #endif
@@ -50,9 +53,7 @@
 #include <emscripten/threading.h>
 #include <emscripten/threading.h>
 #endif
 #endif
 
 
-#if defined(_MSC_VER)
-#include <float.h>
-#elif !defined(ANDROID) && !defined(IOS) && !defined(__ARM_ARCH) && !defined(__EMSCRIPTEN__)
+#if defined(__i386__)
 // From http://stereopsis.com/FPU.html
 // From http://stereopsis.com/FPU.html
 
 
 #define FPU_CW_PREC_MASK        0x0300
 #define FPU_CW_PREC_MASK        0x0300
@@ -76,7 +77,6 @@ inline void SetFPUState(unsigned control)
 {
 {
     __asm__ __volatile__ ("fldcw %0" : : "m" (control));
     __asm__ __volatile__ ("fldcw %0" : : "m" (control));
 }
 }
-
 #endif
 #endif
 
 
 #ifndef MINI_URHO
 #ifndef MINI_URHO
@@ -102,8 +102,50 @@ static void GetCPUData(host_basic_info_data_t* data)
     infoCount = HOST_BASIC_INFO_COUNT;
     infoCount = HOST_BASIC_INFO_COUNT;
     host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)data, &infoCount);
     host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)data, &infoCount);
 }
 }
-#elif !defined(ANDROID) && !defined(__ARM_ARCH) && !defined(__EMSCRIPTEN__)
+#elif defined(__linux__)
+struct CpuCoreCount
+{
+    unsigned numPhysicalCores_;
+    unsigned numLogicalCores_;
+};
+
+// This function is used by all the target triplets with Linux as the OS, such as Android, RPI, desktop Linux, etc
+static void GetCPUData(struct CpuCoreCount* data)
+{
+    // Sanity check
+    assert(data);
+    // At least return 1 core
+    data->numPhysicalCores_ = data->numLogicalCores_ = 1;
+
+    FILE* fp;
+    int res;
+    unsigned i, j;
 
 
+    fp = fopen("/sys/devices/system/cpu/present", "r");
+    if (fp)
+    {
+        res = fscanf(fp, "%d-%d", &i, &j);
+        fclose(fp);
+
+        if (res == 2 && i == 0)
+        {
+            data->numPhysicalCores_ = data->numLogicalCores_ = j + 1;
+
+            fp = fopen("/sys/devices/system/cpu/cpu0/topology/thread_siblings_list", "r");
+            if (fp)
+            {
+                res = fscanf(fp, "%d,%d,%d,%d", &i, &j, &i, &j);
+                fclose(fp);
+
+                // Having sibling thread(s) indicates the CPU is using HT/SMT technology
+                if (res > 1)
+                    data->numPhysicalCores_ /= res;
+            }
+        }
+    }
+}
+
+#elif !defined(__EMSCRIPTEN__)
 static void GetCPUData(struct cpu_id_t* data)
 static void GetCPUData(struct cpu_id_t* data)
 {
 {
     if (cpu_identify(0, data) < 0)
     if (cpu_identify(0, data) < 0)
@@ -112,23 +154,20 @@ static void GetCPUData(struct cpu_id_t* data)
         data->num_cores = 1;
         data->num_cores = 1;
     }
     }
 }
 }
-
 #endif
 #endif
 
 
 void InitFPU()
 void InitFPU()
 {
 {
-#if !defined(URHO3D_LUAJIT) && !defined(ANDROID) && !defined(IOS) && !defined(__ARM_ARCH) && !defined(__x86_64__) && !defined(_M_AMD64) && !defined(__EMSCRIPTEN__)
     // Make sure FPU is in round-to-nearest, single precision mode
     // Make sure FPU is in round-to-nearest, single precision mode
     // This ensures Direct3D and OpenGL behave similarly, and all threads behave similarly
     // This ensures Direct3D and OpenGL behave similarly, and all threads behave similarly
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && defined(_M_IX86)
     _controlfp(_RC_NEAR | _PC_24, _MCW_RC | _MCW_PC);
     _controlfp(_RC_NEAR | _PC_24, _MCW_RC | _MCW_PC);
-#else
+#elif defined(__i386__)
     unsigned control = GetFPUState();
     unsigned control = GetFPUState();
     control &= ~(FPU_CW_PREC_MASK | FPU_CW_ROUND_MASK);
     control &= ~(FPU_CW_PREC_MASK | FPU_CW_ROUND_MASK);
     control |= (FPU_CW_PREC_SINGLE | FPU_CW_ROUND_NEAR);
     control |= (FPU_CW_PREC_SINGLE | FPU_CW_ROUND_NEAR);
     SetFPUState(control);
     SetFPUState(control);
 #endif
 #endif
-#endif
 }
 }
 
 
 void ErrorDialog(const String& title, const String& message)
 void ErrorDialog(const String& title, const String& message)
@@ -280,8 +319,7 @@ String GetConsoleInput()
 #ifdef URHO3D_TESTING
 #ifdef URHO3D_TESTING
     // When we are running automated tests, reading the console may block. Just return empty in that case
     // When we are running automated tests, reading the console may block. Just return empty in that case
     return ret;
     return ret;
-#endif
-
+#else
 #ifdef _WIN32
 #ifdef _WIN32
     HANDLE input = GetStdHandle(STD_INPUT_HANDLE);
     HANDLE input = GetStdHandle(STD_INPUT_HANDLE);
     HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
     HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -345,6 +383,7 @@ String GetConsoleInput()
 #endif
 #endif
 
 
     return ret;
     return ret;
+#endif
 }
 }
 
 
 String GetPlatform()
 String GetPlatform()
@@ -368,30 +407,6 @@ String GetPlatform()
 #endif
 #endif
 }
 }
 
 
-#if defined(ANDROID) || defined(__ARM_ARCH)
-static unsigned GetArmCPUCount()
-{
-    FILE* fp;
-    int res, i = -1, j = -1;
-
-    fp = fopen("/sys/devices/system/cpu/present", "r");
-    // If failed, return at least 1
-    if (fp == 0)
-        return 1;
-
-    res = fscanf(fp, "%d-%d", &i, &j);
-    fclose(fp);
-
-    if (res == 1 && i == 0)
-        return 1;
-    else if (res == 2 && i == 0)
-        return j + 1;
-
-    // If failed, return at least 1
-    return 1;
-}
-#endif
-
 unsigned GetNumPhysicalCPUs()
 unsigned GetNumPhysicalCPUs()
 {
 {
 #if defined(IOS)
 #if defined(IOS)
@@ -403,8 +418,10 @@ unsigned GetNumPhysicalCPUs()
 #else
 #else
     return data.physical_cpu;
     return data.physical_cpu;
 #endif
 #endif
-#elif defined(ANDROID) || defined(__ARM_ARCH)
-    return GetArmCPUCount();
+#elif defined(__linux__)
+    struct CpuCoreCount data;
+    GetCPUData(&data);
+    return data.numPhysicalCores_;
 #elif defined(__EMSCRIPTEN__)
 #elif defined(__EMSCRIPTEN__)
 #ifdef __EMSCRIPTEN_PTHREADS__
 #ifdef __EMSCRIPTEN_PTHREADS__
     return emscripten_num_logical_cores();
     return emscripten_num_logical_cores();
@@ -428,8 +445,10 @@ unsigned GetNumLogicalCPUs()
 #else
 #else
     return data.logical_cpu;
     return data.logical_cpu;
 #endif
 #endif
-#elif defined(ANDROID) || defined (__ARM_ARCH)
-    return GetArmCPUCount();
+#elif defined(__linux__)
+    struct CpuCoreCount data;
+    GetCPUData(&data);
+    return data.numLogicalCores_;
 #elif defined(__EMSCRIPTEN__)
 #elif defined(__EMSCRIPTEN__)
 #ifdef __EMSCRIPTEN_PTHREADS__
 #ifdef __EMSCRIPTEN_PTHREADS__
     return emscripten_num_logical_cores();
     return emscripten_num_logical_cores();

+ 1 - 1
Source/Urho3D/Engine/Engine.cpp

@@ -93,7 +93,7 @@ Engine::Engine(Context* context) :
     timeStep_(0.0f),
     timeStep_(0.0f),
     timeStepSmoothing_(2),
     timeStepSmoothing_(2),
     minFps_(10),
     minFps_(10),
-#if defined(ANDROID) || defined(IOS) || defined(RPI) || defined(__ARM_ARCH)
+#if defined(ANDROID) || defined(__arm__) || defined(__aarch64)
     maxFps_(60),
     maxFps_(60),
     maxInactiveFps_(10),
     maxInactiveFps_(10),
     pauseMinimized_(true),
     pauseMinimized_(true),

+ 1 - 1
Source/Urho3D/Graphics/GraphicsDefs.h

@@ -31,7 +31,7 @@ namespace Urho3D
 class Vector3;
 class Vector3;
 
 
 /// Graphics capability support level. Web platform (Emscripten) also uses OpenGL ES, but is considered a desktop platform capability-wise
 /// Graphics capability support level. Web platform (Emscripten) also uses OpenGL ES, but is considered a desktop platform capability-wise
-#if defined(ANDROID) || defined(IOS) || defined(RPI) || defined(__ARM_ARCH)
+#if defined(ANDROID) || defined(__arm__) || defined(__aarch64)
 #define MOBILE_GRAPHICS
 #define MOBILE_GRAPHICS
 #else
 #else
 #define DESKTOP_GRAPHICS
 #define DESKTOP_GRAPHICS

+ 1 - 0
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -2072,6 +2072,7 @@ unsigned Graphics::GetFormat(CompressedFormat format) const
 unsigned Graphics::GetMaxBones()
 unsigned Graphics::GetMaxBones()
 {
 {
 #ifdef RPI
 #ifdef RPI
+    // At the moment all RPI GPUs are low powered and only have limited number of uniforms
     return 32;
     return 32;
 #else
 #else
     return gl3Support ? 128 : 64;
     return gl3Support ? 128 : 64;

+ 5 - 6
Source/Urho3D/Graphics/OpenGL/OGLGraphicsImpl.h

@@ -26,14 +26,12 @@
 #include "../../Core/Timer.h"
 #include "../../Core/Timer.h"
 #include "../../Math/Color.h"
 #include "../../Math/Color.h"
 
 
-#include <SDL/SDL.h>
-
-#if defined(ANDROID) || defined (RPI) || defined(SDL_VIDEO_OPENGL_ES2) || defined (__EMSCRIPTEN__)
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-#elif defined(IOS)
+#if defined(IOS)
 #include <OpenGLES/ES2/gl.h>
 #include <OpenGLES/ES2/gl.h>
 #include <OpenGLES/ES2/glext.h>
 #include <OpenGLES/ES2/glext.h>
+#elif defined(ANDROID) || defined (__arm__) || defined(__aarch64__) || defined (__EMSCRIPTEN__)
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 #else
 #else
 #include <GLEW/glew.h>
 #include <GLEW/glew.h>
 #endif
 #endif
@@ -63,6 +61,7 @@
 #define COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8c03
 #define COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8c03
 #endif
 #endif
 
 
+#include <SDL/SDL.h>
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {

+ 1 - 1
Source/Urho3D/Input/Input.cpp

@@ -48,7 +48,7 @@
 extern "C" int SDL_AddTouch(SDL_TouchID touchID, const char* name);
 extern "C" int SDL_AddTouch(SDL_TouchID touchID, const char* name);
 
 
 // Use a "click inside window to focus" mechanism on desktop platforms when the mouse cursor is hidden
 // Use a "click inside window to focus" mechanism on desktop platforms when the mouse cursor is hidden
-#if defined(_WIN32) || (defined(__APPLE__) && !defined(IOS)) || (defined(__linux__) && !defined(ANDROID) && !defined(RPI))
+#if defined(_WIN32) || (defined(__APPLE__) && !defined(IOS)) || (defined(__linux__) && !defined(ANDROID))
 #define REQUIRE_CLICK_TO_FOCUS
 #define REQUIRE_CLICK_TO_FOCUS
 #endif
 #endif