Browse Source

Merge branch 'master' of https://github.com/urho3d/Urho3D

aster2013 10 years ago
parent
commit
6beb325b69

+ 1 - 1
.bash_helpers.sh

@@ -89,7 +89,7 @@ post_cmake() {
                 #
                 xmlstarlet ed -P -L \
                     -u "/cproject/storageModule/cconfiguration/storageModule/pathentry[@kind = 'src']/@path" -v "" \
-                    -s "/cproject/storageModule/cconfiguration/storageModule/pathentry[@kind = 'src']" -t attr -n "excluding" -v "[Build]/|[Subprojects]/|[Targets]/" \
+                    -s "/cproject/storageModule/cconfiguration/storageModule/pathentry[@kind = 'src']" -t attr -n "excluding" -v "[Build]/|[Subprojects]/|[Targets]/|Docs/AngelScriptAPI.h" \
                     -u "/cproject/storageModule/cconfiguration/storageModule/pathentry[@kind = 'out']/@path" -v "[Build]" \
                     -u "/cproject/storageModule/cconfiguration/storageModule/pathentry[@kind = 'out']/@excluding" -x "substring-after(., '[Source directory]/|')" \
                     "$SOURCE"/.cproject

+ 2 - 0
.travis.yml

@@ -42,6 +42,8 @@ env:
     - LINUX=1   URHO3D_LIB_TYPE=SHARED URHO3D_64BIT=0
     - WINDOWS=1 URHO3D_LIB_TYPE=STATIC URHO3D_64BIT=0
     - WINDOWS=1 URHO3D_LIB_TYPE=SHARED URHO3D_64BIT=0
+    - WINDOWS=1 URHO3D_LIB_TYPE=STATIC URHO3D_64BIT=0 URHO3D_OPENGL=0
+    - WINDOWS=1 URHO3D_LIB_TYPE=SHARED URHO3D_64BIT=0 URHO3D_OPENGL=0
     # WINDOWS=1 URHO3D_LIB_TYPE=STATIC URHO3D_64BIT=0 URHO3D_D3D11=1
     # WINDOWS=1 URHO3D_LIB_TYPE=SHARED URHO3D_64BIT=0 URHO3D_D3D11=1
 matrix:

+ 41 - 19
CMake/Modules/Urho3D-CMake-common.cmake

@@ -22,7 +22,7 @@
 
 # Limit the supported build configurations
 set (URHO3D_BUILD_CONFIGURATIONS Release RelWithDebInfo Debug)
-set (DOC_STRING "Choose the build configuration, possible options are: ${URHO3D_BUILD_CONFIGURATIONS}")
+set (DOC_STRING "Specify CMake build configuration (single-configuration generator only), possible values are Release (default), RelWithDebInfo, and Debug")
 if (CMAKE_CONFIGURATION_TYPES)
     # For multi-configurations generator, such as VS and Xcode
     set (CMAKE_CONFIGURATION_TYPES ${URHO3D_BUILD_CONFIGURATIONS} CACHE STRING "${DOC_STRING}" FORCE)
@@ -68,7 +68,7 @@ if (ANDROID OR RPI OR EMSCRIPTEN)
     # This build option is not available on Android, Raspberry-Pi, and Emscripten platforms as its value is preset by the chosen toolchain in the build tree
     set (URHO3D_64BIT ${URHO3D_DEFAULT_64BIT})
 else ()
-    option (URHO3D_64BIT "Enable 64-bit build" ${URHO3D_DEFAULT_64BIT})
+    option (URHO3D_64BIT "Enable 64-bit build, on MSVC default to 0, on other compilers the default is set based on the 64-bit capability of the chosen toolchain on host system" ${URHO3D_DEFAULT_64BIT})
 endif ()
 cmake_dependent_option (URHO3D_ANGELSCRIPT "Enable AngelScript scripting support" TRUE "NOT EMSCRIPTEN" FALSE)
 option (URHO3D_LUA "Enable additional Lua scripting support")
@@ -114,7 +114,7 @@ option (URHO3D_TESTING "Enable testing support")
 if (URHO3D_TESTING)
     if (EMSCRIPTEN)
         set (DEFAULT_TIMEOUT 10)
-        set (EMSCRIPTEN_EMRUN_BROWSER firefox CACHE STRING "Specify the particular browser to be spawned by emrun during testing (Emscripten cross-compiling build only), default to firefox")
+        set (EMSCRIPTEN_EMRUN_BROWSER firefox CACHE STRING "Specify the particular browser to be spawned by emrun during testing (Emscripten cross-compiling build only), use 'emrun --list_browsers' command to get the list of possible values")
     else ()
         set (DEFAULT_TIMEOUT 5)
     endif ()
@@ -168,6 +168,13 @@ endif ()
 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)")
+    # When cross-compiling then we are most probably in Unix-alike host environment which should not have problem to handle long include dirs
+    # This change is required to keep ccache happy because it does not like the CMake generated include response file
+    foreach (lang C CXX)
+        foreach (cat OBJECTS INCLUDES)
+            unset (CMAKE_${lang}_USE_RESPONSE_FILE_FOR_${cat})
+        endforeach ()
+    endforeach ()
 endif ()
 if (RPI)
     if (NOT RPI_SUPPORTED_ABIS)
@@ -203,13 +210,14 @@ if (RPI)
     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)
+    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)")
     math (EXPR EMSCRIPTEN_TOTAL_MEMORY "32 * 1024 * 1024")     # This option is ignored when EMSCRIPTEN_ALLOW_MEMORY_GROWTH option is set
+    set (EMSCRIPTEN_TOTAL_MEMORY ${EMSCRIPTEN_TOTAL_MEMORY} CACHE STRING "Specify the total size of memory to be used (Emscripten cross-compiling build only); default to 33554432 (32MB), this option is ignored when EMSCRIPTEN_ALLOW_MEMORY_GROWTH=1")
     cmake_dependent_option (EMSCRIPTEN_SHARE_DATA "Enable sharing data file support (Emscripten cross-compiling build only)" FALSE "EMSCRIPTEN" FALSE)
 endif ()
 # Constrain the build option values in cmake-gui, if applicable
@@ -456,9 +464,11 @@ else ()
         if (EMSCRIPTEN)
             # Emscripten-specific setup
             set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-warn-absolute-paths -Wno-unknown-warning-option")
-            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-warn-absolute-paths -Wno-unknown-warning-option")
-            set (CMAKE_C_FLAGS_RELEASE "-Oz")
-            set (CMAKE_CXX_FLAGS_RELEASE "-Oz")
+            # Temporarily add the C++ standard explicitly because currently Emscripten does not consistently add the standard in its internall processing
+            # and this may cause compilation problem when precompiled header is involved (See https://github.com/kripken/emscripten/issues/3365 for more detail)
+            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-warn-absolute-paths -Wno-unknown-warning-option -std=c++03")
+            set (CMAKE_C_FLAGS_RELEASE "-Oz -DNDEBUG")
+            set (CMAKE_CXX_FLAGS_RELEASE "-Oz -DNDEBUG")
             if (DEFINED ENV{CI})
                 # Our CI server is slow, so do not optimize and discard all debug info when test building in Debug configuration
                 set (CMAKE_C_FLAGS_DEBUG "-g0")
@@ -483,13 +493,14 @@ else ()
         set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -D_DEBUG")
     endif ()
     if (CMAKE_CXX_COMPILER_ID STREQUAL Clang)
-        if (CMAKE_GENERATOR STREQUAL Ninja)
-            set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics")
-            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
+        if (CMAKE_GENERATOR STREQUAL Ninja OR "$ENV{USE_CCACHE}")
+            # When ccache support is on, these flags keep the color diagnostics pipe through ccache output and suppress Clang warning due ccache internal preprocessing step
+            set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics -Qunused-arguments")
+            set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics -Qunused-arguments")
         endif ()
         # Temporary workaround for Travis CI VM as Ubuntu 12.04 LTS still uses old glibc header files that do not have the necessary patch for Clang to work correctly
         # TODO: Remove this workaround when Travis CI VM has been migrated to Ubuntu 14.04 LTS (or hopefully it will be CentOS :)
-        if (DEFINED ENV{CI} AND "$ENV{LINUX}" STREQUAL 1)
+        if (DEFINED ENV{CI} AND "$ENV{LINUX}")
             add_definitions (-D__extern_always_inline=inline)
         endif ()
     endif ()
@@ -649,11 +660,14 @@ macro (enable_pch HEADER_PATHNAME)
                     COMMENT "Precompiling header file '${HEADER_FILENAME}' for ${CONFIG} configuration")
             endforeach ()
             # Use the precompiled header file
+            if (NOT XCODE)
+                set (PCH_DIR ${CMAKE_CURRENT_BINARY_DIR}/)
+            endif ()
             foreach (FILE ${SOURCE_FILES})
                 if (FILE MATCHES \\.cpp$)
                     get_property (NO_PCH SOURCE ${FILE} PROPERTY NO_PCH)
                     if (NOT NO_PCH)
-                        set_property (SOURCE ${FILE} APPEND_STRING PROPERTY COMPILE_FLAGS " -include ${HEADER_FILENAME}")
+                        set_property (SOURCE ${FILE} APPEND_STRING PROPERTY COMPILE_FLAGS " -include ${PCH_DIR}${HEADER_FILENAME}")
                     endif ()
                 endif ()
             endforeach ()
@@ -672,12 +686,6 @@ macro (enable_pch HEADER_PATHNAME)
                 set (TRIGGERS ${HEADER_FILENAME}.${CMAKE_BUILD_TYPE}.pch.trigger)
             endif ()
             list (APPEND SOURCE_FILES ${TRIGGERS})
-            # Ninja-build specific
-            if (CMAKE_GENERATOR STREQUAL Ninja)
-                # The precompiled header is always generated in the current binary dir,
-                # but Ninja project is not able to find it without adding the binary dir to the include search path
-                list (APPEND INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
-            endif ()
         endif ()
     endif ()
 endmacro ()
@@ -1124,7 +1132,13 @@ macro (setup_test)
         endif ()
         list (APPEND ARG_OPTIONS -timeout ${URHO3D_TEST_TIMEOUT})
         if (EMSCRIPTEN)
-            math (EXPR EMRUN_TIMEOUT "2 * ${URHO3D_TEST_TIMEOUT}")
+            if (DEFINED ENV{CI})
+                # The latency on Travis CI server could be very high at time, so set it to the maximum allowed by Travis CI before the process being timed out by Travis CI itself
+                set (EMRUN_TIMEOUT 590)     # 10 minutes (Travis CI timeout) - 10 seconds
+            else ()
+                # Non-CI test
+                math (EXPR EMRUN_TIMEOUT "2 * ${URHO3D_TEST_TIMEOUT}")
+            endif ()
             add_test (NAME ${ARG_NAME} COMMAND ${EMRUN} --browser ${EMSCRIPTEN_EMRUN_BROWSER} --timeout ${EMRUN_TIMEOUT} --timeout_returncode 1 --kill_exit ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TARGET_NAME}.html ${ARG_OPTIONS})
         else ()
             add_test (NAME ${ARG_NAME} COMMAND ${TARGET_NAME} ${ARG_OPTIONS})
@@ -1435,6 +1449,14 @@ elseif (EMSCRIPTEN)
         string (REPLACE "<body>" "<body>\n\n<a href=\"http://urho3d.github.io\" title=\"Urho3D Homepage\"><img src=\"http://urho3d.github.io/assets/images/logo.png\" alt=\"link to http://urho3d.github.io\" height=\"80\" width=\"320\" /></a>\n" SHELL_HTML "${SHELL_HTML}")
         file (WRITE ${CMAKE_BINARY_DIR}/Source/shell.html "${SHELL_HTML}")
     endif ()
+elseif (NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_HOST_WIN32 AND "$ENV{USE_CCACHE}")
+    # Warn user if PATH environment variable has not been correctly set for using ccache
+    execute_process (COMMAND whereis -b ccache COMMAND grep -o \\S*lib\\S* RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE CCACHE_SYMLINK ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+    if (EXIT_CODE EQUAL 0 AND NOT ${CMAKE_C_COMPILER} MATCHES ${CCACHE_SYMLINK})
+        message (WARNING "The lib directory containing the ccache symlinks (${CCACHE_SYMLINK}) has not been added in the PATH environment variable. "
+            "This is required to enable ccache support for native compiler toolchain. CMake has been configured to use the actual compiler toolchain instead of ccache. "
+            "In order to rectify this, the build tree must be regenerated after the PATH environment variable has been adjusted accordingly.")
+    endif ()
 endif ()
 
 # Post-CMake fixes

+ 29 - 0
CMake/Toolchains/android.toolchain.cmake

@@ -1147,6 +1147,35 @@ if( NOT CMAKE_C_COMPILER )
    set( CMAKE_C_COMPILER_ARG1   "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler")
    set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler")
   endif()
+ # Urho3D - there are two ways to use ccache, by prefixing compiler toolchain with 'ccache' command (as done by NDK_CCACHE code branch above) or
+ #          let ccache masquerade as the compiler by creating a symbolic link named as the compiler pointing back to 'ccache' command
+ #          Urho3D has to use the second way because the first one does not handle our precompiled header build rules well
+ elseif ("$ENV{USE_CCACHE}" AND NOT CMAKE_HOST_WIN32)   # Need to stringify to guard against undefined environment variable
+    execute_process (COMMAND which ccache RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE CCACHE ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+    if (EXIT_CODE EQUAL 0)
+        if (ANDROID_COMPILER_IS_CLANG)
+            set (PATH ${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin)
+            execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${CCACHE} ${CMAKE_BINARY_DIR}/${_clang_name})
+            set (CMAKE_C_COMPILER ${CMAKE_BINARY_DIR}/${_clang_name} CACHE PATH "C compiler")
+            execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${CCACHE} ${CMAKE_BINARY_DIR}/${_clang_name}++)
+            set (CMAKE_CXX_COMPILER ${CMAKE_BINARY_DIR}/${_clang_name}++ CACHE PATH "C++ compiler")
+        else ()
+            set (PATH ${ANDROID_TOOLCHAIN_ROOT}/bin)
+            execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${CCACHE} ${CMAKE_BINARY_DIR}/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc)
+            set (CMAKE_C_COMPILER ${CMAKE_BINARY_DIR}/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc CACHE PATH "C compiler")
+            execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${CCACHE} ${CMAKE_BINARY_DIR}/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++)
+            set (CMAKE_CXX_COMPILER ${CMAKE_BINARY_DIR}/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++ CACHE PATH "C++ compiler")
+        endif ()
+    else ()
+        # To avoid repeating the code to instruct CMake to fallback to use the actual Android compiler toolchain below, we raise this as an error instead of warning
+        message (FATAL_ERROR "ccache may not have been installed on this host system. "
+            "This is required to enable ccache support for Android compiler toolchain. "
+            "In order to rectify this, install ccache software package first or do not set the USE_CCACHE environment variable.")
+    endif ()
+    if (NOT $ENV{PATH} MATCHES ${PATH})
+        message (FATAL_ERROR "The bin directory containing the compiler toolchain (${PATH}) has not been added in the PATH environment variable. "
+            "This is required to enable ccache support for Android compiler toolchain.")
+    endif ()
  else()
   if( ANDROID_COMPILER_IS_CLANG )
    set( CMAKE_C_COMPILER   "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}"   CACHE PATH "C compiler")

+ 22 - 2
CMake/Toolchains/emscripten.toolchain.cmake

@@ -45,8 +45,28 @@ endif ()
 if (CMAKE_HOST_WIN32)
     set (TOOL_EXT .bat)
 endif ()
-set (CMAKE_C_COMPILER   ${EMSCRIPTEN_ROOT_PATH}/emcc${TOOL_EXT}     CACHE PATH "C compiler")
-set (CMAKE_CXX_COMPILER ${EMSCRIPTEN_ROOT_PATH}/em++${TOOL_EXT}     CACHE PATH "C++ compiler")
+set (COMPILER_PATH ${EMSCRIPTEN_ROOT_PATH})
+# For now enable ccache support only when the CCACHE_CPP2 env var is also set to 1, until Emscripten has fixed https://github.com/kripken/emscripten/issues/3365
+# This ccache's option tells ccache to fallback to use original input source file instead of preprocessed source file which Emscripten does not support currently
+if ("$ENV{USE_CCACHE}" AND NOT CMAKE_HOST_WIN32 AND "$ENV{CCACHE_CPP2}")
+    if (NOT $ENV{PATH} MATCHES ${EMSCRIPTEN_ROOT_PATH})
+        message (FATAL_ERROR "The bin directory containing the compiler toolchain (${EMSCRIPTEN_ROOT_PATH}) has not been added in the PATH environment variable. "
+            "This is required to enable ccache support for Emscripten compiler toolchain.")
+    endif ()
+    execute_process (COMMAND which ccache RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE CCACHE ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+    if (EXIT_CODE EQUAL 0)
+        foreach (name emcc em++)
+            execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${CCACHE} ${CMAKE_BINARY_DIR}/${name})
+        endforeach ()
+        set (COMPILER_PATH ${CMAKE_BINARY_DIR})
+    else ()
+        message (WARNING "ccache may not have been installed on this host system. "
+            "This is required to enable ccache support for Emscripten compiler toolchain. CMake has been configured to use the actual compiler toolchain instead of ccache. "
+            "In order to rectify this, the build tree must be regenerated after installing ccache.")
+    endif ()
+endif ()
+set (CMAKE_C_COMPILER   ${COMPILER_PATH}/emcc${TOOL_EXT}            CACHE PATH "C compiler")
+set (CMAKE_CXX_COMPILER ${COMPILER_PATH}/em++${TOOL_EXT}            CACHE PATH "C++ compiler")
 set (CMAKE_AR           ${EMSCRIPTEN_ROOT_PATH}/emar${TOOL_EXT}     CACHE PATH "archive")
 set (CMAKE_RANLIB       ${EMSCRIPTEN_ROOT_PATH}/emranlib${TOOL_EXT} CACHE PATH "ranlib")
 # Specific to Emscripten

+ 28 - 2
CMake/Toolchains/mingw.toolchain.cmake

@@ -40,8 +40,34 @@ if (NOT EXISTS ${MINGW_PREFIX}-gcc)
     message (FATAL_ERROR "Could not find MinGW cross compilation tool. "
         "Use MINGW_PREFIX environment variable or build option to specify the location of the toolchain.")
 endif ()
-set (CMAKE_C_COMPILER   ${MINGW_PREFIX}-gcc     CACHE PATH "C compiler")
-set (CMAKE_CXX_COMPILER ${MINGW_PREFIX}-g++     CACHE PATH "C++ compiler")
+set (COMPILER_PREFIX ${MINGW_PREFIX})
+if ($ENV{USE_CCACHE})
+    get_filename_component (NAME ${MINGW_PREFIX} NAME)
+    execute_process (COMMAND whereis -b ccache COMMAND grep -o \\S*lib\\S* RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE CCACHE_SYMLINK ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+    if (EXIT_CODE EQUAL 0 AND EXISTS ${CCACHE_SYMLINK}/${NAME}-gcc AND EXISTS ${CCACHE_SYMLINK}/${NAME}-g++)
+        set (COMPILER_PREFIX ${CCACHE_SYMLINK}/${NAME})
+    else ()
+        # Most probably this is a custom compiler toolchain not provided by the distro's own repository
+        get_filename_component (PATH ${MINGW_PREFIX} PATH)
+        if (NOT $ENV{PATH} MATCHES ${PATH})
+            message (FATAL_ERROR "The bin directory containing the compiler toolchain (${PATH}) has not been added in the PATH environment variable. "
+                "This is required to enable ccache support for MinGW compiler toolchain.")
+        endif ()
+        execute_process (COMMAND which ccache RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE CCACHE ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+        if (EXIT_CODE EQUAL 0)
+            foreach (suffix gcc g++)
+                execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${CCACHE} ${CMAKE_BINARY_DIR}/${NAME}-${suffix})
+            endforeach ()
+            set (COMPILER_PREFIX ${CMAKE_BINARY_DIR}/${NAME})
+        else ()
+            message (WARNING "ccache may not have been installed on this host system. "
+                "This is required to enable ccache support for MinGW compiler toolchain. CMake has been configured to use the actual compiler toolchain instead of ccache. "
+                "In order to rectify this, the build tree must be regenerated after installing ccache.")
+        endif ()
+    endif ()
+endif ()
+set (CMAKE_C_COMPILER   ${COMPILER_PREFIX}-gcc  CACHE PATH "C compiler")
+set (CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++  CACHE PATH "C++ compiler")
 set (CMAKE_STRIP        ${MINGW_PREFIX}-strip   CACHE PATH "strip")
 set (CMAKE_AR           ${MINGW_PREFIX}-ar      CACHE PATH "archive")
 set (CMAKE_LINKER       ${MINGW_PREFIX}-ld      CACHE PATH "linker")

+ 35 - 9
CMake/Toolchains/raspberrypi.toolchain.cmake

@@ -40,15 +40,41 @@ if (NOT EXISTS ${RPI_PREFIX}-gcc)
     message (FATAL_ERROR "Could not find Raspberry Pi cross compilation tool. "
         "Use RPI_PREFIX environment variable or build option to specify the location of the toolchain.")
 endif ()
-set (CMAKE_C_COMPILER   ${RPI_PREFIX}-gcc     CACHE PATH "C compiler")
-set (CMAKE_CXX_COMPILER ${RPI_PREFIX}-c++     CACHE PATH "C++ compiler")
-set (CMAKE_STRIP        ${RPI_PREFIX}-strip   CACHE PATH "strip")
-set (CMAKE_AR           ${RPI_PREFIX}-ar      CACHE PATH "archive")
-set (CMAKE_LINKER       ${RPI_PREFIX}-ld      CACHE PATH "linker")
-set (CMAKE_NM           ${RPI_PREFIX}-nm      CACHE PATH "nm")
-set (CMAKE_OBJCOPY      ${RPI_PREFIX}-objcopy CACHE PATH "objcopy")
-set (CMAKE_OBJDUMP      ${RPI_PREFIX}-objdump CACHE PATH "objdump")
-set (CMAKE_RANLIB       ${RPI_PREFIX}-ranlib  CACHE PATH "ranlib")
+set (COMPILER_PREFIX ${RPI_PREFIX})
+if ($ENV{USE_CCACHE})
+    get_filename_component (NAME ${RPI_PREFIX} NAME)
+    execute_process (COMMAND whereis -b ccache COMMAND grep -o \\S*lib\\S* RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE CCACHE_SYMLINK ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+    if (EXIT_CODE EQUAL 0 AND EXISTS ${CCACHE_SYMLINK}/${NAME}-gcc AND EXISTS ${CCACHE_SYMLINK}/${NAME}-g++)
+        set (COMPILER_PREFIX ${CCACHE_SYMLINK}/${NAME})
+    else ()
+        # Most probably this is a custom compiler toolchain not provided by the distro's own repository
+        get_filename_component (PATH ${RPI_PREFIX} PATH)
+        if (NOT $ENV{PATH} MATCHES ${PATH})
+            message (FATAL_ERROR "The bin directory containing the compiler toolchain (${PATH}) has not been added in the PATH environment variable. "
+                "This is required to enable ccache support for Raspberry-Pi compiler toolchain.")
+        endif ()
+        execute_process (COMMAND which ccache RESULT_VARIABLE EXIT_CODE OUTPUT_VARIABLE CCACHE ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+        if (EXIT_CODE EQUAL 0)
+            foreach (suffix gcc g++)
+                execute_process (COMMAND ${CMAKE_COMMAND} -E create_symlink ${CCACHE} ${CMAKE_BINARY_DIR}/${NAME}-${suffix})
+            endforeach ()
+            set (COMPILER_PREFIX ${CMAKE_BINARY_DIR}/${NAME})
+        else ()
+            message (WARNING "ccache may not have been installed on this host system. "
+                "This is required to enable ccache support for Raspberry-Pi compiler toolchain. CMake has been configured to use the actual compiler toolchain instead of ccache. "
+                "In order to rectify this, the build tree must be regenerated after installing ccache.")
+        endif ()
+    endif ()
+endif ()
+set (CMAKE_C_COMPILER   ${COMPILER_PREFIX}-gcc CACHE PATH "C compiler")
+set (CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++ CACHE PATH "C++ compiler")
+set (CMAKE_STRIP        ${RPI_PREFIX}-strip    CACHE PATH "strip")
+set (CMAKE_AR           ${RPI_PREFIX}-ar       CACHE PATH "archive")
+set (CMAKE_LINKER       ${RPI_PREFIX}-ld       CACHE PATH "linker")
+set (CMAKE_NM           ${RPI_PREFIX}-nm       CACHE PATH "nm")
+set (CMAKE_OBJCOPY      ${RPI_PREFIX}-objcopy  CACHE PATH "objcopy")
+set (CMAKE_OBJDUMP      ${RPI_PREFIX}-objdump  CACHE PATH "objdump")
+set (CMAKE_RANLIB       ${RPI_PREFIX}-ranlib   CACHE PATH "ranlib")
 
 # specify the system root
 if (NOT RPI_SYSROOT OR NOT BCM_VC_INCLUDE_DIRS OR NOT BCM_VC_LIBRARIES)

+ 3 - 0
CMakeLists.txt

@@ -134,6 +134,9 @@ elseif (CPACK_SYSTEM_NAME STREQUAL Linux)
 endif ()
 if (URHO3D_64BIT)
     set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-64bit)
+else ()
+    set (CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
+    set (CPACK_RPM_PACKAGE_ARCHITECTURE i686)       # The 'package' target should be built with the help of 'setarch i686' command on a 64-bit host system
 endif ()
 set (CPACK_SYSTEM_NAME ${CPACK_SYSTEM_NAME}-${URHO3D_LIB_TYPE})
 if (WIN32 AND NOT URHO3D_OPENGL)

+ 30 - 12
Docs/GettingStarted.dox

@@ -4,6 +4,8 @@ namespace Urho3D
 /**
 \page Building Building Urho3D
 
+\tableofcontents
+
 \section Building_Prerequisites Building prerequisites
 
 Although all required third-party libraries are included as source code, there are system-level dependencies that must be satisfied before Urho3D can be built successfully:
@@ -62,14 +64,14 @@ Our CMakeLists.txt files are designed to work with most of the generators suppor
 
 \section Build_Options Build options
 
-A number of build options can be defined when invoking the build scripts or when configurating the project interactively using cmake-gui. To use one of these build options on the command line interface, pass it in this format "-DOPTION=VALUE" without the quotes.\n
-|Build Option         |V|Description          |
-|---------------------|-|---------------------|
+A number of build options can be defined when invoking the build scripts or when configurating the project interactively using cmake-gui. To use one of these build options on the command line interface, pass it in this format "-DOPTION=VALUE" without the quotes. Most of the build options are boolean variables where setting their values to 0 means disabling a feature or setting an option to false, while 1 means enabling a feature or setting an option to true. The table below shows all the available build options and their default values. Non-boolean build options generally do not have any default values and are marked with '-' in the table. However, a few build options marked with '*' have their default values set differently based on the value of other variables or external factors.
+|Build Option         |Value|Description          |
+|---------------------|-----|---------------------|
 |ANDROID              |0|Configure project using Android cross-compiler toolchain (cmake_generic.bat and cmake_generic.sh only)|
 |RPI                  |0|Configure project using Raspberry Pi cross-compiler toolchain (cmake_generic.sh only)|
 |WIN32                |0|Configure project using MinGW cross-compiler toolchain (cmake_generic.sh only); also applicable when cross-compiling 64-bit Windows platform|
 |IOS                  |0|Configure project for targeting iOS platform (cmake_generic.sh and cmake-gui only)|
-|URHO3D_64BIT         |*|Enable 64bit build, on MSVC default to 0, on other compilers the default is set based on the 64-bit capability of the chosen toolchain on host system|
+|URHO3D_64BIT         |*|Enable 64-bit build, on MSVC default to 0, on other compilers the default is set based on the 64-bit capability of the chosen toolchain on host system|
 |URHO3D_ANGELSCRIPT   |1|Enable AngelScript scripting support|
 |URHO3D_LUA           |0|Enable Lua scripting support|
 |URHO3D_LUAJIT        |0|Enable Lua scripting support using LuaJIT (check LuaJIT's CMakeLists.txt for more options)|
@@ -97,29 +99,29 @@ A number of build options can be defined when invoking the build scripts or when
 |URHO3D_STATIC_RUNTIME|0|Use static C/C++ runtime libraries and eliminate the need for runtime DLLs installation (VS only)|
 |URHO3D_WIN32_CONSOLE |0|Use console main() as entry point when setting up Windows executable targets (Windows platform only)|
 |URHO3D_MACOSX_BUNDLE |0|Use MACOSX_BUNDLE when setting up Mac OS X executable targets (Xcode native build only)|
-|URHO3D_LIB_TYPE      |*|Specify Urho3D library type, possible values are STATIC (\*default) and SHARED|
+|URHO3D_LIB_TYPE      |STATIC|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_USE_LIB64_RPM |0|Enable 64-bit RPM CPack generator using /usr/lib64 and disable all other generators (Debian-based host only, which uses /usr/lib by default)|
 |URHO3D_USE_LIB_DEB   |0|Enable 64-bit DEB CPack generator using /usr/lib and disable all other generators (Redhat-based host only, which uses /usr/lib64 by default)|
 |URHO3D_HOME          |-|Path to Urho3D build tree or SDK installation location (external project only)|
-|CMAKE_BUILD_TYPE     |*|Specify CMake build configuration (single-configuration generator only), possible values are Release (\*default), RelWithDebInfo, and Debug|
+|CMAKE_BUILD_TYPE     |Release|Specify CMake build configuration (single-configuration generator only), possible values are Release (default), RelWithDebInfo, and Debug|
 |CMAKE_INSTALL_PREFIX |*|Install path prefix, prepended onto install directories; default to 'c:/Program Files/Urho3D' on Windows host and '/usr/local' on all other non-Windows hosts|
 |CMAKE_OSX_DEPLOYMENT_TARGET|-|Specify Mac OS X deployment target (OSX build only); default to current running OS X if not specified, the minimum supported target is 10.5 due to constraint from SDL library|
 |IPHONEOS_DEPLOYMENT_TARGET|-|Specify iPhone OS deployment target (iOS build only); default to latest installed iOS SDK if not specified, the minimum spported target is 3.0 due to constraint from SDL library|
-|ANDROID_ABI          |*|Specify target ABI (Android build only), possible values are arm64-v8a, armeabi, armeabi-v6 with VFP, armeabi-v7a (\*default), armeabi-v7a with NEON, armeabi-v7a with VFPV3, mips, mips64, x86, and x86_64|
+|ANDROID_ABI          |armeabi-v7a|Specify target ABI (Android build only), possible values are arm64-v8a, armeabi, armeabi-v6 with VFP, armeabi-v7a (default), armeabi-v7a with NEON, armeabi-v7a with VFPV3, mips, mips64, x86, and x86_64|
 |ANDROID_NATIVE_API_LEVEL|*|Specify target API level (Android build only), possible values depends on installed NDK version, default to API level 12 on 32-bit ABIs, default to API level 21 on 64-bit ABIs|
 |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_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_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|
 |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_ALLOW_MEMORY_GROWTH|0|Enable memory growing based on application demand (Emscripten cross-compiling build only)|
-|EMSCRIPTEN_TOTAL_MEMORY|*|Specify the total size of memory to be used (Emscripten cross-compiling build only); default to 32MB, this option is ignored when EMSCRIPTEN_ALLOW_MEMORY_GROWTH=1|
+|EMSCRIPTEN_TOTAL_MEMORY|*|Specify the total size of memory to be used (Emscripten cross-compiling build only); default to 33554432 (32MB), this option is ignored when EMSCRIPTEN_ALLOW_MEMORY_GROWTH=1|
 |EMSCRIPTEN_SHARE_DATA|0|Enable sharing data file support (Emscripten cross-compiling build only)|
-|EMSCRIPTEN_EMRUN_BROWSER|*|Specify the particular browser to be spawned by emrun during testing (Emscripten cross-compiling build only), default to firefox|
+|EMSCRIPTEN_EMRUN_BROWSER|firefox|Specify the particular browser to be spawned by emrun during testing (Emscripten cross-compiling build only), use 'emrun --list_browsers' command to get the list of possible values|
 
 Note that the specified build option values are cached by CMake after the initial configuration step. The cached values will be used by CMake in the subsequent configuration. The same build options are not required to be specified again and again. But once a non-default build option value is being cached, it can only be reverted back to its default value by explicitly resetting it. That is, simply by not passing the corresponding build option would not revert it back to its default. One way to revert all the build options to their default values is by clearing the CMake cache by executing cmake_clean.bat or cmake_clean.sh with the location of the build tree as the first argument or by executing it in the build tree itself.
 
@@ -278,15 +280,27 @@ OpenGL does not depend on a separate shader compiler DLL.
 
 \section Using_ccache Using ccache
 
-ccache is a compiler cache software available on Linux and Mac OS X host systems. It speeds up the build by bypassing the actual compilation and reusing the result from previous compilation when the cache is hit. In order for this to work correctly when building/using Urho3D library with GCC/Clang precompiled header enabled, the following environment variable must be set:
+ccache is a compiler cache software available on Linux and Mac OS X host systems. It speeds up the build by bypassing the actual compilation and reusing the result from previous compilation when the cache is hit. As such, this is optional in the build process. In order to enable ccache support and make it work correctly when building/using Urho3D library with GCC/Clang precompiled header enabled, the following environment variables must be set:
 \verbatim
+USE_CCACHE=1
 CCACHE_SLOPPINESS=pch_defines,time_macros
 \endverbatim
 
-Failure to do so would cause the precompiled header cannot be used by ccache. When ccache is setup correctly and with more hits than misses then even clean build can be done as fast as incremental build.
+Failure to do so would cause the precompiled header cannot be used by ccache. When ccache is setup correctly and with more hits than misses then even clean build can be done as fast as incremental build. The ccache support is available for native compiler toolchains as well as all cross-compiler toolchains supported by Urho3D.
+
+> There are some caveats with ccache support on Emscripten compiler toolchain. At the moment to enable ccache support for Emscripten, you also need to set 'CCACHE_CPP2' environment variable to 1 (see Emscripten issue [#3365](https://github.com/kripken/emscripten/issues/3365) for more detail).
+
+You may also want to set 'CCACHE_COMPRESS' environment variable to 1 to enable the compression of the cached objects. It is a trade-off between cache size and build time.
+
+Ensure the ccache symlinks directory is being added as the first entry in the 'PATH' environment variable so the symlinks of the compiler toolchain is being found first by CMake rather than the actual compiler toolchain. This is especially important for native build. Usually the 'PATH' environment variable has been set correctly for ccache in RedHat-based host system such as Fedora, but it is not the case in Debian-based host system such as Ubuntu nor in Mac OS X host system with homebrew's ccache installation. For the latter case, use "whereis -b ccache" or "brew info ccache" to find out where your ccache symlinks directory is and adjust the 'PATH' environment variable accordingly.
+
+Note that these environment variables are used by ccache itself and not by our CMake build rules, so they must remain set in the host system not only while generating the initial project file using CMake but also while building the project later.
+
 
 \page Running Running Urho3D player application
 
+\tableofcontents
+
 The Urho3D player application in the bin directory contains all the engine runtime functionality. However, it does not contain any inbuilt logic, and therefore must be supplied with the name of the application script file it should run:
 
 \verbatim
@@ -421,6 +435,8 @@ F2          Toggle debug HUD
 
 \page UsingLibrary Using Urho3D as external library
 
+\tableofcontents
+
 This page shows how to create a new C++ project linking against Urho3D library as external library. There are two approaches to do this. The first approach uses Urho3D library directly from the Urho3D project build tree. The second approach uses Urho3D SDK installation. It is imperative to clean the CMake cache when changing from one approach to the other. You should also clean the cache when you change the path in the URHO3D_HOME environment variable.
 
 First of all, structure your project similar to Urho3D project as below. Although this is not mandatory, it should increase the chance the CMake modules designed for Urho3D project also works out of the box for your project too. CMake and our CMake modules are case-sensitive. It is recommended that your project adheres to the same naming convention as Urho3D project uses, even when the filesystem in your host system is not case-sensitive.
@@ -661,6 +677,8 @@ For more details related to the C++ coding style, see also \ref CodingConvention
 
 \page EditorInstructions Editor instructions
 
+\tableofcontents
+
 The Urho3D editor is a script application that can be run with the Urho3D player application. To start, execute any of these commands: (in the bin directory) Editor.bat, Editor.sh or Urho3DPlayer Scripts/Editor.as
 
 All the \ref Running_Commandline "command line options" supported by Urho3D player application are available for Editor as well. Additionally, Editor also supports the following command line options:

+ 3 - 2
Docs/Reference.dox

@@ -891,7 +891,7 @@ OpenGL ES 2.0 has further limitations:
 
 Material and Technique resources define how to render 3D scene geometry. On the disk, they are XML data. Default and example materials exist in the bin/CoreData/Materials & bin/Data/Materials subdirectories, and techniques exist in the bin/CoreData/Techniques subdirectory.
 
-A material defines the textures, shader parameters and culling mode to use, and refers to one or several techniques. A technique defines the actual rendering passes, the shaders to use in each, and all other rendering states such as depth test, depth write, and blending.
+A material defines the textures, shader parameters and culling & fill mode to use, and refers to one or several techniques. A technique defines the actual rendering passes, the shaders to use in each, and all other rendering states such as depth test, depth write, and blending.
 
 A material definition looks like this:
 
@@ -904,6 +904,7 @@ A material definition looks like this:
     <parameter ... />
     <cull value="cw|ccw|none" />
     <shadowcull value="cw|ccw|none" />
+    <fill value="solid|wireframe|point" />
     <depthbias constant="x" slopescaled="y" />
 </material>
 \endcode
@@ -2083,7 +2084,7 @@ The following queries into the physics world are provided:
 Contact listener (see Box2D manual, Chapter 9 Contacts) enables a given node to report contacts through events. Available events are:
 - E_PHYSICSBEGINCONTACT2D ("PhysicsBeginContact2D" in script): called when 2 collision shapes begin to overlap
 - E_PHYSICSENDCONTACT2D ("PhysicsEndContact2D" in script): called when 2 collision shapes cease to overlap
-- E_PHYSICSPRESTEP2D ("Physics2DPreStep2D" in script): called after collision detection, but before collision resolution. This allows to disable the contact if need be (for example on a one-sided platform). Currently ineffective (only reports PhysicsWorld2D and time step)
+- E_PHYSICSPRESTEP2D ("PhysicsPreStep2D" in script): called after collision detection, but before collision resolution. This allows to disable the contact if need be (for example on a one-sided platform). Currently ineffective (only reports PhysicsWorld2D and time step)
 - E_PHYSICSPOSTSTEP2D ("PhysicsPostStep2D" in script): used to gather collision impulse results. Currentlly ineffective (only reports PhysicsWorld2D and time step)
 
 \section Urho2D_TileMap Tile maps

+ 2 - 0
Docs/Urho3D.dox

@@ -99,9 +99,11 @@ Urho3D development, contributions and bugfixes by:
 - att
 - celeron55
 - hdunderscore
+- marynate
 - mightyCelu
 - nemerle
 - ninjastone
+- raould
 - rasteron
 - reattiva
 - rifai

+ 3 - 0
README.md

@@ -45,6 +45,7 @@ Urho3D development, contributions and bugfixes by:
 - Firegorilla
 - Magic.Lixin
 - Mike3D
+- Modanung
 - OvermindDL1
 - andmar1x
 - amadeus_osa
@@ -52,9 +53,11 @@ Urho3D development, contributions and bugfixes by:
 - att
 - celeron55
 - hdunderscore
+- marynate
 - mightyCelu
 - nemerle
 - ninjastone
+- raould
 - rasteron
 - reattiva
 - rifai

+ 25 - 14
Rakefile

@@ -85,7 +85,12 @@ task :cmake do
     end
   }
   build_tree = ENV["#{platform}_build_tree"] || ENV['build_tree'] || "../#{platform}-Build"
-  system "./#{script}#{ENV['OS'] ? '.bat' : '.sh'} \"#{build_tree}\" #{build_options}" or abort
+  unless ENV['OS']
+    ccache_envvar = ENV['CCACHE_SLOPPINESS'] ? '' : 'CCACHE_SLOPPINESS=pch_defines,time_macros'   # Only attempt to do the right thing when user hasn't done it
+    ccache_envvar = "#{ccache_envvar} CCACHE_COMPRESS=1" unless ENV['CCACHE_COMPRESS']
+    ccache_envvar = "#{ccache_envvar} CCACHE_CPP2=1" unless ENV['CCACHE_CPP2'] || platform != 'emscripten'  # TODO: Temporary workaround for ccache support on Emscripten
+  end
+  system "#{ccache_envvar} ./#{script}#{ENV['OS'] ? '.bat' : '.sh'} \"#{build_tree}\" #{build_options}" or abort
 end
 
 # Usage: rake make [<platform>] [<option>=<value> [<option>=<value>]] [[<platform>_]build_tree=/path/to/build-tree] [numjobs=n] [clean_first] [unfilter]
@@ -117,7 +122,11 @@ task :make do
     end
   }
   build_tree = ENV["#{platform}_build_tree"] || ENV['build_tree'] || "../#{platform}-Build"
-  ccache_envvar = ''
+  unless ENV['OS']
+    ccache_envvar = ENV['CCACHE_SLOPPINESS'] ? '' : 'CCACHE_SLOPPINESS=pch_defines,time_macros'   # Only attempt to do the right thing when user hasn't done it
+    ccache_envvar = "#{ccache_envvar} CCACHE_COMPRESS=1" unless ENV['CCACHE_COMPRESS']
+    ccache_envvar = "#{ccache_envvar} CCACHE_CPP2=1" unless ENV['CCACHE_CPP2'] || platform != 'emscripten'  # TODO: Temporary workaround for ccache support on Emscripten
+  end
   if !Dir.glob("#{build_tree}/*.xcodeproj").empty?
     # xcodebuild
     if !numjobs.empty?
@@ -129,20 +138,23 @@ task :make do
     numjobs = ":#{numjobs}" unless numjobs.empty?
     build_options = "/maxcpucount#{numjobs}#{build_options}"
     filter = unfilter ? '' : '/nologo /verbosity:minimal'
+  elsif !Dir.glob("#{build_tree}/*.ninja").empty?
+    # ninja
+    if !numjobs.empty?
+      build_options = "-j#{numjobs}#{build_options}"
+    end
+    filter = ''
   else
     # make
-    ccache_envvar = 'CCACHE_SLOPPINESS=pch_defines,time_macros' unless ENV['CCACHE_SLOPPINESS']   # Only attempt to do the right thing when user hasn't done it
-    ccache_envvar = "#{ccache_envvar} CCACHE_COMPRESS=1" unless ENV['CACHE_COMPRESS']
     if numjobs.empty?
       case RUBY_PLATFORM
       when /linux/
-        numjobs = `grep -c processor /proc/cpuinfo`.chomp
+        numjobs = (platform == 'emscripten' ? `grep 'core id' /proc/cpuinfo |sort |uniq |wc -l` : `grep -c processor /proc/cpuinfo`).chomp
       when /darwin/
-        numjobs = `sysctl -n hw.logicalcpu`.chomp
+        numjobs = `sysctl -n hw.#{platform == 'emscripten' ? 'physical' : 'logical'}cpu`.chomp
       when /win32|mingw|mswin/
         require 'win32ole'
-        WIN32OLE.connect('winmgmts://').ExecQuery('select NumberOfLogicalProcessors from Win32_ComputerSystem').each { |out| numjobs = out.NumberOfLogicalProcessors }
-        ccache_envvar = ''    # Extra env var is harmless even when ccache is not in use, well, except on Windows host system
+        WIN32OLE.connect('winmgmts://').ExecQuery("select NumberOf#{platform == 'emscripten' ? '' : 'Logical'}Processors from Win32_ComputerSystem").each { |out| numjobs = platform == 'emscripten' ? out.NumberOfProcessors : out.NumberOfLogicalProcessors }
       else
         numjobs = 1
       end
@@ -194,9 +206,7 @@ task :ci do
   $build_options = "-DWIN32=#{ENV['WINDOWS']}" if ENV['WINDOWS']
   $build_options = "#{$build_options} -DANDROID_ABI=#{ENV['ABI']}" if ENV['ABI']
   $build_options = "#{$build_options} -DANDROID_NATIVE_API_LEVEL=#{ENV['API']}" if ENV['API']
-  ['URHO3D_64BIT', 'URHO3D_OPENGL', 'URHO3D_D3D11', 'ANDROID', 'RPI', 'RPI_ABI', 'EMSCRIPTEN', 'EMSCRIPTEN_SHARE_DATA', 'EMSCRIPTEN_EMRUN_BROWSER'].each { |var|
-    $build_options = "#{$build_options} -D#{var}=#{ENV[var]}" if ENV[var]
-  }
+  ['URHO3D_64BIT', 'URHO3D_OPENGL', 'URHO3D_D3D11', 'URHO3D_TEST_TIMEOUT', 'ANDROID', 'RPI', 'RPI_ABI', 'EMSCRIPTEN', 'EMSCRIPTEN_SHARE_DATA', 'EMSCRIPTEN_EMRUN_BROWSER'].each { |var| $build_options = "#{$build_options} -D#{var}=#{ENV[var]}" if ENV[var] }
   if ENV['XCODE']
     # xcodebuild
     xcode_ci
@@ -262,7 +272,7 @@ task :ci_rebase do
   system 'git config user.name $GIT_NAME && git config user.email $GIT_EMAIL && git remote set-url --push origin https://[email protected]/$TRAVIS_REPO_SLUG.git'
   baseline = ENV['RELEASE_TAG'] || "origin/#{ENV['TRAVIS_BRANCH']}"
   enable = /\[ci rebase\]/ =~ ENV['COMMIT_MESSAGE']
-  [ 'Android-CI', 'RPI-CI', 'Emscripten-CI', 'OSX-CI' ].each { |ci| ci_branch = ENV['RELEASE_TAG'] || ENV['TRAVIS_BRANCH'] == 'master' ? ci : "#{ENV['TRAVIS_BRANCH']}-#{ci}"; system "if git fetch origin #{ci_branch}:#{ci_branch} 2>/dev/null; then git rebase #{baseline} #{ci_branch} && git push -qf -u origin #{ci_branch} >/dev/null 2>&1; elif [ #{enable} ]; then git checkout -b #{ci_branch} #{ENV['TRAVIS_BRANCH']} && rm .travis.yml && wget -q https://raw.githubusercontent.com/#{ENV['TRAVIS_REPO_SLUG']}/#{ci}/.travis.yml && cat <<EOF >README.md && git add -A . && git commit -m 'For Travis CI - switch CI build to use #{ci.split('-').first} build environment.' && git push -qf -u origin #{ci_branch} >/dev/null 2>&1; fi
+  ['Android-CI', 'RPI-CI', 'OSX-CI', 'Emscripten-CI'].each { |ci| ci_branch = ENV['RELEASE_TAG'] || ENV['TRAVIS_BRANCH'] == 'master' ? ci : "#{ENV['TRAVIS_BRANCH']}-#{ci}"; system "if git fetch origin #{ci_branch}:#{ci_branch} 2>/dev/null; then git rebase #{baseline} #{ci_branch} && git push -qf -u origin #{ci_branch} >/dev/null 2>&1; elif [ #{enable} ]; then git checkout -b #{ci_branch} #{ENV['TRAVIS_BRANCH']} && rm .travis.yml && wget -q https://raw.githubusercontent.com/#{ENV['TRAVIS_REPO_SLUG']}/#{ci}/.travis.yml && cat <<EOF >README.md && git add -A . && git commit -m 'For Travis CI - switch CI build to use #{ci.split('-').first} build environment.' && git push -qf -u origin #{ci_branch} >/dev/null 2>&1; fi
 This is a mirror branch which is constantly being \"rebased\" from #{ENV['TRAVIS_BRANCH']} branch. Please DO NOT checkout from this mirror branch! The purpose of this mirror branch is to perform CI build using #{ci.split('-').first} build environment on Travis-CI.org. See #{ENV['TRAVIS_BRANCH']} branch for CI build result using Ubuntu Linux build environment.
 
 [![Build Status](https://travis-ci.org/#{ENV['TRAVIS_REPO_SLUG']}.png?branch=#{ci_branch})](https://travis-ci.org/#{ENV['TRAVIS_REPO_SLUG']}?branch=#{ci_branch})
@@ -313,7 +323,8 @@ task :ci_package_upload do
     if ENV['URHO3D_USE_LIB64_RPM']
       system "cd ../Build && cmake . -DURHO3D_USE_LIB64_RPM=#{ENV['URHO3D_USE_LIB64_RPM']}" or abort 'Failed to reconfigure to generate 64-bit RPM package'
     end
-    system 'cd ../Build && make package' or abort 'Failed to make binary package'
+    wrapper = ENV['CI'] && ENV['URHO3D_64BIT'] ? 'setarch i686' : ''
+    system "cd ../Build && #{wrapper} make package" or abort 'Failed to make binary package'
   end
   # Determine the upload location
   setup_digital_keys
@@ -433,7 +444,7 @@ def makefile_ci
   end
   system "./cmake_generic.sh ../Build -DURHO3D_LIB_TYPE=$URHO3D_LIB_TYPE #{$build_options} -DURHO3D_LUA#{jit}=1 #{amalg} -DURHO3D_SAMPLES=1 -DURHO3D_TOOLS=1 -DURHO3D_EXTRAS=1 -DURHO3D_TESTING=#{$testing} -DCMAKE_BUILD_TYPE=#{$configuration}" or abort 'Failed to configure Urho3D library build'
   if ENV['AVD'] && !ENV['PACKAGE_UPLOAD']   # Skip APK test run when packaging
-      android_prepare_device ENV['API'], ENV['ABI'], ENV['AVD'] or abort 'Failed to prepare Android (virtual) device for test run'
+    android_prepare_device ENV['API'], ENV['ABI'], ENV['AVD'] or abort 'Failed to prepare Android (virtual) device for test run'
   end
   test = $testing == 1 ? '&& make test' : ''
   system "cd ../Build && make -j$NUMJOBS #{test}" or abort 'Failed to build or test Urho3D library'

+ 4 - 4
Source/CMakeLists.txt

@@ -74,14 +74,14 @@ if (URHO3D_NAVIGATION)
     add_subdirectory (ThirdParty/Recast)
 endif ()
 
-if (URHO3D_PHYSICS)
-    add_subdirectory (ThirdParty/Bullet)
-endif ()
-
 if (URHO3D_URHO2D)
     add_subdirectory (ThirdParty/Box2D)
 endif ()
 
+if (URHO3D_PHYSICS)
+    add_subdirectory (ThirdParty/Bullet)
+endif ()
+
 if (NOT IOS AND NOT ANDROID AND NOT RPI AND NOT EMSCRIPTEN)
     if (URHO3D_OPENGL)
         add_subdirectory (ThirdParty/GLEW)

+ 1 - 1
Source/Tools/AssetImporter/AssetImporter.cpp

@@ -426,7 +426,7 @@ void Run(const Vector<String>& arguments)
         PrintLine("Reading file " + inFile);
         scene_ = aiImportFile(GetNativePath(inFile).CString(), flags);
         if (!scene_)
-            ErrorExit("Could not open or parse input file " + inFile);
+            ErrorExit("Could not open or parse input file " + inFile + ": " + String(aiGetErrorString()));
         
         if (verboseLog_)
             Assimp::DefaultLogger::kill();

+ 20 - 0
Source/Urho3D/Container/Str.cpp

@@ -182,6 +182,16 @@ String& String::operator += (short rhs)
     return *this += String(rhs);
 }
 
+String& String::operator += (long rhs)
+{
+    return *this += String(rhs);
+}
+
+String& String::operator += (long long rhs)
+{
+    return *this += String(rhs);
+}
+
 String& String::operator += (unsigned rhs)
 {
     return *this += String(rhs);
@@ -192,6 +202,16 @@ String& String::operator += (unsigned short rhs)
     return *this += String(rhs);
 }
 
+String& String::operator += (unsigned long rhs)
+{
+    return *this += String(rhs);
+}
+
+String& String::operator += (unsigned long long rhs)
+{
+    return *this += String(rhs);
+}
+
 String& String::operator += (float rhs)
 {
     return *this += String(rhs);

+ 8 - 0
Source/Urho3D/Container/Str.h

@@ -206,10 +206,18 @@ public:
     String& operator += (int rhs);
     /// Add-assign a short integer.
     String& operator += (short rhs);
+    /// Add-assign a long integer.
+    String& operator += (long rhs);
+    /// Add-assign a long long integer.
+    String& operator += (long long rhs);
     /// Add-assign an unsigned integer.
     String& operator += (unsigned rhs);
     /// Add-assign a short unsigned integer.
     String& operator += (unsigned short rhs);
+    /// Add-assign a long unsigned integer.
+    String& operator += (unsigned long rhs);
+    /// Add-assign a long long unsigned integer.
+    String& operator += (unsigned long long rhs);
     /// Add-assign a float.
     String& operator += (float rhs);
     /// Add-assign a bool.

+ 14 - 6
Source/Urho3D/Core/ProcessUtils.cpp

@@ -162,12 +162,20 @@ void PrintUnicode(const String& str, bool error)
 {
     #if !defined(ANDROID) && !defined(IOS)
     #ifdef WIN32
-    HANDLE stream = GetStdHandle(error ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
-    if (stream == INVALID_HANDLE_VALUE)
-        return;
-    WString strW(str);
-    DWORD charsWritten;
-    WriteConsoleW(stream, strW.CString(), strW.Length(), &charsWritten, 0);
+    // If the output stream has been redirected, use fprintf instead of WriteConsoleW,
+    // though it means that proper Unicode output will not work
+    FILE* out = error ? stderr : stdout;
+    if (!_isatty(_fileno(out)))
+        fprintf(out, "%s", str.CString());
+    else
+    {
+        HANDLE stream = GetStdHandle(error ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
+        if (stream == INVALID_HANDLE_VALUE)
+            return;
+        WString strW(str);
+        DWORD charsWritten;
+        WriteConsoleW(stream, strW.CString(), strW.Length(), &charsWritten, 0);
+    }
     #else
     fprintf(error ? stderr : stdout, "%s", str.CString());
     #endif

+ 23 - 4
Source/Urho3D/Graphics/OpenGL/OGLTexture.cpp

@@ -36,7 +36,7 @@
 namespace Urho3D
 {
 
-GLenum glWrapModes[] =
+static GLenum glWrapModes[] =
 {
     GL_REPEAT,
     GL_MIRRORED_REPEAT,
@@ -48,6 +48,16 @@ GLenum glWrapModes[] =
     #endif
 };
 
+#ifndef GL_ES_VERSION_2_0
+static GLenum gl3WrapModes[] =
+{
+    GL_REPEAT,
+    GL_MIRRORED_REPEAT,
+    GL_CLAMP_TO_EDGE,
+    GL_CLAMP_TO_BORDER
+};
+#endif
+
 static const char* addressModeNames[] =
 {
     "wrap",
@@ -67,6 +77,15 @@ static const char* filterModeNames[] =
     0
 };
 
+static GLenum GetWrapMode(TextureAddressMode mode)
+{
+    #ifndef GL_ES_VERSION_2_0
+    return Graphics::GetGL3Support() ? gl3WrapModes[mode] : glWrapModes[mode];
+    #else
+    return glWrapModes[mode];
+    #endif
+}
+
 Texture::Texture(Context* context) :
     Resource(context),
     GPUObject(GetSubsystem<Graphics>()),
@@ -170,10 +189,10 @@ void Texture::UpdateParameters()
         return;
     
     // Wrapping
-    glTexParameteri(target_, GL_TEXTURE_WRAP_S, glWrapModes[addressMode_[COORD_U]]);
-    glTexParameteri(target_, GL_TEXTURE_WRAP_T, glWrapModes[addressMode_[COORD_V]]);
+    glTexParameteri(target_, GL_TEXTURE_WRAP_S, GetWrapMode(addressMode_[COORD_U]));
+    glTexParameteri(target_, GL_TEXTURE_WRAP_T, GetWrapMode(addressMode_[COORD_V]));
     #ifndef GL_ES_VERSION_2_0
-    glTexParameteri(target_, GL_TEXTURE_WRAP_R, glWrapModes[addressMode_[COORD_W]]);
+    glTexParameteri(target_, GL_TEXTURE_WRAP_R, GetWrapMode(addressMode_[COORD_W]));
     #endif
     
     TextureFilterMode filterMode = filterMode_;

+ 1 - 1
cmake_clean.bat

@@ -32,6 +32,6 @@ cmake -E touch "%BUILD%\CMakeCache.txt"
 
 goto :eof
 :error
-echo An error has occured, build tree has to be provided as the first argument OR call this script in a build tree itself
+echo Usage: %~nx0 \path\to\build-tree
 exit /B 1
 :eof

+ 1 - 1
cmake_clean.sh

@@ -22,7 +22,7 @@
 #
 
 # Clean the CMake cache and CMake generated files in the build tree
-if [ "$1" ] && [ -f "$1"/CMakeCache.txt ]; then BUILD=$1; elif [ -f $(pwd)/CMakeCache.txt ]; then BUILD=$(pwd); else echo An error has occured, build tree has to be provided as the first argument OR call this script in a build tree itself; exit 1; fi
+if [ "$1" ] && [ -f "$1"/CMakeCache.txt ]; then BUILD=$1; elif [ -f $(pwd)/CMakeCache.txt ]; then BUILD=$(pwd); else echo Usage: ${0##*/} /path/to/build-tree; exit 1; fi
 rm -rf "$BUILD"/{CMakeCache.txt,CMakeFiles}
 touch "$BUILD"/CMakeCache.txt
 

+ 1 - 1
cmake_generic.bat

@@ -59,6 +59,6 @@ cmake -E make_directory %BUILD% && cmake -E chdir %BUILD% cmake %OPTS% %* %SOURC
 
 goto :eof
 :error
-echo An error has occured, build tree has to be provided as the first argument OR call this script in a build tree itself
+echo Usage: %~nx0 \path\to\build-tree [build-options]
 exit /B 1
 :eof

+ 2 - 3
cmake_generic.sh

@@ -22,9 +22,8 @@
 #
 
 # Determine source tree and build tree
-if [ "$1" ] && [[ ! "$1" =~ ^- ]]; then BUILD=$1; shift; elif [ -f $(pwd)/CMakeCache.txt ]; then BUILD=$(pwd); else echo An error has occured, build tree has to be provided as the first argument OR call this script in a build tree itself; exit 1; fi
-SOURCE=$(dirname $0)
-if [ "$SOURCE" == "." ]; then SOURCE=$(pwd); fi
+if [ "$1" ] && [[ ! "$1" =~ ^- ]]; then BUILD=$1; shift; elif [ -f $(pwd)/CMakeCache.txt ]; then BUILD=$(pwd); else caller=$(ps -o args= $PPID |cut -d' ' -f2); if [[ ! "$caller" =~ cmake_.*\.sh$ ]]; then caller=$0; fi; echo "Usage: ${caller##*/} /path/to/build-tree [build-options]"; exit 1; fi
+SOURCE=$(cd ${0%/*}; pwd)
 if [ "$BUILD" == "." ]; then BUILD=$(pwd); fi
 
 # Define helpers

+ 1 - 1
cmake_ios.sh

@@ -21,6 +21,6 @@
 # THE SOFTWARE.
 #
 
-$(dirname $0)/cmake_macosx.sh $@ -DIOS=1
+$(dirname $0)/cmake_generic.sh $@ -G Xcode -DIOS=1
 
 # vi: set ts=4 sw=4 expandtab: