Browse Source

Add new build option for better targeting Raspberry Pi platform.

Yao Wei Tjong 姚伟忠 10 years ago
parent
commit
536b0a5429

+ 74 - 20
CMake/Modules/Urho3D-CMake-common.cmake

@@ -156,15 +156,46 @@ if (MINGW AND CMAKE_CROSSCOMPILING)
     set (MINGW_PREFIX "" CACHE STRING "Prefix path to MinGW cross-compiler tools (MinGW cross-compiling build only)")
     set (MINGW_SYSROOT "" CACHE PATH "Path to MinGW system root (MinGW cross-compiling build only)")
 endif ()
-if (RPI AND CMAKE_CROSSCOMPILING)
-    set (RPI_PREFIX "" CACHE STRING "Prefix path to Raspberry Pi cross-compiler tools (RPI cross-compiling build only)")
-    set (RPI_SYSROOT "" CACHE PATH "Path to Raspberry Pi system root (RPI cross-compiling build only)")
+if (RPI)
+    if (NOT RPI_SUPPORTED_ABIS)
+        set (RPI_SUPPORTED_ABIS armeabi-v6)
+        if (CMAKE_CROSSCOMPILING)
+            # We have no way to know for sure so just give all the available options to user
+            list (APPEND RPI_SUPPORTED_ABIS armeabi-v7a "armeabi-v7a with NEON" "armeabi-v7a with VFPV4")
+        else ()
+            execute_process (COMMAND uname -m OUTPUT_VARIABLE HOST_MACHINE ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+            if (HOST_MACHINE MATCHES ^armv7)
+                set (RPI_SUPPORTED_ABIS armeabi-v6 armeabi-v7a "armeabi-v7a with NEON" "armeabi-v7a with VFPV4")
+                if (NOT RPI_ABI)
+                    set (RPI_ABI armeabi-v7a)
+                endif ()
+            endif ()
+        endif ()
+        set (RPI_SUPPORTED_ABIS ${RPI_SUPPORTED_ABIS} CACHE INTERNAL "Supported target ABIs for RPI build")
+    endif ()
+    if (CMAKE_CROSSCOMPILING)
+        set (RPI_PREFIX "" CACHE STRING "Prefix path to Raspberry Pi cross-compiler tools (RPI cross-compiling build only)")
+        set (RPI_SYSROOT "" CACHE PATH "Path to Raspberry Pi system root (RPI cross-compiling build only)")
+    endif ()
+    if (RPI_ABI)
+        list (FIND RPI_SUPPORTED_ABIS ${RPI_ABI} RPI_ABI_FOUND_INDEX)
+        if (RPI_ABI_FOUND_INDEX EQUAL -1)
+            string (REPLACE ";" "\", \"" PRINTABLE_RPI_SUPPORTED_ABIS "${RPI_SUPPORTED_ABIS}")  # Stringify for string replace to work
+            if (NOT CMAKE_CROSSCOMPILING)
+                set (MSG_STR " by this Raspberry Pi device")
+            endif ()
+            message (FATAL_ERROR "Specified RPI_ABI = \"${RPI_ABI}\" is not supported${MSG_STR}. Supported values are: \"${PRINTABLE_RPI_SUPPORTED_ABIS}\".")
+        endif()
+    else ()
+        set (RPI_ABI armeabi-v6)
+    endif ()
+    set (RPI_ABI ${RPI_ABI} CACHE STRING "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" FORCE)
 endif ()
 if (EMSCRIPTEN)     # CMAKE_CROSSCOMPILING is always true for Emscripten
     set (EMSCRIPTEN_ROOT_PATH "" CACHE PATH "Root path to Emscripten cross-compiler tools (Emscripten cross-compiling build only)")
     set (EMSCRIPTEN_SYSROOT "" CACHE PATH "Path to Emscripten system root (Emscripten cross-compiling build only)")
     option (EMSCRIPTEN_ALLOW_MEMORY_GROWTH "Enable memory growing based on application demand (Emscripten cross-compiling build only)")
-    set (EMSCRIPTEN_TOTAL_MEMORY 268435456)  # This option is ignored when EMSCRIPTEN_ALLOW_MEMORY_GROWTH=1
+    set (EMSCRIPTEN_TOTAL_MEMORY 268435456)  # This option is ignored when EMSCRIPTEN_ALLOW_MEMORY_GROWTH option is set
 endif ()
 # Constrain the build option values in cmake-gui, if applicable
 if (CMAKE_VERSION VERSION_GREATER 2.8 OR CMAKE_VERSION VERSION_EQUAL 2.8)
@@ -172,6 +203,9 @@ if (CMAKE_VERSION VERSION_GREATER 2.8 OR CMAKE_VERSION VERSION_EQUAL 2.8)
     if (NOT CMAKE_CONFIGURATION_TYPES)
         set_property (CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${URHO3D_BUILD_CONFIGURATIONS})
     endif ()
+    if (RPI)
+        set_property (CACHE RPI_ABI PROPERTY STRINGS ${RPI_SUPPORTED_ABIS})
+    endif ()
 endif()
 
 # Enable testing
@@ -365,8 +399,21 @@ else ()
     else ()
         if (RPI)
             add_definitions (-DRPI)
-            set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Wno-psabi")
-            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pipe -mcpu=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard -Wno-psabi")
+            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")
+                else ()
+                    set (RPI_CFLAGS "${RPI_CFLAGS} -mfpu=vfpv4-d16")
+                endif ()
+            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}")
         else ()
             set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math")
             set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math")
@@ -439,32 +486,39 @@ set_output_directories (${CMAKE_BINARY_DIR}/bin RUNTIME PDB)
 
 # Macro for setting symbolic link on platform that supports it
 macro (create_symlink SOURCE DESTINATION)
+    # Make absolute paths so they work more reliably on cmake-gui
+    if (IS_ABSOLUTE ${SOURCE})
+        set (ABS_SOURCE ${SOURCE})
+    else ()
+        set (ABS_SOURCE ${CMAKE_SOURCE_DIR}/${SOURCE})
+    endif ()
+    if (IS_ABSOLUTE ${DESTINATION})
+        set (ABS_DESTINATION ${DESTINATION})
+    else ()
+        set (ABS_DESTINATION ${CMAKE_BINARY_DIR}/${DESTINATION})
+    endif ()
     if (CMAKE_HOST_WIN32)
-        if (IS_DIRECTORY ${SOURCE})
+        if (IS_DIRECTORY ${ABS_SOURCE})
             set (SLASH_D /D)
         else ()
             unset (SLASH_D)
         endif ()
         if (URHO3D_MKLINK)
-            if (NOT EXISTS ${DESTINATION})
-                # Have to use string-REPLACE as file-TO_NATIVE_PATH does not work as expected with MinGW on "backward host" system
-                string (REPLACE / \\ BACKWARD_DESTINATION ${DESTINATION})
-                string (REPLACE / \\ BACKWARD_SOURCE ${SOURCE})
-                execute_process (COMMAND cmd /C mklink ${SLASH_D} ${BACKWARD_DESTINATION} ${BACKWARD_SOURCE} OUTPUT_QUIET ERROR_QUIET)
+            if (NOT EXISTS ${ABS_DESTINATION})
+                # Have to use string-REPLACE as file-TO_NATIVE_PATH does not work as expected with MinGW on "backward slash" host system
+                string (REPLACE / \\ BACKWARD_ABS_DESTINATION ${ABS_DESTINATION})
+                string (REPLACE / \\ BACKWARD_ABS_SOURCE ${ABS_SOURCE})
+                execute_process (COMMAND cmd /C mklink ${SLASH_D} ${BACKWARD_ABS_DESTINATION} ${BACKWARD_ABS_SOURCE} OUTPUT_QUIET ERROR_QUIET)
             endif ()
         elseif (${ARGN} STREQUAL FALLBACK_TO_COPY)
-            if (NOT IS_ABSOLUTE ${SOURCE})
-                get_filename_component (PATH ${DESTINATION} PATH)
-                set (SOURCE ${PATH}/${SOURCE})
-            endif ()
             if (SLASH_D)
-                set (COMMAND COMMAND ${CMAKE_COMMAND} -E copy_directory ${SOURCE} ${DESTINATION})
+                set (COMMAND COMMAND ${CMAKE_COMMAND} -E copy_directory ${ABS_SOURCE} ${ABS_DESTINATION})
             else ()
-                set (COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SOURCE} ${DESTINATION})
+                set (COMMAND COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ABS_SOURCE} ${ABS_DESTINATION})
             endif ()
             if (TARGET ${TARGET_NAME})
                 # Fallback to copy everytime the target is built
-                add_custom_command (TARGET ${TARGET_NAME} POST_BUILD ${COMMAND} WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+                add_custom_command (TARGET ${TARGET_NAME} POST_BUILD ${COMMAND})
             else ()
                 # Fallback to copy only one time
                 execute_process (${COMMAND})
@@ -473,7 +527,7 @@ macro (create_symlink SOURCE DESTINATION)
             message (WARNING "Unable to create symbolic link on this host system, you may need to manually copy file/dir from \"${SOURCE}\" to \"${DESTINATION}\"")
         endif ()
     else ()
-        execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${SOURCE} ${DESTINATION})
+        execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${ABS_SOURCE} ${ABS_DESTINATION})
     endif ()
 endmacro ()
 

+ 3 - 2
Docs/GettingStarted.dox

@@ -110,6 +110,7 @@ A number of build options can be defined when invoking the build scripts or when
 |ANDROID_NDK_GDB      |0|Enable ndk-gdb support (Android Debug build only)|
 |MINGW_PREFIX         |-|Prefix path to MinGW cross-compiler tools (MinGW cross-compiling build only)|
 |MINGW_SYSROOT        |-|Path to MinGW system root (MinGW 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_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)|
 |EMSCRIPTEN_ROOT_PATH |-|Root path to Emscripten cross-compiler tools (Emscripten cross-compiling build only)|
@@ -200,9 +201,9 @@ To run from Xcode on iPhone/iPad Simulator, edit the Product Scheme to set "Run"
 
 For native build on Raspberry Pi itself, use the similar process for \ref Building_Native "Native build process" described above.
 
-For cross-compiling build on an Linux host system, firstly set the RPI_PREFIX environment variable or build option to point to your Raspberry Pi Cross-Compiling tool are located. You can setup the tool using <a href="http://crosstool-ng.org/">crosstool-NG</a> or just download one from https://github.com/raspberrypi/tools. Secondly, set the RPI_SYSROOT environment variable or build option to point to your Raspbian or Pidora system root. You must install the Urho3D prerequisites software development packages for Raspberry Pi (see \ref Building_Prerequisites) in the system root before attempting to do the Urho3D cross-compiling build. You are recommended to download the Raspbian system root with Urho3D prerequisite software installed from https://github.com/urho3d/rpi-sysroot. You can just download from the "strip" branch to cut down the download time and size.
+For cross-compiling build on an Linux host system, firstly set the RPI_PREFIX environment variable or build option to point to your Raspberry Pi Cross-Compiling tool are located. You can setup the tool using <a href="http://crosstool-ng.org/">crosstool-NG</a> or just download one from https://github.com/raspberrypi/tools. Secondly, set the RPI_SYSROOT environment variable or build option to point to your Raspbian or Pidora system root. You must install the Urho3D prerequisites software development packages for Raspberry Pi (see \ref Building_Prerequisites) in the system root before attempting to do the Urho3D cross-compiling build. You are recommended to download the Raspbian system root with Urho3D prerequisite software installed from https://github.com/urho3d/rpi-sysroot. You can just download from the "strip" branch to cut down the download time and size. Alternatively, if you have a fast LAN connection then you can also opt to mount the system root on your actual Raspberry Pi device to your host system via SSHFS and set the RPI_SYSROOT to use the mount point.
 
-Execute cmake_raspi.sh then go to the build tree to execute make command. After the build is complete, the ARM executables can be found in the build tree's "bin" subdirectory.
+Execute cmake_raspi.sh then go to the build tree to execute make command. You may pass the optional RPI_ABI build option to specifically target for the Raspberry Pi 2. After the build is complete, the ARM executables can be found in the build tree's "bin" subdirectory.
 
 You can also build, deploy, run/debug (as C/C++ Remote %Application) using Eclipse IDE. To do that, execute cmake_eclipse.sh with "-DRPI=1" build option set. Import the CMake generated Eclipse project in the build tree into Eclipse's workspace. Build the project as usual. Optionally, use the "URHO3D_SCP_TO_TARGET" build option to automatically deploy the ARM executables to target Raspberry Pi device as part of build process; or configure Eclipse to perform a "download to target path" in the Run/Debug configuration for C/C++ Remote %Application. Either way, you have to configure the Run/Debug configuration to let it know how to reach your target Raspberry Pi device.
 

+ 8 - 8
Source/Urho3D/Core/ProcessUtils.cpp

@@ -357,8 +357,8 @@ String GetPlatform()
     #endif
 }
 
-#ifdef ANDROID
-static unsigned GetAndroidCPUCount()
+#if defined(ANDROID) || defined(RPI)
+static unsigned GetArmCPUCount()
 {
     FILE* fp;
     int res, i = -1, j = -1;
@@ -392,9 +392,9 @@ unsigned GetNumPhysicalCPUs()
     #else
     return data.physical_cpu;
     #endif
-    #elif defined(ANDROID)
-    return GetAndroidCPUCount();
-    #elif !defined(RPI) && !defined(EMSCRIPTEN)
+    #elif defined(ANDROID) || defined(RPI)
+    return GetArmCPUCount();
+    #elif !defined(EMSCRIPTEN)
     struct cpu_id_t data;
     GetCPUData(&data);
     return data.num_cores;
@@ -414,9 +414,9 @@ unsigned GetNumLogicalCPUs()
     #else
     return data.logical_cpu;
     #endif
-    #elif defined(ANDROID)
-    return GetAndroidCPUCount();
-    #elif !defined(RPI) && !defined(EMSCRIPTEN)
+    #elif defined(ANDROID) || defined (RPI)
+    return GetArmCPUCount();
+    #elif !defined(EMSCRIPTEN)
     struct cpu_id_t data;
     GetCPUData(&data);
     return data.num_logical_cpus;

+ 1 - 1
cmake_generic.sh

@@ -52,7 +52,7 @@ for a in $@; do
             ANDROID=1 && OPTS="-DCMAKE_TOOLCHAIN_FILE=$TOOLCHAINS/android.toolchain.cmake"
             ;;
         -DRPI=1)
-            RPI=1 && if [[ ! $(uname -m) =~ ^armv6 ]]; then OPTS="-DCMAKE_TOOLCHAIN_FILE=$TOOLCHAINS/raspberrypi.toolchain.cmake"; fi
+            RPI=1 && if [[ ! $(uname -m) =~ ^arm ]]; then OPTS="-DCMAKE_TOOLCHAIN_FILE=$TOOLCHAINS/raspberrypi.toolchain.cmake"; fi
             ;;
         -DWIN32=1)
             WINDOWS=1 && OPTS="-DCMAKE_TOOLCHAIN_FILE=$TOOLCHAINS/mingw.toolchain.cmake"