Build gamesdk using pre-built NDKs
(cherry picked from internal d35e90b16f7126427363d49050bac493dadbd03a)
Bug: 120609511
Test: ./gradlew will build gamesdk.zip
Test: From android studio:
Test: Build and run samples/bouncyball
Test: Build and run samples/tuningfork/tftestapp
Test: Build and run samples/cube
Change-Id: I6d5e77d52013e7f23999f312823b4f6d8cb126ef
diff --git a/README b/README
new file mode 100644
index 0000000..32e61bf
--- /dev/null
+++ b/README
@@ -0,0 +1,17 @@
+
+In order to build using prebuild NDK versions, this project must be initialized from a custom repo using:
+mkdir android-games-sdk
+cd android-games-sdk
+Corp -> repo init -u persistent-https://googleplex-android.git.corp.google.com/platform/manifest -b android-games-sdk
+AOSP -> repo init -u https://android.googlesource.com/platform/manifest -b android-games-sdk
+repo sync -c -j8
+
+Then:
+./gradlew gamesdkZip
+will build static and dynamic libraries for several NDK versions.
+
+By default, the gradle script builds target archiveZip, which will use a locally installed SDK/NDK pointed
+to by ANDROID_HOME (and ANDROID_NDK, if the ndk isn't in ANDROID_HOME/ndk-bundle).
+
+It is also possible to build from a direct AOSP checkout, but then you won't be able to build for multiple
+NDKs: archiveZip will still work but the gamesdkZip target will fail.
diff --git a/build.gradle b/build.gradle
index 64b0dc9..69f5c71 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,181 +1,358 @@
+import java.nio.file.Paths
import org.gradle.internal.logging.text.StyledTextOutput;
import org.gradle.internal.logging.text.StyledTextOutputFactory;
import static org.gradle.internal.logging.text.StyledTextOutput.Style;
+import org.gradle.internal.os.OperatingSystem;
+import org.gradle.api.Project;
defaultTasks 'clean', 'archiveZip'
-def getAndroidNDKPath() {
- return System.getenv("ANDROID_NDK")
+task get_protoc_version(type: Exec) {
+ commandLine "protoc"
+ args = ["--version"]
+ standardOutput = new ByteArrayOutputStream()
+ ext.output = {
+ return standardOutput.toString().trim()
+ }
}
-def getAndroidSDKPath() {
- return System.getenv("ANDROID_HOME")
+task check_protoc_version(dependsOn: get_protoc_version) {
+ doLast {
+ def version_needed = "3.0.0"
+ def is_protoc_version_correct = tasks.get_protoc_version.output().endsWith(version_needed)
+ def version_error_msg = "Make sure you have protoc installed and its version is exactly " + version_needed
+ assert is_protoc_version_correct : version_error_msg
+ }
}
-ext.tempFolder = '.temp'
-ext.buildFolder = 'build'
-ext.androidNDK = getAndroidNDKPath()
-ext.androidNDKVersion = "26"
-ext.androidSDK = getAndroidSDKPath()
-
-if (ext.androidSDK == null) {
- throw new GradleException('Must set ANDROID_HOME')
+task make_proto(type: Exec) {
+ workingDir getExternalPath() + '/nanopb-c/generator/proto'
+ commandLine 'make'
}
-if (ext.androidNDK == null) {
- ext.androidNDK = ext.androidSDK + '/ndk-bundle'
- if (!file(ext.androidNDK).exists())
- throw new GradleException('No NDK found in SDK: must set ANDROID_NDK')
-}
-
-def findCMake() {
- def cmake = System.getenv("CMAKE");
- if (cmake != null) {
- return cmake;
- }
-
- def cmakes = fileTree(project.property('androidSDK')).matching { include 'cmake/*/bin/cmake' }
- if (cmakes.size() == 0) {
- throw new GradleException('No cmake found in ' + project.property('androidSDK') + 'cmake')
- }
- return cmakes.last();
-}
-
-ext.cmake = findCMake()
-
-println "Build folder: $buildFolder"
-println "Android SDK folder: $androidSDK"
-println "Android NDK folder: $androidNDK"
-println "Using cmake from: $cmake"
-
buildscript {
- repositories {
- google()
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
- }
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.2.1'
+ }
}
allprojects {
- repositories {
- google()
- jcenter()
- }
+ buildDir = getOutPath()
+ repositories {
+ google()
+ jcenter()
+ }
}
-def cmake(projectFolder, cmakeFolder, arch, ndkVersion) {
- exec {
- workingDir cmakeFolder
-
- commandLine "$cmake",
- "$projectFolder",
- "-DCMAKE_BUILD_TYPE=Release ",
- "-DANDROID_PLATFORM=android-" + ndkVersion,
- "-DANDROID_NDK=" + project.property('androidNDK') + " ",
- "-DANDROID_STL=c++_static ",
- "-DANDROID_ABI=" + arch,
- "-DCMAKE_CXX_FLAGS= ",
- "-DCMAKE_TOOLCHAIN_FILE=" + project.property('androidNDK') + "/build/cmake/android.toolchain.cmake",
- "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=./"
- }
+abstract class Toolchain {
+ abstract String getAndroidNDKPath();
+ abstract String getCMakePath();
+ abstract String getNinjaPath();
+ abstract String getAndroidVersion();
+ abstract String getBuildKey(String arch, String stl);
+}
+class SpecificToolchain extends Toolchain {
+ private String androidVersion_;
+ private String ndkVersion_;
+ SpecificToolchain(String androidVersion, String ndkVersion) {
+ androidVersion_ = androidVersion;
+ ndkVersion_ = ndkVersion;
+ }
+ public String getAndroidNDKPath() {
+ return new File("../prebuilts/ndk/" + ndkVersion_).getCanonicalPath()
+ }
+ public String getCMakePath() {
+ return new File("../prebuilts/cmake/linux-x86/bin/cmake").getCanonicalPath()
+ }
+ public String getNinjaPath() {
+ return new File("../prebuilts/cmake/linux-x86/bin/ninja").getCanonicalPath()
+ }
+ public String getAndroidVersion() { return androidVersion_; }
+ public String getBuildKey(String arch, String stl) {
+ return arch + '_' + ndkVersion_ + '_' + stl
+ }
+}
+class LocalToolchain extends Toolchain {
+ Project project_;
+ String sdkPath_;
+ String ndkPath_;
+ String cmakePath_;
+ String ninjaPath_;
+ String androidVersion_;
+ LocalToolchain(Project project, String androidVersion) {
+ project_ = project
+ androidVersion_ = androidVersion
+ sdkPath_ = System.getenv("ANDROID_HOME")
+ if(sdkPath_ == null)
+ throw new GradleException('Must set ANDROID_HOME')
+ ndkPath_ = System.getenv("ANDROID_NDK")
+ if(ndkPath_ == null) {
+ ndkPath_ = Paths.get(sdkPath_,'ndk-bundle').toString()
+ if (!project_.file(ndkPath_).exists())
+ throw new GradleException('No NDK found in SDK: must set ANDROID_NDK')
+ }
+ cmakePath_ = findCMakeTool("CMAKE", "cmake")
+ ninjaPath_ = findCMakeTool("NINJA", "ninja")
+ }
+ String getAndroidNDKPath() {
+ return ndkPath_;
+ }
+ String getCMakePath() {
+ return cmakePath_;
+ }
+ String getNinjaPath() {
+ return ninjaPath_;
+ }
+ String getAndroidVersion() {
+ return androidVersion_;
+ }
+ String getBuildKey(String arch, String stl) {
+ return arch + '_local_' + stl
+ }
+ String findCMakeTool(String envVar, String name) {
+ def tool = System.getenv(envVar);
+ if (tool) {
+ return tool;
+ }
+ def osname = OperatingSystem.current().isWindows() ? name + '.exe' : name
+ def tools = project_.fileTree( dir: Paths.get(sdkPath_, 'cmake').toString(), include: ['**/bin/'+osname] )
+ if (tools==null || tools.size() == 0) {
+ throw new GradleException('No ' + osname + ' found in ' + sdkPath_ + '/cmake')
+ }
+ return tools.getFiles().last().toString();
+ }
}
-def buildNative(arch, ndkVersion) {
- def cmakeFolder = project.property('tempFolder') + '/' + arch + '/.cmake'
- def buildFolder = project.property('buildFolder') + '/lib/' + arch
-
- def out = services.get(StyledTextOutputFactory).create("ouput")
- out.style(Style.Identifier).println("\n========= Building native [" + arch + "]");
- println "cmake folder: $cmakeFolder";
-
- mkdir cmakeFolder
- mkdir buildFolder
-
- exec {
- commandLine "$cmake", '--version'
- }
-
- cmake("$projectDir/src/", cmakeFolder, arch, ndkVersion)
-
- exec {
- workingDir cmakeFolder
-
- commandLine "make", "-j"
- }
-
- out.style(Style.ProgressStatus).println("\nCopying libraries to " + buildFolder);
-
- copy {
- from file(cmakeFolder)
- include "*/lib*_static.a"
- into file(buildFolder)
- includeEmptyDirs = false
- }
- copy {
- from file(cmakeFolder)
- include "*/lib*.so"
- into file(buildFolder)
- includeEmptyDirs = false
- }
+def getOutPath() {
+ return new File("../out").getCanonicalPath()
}
+def getPackagePath() {
+ return new File("../package").getCanonicalPath()
+}
+
+def getTempPath() {
+ return new File("../.temp").getCanonicalPath()
+}
+
+def getExternalPath() {
+ def f = new File("../external/");
+ if ( !f.exists() )
+ f = new File("../../../external/");
+ return f.getCanonicalPath()
+}
+def useNinja() {
+ return true;
+}
+def cmake(projectFolder, workingFolder, outputFolder, arch, toolchain, stl,
+ threadChecks) {
+ def ndkPath = toolchain.getAndroidNDKPath()
+ def toolchainFilePath = ndkPath + "/build/cmake/android.toolchain.cmake"
+ def externalPath = getExternalPath();
+ def androidVersion = toolchain.getAndroidVersion()
+ def ninjaPath = toolchain.getNinjaPath()
+ mkdir workingFolder
+ mkdir outputFolder
+
+ def threadFlags = ""
+ if (threadChecks) {
+ threadFlags = "-DGAMESDK_THREAD_CHECKS=1"
+ } else {
+ threadFlags = "-DGAMESDK_THREAD_CHECKS=0"
+ }
+
+ def cmdLine = [toolchain.getCMakePath(),
+ "$projectFolder",
+ "-DCMAKE_BUILD_TYPE=Release",
+ "-DANDROID_PLATFORM=android-$androidVersion",
+ "-DANDROID_NDK=$ndkPath",
+ "-DANDROID_STL=$stl",
+ "-DANDROID_ABI=$arch",
+ "-DCMAKE_CXX_FLAGS=",
+ "-DCMAKE_TOOLCHAIN_FILE=$toolchainFilePath",
+ "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=$outputFolder",
+ "-DEXTERNAL_ROOT=$externalPath",
+ threadFlags]
+ if (useNinja()) {
+ cmdLine += ["-DCMAKE_MAKE_PROGRAM=" + "$ninjaPath",
+ "-GNinja"]
+ }
+ exec {
+ workingDir workingFolder
+ commandLine cmdLine
+ }
+}
+
+def buildNativeModules(arch, toolchain, stl, threadChecks) {
+ def buildKey = toolchain.getBuildKey(arch, stl)
+ def workingFolder = getTempPath() + '/' + buildKey + '/.cmake'
+ def outputFolder = getOutPath() + '/' + buildKey
+ def cmakeProjectLocation = "$projectDir/src/"
+
+ cmake(cmakeProjectLocation, workingFolder, outputFolder, arch, toolchain, stl, threadChecks)
+ def cmdLine = useNinja() ? [toolchain.getNinjaPath()] : ["make", "-j"]
+ exec {
+ workingDir workingFolder
+ commandLine cmdLine
+ }
+ return [arch: arch, buildKey: buildKey]
+}
+def buildNativeModules(arch, androidVersion, ndkVersion, stl, threadChecks) {
+ return buildNativeModules(arch,
+ new SpecificToolchain(androidVersion, ndkVersion),
+ stl, threadChecks)
+}
task clean(type: Delete) {
- delete project.property('tempFolder')
- delete project.property('buildFolder')
-}
-
-task buildGameSDKJavaLibs() {
- def buildFolder = project.property('buildFolder') + '/aar'
- def outputFolder = 'src/extras/build/outputs/aar'
- dependsOn ':extras:assembleRelease'
-
- doFirst {
- delete buildFolder
- mkdir buildFolder
- }
- doLast {
- copy {
- from file(outputFolder + "/extras-release.aar")
- into file(buildFolder + "/extras-release.aar")
+ doLast {
+ delete getOutPath(), getPackagePath(), getTempPath()
}
- }
}
-task build(dependsOn: buildGameSDKJavaLibs) {
- def includeFolder = project.property('buildFolder') + '/include'
- doFirst {
- delete includeFolder
- mkdir includeFolder
- }
-
- def ndkVersion = project.property('androidNDKVersion')
-
- doLast {
- buildNative("armeabi-v7a", ndkVersion)
- buildNative("arm64-v8a", ndkVersion)
- copy {
- from "$projectDir/include"
- into includeFolder
+// Create outAr from the contents of inArs
+// All files taken/created in dir
+def repackArchives(dir, inArs, outAr) {
+ def cmd = /pushd $dir &&/
+ inArs.each {
+ cmd <<= /ar -x $it &&/
}
- }
+ cmd <<= /ar -qc $outAr *.o && rm *.o && popd/
+ ['/bin/bash', '-c', cmd.toString()].execute().waitFor()
+}
+def sdkCopy(buildInfo, outFolder, all = true, staticToo = false,
+ useFullBuildKey = false) {
+ def arch = buildInfo.arch
+ def buildKey = buildInfo.buildKey
+ def cmakeFolder = getTempPath() + '/' + buildKey + '/.cmake'
+ def buildFolder = getPackagePath() + '/' + outFolder
+ def libBuildFolder = buildFolder + '/libs/' +
+ (useFullBuildKey ? buildKey : arch ) + '/lib'
+
+ copy {
+ from file(cmakeFolder)
+ include all ? "*/lib*.so" : "swappy*/lib*.so"
+ into file(libBuildFolder)
+ includeEmptyDirs = false
+ }
+
+ if (staticToo) {
+ def staticsFolder = getOutPath() + '/' + buildKey
+ def staticLibsBuildFolder = buildFolder + '/libs/' + buildKey
+ def staticLibs = ['libswappy_static.a',
+ 'libswappyVk_static.a']
+ if (all)
+ staticLibs += 'libtuningfork_static.a'
+ repackArchives(staticsFolder, staticLibs, 'libgamesdk.a')
+ copy {
+ from file(staticsFolder)
+ include "libgamesdk.a"
+ into file(staticLibsBuildFolder)
+ }
+ }
+}
+def copyExtras(outFolder, all = true) {
+ def buildFolder = getPackagePath() + '/' + outFolder
+ def headerFolder = './include'
+ def aarFolder = getOutPath() + '/outputs/aar'
+ def includeBuildFolder = buildFolder + '/include'
+ def aarBuildFolder = buildFolder + '/aar'
+
+ copy {
+ from file(headerFolder)
+ include all ? "*/*.h" : "swappy*/*.h"
+ into file(includeBuildFolder)
+ includeEmptyDirs = false
+ }
+ copy {
+ from file(aarFolder)
+ into file(aarBuildFolder)
+ includeEmptyDirs = false
+ }
+}
+// The latest Unity is using NDK 16b and SDK 26 with gnu stl
+def defaultAbis() { return ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"] }
+def unityNativeBuild() {
+ return defaultAbis().collect { buildNativeModules(it, "26", "r16", "gnustl_shared", false) }
+}
+def sdkNativeBuild() {
+ return defaultAbis().collectMany {
+ [ buildNativeModules(it, "26", "r16", "gnustl_shared", false) ] +
+ [ buildNativeModules(it, "28", "r17", "gnustl_shared", false) ] +
+ [ buildNativeModules(it, "28", "r17", "c++_static", false) ] }
+}
+def localNativeBuild() {
+ def kLocalMinSdk = "26"
+ def stl = "c++_static"
+ def toolchain = new LocalToolchain(project, kLocalMinSdk)
+ return defaultAbis().collect {
+ buildNativeModules(it, toolchain , stl, true)
+ }
+}
+// Just build swappy
+task swappyUnityBuild() {
+ dependsOn ':extras:assembleRelease', 'check_protoc_version', 'make_proto'
+ ext.packageName = 'swappyUnity'
+ doLast {
+ unityNativeBuild().each { sdkCopy(it, packageName, false) }
+ copyExtras(packageName, false)
+ }
+}
+// Full build including tuning fork for unity
+task unityBuild() {
+ dependsOn ':extras:assembleRelease', 'check_protoc_version', 'make_proto'
+ ext.packageName = 'unity'
+ doLast {
+ unityNativeBuild().each { sdkCopy(it, packageName, true) }
+ copyExtras(packageName, true)
+ }
}
-task archiveZip(type: Zip, dependsOn: 'build') {
- baseName = project.property('buildFolder') + '/gamesdk'
-
- from fileTree(project.property('buildFolder'))
- exclude "*.zip"
-
- into 'gamesdk'
-
- doLast {
- def out = services.get(StyledTextOutputFactory).create("ouput")
-
- out.style(Style.Identifier).text('\nGameSDK zip is in ')
- .style(Style.ProgressStatus)
- .println(project.property('buildFolder') + '/gamesdk.zip' );
- }
+// Build everything
+task sdkBuild() {
+ dependsOn ':extras:assembleRelease', 'check_protoc_version', 'make_proto'
+ ext.packageName = 'gamesdk'
+ doLast {
+ sdkNativeBuild().each { sdkCopy(it, packageName, true, true, true) }
+ copyExtras(packageName, true)
+ }
}
+
+// Build using local SDK
+task localBuild() {
+ dependsOn ':extras:assembleRelease', 'check_protoc_version', 'make_proto'
+ ext.packageName = 'local'
+ doLast {
+ localNativeBuild().each { sdkCopy(it, packageName, true, true, false) }
+ copyExtras(packageName, true)
+ }
+}
+// Zipping things up
+def addZipTask(name, buildTask, zipName, rootName = "gamesdk") {
+ def packPath = buildTask.packageName
+ tasks.register(name, Zip) {
+ dependsOn buildTask
+ def buildFolder = Paths.get(getPackagePath(), packPath).toString()
+ baseName = Paths.get(buildFolder, zipName).toString()
+
+ from fileTree(buildFolder)
+ exclude "*.zip"
+
+ into rootName
+
+ doLast {
+ def out = services.get(StyledTextOutputFactory).create("ouput")
+ out.style(Style.Identifier).text('\n'+packPath+' zip is in ')
+ .style(Style.ProgressStatus)
+ .println(baseName + '.zip' );
+ }
+ }
+
+}
+addZipTask("swappyUnityZip", swappyUnityBuild, "builds")
+addZipTask("unityZip", unityBuild, "builds")
+addZipTask("archiveZip", localBuild, "gamesdk")
+addZipTask("gamesdkZip", sdkBuild, "gamesdk")
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..8046488
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1 @@
+android.builder.sdkDownload=false
diff --git a/samples/bouncyball/app/CMakeLists.txt b/samples/bouncyball/app/CMakeLists.txt
index 5e141f0..7b9cb3c 100644
--- a/samples/bouncyball/app/CMakeLists.txt
+++ b/samples/bouncyball/app/CMakeLists.txt
@@ -4,9 +4,14 @@
# ============== Games SDK
-add_subdirectory(../../../src/swappy ./swappy-output) # Swappy Library
+# This will include and build swappy from the gamesdk
+#add_subdirectory(../../../src/swappy ./swappy-output) # Swappy Library
+#include_directories( "../../../include" ) # Games SDK Public Includes
-include_directories( ../../../include ) # Games SDK Public Includes
+# This will use swappy from a packaged version
+include("../../gamesdk.cmake")
+add_gamesdk_target()
+
include_directories( ../../common/include ) # Samples Includes
# ============== Bouncy Ball
@@ -21,15 +26,14 @@
src/main/cpp/Orbit.cpp
src/main/cpp/Renderer.cpp
src/main/cpp/Settings.cpp
- ../../common/src/Thread.cpp
+ ../../../samples/common/src/Thread.cpp
)
-
target_link_libraries( native-lib
android
EGL
GLESv2
log
- swappy
- )
\ No newline at end of file
+ gamesdk
+ )
diff --git a/samples/bouncyball/app/build.gradle b/samples/bouncyball/app/build.gradle
index b4c5193..bd1a902 100644
--- a/samples/bouncyball/app/build.gradle
+++ b/samples/bouncyball/app/build.gradle
@@ -1,5 +1,7 @@
apply plugin: 'com.android.application'
+def GAMESDK_ROOT = '../../../..'
+
android {
compileSdkVersion 28
defaultConfig {
@@ -11,7 +13,7 @@
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
- cppFlags ""
+ arguments "-DGAMESDK_ROOT=$GAMESDK_ROOT"
}
}
}
@@ -55,6 +57,4 @@
implementation 'androidx.preference:preference:1.0.0-rc01'
implementation project(':extras')
testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.androidx.test:runner:1.0.2'
- androidTestImplementation 'com.androidx.test.espresso:espresso-core:3.1.1'
}
diff --git a/samples/gamesdk.cmake b/samples/gamesdk.cmake
new file mode 100644
index 0000000..32cb6a0
--- /dev/null
+++ b/samples/gamesdk.cmake
@@ -0,0 +1,22 @@
+function(add_gamesdk_target)
+
+ set(GAMESDK_PACKAGE_ROOT "${GAMESDK_ROOT}/package/gamesdk")
+ set(GAMESDK_GEN_TASK sdkBuild)
+ set(NDK_VERSION ${ANDROID_NDK_REVISION})
+ string(REGEX REPLACE "^([^.]+).*" "\\1" NDK_VERSION ${ANDROID_NDK_REVISION} )
+ set(GAMESDK_LIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/${GAMESDK_PACKAGE_ROOT}/libs/${ANDROID_ABI}_r${NDK_VERSION}_${ANDROID_STL}")
+
+ include_directories( "${GAMESDK_PACKAGE_ROOT}/include" ) # Games SDK Public Includes
+ get_filename_component(DEP_LIB "${GAMESDK_LIB_ROOT}/libgamesdk.a" REALPATH)
+ set(GAMESDK_LIB ${DEP_LIB} PARENT_SCOPE)
+
+ add_custom_command(OUTPUT ${DEP_LIB}
+ COMMAND ./gradlew ${GAMESDK_GEN_TASK} VERBATIM
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${GAMESDK_ROOT}/gamesdk"
+ )
+ add_custom_target(gamesdk_lib DEPENDS ${DEP_LIB})
+ add_library( gamesdk STATIC IMPORTED GLOBAL)
+ add_dependencies(gamesdk gamesdk_lib)
+ set_target_properties(gamesdk PROPERTIES IMPORTED_LOCATION ${DEP_LIB})
+
+endfunction()
diff --git a/samples/tuningfork/tftestapp/app/CMakeLists.txt b/samples/tuningfork/tftestapp/app/CMakeLists.txt
index ddd7be9..07adc93 100644
--- a/samples/tuningfork/tftestapp/app/CMakeLists.txt
+++ b/samples/tuningfork/tftestapp/app/CMakeLists.txt
@@ -2,14 +2,19 @@
# If you have protobuf installed from a different directory, set it here. The source version
# must match the protoc version.
-#set(PROTOBUF_SRC_DIR ~/3rdParty/protobuf-3.0.2/src)
+set(PROTOBUF_SRC_DIR ~/3rdParty/protobuf-3.0.2/src)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Werror -Wthread-safety" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -Os -fPIC" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGOOGLE_PROTOBUF_NO_RTTI -DHAVE_PTHREAD")
-set( BUILD_PROTOBUF_FULL_AND_LITE "True")
-add_subdirectory(../../../../src/tuningfork ./tuningfork_output)
+#set( BUILD_PROTOBUF_FULL_AND_LITE "True")
+#add_subdirectory(../../../../src/tuningfork ./tuningfork_output)
+
+# This will use tuningfork from a packaged version
+include("../../../gamesdk.cmake")
+add_gamesdk_target()
+include("../../../../src/protobuf/protobuf.cmake")
protobuf_generate_nano_c( ${CMAKE_CURRENT_SOURCE_DIR}/src/main/proto src/main/proto/tuningfork_extensions.proto)
protobuf_generate_full_cpp( ${CMAKE_CURRENT_SOURCE_DIR}/src/main/proto src/main/proto/tuningfork_extensions.proto)
@@ -20,6 +25,11 @@
include_directories(${PROTOBUF_NANO_SRC_DIR})
include_directories(../../../../src)
+add_library( protobuf-static
+ STATIC ${PROTOBUF_LITE_SRCS} ${PROTOBUF_SRCS}
+ )
+target_compile_options(protobuf-static PUBLIC "-Wno-tautological-constant-compare" "-Wno-enum-compare-switch")
+
add_library( tuningfork_test
SHARED
src/test/cpp/nativetests.cpp
@@ -31,7 +41,7 @@
# Note that we use the FULL version of protobuf in the tests, so we can get debug strings
target_link_libraries( tuningfork_test
- tuningfork-static
+ gamesdk
protobuf-static
log
)
diff --git a/samples/tuningfork/tftestapp/app/build.gradle b/samples/tuningfork/tftestapp/app/build.gradle
index dd156e1..4b34757 100644
--- a/samples/tuningfork/tftestapp/app/build.gradle
+++ b/samples/tuningfork/tftestapp/app/build.gradle
@@ -1,5 +1,7 @@
apply plugin: 'com.android.application'
+def GAMESDK_ROOT = '../../../../..'
+
android {
compileSdkVersion 28
defaultConfig {
@@ -11,7 +13,7 @@
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
- cppFlags ""
+ arguments "-DGAMESDK_ROOT=$GAMESDK_ROOT"
}
}
}
@@ -36,6 +38,4 @@
implementation "com.google.android.gms:play-services-clearcut:16.0.0"
testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.androidx.test:runner:1.1.1'
- androidTestImplementation 'com.androidx.test.espresso:espresso-core:3.1.1'
}
diff --git a/src/common/Log.h b/src/common/Log.h
index 9984267..c5a74bd 100644
--- a/src/common/Log.h
+++ b/src/common/Log.h
@@ -24,4 +24,10 @@
#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);
#else
#define ALOGV(...)
-#endif
\ No newline at end of file
+#endif
+
+namespace swappy {
+
+std::string to_string(int value);
+
+}
diff --git a/src/extras/build.gradle b/src/extras/build.gradle
index c71ac7f..a173f85 100644
--- a/src/extras/build.gradle
+++ b/src/extras/build.gradle
@@ -25,6 +25,4 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.androidx.test:runner:1.1.1'
- androidTestImplementation 'com.androidx.test.espresso:espresso-core:3.1.1'
}
diff --git a/src/protobuf/full/CMakeLists.txt b/src/protobuf/full/CMakeLists.txt
index 73df24e..13ffc79 100644
--- a/src/protobuf/full/CMakeLists.txt
+++ b/src/protobuf/full/CMakeLists.txt
@@ -8,8 +8,12 @@
add_library( protobuf-static
STATIC ${PROTOBUF_LITE_SRCS} ${PROTOBUF_SRCS}
)
+target_compile_options(protobuf-static PUBLIC
+ "-Wno-tautological-constant-compare" "-Wno-enum-compare-switch")
add_library( protobuf
SHARED ${PROTOBUF_LITE_SRCS} ${PROTOBUF_SRCS}
)
+target_compile_options(protobuf PUBLIC
+ "-Wno-tautological-constant-compare" "-Wno-enum-compare-switch")
extra_pb_link_options(protobuf)
diff --git a/src/protobuf/lite/CMakeLists.txt b/src/protobuf/lite/CMakeLists.txt
index f9a1000..2b913df 100644
--- a/src/protobuf/lite/CMakeLists.txt
+++ b/src/protobuf/lite/CMakeLists.txt
@@ -9,9 +9,13 @@
STATIC
${PROTOBUF_LITE_SRCS}
)
+target_compile_options(protobuf-lite-static PUBLIC
+ "-Wno-tautological-constant-compare" "-Wno-enum-compare-switch")
add_library( protobuf-lite
SHARED
${PROTOBUF_LITE_SRCS}
)
+target_compile_options(protobuf-lite PUBLIC
+ "-Wno-tautological-constant-compare" "-Wno-enum-compare-switch")
extra_pb_link_options(protobuf-lite)
diff --git a/src/protobuf/protobuf.cmake b/src/protobuf/protobuf.cmake
index 08c7f19..1184ca1 100644
--- a/src/protobuf/protobuf.cmake
+++ b/src/protobuf/protobuf.cmake
@@ -4,12 +4,12 @@
# and use the same version of protoc below.
# If autogen.sh complains about gmock, comment out the check for it
if( NOT DEFINED PROTOBUF_SRC_DIR)
- set( PROTOBUF_SRC_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../../../external/protobuf/src")
+ set( PROTOBUF_SRC_DIR "${EXTERNAL_ROOT}/protobuf/src")
endif()
# To use this default, you'll need to run 'protoc-gen-nanopb'
# in external/nanopb-c/generator
if( NOT DEFINED PROTOBUF_NANO_SRC_DIR)
- set( PROTOBUF_NANO_SRC_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../../../external/nanopb-c")
+ set( PROTOBUF_NANO_SRC_DIR "${EXTERNAL_ROOT}/nanopb-c")
endif()
if( DEFINED ENV{PROTOBUF_INSTALL_DIR})
set( PROTOBUF_INSTALL_DIR $ENV{PROTOBUF_INSTALL_DIR})
@@ -22,15 +22,11 @@
set( PROTOBUF_INCLUDE_DIR ${PROTOBUF_INSTALL_DIR}/include )
endif()
-#message(STATUS "PROTOC_EXE=${PROTOC_EXE}")
-
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Werror -Wthread-safety" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -Os -fPIC" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGOOGLE_PROTOBUF_NO_RTTI -DHAVE_PTHREAD")
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections" )
-#The following are needed for some of the protobuf code to compile
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-tautological-constant-compare -Wno-enum-compare-switch")
function(set_link_options libname versionscript)
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
diff --git a/src/swappy/CMakeLists.txt b/src/swappy/CMakeLists.txt
index 54a5ab6..3ff9566 100644
--- a/src/swappy/CMakeLists.txt
+++ b/src/swappy/CMakeLists.txt
@@ -5,6 +5,9 @@
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffunction-sections -fdata-sections" )
+if ( DEFINED GAMESDK_THREAD_CHECKS )
+ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGAMESDK_THREAD_CHECKS=${GAMESDK_THREAD_CHECKS}" )
+endif()
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections" )
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-s" )
diff --git a/src/swappy/ChoreographerFilter.cpp b/src/swappy/ChoreographerFilter.cpp
index 7cd731c..5361ad8 100644
--- a/src/swappy/ChoreographerFilter.cpp
+++ b/src/swappy/ChoreographerFilter.cpp
@@ -173,7 +173,7 @@
}
std::string threadName = "Filter";
- threadName += std::to_string(thread);
+ threadName += swappy::to_string(thread);
pthread_setname_np(pthread_self(), threadName.c_str());
std::unique_lock<std::mutex> lock(mMutex);
diff --git a/src/swappy/ChoreographerThread.cpp b/src/swappy/ChoreographerThread.cpp
index c29229e..876bf16 100644
--- a/src/swappy/ChoreographerThread.cpp
+++ b/src/swappy/ChoreographerThread.cpp
@@ -24,6 +24,10 @@
#include "Thread.h"
#include "CpuInfo.h"
+#include <condition_variable>
+#include <cstring>
+#include <cstdlib>
+
#include <sched.h>
#include <pthread.h>
#include <unistd.h>
diff --git a/src/swappy/CpuInfo.cpp b/src/swappy/CpuInfo.cpp
index e29cadd..9112643 100644
--- a/src/swappy/CpuInfo.cpp
+++ b/src/swappy/CpuInfo.cpp
@@ -20,6 +20,8 @@
#include <limits>
#include <bitset>
+#include <cstdlib>
+#include <cstring>
#include "Log.h"
@@ -62,6 +64,13 @@
namespace swappy {
+std::string to_string(int n) {
+ constexpr int kBufSize = 12; // strlen("−2147483648")+1
+ static char buf[kBufSize];
+ snprintf(buf, kBufSize, "%d", n);
+ return buf;
+}
+
CpuInfo::CpuInfo() {
const auto BUFFER_LENGTH = 10240;
@@ -84,13 +93,13 @@
core.id = mCpus.size();
auto core_path = std::string("/sys/devices/system/cpu/cpu")
- + std::to_string(core.id);
+ + to_string(core.id);
auto package_id = ReadFile(core_path + "/topology/physical_package_id");
auto frequency = ReadFile(core_path + "/cpufreq/cpuinfo_max_freq");
- core.package_id = std::atol(package_id.c_str());
- core.frequency = std::atol(frequency.c_str());
+ core.package_id = atol(package_id.c_str());
+ core.frequency = atol(frequency.c_str());
mMinFrequency = std::min(mMinFrequency, core.frequency);
mMaxFrequency = std::max(mMaxFrequency, core.frequency);
diff --git a/src/swappy/EGL.h b/src/swappy/EGL.h
index a019548..be8df40 100644
--- a/src/swappy/EGL.h
+++ b/src/swappy/EGL.h
@@ -19,9 +19,9 @@
#include <chrono>
#include <condition_variable>
#include <mutex>
-#include <optional>
#include <thread>
#include <memory>
+#include <atomic>
#include <EGL/egl.h>
#include <EGL/eglext.h>
diff --git a/src/swappy/FrameStatistics.cpp b/src/swappy/FrameStatistics.cpp
index 6865f2d..cb16841 100644
--- a/src/swappy/FrameStatistics.cpp
+++ b/src/swappy/FrameStatistics.cpp
@@ -123,31 +123,31 @@
ALOGI("total frames: %" PRIu64, mStats.totalFrames);
message += "Buckets: ";
for (int i = 0; i < MAX_FRAME_BUCKETS; i++)
- message += "\t[" + std::to_string(i) + "]";
+ message += "\t[" + swappy::to_string(i) + "]";
ALOGI("%s", message.c_str());
message = "";
message += "idle frames: ";
for (int i = 0; i < MAX_FRAME_BUCKETS; i++)
- message += "\t " + std::to_string(mStats.idleFrames[i]);
+ message += "\t " + swappy::to_string(mStats.idleFrames[i]);
ALOGI("%s", message.c_str());
message = "";
message += "late frames: ";
for (int i = 0; i < MAX_FRAME_BUCKETS; i++)
- message += "\t " + std::to_string(mStats.lateFrames[i]);
+ message += "\t " + swappy::to_string(mStats.lateFrames[i]);
ALOGI("%s", message.c_str());
message = "";
message += "offset from previous frame: ";
for (int i = 0; i < MAX_FRAME_BUCKETS; i++)
- message += "\t " + std::to_string(mStats.offsetFromPreviousFrame[i]);
+ message += "\t " + swappy::to_string(mStats.offsetFromPreviousFrame[i]);
ALOGI("%s", message.c_str());
message = "";
message += "frame latency: ";
for (int i = 0; i < MAX_FRAME_BUCKETS; i++)
- message += "\t " + std::to_string(mStats.latencyFrames[i]);
+ message += "\t " + swappy::to_string(mStats.latencyFrames[i]);
ALOGI("%s", message.c_str());
previousLogTime = std::chrono::steady_clock::now();
diff --git a/src/swappy/Swappy.cpp b/src/swappy/Swappy.cpp
index f24c0a5..bb32d57 100644
--- a/src/swappy/Swappy.cpp
+++ b/src/swappy/Swappy.cpp
@@ -398,8 +398,7 @@
Settings::getInstance()->addListener([this]() { onSettingsChanged(); });
ALOGI("Initialized Swappy with refreshPeriod=%lld, appOffset=%lld, sfOffset=%lld",
- refreshPeriod.count(), appOffset.count(), sfOffset.count());
-
+ (long long)refreshPeriod.count(), (long long)appOffset.count(), (long long)sfOffset.count());
std::lock_guard<std::mutex> lock(mEglMutex);
mEgl = EGL::create(refreshPeriod);
if (!mEgl) {
@@ -413,7 +412,7 @@
void Swappy::onSettingsChanged() {
std::lock_guard<std::mutex> lock(mFrameDurationsMutex);
- int32_t newSwapInterval = std::round(float(Settings::getInstance()->getSwapIntervalNS()) /
+ int32_t newSwapInterval = ::round(float(Settings::getInstance()->getSwapIntervalNS()) /
float(mRefreshPeriod.count()));
if (mSwapInterval != newSwapInterval || mAutoSwapInterval != newSwapInterval) {
mSwapInterval = newSwapInterval;
@@ -607,7 +606,7 @@
// are exactly at the edge.
lowerBound -= FRAME_HYSTERESIS;
- auto div_result = std::div((averageFrameTime.getTime(true) + FRAME_HYSTERESIS).count(),
+ auto div_result = ::div((averageFrameTime.getTime(true) + FRAME_HYSTERESIS).count(),
mRefreshPeriod.count());
auto framesPerRefresh = div_result.quot;
auto framesPerRefreshRemainder = div_result.rem;
diff --git a/src/swappy/SystemProperties.cpp b/src/swappy/SystemProperties.cpp
index 95aa7d3..e6cdd70 100644
--- a/src/swappy/SystemProperties.cpp
+++ b/src/swappy/SystemProperties.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <cstdlib>
#include <string>
#include "Log.h"
@@ -37,7 +38,7 @@
if (bufferLen > PROP_VALUE_MAX || bufferLen == 0) {
return default_value;
}
- return atoi(buffer);
+ return ::atoi(buffer);
}
int getSystemPropViaGetAsBool(const char* key, bool default_value = false) {
diff --git a/src/swappyVk/SwappyVk.cpp b/src/swappyVk/SwappyVk.cpp
index 2b30da0..77536c0 100644
--- a/src/swappyVk/SwappyVk.cpp
+++ b/src/swappyVk/SwappyVk.cpp
@@ -17,6 +17,8 @@
#include <swappyVk/SwappyVk.h>
#include <map>
+#include <condition_variable>
+#include <cstring>
#include <unistd.h>
#include <dlfcn.h>
@@ -250,7 +252,7 @@
}
void SwappyVkBase::calcRefreshRate(long frameTimeNanos) {
- long refresh_nano = abs(frameTimeNanos - mLastframeTimeNanos);
+ long refresh_nano = std::abs(frameTimeNanos - mLastframeTimeNanos);
if (mRefreshDur != 0 || mLastframeTimeNanos == 0) {
return;
diff --git a/src/tuningfork/CMakeLists.txt b/src/tuningfork/CMakeLists.txt
index 9556b3d..04c256f 100644
--- a/src/tuningfork/CMakeLists.txt
+++ b/src/tuningfork/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.4.1)
include("../protobuf/protobuf.cmake")
-set( MODPB64_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../external/modp_b64")
+set( MODPB64_DIR "${EXTERNAL_ROOT}/modp_b64")
if (${CMAKE_BUILD_TYPE} STREQUAL "Release")
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections,-s")
@@ -38,9 +38,9 @@
${PROTO_GENS_DIR}/nano/tuningfork_clearcut_log.pb.c
${PROTO_GENS_DIR}/nano/eng_tuningfork.pb.c)
-add_library( tuningfork-static
+add_library( tuningfork_static
STATIC ${TUNINGFORK_SRCS} ${PROTOBUF_NANO_SRCS})
-set_target_properties( tuningfork-static PROPERTIES
+set_target_properties( tuningfork_static PROPERTIES
COMPILE_OPTIONS "-DPROTOBUF_NANO" )
add_library( tuningfork
diff --git a/src/tuningfork/prong.h b/src/tuningfork/prong.h
index b3d254d..e94eabc 100644
--- a/src/tuningfork/prong.h
+++ b/src/tuningfork/prong.h
@@ -21,6 +21,7 @@
#include <vector>
#include <map>
#include <string>
+#include <memory>
namespace tuningfork {
diff --git a/src/tuningfork/tuningfork_c.cpp b/src/tuningfork/tuningfork_c.cpp
index 97aff92..9440de8 100644
--- a/src/tuningfork/tuningfork_c.cpp
+++ b/src/tuningfork/tuningfork_c.cpp
@@ -15,6 +15,8 @@
#include "tuningfork/tuningfork.h"
#include "tuningfork_internal.h"
+#include <cstdlib>
+
namespace {
tuningfork::ProtobufSerialization ToProtobufSerialization(const CProtobufSerialization& cpbs) {
return tuningfork::ProtobufSerialization(cpbs.bytes, cpbs.bytes + cpbs.size);
diff --git a/src/tuningfork/uploadthread.h b/src/tuningfork/uploadthread.h
index 55f51de..85767ab 100644
--- a/src/tuningfork/uploadthread.h
+++ b/src/tuningfork/uploadthread.h
@@ -18,6 +18,7 @@
#include <thread>
#include <mutex>
#include <map>
+#include <condition_variable>
#include "prong.h"
namespace tuningfork {
diff --git a/third_party/cube/app/CMakeLists.txt b/third_party/cube/app/CMakeLists.txt
index 9ebec21..819a77d 100644
--- a/third_party/cube/app/CMakeLists.txt
+++ b/third_party/cube/app/CMakeLists.txt
@@ -4,10 +4,14 @@
# ============== Games SDK
-include_directories( ../../../include ) # Games SDK Public Includes
-include_directories( ../../../src ) # Games SDK Internal Includes
+# This will use the in-source version of swappyVk
+#include_directories( ../../../include ) # Games SDK Public Includes
+#include_directories( ../../../src ) # Games SDK Internal Includes
+#add_subdirectory(../../../src/swappyVk ./swappyVk-output) # SwappyVk Library
-add_subdirectory(../../../src/swappyVk ./swappyVk-output) # SwappyVk Library
+# This will use swappy from a packaged version
+include("../../../samples/gamesdk.cmake")
+add_gamesdk_target()
# ============== cube
@@ -65,13 +69,12 @@
${SHADERC_SRC}/third_party/spirv-tools/include/spirv-tools
src/main/cpp/include
src/main/cpp/common
- ../../../src/swappyVk
${ANDROID_NDK}/sources/android/native_app_glue)
target_link_libraries( native-lib
- swappyVk
+ gamesdk
android
log
)
diff --git a/third_party/cube/app/build.gradle b/third_party/cube/app/build.gradle
index 909fc4e..8b6f82b 100644
--- a/third_party/cube/app/build.gradle
+++ b/third_party/cube/app/build.gradle
@@ -14,6 +14,8 @@
apply plugin: 'com.android.application'
+def GAMESDK_ROOT = '../../../..'
+
def ndkDir
if (project.rootProject.file('local.properties').exists()) {
Properties properties = new Properties()
@@ -45,8 +47,11 @@
}
externalNativeBuild {
cmake {
- arguments '-DANDROID_PLATFORM=android-24', '-DANDROID_TOOLCHAIN=clang',
- "-DANDROID_STL=${stlType}", '-DSAMPLE_NAME=' + project.getName()
+ arguments "-DANDROID_PLATFORM=android-24"
+ arguments "-DANDROID_TOOLCHAIN=clang"
+ arguments "-DANDROID_STL=${stlType}"
+ arguments "-DSAMPLE_NAME=" + project.getName()
+ arguments "-DGAMESDK_ROOT=$GAMESDK_ROOT"
}
}
}
@@ -55,7 +60,6 @@
path 'CMakeLists.txt'
}
}
-
buildTypes {
release {
minifyEnabled false
@@ -63,8 +67,6 @@
'proguard-rules.pro'
}
}
-
-
}
dependencies {