Merge branch 'master' of https://github.com/highfidelity/hifi into hdr

This commit is contained in:
samcake 2016-09-01 15:20:34 -07:00
commit 0c0109e427
37 changed files with 664 additions and 916 deletions

View file

@ -4,13 +4,11 @@ Please read the [general build guide](BUILD.md) for information on dependencies
You will need the following tools to build our Android targets. You will need the following tools to build our Android targets.
* [cmake](http://www.cmake.org/download/) ~> 3.1.0 * [cmake](http://www.cmake.org/download/) ~> 3.5.1
* Note that this is a newer version required than the minimum for hifi desktop targets. * [Qt](http://www.qt.io/download-open-source/#) ~> 5.5.1
* [Qt](http://www.qt.io/download-open-source/#) ~> 5.4.0
* Note that this is a newer version required than the minimum for hifi desktop targets.
* [ant](http://ant.apache.org/bindownload.cgi) ~> 1.9.4 * [ant](http://ant.apache.org/bindownload.cgi) ~> 1.9.4
* [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html) = r10c * [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html) ~> r10d
* [Android SDK](http://developer.android.com/sdk/installing/index.html) ~> 24.0.2 * [Android SDK](http://developer.android.com/sdk/installing/index.html) ~> 24.4.1.1
* Install the latest Platform-tools * Install the latest Platform-tools
* Install the latest Build-tools * Install the latest Build-tools
* Install the SDK Platform for API Level 19 * Install the SDK Platform for API Level 19
@ -19,6 +17,12 @@ You will need the following tools to build our Android targets.
You will also need to cross-compile the dependencies required for all platforms for Android, and help CMake find these compiled libraries on your machine. You will also need to cross-compile the dependencies required for all platforms for Android, and help CMake find these compiled libraries on your machine.
####Scribe
High Fidelity has a shader pre-processing tool called `scribe` that various libraries will call on during the build process. You must compile scribe using your native toolchain (following the build instructions for your platform) and then pass a CMake variable or set an ENV variable `SCRIBE_PATH` that is a path to the scribe executable.
CMake will fatally error if it does not find the scribe executable while using the android toolchain.
####Optional Components ####Optional Components
* [Oculus Mobile SDK](https://developer.oculus.com/downloads/#sdk=mobile) ~> 0.4.2 * [Oculus Mobile SDK](https://developer.oculus.com/downloads/#sdk=mobile) ~> 0.4.2
@ -31,11 +35,11 @@ This is most easily accomplished by installing all Android dependencies in the s
####Qt ####Qt
Install Qt 5.4 for Android for your host environment from the [Qt downloads page](http://www.qt.io/download/). Install Qt to ``$ANDROID_LIB_DIR/Qt``. This is required so that our root CMakeLists file can help CMake find your Android Qt installation. Install Qt 5.5.1 for Android for your host environment from the [Qt downloads page](http://www.qt.io/download/). Install Qt to ``$ANDROID_LIB_DIR/Qt``. This is required so that our root CMakeLists file can help CMake find your Android Qt installation.
The component required for the Android build is the `Android armv7` component. The component required for the Android build is the `Android armv7` component.
If you would like to install Qt to a different location, or attempt to build with a different Qt version, you can pass `ANDROID_QT_CMAKE_PREFIX_PATH` to CMake. Point to the `cmake` folder inside `$VERSION_NUMBER/android_armv7/lib`. Otherwise, our root CMakeLists will set it to `$ANDROID_LIB_DIR/Qt/5.3/android_armv7/lib/cmake`. If you would like to install Qt to a different location, or attempt to build with a different Qt version, you can pass `ANDROID_QT_CMAKE_PREFIX_PATH` to CMake. Point to the `cmake` folder inside `$VERSION_NUMBER/android_armv7/lib`. Otherwise, our root CMakeLists will set it to `$ANDROID_LIB_DIR/Qt/5.5/android_armv7/lib/cmake`.
####OpenSSL ####OpenSSL

View file

@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.2)
if (USE_ANDROID_TOOLCHAIN) if (USE_ANDROID_TOOLCHAIN)
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/android/android.toolchain.cmake") set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/android/android.toolchain.cmake")
set(ANDROID_NATIVE_API_LEVEL 19) set(ANDROID_NATIVE_API_LEVEL 19)
set(ANDROID_TOOLCHAIN_NAME arm-linux-androideabi-clang3.5)
set(ANDROID_STL c++_shared)
endif () endif ()
if (WIN32) if (WIN32)
@ -64,7 +66,7 @@ if (WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG /OPT:REF /OPT:ICF") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG /OPT:REF /OPT:ICF")
else () else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-strict-aliasing -Wno-unused-parameter") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fno-strict-aliasing -Wno-unused-parameter")
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -Woverloaded-virtual -Wdouble-promotion") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ggdb -Woverloaded-virtual -Wdouble-promotion")
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.1") # gcc 5.1 and on have suggest-override if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.1") # gcc 5.1 and on have suggest-override
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override")
@ -72,18 +74,23 @@ else ()
endif () endif ()
endif(WIN32) endif(WIN32)
if ((NOT MSVC12) AND (NOT MSVC14)) if (NOT ANDROID)
include(CheckCXXCompilerFlag) if ((NOT MSVC12) AND (NOT MSVC14))
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if (COMPILER_SUPPORTS_CXX11) if (COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X) elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else() else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif() endif()
endif ()
else ()
# assume that the toolchain selected for android has C++11 support
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif () endif ()
if (APPLE) if (APPLE)
@ -98,7 +105,7 @@ endif ()
if (ANDROID) if (ANDROID)
if (NOT ANDROID_QT_CMAKE_PREFIX_PATH) if (NOT ANDROID_QT_CMAKE_PREFIX_PATH)
set(QT_CMAKE_PREFIX_PATH ${ANDROID_LIB_DIR}/Qt/5.4/android_armv7/lib/cmake) set(QT_CMAKE_PREFIX_PATH ${ANDROID_LIB_DIR}/Qt/5.5/android_armv7/lib/cmake)
else () else ()
set(QT_CMAKE_PREFIX_PATH ${ANDROID_QT_CMAKE_PREFIX_PATH}) set(QT_CMAKE_PREFIX_PATH ${ANDROID_QT_CMAKE_PREFIX_PATH})
endif () endif ()
@ -236,7 +243,9 @@ if (NOT ANDROID)
endif() endif()
if (ANDROID OR DESKTOP_GVR) if (ANDROID OR DESKTOP_GVR)
add_subdirectory(interface)
add_subdirectory(gvr-interface) add_subdirectory(gvr-interface)
add_subdirectory(plugins)
endif () endif ()
if (DEFINED ENV{HIFI_MEMORY_DEBUGGING}) if (DEFINED ENV{HIFI_MEMORY_DEBUGGING})

View file

@ -29,8 +29,8 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Android CMake toolchain file, for use with the Android NDK r5-r10c # Android CMake toolchain file, for use with the Android NDK r5-r10d
# Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended). # Requires cmake 2.6.3 or newer (2.8.9 or newer is recommended).
# See home page: https://github.com/taka-no-me/android-cmake # See home page: https://github.com/taka-no-me/android-cmake
# #
# Usage Linux: # Usage Linux:
@ -39,12 +39,6 @@
# $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake .. # $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake ..
# $ make -j8 # $ make -j8
# #
# Usage Linux (using standalone toolchain):
# $ export ANDROID_STANDALONE_TOOLCHAIN=/absolute/path/to/android-toolchain
# $ mkdir build && cd build
# $ cmake -DCMAKE_TOOLCHAIN_FILE=path/to/the/android.toolchain.cmake ..
# $ make -j8
#
# Usage Windows: # Usage Windows:
# You need native port of make to build your project. # You need native port of make to build your project.
# Android NDK r7 (and newer) already has make.exe on board. # Android NDK r7 (and newer) already has make.exe on board.
@ -63,11 +57,6 @@
# ANDROID_NDK=/opt/android-ndk - path to the NDK root. # ANDROID_NDK=/opt/android-ndk - path to the NDK root.
# Can be set as environment variable. Can be set only at first cmake run. # Can be set as environment variable. Can be set only at first cmake run.
# #
# ANDROID_STANDALONE_TOOLCHAIN=/opt/android-toolchain - path to the
# standalone toolchain. This option is not used if full NDK is found
# (ignored if ANDROID_NDK is set).
# Can be set as environment variable. Can be set only at first cmake run.
#
# ANDROID_ABI=armeabi-v7a - specifies the target Application Binary # ANDROID_ABI=armeabi-v7a - specifies the target Application Binary
# Interface (ABI). This option nearly matches to the APP_ABI variable # Interface (ABI). This option nearly matches to the APP_ABI variable
# used by ndk-build tool from Android NDK. # used by ndk-build tool from Android NDK.
@ -123,8 +112,8 @@
# * x86_64-clang3.5 # * x86_64-clang3.5
# #
# ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions # ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions
# instead of Thumb. Is not available for "x86" (inapplicable) and # instead of Thumb. Is not available for "armeabi-v6 with VFP"
# "armeabi-v6 with VFP" (is forced to be ON) ABIs. # (is forced to be ON) ABI.
# #
# ANDROID_NO_UNDEFINED=ON - set ON to show all undefined symbols as linker # ANDROID_NO_UNDEFINED=ON - set ON to show all undefined symbols as linker
# errors even if they are not used. # errors even if they are not used.
@ -133,13 +122,6 @@
# libraries. Automatically turned for NDK r5x and r6x due to GLESv2 # libraries. Automatically turned for NDK r5x and r6x due to GLESv2
# problems. # problems.
# #
# LIBRARY_OUTPUT_PATH_ROOT=${CMAKE_SOURCE_DIR} - where to output binary
# files. See additional details below.
#
# ANDROID_SET_OBSOLETE_VARIABLES=ON - if set, then toolchain defines some
# obsolete variables which were used by previous versions of this file for
# backward compatibility.
#
# ANDROID_STL=gnustl_static - specify the runtime to use. # ANDROID_STL=gnustl_static - specify the runtime to use.
# #
# Possible values are: # Possible values are:
@ -172,6 +154,8 @@
# Implies -frtti -fno-exceptions. # Implies -frtti -fno-exceptions.
# Available for NDK r7b and newer. # Available for NDK r7b and newer.
# Silently degrades to gnustl_static if not available. # Silently degrades to gnustl_static if not available.
# c++_static -> Use the LLVM libc++ runtime as a static library.
# c++_shared -> Use the LLVM libc++ runtime as a shared library.
# #
# ANDROID_STL_FORCE_FEATURES=ON - turn rtti and exceptions support based on # ANDROID_STL_FORCE_FEATURES=ON - turn rtti and exceptions support based on
# chosen runtime. If disabled, then the user is responsible for settings # chosen runtime. If disabled, then the user is responsible for settings
@ -200,12 +184,6 @@
# will be set true, mutually exclusive. NEON option will be set true # will be set true, mutually exclusive. NEON option will be set true
# if VFP is set to NEON. # if VFP is set to NEON.
# #
# LIBRARY_OUTPUT_PATH_ROOT should be set in cache to determine where Android
# libraries will be installed.
# Default is ${CMAKE_SOURCE_DIR}, and the android libs will always be
# under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}
# (depending on the target ABI). This is convenient for Android packaging.
#
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
cmake_minimum_required( VERSION 2.6.3 ) cmake_minimum_required( VERSION 2.6.3 )
@ -235,22 +213,22 @@ endif()
# this one not so much # this one not so much
set( CMAKE_SYSTEM_VERSION 1 ) set( CMAKE_SYSTEM_VERSION 1 )
# rpath makes low sence for Android # rpath makes low sense for Android
set( CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "" ) set( CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "" )
set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." ) set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." )
# NDK search paths # NDK search paths
set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r10c -r10b -r10 -r9d -r9c -r9b -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r10d -r10c -r10b -r10 -r9d -r9c -r9b -r9 -r8e -r8d -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS) if( NOT DEFINED ANDROID_NDK_SEARCH_PATHS )
if( CMAKE_HOST_WIN32 ) if( CMAKE_HOST_WIN32 )
file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS ) file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}/android-ndk" "$ENV{SystemDrive}/NVPACK/android-ndk" ) set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}" "$ENV{SystemDrive}/NVPACK" )
else() else()
file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS ) file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS )
set( ANDROID_NDK_SEARCH_PATHS /opt/android-ndk "${ANDROID_NDK_SEARCH_PATHS}/NVPACK/android-ndk" ) set( ANDROID_NDK_SEARCH_PATHS /opt "${ANDROID_NDK_SEARCH_PATHS}/NVPACK" )
endif() endif()
endif() endif()
if(NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH) if( NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH )
set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain ) set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain )
endif() endif()
@ -272,106 +250,90 @@ set( ANDROID_DEFAULT_NDK_API_LEVEL_mips64 21 )
macro( __LIST_FILTER listvar regex ) macro( __LIST_FILTER listvar regex )
if( ${listvar} ) if( ${listvar} )
foreach( __val ${${listvar}} ) foreach( __val ${${listvar}} )
if( __val MATCHES "${regex}" ) if( __val MATCHES "${regex}" )
list( REMOVE_ITEM ${listvar} "${__val}" ) list( REMOVE_ITEM ${listvar} "${__val}" )
endif() endif()
endforeach() endforeach()
endif() endif()
endmacro() endmacro()
macro( __INIT_VARIABLE var_name ) macro( __INIT_VARIABLE var_name )
set( __test_path 0 ) set( __test_path 0 )
foreach( __var ${ARGN} )
if( __var STREQUAL "PATH" )
set( __test_path 1 )
break()
endif()
endforeach()
if( __test_path AND NOT EXISTS "${${var_name}}" )
unset( ${var_name} CACHE )
endif()
if( "${${var_name}}" STREQUAL "" )
set( __values 0 )
foreach( __var ${ARGN} ) foreach( __var ${ARGN} )
if( __var STREQUAL "VALUES" ) if( __var STREQUAL "PATH" )
set( __values 1 ) set( __test_path 1 )
elseif( NOT __var STREQUAL "PATH" )
set( __obsolete 0 )
if( __var MATCHES "^OBSOLETE_.*$" )
string( REPLACE "OBSOLETE_" "" __var "${__var}" )
set( __obsolete 1 )
endif()
if( __var MATCHES "^ENV_.*$" )
string( REPLACE "ENV_" "" __var "${__var}" )
set( __value "$ENV{${__var}}" )
elseif( DEFINED ${__var} )
set( __value "${${__var}}" )
else()
if( __values )
set( __value "${__var}" )
else()
set( __value "" )
endif()
endif()
if( NOT "${__value}" STREQUAL "" )
if( __test_path )
if( EXISTS "${__value}" )
file( TO_CMAKE_PATH "${__value}" ${var_name} )
if( __obsolete AND NOT _CMAKE_IN_TRY_COMPILE )
message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." )
endif()
break()
endif()
else()
set( ${var_name} "${__value}" )
if( __obsolete AND NOT _CMAKE_IN_TRY_COMPILE )
message( WARNING "Using value of obsolete variable ${__var} as initial value for ${var_name}. Please note, that ${__var} can be completely removed in future versions of the toolchain." )
endif()
break() break()
endif()
endif() endif()
endif()
endforeach() endforeach()
unset( __value )
unset( __values ) if( __test_path AND NOT EXISTS "${${var_name}}" )
unset( __obsolete ) unset( ${var_name} CACHE )
elseif( __test_path ) endif()
file( TO_CMAKE_PATH "${${var_name}}" ${var_name} )
endif() if( " ${${var_name}}" STREQUAL " " )
unset( __test_path ) set( __values 0 )
foreach( __var ${ARGN} )
if( __var STREQUAL "VALUES" )
set( __values 1 )
elseif( NOT __var STREQUAL "PATH" )
if( __var MATCHES "^ENV_.*$" )
string( REPLACE "ENV_" "" __var "${__var}" )
set( __value "$ENV{${__var}}" )
elseif( DEFINED ${__var} )
set( __value "${${__var}}" )
elseif( __values )
set( __value "${__var}" )
else()
set( __value "" )
endif()
if( NOT " ${__value}" STREQUAL " " AND (NOT __test_path OR EXISTS "${__value}") )
set( ${var_name} "${__value}" )
break()
endif()
endif()
endforeach()
unset( __value )
unset( __values )
endif()
if( __test_path )
file( TO_CMAKE_PATH "${${var_name}}" ${var_name} )
endif()
unset( __test_path )
endmacro() endmacro()
macro( __DETECT_NATIVE_API_LEVEL _var _path ) macro( __DETECT_NATIVE_API_LEVEL _var _path )
SET( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*.*$" ) set( __ndkApiLevelRegex "^[\t ]*#define[\t ]+__ANDROID_API__[\t ]+([0-9]+)[\t ]*.*$" )
FILE( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" ) file( STRINGS ${_path} __apiFileContent REGEX "${__ndkApiLevelRegex}" )
if( NOT __apiFileContent ) if( NOT __apiFileContent )
message( SEND_ERROR "Could not get Android native API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken." ) message( SEND_ERROR "Could not get Android native API level. Probably you have specified invalid level value, or your copy of NDK/toolchain is broken." )
endif() endif()
string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" ) string( REGEX REPLACE "${__ndkApiLevelRegex}" "\\1" ${_var} "${__apiFileContent}" )
unset( __apiFileContent ) unset( __apiFileContent )
unset( __ndkApiLevelRegex ) unset( __ndkApiLevelRegex )
endmacro() endmacro()
macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root ) macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root )
if( EXISTS "${_root}" ) if( EXISTS "${_root}" )
file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" ) file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" )
__LIST_FILTER( __gccExePath "^[.].*" ) __LIST_FILTER( __gccExePath "^[.].*" )
list( LENGTH __gccExePath __gccExePathsCount ) list( LENGTH __gccExePath __gccExePathsCount )
if( NOT __gccExePathsCount EQUAL 1 AND NOT _CMAKE_IN_TRY_COMPILE ) if( NOT __gccExePathsCount EQUAL 1 AND NOT _CMAKE_IN_TRY_COMPILE )
message( WARNING "Could not determine machine name for compiler from ${_root}" ) message( WARNING "Could not determine machine name for compiler from ${_root}" )
set( ${_var} "" ) set( ${_var} "" )
else()
get_filename_component( __gccExeName "${__gccExePath}" NAME_WE )
string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" )
endif()
unset( __gccExePath )
unset( __gccExePathsCount )
unset( __gccExeName )
else() else()
get_filename_component( __gccExeName "${__gccExePath}" NAME_WE ) set( ${_var} "" )
string( REPLACE "-gcc" "" ${_var} "${__gccExeName}" )
endif() endif()
unset( __gccExePath )
unset( __gccExePathsCount )
unset( __gccExeName )
else()
set( ${_var} "" )
endif()
endmacro() endmacro()
@ -419,17 +381,19 @@ if( NOT ANDROID_NDK_HOST_X64 )
endif() endif()
# see if we have path to Android NDK # see if we have path to Android NDK
__INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK ) if( NOT ANDROID_NDK AND NOT ANDROID_STANDALONE_TOOLCHAIN )
__INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK )
endif()
if( NOT ANDROID_NDK ) if( NOT ANDROID_NDK )
# see if we have path to Android standalone toolchain # see if we have path to Android standalone toolchain
__INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN OBSOLETE_ANDROID_NDK_TOOLCHAIN_ROOT OBSOLETE_ENV_ANDROID_NDK_TOOLCHAIN_ROOT ) __INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN )
if( NOT ANDROID_STANDALONE_TOOLCHAIN ) if( NOT ANDROID_STANDALONE_TOOLCHAIN )
#try to find Android NDK in one of the the default locations #try to find Android NDK in one of the the default locations
set( __ndkSearchPaths ) set( __ndkSearchPaths )
foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} ) foreach( __ndkSearchPath ${ANDROID_NDK_SEARCH_PATHS} )
foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} ) foreach( suffix ${ANDROID_SUPPORTED_NDK_VERSIONS} )
list( APPEND __ndkSearchPaths "${__ndkSearchPath}${suffix}" ) list( APPEND __ndkSearchPaths "${__ndkSearchPath}/android-ndk${suffix}" )
endforeach() endforeach()
endforeach() endforeach()
__INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} ) __INIT_VARIABLE( ANDROID_NDK PATH VALUES ${__ndkSearchPaths} )
@ -487,7 +451,7 @@ else()
or or
export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain export ANDROID_STANDALONE_TOOLCHAIN=~/my-android-toolchain
or put the toolchain or NDK in the default path: or put the toolchain or NDK in the default path:
sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH} sudo ln -s ~/my-android-ndk ${ANDROID_NDK_SEARCH_PATH}/android-ndk
sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" ) sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" )
endif() endif()
@ -636,7 +600,7 @@ if( BUILD_WITH_ANDROID_NDK )
endif() endif()
if( NOT __availableToolchains ) if( NOT __availableToolchains )
file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" ) file( GLOB __availableToolchainsLst RELATIVE "${ANDROID_NDK_TOOLCHAINS_PATH}" "${ANDROID_NDK_TOOLCHAINS_PATH}/*" )
if( __availableToolchains ) if( __availableToolchainsLst )
list(SORT __availableToolchainsLst) # we need clang to go after gcc list(SORT __availableToolchainsLst) # we need clang to go after gcc
endif() endif()
__LIST_FILTER( __availableToolchainsLst "^[.]" ) __LIST_FILTER( __availableToolchainsLst "^[.]" )
@ -669,7 +633,7 @@ if( NOT ANDROID_SUPPORTED_ABIS )
endif() endif()
# choose target ABI # choose target ABI
__INIT_VARIABLE( ANDROID_ABI OBSOLETE_ARM_TARGET OBSOLETE_ARM_TARGETS VALUES ${ANDROID_SUPPORTED_ABIS} ) __INIT_VARIABLE( ANDROID_ABI VALUES ${ANDROID_SUPPORTED_ABIS} )
# verify that target ABI is supported # verify that target ABI is supported
list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx ) list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx )
if( __androidAbiIdx EQUAL -1 ) if( __androidAbiIdx EQUAL -1 )
@ -760,7 +724,7 @@ if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMa
endif() endif()
if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 ) if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 )
__INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD OBSOLETE_FORCE_ARM VALUES OFF ) __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD VALUES OFF )
set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE ) set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE )
mark_as_advanced( ANDROID_FORCE_ARM_BUILD ) mark_as_advanced( ANDROID_FORCE_ARM_BUILD )
else() else()
@ -845,6 +809,7 @@ else()
unset( __realApiLevel ) unset( __realApiLevel )
endif() endif()
set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE ) set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE )
set( CMAKE_ANDROID_API ${ANDROID_NATIVE_API_LEVEL} )
if( CMAKE_VERSION VERSION_GREATER "2.8" ) if( CMAKE_VERSION VERSION_GREATER "2.8" )
list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS ) list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS )
set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
@ -863,23 +828,14 @@ endif()
# runtime choice (STL, rtti, exceptions) # runtime choice (STL, rtti, exceptions)
if( NOT ANDROID_STL ) if( NOT ANDROID_STL )
# honor legacy ANDROID_USE_STLPORT
if( DEFINED ANDROID_USE_STLPORT )
if( ANDROID_USE_STLPORT )
set( ANDROID_STL stlport_static )
endif()
message( WARNING "You are using an obsolete variable ANDROID_USE_STLPORT to select the STL variant. Use -DANDROID_STL=stlport_static instead." )
endif()
if( NOT ANDROID_STL )
set( ANDROID_STL gnustl_static ) set( ANDROID_STL gnustl_static )
endif()
endif() endif()
set( ANDROID_STL "${ANDROID_STL}" CACHE STRING "C++ runtime" ) set( ANDROID_STL "${ANDROID_STL}" CACHE STRING "C++ runtime" )
set( ANDROID_STL_FORCE_FEATURES ON CACHE BOOL "automatically configure rtti and exceptions support based on C++ runtime" ) set( ANDROID_STL_FORCE_FEATURES ON CACHE BOOL "automatically configure rtti and exceptions support based on C++ runtime" )
mark_as_advanced( ANDROID_STL ANDROID_STL_FORCE_FEATURES ) mark_as_advanced( ANDROID_STL ANDROID_STL_FORCE_FEATURES )
if( BUILD_WITH_ANDROID_NDK ) if( BUILD_WITH_ANDROID_NDK )
if( NOT "${ANDROID_STL}" MATCHES "^(none|system|system_re|gabi\\+\\+_static|gabi\\+\\+_shared|stlport_static|stlport_shared|gnustl_static|gnustl_shared)$") if( NOT "${ANDROID_STL}" MATCHES "^(none|system|system_re|gabi\\+\\+_static|gabi\\+\\+_shared|stlport_static|stlport_shared|gnustl_static|gnustl_shared|c\\+\\+_static|c\\+\\+_shared)$")
message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\". message( FATAL_ERROR "ANDROID_STL is set to invalid value \"${ANDROID_STL}\".
The possible values are: The possible values are:
none -> Do not configure the runtime. none -> Do not configure the runtime.
@ -891,6 +847,8 @@ The possible values are:
stlport_shared -> Use the STLport runtime as a shared library. stlport_shared -> Use the STLport runtime as a shared library.
gnustl_static -> (default) Use the GNU STL as a static library. gnustl_static -> (default) Use the GNU STL as a static library.
gnustl_shared -> Use the GNU STL as a shared library. gnustl_shared -> Use the GNU STL as a shared library.
c++_static -> Use the LLVM libc++ runtime as a static library.
c++_shared -> Use the LLVM libc++ runtime as a shared library.
" ) " )
endif() endif()
elseif( BUILD_WITH_STANDALONE_TOOLCHAIN ) elseif( BUILD_WITH_STANDALONE_TOOLCHAIN )
@ -1033,7 +991,7 @@ if( BUILD_WITH_ANDROID_NDK )
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" ) set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_NDK}/sources/cxx-stl/system/include" )
elseif( ANDROID_STL MATCHES "gabi" ) elseif( ANDROID_STL MATCHES "gabi" )
if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7 if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
message( FATAL_ERROR "gabi++ is not awailable in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.") message( FATAL_ERROR "gabi++ is not available in your NDK. You have to upgrade to NDK r7 or newer to use gabi++.")
endif() endif()
set( ANDROID_RTTI ON ) set( ANDROID_RTTI ON )
set( ANDROID_EXCEPTIONS OFF ) set( ANDROID_EXCEPTIONS OFF )
@ -1066,12 +1024,40 @@ if( BUILD_WITH_ANDROID_NDK )
else() else()
set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" ) set( __libstl "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++" )
endif() endif()
set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" ) set( ANDROID_STL_INCLUDE_DIRS "${__libstl}/include" "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/include" "${__libstl}/include/backward" )
if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" ) if( EXISTS "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" ) set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libgnustl_static.a" )
else() else()
set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" ) set( __libstl "${__libstl}/libs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
endif() endif()
elseif( ANDROID_STL MATCHES "c\\+\\+_shared" OR ANDROID_STL MATCHES "c\\+\\+_static" )
set( ANDROID_EXCEPTIONS ON )
set( ANDROID_RTTI ON )
set( ANDROID_CXX_ROOT "${ANDROID_NDK}/sources/cxx-stl/" )
set( ANDROID_LLVM_ROOT "${ANDROID_CXX_ROOT}/llvm-libc++" )
if( X86 )
set( ANDROID_ABI_INCLUDE_DIRS "${ANDROID_CXX_ROOT}/gabi++/include" )
else()
set( ANDROID_ABI_INCLUDE_DIRS "${ANDROID_CXX_ROOT}/llvm-libc++abi/include" )
endif()
set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_LLVM_ROOT}/libcxx/include" "${ANDROID_ABI_INCLUDE_DIRS}" )
# android support sfiles
include_directories ( SYSTEM ${ANDROID_NDK}/sources/android/support/include )
if(ANDROID_STL MATCHES "c\\+\\+_shared")
set ( LLVM_LIBRARY_NAME "libc++_shared.so")
else()
set ( LLVM_LIBRARY_NAME "libc++_static.a" )
endif ()
if( EXISTS "${ANDROID_LLVM_ROOT}/libs/${ANDROID_NDK_ABI_NAME}/${LLVM_LIBRARY_NAME}" )
set( __libstl "${ANDROID_LLVM_ROOT}/libs/${ANDROID_NDK_ABI_NAME}/${LLVM_LIBRARY_NAME}" )
else()
message( FATAL_ERROR "Could not find libc++ library" )
endif()
else() else()
message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" ) message( FATAL_ERROR "Unknown runtime: ${ANDROID_STL}" )
endif() endif()
@ -1144,7 +1130,12 @@ if( NOT CMAKE_C_COMPILER )
endif() endif()
set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "assembler" ) set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "assembler" )
set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" ) set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" )
set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" ) if( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}" )
# Use gcc-ar if we have it for better LTO support.
set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" )
else()
set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" )
endif()
set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" ) set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" )
set( CMAKE_NM "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" ) set( CMAKE_NM "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" )
set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" ) set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" )
@ -1168,7 +1159,7 @@ endif()
include( CMakeForceCompiler ) include( CMakeForceCompiler )
CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU ) CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU )
if( ANDROID_COMPILER_IS_CLANG ) if( ANDROID_COMPILER_IS_CLANG )
set( CMAKE_C_COMPILER_ID Clang) set( CMAKE_C_COMPILER_ID Clang )
endif() endif()
set( CMAKE_C_PLATFORM_ID Linux ) set( CMAKE_C_PLATFORM_ID Linux )
if( X86_64 OR MIPS64 OR ARM64_V8A ) if( X86_64 OR MIPS64 OR ARM64_V8A )
@ -1195,6 +1186,14 @@ set( CMAKE_ASM_COMPILER_FORCED TRUE )
set( CMAKE_COMPILER_IS_GNUASM 1) set( CMAKE_COMPILER_IS_GNUASM 1)
set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm ) set( CMAKE_ASM_SOURCE_FILE_EXTENSIONS s S asm )
foreach( lang C CXX ASM )
if( ANDROID_COMPILER_IS_CLANG )
set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_CLANG_VERSION} )
else()
set( CMAKE_${lang}_COMPILER_VERSION ${ANDROID_COMPILER_VERSION} )
endif()
endforeach()
# flags and definitions # flags and definitions
remove_definitions( -DANDROID ) remove_definitions( -DANDROID )
add_definitions( -DANDROID ) add_definitions( -DANDROID )
@ -1225,14 +1224,14 @@ endif()
# NDK flags # NDK flags
if (ARM64_V8A ) if (ARM64_V8A )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -ffunction-sections -funwind-tables" ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" ) set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" ) set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" )
if( NOT ANDROID_COMPILER_IS_CLANG ) if( NOT ANDROID_COMPILER_IS_CLANG )
set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" ) set( ANDROID_CXX_FLAGS_RELEASE "${ANDROID_CXX_FLAGS_RELEASE} -funswitch-loops -finline-limit=300" )
endif() endif()
elseif( ARMEABI OR ARMEABI_V7A) elseif( ARMEABI OR ARMEABI_V7A)
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -funwind-tables" ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 ) if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 )
set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" ) set( ANDROID_CXX_FLAGS_RELEASE "-mthumb -fomit-frame-pointer -fno-strict-aliasing" )
set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" ) set( ANDROID_CXX_FLAGS_DEBUG "-marm -fno-omit-frame-pointer -fno-strict-aliasing" )
@ -1251,13 +1250,11 @@ elseif( X86 OR X86_64 )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funwind-tables" )
if( NOT ANDROID_COMPILER_IS_CLANG ) if( NOT ANDROID_COMPILER_IS_CLANG )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
else()
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fPIC" )
endif() endif()
set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" ) set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer -fstrict-aliasing" )
set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" ) set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer -fno-strict-aliasing" )
elseif( MIPS OR MIPS64 ) elseif( MIPS OR MIPS64 )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fpic -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0" ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fno-strict-aliasing -finline-functions -funwind-tables -fmessage-length=0" )
set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" ) set( ANDROID_CXX_FLAGS_RELEASE "-fomit-frame-pointer" )
set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer" ) set( ANDROID_CXX_FLAGS_DEBUG "-fno-omit-frame-pointer" )
if( NOT ANDROID_COMPILER_IS_CLANG ) if( NOT ANDROID_COMPILER_IS_CLANG )
@ -1342,7 +1339,7 @@ if( ANDROID_NDK_RELEASE_NUM LESS 7000 ) # before r7
else() else()
__INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES OFF ) __INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES OFF )
endif() endif()
__INIT_VARIABLE( ANDROID_NO_UNDEFINED OBSOLETE_NO_UNDEFINED VALUES ON ) __INIT_VARIABLE( ANDROID_NO_UNDEFINED VALUES ON )
__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING VALUES ON ) __INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING VALUES ON )
__INIT_VARIABLE( ANDROID_GOLD_LINKER VALUES ON ) __INIT_VARIABLE( ANDROID_GOLD_LINKER VALUES ON )
__INIT_VARIABLE( ANDROID_NOEXECSTACK VALUES ON ) __INIT_VARIABLE( ANDROID_NOEXECSTACK VALUES ON )
@ -1350,7 +1347,7 @@ __INIT_VARIABLE( ANDROID_RELRO VALUES ON )
set( ANDROID_NO_UNDEFINED ${ANDROID_NO_UNDEFINED} CACHE BOOL "Show all undefined symbols as linker errors" ) set( ANDROID_NO_UNDEFINED ${ANDROID_NO_UNDEFINED} CACHE BOOL "Show all undefined symbols as linker errors" )
set( ANDROID_SO_UNDEFINED ${ANDROID_SO_UNDEFINED} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" ) set( ANDROID_SO_UNDEFINED ${ANDROID_SO_UNDEFINED} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
set( ANDROID_FUNCTION_LEVEL_LINKING ${ANDROID_FUNCTION_LEVEL_LINKING} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" ) set( ANDROID_FUNCTION_LEVEL_LINKING ${ANDROID_FUNCTION_LEVEL_LINKING} CACHE BOOL "Put each function in separate section and enable garbage collection of unused input sections at link time" )
set( ANDROID_GOLD_LINKER ${ANDROID_GOLD_LINKER} CACHE BOOL "Enables gold linker" ) set( ANDROID_GOLD_LINKER ${ANDROID_GOLD_LINKER} CACHE BOOL "Enables gold linker" )
set( ANDROID_NOEXECSTACK ${ANDROID_NOEXECSTACK} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" ) set( ANDROID_NOEXECSTACK ${ANDROID_NOEXECSTACK} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" )
set( ANDROID_RELRO ${ANDROID_RELRO} CACHE BOOL "Enables RELRO - a memory corruption mitigation technique" ) set( ANDROID_RELRO ${ANDROID_RELRO} CACHE BOOL "Enables RELRO - a memory corruption mitigation technique" )
@ -1452,6 +1449,16 @@ if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" )
set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK_TOOLCHAINS_PATH}/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" )
endif() endif()
# pie/pic
if( NOT (ANDROID_NATIVE_API_LEVEL LESS 16) AND (NOT DEFINED ANDROID_APP_PIE OR ANDROID_APP_PIE) AND (CMAKE_VERSION VERSION_GREATER 2.8.8) )
set( CMAKE_POSITION_INDEPENDENT_CODE TRUE )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")
else()
set( CMAKE_POSITION_INDEPENDENT_CODE FALSE )
set( CMAKE_CXX_FLAGS "-fpic ${CMAKE_CXX_FLAGS}" )
set( CMAKE_C_FLAGS "-fpic ${CMAKE_C_FLAGS}" )
endif()
# configure rtti # configure rtti
if( DEFINED ANDROID_RTTI AND ANDROID_STL_FORCE_FEATURES ) if( DEFINED ANDROID_RTTI AND ANDROID_STL_FORCE_FEATURES )
if( ANDROID_RTTI ) if( ANDROID_RTTI )
@ -1515,27 +1522,31 @@ if( ANDROID_EXPLICIT_CRT_LINK )
endif() endif()
# setup output directories # setup output directories
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
if(NOT _CMAKE_IN_TRY_COMPILE) if( DEFINED LIBRARY_OUTPUT_PATH_ROOT
if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" ) OR EXISTS "${CMAKE_SOURCE_DIR}/AndroidManifest.xml"
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" ) OR (EXISTS "${CMAKE_SOURCE_DIR}/../AndroidManifest.xml" AND EXISTS "${CMAKE_SOURCE_DIR}/../jni/") )
else() set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "Root for binaries output, set this to change where Android libs are installed to" )
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" ) if( NOT _CMAKE_IN_TRY_COMPILE )
endif() if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" ) set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
else()
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
endif()
set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for Android libs" )
endif()
endif() endif()
# copy shaed stl library to build directory # copy shaed stl library to build directory
if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" ) if( NOT _CMAKE_IN_TRY_COMPILE AND __libstl MATCHES "[.]so$" AND DEFINED LIBRARY_OUTPUT_PATH )
get_filename_component( __libstlname "${__libstl}" NAME ) get_filename_component( __libstlname "${__libstl}" NAME )
execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess ) execute_process( COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${__libstl}" "${LIBRARY_OUTPUT_PATH}/${__libstlname}" RESULT_VARIABLE __fileCopyProcess )
if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}") if( NOT __fileCopyProcess EQUAL 0 OR NOT EXISTS "${LIBRARY_OUTPUT_PATH}/${__libstlname}")
message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" ) message( SEND_ERROR "Failed copying of ${__libstl} to the ${LIBRARY_OUTPUT_PATH}/${__libstlname}" )
endif() endif()
unset( __fileCopyProcess ) unset( __fileCopyProcess )
unset( __libstlname ) unset( __libstlname )
endif() endif()
@ -1596,28 +1607,10 @@ macro( find_host_program )
endmacro() endmacro()
macro( ANDROID_GET_ABI_RAWNAME TOOLCHAIN_FLAG VAR )
if( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI" )
set( ${VAR} "armeabi" )
elseif( "${TOOLCHAIN_FLAG}" STREQUAL "ARMEABI_V7A" )
set( ${VAR} "armeabi-v7a" )
elseif( "${TOOLCHAIN_FLAG}" STREQUAL "X86" )
set( ${VAR} "x86" )
elseif( "${TOOLCHAIN_FLAG}" STREQUAL "MIPS" )
set( ${VAR} "mips" )
else()
set( ${VAR} "unknown" )
endif()
endmacro()
if (POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
endif ()
# export toolchain settings for the try_compile() command # export toolchain settings for the try_compile() command
if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" ) if( NOT _CMAKE_IN_TRY_COMPILE )
set( __toolchain_config "") set( __toolchain_config "")
foreach( __var NDK_CCACHE LIBRARY_OUTPUT_PATH_ROOT ANDROID_FORBID_SYGWIN ANDROID_SET_OBSOLETE_VARIABLES foreach( __var NDK_CCACHE LIBRARY_OUTPUT_PATH_ROOT ANDROID_FORBID_SYGWIN
ANDROID_NDK_HOST_X64 ANDROID_NDK_HOST_X64
ANDROID_NDK ANDROID_NDK
ANDROID_NDK_LAYOUT ANDROID_NDK_LAYOUT
@ -1636,9 +1629,10 @@ if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
ANDROID_RELRO ANDROID_RELRO
ANDROID_LIBM_PATH ANDROID_LIBM_PATH
ANDROID_EXPLICIT_CRT_LINK ANDROID_EXPLICIT_CRT_LINK
ANDROID_APP_PIE
) )
if( DEFINED ${__var} ) if( DEFINED ${__var} )
if( "${__var}" MATCHES " ") if( ${__var} MATCHES " ")
set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" ) set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" )
else() else()
set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" ) set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" )
@ -1663,16 +1657,6 @@ if( CMAKE_GENERATOR MATCHES "Ninja" AND CMAKE_HOST_WIN32 )
endif() endif()
# set some obsolete variables for backward compatibility
set( ANDROID_SET_OBSOLETE_VARIABLES ON CACHE BOOL "Define obsolete Andrid-specific cmake variables" )
mark_as_advanced( ANDROID_SET_OBSOLETE_VARIABLES )
if( ANDROID_SET_OBSOLETE_VARIABLES )
set( ANDROID_API_LEVEL ${ANDROID_NATIVE_API_LEVEL} )
set( ARM_TARGET "${ANDROID_ABI}" )
set( ARMEABI_NDK_NAME "${ANDROID_NDK_ABI_NAME}" )
endif()
# Variables controlling behavior or set by cmake toolchain: # Variables controlling behavior or set by cmake toolchain:
# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips", "arm64-v8a", "x86_64", "mips64" # ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips", "arm64-v8a", "x86_64", "mips64"
# ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14,15,16,17,18,19,21 (depends on NDK version) # ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14,15,16,17,18,19,21 (depends on NDK version)
@ -1686,22 +1670,15 @@ endif()
# ANDROID_RELRO : ON/OFF # ANDROID_RELRO : ON/OFF
# ANDROID_FORCE_ARM_BUILD : ON/OFF # ANDROID_FORCE_ARM_BUILD : ON/OFF
# ANDROID_STL_FORCE_FEATURES : ON/OFF # ANDROID_STL_FORCE_FEATURES : ON/OFF
# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF # ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product/<product_name>/obj/lib/libm.so) to workaround unresolved `sincos`
# Can be set only at the first run: # Can be set only at the first run:
# ANDROID_NDK # ANDROID_NDK : path to your NDK install
# ANDROID_STANDALONE_TOOLCHAIN # NDK_CCACHE : path to your ccache executable
# ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain # ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain
# ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems) # ANDROID_NDK_HOST_X64 : try to use x86_64 toolchain (default for x64 host systems)
# ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID) # ANDROID_NDK_LAYOUT : the inner NDK structure (RELEASE, LINARO, ANDROID)
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path> # LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
# NDK_CCACHE : <path to your ccache executable> # ANDROID_STANDALONE_TOOLCHAIN
# Obsolete:
# ANDROID_API_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL
# ARM_TARGET : superseded by ANDROID_ABI
# ARM_TARGETS : superseded by ANDROID_ABI (can be set only)
# ANDROID_NDK_TOOLCHAIN_ROOT : superseded by ANDROID_STANDALONE_TOOLCHAIN (can be set only)
# ANDROID_USE_STLPORT : superseded by ANDROID_STL=stlport_static
# ANDROID_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL (completely removed)
# #
# Primary read-only variables: # Primary read-only variables:
# ANDROID : always TRUE # ANDROID : always TRUE
@ -1715,19 +1692,16 @@ endif()
# X86_64 : TRUE if configured for x86_64 # X86_64 : TRUE if configured for x86_64
# MIPS : TRUE if configured for mips # MIPS : TRUE if configured for mips
# MIPS64 : TRUE if configured for mips64 # MIPS64 : TRUE if configured for mips64
# BUILD_ANDROID : always TRUE
# BUILD_WITH_ANDROID_NDK : TRUE if NDK is used # BUILD_WITH_ANDROID_NDK : TRUE if NDK is used
# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used # BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform # ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86", "mips", "arm64-v8a", "x86_64", "mips64" depending on ANDROID_ABI # ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86", "mips", "arm64-v8a", "x86_64", "mips64" depending on ANDROID_ABI
# ANDROID_NDK_RELEASE : from r5 to r10c; set only for NDK # ANDROID_NDK_RELEASE : from r5 to r10d; set only for NDK
# ANDROID_NDK_RELEASE_NUM : numeric ANDROID_NDK_RELEASE version (1000*major+minor) # ANDROID_NDK_RELEASE_NUM : numeric ANDROID_NDK_RELEASE version (1000*major+minor)
# ANDROID_ARCH_NAME : "arm", "x86", "mips", "arm64", "x86_64", "mips64" depending on ANDROID_ABI # ANDROID_ARCH_NAME : "arm", "x86", "mips", "arm64", "x86_64", "mips64" depending on ANDROID_ABI
# ANDROID_SYSROOT : path to the compiler sysroot # ANDROID_SYSROOT : path to the compiler sysroot
# TOOL_OS_SUFFIX : "" or ".exe" depending on host platform # TOOL_OS_SUFFIX : "" or ".exe" depending on host platform
# ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used # ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used
# Obsolete:
# ARMEABI_NDK_NAME : superseded by ANDROID_NDK_ABI_NAME
# #
# Secondary (less stable) read-only variables: # Secondary (less stable) read-only variables:
# ANDROID_COMPILER_VERSION : GCC version used (not Clang version) # ANDROID_COMPILER_VERSION : GCC version used (not Clang version)
@ -1742,12 +1716,10 @@ endif()
# ANDROID_RTTI : if rtti is enabled by the runtime # ANDROID_RTTI : if rtti is enabled by the runtime
# ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime # ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime
# ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used # ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used
# ANDROID_LIBM_PATH : path to libm.so (set to something like $(TOP)/out/target/product/<product_name>/obj/lib/libm.so) to workaround unresolved `sincos`
# #
# Defaults: # Defaults:
# ANDROID_DEFAULT_NDK_API_LEVEL # ANDROID_DEFAULT_NDK_API_LEVEL
# ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH} # ANDROID_DEFAULT_NDK_API_LEVEL_${ARCH}
# ANDROID_NDK_SEARCH_PATHS # ANDROID_NDK_SEARCH_PATHS
# ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH
# ANDROID_SUPPORTED_ABIS_${ARCH} # ANDROID_SUPPORTED_ABIS_${ARCH}
# ANDROID_SUPPORTED_NDK_VERSIONS # ANDROID_SUPPORTED_NDK_VERSIONS

View file

@ -15,7 +15,6 @@ ExternalProject_Add(
LOG_BUILD 1 LOG_BUILD 1
) )
# Hide this external target (for ide users) # Hide this external target (for ide users)
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
@ -32,4 +31,4 @@ elseif (WIN32)
endif () endif ()
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/${LIB_PREFIX}glew_d.${LIB_EXT} CACHE FILEPATH "Path to glew debug library") set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/${LIB_PREFIX}glew_d.${LIB_EXT} CACHE FILEPATH "Path to glew debug library")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/${LIB_PREFIX}glew.${LIB_EXT} CACHE FILEPATH "Path to glew release library") set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/${LIB_PREFIX}glew.${LIB_EXT} CACHE FILEPATH "Path to glew release library")

View file

@ -5,39 +5,43 @@ set(EXTERNAL_NAME hifiAudioCodec)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (WIN32 OR APPLE) if (NOT ANDROID)
ExternalProject_Add(
${EXTERNAL_NAME} if (WIN32 OR APPLE)
URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-1.zip ExternalProject_Add(
URL_MD5 23ec3fe51eaa155ea159a4971856fc13 ${EXTERNAL_NAME}
CONFIGURE_COMMAND "" URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-1.zip
BUILD_COMMAND "" URL_MD5 23ec3fe51eaa155ea159a4971856fc13
INSTALL_COMMAND "" CONFIGURE_COMMAND ""
LOG_DOWNLOAD 1 BUILD_COMMAND ""
) INSTALL_COMMAND ""
elseif(NOT ANDROID) LOG_DOWNLOAD 1
ExternalProject_Add( )
${EXTERNAL_NAME} else ()
URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-linux.zip ExternalProject_Add(
URL_MD5 7d37914a18aa4de971d2f45dd3043bde ${EXTERNAL_NAME}
CONFIGURE_COMMAND "" URL http://s3.amazonaws.com/hifi-public/dependencies/codecSDK-linux.zip
BUILD_COMMAND "" URL_MD5 7d37914a18aa4de971d2f45dd3043bde
INSTALL_COMMAND "" CONFIGURE_COMMAND ""
LOG_DOWNLOAD 1 BUILD_COMMAND ""
) INSTALL_COMMAND ""
endif() LOG_DOWNLOAD 1
)
# Hide this external target (for ide users) endif()
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
# Hide this external target (for ide users)
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL) ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
if (WIN32) set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/include CACHE TYPE INTERNAL)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE TYPE INTERNAL)
elseif(APPLE) if (WIN32)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL) set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/audio.lib CACHE TYPE INTERNAL)
elseif(NOT ANDROID) elseif(APPLE)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL) set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL)
elseif(NOT ANDROID)
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/Release/libaudio.a CACHE TYPE INTERNAL)
endif()
endif() endif()

View file

@ -46,7 +46,7 @@ else ()
if (ANDROID) if (ANDROID)
set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19") set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19")
endif () endif ()
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://www.libsdl.org/release/SDL2-2.0.3.tar.gz URL http://www.libsdl.org/release/SDL2-2.0.3.tar.gz
@ -61,7 +61,6 @@ endif ()
# Hide this external target (for ide users) # Hide this external target (for ide users)
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
if (APPLE) if (APPLE)
# NOOP # NOOP
@ -78,9 +77,9 @@ elseif (WIN32)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_TEMP ${SOURCE_DIR}/lib/x86/SDL2.lib CACHE FILEPATH "Path to SDL2 library") set(${EXTERNAL_NAME_UPPER}_LIBRARY_TEMP ${SOURCE_DIR}/lib/x86/SDL2.lib CACHE FILEPATH "Path to SDL2 library")
set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${SOURCE_DIR}/lib/x86 CACHE PATH "Location of SDL2 DLL") set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${SOURCE_DIR}/lib/x86 CACHE PATH "Location of SDL2 DLL")
endif() endif()
add_paths_to_fixup_libs(${${EXTERNAL_NAME_UPPER}_DLL_PATH}) add_paths_to_fixup_libs(${${EXTERNAL_NAME_UPPER}_DLL_PATH})
else () else ()
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR) ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)

View file

@ -3,9 +3,9 @@ set(EXTERNAL_NAME tbb)
include(ExternalProject) include(ExternalProject)
if (ANDROID) if (ANDROID)
find_program(NDK_BUILD_COMMAND NAMES ndk-build DOC "Path to the ndk-build command") find_program(NDK_BUILD_COMMAND NAMES ndk-build DOC "Path to the ndk-build command")
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz
@ -20,7 +20,7 @@ if (ANDROID)
) )
elseif (APPLE) elseif (APPLE)
find_program(MAKE_COMMAND NAMES make DOC "Path to the make command") find_program(MAKE_COMMAND NAMES make DOC "Path to the make command")
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz URL http://hifi-public.s3.amazonaws.com/dependencies/tbb43_20150316oss_src.tgz
@ -37,11 +37,11 @@ else ()
if (WIN32) if (WIN32)
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip) set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_win.zip)
set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440) set(DOWNLOAD_MD5 d250d40bb93b255f75bcbb19e976a440)
else () else ()
set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_lin.tgz) set(DOWNLOAD_URL http://s3.amazonaws.com/hifi-public/dependencies/tbb43_20150316oss_lin.tgz)
set(DOWNLOAD_MD5 7830ba2bc62438325fba2ec0c95367a5) set(DOWNLOAD_MD5 7830ba2bc62438325fba2ec0c95367a5)
endif () endif ()
ExternalProject_Add( ExternalProject_Add(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
URL ${DOWNLOAD_URL} URL ${DOWNLOAD_URL}
@ -60,11 +60,11 @@ ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
if (APPLE) if (APPLE)
set(_TBB_LIB_DIR "${SOURCE_DIR}/lib") set(_TBB_LIB_DIR "${SOURCE_DIR}/lib")
set(_LIB_PREFIX "lib") set(_LIB_PREFIX "lib")
set(_LIB_EXT "dylib") set(_LIB_EXT "dylib")
ExternalProject_Add_Step( ExternalProject_Add_Step(
${EXTERNAL_NAME} ${EXTERNAL_NAME}
change-install-name change-install-name
@ -74,7 +74,7 @@ if (APPLE)
WORKING_DIRECTORY <SOURCE_DIR> WORKING_DIRECTORY <SOURCE_DIR>
LOG 1 LOG 1
) )
elseif (WIN32) elseif (WIN32)
if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") if ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/intel64/vc12") set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/intel64/vc12")
@ -91,18 +91,18 @@ elseif (ANDROID)
elseif (UNIX) elseif (UNIX)
set(_LIB_PREFIX "lib") set(_LIB_PREFIX "lib")
set(_LIB_EXT "so") set(_LIB_EXT "so")
if(CMAKE_SIZEOF_VOID_P EQUAL 8) if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_TBB_ARCH_DIR "intel64") set(_TBB_ARCH_DIR "intel64")
else() else()
set(_TBB_ARCH_DIR "ia32") set(_TBB_ARCH_DIR "ia32")
endif() endif()
execute_process( execute_process(
COMMAND ${CMAKE_C_COMPILER} -dumpversion COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION OUTPUT_VARIABLE GCC_VERSION
) )
if (GCC_VERSION VERSION_GREATER 4.4 OR GCC_VERSION VERSION_EQUAL 4.4) if (GCC_VERSION VERSION_GREATER 4.4 OR GCC_VERSION VERSION_EQUAL 4.4)
set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/${_TBB_ARCH_DIR}/gcc4.4") set(_TBB_LIB_DIR "${SOURCE_DIR}/lib/${_TBB_ARCH_DIR}/gcc4.4")
elseif (GCC_VERSION VERSION_GREATER 4.1 OR GCC_VERSION VERSION_EQUAL 4.1) elseif (GCC_VERSION VERSION_GREATER 4.1 OR GCC_VERSION VERSION_EQUAL 4.1)
@ -110,9 +110,9 @@ elseif (UNIX)
else () else ()
message(STATUS "Could not find a compatible version of Threading Building Blocks library for your compiler.") message(STATUS "Could not find a compatible version of Threading Building Blocks library for your compiler.")
endif () endif ()
endif () endif ()
if (DEFINED _TBB_LIB_DIR) if (DEFINED _TBB_LIB_DIR)
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location") set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${_TBB_LIB_DIR}/${_LIB_PREFIX}tbb_debug.${_LIB_EXT} CACHE FILEPATH "TBB debug library location")

View file

@ -1,23 +0,0 @@
#
# AutoMTC.cmake
#
# Created by Andrzej Kapolka on 12/31/13.
# Copyright 2013 High Fidelity, Inc.
#
# Distributed under the Apache License, Version 2.0.
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#
macro(AUTO_MTC)
set(AUTOMTC_SRC ${TARGET_NAME}_automtc.cpp)
file(GLOB INCLUDE_FILES src/*.h)
if (NOT ANDROID)
set(MTC_EXECUTABLE mtc)
else ()
set(MTC_EXECUTABLE $ENV{MTC_PATH}/mtc)
endif ()
add_custom_command(OUTPUT ${AUTOMTC_SRC} COMMAND ${MTC_EXECUTABLE} -o ${AUTOMTC_SRC} ${INCLUDE_FILES} DEPENDS ${MTC_EXECUTABLE} ${INCLUDE_FILES})
endmacro()

View file

@ -1,77 +1,92 @@
# #
# AutoScribeShader.cmake # AutoScribeShader.cmake
# #
# Created by Sam Gateau on 12/17/14. # Created by Sam Gateau on 12/17/14.
# Copyright 2014 High Fidelity, Inc. # Copyright 2014 High Fidelity, Inc.
# #
# Distributed under the Apache License, Version 2.0. # Distributed under the Apache License, Version 2.0.
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
# #
function(AUTOSCRIBE_SHADER SHADER_FILE) function(AUTOSCRIBE_SHADER SHADER_FILE)
# Grab include files
# Grab include files foreach(includeFile ${ARGN})
foreach(includeFile ${ARGN}) list(APPEND SHADER_INCLUDE_FILES ${includeFile})
list(APPEND SHADER_INCLUDE_FILES ${includeFile}) endforeach()
endforeach()
foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES}) foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES})
get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH) get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH)
list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR}) list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR})
endforeach() endforeach()
#Extract the unique include shader paths
set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
#message(${TARGET_NAME} Hifi for includes ${INCLUDES})
foreach(EXTRA_SHADER_INCLUDE ${INCLUDES})
list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE})
endforeach()
#Extract the unique include shader paths list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES}) #message(ready for includes ${SHADER_INCLUDES_PATHS})
#message(${TARGET_NAME} Hifi for includes ${INCLUDES})
foreach(EXTRA_SHADER_INCLUDE ${INCLUDES})
list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE})
endforeach()
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS) # make the scribe include arguments
#message(ready for includes ${SHADER_INCLUDES_PATHS}) set(SCRIBE_INCLUDES)
foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS})
set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/)
endforeach()
# make the scribe include arguments # Define the final name of the generated shader file
set(SCRIBE_INCLUDES) get_filename_component(SHADER_TARGET ${SHADER_FILE} NAME_WE)
foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS}) get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/) if(SHADER_EXT STREQUAL .slv)
endforeach() set(SHADER_TARGET ${SHADER_TARGET}_vert.h)
elseif(${SHADER_EXT} STREQUAL .slf)
set(SHADER_TARGET ${SHADER_TARGET}_frag.h)
elseif(${SHADER_EXT} STREQUAL .slg)
set(SHADER_TARGET ${SHADER_TARGET}_geom.h)
endif()
# Define the final name of the generated shader file set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_TARGET}")
get_filename_component(SHADER_TARGET ${SHADER_FILE} NAME_WE)
get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
if(SHADER_EXT STREQUAL .slv)
set(SHADER_TARGET ${SHADER_TARGET}_vert.h)
elseif(${SHADER_EXT} STREQUAL .slf)
set(SHADER_TARGET ${SHADER_TARGET}_frag.h)
elseif(${SHADER_EXT} STREQUAL .slg)
set(SHADER_TARGET ${SHADER_TARGET}_geom.h)
endif()
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_TARGET}") # Target dependant Custom rule on the SHADER_FILE
if (APPLE)
set(GLPROFILE MAC_GL)
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
# Target dependant Custom rule on the SHADER_FILE add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
if (APPLE) elseif (ANDROID)
set(GLPROFILE MAC_GL) set(GLPROFILE LINUX_GL)
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE}) set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE}) # for an android build, we can't use the scribe that cmake would normally produce as a target,
elseif (UNIX) # since it's unrunnable by the cross-compiling build machine
set(GLPROFILE LINUX_GL)
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE}) # so, we require the compiling user to point us at a compiled executable version for their native toolchain
else () find_program(NATIVE_SCRIBE scribe PATHS ${SCRIBE_PATH} ENV SCRIBE_PATH)
set(GLPROFILE PC_GL)
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE}) if (NOT NATIVE_SCRIBE)
endif() message(FATAL_ERROR "The High Fidelity scribe tool is required for shader pre-processing. \
Please compile scribe using your native toolchain and set SCRIBE_PATH to the path containing the scribe executable in your ENV.\
")
endif ()
#output the generated file name add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND ${NATIVE_SCRIBE} ${SCRIBE_ARGS} DEPENDS ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
set(AUTOSCRIBE_SHADER_RETURN ${SHADER_TARGET} PARENT_SCOPE) elseif (UNIX)
set(GLPROFILE LINUX_GL)
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
file(GLOB INCLUDE_FILES ${SHADER_TARGET}) add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
else ()
set(GLPROFILE PC_GL)
set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE})
endif()
#output the generated file name
set(AUTOSCRIBE_SHADER_RETURN ${SHADER_TARGET} PARENT_SCOPE)
file(GLOB INCLUDE_FILES ${SHADER_TARGET})
endfunction() endfunction()
@ -79,11 +94,11 @@ endfunction()
macro(AUTOSCRIBE_SHADER_LIB) macro(AUTOSCRIBE_SHADER_LIB)
set(HIFI_LIBRARIES_SHADER_INCLUDE_FILES "") set(HIFI_LIBRARIES_SHADER_INCLUDE_FILES "")
file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}") file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
foreach(HIFI_LIBRARY ${ARGN}) foreach(HIFI_LIBRARY ${ARGN})
#if (NOT TARGET ${HIFI_LIBRARY}) #if (NOT TARGET ${HIFI_LIBRARY})
# file(GLOB_RECURSE HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${RELATIVE_LIBRARY_DIR_PATH}/${HIFI_LIBRARY}/src/) # file(GLOB_RECURSE HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${RELATIVE_LIBRARY_DIR_PATH}/${HIFI_LIBRARY}/src/)
#endif () #endif ()
#file(GLOB_RECURSE HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src/*.slh) #file(GLOB_RECURSE HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src/*.slh)
list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src) list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src)
endforeach() endforeach()
@ -99,9 +114,9 @@ macro(AUTOSCRIBE_SHADER_LIB)
#message("${TARGET_NAME} ${SHADER_INCLUDE_FILES}") #message("${TARGET_NAME} ${SHADER_INCLUDE_FILES}")
set(AUTOSCRIBE_SHADER_SRC "") set(AUTOSCRIBE_SHADER_SRC "")
foreach(SHADER_FILE ${SHADER_SOURCE_FILES}) foreach(SHADER_FILE ${SHADER_SOURCE_FILES})
AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES}) AUTOSCRIBE_SHADER(${SHADER_FILE} ${SHADER_INCLUDE_FILES})
file(TO_CMAKE_PATH "${AUTOSCRIBE_SHADER_RETURN}" AUTOSCRIBE_GENERATED_FILE) file(TO_CMAKE_PATH "${AUTOSCRIBE_SHADER_RETURN}" AUTOSCRIBE_GENERATED_FILE)
list(APPEND AUTOSCRIBE_SHADER_SRC ${AUTOSCRIBE_GENERATED_FILE}) list(APPEND AUTOSCRIBE_SHADER_SRC ${AUTOSCRIBE_GENERATED_FILE})
endforeach() endforeach()
#message(${TARGET_NAME} ${AUTOSCRIBE_SHADER_SRC}) #message(${TARGET_NAME} ${AUTOSCRIBE_SHADER_SRC})
@ -118,4 +133,4 @@ macro(AUTOSCRIBE_SHADER_LIB)
# Link library shaders, if they exist # Link library shaders, if they exist
include_directories("${SHADERS_DIR}") include_directories("${SHADERS_DIR}")
endmacro() endmacro()

View file

@ -1,16 +1,16 @@
# #
# SetupHifiLibrary.cmake # SetupHifiLibrary.cmake
# #
# Copyright 2013 High Fidelity, Inc. # Copyright 2013 High Fidelity, Inc.
# #
# Distributed under the Apache License, Version 2.0. # Distributed under the Apache License, Version 2.0.
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html # See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
# #
macro(SETUP_HIFI_LIBRARY) macro(SETUP_HIFI_LIBRARY)
project(${TARGET_NAME}) project(${TARGET_NAME})
# grab the implementation and header files # grab the implementation and header files
file(GLOB_RECURSE LIB_SRCS "src/*.h" "src/*.cpp" "src/*.c") file(GLOB_RECURSE LIB_SRCS "src/*.h" "src/*.cpp" "src/*.c")
list(APPEND ${TARGET_NAME}_SRCS ${LIB_SRCS}) list(APPEND ${TARGET_NAME}_SRCS ${LIB_SRCS})
@ -34,19 +34,19 @@ macro(SETUP_HIFI_LIBRARY)
set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS "-mavx2 -mfma") set_source_files_properties(${SRC} PROPERTIES COMPILE_FLAGS "-mavx2 -mfma")
endif() endif()
endforeach() endforeach()
setup_memory_debugger() setup_memory_debugger()
# create a library and set the property so it can be referenced later # create a library and set the property so it can be referenced later
if (${${TARGET_NAME}_SHARED}) if (${${TARGET_NAME}_SHARED})
add_library(${TARGET_NAME} SHARED ${LIB_SRCS} ${AUTOMTC_SRC} ${AUTOSCRIBE_SHADER_LIB_SRC} ${QT_RESOURCES_FILE}) add_library(${TARGET_NAME} SHARED ${LIB_SRCS} ${AUTOSCRIBE_SHADER_LIB_SRC} ${QT_RESOURCES_FILE})
else () else ()
add_library(${TARGET_NAME} ${LIB_SRCS} ${AUTOMTC_SRC} ${AUTOSCRIBE_SHADER_LIB_SRC} ${QT_RESOURCES_FILE}) add_library(${TARGET_NAME} ${LIB_SRCS} ${AUTOSCRIBE_SHADER_LIB_SRC} ${QT_RESOURCES_FILE})
endif () endif ()
set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN}) set(${TARGET_NAME}_DEPENDENCY_QT_MODULES ${ARGN})
list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core) list(APPEND ${TARGET_NAME}_DEPENDENCY_QT_MODULES Core)
# find these Qt modules and link them to our own target # find these Qt modules and link them to our own target
find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED) find_package(Qt5 COMPONENTS ${${TARGET_NAME}_DEPENDENCY_QT_MODULES} REQUIRED)
@ -59,7 +59,7 @@ macro(SETUP_HIFI_LIBRARY)
set(QT_RESOURCES_FILE "") set(QT_RESOURCES_FILE "")
target_glm() target_glm()
set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Libraries") set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Libraries")
endmacro(SETUP_HIFI_LIBRARY) endmacro(SETUP_HIFI_LIBRARY)

View file

@ -22,7 +22,7 @@ macro(SETUP_HIFI_PROJECT)
endif () endif ()
endforeach() endforeach()
add_executable(${TARGET_NAME} ${TARGET_SRCS} ${AUTOMTC_SRC} ${AUTOSCRIBE_SHADER_LIB_SRC}) add_executable(${TARGET_NAME} ${TARGET_SRCS} ${AUTOSCRIBE_SHADER_LIB_SRC})
# include the generated application version header # include the generated application version header
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes") target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes")

View file

@ -3,7 +3,7 @@ set(TARGET_NAME gvr-interface)
if (ANDROID) if (ANDROID)
set(ANDROID_APK_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/apk-build") set(ANDROID_APK_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/apk-build")
set(ANDROID_APK_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/apk") set(ANDROID_APK_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/apk")
set(ANDROID_SDK_ROOT $ENV{ANDROID_HOME}) set(ANDROID_SDK_ROOT $ENV{ANDROID_HOME})
set(ANDROID_APP_DISPLAY_NAME Interface) set(ANDROID_APP_DISPLAY_NAME Interface)
set(ANDROID_API_LEVEL 19) set(ANDROID_API_LEVEL 19)
@ -13,10 +13,10 @@ if (ANDROID)
set(ANDROID_APK_VERSION_CODE 1) set(ANDROID_APK_VERSION_CODE 1)
set(ANDROID_APK_FULLSCREEN TRUE) set(ANDROID_APK_FULLSCREEN TRUE)
set(ANDROID_DEPLOY_QT_INSTALL "--install") set(ANDROID_DEPLOY_QT_INSTALL "--install")
set(BUILD_SHARED_LIBS ON) set(BUILD_SHARED_LIBS ON)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${ANDROID_APK_OUTPUT_DIR}/libs/${ANDROID_ABI}") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${ANDROID_APK_OUTPUT_DIR}/libs/${ANDROID_ABI}")
setup_hifi_library(Gui Widgets AndroidExtras) setup_hifi_library(Gui Widgets AndroidExtras)
else () else ()
setup_hifi_project(Gui Widgets) setup_hifi_project(Gui Widgets)
@ -28,12 +28,12 @@ link_hifi_libraries(shared networking audio-client avatars)
if (ANDROID) if (ANDROID)
find_package(LibOVR) find_package(LibOVR)
if (LIBOVR_FOUND) if (LIBOVR_FOUND)
add_definitions(-DHAVE_LIBOVR) add_definitions(-DHAVE_LIBOVR)
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES} ${LIBOVR_ANDROID_LIBRARIES} ${TURBOJPEG_LIBRARY}) target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES} ${LIBOVR_ANDROID_LIBRARIES} ${TURBOJPEG_LIBRARY})
include_directories(SYSTEM ${LIBOVR_INCLUDE_DIRS}) include_directories(SYSTEM ${LIBOVR_INCLUDE_DIRS})
# we need VRLib, so add a project.properties to our apk build folder that says that # we need VRLib, so add a project.properties to our apk build folder that says that
file(RELATIVE_PATH RELATIVE_VRLIB_PATH ${ANDROID_APK_OUTPUT_DIR} "${LIBOVR_VRLIB_DIR}") file(RELATIVE_PATH RELATIVE_VRLIB_PATH ${ANDROID_APK_OUTPUT_DIR} "${LIBOVR_VRLIB_DIR}")
file(WRITE "${ANDROID_APK_BUILD_DIR}/project.properties" "android.library.reference.1=${RELATIVE_VRLIB_PATH}") file(WRITE "${ANDROID_APK_BUILD_DIR}/project.properties" "android.library.reference.1=${RELATIVE_VRLIB_PATH}")
@ -50,7 +50,7 @@ if (ANDROID AND HOCKEY_APP_ID)
set(ANDROID_ACTIVITY_NAME io.highfidelity.gvrinterface.InterfaceBetaActivity) set(ANDROID_ACTIVITY_NAME io.highfidelity.gvrinterface.InterfaceBetaActivity)
set(ANDROID_DEPLOY_QT_INSTALL "") set(ANDROID_DEPLOY_QT_INSTALL "")
set(ANDROID_APK_CUSTOM_NAME "Interface-beta.apk") set(ANDROID_APK_CUSTOM_NAME "Interface-beta.apk")
# set the ANDROID_APK_VERSION_CODE to the number of git commits # set the ANDROID_APK_VERSION_CODE to the number of git commits
execute_process( execute_process(
COMMAND git rev-list --first-parent --count HEAD COMMAND git rev-list --first-parent --count HEAD
@ -58,16 +58,16 @@ if (ANDROID AND HOCKEY_APP_ID)
OUTPUT_VARIABLE GIT_COMMIT_COUNT OUTPUT_VARIABLE GIT_COMMIT_COUNT
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
) )
set(ANDROID_APK_VERSION_CODE ${GIT_COMMIT_COUNT}) set(ANDROID_APK_VERSION_CODE ${GIT_COMMIT_COUNT})
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/templates/InterfaceBetaActivity.java.in" "${ANDROID_APK_BUILD_DIR}/src/io/highfidelity/gvrinterface/InterfaceBetaActivity.java") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/templates/InterfaceBetaActivity.java.in" "${ANDROID_APK_BUILD_DIR}/src/io/highfidelity/gvrinterface/InterfaceBetaActivity.java")
elseif (ANDROID) elseif (ANDROID)
set(HOCKEY_APP_ENABLED false) set(HOCKEY_APP_ENABLED false)
endif () endif ()
if (ANDROID) if (ANDROID)
set(HIFI_URL_INTENT "<intent-filter>\ set(HIFI_URL_INTENT "<intent-filter>\
\n <action android:name='android.intent.action.VIEW' />\ \n <action android:name='android.intent.action.VIEW' />\
\n <category android:name='android.intent.category.DEFAULT' />\ \n <category android:name='android.intent.category.DEFAULT' />\
@ -75,13 +75,11 @@ if (ANDROID)
\n <data android:scheme='hifi' />\ \n <data android:scheme='hifi' />\
\n </intent-filter>" \n </intent-filter>"
) )
set(ANDROID_EXTRA_APPLICATION_XML "${HOCKEY_APP_ACTIVITY}") set(ANDROID_EXTRA_APPLICATION_XML "${HOCKEY_APP_ACTIVITY}")
set(ANDROID_EXTRA_ACTIVITY_XML "${HIFI_URL_INTENT}") set(ANDROID_EXTRA_ACTIVITY_XML "${HIFI_URL_INTENT}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/templates/hockeyapp.xml.in" "${ANDROID_APK_BUILD_DIR}/res/values/hockeyapp.xml") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/templates/hockeyapp.xml.in" "${ANDROID_APK_BUILD_DIR}/res/values/hockeyapp.xml")
qt_create_apk() qt_create_apk()
endif (ANDROID)
copy_dlls_beside_windows_executable() endif (ANDROID)

View file

@ -39,9 +39,18 @@ else ()
list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP}) list(REMOVE_ITEM INTERFACE_SRCS ${SPEECHRECOGNIZER_CPP})
endif () endif ()
find_package(Qt5 COMPONENTS if (ANDROID)
Gui Multimedia Network OpenGL Qml Quick Script ScriptTools Svg set(PLATFORM_QT_COMPONENTS AndroidExtras)
WebChannel WebEngine WebEngineWidgets WebKitWidgets WebSockets) else ()
set(PLATFORM_QT_COMPONENTS WebEngine WebEngineWidgets WebKitWidgets)
endif ()
find_package(
Qt5 COMPONENTS
Gui Multimedia Network OpenGL Qml Quick Script ScriptTools Svg
${PLATFORM_QT_COMPONENTS}
WebChannel WebSockets
)
# grab the ui files in resources/ui # grab the ui files in resources/ui
file (GLOB_RECURSE QT_UI_FILES ui/*.ui) file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
@ -57,6 +66,26 @@ set(INTERFACE_SRCS ${INTERFACE_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
# set(TS ${TARGET_NAME}_en.ts) # set(TS ${TARGET_NAME}_en.ts)
# qt5_create_translation_custom(${QM} ${INTERFACE_SRCS} ${QT_UI_FILES} ${TS}) # qt5_create_translation_custom(${QM} ${INTERFACE_SRCS} ${QT_UI_FILES} ${TS})
# setup the android parameters that will help us produce an APK
if (ANDROID)
set(ANDROID_APK_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/apk-build")
set(ANDROID_APK_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/apk")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${ANDROID_APK_OUTPUT_DIR}/libs/${ANDROID_ABI}")
set(ANDROID_SDK_ROOT $ENV{ANDROID_HOME})
set(ANDROID_APP_DISPLAY_NAME Interface)
set(ANDROID_API_LEVEL 19)
set(ANDROID_APK_PACKAGE io.highfidelity.interface)
set(ANDROID_ACTIVITY_NAME io.highfidelity.interface.InterfaceActivity)
set(ANDROID_APK_VERSION_NAME "0.1")
set(ANDROID_APK_VERSION_CODE 1)
set(ANDROID_APK_FULLSCREEN TRUE)
set(ANDROID_DEPLOY_QT_INSTALL "--install")
set(BUILD_SHARED_LIBS ON)
endif ()
if (APPLE) if (APPLE)
# configure CMake to use a custom Info.plist # configure CMake to use a custom Info.plist
@ -95,7 +124,7 @@ if (APPLE)
# make sure the output name for the .app bundle is correct # make sure the output name for the .app bundle is correct
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${INTERFACE_BUNDLE_NAME}) set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${INTERFACE_BUNDLE_NAME})
elseif(WIN32) elseif (WIN32)
# configure an rc file for the chosen icon # configure an rc file for the chosen icon
set(CONFIGURE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}") set(CONFIGURE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/icon/${INTERFACE_ICON_FILENAME}")
set(CONFIGURE_ICON_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Icon.rc") set(CONFIGURE_ICON_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Icon.rc")
@ -104,7 +133,7 @@ elseif(WIN32)
# add an executable that also has the icon itself and the configured rc file as resources # add an executable that also has the icon itself and the configured rc file as resources
add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT}) add_executable(${TARGET_NAME} WIN32 ${INTERFACE_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT})
if ( NOT DEV_BUILD ) if (NOT DEV_BUILD)
add_custom_command( add_custom_command(
TARGET ${TARGET_NAME} TARGET ${TARGET_NAME}
POST_BUILD POST_BUILD
@ -113,9 +142,12 @@ elseif(WIN32)
) )
endif() endif()
else() elseif (ANDROID)
# on android the Interface target is a library that gets linked/used by the APK shell that qtcreateapk produces
add_library(${TARGET_NAME} ${INTERFACE_SRCS} ${QM})
else ()
add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM}) add_executable(${TARGET_NAME} ${INTERFACE_SRCS} ${QM})
endif() endif ()
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes") target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes")
@ -135,21 +167,32 @@ if (WIN32)
set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG "/OPT:NOREF /OPT:NOICF") set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG "/OPT:NOREF /OPT:NOICF")
endif() endif()
if (NOT ANDROID)
set(NON_ANDROID_LIBRARIES steamworks-wrapper)
endif ()
# link required hifi libraries # link required hifi libraries
link_hifi_libraries(shared octree gpu gl gpu-gl procedural model render link_hifi_libraries(
recording fbx networking model-networking entities avatars shared octree gpu gl gpu-gl procedural model render
audio audio-client animation script-engine physics recording fbx networking model-networking entities avatars
render-utils entities-renderer ui auto-updater audio audio-client animation script-engine physics
controllers plugins ui-plugins display-plugins input-plugins steamworks-wrapper) render-utils entities-renderer ui auto-updater
controllers plugins
ui-plugins display-plugins input-plugins
${NON_ANDROID_LIBRARIES}
)
# include the binary directory of render-utils for shader includes # include the binary directory of render-utils for shader includes
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries/render-utils") target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/libraries/render-utils")
#fixme find a way to express faceshift as a plugin #fixme find a way to express faceshift as a plugin
target_bullet() target_bullet()
target_glew()
target_opengl() target_opengl()
if (NOT ANDROID)
target_glew()
endif ()
if (WIN32 OR APPLE) if (WIN32 OR APPLE)
target_faceshift() target_faceshift()
endif() endif()
@ -291,3 +334,17 @@ if (WIN32)
package_libraries_for_deployment() package_libraries_for_deployment()
endif() endif()
if (ANDROID)
set(HIFI_URL_INTENT "<intent-filter>\
\n <action android:name='android.intent.action.VIEW' />\
\n <category android:name='android.intent.category.DEFAULT' />\
\n <category android:name='android.intent.category.BROWSABLE' />\
\n <data android:scheme='hifi' />\
\n </intent-filter>"
)
set(ANDROID_EXTRA_ACTIVITY_XML "${HIFI_URL_INTENT}")
qt_create_apk()
endif ()

View file

@ -0,0 +1,41 @@
//
// InterfaceActivity.java
// gvr-interface/java
//
// Created by Stephen Birarda on 1/26/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
package io.highfidelity.gvrinterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.WindowManager;
import android.util.Log;
import org.qtproject.qt5.android.bindings.QtActivity;
public class InterfaceActivity extends QtActivity {
public static native void handleHifiURL(String hifiURLString);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Get the intent that started this activity in case we have a hifi:// URL to parse
Intent intent = getIntent();
if (intent.getAction() == Intent.ACTION_VIEW) {
Uri data = intent.getData();
if (data.getScheme().equals("hifi")) {
handleHifiURL(data.toString());
}
}
}
}

View file

@ -1,3 +1,8 @@
set(TARGET_NAME audio) set(TARGET_NAME audio)
setup_hifi_library(Network) setup_hifi_library(Network)
if (ANDROID)
add_definitions("-D__STDC_CONSTANT_MACROS")
endif ()
link_hifi_libraries(networking shared plugins) link_hifi_libraries(networking shared plugins)

View file

@ -9,6 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "AudioInjector.h"
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QDataStream> #include <QtCore/QDataStream>
@ -24,8 +26,6 @@
#include "SoundCache.h" #include "SoundCache.h"
#include "AudioSRC.h" #include "AudioSRC.h"
#include "AudioInjector.h"
int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>(); int audioInjectorPtrMetaTypeId = qRegisterMetaType<AudioInjector*>();
AudioInjectorState operator& (AudioInjectorState lhs, AudioInjectorState rhs) { AudioInjectorState operator& (AudioInjectorState lhs, AudioInjectorState rhs) {
@ -52,7 +52,7 @@ AudioInjector::AudioInjector(const Sound& sound, const AudioInjectorOptions& inj
AudioInjector::AudioInjector(const QByteArray& audioData, const AudioInjectorOptions& injectorOptions) : AudioInjector::AudioInjector(const QByteArray& audioData, const AudioInjectorOptions& injectorOptions) :
_audioData(audioData), _audioData(audioData),
_options(injectorOptions) _options(injectorOptions)
{ {
} }
@ -62,7 +62,7 @@ bool AudioInjector::stateHas(AudioInjectorState state) const {
} }
void AudioInjector::setOptions(const AudioInjectorOptions& options) { void AudioInjector::setOptions(const AudioInjectorOptions& options) {
// since options.stereo is computed from the audio stream, // since options.stereo is computed from the audio stream,
// we need to copy it from existing options just in case. // we need to copy it from existing options just in case.
bool currentlyStereo = _options.stereo; bool currentlyStereo = _options.stereo;
_options = options; _options = options;
@ -71,7 +71,7 @@ void AudioInjector::setOptions(const AudioInjectorOptions& options) {
void AudioInjector::finishNetworkInjection() { void AudioInjector::finishNetworkInjection() {
_state |= AudioInjectorState::NetworkInjectionFinished; _state |= AudioInjectorState::NetworkInjectionFinished;
// if we are already finished with local // if we are already finished with local
// injection, then we are finished // injection, then we are finished
if(stateHas(AudioInjectorState::LocalInjectionFinished)) { if(stateHas(AudioInjectorState::LocalInjectionFinished)) {
@ -154,13 +154,13 @@ void AudioInjector::restart() {
_hasSetup = false; _hasSetup = false;
_shouldStop = false; _shouldStop = false;
_state = AudioInjectorState::NotFinished; _state = AudioInjectorState::NotFinished;
// call inject audio to start injection over again // call inject audio to start injection over again
setupInjection(); setupInjection();
// inject locally // inject locally
if(injectLocally()) { if(injectLocally()) {
// if not localOnly, wake the AudioInjectorManager back up if it is stuck waiting // if not localOnly, wake the AudioInjectorManager back up if it is stuck waiting
if (!_options.localOnly) { if (!_options.localOnly) {
@ -221,7 +221,7 @@ qint64 writeStringToStream(const QString& string, QDataStream& stream) {
stream << static_cast<quint32>(length); stream << static_cast<quint32>(length);
} else { } else {
// http://doc.qt.io/qt-5/datastreamformat.html // http://doc.qt.io/qt-5/datastreamformat.html
// QDataStream << QByteArray - // QDataStream << QByteArray -
// If the byte array is null : 0xFFFFFFFF (quint32) // If the byte array is null : 0xFFFFFFFF (quint32)
// Otherwise : the array size(quint32) followed by the array bytes, i.e.size bytes // Otherwise : the array size(quint32) followed by the array bytes, i.e.size bytes
stream << data; stream << data;
@ -239,7 +239,7 @@ int64_t AudioInjector::injectNextFrame() {
static int positionOptionOffset = -1; static int positionOptionOffset = -1;
static int volumeOptionOffset = -1; static int volumeOptionOffset = -1;
static int audioDataOffset = -1; static int audioDataOffset = -1;
if (!_currentPacket) { if (!_currentPacket) {
if (_currentSendOffset < 0 || if (_currentSendOffset < 0 ||
_currentSendOffset >= _audioData.size()) { _currentSendOffset >= _audioData.size()) {
@ -277,7 +277,7 @@ int64_t AudioInjector::injectNextFrame() {
// current injectors don't use codecs, so pack in the unknown codec name // current injectors don't use codecs, so pack in the unknown codec name
QString noCodecForInjectors(""); QString noCodecForInjectors("");
writeStringToStream(noCodecForInjectors, audioPacketStream); writeStringToStream(noCodecForInjectors, audioPacketStream);
// pack stream identifier (a generated UUID) // pack stream identifier (a generated UUID)
audioPacketStream << QUuid::createUuid(); audioPacketStream << QUuid::createUuid();
@ -286,7 +286,7 @@ int64_t AudioInjector::injectNextFrame() {
audioPacketStream << _options.stereo; audioPacketStream << _options.stereo;
// pack the flag for loopback. Now, we don't loopback // pack the flag for loopback. Now, we don't loopback
// and _always_ play locally, so loopbackFlag should be // and _always_ play locally, so loopbackFlag should be
// false always. // false always.
uchar loopbackFlag = (uchar)false; uchar loopbackFlag = (uchar)false;
audioPacketStream << loopbackFlag; audioPacketStream << loopbackFlag;
@ -365,7 +365,7 @@ int64_t AudioInjector::injectNextFrame() {
_currentSendOffset = 0; _currentSendOffset = 0;
} }
} }
// FIXME -- good place to call codec encode here. We need to figure out how to tell the AudioInjector which // FIXME -- good place to call codec encode here. We need to figure out how to tell the AudioInjector which
// codec to use... possible through AbstractAudioInterface. // codec to use... possible through AbstractAudioInterface.
QByteArray encodedAudio = decodedAudio; QByteArray encodedAudio = decodedAudio;
_currentPacket->write(encodedAudio.data(), encodedAudio.size()); _currentPacket->write(encodedAudio.data(), encodedAudio.size());
@ -407,7 +407,7 @@ int64_t AudioInjector::injectNextFrame() {
} }
int64_t playNextFrameAt = ++_nextFrame * AudioConstants::NETWORK_FRAME_USECS; int64_t playNextFrameAt = ++_nextFrame * AudioConstants::NETWORK_FRAME_USECS;
return std::max(INT64_C(0), playNextFrameAt - currentTime); return std::max(INT64_C(0), playNextFrameAt - currentTime);
} }
@ -491,7 +491,7 @@ AudioInjector* AudioInjector::playSound(const QByteArray& buffer, const AudioInj
// we always inject locally, except when there is no localInterface // we always inject locally, except when there is no localInterface
injector->injectLocally(); injector->injectLocally();
// if localOnly, we are done, just return injector. // if localOnly, we are done, just return injector.
if (!options.localOnly) { if (!options.localOnly) {

View file

@ -1,7 +1,7 @@
set(TARGET_NAME controllers) set(TARGET_NAME controllers)
# set a default root dir for each of our optional externals if it was not passed # set a default root dir for each of our optional externals if it was not passed
setup_hifi_library(Script) setup_hifi_library(Script Qml)
# use setup_hifi_library macro to setup our project and link appropriate Qt modules # use setup_hifi_library macro to setup our project and link appropriate Qt modules
link_hifi_libraries(shared) link_hifi_libraries(shared)
@ -11,4 +11,3 @@ GroupSources("src/controllers")
add_dependency_external_projects(glm) add_dependency_external_projects(glm)
find_package(GLM REQUIRED) find_package(GLM REQUIRED)
target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS}) target_include_directories(${TARGET_NAME} PUBLIC ${GLM_INCLUDE_DIRS})

View file

@ -7,4 +7,6 @@ target_opengl()
GroupSources("src/display-plugins") GroupSources("src/display-plugins")
target_oglplus() if (NOT ANDROID)
target_oglplus()
endif ()

View file

@ -2,6 +2,9 @@ set(TARGET_NAME gl)
setup_hifi_library(OpenGL Qml Quick) setup_hifi_library(OpenGL Qml Quick)
link_hifi_libraries(shared) link_hifi_libraries(shared)
target_glew()
target_opengl() target_opengl()
target_oglplus()
if (NOT ANDROID)
target_glew()
target_oglplus()
endif ()

View file

@ -3,5 +3,8 @@ setup_hifi_library()
link_hifi_libraries(shared gl gpu) link_hifi_libraries(shared gl gpu)
GroupSources("src") GroupSources("src")
target_glew() target_opengl()
target_opengl()
if (NOT ANDROID)
target_glew()
endif ()

View file

@ -1,5 +1,5 @@
set(TARGET_NAME gpu) set(TARGET_NAME gpu)
AUTOSCRIBE_SHADER_LIB(gpu) autoscribe_shader_lib(gpu)
setup_hifi_library() setup_hifi_library()
link_hifi_libraries(shared) link_hifi_libraries(shared)

View file

@ -56,7 +56,7 @@ JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, co
updateReciever(updateReceiver), updateReciever(updateReceiver),
updateSlot(updateSlot) updateSlot(updateSlot)
{ {
} }
QJsonObject AccountManager::dataObjectFromResponse(QNetworkReply &requestReply) { QJsonObject AccountManager::dataObjectFromResponse(QNetworkReply &requestReply) {
@ -85,7 +85,7 @@ AccountManager::AccountManager(UserAgentGetter userAgentGetter) :
qRegisterMetaType<QNetworkAccessManager::Operation>("QNetworkAccessManager::Operation"); qRegisterMetaType<QNetworkAccessManager::Operation>("QNetworkAccessManager::Operation");
qRegisterMetaType<JSONCallbackParameters>("JSONCallbackParameters"); qRegisterMetaType<JSONCallbackParameters>("JSONCallbackParameters");
qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*"); qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*");
qRegisterMetaType<AccountManagerAuth::Type>(); qRegisterMetaType<AccountManagerAuth::Type>();
@ -143,7 +143,7 @@ void AccountManager::setAuthURL(const QUrl& authURL) {
_authURL = authURL; _authURL = authURL;
qCDebug(networking) << "AccountManager URL for authenticated requests has been changed to" << qPrintable(_authURL.toString()); qCDebug(networking) << "AccountManager URL for authenticated requests has been changed to" << qPrintable(_authURL.toString());
// check if there are existing access tokens to load from settings // check if there are existing access tokens to load from settings
QFile accountsFile { accountFilePath() }; QFile accountsFile { accountFilePath() };
bool loadedMap = false; bool loadedMap = false;
@ -434,9 +434,9 @@ void AccountManager::removeAccountFromFile() {
} }
bool AccountManager::hasValidAccessToken() { bool AccountManager::hasValidAccessToken() {
if (_accountInfo.getAccessToken().token.isEmpty() || _accountInfo.getAccessToken().isExpired()) { if (_accountInfo.getAccessToken().token.isEmpty() || _accountInfo.getAccessToken().isExpired()) {
if (VERBOSE_HTTP_REQUEST_DEBUGGING) { if (VERBOSE_HTTP_REQUEST_DEBUGGING) {
qCDebug(networking) << "An access token is required for requests to" << qPrintable(_authURL.toString()); qCDebug(networking) << "An access token is required for requests to" << qPrintable(_authURL.toString());
} }
@ -468,7 +468,7 @@ void AccountManager::setAccessTokenForCurrentAuthURL(const QString& accessToken)
} else if (!_accountInfo.getAccessToken().token.isEmpty()) { } else if (!_accountInfo.getAccessToken().token.isEmpty()) {
qCDebug(networking) << "Clearing AccountManager OAuth token."; qCDebug(networking) << "Clearing AccountManager OAuth token.";
} }
_accountInfo.setAccessToken(newOAuthToken); _accountInfo.setAccessToken(newOAuthToken);
persistAccountToFile(); persistAccountToFile();
@ -553,7 +553,7 @@ void AccountManager::requestAccessTokenFinished() {
_accountInfo.setAccessTokenFromJSON(rootObject); _accountInfo.setAccessTokenFromJSON(rootObject);
emit loginComplete(rootURL); emit loginComplete(rootURL);
persistAccountToFile(); persistAccountToFile();
requestProfile(); requestProfile();
@ -576,7 +576,7 @@ void AccountManager::requestProfile() {
QUrl profileURL = _authURL; QUrl profileURL = _authURL;
profileURL.setPath("/api/v1/user/profile"); profileURL.setPath("/api/v1/user/profile");
QNetworkRequest profileRequest(profileURL); QNetworkRequest profileRequest(profileURL);
profileRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter()); profileRequest.setHeader(QNetworkRequest::UserAgentHeader, _userAgentGetter());
profileRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, _accountInfo.getAccessToken().authorizationHeaderValue()); profileRequest.setRawHeader(ACCESS_TOKEN_AUTHORIZATION_HEADER, _accountInfo.getAccessToken().authorizationHeaderValue());
@ -602,7 +602,7 @@ void AccountManager::requestProfileFinished() {
// store the whole profile into the local settings // store the whole profile into the local settings
persistAccountToFile(); persistAccountToFile();
} else { } else {
// TODO: error handling // TODO: error handling
qCDebug(networking) << "Error in response for profile"; qCDebug(networking) << "Error in response for profile";
@ -658,14 +658,14 @@ void AccountManager::generateNewKeypair(bool isUserKeypair, const QUuid& domainI
connect(generateThread, &QThread::finished, generateThread, &QThread::deleteLater); connect(generateThread, &QThread::finished, generateThread, &QThread::deleteLater);
keypairGenerator->moveToThread(generateThread); keypairGenerator->moveToThread(generateThread);
qCDebug(networking) << "Starting worker thread to generate 2048-bit RSA keypair."; qCDebug(networking) << "Starting worker thread to generate 2048-bit RSA keypair.";
generateThread->start(); generateThread->start();
} }
} }
void AccountManager::processGeneratedKeypair() { void AccountManager::processGeneratedKeypair() {
qCDebug(networking) << "Generated 2048-bit RSA keypair. Uploading public key now."; qCDebug(networking) << "Generated 2048-bit RSA keypair. Uploading public key now.";
RSAKeypairGenerator* keypairGenerator = qobject_cast<RSAKeypairGenerator*>(sender()); RSAKeypairGenerator* keypairGenerator = qobject_cast<RSAKeypairGenerator*>(sender());
@ -716,7 +716,7 @@ void AccountManager::processGeneratedKeypair() {
sendRequest(uploadPath, AccountManagerAuth::Optional, QNetworkAccessManager::PutOperation, sendRequest(uploadPath, AccountManagerAuth::Optional, QNetworkAccessManager::PutOperation,
callbackParameters, QByteArray(), requestMultiPart); callbackParameters, QByteArray(), requestMultiPart);
keypairGenerator->deleteLater(); keypairGenerator->deleteLater();
} else { } else {
qCWarning(networking) << "Expected processGeneratedKeypair to be called by a live RSAKeypairGenerator" qCWarning(networking) << "Expected processGeneratedKeypair to be called by a live RSAKeypairGenerator"

View file

@ -32,25 +32,25 @@ PacketQueue::PacketPointer PacketQueue::takePacket() {
if (isEmpty()) { if (isEmpty()) {
return PacketPointer(); return PacketPointer();
} }
// Find next non empty channel // Find next non empty channel
if (_channels[nextIndex()].empty()) { if (_channels[nextIndex()].empty()) {
nextIndex(); nextIndex();
} }
auto& channel = _channels[_currentIndex]; auto& channel = _channels[_currentIndex];
Q_ASSERT(!channel.empty()); Q_ASSERT(!channel.empty());
// Take front packet // Take front packet
auto packet = std::move(channel.front()); auto packet = std::move(channel.front());
channel.pop_front(); channel.pop_front();
// Remove now empty channel (Don't remove the main channel) // Remove now empty channel (Don't remove the main channel)
if (channel.empty() && _currentIndex != 0) { if (channel.empty() && _currentIndex != 0) {
channel.swap(_channels.back()); channel.swap(_channels.back());
_channels.pop_back(); _channels.pop_back();
--_currentIndex; --_currentIndex;
} }
return packet; return packet;
} }
@ -68,7 +68,7 @@ void PacketQueue::queuePacketList(PacketListPointer packetList) {
if (packetList->isOrdered()) { if (packetList->isOrdered()) {
packetList->preparePackets(getNextMessageNumber()); packetList->preparePackets(getNextMessageNumber());
} }
LockGuard locker(_packetsLock); LockGuard locker(_packetsLock);
_channels.push_back(std::move(packetList->_packets)); _channels.push_back(std::move(packetList->_packets));
} }

View file

@ -11,6 +11,10 @@
#include "Socket.h" #include "Socket.h"
#ifdef Q_OS_ANDROID
#include <sys/socket.h>
#endif
#include <QtCore/QThread> #include <QtCore/QThread>
#include <LogHandler.h> #include <LogHandler.h>
@ -30,10 +34,10 @@ Socket::Socket(QObject* parent) :
_synTimer(new QTimer(this)) _synTimer(new QTimer(this))
{ {
connect(&_udpSocket, &QUdpSocket::readyRead, this, &Socket::readPendingDatagrams); connect(&_udpSocket, &QUdpSocket::readyRead, this, &Socket::readPendingDatagrams);
// make sure our synchronization method is called every SYN interval // make sure our synchronization method is called every SYN interval
connect(_synTimer, &QTimer::timeout, this, &Socket::rateControlSync); connect(_synTimer, &QTimer::timeout, this, &Socket::rateControlSync);
// start our timer for the synchronization time interval // start our timer for the synchronization time interval
_synTimer->start(_synInterval); _synTimer->start(_synInterval);
@ -60,7 +64,7 @@ void Socket::bind(const QHostAddress& address, quint16 port) {
void Socket::rebind() { void Socket::rebind() {
quint16 oldPort = _udpSocket.localPort(); quint16 oldPort = _udpSocket.localPort();
_udpSocket.close(); _udpSocket.close();
bind(QHostAddress::AnyIPv4, oldPort); bind(QHostAddress::AnyIPv4, oldPort);
} }
@ -69,26 +73,26 @@ void Socket::setSystemBufferSizes() {
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
QAbstractSocket::SocketOption bufferOpt; QAbstractSocket::SocketOption bufferOpt;
QString bufferTypeString; QString bufferTypeString;
int numBytes = 0; int numBytes = 0;
if (i == 0) { if (i == 0) {
bufferOpt = QAbstractSocket::SendBufferSizeSocketOption; bufferOpt = QAbstractSocket::SendBufferSizeSocketOption;
numBytes = udt::UDP_SEND_BUFFER_SIZE_BYTES; numBytes = udt::UDP_SEND_BUFFER_SIZE_BYTES;
bufferTypeString = "send"; bufferTypeString = "send";
} else { } else {
bufferOpt = QAbstractSocket::ReceiveBufferSizeSocketOption; bufferOpt = QAbstractSocket::ReceiveBufferSizeSocketOption;
numBytes = udt::UDP_RECEIVE_BUFFER_SIZE_BYTES; numBytes = udt::UDP_RECEIVE_BUFFER_SIZE_BYTES;
bufferTypeString = "receive"; bufferTypeString = "receive";
} }
int oldBufferSize = _udpSocket.socketOption(bufferOpt).toInt(); int oldBufferSize = _udpSocket.socketOption(bufferOpt).toInt();
if (oldBufferSize < numBytes) { if (oldBufferSize < numBytes) {
_udpSocket.setSocketOption(bufferOpt, QVariant(numBytes)); _udpSocket.setSocketOption(bufferOpt, QVariant(numBytes));
int newBufferSize = _udpSocket.socketOption(bufferOpt).toInt(); int newBufferSize = _udpSocket.socketOption(bufferOpt).toInt();
qCDebug(networking) << "Changed socket" << bufferTypeString << "buffer size from" << oldBufferSize << "to" qCDebug(networking) << "Changed socket" << bufferTypeString << "buffer size from" << oldBufferSize << "to"
<< newBufferSize << "bytes"; << newBufferSize << "bytes";
} else { } else {
@ -101,29 +105,29 @@ void Socket::setSystemBufferSizes() {
qint64 Socket::writeBasePacket(const udt::BasePacket& packet, const HifiSockAddr &sockAddr) { qint64 Socket::writeBasePacket(const udt::BasePacket& packet, const HifiSockAddr &sockAddr) {
// Since this is a base packet we have no way to know if this is reliable or not - we just fire it off // Since this is a base packet we have no way to know if this is reliable or not - we just fire it off
// this should not be called with an instance of Packet // this should not be called with an instance of Packet
Q_ASSERT_X(!dynamic_cast<const Packet*>(&packet), Q_ASSERT_X(!dynamic_cast<const Packet*>(&packet),
"Socket::writeBasePacket", "Cannot send a Packet/NLPacket via writeBasePacket"); "Socket::writeBasePacket", "Cannot send a Packet/NLPacket via writeBasePacket");
return writeDatagram(packet.getData(), packet.getDataSize(), sockAddr); return writeDatagram(packet.getData(), packet.getDataSize(), sockAddr);
} }
qint64 Socket::writePacket(const Packet& packet, const HifiSockAddr& sockAddr) { qint64 Socket::writePacket(const Packet& packet, const HifiSockAddr& sockAddr) {
Q_ASSERT_X(!packet.isReliable(), "Socket::writePacket", "Cannot send a reliable packet unreliably"); Q_ASSERT_X(!packet.isReliable(), "Socket::writePacket", "Cannot send a reliable packet unreliably");
// write the correct sequence number to the Packet here // write the correct sequence number to the Packet here
packet.writeSequenceNumber(++_unreliableSequenceNumbers[sockAddr]); packet.writeSequenceNumber(++_unreliableSequenceNumbers[sockAddr]);
return writeDatagram(packet.getData(), packet.getDataSize(), sockAddr); return writeDatagram(packet.getData(), packet.getDataSize(), sockAddr);
} }
qint64 Socket::writePacket(std::unique_ptr<Packet> packet, const HifiSockAddr& sockAddr) { qint64 Socket::writePacket(std::unique_ptr<Packet> packet, const HifiSockAddr& sockAddr) {
if (packet->isReliable()) { if (packet->isReliable()) {
// hand this packet off to writeReliablePacket // hand this packet off to writeReliablePacket
// because Qt can't invoke with the unique_ptr we have to release it here and re-construct in writeReliablePacket // because Qt can't invoke with the unique_ptr we have to release it here and re-construct in writeReliablePacket
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "writeReliablePacket", Qt::QueuedConnection, QMetaObject::invokeMethod(this, "writeReliablePacket", Qt::QueuedConnection,
Q_ARG(Packet*, packet.release()), Q_ARG(Packet*, packet.release()),
@ -131,10 +135,10 @@ qint64 Socket::writePacket(std::unique_ptr<Packet> packet, const HifiSockAddr& s
} else { } else {
writeReliablePacket(packet.release(), sockAddr); writeReliablePacket(packet.release(), sockAddr);
} }
return 0; return 0;
} }
return writePacket(*packet, sockAddr); return writePacket(*packet, sockAddr);
} }
@ -142,7 +146,7 @@ qint64 Socket::writePacketList(std::unique_ptr<PacketList> packetList, const Hif
if (packetList->isReliable()) { if (packetList->isReliable()) {
// hand this packetList off to writeReliablePacketList // hand this packetList off to writeReliablePacketList
// because Qt can't invoke with the unique_ptr we have to release it here and re-construct in writeReliablePacketList // because Qt can't invoke with the unique_ptr we have to release it here and re-construct in writeReliablePacketList
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
auto ptr = packetList.release(); auto ptr = packetList.release();
QMetaObject::invokeMethod(this, "writeReliablePacketList", Qt::AutoConnection, QMetaObject::invokeMethod(this, "writeReliablePacketList", Qt::AutoConnection,
@ -151,7 +155,7 @@ qint64 Socket::writePacketList(std::unique_ptr<PacketList> packetList, const Hif
} else { } else {
writeReliablePacketList(packetList.release(), sockAddr); writeReliablePacketList(packetList.release(), sockAddr);
} }
return 0; return 0;
} }
@ -177,18 +181,18 @@ qint64 Socket::writeDatagram(const char* data, qint64 size, const HifiSockAddr&
} }
qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& sockAddr) { qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& sockAddr) {
qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort()); qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort());
if (bytesWritten < 0) { if (bytesWritten < 0) {
// when saturating a link this isn't an uncommon message - suppress it so it doesn't bomb the debug // when saturating a link this isn't an uncommon message - suppress it so it doesn't bomb the debug
static const QString WRITE_ERROR_REGEX = "Socket::writeDatagram QAbstractSocket::NetworkError - Unable to send a message"; static const QString WRITE_ERROR_REGEX = "Socket::writeDatagram QAbstractSocket::NetworkError - Unable to send a message";
static QString repeatedMessage static QString repeatedMessage
= LogHandler::getInstance().addRepeatedMessageRegex(WRITE_ERROR_REGEX); = LogHandler::getInstance().addRepeatedMessageRegex(WRITE_ERROR_REGEX);
qCDebug(networking) << "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString()); qCDebug(networking) << "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString());
} }
return bytesWritten; return bytesWritten;
} }
@ -199,17 +203,17 @@ Connection& Socket::findOrCreateConnection(const HifiSockAddr& sockAddr) {
auto congestionControl = _ccFactory->create(); auto congestionControl = _ccFactory->create();
congestionControl->setMaxBandwidth(_maxBandwidth); congestionControl->setMaxBandwidth(_maxBandwidth);
auto connection = std::unique_ptr<Connection>(new Connection(this, sockAddr, std::move(congestionControl))); auto connection = std::unique_ptr<Connection>(new Connection(this, sockAddr, std::move(congestionControl)));
// we queue the connection to cleanup connection in case it asks for it during its own rate control sync // we queue the connection to cleanup connection in case it asks for it during its own rate control sync
QObject::connect(connection.get(), &Connection::connectionInactive, this, &Socket::cleanupConnection); QObject::connect(connection.get(), &Connection::connectionInactive, this, &Socket::cleanupConnection);
#ifdef UDT_CONNECTION_DEBUG #ifdef UDT_CONNECTION_DEBUG
qCDebug(networking) << "Creating new connection to" << sockAddr; qCDebug(networking) << "Creating new connection to" << sockAddr;
#endif #endif
it = _connectionsHash.insert(it, std::make_pair(sockAddr, std::move(connection))); it = _connectionsHash.insert(it, std::make_pair(sockAddr, std::move(connection)));
} }
return *it->second; return *it->second;
} }
@ -228,7 +232,7 @@ void Socket::clearConnections() {
void Socket::cleanupConnection(HifiSockAddr sockAddr) { void Socket::cleanupConnection(HifiSockAddr sockAddr) {
auto numErased = _connectionsHash.erase(sockAddr); auto numErased = _connectionsHash.erase(sockAddr);
if (numErased > 0) { if (numErased > 0) {
#ifdef UDT_CONNECTION_DEBUG #ifdef UDT_CONNECTION_DEBUG
qCDebug(networking) << "Socket::cleanupConnection called for UDT connection to" << sockAddr; qCDebug(networking) << "Socket::cleanupConnection called for UDT connection to" << sockAddr;
@ -253,10 +257,10 @@ void Socket::readPendingDatagrams() {
while ((packetSizeWithHeader = _udpSocket.pendingDatagramSize()) != -1) { while ((packetSizeWithHeader = _udpSocket.pendingDatagramSize()) != -1) {
// setup a HifiSockAddr to read into // setup a HifiSockAddr to read into
HifiSockAddr senderSockAddr; HifiSockAddr senderSockAddr;
// setup a buffer to read the packet into // setup a buffer to read the packet into
auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]); auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]);
// pull the datagram // pull the datagram
auto sizeRead = _udpSocket.readDatagram(buffer.get(), packetSizeWithHeader, auto sizeRead = _udpSocket.readDatagram(buffer.get(), packetSizeWithHeader,
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
@ -266,34 +270,34 @@ void Socket::readPendingDatagrams() {
// on windows even if there's not a packet available) // on windows even if there's not a packet available)
continue; continue;
} }
auto it = _unfilteredHandlers.find(senderSockAddr); auto it = _unfilteredHandlers.find(senderSockAddr);
if (it != _unfilteredHandlers.end()) { if (it != _unfilteredHandlers.end()) {
// we have a registered unfiltered handler for this HifiSockAddr - call that and return // we have a registered unfiltered handler for this HifiSockAddr - call that and return
if (it->second) { if (it->second) {
auto basePacket = BasePacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); auto basePacket = BasePacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr);
it->second(std::move(basePacket)); it->second(std::move(basePacket));
} }
continue; continue;
} }
// check if this was a control packet or a data packet // check if this was a control packet or a data packet
bool isControlPacket = *reinterpret_cast<uint32_t*>(buffer.get()) & CONTROL_BIT_MASK; bool isControlPacket = *reinterpret_cast<uint32_t*>(buffer.get()) & CONTROL_BIT_MASK;
if (isControlPacket) { if (isControlPacket) {
// setup a control packet from the data we just read // setup a control packet from the data we just read
auto controlPacket = ControlPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); auto controlPacket = ControlPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr);
// move this control packet to the matching connection // move this control packet to the matching connection
auto& connection = findOrCreateConnection(senderSockAddr); auto& connection = findOrCreateConnection(senderSockAddr);
connection.processControl(move(controlPacket)); connection.processControl(move(controlPacket));
} else { } else {
// setup a Packet from the data we just read // setup a Packet from the data we just read
auto packet = Packet::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); auto packet = Packet::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr);
// call our verification operator to see if this packet is verified // call our verification operator to see if this packet is verified
if (!_packetFilterOperator || _packetFilterOperator(*packet)) { if (!_packetFilterOperator || _packetFilterOperator(*packet)) {
if (packet->isReliable()) { if (packet->isReliable()) {
@ -328,27 +332,27 @@ void Socket::connectToSendSignal(const HifiSockAddr& destinationAddr, QObject* r
} }
void Socket::rateControlSync() { void Socket::rateControlSync() {
// enumerate our list of connections and ask each of them to send off periodic ACK packet for rate control // enumerate our list of connections and ask each of them to send off periodic ACK packet for rate control
// the way we do this is a little funny looking - we need to avoid the case where we call sync and // the way we do this is a little funny looking - we need to avoid the case where we call sync and
// (because of our Qt direct connection to the Connection's signal that it has been deactivated) // (because of our Qt direct connection to the Connection's signal that it has been deactivated)
// an iterator on _connectionsHash would be invalidated by our own call to cleanupConnection // an iterator on _connectionsHash would be invalidated by our own call to cleanupConnection
// collect the sockets for all connections in a vector // collect the sockets for all connections in a vector
std::vector<HifiSockAddr> sockAddrVector; std::vector<HifiSockAddr> sockAddrVector;
sockAddrVector.reserve(_connectionsHash.size()); sockAddrVector.reserve(_connectionsHash.size());
for (auto& connection : _connectionsHash) { for (auto& connection : _connectionsHash) {
sockAddrVector.emplace_back(connection.first); sockAddrVector.emplace_back(connection.first);
} }
// enumerate that vector of HifiSockAddr objects // enumerate that vector of HifiSockAddr objects
for (auto& sockAddr : sockAddrVector) { for (auto& sockAddr : sockAddrVector) {
// pull out the respective connection via a quick find on the unordered_map // pull out the respective connection via a quick find on the unordered_map
auto it = _connectionsHash.find(sockAddr); auto it = _connectionsHash.find(sockAddr);
if (it != _connectionsHash.end()) { if (it != _connectionsHash.end()) {
// if the connection is erased while calling sync since we are re-using the iterator that was invalidated // if the connection is erased while calling sync since we are re-using the iterator that was invalidated
// we're good to go // we're good to go
@ -356,7 +360,7 @@ void Socket::rateControlSync() {
connection->sync(); connection->sync();
} }
} }
if (_synTimer->interval() != _synInterval) { if (_synTimer->interval() != _synInterval) {
// if the _synTimer interval doesn't match the current _synInterval (changes when the CC factory is changed) // if the _synTimer interval doesn't match the current _synInterval (changes when the CC factory is changed)
// then restart it now with the right interval // then restart it now with the right interval
@ -367,7 +371,7 @@ void Socket::rateControlSync() {
void Socket::setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory) { void Socket::setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory) {
// swap the current unique_ptr for the new factory // swap the current unique_ptr for the new factory
_ccFactory.swap(ccFactory); _ccFactory.swap(ccFactory);
// update the _synInterval to the value from the factory // update the _synInterval to the value from the factory
_synInterval = _ccFactory->synInterval(); _synInterval = _ccFactory->synInterval();
} }
@ -402,10 +406,10 @@ Socket::StatsVector Socket::sampleStatsForAllConnections() {
} }
std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() { std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() {
std::vector<HifiSockAddr> addr; std::vector<HifiSockAddr> addr;
addr.reserve(_connectionsHash.size()); addr.reserve(_connectionsHash.size());
for (const auto& connectionPair : _connectionsHash) { for (const auto& connectionPair : _connectionsHash) {
addr.push_back(connectionPair.first); addr.push_back(connectionPair.first);
} }

View file

@ -187,7 +187,7 @@ btTriangleIndexVertexArray* createStaticMeshArray(const ShapeInfo& info) {
btIndexedMesh mesh; btIndexedMesh mesh;
const int32_t VERTICES_PER_TRIANGLE = 3; const int32_t VERTICES_PER_TRIANGLE = 3;
mesh.m_numTriangles = numIndices / VERTICES_PER_TRIANGLE; mesh.m_numTriangles = numIndices / VERTICES_PER_TRIANGLE;
if (numIndices < INT16_MAX) { if (numIndices < std::numeric_limits<int16_t>::max()) {
// small number of points so we can use 16-bit indices // small number of points so we can use 16-bit indices
mesh.m_triangleIndexBase = new unsigned char[sizeof(int16_t) * (size_t)numIndices]; mesh.m_triangleIndexBase = new unsigned char[sizeof(int16_t) * (size_t)numIndices];
mesh.m_indexType = PHY_SHORT; mesh.m_indexType = PHY_SHORT;
@ -211,7 +211,7 @@ btTriangleIndexVertexArray* createStaticMeshArray(const ShapeInfo& info) {
vertexData[j + 1] = point.y; vertexData[j + 1] = point.y;
vertexData[j + 2] = point.z; vertexData[j + 2] = point.z;
} }
if (numIndices < INT16_MAX) { if (numIndices < std::numeric_limits<int16_t>::max()) {
int16_t* indices = static_cast<int16_t*>((void*)(mesh.m_triangleIndexBase)); int16_t* indices = static_cast<int16_t*>((void*)(mesh.m_triangleIndexBase));
for (int32_t i = 0; i < numIndices; ++i) { for (int32_t i = 0; i < numIndices; ++i) {
indices[i] = (int16_t)triangleIndices[i]; indices[i] = (int16_t)triangleIndices[i];

View file

@ -1,4 +1,4 @@
set(TARGET_NAME plugins) set(TARGET_NAME plugins)
setup_hifi_library(OpenGL) setup_hifi_library(OpenGL)
link_hifi_libraries(shared) link_hifi_libraries(shared networking)
include_hifi_library_headers(gpu) include_hifi_library_headers(gpu)

View file

@ -115,10 +115,42 @@ const LoaderList& getLoadedPlugins() {
PluginManager::PluginManager() { PluginManager::PluginManager() {
} }
extern CodecPluginList getCodecPlugins();
const CodecPluginList& PluginManager::getCodecPlugins() {
static CodecPluginList codecPlugins;
static std::once_flag once;
std::call_once(once, [&] {
//codecPlugins = ::getCodecPlugins();
// Now grab the dynamic plugins
for (auto loader : getLoadedPlugins()) {
CodecProvider* codecProvider = qobject_cast<CodecProvider*>(loader->instance());
if (codecProvider) {
for (auto codecPlugin : codecProvider->getCodecPlugins()) {
if (codecPlugin->isSupported()) {
codecPlugins.push_back(codecPlugin);
}
}
}
}
for (auto plugin : codecPlugins) {
plugin->setContainer(_container);
plugin->init();
qDebug() << "init codec:" << plugin->getName();
}
});
return codecPlugins;
}
#ifndef Q_OS_ANDROID
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
extern DisplayPluginList getDisplayPlugins(); extern DisplayPluginList getDisplayPlugins();
extern InputPluginList getInputPlugins(); extern InputPluginList getInputPlugins();
extern CodecPluginList getCodecPlugins();
extern void saveInputPluginSettings(const InputPluginList& plugins); extern void saveInputPluginSettings(const InputPluginList& plugins);
static DisplayPluginList displayPlugins; static DisplayPluginList displayPlugins;
@ -137,6 +169,7 @@ const DisplayPluginList& PluginManager::getDisplayPlugins() {
// Grab the built in plugins // Grab the built in plugins
displayPlugins = ::getDisplayPlugins(); displayPlugins = ::getDisplayPlugins();
// Now grab the dynamic plugins // Now grab the dynamic plugins
for (auto loader : getLoadedPlugins()) { for (auto loader : getLoadedPlugins()) {
DisplayProvider* displayProvider = qobject_cast<DisplayProvider*>(loader->instance()); DisplayProvider* displayProvider = qobject_cast<DisplayProvider*>(loader->instance());
@ -204,35 +237,6 @@ const InputPluginList& PluginManager::getInputPlugins() {
return inputPlugins; return inputPlugins;
} }
const CodecPluginList& PluginManager::getCodecPlugins() {
static CodecPluginList codecPlugins;
static std::once_flag once;
std::call_once(once, [&] {
//codecPlugins = ::getCodecPlugins();
// Now grab the dynamic plugins
for (auto loader : getLoadedPlugins()) {
CodecProvider* codecProvider = qobject_cast<CodecProvider*>(loader->instance());
if (codecProvider) {
for (auto codecPlugin : codecProvider->getCodecPlugins()) {
if (codecPlugin->isSupported()) {
codecPlugins.push_back(codecPlugin);
}
}
}
}
for (auto plugin : codecPlugins) {
plugin->setContainer(_container);
plugin->init();
qDebug() << "init codec:" << plugin->getName();
}
});
return codecPlugins;
}
void PluginManager::setPreferredDisplayPlugins(const QStringList& displays) { void PluginManager::setPreferredDisplayPlugins(const QStringList& displays) {
preferredDisplayPlugins = displays; preferredDisplayPlugins = displays;
} }
@ -270,3 +274,5 @@ void PluginManager::disableInputs(const QStringList& inputs) {
void PluginManager::saveSettings() { void PluginManager::saveSettings() {
saveInputPluginSettings(getInputPlugins()); saveInputPluginSettings(getInputPlugins());
} }
#endif

View file

@ -13,7 +13,12 @@
#include "Forward.h" #include "Forward.h"
#include <functional> #include <functional>
#ifdef Q_OS_WIN
#include <stdint.h> #include <stdint.h>
#else
#include <limits>
#endif
#include <QtCore/QObject> #include <QtCore/QObject>
@ -22,7 +27,13 @@ namespace recording {
struct FrameHeader { struct FrameHeader {
using Time = uint32_t; using Time = uint32_t;
// until we use a version of visual studio that has constexpr support, we can't use numeric_limits at compile time
#ifdef Q_OS_WIN
static const Time INVALID_TIME = UINT32_MAX; static const Time INVALID_TIME = UINT32_MAX;
#else
static const Time INVALID_TIME = std::numeric_limits<uint32_t>::max();
#endif
static const FrameType TYPE_INVALID = 0xFFFF; static const FrameType TYPE_INVALID = 0xFFFF;
static const FrameType TYPE_HEADER = 0x0; static const FrameType TYPE_HEADER = 0x0;
@ -51,7 +62,7 @@ public:
QByteArray data; QByteArray data;
Frame() {} Frame() {}
Frame(FrameType type, float timeOffset, const QByteArray& data) Frame(FrameType type, float timeOffset, const QByteArray& data)
: FrameHeader(type, timeOffset), data(data) { } : FrameHeader(type, timeOffset), data(data) { }
static FrameType registerFrameType(const QString& frameTypeName); static FrameType registerFrameType(const QString& frameTypeName);

View file

@ -3,7 +3,9 @@ AUTOSCRIBE_SHADER_LIB(gpu model render)
# pull in the resources.qrc file # pull in the resources.qrc file
qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc") qt5_add_resources(QT_RESOURCES_FILE "${CMAKE_CURRENT_SOURCE_DIR}/res/fonts/fonts.qrc")
setup_hifi_library(Widgets OpenGL Network Qml Quick Script) setup_hifi_library(Widgets OpenGL Network Qml Quick Script)
link_hifi_libraries(shared gpu model model-networking render animation fbx) link_hifi_libraries(shared gpu model model-networking render animation fbx entities)
target_nsight() if (NOT ANDROID)
target_oglplus() target_nsight()
target_oglplus()
endif ()

View file

@ -1,7 +1,8 @@
set(TARGET_NAME render) set(TARGET_NAME render)
AUTOSCRIBE_SHADER_LIB(gpu model) AUTOSCRIBE_SHADER_LIB(gpu model)
setup_hifi_library() setup_hifi_library()
link_hifi_libraries(shared gpu model)
# render needs octree only for getAccuracyAngle(float, int)
link_hifi_libraries(shared gpu model octree)
target_nsight() target_nsight()

View file

@ -3,13 +3,17 @@ setup_hifi_library(Gui Network Script ScriptTools WebSockets Widgets)
target_zlib() target_zlib()
add_dependency_external_projects(quazip) if (NOT ANDROID)
find_package(QuaZip REQUIRED)
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${QUAZIP_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${QUAZIP_LIBRARIES})
if (WIN32) add_dependency_external_projects(quazip)
find_package(QuaZip REQUIRED)
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${QUAZIP_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${QUAZIP_LIBRARIES})
if (WIN32)
add_paths_to_fixup_libs(${QUAZIP_DLL_PATH}) add_paths_to_fixup_libs(${QUAZIP_DLL_PATH})
endif ()
endif () endif ()
link_hifi_libraries(shared networking octree gpu ui procedural model model-networking recording avatars fbx entities controllers animation audio physics) link_hifi_libraries(shared networking octree gpu ui procedural model model-networking recording avatars fbx entities controllers animation audio physics)

View file

@ -28,7 +28,7 @@ namespace bilateral {
case Side::Right: case Side::Right:
return 0x02; return 0x02;
} }
return UINT8_MAX; return std::numeric_limits<uint8_t>::max();
} }
inline uint8_t index(Side side) { inline uint8_t index(Side side) {
@ -38,7 +38,7 @@ namespace bilateral {
case Side::Right: case Side::Right:
return 1; return 1;
} }
return UINT8_MAX; return std::numeric_limits<uint8_t>::max();
} }
template <typename F> template <typename F>

View file

@ -11,7 +11,7 @@ file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT
list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles")
# client-side plugins # client-side plugins
if (NOT SERVER_ONLY) if (NOT SERVER_ONLY AND NOT ANDROID)
set(DIR "oculus") set(DIR "oculus")
add_subdirectory(${DIR}) add_subdirectory(${DIR})
set(DIR "hifiSdl2") set(DIR "hifiSdl2")

View file

@ -6,7 +6,9 @@
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html # See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
# #
set(TARGET_NAME hifiSixense) if (NOT ANDROID)
setup_hifi_plugin(Script Qml Widgets) set(TARGET_NAME hifiSixense)
link_hifi_libraries(shared controllers ui plugins ui-plugins input-plugins) setup_hifi_plugin(Script Qml Widgets)
target_sixense() link_hifi_libraries(shared controllers ui plugins ui-plugins input-plugins)
target_sixense()
endif ()

View file

@ -1,7 +1,4 @@
# add the tool directories # add the tool directories
add_subdirectory(mtc)
set_target_properties(mtc PROPERTIES FOLDER "Tools")
add_subdirectory(scribe) add_subdirectory(scribe)
set_target_properties(scribe PROPERTIES FOLDER "Tools") set_target_properties(scribe PROPERTIES FOLDER "Tools")

View file

@ -1,4 +0,0 @@
set(TARGET_NAME mtc)
setup_hifi_project()
package_libraries_for_deployment()

View file

@ -1,362 +0,0 @@
//
// main.cpp
// tools/mtc/src
//
// Created by Andrzej Kapolka on 12/31/13.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
#include <iostream>
#include <QFile>
#include <QList>
#include <QRegExp>
#include <QString>
#include <QStringList>
#include <QTextStream>
#include <QtDebug>
using namespace std;
class Class {
public:
QString name;
QStringList bases;
};
class Field {
public:
QString type;
QString name;
};
class Streamable {
public:
Class clazz;
QList<Field> fields;
};
void processInput(QTextStream& in, QList<Streamable>* streamables) {
Class clazz;
Streamable currentStreamable;
QRegExp exp(
"(/\\*.*\\*/)|" // multi-line comments
"(//.*\n)|" // single-line comments
"(\\s*#.*\n)|" // preprocessor definitions
"(\\s*STREAMABLE\\s+)|" // STREAMABLE tag for classes
"(\\s*STREAM\\s+.*;)|" // STREAM tag for fields
"(\\s*class\\s+[^;]+\\{)" // class definition
);
exp.setMinimal(true);
QRegExp classExp("class (\\w+) ?:?([^:]*)\\{");
// read in the entire input and look for matches with our expression
QString all = in.readAll();
for (int off = 0; (off = exp.indexIn(all, off)) != -1; off += exp.matchedLength()) {
QString match = exp.cap().simplified();
if (match.startsWith("/*") || match.startsWith("//") || match.startsWith('#')) {
continue; // comment, preprocessor definition
}
if (match.startsWith("STREAMABLE")) {
if (clazz.name.isEmpty()) {
cerr << "Found STREAMABLE marker before class definition." << endl;
continue;
}
if (!currentStreamable.clazz.name.isEmpty()) {
streamables->append(currentStreamable);
}
currentStreamable.clazz = clazz;
currentStreamable.fields.clear();
} else if (match.startsWith("STREAM")) {
match.chop(1); // get rid of the semicolon
match = match.mid(match.indexOf(' ') + 1).trimmed(); // and STREAM, and any space before it
int index = match.lastIndexOf(' ');
Field field = { match.left(index).simplified(), match.mid(index + 1) };
currentStreamable.fields.append(field);
} else { // match.startsWith("class")
classExp.exactMatch(match);
clazz.name = classExp.cap(1);
clazz.bases.clear();
foreach (const QString& bstr, classExp.cap(2).split(',')) {
QString base = bstr.trimmed();
if (!base.isEmpty() && base.startsWith("STREAM")) {
clazz.bases.append(base.mid(base.lastIndexOf(' ') + 1));
}
}
}
}
if (!currentStreamable.clazz.name.isEmpty()) {
streamables->append(currentStreamable);
}
}
void generateOutput (QTextStream& out, const QList<Streamable>& streamables) {
foreach (const Streamable& str, streamables) {
const QString& name = str.clazz.name;
out << "const int " << name << "::Type = registerStreamableMetaType<" << name << ">();\n";
out << "const QVector<MetaField>& " << name << "::getMetaFields() {\n";
out << " static QVector<MetaField> metaFields = QVector<MetaField>()";
foreach (const QString& base, str.clazz.bases) {
out << " << " << base << "::getMetaFields()";
}
foreach (const Field& field, str.fields) {
out << "\n << MetaField(\"" << field.name << "\", Bitstream::getTypeStreamer(qMetaTypeId<" <<
field.type << ">()))";
}
out << ";\n";
out << " return metaFields;\n";
out << "}\n";
out << "int " << name << "::getFieldIndex(const QByteArray& name) {\n";
out << " static QHash<QByteArray, int> fieldIndices = createFieldIndices();\n";
out << " return fieldIndices.value(name) - 1;\n";
out << "}\n";
out << "QHash<QByteArray, int> " << name << "::createFieldIndices() {\n";
out << " QHash<QByteArray, int> indices;\n";
out << " int index = 1;\n";
out << " foreach (const MetaField& field, getMetaFields()) {\n";
out << " indices.insert(field.getName(), index++);\n";
out << " }\n";
out << " return indices;\n";
out << "}\n";
out << "void " << name << "::setField(int index, const QVariant& value) {\n";
if (!str.clazz.bases.isEmpty()) {
out << " int nextIndex;\n";
}
foreach (const QString& base, str.clazz.bases) {
out << " if ((nextIndex = index - " << base << "::getMetaFields().size()) < 0) {\n";
out << " " << base << "::setField(index, value);\n";
out << " return;\n";
out << " }\n";
out << " index = nextIndex;\n";
}
if (!str.fields.isEmpty()) {
out << " switch (index) {\n";
for (int i = 0; i < str.fields.size(); i++) {
out << " case " << i << ":\n";
out << " this->" << str.fields.at(i).name << " = value.value<" << str.fields.at(i).type << ">();\n";
out << " break;\n";
}
out << " }\n";
}
out << "}\n";
out << "QVariant " << name << "::getField(int index) const {\n";
if (!str.clazz.bases.isEmpty()) {
out << " int nextIndex;\n";
}
foreach (const QString& base, str.clazz.bases) {
out << " if ((nextIndex = index - " << base << "::getMetaFields().size()) < 0) {\n";
out << " return " << base << "::getField(index);\n";
out << " }\n";
out << " index = nextIndex;\n";
}
if (!str.fields.isEmpty()) {
out << " switch (index) {\n";
for (int i = 0; i < str.fields.size(); i++) {
out << " case " << i << ":\n";
out << " return QVariant::fromValue(this->" << str.fields.at(i).name << ");\n";
}
out << " }\n";
}
out << " return QVariant();\n";
out << "}\n";
out << "Bitstream& operator<<(Bitstream& out, const " << name << "& obj) {\n";
foreach (const QString& base, str.clazz.bases) {
out << " out << static_cast<const " << base << "&>(obj);\n";
}
foreach (const Field& field, str.fields) {
out << " out << obj." << field.name << ";\n";
}
out << " return out;\n";
out << "}\n";
out << "Bitstream& operator>>(Bitstream& in, " << name << "& obj) {\n";
foreach (const QString& base, str.clazz.bases) {
out << " in >> static_cast<" << base << "&>(obj);\n";
}
foreach (const Field& field, str.fields) {
out << " in >> obj." << field.name << ";\n";
}
out << " return in;\n";
out << "}\n";
out << "template<> void Bitstream::writeRawDelta(const " << name << "& value, const " << name << "& reference) {\n";
foreach (const QString& base, str.clazz.bases) {
out << " writeRawDelta(static_cast<const " << base << "&>(value), static_cast<const " <<
base << "&>(reference));\n";
}
foreach (const Field& field, str.fields) {
out << " writeDelta(value." << field.name << ", reference." << field.name << ");\n";
}
out << "}\n";
out << "template<> void Bitstream::readRawDelta(" << name << "& value, const " << name << "& reference) {\n";
foreach (const QString& base, str.clazz.bases) {
out << " readRawDelta(static_cast<" << base << "&>(value), static_cast<const " <<
base << "&>(reference));\n";
}
foreach (const Field& field, str.fields) {
out << " readDelta(value." << field.name << ", reference." << field.name << ");\n";
}
out << "}\n";
out << "template<> QJsonValue JSONWriter::getData(const " << name << "& value) {\n";
out << " QJsonArray array;\n";
foreach (const QString& base, str.clazz.bases) {
out << " foreach (const QJsonValue& element, getData(static_cast<const " << base << "&>(value)).toArray()) {\n";
out << " array.append(element);\n";
out << " }\n";
}
foreach (const Field& field, str.fields) {
out << " array.append(getData(value." << field.name << "));\n";
}
out << " return array;\n";
out << "}\n";
out << "template<> void JSONReader::putData(const QJsonValue& data, " << name << "& value) {\n";
if (!(str.clazz.bases.isEmpty() && str.fields.isEmpty())) {
out << " QJsonArray array = data.toArray(), subarray;\n";
out << " QJsonArray::const_iterator it = array.constBegin();\n";
foreach (const QString& base, str.clazz.bases) {
out << " subarray = QJsonArray();\n";
out << " for (int i = 0; i < " << base << "::getMetaFields().size(); i++) {\n";
out << " subarray.append(*it++);\n";
out << " }\n";
out << " putData(subarray, static_cast<" << base << "&>(value));\n";
}
foreach (const Field& field, str.fields) {
out << " putData(*it++, value." << field.name << ");\n";
}
}
out << "}\n";
out << "bool operator==(const " << name << "& first, const " << name << "& second) {\n";
if (str.clazz.bases.isEmpty() && str.fields.isEmpty()) {
out << " return true";
} else {
out << " return ";
bool first = true;
foreach (const QString& base, str.clazz.bases) {
if (!first) {
out << " &&\n";
out << " ";
}
out << "static_cast<const " << base << "&>(first) == static_cast<const " << base << "&>(second)";
first = false;
}
foreach (const Field& field, str.fields) {
if (!first) {
out << " &&\n";
out << " ";
}
out << "first." << field.name << " == second." << field.name;
first = false;
}
}
out << ";\n";
out << "}\n";
out << "bool operator!=(const " << name << "& first, const " << name << "& second) {\n";
if (str.clazz.bases.isEmpty() && str.fields.isEmpty()) {
out << " return false";
} else {
out << " return ";
bool first = true;
foreach (const QString& base, str.clazz.bases) {
if (!first) {
out << " ||\n";
out << " ";
}
out << "static_cast<const " << base << "&>(first) != static_cast<const " << base << "&>(second)";
first = false;
}
foreach (const Field& field, str.fields) {
if (!first) {
out << " ||\n";
out << " ";
}
out << "first." << field.name << " != second." << field.name;
first = false;
}
}
out << ";\n";
out << "}\n\n";
}
}
int main (int argc, char** argv) {
// process the command line arguments
QStringList inputs;
QString output;
for (int ii = 1; ii < argc; ii++) {
QString arg(argv[ii]);
if (!arg.startsWith('-')) {
inputs.append(arg);
continue;
}
QStringRef name = arg.midRef(1);
if (name == "o") {
if (++ii == argc) {
cerr << "Missing file name argument for -o" << endl;
return 1;
}
output = argv[ii];
} else {
cerr << "Unknown option " << arg.toStdString() << endl;
return 1;
}
}
if (inputs.isEmpty()) {
cerr << "Usage: mtc [OPTION]... input files" << endl;
cerr << "Where options include:" << endl;
cerr << " -o filename: Send output to filename rather than standard output." << endl;
return 0;
}
QList<Streamable> streamables;
foreach (const QString& input, inputs) {
QFile ifile(input);
if (!ifile.open(QIODevice::ReadOnly | QIODevice::Text)) {
cerr << ("Couldn't open " + input + ": " + ifile.errorString()).toStdString() << endl;
continue;
}
QTextStream istream(&ifile);
int oldSize = streamables.size();
processInput(istream, &streamables);
if (streamables.size() == oldSize) {
// no streamables; remove from list
inputs.removeOne(input);
}
}
QFile ofile(output);
if (output.isNull()) {
ofile.open(stdout, QIODevice::WriteOnly | QIODevice::Text);
} else if (!ofile.open(QIODevice::WriteOnly | QIODevice::Text)) {
cerr << ("Couldn't open " + output + ": " + ofile.errorString()).toStdString() << endl;
return 1;
}
QTextStream ostream(&ofile);
ostream << "// generated by mtc\n";
foreach (const QString& input, inputs) {
ostream << "#include \"" << input << "\"\n";
}
generateOutput(ostream, streamables);
return 0;
}