Squashed 'third_party/ntcore_2016/' content from commit d8de5e4

Change-Id: Id4839f41b6a620d8bae58dcf1710016671cc4992
git-subtree-dir: third_party/ntcore_2016
git-subtree-split: d8de5e4f19e612e7102172c0dbf152ce82d3d63a
diff --git a/toolchains/arm.gradle b/toolchains/arm.gradle
new file mode 100644
index 0000000..144a8bd
--- /dev/null
+++ b/toolchains/arm.gradle
@@ -0,0 +1,94 @@
+def compilerPrefix = 'arm-frc-linux-gnueabi-'
+model {
+    toolChains {
+        gcc(Gcc) {
+            target("arm"){
+                // We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
+                // If this ever changes, the prefix will need to be changed here
+                cppCompiler.executable = compilerPrefix + cppCompiler.executable
+                linker.executable = compilerPrefix + linker.executable
+                assembler.executable = compilerPrefix + assembler.executable
+                // Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
+                // arm, and doesn't understand this flag, so it is removed from both
+                cppCompiler.withArguments { args ->
+                    args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
+                    args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-rdynamic'
+                    //TODO: When the compiler allows us to actually call deprecated functions from within
+                    // deprecated function, remove this line (this will cause calling deprecated functions
+                    // to be treated as a warning rather than an error).
+                    args << '-Wno-error=deprecated-declarations'
+                    args.remove('-m32')
+                }
+                linker.withArguments { args ->
+                    args << '-rdynamic'
+                    args.remove('-m32')
+                }
+                staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable
+            }
+        }
+        // Workaround for OS X. Macs for some reason want to use Xcode's gcc
+        // (which just wraps Clang), so we have to explicitly make it so
+        // that trying to compile with Clang will call gcc instead
+        macGcc(Clang) {
+            target('arm') {
+                // We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi-<util name>
+                // If this ever changes, the prefix will need to be changed here
+                cppCompiler.executable = compilerPrefix + 'g++'
+                linker.executable = compilerPrefix + 'g++'
+                assembler.executable = compilerPrefix + 'gcc'
+                // Gradle auto-adds the -m32 argument to the linker and compiler. Our compiler only supports
+                // arm, and doesn't understand this flag, so it is removed from both
+                cppCompiler.withArguments { args ->
+                    args << '-std=c++1y' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
+                    args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-O0' << '-g3' << '-rdynamic'
+                    //TODO: When the compiler allows us to actually call deprecated functions from within
+                    // deprecated function, remove this line (this will cause calling deprecated functions
+                    // to be treated as a warning rather than an error).
+                    args << '-Wno-error=deprecated-declarations'
+                    args.remove('-m32')
+                }
+                linker.withArguments { args ->
+                    args << '-rdynamic'
+                    args.remove('-m32')
+                }
+                staticLibArchiver.executable = compilerPrefix + 'ar'
+            }
+        }
+    }
+}
+
+ext.setupReleaseDefines = { cppCompiler, linker ->
+    cppCompiler.args '-O2', '-g'
+}
+
+ext.setupDebugDefines = { cppCompiler, linker ->
+    cppCompiler.args '-g', '-O0'
+}
+
+ext.releaseSetup = { releaseTasks ->
+    binaries.withType(SharedLibraryBinarySpec) { binary ->
+        if (!project.hasProperty('debug')) {
+            def library = binary.sharedLibraryFile.absolutePath
+            def debugLibrary = binary.sharedLibraryFile.absolutePath + ".debug"
+            if (project.tasks.findByName("firstObjcopy${binary.name}") == null) {
+                def firstObjcopy = project.tasks.create("firstObjcopy${binary.name}", Exec) { task ->
+                    task.commandLine "${compilerPrefix}objcopy", '--only-keep-debug', library, debugLibrary
+                }
+                def strip = project.tasks.create("strip${binary.name}", Exec) { task ->
+                    task.commandLine "${compilerPrefix}strip", '-g', library
+                }
+                def secondObjcopy = project.tasks.create("secondObjcopy${binary.name}", Exec) { task ->
+                    task.commandLine "${compilerPrefix}objcopy", "--add-gnu-debuglink=$debugLibrary", library
+                }
+                secondObjcopy.dependsOn strip
+                strip.dependsOn firstObjcopy
+                binary.tasks.whenObjectAdded { task ->
+                    if (task.name.contains('link')) {
+                        firstObjcopy.dependsOn task
+                    }
+                }
+            }
+            releaseTasks.each { it.dependsOn project.tasks.getByName("secondObjcopy${binary.name}") }
+        }
+    }
+}
diff --git a/toolchains/linux.gradle b/toolchains/linux.gradle
new file mode 100644
index 0000000..415b921
--- /dev/null
+++ b/toolchains/linux.gradle
@@ -0,0 +1,70 @@
+model {
+    toolChains {
+        gcc(Gcc) {
+            target('x86') {
+                cppCompiler.withArguments { args ->
+                    args << '-std=c++11' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
+                    args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-rdynamic'
+                    //TODO: When the compiler allows us to actually call deprecated functions from within
+                    // deprecated function, remove this line (this will cause calling deprecated functions
+                    // to be treated as a warning rather than an error).
+                    args << '-Wno-error=deprecated-declarations'
+                    args << '-m32'
+                }
+                linker.withArguments { args ->
+                    args << '-rdynamic'
+                    args << '-m32'
+                }
+            }
+            target('x64') {
+                cppCompiler.withArguments { args ->
+                    args << '-std=c++11' << '-Wformat=2' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic'
+                    args << '-Wno-psabi' << '-Wno-unused-parameter' << '-fPIC' << '-rdynamic'
+                    //TODO: When the compiler allows us to actually call deprecated functions from within
+                    // deprecated function, remove this line (this will cause calling deprecated functions
+                    // to be treated as a warning rather than an error).
+                    args << '-Wno-error=deprecated-declarations'
+                }
+                linker.withArguments { args ->
+                    args << '-rdynamic'
+                }
+            }
+        }
+    }
+}
+
+ext.setupReleaseDefines = { cppCompiler, linker ->
+    cppCompiler.args '-O2', '-g'
+}
+
+ext.setupDebugDefines = { cppCompiler, linker ->
+    cppCompiler.args '-g', '-O0'
+}
+
+ext.releaseSetup = { releaseTasks ->
+    binaries.withType(SharedLibraryBinarySpec) { binary ->
+        if (!project.hasProperty('debug')) {
+            def library = binary.sharedLibraryFile.absolutePath
+            def debugLibrary = binary.sharedLibraryFile.absolutePath + ".debug"
+            if (project.tasks.findByName("firstObjcopy${binary.name}") == null) {
+                def firstObjcopy = project.tasks.create("firstObjcopy${binary.name}", Exec) { task ->
+                    task.commandLine 'objcopy', '--only-keep-debug', library, debugLibrary
+                }
+                def strip = project.tasks.create("strip${binary.name}", Exec) { task ->
+                    task.commandLine 'strip', '-g', library
+                }
+                def secondObjcopy = project.tasks.create("secondObjcopy${binary.name}", Exec) { task ->
+                    task.commandLine 'objcopy', "--add-gnu-debuglink=$debugLibrary", library
+                }
+                secondObjcopy.dependsOn strip
+                strip.dependsOn firstObjcopy
+                binary.tasks.whenObjectAdded { task ->
+                    if (task.name.contains('link')) {
+                        firstObjcopy.dependsOn task
+                    }
+                }
+            }
+            releaseTasks.each { it.dependsOn project.tasks.getByName("secondObjcopy${binary.name}") }
+        }
+    }
+}
diff --git a/toolchains/mac.gradle b/toolchains/mac.gradle
new file mode 100644
index 0000000..5ef05b7
--- /dev/null
+++ b/toolchains/mac.gradle
@@ -0,0 +1,54 @@
+model {
+    toolChains {
+        clang(Clang) {
+            target('x86') {
+                cppCompiler.withArguments { args ->
+                    args << '-std=c++11' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic-errors'
+                    args << '-fPIC' << '-m32'
+                    args << '-Wno-unused-parameter' << '-Wno-missing-field-initializers' << '-Wno-unused-private-field'
+                }
+                linker.withArguments { args ->
+                    args << '-m32'
+                }
+            }
+            target('x64') {
+                cppCompiler.withArguments { args ->
+                    args << '-std=c++11' << '-Wall' << '-Wextra' << '-Werror' << '-pedantic-errors'
+                    args << '-fPIC'
+                    args << '-Wno-missing-field-initializers' << '-Wno-unused-private-field' << '-Wno-unused-parameter'
+                }
+            }
+        }
+    }
+}
+
+ext.setupReleaseDefines = { cppCompiler, linker ->
+    cppCompiler.args '-O2'
+}
+
+ext.setupDebugDefines = { cppCompiler, linker ->
+    cppCompiler.args '-g', '-O0'
+}
+
+ext.releaseSetup = { releaseTasks ->
+    binaries.withType(SharedLibraryBinarySpec) { binary ->
+        if (!project.hasProperty('debug')) {
+            def library = binary.sharedLibraryFile.absolutePath
+            if (project.tasks.findByName("strip${binary.name}") == null) {
+                def dsymutil = project.tasks.create("dsymutil${binary.name}", Exec) { task ->
+                    task.commandLine 'dsymutil', library
+                }
+                def strip = project.tasks.create("strip${binary.name}", Exec) { task ->
+                    task.commandLine 'strip', '-S', library
+                }
+                strip.dependsOn dsymutil
+                binary.tasks.whenObjectAdded { task ->
+                    if (task.name.contains('link')) {
+                        dsymutil.dependsOn task
+                    }
+                }
+            }
+            releaseTasks.each { it.dependsOn project.tasks.getByName("strip${binary.name}") }
+        }
+    }
+}
diff --git a/toolchains/windows.gradle b/toolchains/windows.gradle
new file mode 100644
index 0000000..41d18ff
--- /dev/null
+++ b/toolchains/windows.gradle
@@ -0,0 +1,49 @@
+model {
+    toolChains {
+        visualCpp(VisualCpp) {
+            // Workaround for VS2015 adapted from https://github.com/couchbase/couchbase-lite-java-native/issues/23
+            def VS_2015_INCLUDE_DIR = "C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt"
+            def VS_2015_LIB_DIR = "C:/Program Files (x86)/Windows Kits/10/Lib/10.0.10240.0/ucrt"
+            def VS_2015_INSTALL_DIR = 'C:/Program Files (x86)/Microsoft Visual Studio 14.0'
+            def vsInstallDir = file(VS_2015_INSTALL_DIR)
+
+            // If you ever happen to install and uninstall any other version of VS, Gradle will misdetect the compiler
+            // and linker to run. This fixes that by manually setting the install dir
+            if (vsInstallDir.exists()) {
+                installDir = vsInstallDir
+            }
+
+            eachPlatform {
+                cppCompiler.withArguments { args ->
+                    args << '/EHsc' << '/DNOMINMAX' << '/D_SCL_SECURE_NO_WARNINGS' << '/D_WINSOCK_DEPRECATED_NO_WARNINGS'
+                    if (file(VS_2015_INCLUDE_DIR).exists()) {
+                        args << "/I$VS_2015_INCLUDE_DIR"
+                    }
+                }
+                linker.withArguments { args ->
+                    if (file(VS_2015_LIB_DIR).exists()) {
+                        if (platform.architecture.name == 'x86') {
+                            args << "/LIBPATH:$VS_2015_LIB_DIR/x86"
+                        } else {
+                            args << "/LIBPATH:$VS_2015_LIB_DIR/x64"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+ext.setupReleaseDefines = { cppCompiler, linker ->
+    cppCompiler.args '/O2', '/Zi', '/FS'
+    linker.args '/DEF:../ntcore.def'
+}
+
+ext.setupDebugDefines = { cppCompiler, linker ->
+    cppCompiler.args '/Zi', '/FS'
+    linker.args '/DEBUG', '/DEF:../ntcore.def'
+}
+
+// This is a noop on Windows. On gcc platforms, we strip the release binary and create a separate
+// debug library, but Windows already separates debug symbols into a .pdb file.
+ext.releaseSetup = {}