From 133540f5778ee9bd9176be5cb4736390f2aa1dde Mon Sep 17 00:00:00 2001 From: Thad House Date: Fri, 18 Aug 2017 17:52:08 -0700 Subject: [PATCH] Switches to the new build system (#87) * Removes old build system * Removes old gmock * Adds new gmock * Moves source files to new locations * Adds new build system --- .gitattributes | 1 + .gitignore | 6 +- .travis.yml | 31 ++ appveyor.yml | 21 +- build.gradle | 291 +++++++++++--- config.gradle | 229 +++++++++++ cscore-jni.def | 168 --------- cscore.def | 89 ----- cscore.gradle | 355 ------------------ dependencies.gradle | 230 ------------ gmock/build.gradle | 67 ++-- gradle/wrapper/gradle-wrapper.jar | Bin 54208 -> 54708 bytes gradle/wrapper/gradle-wrapper.properties | 11 +- gradlew | 6 +- gradlew.bat | 168 ++++----- java/java.gradle | 185 --------- publish.gradle | 280 +++++++++++--- settings.gradle | 5 - {java/arm-linux => src/arm-linux-jni}/LICENSE | 0 {java/arm-linux => src/arm-linux-jni}/jni.h | 0 .../arm-linux-jni}/linux/jni_md.h | 0 src/dev/java/edu/wpi/cscore/DevMain.java | 12 + src/dev/native/cpp/main.cpp | 6 + .../main/java}/edu/wpi/cscore/AxisCamera.java | 0 .../java}/edu/wpi/cscore/CameraServerJNI.java | 62 ++- .../main/java}/edu/wpi/cscore/CvSink.java | 0 .../main/java}/edu/wpi/cscore/CvSource.java | 0 .../main/java}/edu/wpi/cscore/HttpCamera.java | 0 .../java}/edu/wpi/cscore/MjpegServer.java | 0 .../main/java}/edu/wpi/cscore/UsbCamera.java | 0 .../java}/edu/wpi/cscore/UsbCameraInfo.java | 0 .../java}/edu/wpi/cscore/VideoCamera.java | 0 .../main/java}/edu/wpi/cscore/VideoEvent.java | 0 .../java}/edu/wpi/cscore/VideoException.java | 0 .../java}/edu/wpi/cscore/VideoListener.java | 0 .../main/java}/edu/wpi/cscore/VideoMode.java | 0 .../java}/edu/wpi/cscore/VideoProperty.java | 0 .../main/java}/edu/wpi/cscore/VideoSink.java | 0 .../java}/edu/wpi/cscore/VideoSource.java | 0 src/{ => main/native/cpp}/CvSinkImpl.cpp | 0 src/{ => main/native/cpp}/CvSinkImpl.h | 0 src/{ => main/native/cpp}/CvSourceImpl.cpp | 0 src/{ => main/native/cpp}/CvSourceImpl.h | 0 src/{ => main/native/cpp}/Frame.cpp | 0 src/{ => main/native/cpp}/Frame.h | 0 src/{ => main/native/cpp}/Handle.cpp | 0 src/{ => main/native/cpp}/Handle.h | 0 src/{ => main/native/cpp}/HttpCameraImpl.cpp | 0 src/{ => main/native/cpp}/HttpCameraImpl.h | 0 src/{ => main/native/cpp}/HttpUtil.cpp | 0 src/{ => main/native/cpp}/HttpUtil.h | 0 src/{ => main/native/cpp}/HttpUtil.inl | 0 src/{ => main/native/cpp}/Image.h | 0 src/{ => main/native/cpp}/JpegUtil.cpp | 0 src/{ => main/native/cpp}/JpegUtil.h | 0 src/{ => main/native/cpp}/Log.cpp | 0 src/{ => main/native/cpp}/Log.h | 0 src/{ => main/native/cpp}/MjpegServerImpl.cpp | 0 src/{ => main/native/cpp}/MjpegServerImpl.h | 0 src/{ => main/native/cpp}/NetworkListener.cpp | 0 src/{ => main/native/cpp}/NetworkListener.h | 0 src/{ => main/native/cpp}/Notifier.cpp | 0 src/{ => main/native/cpp}/Notifier.h | 0 src/{ => main/native/cpp}/PropertyImpl.h | 0 src/{ => main/native/cpp}/SinkImpl.cpp | 0 src/{ => main/native/cpp}/SinkImpl.h | 0 src/{ => main/native/cpp}/SourceImpl.cpp | 0 src/{ => main/native/cpp}/SourceImpl.h | 0 .../native/cpp}/UnlimitedHandleResource.h | 0 src/{ => main/native/cpp}/UsbCameraBuffer.h | 0 src/{ => main/native/cpp}/UsbCameraImpl.cpp | 0 src/{ => main/native/cpp}/UsbCameraImpl.h | 0 .../native/cpp}/UsbCameraProperty.cpp | 0 src/{ => main/native/cpp}/UsbCameraProperty.h | 0 src/{ => main/native/cpp}/UsbUtil.cpp | 0 src/{ => main/native/cpp}/UsbUtil.h | 0 src/{ => main/native/cpp}/c_util.h | 0 src/{ => main/native/cpp}/cscore_c.cpp | 0 src/{ => main/native/cpp}/cscore_cpp.cpp | 0 src/{ => main/native/cpp}/cscore_oo.cpp | 0 .../native/cpp}/default_init_allocator.h | 0 .../main/native/cpp/jni}/CameraServerJNI.cpp | 0 {include => src/main/native/include}/cscore.h | 0 .../main/native/include}/cscore_c.h | 0 .../main/native/include}/cscore_cpp.h | 0 .../main/native/include}/cscore_oo.h | 0 .../main/native/include}/cscore_oo.inl | 0 src/test/java/edu/wpi/cscore/JNITest.java | 11 + .../test/native/cpp}/CameraSourceTest.cpp | 4 +- {test/unit => src/test/native/cpp}/main.cpp | 0 test/tests.gradle | 49 --- toolchains/arm.gradle | 100 ----- toolchains/linux.gradle | 87 ----- toolchains/mac.gradle | 74 ---- toolchains/native.gradle | 25 -- toolchains/windows.gradle | 32 -- 96 files changed, 929 insertions(+), 1676 deletions(-) create mode 100644 .gitattributes create mode 100644 .travis.yml create mode 100644 config.gradle delete mode 100644 cscore-jni.def delete mode 100644 cscore.def delete mode 100644 cscore.gradle delete mode 100644 dependencies.gradle delete mode 100644 java/java.gradle rename {java/arm-linux => src/arm-linux-jni}/LICENSE (100%) rename {java/arm-linux => src/arm-linux-jni}/jni.h (100%) rename {java/arm-linux => src/arm-linux-jni}/linux/jni_md.h (100%) create mode 100644 src/dev/java/edu/wpi/cscore/DevMain.java create mode 100644 src/dev/native/cpp/main.cpp rename {java/src => src/main/java}/edu/wpi/cscore/AxisCamera.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/CameraServerJNI.java (83%) rename {java/src => src/main/java}/edu/wpi/cscore/CvSink.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/CvSource.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/HttpCamera.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/MjpegServer.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/UsbCamera.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/UsbCameraInfo.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoCamera.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoEvent.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoException.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoListener.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoMode.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoProperty.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoSink.java (100%) rename {java/src => src/main/java}/edu/wpi/cscore/VideoSource.java (100%) rename src/{ => main/native/cpp}/CvSinkImpl.cpp (100%) rename src/{ => main/native/cpp}/CvSinkImpl.h (100%) rename src/{ => main/native/cpp}/CvSourceImpl.cpp (100%) rename src/{ => main/native/cpp}/CvSourceImpl.h (100%) rename src/{ => main/native/cpp}/Frame.cpp (100%) rename src/{ => main/native/cpp}/Frame.h (100%) rename src/{ => main/native/cpp}/Handle.cpp (100%) rename src/{ => main/native/cpp}/Handle.h (100%) rename src/{ => main/native/cpp}/HttpCameraImpl.cpp (100%) rename src/{ => main/native/cpp}/HttpCameraImpl.h (100%) rename src/{ => main/native/cpp}/HttpUtil.cpp (100%) rename src/{ => main/native/cpp}/HttpUtil.h (100%) rename src/{ => main/native/cpp}/HttpUtil.inl (100%) rename src/{ => main/native/cpp}/Image.h (100%) rename src/{ => main/native/cpp}/JpegUtil.cpp (100%) rename src/{ => main/native/cpp}/JpegUtil.h (100%) rename src/{ => main/native/cpp}/Log.cpp (100%) rename src/{ => main/native/cpp}/Log.h (100%) rename src/{ => main/native/cpp}/MjpegServerImpl.cpp (100%) rename src/{ => main/native/cpp}/MjpegServerImpl.h (100%) rename src/{ => main/native/cpp}/NetworkListener.cpp (100%) rename src/{ => main/native/cpp}/NetworkListener.h (100%) rename src/{ => main/native/cpp}/Notifier.cpp (100%) rename src/{ => main/native/cpp}/Notifier.h (100%) rename src/{ => main/native/cpp}/PropertyImpl.h (100%) rename src/{ => main/native/cpp}/SinkImpl.cpp (100%) rename src/{ => main/native/cpp}/SinkImpl.h (100%) rename src/{ => main/native/cpp}/SourceImpl.cpp (100%) rename src/{ => main/native/cpp}/SourceImpl.h (100%) rename src/{ => main/native/cpp}/UnlimitedHandleResource.h (100%) rename src/{ => main/native/cpp}/UsbCameraBuffer.h (100%) rename src/{ => main/native/cpp}/UsbCameraImpl.cpp (100%) rename src/{ => main/native/cpp}/UsbCameraImpl.h (100%) rename src/{ => main/native/cpp}/UsbCameraProperty.cpp (100%) rename src/{ => main/native/cpp}/UsbCameraProperty.h (100%) rename src/{ => main/native/cpp}/UsbUtil.cpp (100%) rename src/{ => main/native/cpp}/UsbUtil.h (100%) rename src/{ => main/native/cpp}/c_util.h (100%) rename src/{ => main/native/cpp}/cscore_c.cpp (100%) rename src/{ => main/native/cpp}/cscore_cpp.cpp (100%) rename src/{ => main/native/cpp}/cscore_oo.cpp (100%) rename src/{ => main/native/cpp}/default_init_allocator.h (100%) rename {java/lib => src/main/native/cpp/jni}/CameraServerJNI.cpp (100%) rename {include => src/main/native/include}/cscore.h (100%) rename {include => src/main/native/include}/cscore_c.h (100%) rename {include => src/main/native/include}/cscore_cpp.h (100%) rename {include => src/main/native/include}/cscore_oo.h (100%) rename {include => src/main/native/include}/cscore_oo.inl (100%) create mode 100644 src/test/java/edu/wpi/cscore/JNITest.java rename {test/unit => src/test/native/cpp}/CameraSourceTest.cpp (88%) rename {test/unit => src/test/native/cpp}/main.cpp (100%) delete mode 100644 test/tests.gradle delete mode 100644 toolchains/arm.gradle delete mode 100644 toolchains/linux.gradle delete mode 100644 toolchains/mac.gradle delete mode 100644 toolchains/native.gradle delete mode 100644 toolchains/windows.gradle diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..55f724d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +gradlew.bat eol=crlf diff --git a/.gitignore b/.gitignore index fbf0a47..b3b0c73 100644 --- a/.gitignore +++ b/.gitignore @@ -27,8 +27,8 @@ .vs/ *.def -!ntcore.def -!ntcore-jni.def +!cscore.def +!cscore-jni.def *.opensdf *.vcxproj *.vcxproj.user @@ -41,7 +41,7 @@ # Build directories /.gradle -/build* +/build/ !build.gradle /native /arm diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cc60cf2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,31 @@ +language: java + +matrix: + include: + - os: linux + dist: trusty + sudo: required + - os: osx + osx_image: xcode8 + +addons: + apt: + packages: + - g++-multilib + - lib32stdc++6 + +before_install: + - .travis-scripts/install.sh + +install: + - ./gradlew build -PbuildAll + +script: + - ./gradlew build -PbuildAll + +before_cache: + - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock +cache: + directories: + - $HOME/.gradle/caches/ + - $HOME/.gradle/wrapper/ diff --git a/appveyor.yml b/appveyor.yml index d04d8e1..4bad140 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,18 +1,27 @@ version: "{branch} {build}" +image: +- Visual Studio 2015 + build: verbosity: detailed build_script: - - gradlew.bat assemble --info -PskipArm + - gradlew.bat tasks test_script: - - gradlew.bat check --info -PskipArm +- cmd: >- + SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0 + + gradlew.bat clean + + gradlew.bat check --info + + SET JAVA_HOME=C:\Program Files (x86)\Java\jdk1.8.0 + + gradlew.bat clean -environment: - matrix: - - JAVA_HOME: C:\Program Files\Java\jdk1.8.0 - - JAVA_HOME: C:\Program Files (x86)\Java\jdk1.8.0 + gradlew.bat check --info cache: - C:\Users\appveyor\.gradle diff --git a/build.gradle b/build.gradle index 83adc30..a5b74a7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,85 +1,260 @@ +import edu.wpi.first.nativeutils.NativeUtils +import org.gradle.api.file.FileCollection import org.gradle.internal.os.OperatingSystem +import edu.wpi.first.nativeutils.tasks.JNIHeaders -plugins { - id 'net.ltgt.errorprone' version '0.0.8' - id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '1.6' -} - -allprojects { +buildscript { repositories { - mavenCentral() + mavenLocal() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath 'gradle.plugin.edu.wpi.first:native-utils:1.2.11' + classpath 'gradle.plugin.edu.wpi.first.wpilib.versioning:wpilib-version-plugin:1.6' } } -ext.buildArm = !project.hasProperty('skipArm') -ext.includeJava = !project.hasProperty('skipJava') +repositories { + mavenCentral() +} -if (hasProperty('makeDesktop')) { - println 'Making desktop classifier jar. NOTE: This desktop version should only be used for local testing.' + - 'It will only support the current platform, and will override fetching the latest development version from' + - ' the maven repo until you manually delete it!' +ext.getClassifier = { binary-> + return NativeUtils.getClassifier(binary) } -ext.getPlatformPath2 = { targetPlatform -> - if (targetPlatform.architecture.arm) { - return 'Linux/arm' - } else if (targetPlatform.operatingSystem.linux) { - if (targetPlatform.architecture.amd64) { - return 'Linux/amd64' - } else { - return 'Linux/' + targetPlatform.architecture.name - } - } else if (targetPlatform.operatingSystem.windows) { - if (targetPlatform.architecture.amd64) { - return 'Windows/amd64' - } else { - return 'Windows/' + targetPlatform.architecture.name - } - } else if (targetPlatform.operatingSystem.macOsX) { - if (targetPlatform.architecture.amd64) { - return 'Mac OS X/x86_64' - } else { - return 'Mac OS X/' + targetPlatform.architecture.name +ext.getPlatformPath = { binary-> + return NativeUtils.getPlatformPath(binary) +} + +ext.getJNIHeadersClass = { + return JNIHeaders +} + +apply plugin: 'cpp' +apply plugin: 'google-test' +apply plugin: 'visual-studio' +apply plugin: 'edu.wpi.first.NativeUtils' +apply plugin: 'java' + +apply from: 'config.gradle' + +if (project.hasProperty('onlyAthena')) { + test.enabled = false +} + +sourceSets { + dev +} + +task nativeTestFilesJar(type: Jar) { + destinationDir = project.buildDir + classifier = "nativeTestFiles" + + project.model { + binaries { + withType(SharedLibraryBinarySpec) { binary -> + if (binary.component.name == 'cscoreJNI') { + from(binary.sharedLibraryFile) { + into NativeUtils.getPlatformPath(binary) + } + dependsOn binary.buildTask + } + } } - } else { - return targetPlatform.operatingSystem.name + '/' + targetPlatform.architecture.name } } -ext.getPlatformPath = { binary -> - return getPlatformPath2(binary.targetPlatform) +task run(type: JavaExec) { + classpath = sourceSets.dev.runtimeClasspath + + main = 'edu.wpi.cscore.DevMain' } -apply from: "dependencies.gradle" +test.dependsOn nativeTestFilesJar +run.dependsOn nativeTestFilesJar -ext.setupDefines = { project, binaries -> - binaries.all { - if (project.hasProperty('debug')) { - project.setupDebugDefines(cppCompiler, linker) - } else { - project.setupReleaseDefines(cppCompiler, linker) +build.dependsOn devClasses + +dependencies { + compile 'edu.wpi.first.wpiutil:wpiutil-java:+' + compile 'org.opencv:opencv-java:3.2.0' + testCompile 'junit:junit:4.12' + testRuntime files(project(':').nativeTestFilesJar.archivePath) + testRuntime 'org.opencv:opencv-jni:3.2.0:all' + devCompile 'edu.wpi.first.wpiutil:wpiutil-java:+' + devCompile 'org.opencv:opencv-java:3.2.0' + devCompile sourceSets.main.output + devRuntime files(project(':').nativeTestFilesJar.archivePath) + devRuntime 'org.opencv:opencv-jni:3.2.0:all' +} + + +model { + jniConfigs { + cscore(JNIConfig) { + jniDefinitionClasses = [ "edu.wpi.cscore.CameraServerJNI" ] + jniArmHeaderLocations = [ all: file("${rootDir}/src/arm-linux-jni") ] + sourceSets = [ project.sourceSets.main ] + } + cscoreJNI(JNIConfig) { + jniDefinitionClasses = [ "edu.wpi.cscore.CameraServerJNI" ] + jniArmHeaderLocations = [ all: file("${rootDir}/src/arm-linux-jni") ] + sourceSets = [ project.sourceSets.main ] + } + } + exportsConfigs { + cscore(ExportsConfig) { + x86ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure', + '_CT??_R0?AVbad_cast', + '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure', + '_TI5?AVfailure' ] + x64ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure', + '_CT??_R0?AVbad_cast', + '_CT??_R0?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure', + '_TI5?AVfailure' ] + } + cscoreJNI(ExportsConfig) { + x86SymbolFilter = { symbols-> + def retList = [] + symbols.each { symbol-> + if (symbol.startsWith('NT_') || symbol.startsWith('Java_') || symbol.startsWith('JNI_')) { + retList << symbol + } + } + return retList + } + x64SymbolFilter = { symbols-> + def retList = [] + symbols.each { symbol-> + if (symbol.startsWith('NT_') || symbol.startsWith('Java_') || symbol.startsWith('JNI_')) { + retList << symbol + } + } + return retList + } + } + } + dependencyConfigs { + wpiutil(DependencyConfig) { + groupId = 'edu.wpi.first.wpiutil' + artifactId = 'wpiutil-cpp' + headerClassifier = 'headers' + ext = 'zip' + version = '+' + sharedConfigs = [ cscore: [], + cscoreDev: [], + cscoreTestingBaseTest: [] ] + staticConfigs = [ cscoreJNI: [] ] + } + opencv(DependencyConfig) { + groupId = 'org.opencv' + artifactId = 'opencv-cpp' + headerClassifier = 'headers' + ext = 'zip' + version = '3.2.0' + sharedConfigs = [ cscore: [], + cscoreDev: [], + cscoreTestingBaseTest: [] ] + staticConfigs = [ cscoreJNI: [] ] + } + } + components { + cscore(NativeLibrarySpec) { + sources { + cpp { + source { + srcDirs 'src/main/native/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/main/native/include' + } + } + } + } + cscoreJNI(NativeLibrarySpec) { + baseName = 'cscore' + sources { + cpp { + source { + srcDirs 'src/main/native/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/main/native/include' + } + } + } + } + if (!project.hasProperty('skipTestExe')) { + cscoreDev(NativeExecutableSpec) { + sources { + cpp { + lib library: "cscore" + source { + srcDirs 'src/dev/native/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/dev/native/include' + } + } + } + } + } + cscoreTestingBase(NativeLibrarySpec) { } + } + testSuites { + cscoreTestingBaseTest { + sources { + cpp.source.srcDir 'src/test/native/cpp' + cpp.exportedHeaders { + srcDirs 'src/test/native/include', 'src/main/native/cpp' + } + } + } + } + binaries { + withType(StaticLibraryBinarySpec) { + if (it.component.name == 'cscoreJNI') { + it.buildable = false + } } - tasks.withType(CppCompile) { - if (!project.hasProperty('compilerPrefix') && targetPlatform.architecture.name == 'arm-v7') { - project.addWpiUtilSharedLibraryLinks(it, linker, targetPlatform) + withType(GoogleTestTestSuiteBinarySpec) { + if (it.component.testedComponent.name.contains('TestingBase') && !project.hasProperty('onlyAthena')) { + lib project: ':gmock', library: 'gmock', linkage: 'static' + lib library: 'cscore', linkage: 'shared' } else { - project.addWpiUtilStaticLibraryLinks(it, linker, targetPlatform) + it.buildable = false + } + } + } + tasks { + def c = $.components + project.tasks.create('runCpp', Exec) { + def found = false + c.each { + if (it in NativeExecutableSpec && it.name == 'cscoreDev') { + it.binaries.each { + if (!found) { + def arch = it.targetPlatform.architecture.name + if (arch == 'x86-64' || arch == 'x86') { + dependsOn it.tasks.install + commandLine it.tasks.install.runScript + found = true + } + } + } + } } - project.addOpenCvLibraryLinks(it, linker, targetPlatform) } } } -apply from: "cscore.gradle" - -// Empty task for build so that cscoreSourceZip will be -// built when running ./gradlew build -task build - -build.dependsOn cscoreSourceZip - apply from: 'publish.gradle' task wrapper(type: Wrapper) { - gradleVersion = '3.3' + gradleVersion = '4.1' } diff --git a/config.gradle b/config.gradle new file mode 100644 index 0000000..52aa269 --- /dev/null +++ b/config.gradle @@ -0,0 +1,229 @@ +import edu.wpi.first.nativeutils.* +import org.gradle.internal.os.OperatingSystem + +def windowsCompilerArgs = ['/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS', + '/Zi', '/FS', '/Zc:inline', '/MT'] +def windowsReleaseCompilerArgs = ['/O2'] +def windowsLinkerArgs = [ '/DEBUG:FULL' ] +def windowsReleaseLinkerArgs = [ '/OPT:REF', '/OPT:ICF' ] + +def linuxCompilerArgs = ['-std=c++11', '-Wformat=2', '-Wall', '-Wextra', '-Werror', '-pedantic', '-Wno-psabi', '-g', + '-Wno-unused-parameter', '-fPIC', '-rdynamic', '-Wno-error=deprecated-declarations', '-pthread'] +def linuxLinkerArgs = ['-rdynamic', '-pthread'] +def linuxReleaseCompilerArgs = ['-O2'] +def linuxDebugCompilerArgs = ['-O0'] +def linux32BitArg = '-m32' + +def macCompilerArgs = ['-std=c++11', '-Wall', '-Wextra', '-Werror', '-pedantic-errors', '-fPIC', '-g', + '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-Wno-unused-private-field'] +def macReleaseCompilerArgs = ['-O2'] +def macDebugCompilerArgs = ['-O0'] +def mac32BitArg = '-m32' + +def buildAll = project.hasProperty('buildAll') + +def windows64PlatformDetect = { + def arch = System.getProperty("os.arch") + def isWin = OperatingSystem.current().isWindows() + if (buildAll) { + return isWin + } else { + return isWin && arch == 'amd64' + } +} + +def windows32PlatformDetect = { + def arch = System.getProperty("os.arch") + def isWin = OperatingSystem.current().isWindows() + if (buildAll) { + return isWin + } else { + return isWin && arch == 'x86' + } +} + +def linux32IntelPlatformDetect = { + def arch = System.getProperty("os.arch") + def isLinux = OperatingSystem.current().isLinux() + def isIntel = (arch == 'amd64' || arch == 'i386') + if (buildAll) { + return isLinux && isIntel + } else { + return isLinux && arch == 'i386' + } +} + +def linux64IntelPlatformDetect = { + def arch = System.getProperty("os.arch") + def isLinux = OperatingSystem.current().isLinux() + def isIntel = (arch == 'amd64' || arch == 'i386') + if (buildAll) { + return isLinux && isIntel + } else { + return isLinux && arch == 'amd64' + } +} + +def linuxArmPlatformDetect = { + def arch = System.getProperty("os.arch") + def isIntel = (arch == 'amd64' || arch == 'i386') + return OperatingSystem.current().isLinux() && !isIntel +} + +def mac64PlatformDetect = { + def arch = System.getProperty("os.arch") + def isMac = OperatingSystem.current().isMacOsX() + if (buildAll) { + return isMac + } else { + return isMac && arch == 'x86_64' + } +} + +def mac32PlatformDetect = { + def arch = System.getProperty("os.arch") + def isMac = OperatingSystem.current().isMacOsX() + if (buildAll) { + return isMac + } else { + return isMac && arch == 'x86' + } +} + +if (!project.hasProperty('skipAthena')) { + model { + buildConfigs { + roboRio(CrossBuildConfig) { + architecture = 'athena' + operatingSystem = 'linux' + toolChainPrefix = 'arm-frc-linux-gnueabi-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + releaseStripBinaries = true + compilerFamily = 'Gcc' + exclude << 'gmock' + exclude << 'wpiutilTestingBase' + } + } + } +} + +if (!project.hasProperty('onlyAthena')) { + model { + buildConfigs { + winX86(BuildConfig) { + architecture = 'x86' + operatingSystem = 'windows' + compilerArgs = windowsCompilerArgs + linkerArgs = windowsLinkerArgs + releaseCompilerArgs = windowsReleaseCompilerArgs + releaseLinkerArgs = windowsReleaseLinkerArgs + compilerFamily = 'VisualCpp' + detectPlatform = windows32PlatformDetect + } + winX64(BuildConfig) { + architecture = 'x86-64' + operatingSystem = 'windows' + compilerArgs = windowsCompilerArgs + linkerArgs = windowsLinkerArgs + releaseCompilerArgs = windowsReleaseCompilerArgs + releaseLinkerArgs = windowsReleaseLinkerArgs + compilerFamily = 'VisualCpp' + detectPlatform = windows64PlatformDetect + } + linuxX86(BuildConfig) { + architecture = 'x86' + operatingSystem = 'linux' + compilerArgs = linuxCompilerArgs + compilerArgs << linux32BitArg + linkerArgs = linuxLinkerArgs + linkerArgs << linux32BitArg + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + compilerFamily = 'Gcc' + detectPlatform = linux32IntelPlatformDetect + } + linuxX64(BuildConfig) { + architecture = 'x86-64' + operatingSystem = 'linux' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + compilerFamily = 'Gcc' + detectPlatform = linux64IntelPlatformDetect + } + /* 32 bit Mac OS X not supported by OpenCV. + * If support is ever added, will add this back in + macX86(BuildConfig) { + architecture = 'x86' + operatingSystem = 'osx' + compilerArgs = macCompilerArgs + compilerArgs << mac32BitArg + linkerArgs << mac32BitArg + debugCompilerArgs = macDebugCompilerArgs + releaseCompilerArgs = macReleaseCompilerArgs + compilerFamily = 'Clang' + detectPlatform = mac32PlatformDetect + } + */ + macX64(BuildConfig) { + architecture = 'x86-64' + operatingSystem = 'osx' + compilerArgs = macCompilerArgs + debugCompilerArgs = macDebugCompilerArgs + releaseCompilerArgs = macReleaseCompilerArgs + compilerFamily = 'Clang' + detectPlatform = mac64PlatformDetect + } + raspbian(CrossBuildConfig) { + architecture = 'raspbian' + operatingSystem = 'linux' + toolChainPrefix = 'arm-linux-gnueabihf-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + skipByDefault = true + compilerFamily = 'Gcc' + exclude << 'gmock' + } + armhf(CrossBuildConfig) { + architecture = 'armhf' + operatingSystem = 'linux' + toolChainPrefix = 'arm-linux-gnueabihf-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + skipByDefault = true + compilerFamily = 'Gcc' + exclude << 'gmock' + } + aarch(CrossBuildConfig) { + architecture = 'aarch' + operatingSystem = 'linux' + toolChainPrefix = 'aarch-linux-gnu-' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + skipByDefault = true + compilerFamily = 'Gcc' + exclude << 'gmock' + } + linuxArm(BuildConfig) { + architecture = 'arm' + operatingSystem = 'linux' + compilerArgs = linuxCompilerArgs + linkerArgs = linuxLinkerArgs + debugCompilerArgs = linuxDebugCompilerArgs + releaseCompilerArgs = linuxReleaseCompilerArgs + compilerFamily = 'Gcc' + detectPlatform = linuxArmPlatformDetect + } + } + } +} diff --git a/cscore-jni.def b/cscore-jni.def deleted file mode 100644 index f921cde..0000000 --- a/cscore-jni.def +++ /dev/null @@ -1,168 +0,0 @@ -LIBRARY CSCORE -EXPORTS -CS_GetPropertyKind @1 -CS_GetPropertyName @2 -CS_GetProperty @3 -CS_SetProperty @4 -CS_GetPropertyMin @5 -CS_GetPropertyMax @6 -CS_GetPropertyStep @7 -CS_GetPropertyDefault @8 -CS_GetStringProperty @9 -CS_SetStringProperty @10 -CS_GetEnumPropertyChoices @11 -CS_CreateUsbCameraDev @12 -CS_CreateUsbCameraPath @13 -CS_CreateHttpCamera @14 -CS_CreateHttpCameraMulti @15 -CS_CreateCvSource @16 -CS_GetSourceName @17 -CS_GetSourceDescription @18 -CS_GetSourceLastFrameTime @19 -CS_IsSourceConnected @20 -CS_GetSourceProperty @21 -CS_EnumerateSourceProperties @22 -CS_CopySource @23 -CS_ReleaseSource @24 -CS_PutSourceFrameCpp @25 -CS_NotifySourceError @26 -CS_SetSourceConnected @27 -CS_CreateSourceProperty @28 -CS_CreateCvSink @29 -CS_CreateCvSinkCallback @30 -CS_GetSinkName @31 -CS_GetSinkDescription @32 -CS_SetSinkSource @33 -CS_GetSinkSourceProperty @34 -CS_GetSinkSource @35 -CS_CopySink @36 -CS_ReleaseSink @37 -CS_GrabSinkFrameCpp @38 -CS_GetSinkError @39 -CS_SetSinkEnabled @40 -CS_EnumerateUsbCameras @41 -CS_FreeEnumeratedUsbCameras @42 -CS_EnumerateSources @43 -CS_ReleaseEnumeratedSources @44 -CS_EnumerateSinks @45 -CS_ReleaseEnumeratedSinks @46 -CS_FreeString @47 -CS_FreeEnumPropertyChoices @48 -CS_FreeEnumeratedProperties @49 -CS_SetSinkDescription @50 -CS_GetSinkKind @51 -CS_GetSourceKind @52 -CS_GetSourceVideoMode @53 -CS_SetSourceVideoModeDiscrete @54 -CS_SetSourcePixelFormat @55 -CS_SetSourceResolution @56 -CS_SetSourceFPS @57 -CS_EnumerateSourceVideoModes @58 -CS_EnumerateSourceSinks @59 -CS_FreeEnumeratedVideoModes @60 -CS_SetSourceDescription @61 -CS_SetSourceEnumPropertyChoices @62 -CS_CreateMjpegServer @63 -CS_GetMjpegServerListenAddress @64 -CS_GetMjpegServerPort @65 -CS_GetUsbCameraPath @66 -CS_AddListener @67 -CS_RemoveListener @68 -CS_GetHostname @69 -CS_GetNetworkInterfaces @70 -CS_FreeNetworkInterfaces @71 -CS_FreeHttpCameraUrls @72 -CS_GetHttpCameraKind @73 -CS_GetHttpCameraUrls @74 -CS_SetHttpCameraUrls @75 -CS_SetLogger @76 -CS_SetCameraBrightness @77 -CS_GetCameraBrightness @78 -CS_SetCameraWhiteBalanceAuto @79 -CS_SetCameraWhiteBalanceHoldCurrent @80 -CS_SetCameraWhiteBalanceManual @81 -CS_SetCameraExposureAuto @82 -CS_SetCameraExposureHoldCurrent @83 -CS_SetCameraExposureManual @84 -CS_SetDefaultLogger @85 -CS_GrabSinkFrameTimeout @86 -CS_GrabSinkFrameTimeoutCpp @87 - -; JNI functions -JNI_OnLoad -JNI_OnUnload -Java_edu_wpi_cscore_CameraServerJNI_getPropertyKind -Java_edu_wpi_cscore_CameraServerJNI_getPropertyName -Java_edu_wpi_cscore_CameraServerJNI_getProperty -Java_edu_wpi_cscore_CameraServerJNI_setProperty -Java_edu_wpi_cscore_CameraServerJNI_getPropertyMin -Java_edu_wpi_cscore_CameraServerJNI_getPropertyMax -Java_edu_wpi_cscore_CameraServerJNI_getPropertyStep -Java_edu_wpi_cscore_CameraServerJNI_getPropertyDefault -Java_edu_wpi_cscore_CameraServerJNI_getStringProperty -Java_edu_wpi_cscore_CameraServerJNI_setStringProperty -Java_edu_wpi_cscore_CameraServerJNI_getEnumPropertyChoices -Java_edu_wpi_cscore_CameraServerJNI_createUsbCameraDev -Java_edu_wpi_cscore_CameraServerJNI_createUsbCameraPath -Java_edu_wpi_cscore_CameraServerJNI_createHttpCamera -Java_edu_wpi_cscore_CameraServerJNI_createHttpCameraMulti -Java_edu_wpi_cscore_CameraServerJNI_createCvSource -Java_edu_wpi_cscore_CameraServerJNI_getSourceKind -Java_edu_wpi_cscore_CameraServerJNI_getSourceName -Java_edu_wpi_cscore_CameraServerJNI_getSourceDescription -Java_edu_wpi_cscore_CameraServerJNI_getSourceLastFrameTime -Java_edu_wpi_cscore_CameraServerJNI_isSourceConnected -Java_edu_wpi_cscore_CameraServerJNI_getSourceProperty -Java_edu_wpi_cscore_CameraServerJNI_enumerateSourceProperties -Java_edu_wpi_cscore_CameraServerJNI_getSourceVideoMode -Java_edu_wpi_cscore_CameraServerJNI_setSourceVideoMode -Java_edu_wpi_cscore_CameraServerJNI_setSourcePixelFormat -Java_edu_wpi_cscore_CameraServerJNI_setSourceResolution -Java_edu_wpi_cscore_CameraServerJNI_setSourceFPS -Java_edu_wpi_cscore_CameraServerJNI_enumerateSourceVideoModes -Java_edu_wpi_cscore_CameraServerJNI_enumerateSourceSinks -Java_edu_wpi_cscore_CameraServerJNI_copySource -Java_edu_wpi_cscore_CameraServerJNI_releaseSource -Java_edu_wpi_cscore_CameraServerJNI_setCameraBrightness -Java_edu_wpi_cscore_CameraServerJNI_getCameraBrightness -Java_edu_wpi_cscore_CameraServerJNI_setCameraWhiteBalanceAuto -Java_edu_wpi_cscore_CameraServerJNI_setCameraWhiteBalanceHoldCurrent -Java_edu_wpi_cscore_CameraServerJNI_setCameraWhiteBalanceManual -Java_edu_wpi_cscore_CameraServerJNI_setCameraExposureAuto -Java_edu_wpi_cscore_CameraServerJNI_setCameraExposureHoldCurrent -Java_edu_wpi_cscore_CameraServerJNI_setCameraExposureManual -Java_edu_wpi_cscore_CameraServerJNI_getUsbCameraPath -Java_edu_wpi_cscore_CameraServerJNI_getHttpCameraKind -Java_edu_wpi_cscore_CameraServerJNI_setHttpCameraUrls -Java_edu_wpi_cscore_CameraServerJNI_getHttpCameraUrls -Java_edu_wpi_cscore_CameraServerJNI_putSourceFrame -Java_edu_wpi_cscore_CameraServerJNI_notifySourceError -Java_edu_wpi_cscore_CameraServerJNI_setSourceConnected -Java_edu_wpi_cscore_CameraServerJNI_setSourceDescription -Java_edu_wpi_cscore_CameraServerJNI_createSourceProperty -Java_edu_wpi_cscore_CameraServerJNI_setSourceEnumPropertyChoices -Java_edu_wpi_cscore_CameraServerJNI_createMjpegServer -Java_edu_wpi_cscore_CameraServerJNI_createCvSink -Java_edu_wpi_cscore_CameraServerJNI_getSinkKind -Java_edu_wpi_cscore_CameraServerJNI_getSinkName -Java_edu_wpi_cscore_CameraServerJNI_getSinkDescription -Java_edu_wpi_cscore_CameraServerJNI_setSinkSource -Java_edu_wpi_cscore_CameraServerJNI_getSinkSourceProperty -Java_edu_wpi_cscore_CameraServerJNI_getSinkSource -Java_edu_wpi_cscore_CameraServerJNI_copySink -Java_edu_wpi_cscore_CameraServerJNI_releaseSink -Java_edu_wpi_cscore_CameraServerJNI_getMjpegServerListenAddress -Java_edu_wpi_cscore_CameraServerJNI_getMjpegServerPort -Java_edu_wpi_cscore_CameraServerJNI_setSinkDescription -Java_edu_wpi_cscore_CameraServerJNI_grabSinkFrame -Java_edu_wpi_cscore_CameraServerJNI_grabSinkFrameTimeout -Java_edu_wpi_cscore_CameraServerJNI_getSinkError -Java_edu_wpi_cscore_CameraServerJNI_setSinkEnabled -Java_edu_wpi_cscore_CameraServerJNI_addListener -Java_edu_wpi_cscore_CameraServerJNI_removeListener -Java_edu_wpi_cscore_CameraServerJNI_setLogger -Java_edu_wpi_cscore_CameraServerJNI_enumerateUsbCameras -Java_edu_wpi_cscore_CameraServerJNI_enumerateSources -Java_edu_wpi_cscore_CameraServerJNI_enumerateSinks -Java_edu_wpi_cscore_CameraServerJNI_getHostname -Java_edu_wpi_cscore_CameraServerJNI_getNetworkInterfaces diff --git a/cscore.def b/cscore.def deleted file mode 100644 index 95ccd5b..0000000 --- a/cscore.def +++ /dev/null @@ -1,89 +0,0 @@ -LIBRARY CSCORE -EXPORTS -CS_GetPropertyKind @1 -CS_GetPropertyName @2 -CS_GetProperty @3 -CS_SetProperty @4 -CS_GetPropertyMin @5 -CS_GetPropertyMax @6 -CS_GetPropertyStep @7 -CS_GetPropertyDefault @8 -CS_GetStringProperty @9 -CS_SetStringProperty @10 -CS_GetEnumPropertyChoices @11 -CS_CreateUsbCameraDev @12 -CS_CreateUsbCameraPath @13 -CS_CreateHttpCamera @14 -CS_CreateHttpCameraMulti @15 -CS_CreateCvSource @16 -CS_GetSourceName @17 -CS_GetSourceDescription @18 -CS_GetSourceLastFrameTime @19 -CS_IsSourceConnected @20 -CS_GetSourceProperty @21 -CS_EnumerateSourceProperties @22 -CS_CopySource @23 -CS_ReleaseSource @24 -CS_PutSourceFrameCpp @25 -CS_NotifySourceError @26 -CS_SetSourceConnected @27 -CS_CreateSourceProperty @28 -CS_CreateCvSink @29 -CS_CreateCvSinkCallback @30 -CS_GetSinkName @31 -CS_GetSinkDescription @32 -CS_SetSinkSource @33 -CS_GetSinkSourceProperty @34 -CS_GetSinkSource @35 -CS_CopySink @36 -CS_ReleaseSink @37 -CS_GrabSinkFrameCpp @38 -CS_GetSinkError @39 -CS_SetSinkEnabled @40 -CS_EnumerateUsbCameras @41 -CS_FreeEnumeratedUsbCameras @42 -CS_EnumerateSources @43 -CS_ReleaseEnumeratedSources @44 -CS_EnumerateSinks @45 -CS_ReleaseEnumeratedSinks @46 -CS_FreeString @47 -CS_FreeEnumPropertyChoices @48 -CS_FreeEnumeratedProperties @49 -CS_SetSinkDescription @50 -CS_GetSinkKind @51 -CS_GetSourceKind @52 -CS_GetSourceVideoMode @53 -CS_SetSourceVideoModeDiscrete @54 -CS_SetSourcePixelFormat @55 -CS_SetSourceResolution @56 -CS_SetSourceFPS @57 -CS_EnumerateSourceVideoModes @58 -CS_EnumerateSourceSinks @59 -CS_FreeEnumeratedVideoModes @60 -CS_SetSourceDescription @61 -CS_SetSourceEnumPropertyChoices @62 -CS_CreateMjpegServer @63 -CS_GetMjpegServerListenAddress @64 -CS_GetMjpegServerPort @65 -CS_GetUsbCameraPath @66 -CS_AddListener @67 -CS_RemoveListener @68 -CS_GetHostname @69 -CS_GetNetworkInterfaces @70 -CS_FreeNetworkInterfaces @71 -CS_FreeHttpCameraUrls @72 -CS_GetHttpCameraKind @73 -CS_GetHttpCameraUrls @74 -CS_SetHttpCameraUrls @75 -CS_SetLogger @76 -CS_SetCameraBrightness @77 -CS_GetCameraBrightness @78 -CS_SetCameraWhiteBalanceAuto @79 -CS_SetCameraWhiteBalanceHoldCurrent @80 -CS_SetCameraWhiteBalanceManual @81 -CS_SetCameraExposureAuto @82 -CS_SetCameraExposureHoldCurrent @83 -CS_SetCameraExposureManual @84 -CS_SetDefaultLogger @85 -CS_GrabSinkFrameTimeout @86 -CS_GrabSinkFrameTimeoutCpp @87 diff --git a/cscore.gradle b/cscore.gradle deleted file mode 100644 index a0119cf..0000000 --- a/cscore.gradle +++ /dev/null @@ -1,355 +0,0 @@ -import org.gradle.internal.os.OperatingSystem - -def cscoreSetupModel = { project -> - project.model { - components { - cscore(NativeLibrarySpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - //targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - - if (includeJava) { - project.setupJniIncludes(binaries) - project.checkNativeSymbols(project.getNativeJNISymbols) - binaries.all { - project.setupDef(linker, "${rootDir}/cscore-jni.def") - } - } else { - binaries.all { - project.setupDef(linker, "${rootDir}/cscore.def") - } - } - - sources { - cpp { - source { - srcDirs = ["${rootDir}/src"] - if (includeJava) { - srcDirs "${rootDir}/java/lib" - } - includes = ['**/*.cpp'] - } - exportedHeaders { - srcDirs = ["${rootDir}/include", project.wpiUtilInclude, project.openCvInclude] - if (includeJava) { - project.jniHeadersCscore.outputs.files.each { file -> - srcDirs file.getPath() - } - } - includes = ['**/*.h'] - } - } - } - } - } - } -} - -def cscoreSetupExamplesModel = { project -> - project.model { - components { - if (!OperatingSystem.current().isWindows() || project.isArm) { - enum_usb(NativeExecutableSpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - //targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - sources { - cpp { - source { - srcDir "${rootDir}/examples/enum_usb" - include '**/*.cpp' - } - exportedHeaders { - srcDirs = ["${rootDir}/include", "${rootDir}/wpiutil/include"] - include '**/*.h' - } - lib library: 'cscore', linkage: 'static' - } - } - } - - usbstream(NativeExecutableSpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - //targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - sources { - cpp { - source { - srcDir "${rootDir}/examples/usbstream" - include '**/*.cpp' - } - exportedHeaders { - srcDirs = ["${rootDir}/include", "${rootDir}/wpiutil/include"] - include '**/*.h' - } - lib library: 'cscore', linkage: 'static' - } - } - } - - usbcvstream(NativeExecutableSpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - //targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - sources { - cpp { - source { - srcDir "${rootDir}/examples/usbcvstream" - include '**/*.cpp' - } - exportedHeaders { - srcDirs = ["${rootDir}/include", "${rootDir}/wpiutil/include", project.openCvInclude] - include '**/*.h' - } - lib library: 'cscore', linkage: 'static' - } - } - } - - settings(NativeExecutableSpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - //targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - sources { - cpp { - source { - srcDir "${rootDir}/examples/settings" - include '**/*.cpp' - } - exportedHeaders { - srcDirs = ["${rootDir}/include", "${rootDir}/wpiutil/include", project.openCvInclude] - include '**/*.h' - } - lib library: 'cscore', linkage: 'static' - } - } - } - } - - httpcvstream(NativeExecutableSpec) { - if (project.isArm) { - targetPlatform 'arm' - } else { - //targetPlatform 'x86' - targetPlatform 'x64' - } - setupDefines(project, binaries) - sources { - cpp { - source { - srcDir "${rootDir}/examples/httpcvstream" - include '**/*.cpp' - } - exportedHeaders { - srcDirs = ["${rootDir}/include", "${rootDir}/wpiutil/include", project.openCvInclude] - include '**/*.h' - } - lib library: 'cscore', linkage: 'static' - } - } - } - } - } -} - -def cscoreZipTask = { project -> - project.ext.cscoreZip = project.tasks.create("${project.isArm ? 'arm' : 'native'}CscoreZip", Zip) { - description = 'Creates platform-specific zip of the desktop cscore libraries.' - group = 'WPILib' - destinationDir = project.buildDir - baseName = 'cscore' - if (project.isArm && project.hasProperty('compilerPrefix') - && project.hasProperty('armSuffix')) { - classifier = "${project.buildPlatform}${project.armSuffix}" - } else { - classifier = "${project.buildPlatform}" - } - duplicatesStrategy = 'exclude' - - from(file('include')) { - into 'include' - } - - if (!project.hasProperty('skipJava')) { - project.jniHeadersCscore.outputs.each { - from(it) { - into 'include' - } - } - } - - project.model { - binaries { - withType(StaticLibraryBinarySpec) { binary -> - from(binary.staticLibraryFile) { - into getPlatformPath(binary) - } - } - withType(SharedLibraryBinarySpec) { binary -> - from(binary.sharedLibraryFile) { - into getPlatformPath(binary) - } - from (new File(binary.sharedLibraryFile.absolutePath + ".debug")) { - into getPlatformPath(binary) - } - } - } - } - } - - project.build.dependsOn project.cscoreZip - - project.debugStripSetup() - - project.tasks.whenTaskAdded { task -> - def name = task.name.toLowerCase() - if (name.contains("cscoresharedlibrary") || name.contains("cscorestaticlibrary") || name.contains("cscoretest")) { - project.cscoreZip.dependsOn task - } - } -} - -def cscoreAthenaUberZipTask = { pjt -> - if (pjt.isArm && !project.hasProperty('compilerPrefix')) { - pjt.ext.cscoreAthenaUberZip = pjt.tasks.create("athenaCscoreUberZip", Zip) { - description = 'Create athena zip of cscore libraries including opencv' - group = 'WPILib' - destinationDir = pjt.buildDir - baseName = 'cscore' - classifier = 'athena-uberzip' - duplicatesStrategy = 'exclude' - - from(file('include')) { - into 'include' - } - - if (!pjt.hasProperty('skipJava')) { - pjt.jniHeadersCscore.outputs.each { - from(it) { - into 'include' - } - } - } - - from(file("${pjt.openCvInclude}")) { - exclude 'META-INF' - into 'include' - } - - pjt.model { - def openCvPlatform = pjt.getOpenCvPlatformPackage(targetPlatform) - from(file("${pjt.openCv}/${openCvPlatform}")) { - exclude 'META-INF' - into 'lib' - } - binaries { - withType(SharedLibraryBinarySpec) { binary -> - from(binary.sharedLibraryFile) { - into 'lib' - } - from (new File(binary.sharedLibraryFile.absolutePath + ".debug")) { - into 'lib' - } - } - } - } - } - - pjt.build.dependsOn pjt.cscoreAthenaUberZip - - pjt.tasks.whenTaskAdded { task -> - def name = task.name.toLowerCase() - if (name.contains("cscoresharedlibrary") || name.contains("cscorestaticlibrary") || name.contains("cscoretest")) { - pjt.cscoreAthenaUberZip.dependsOn task - } - } - } -} - -if (buildArm) { - project(':arm') { - apply plugin: 'cpp' - - apply from: "${rootDir}/toolchains/arm.gradle" - if (includeJava) { - apply from: "${rootDir}/java/java.gradle" - } - - cscoreSetupModel(project) - cscoreSetupExamplesModel(project) - cscoreZipTask(project) - useWpiUtil(project) - useOpenCv(project) - cscoreAthenaUberZipTask(project) - } -} - -project(':native') { - apply plugin: 'cpp' - - apply from: "${rootDir}/toolchains/native.gradle" - - //if (!project.hasProperty("withoutTests")) { - // apply from: "${rootDir}/test/tests.gradle" - //} - - if (includeJava) { - apply from: "${rootDir}/java/java.gradle" - } - - cscoreSetupModel(project) - cscoreSetupExamplesModel(project) - cscoreZipTask(project) - useWpiUtil(project) - useOpenCv(project) -} - -task cscoreSourceZip(type: Zip) { - description = 'Creates a sources-zip of the cscore source files' - group = 'WPILib' - destinationDir = project.buildDir - baseName = 'cscore' - classifier = "sources" - duplicatesStrategy = 'exclude' - - from('src') { - into 'src' - } - - from('include') { - into 'include' - } - - if (includeJava) { - from('java/lib') { - into 'src' - } - if (!OperatingSystem.current().isWindows()) { - project(':native').jniHeadersCscore.outputs.each { - from(it) { - into 'include' - } - } - } - } -} diff --git a/dependencies.gradle b/dependencies.gradle deleted file mode 100644 index a72e2bf..0000000 --- a/dependencies.gradle +++ /dev/null @@ -1,230 +0,0 @@ -ext.useWpiUtil = { project -> - project.tasks.create(name: "downloadWpiUtil") { - description = 'Downloads the wpiutil maven dependency.' - group = 'WPILib' - def depFolder = "${project.buildDir}/dependencies" - def utilZip = file("${depFolder}/wpiutil.zip") - outputs.file(utilZip) - def wpiUtil - - doFirst { - def wpiUtilDependency - if (project.isArm && project.hasProperty('compilerPrefix') && project.hasProperty('armSuffix')) { - wpiUtilDependency = project.dependencies.create("edu.wpi.first.wpilib:wpiutil:+:arm${project.armSuffix}@zip") - } else { - wpiUtilDependency = project.dependencies.create("edu.wpi.first.wpilib:wpiutil:+:${project.isArm ? 'arm' : 'desktop'}@zip") - } - - def wpiUtilConfig = project.configurations.detachedConfiguration(wpiUtilDependency) - wpiUtilConfig.setTransitive(false) - wpiUtil = wpiUtilConfig.files[0].canonicalFile - } - - doLast { - copy { - from wpiUtil - rename 'wpiutil(.+)', 'wpiutil.zip' - into depFolder - } - } - } - - def wpiUtilUnzipLocation = "${project.buildDir}/wpiutil" - - // Create a task that will unzip the wpiutil files into a temporary build directory - project.tasks.create(name: "unzipWpiUtil", type: Copy) { - description = 'Unzips the wpiutil maven dependency so that the include files and libraries can be used' - group = 'WPILib' - dependsOn project.tasks.downloadWpiUtil - from zipTree(project.tasks.downloadWpiUtil.outputs.files.singleFile) - into wpiUtilUnzipLocation - } - - project.ext.wpiUtil = wpiUtilUnzipLocation - project.ext.wpiUtilInclude = "$wpiUtilUnzipLocation/include" - - project.ext.addWpiUtilStaticLibraryLinks = { compileTask, linker, targetPlatform -> - compileTask.dependsOn project.tasks.unzipWpiUtil - String path = project.getPlatformPath2(targetPlatform) - if (targetPlatform.operatingSystem.windows) { - linker.args "${project.wpiUtil}/${path}/wpiutil.lib" - } else { - linker.args "${project.wpiUtil}/${path}/libwpiutil.a" - } - } - - project.ext.addWpiUtilSharedLibraryLinks = { compileTask, linker, targetPlatform -> - compileTask.dependsOn project.tasks.unzipWpiUtil - String path = project.getPlatformPath2(targetPlatform) - if (targetPlatform.operatingSystem.windows) { - linker.args "${project.wpiUtil}/${path}/wpiutil.dll" - } else { - linker.args "${project.wpiUtil}/${path}/libwpiutil.so" - } - } -} - -ext.getOpenCvPlatformPackage = { targetPlatform -> - if (targetPlatform.architecture.arm && project.hasProperty('compilerPrefix') && project.hasProperty('armSuffix')) { - return "linux-arm${project.armSuffix}" - } else if (targetPlatform.architecture.arm) { - return 'linux-arm' - } else if (targetPlatform.operatingSystem.linux) { - if (targetPlatform.architecture.amd64) { - return 'linux-x86_64' - } else { - return 'linux-' + targetPlatform.architecture.name - } - } else if (targetPlatform.operatingSystem.windows) { - if (targetPlatform.architecture.amd64) { - return 'windows-x86_64' - } else { - return 'windows-' + targetPlatform.architecture.name - } - } else if (targetPlatform.operatingSystem.macOsX) { - if (targetPlatform.architecture.amd64) { - return 'osx-x86_64' - } else { - return 'osx-' + targetPlatform.architecture.name - } - } else { - return targetPlatform.operatingSystem.name + '-' + targetPlatform.architecture.name - } -} - -task downloadOpenCvHeaders() { - description = 'Downloads the OpenCV Headers maven dependency.' - group = 'WPILib' - def depFolder = "${buildDir}/dependencies" - def openCvHeadersZip = file("${depFolder}/opencv-headers.zip") - outputs.file(openCvHeadersZip) - def openCvHeaders - - doFirst { - def openCvHeadersDependency = project.dependencies.create("org.opencv:opencv-headers:3.1.0@jar") - def openCvHeadersConfig = project.configurations.detachedConfiguration(openCvHeadersDependency) - openCvHeadersConfig.setTransitive(false) - openCvHeaders = openCvHeadersConfig.files[0].canonicalFile - } - - doLast { - copy { - from openCvHeaders - rename 'opencv-headers(.+)', 'opencv-headers.zip' - into depFolder - } - } -} - -ext.useOpenCv = { project -> - def openCvUnzipLocation = "${project.buildDir}/opencv" - - project.tasks.create(name: "unzipOpenCvHeaders", type: Copy) { - description = 'Unzips the OpenCV maven dependency so that the include files and libraries can be used' - group = 'OpenCv' - dependsOn downloadOpenCvHeaders - from zipTree(downloadOpenCvHeaders.outputs.files.singleFile) - into "${openCvUnzipLocation}/include" - } - - project.ext.openCv = openCvUnzipLocation - project.ext.openCvInclude = "$openCvUnzipLocation/include" - - project.ext.addOpenCvLibraryLinks = { compileTask, linker, targetPlatform -> - def openCvPlatform = project.getOpenCvPlatformPackage(targetPlatform) - def openCvNativesFolder = "${project.openCv}/${openCvPlatform}" - - if (project.tasks.findByPath("unzipOpenCvNatives_${openCvPlatform}") == null) { - project.tasks.create(name: "downloadOpenCvNatives_${openCvPlatform}") { - description = 'Downloads the OpenCV natives maven dependency.' - group = 'OpenCv' - def depFolder = "${project.buildDir}/dependencies" - def openCvNativesZip = file("${depFolder}/opencv-natives-${openCvPlatform}.zip") - outputs.file(openCvNativesZip) - def openCvNatives - - doFirst { - def openCvNativesDependency = project.dependencies.create("org.opencv:opencv-natives:3.1.0:${openCvPlatform}@jar") - def openCvNativesConfig = project.configurations.detachedConfiguration(openCvNativesDependency) - openCvNativesConfig.setTransitive(false) - openCvNatives = openCvNativesConfig.files[0].canonicalFile - } - - doLast { - copy { - from openCvNatives - rename 'opencv-natives(.+)', "opencv-natives-${openCvPlatform}.zip" - into depFolder - } - } - } - - project.tasks.create(name: "unzipOpenCvNatives_${openCvPlatform}", type: Copy) { - description = 'Unzips the OpenCV maven dependency so that the include files and libraries can be used' - group = 'OpenCv' - dependsOn "downloadOpenCvNatives_${openCvPlatform}" - from zipTree(project.tasks["downloadOpenCvNatives_${openCvPlatform}"].outputs.files.singleFile) - into openCvNativesFolder - exclude '**/MANIFEST.MF' - } - } - - if (project.includeJava && project.tasks.findByPath("unzipOpenCvJni_${openCvPlatform}") == null) { - project.tasks.create(name: "downloadOpenCvJni_${openCvPlatform}") { - description = 'Downloads the OpenCV JNI maven dependency.' - group = 'OpenCv' - def depFolder = "${project.buildDir}/dependencies" - def openCvJniZip = file("${depFolder}/opencv-jni-${openCvPlatform}.zip") - outputs.file(openCvJniZip) - def openCvJni - - doFirst { - def openCvJniDependency = project.dependencies.create("org.opencv:opencv-jni:3.1.0:${openCvPlatform}@jar") - def openCvJniConfig = project.configurations.detachedConfiguration(openCvJniDependency) - openCvJniConfig.setTransitive(false) - openCvJni = openCvJniConfig.files[0].canonicalFile - } - - doLast { - copy { - from openCvJni - rename 'opencv-jni(.+)', "opencv-jni-${openCvPlatform}.zip" - into depFolder - } - } - } - - project.tasks.create(name: "unzipOpenCvJni_${openCvPlatform}", type: Copy) { - description = 'Unzips the OpenCV maven dependency so that the include files and libraries can be used' - group = 'OpenCv' - dependsOn "downloadOpenCvJni_${openCvPlatform}" - from zipTree(project.tasks["downloadOpenCvJni_${openCvPlatform}"].outputs.files.singleFile) - into openCvNativesFolder - exclude '**/MANIFEST.MF' - } - } - - compileTask.dependsOn "unzipOpenCvHeaders", "unzipOpenCvNatives_${openCvPlatform}" - if (project.includeJava) { - compileTask.dependsOn "unzipOpenCvJni_${openCvPlatform}" - } - if (targetPlatform.operatingSystem.windows) { - linker.args new String("${openCvNativesFolder}\\opencv.lib").replace('/', '\\') - linker.args new String("${openCvNativesFolder}\\Release\\libjpeg.lib").replace('/', '\\') - linker.args new String("${openCvNativesFolder}\\Release\\libpng.lib").replace('/', '\\') - linker.args new String("${openCvNativesFolder}\\Release\\zlib.lib").replace('/', '\\') - linker.args "kernel32.lib" - linker.args "user32.lib" - linker.args "gdi32.lib" - linker.args "Ole32.lib" - linker.args "OleAut32.lib" - linker.args "comdlg32.lib" - linker.args "advapi32.lib" - linker.args "Vfw32.lib" - } else { - linker.args "-L${openCvNativesFolder}" - linker.args "-lopencv" - linker.args "-ldl" - } - } -} diff --git a/gmock/build.gradle b/gmock/build.gradle index 809c55c..51ff139 100644 --- a/gmock/build.gradle +++ b/gmock/build.gradle @@ -1,49 +1,38 @@ import org.gradle.internal.os.OperatingSystem -apply plugin: 'cpp' -apply plugin: 'visual-studio' +if (!project.hasProperty('onlyAthena')) { + apply plugin: 'cpp' + apply plugin: 'visual-studio' + apply plugin: 'edu.wpi.first.NativeUtils' -// Apply the correct toolchain settings for the target platform -if (OperatingSystem.current().isLinux()) { - apply from: '../toolchains/linux.gradle' -} else if (OperatingSystem.current().isMacOsX()) { - apply from: '../toolchains/mac.gradle' -} else if (OperatingSystem.current().isWindows()) { - apply from: '../toolchains/windows.gradle' -} else { - throw new GradleException("ntcore does not support building on ${OperatingSystem.current().getFamilyName()}.") -} + ext.gmockProject = true -model { - platforms { - x86 { - architecture 'x86' - } - x64 { - architecture 'x86_64' - } - } - components { - gmock(NativeLibrarySpec) { - targetPlatform 'x86' - targetPlatform 'x64' - sources { - cpp { - source { - srcDirs = ['src', 'gtest/src'] - includes = ['*-all.cc'] + apply from: '../config.gradle' + + model { + components { + gmock(NativeLibrarySpec) { + sources { + cpp { + source { + srcDirs = ['src', 'gtest/src'] + includes = ['*-all.cc'] + } + exportedHeaders { + srcDirs = ['include', 'gtest/include', '.', 'gtest'] + includes = ['**/*.h', '**/*.cc'] + } } - exportedHeaders { - srcDirs = ['include', 'gtest/include', '.', 'gtest'] - includes = ['**/*.h', '**/*.cc'] + } + binaries.all { + if (toolChain in VisualCpp) { + cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1' + } else { + cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-pthread', '-fPIC' } } - } - binaries.all { - if (toolChain in VisualCpp) { - cppCompiler.args '-D_UNICODE', '-DUNICODE', '-DWIN32', '-D_WIN32', '-DSTRICT', '-DWIN32_LEAN_AND_MEAN', '-D_HAS_EXCEPTIONS=1' - } else { - cppCompiler.args '-Wall', '-Wshadow', '-fexceptions', '-Wextra', '-Wno-unused-parameter', '-Wno-missing-field-initializers', '-pthread', '-fPIC' + binaries.withType(SharedLibraryBinarySpec) { + buildable = false } } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1cc2a88d976e09c3df217919ce93ba571e13d4af..7a3265ee94c0ab25cf079ac8ccdf87f41d455d42 100644 GIT binary patch delta 19176 zcmZ6yV{m3&w>2Ew?6_mwwr$(Cadpzk6(=3rwylnB+qRv&_j&H~)mP8?v1`rRHP^0M zRb!8-vHq5TH&%cnDanFEV1R(Yz<_{&2!q5Sk^f@|gK)(i$;9z$V5gtp+_~JkfP(xV zx6+>w|8bw7{C9n3{Lk9pK+OU9A1k4hVdpL(FvcSWu!X=@u3r5y z{&N>8=QoGFZncMeBZ+ejqAmiv=%4C)ob7te?`iRLT;nJRl6bo!fyRx8{r=D9z5UL4ODV`5f(yi zVZh^C*&pM4cV;SH4@jv65Rk`0EoM7JD!n6C7nwL2gybnT{qpPx;woxaqpvCQVns19 zyj75-x(>Mr4Lq2fY=ERe7^lzkr0QZ+cLlpQAE}LFT-d%x-hdBzvPhu8x?=fd%rDsD z*=7P2i=Xtv|Q=c`3^TFdX&KOq&?uixhEl zg8vOx(gsDXO~u<93tikV3LpC;;@dM7Ax*Hn_}5|^I%{EQI4H92)>UrBAhGD&Mr8cJ z0ywbB&p#+XiKv+-q=6Vn$r|>Znw}jK2SaabUtKQajD|Xn{bY--Xa$EV7Y@6iiQ#7*7;x)!8K}A8I^6 z@*xY4w>JpSvkIN8d#{iAVp{c3Kt6FiW(+m8ugSTs#EjIG-mW=$B8+Ltq!Uw*sJII0 zmD4G$Qq}+sQZFdF!YoeV1M0s~^XC?I3Jw_w1cU+~1cVqQL3sc(fe#M`z+h@;?CP4O z4R3_8?9Q*awuuuhL8Kv7Yjk7s7wZid?>9Yy1R5AbJc@_!j^nf4`b}QYdhUKJpi##jqon!q z$p6a!x!ZTT>$>~#xaaj0Fb%ds&G18Nr#;ZPQ>}l?((GP)wUaJG^Wco}U;fEJykI9bat@r9jdf}`4>IX1z{WcxAy>O!om434h)%QXG-V?c`Y` z*Ei2iFVLM1J4CnY1gtJcIR^@c39N?mH`6LFX`|J8w@$f-)nn+w2HHe-Kwbn0>Y|vZ>u_Ni33K3Fim)xjX9YAXMA6gbj(q+#rR%-O}J> zd)S#tB!k23phjCShrHeLKvjCHJP6oP?*57aU`(duvQfxu!IhEz!Qw-E{Wd{0`Pv8U zvA}c~ITmri1o?>whlrcvClut_n?B{GZj7LD5sODtV}TIBe)}a)6x@u{iLJhP zRZ@Co<|;FQ80EwheWBBs>U4!PtxbBJ*IK@KL3@LmmfhG}ntMtS>SL8mzRQ|DsVu*v z++usudHaOfA>AeG^gwQ?VO%+P!eEmo{6Wkh>hEM#n?L^gH6an+#C5t`2Qs;8^O|x4 z8f+OHb7N+rlJttT;OW70wc(U(D6(F9{qZ458Xi1=1)5;{37=NnoW-ErZkf1#(Q>YN znb-8#SXxriqPT=yqJ)S7~^ zqGthEB{*E#zfDNDDk9TqotB|28S82)$amE!r`t4>!yI<2W!ueVy=38*)3Nq_t_HP~ z*?nJHf@>|qsETH7&N00M+5?t~4mlEMyr0}6=Gt9t3pwq@^>P
    ;{uxCFdo17>QTVNzIrR=a?@u;vR$fngPL2ck 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37e6625..f16d266 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Wed Jan 04 18:51:47 PST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip diff --git a/gradlew b/gradlew index 4453cce..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -33,11 +33,11 @@ DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -155,7 +155,7 @@ if $cygwin ; then fi # Escape application args -save ( ) { +save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } diff --git a/gradlew.bat b/gradlew.bat index e95643d..f955316 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,84 +1,84 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/java/java.gradle b/java/java.gradle deleted file mode 100644 index efa9a9d..0000000 --- a/java/java.gradle +++ /dev/null @@ -1,185 +0,0 @@ -import org.gradle.internal.os.OperatingSystem - -apply plugin: 'java' -apply plugin: 'net.ltgt.errorprone' - -repositories { - mavenCentral() -} - -configurations.errorprone { - resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.9' -} - -def generatedJNIHeaderLoc = "${buildDir}/include" - -sourceSets { - main { - java { - srcDirs = ["${rootDir}/java/src"] - } - } -} - -dependencies { - compile 'org.opencv:opencv-java:3.1.0' - runtime 'org.opencv:opencv-java:3.1.0' -} - -jar { - description = 'Generates cscore jar, with the JNI shared libraries embedded' - baseName = 'cscore' - if (project.isArm && project.hasProperty('compilerPrefix') - && project.hasProperty('armSuffix')) { - classifier = "${buildPlatform}${project.armSuffix}" - } else { - classifier = "${buildPlatform}" - } - duplicatesStrategy = 'exclude' - - dependsOn { classes } - model { - binaries { - withType(SharedLibraryBinarySpec) { binary -> - // Only include the native file if not cross compiling to the roboRIO - if (!project.isArm || project.hasProperty('compilerPrefix')) - from(file(binary.sharedLibraryFile)) { - into getPlatformPath(binary) - } - } - } - } -} - -project.tasks.whenTaskAdded { task -> - if (isArm) { - if (task.name == 'cscoreSharedLibrary') jar.dependsOn task - } else { - if (task.name == 'cscoreX64SharedLibrary' || task.name == 'cscoreX86SharedLibrary') - jar.dependsOn task - } -} - -task cscoreJavaSource(type: Jar, dependsOn: classes) { - description = 'Generates the source jar for cscore java' - group = 'WPILib' - baseName = 'cscore' - classifier = "sources" - duplicatesStrategy = 'exclude' - - from sourceSets.main.allJava -} - -task cscoreJavadoc(type: Jar, dependsOn: javadoc) { - description = 'Generates the javadoc jar for cscore java' - group = 'WPILib' - baseName = 'cscore' - classifier = "javadoc" - duplicatesStrategy = 'exclude' - - from javadoc.destinationDir -} - -build.dependsOn cscoreJavaSource -build.dependsOn cscoreJavadoc - -/** - * Generates the JNI headers - */ -task jniHeadersCscore { - description = 'Generates JNI headers from edu.wpi.cscore.*' - group = 'WPILib' - def outputFolder = file(generatedJNIHeaderLoc) - inputs.files sourceSets.main.output - outputs.file outputFolder - doLast { - outputFolder.mkdirs() - exec { - executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah') - args '-d', outputFolder - args '-classpath', sourceSets.main.runtimeClasspath.asPath - args 'edu.wpi.cscore.CameraServerJNI' - } - } -} - -ext.getNativeJNISymbols = { - def symbolsList = [] - - jniHeadersCscore.outputs.files.each { - FileTree tree = fileTree(dir: it) - tree.each { File file -> - file.eachLine { line -> - if (line.trim()) { - if (line.startsWith("JNIEXPORT ") && line.contains('JNICALL')) { - def (p1, p2) = line.split('JNICALL').collect { it.trim() } - // p2 is our JNI call - symbolsList << p2 - } - } - } - } - } - - return symbolsList -} - -clean { - delete generatedJNIHeaderLoc -} - -compileJava { - options.compilerArgs << '-Xlint:unchecked' -} - -javadoc { - options.addStringOption('Xdoclint:none', '-quiet') -} - -// This creates a lambda that the main build.gradle can access, which sets up the JNI includes for the -// target build platform. This lambda is exposed as a property in the main build.gradle. -ext.setupJniIncludes = { binaries -> - def platformSpecificIncludeFlag = { loc, cppCompiler -> - if (OperatingSystem.current().isWindows()) { - cppCompiler.args "/I$loc" - } else { - cppCompiler.args '-I', loc - } - } - binaries.all { - tasks.withType(CppCompile) { - if (buildPlatform == 'arm') { - cppCompiler.args '-I', file("${rootDir}/java/arm-linux").absolutePath - cppCompiler.args '-I', file("${rootDir}/java/arm-linux/linux").absolutePath - } else { - def jdkLocation = org.gradle.internal.jvm.Jvm.current().javaHome - platformSpecificIncludeFlag("${jdkLocation}/include", cppCompiler) - - if (targetPlatform.operatingSystem.macOsX) { - platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler) - } else if (targetPlatform.operatingSystem.linux) { - platformSpecificIncludeFlag("${jdkLocation}/include/linux", cppCompiler) - } else if (targetPlatform.operatingSystem.windows) { - platformSpecificIncludeFlag("${jdkLocation}/include/win32", cppCompiler) - } else if (targetPlatform.operatingSystem.freeBSD) { - platformSpecificIncludeFlag("${jdkLocation}/include/freebsd", cppCompiler) - } else if (file("$jdkLocation/include/darwin").exists()) { - // TODO: As of Gradle 2.8, targetPlatform.operatingSystem.macOsX returns false - // on El Capitan. We therefore manually test for the darwin folder and include it - // if it exists - platformSpecificIncludeFlag("${jdkLocation}/include/darwin", cppCompiler) - } - } - - jniHeadersCscore.outputs.files.each { file -> - if (buildPlatform == 'arm') { - cppCompiler.args '-I', file.getPath() - } else { - platformSpecificIncludeFlag(file.getPath(), cppCompiler) - } - } - - dependsOn jniHeadersCscore - } - } -} diff --git a/publish.gradle b/publish.gradle index 59e2b4f..e98e32a 100644 --- a/publish.gradle +++ b/publish.gradle @@ -1,5 +1,3 @@ -import org.gradle.internal.os.OperatingSystem - apply plugin: 'maven-publish' apply plugin: 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' @@ -9,96 +7,262 @@ if (!hasProperty('releaseType')) { } } -def csVersion -if (project.hasProperty("csPublishVersion")) { - csVersion = project.csPublishVersion +def pubVersion +if (project.hasProperty("publishVersion")) { + pubVersion = project.publishVersion } else { - csVersion = WPILibVersion.version + pubVersion = WPILibVersion.version } -def csFile = file("$buildDir/cscore.txt") +def outputsFolder = file("$buildDir/outputs") + +def versionFile = file("$outputsFolder/version.txt") task outputVersions() { - description = 'Prints the version of cscore to a file for use by the downstream packaging project' + description = 'Prints the versions of cscore to a file for use by the downstream packaging project' group = 'Build' - outputs.files(csFile) + outputs.files(versionFile) doFirst { - buildDir.mkdir() + outputsFolder.mkdir() } doLast { - csFile.write csVersion + versionFile.write pubVersion } } -task clean(type: Delete) { - delete csFile +build.dependsOn outputVersions + +def baseArtifactId = 'cscore' +def artifactGroupId = 'edu.wpi.first.cscore' + +def licenseFile = file("$rootDir/license.txt") + +task cppSourcesZip(type: Zip) { + destinationDir = outputsFolder + classifier = "sources" + + from(licenseFile) { + into '/' + } + + from('src/main/native/cpp') { + into '/' + } + + model { + tasks { + it.each { + if (it in getJNIHeadersClass()) { + from (it.outputs.files) { + into '/' + } + dependsOn it + } + } + } + } } -outputVersions.mustRunAfter clean +task cppHeadersZip(type: Zip) { + destinationDir = outputsFolder + classifier = "headers" + + from(licenseFile) { + into '/' + } -project(':native').build.dependsOn outputVersions -if (project.buildArm) { - project(':arm').build.dependsOn outputVersions + from('src/main/native/include') { + into '/' + } } -// We change what repo we publish to depending on whether this is a development, beta, stable, or full -// release. This is set up in the main gradle file. -publishing { - publications { - def nat = project('native') - if (!project.hasProperty('skipJava')) { - java(MavenPublication) { - artifact nat.jar - if (!project.buildArm) { - artifact nat.cscoreJavaSource - artifact nat.cscoreJavadoc +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +if (project.hasProperty('jenkinsBuild')) { + jar { + classifier = 'javaArtifact' + } +} + +artifacts { + archives sourcesJar + archives javadocJar + archives cppHeadersZip + archives cppSourcesZip +} + +def createComponentZipTasks = { components, name, base, type, project, func -> + def configMap = [:] + components.each { + if (it in NativeLibrarySpec && it.name == name) { + it.binaries.each { + def target = getClassifier(it) + if (configMap.containsKey(target)) { + configMap.get(target).add(it) + } else { + configMap.put(target, []) + configMap.get(target).add(it) } - if (project.buildArm) { - def camArm = project('arm') - artifact camArm.jar - // If the library is not embedded include it in the repo - if (!project.hasProperty('compilerPrefix')) { - artifact camArm.cscoreZip - artifact camArm.athenaCscoreUberZip { - classifier = 'athena-uberzip' + } + } + } + def taskList = [] + configMap.each { key, value -> + def baseN = base + name + def task = project.tasks.create(baseN + "-${key}", type) { + description = 'Creates component archive for platform ' + key + destinationDir = outputsFolder + classifier = key + baseName = baseN + '-classifier' + duplicatesStrategy = 'exclude' + + from(licenseFile) { + into '/' + } + + func(it, value) + } + taskList.add(task) + + project.build.dependsOn task + + project.artifacts { + task + } + } + return taskList +} + +model { + publishing { + def cscoreTaskList = createComponentZipTasks($.components, 'cscore', 'zipcppcscore', Zip, project, { task, value -> + value.each { binary-> + if (binary.buildable) { + if (binary instanceof SharedLibraryBinarySpec) { + task.dependsOn binary.buildTask + task.from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) { + into getPlatformPath(binary) + '/shared' + } + task.from (binary.sharedLibraryFile) { + into getPlatformPath(binary) + '/shared' + } + task.from (binary.sharedLibraryLinkFile) { + into getPlatformPath(binary) + '/shared' + } + } else if (binary instanceof StaticLibraryBinarySpec) { + task.dependsOn binary.buildTask + task.from (binary.staticLibraryFile) { + into getPlatformPath(binary) + '/static' } } - artifact camArm.cscoreJavaSource - artifact camArm.cscoreJavadoc } - if (project.hasProperty('makeDesktop')) { - artifact nat.jar, { - classifier = 'desktop' + } + }) + + def cscoreJNITaskList = createComponentZipTasks($.components, 'cscoreJNI', 'jnijnicscore', Jar, project, { task, value -> + value.each { binary-> + if (binary.buildable) { + if (binary instanceof SharedLibraryBinarySpec) { + task.dependsOn binary.buildTask + task.from (binary.sharedLibraryFile) { + into getPlatformPath(binary) + } } } + } + }) - groupId 'edu.wpi.cscore.java' - artifactId 'cscore' - version csVersion + def allJniTask + if (!project.hasProperty('jenkinsBuild')) { + allJniTask = project.tasks.create("cscoreJNIAllJar", Jar) { + description = 'Creates a jar with all JNI artifacts' + classifier = 'all' + baseName = 'jnijnicscorecscoreJNI' + destinationDir = outputsFolder + duplicatesStrategy = 'exclude' + + cscoreJNITaskList.each { + it.outputs.files.each { + from project.zipTree(it) + } + dependsOn it + } } + project.build.dependsOn allJniTask } - cpp(MavenPublication) { - artifact nat.cscoreZip - artifact cscoreSourceZip - if (project.buildArm) { - artifact project(':arm').cscoreZip - if (!project.hasProperty('compilerPrefix')) { - artifact project(':arm').athenaCscoreUberZip { - classifier = 'athena-uberzip' + + def allCppTask + if (!project.hasProperty('jenkinsBuild')) { + allCppTask = project.tasks.create("cscoreAllZip", Zip) { + description = 'Creates a zip with all Cpp artifacts' + classifier = 'all' + baseName = 'zipcppcscorecscore' + destinationDir = outputsFolder + duplicatesStrategy = 'exclude' + + cscoreTaskList.each { + it.outputs.files.each { + from project.zipTree(it) } + dependsOn it } } - if (project.hasProperty('makeDesktop')) { - artifact nat.cscoreZip, { - classifier = 'desktop' + project.build.dependsOn allCppTask + } + + publications { + cpp(MavenPublication) { + cscoreTaskList.each { + artifact it + } + artifact cppHeadersZip + artifact cppSourcesZip + + if (!project.hasProperty('jenkinsBuild')) { + artifact allCppTask } + + artifactId = "${baseArtifactId}-cpp" + groupId artifactGroupId + version pubVersion } + jni(MavenPublication) { + cscoreJNITaskList.each { + artifact it + } + + if (!project.hasProperty('jenkinsBuild')) { + artifact allJniTask + } + + artifactId = "${baseArtifactId}-jni" + groupId artifactGroupId + version pubVersion + } + } + } +} + +publishing { + publications { + java(MavenPublication) { + artifact jar + artifact sourcesJar + artifact javadocJar - groupId 'edu.wpi.cscore.cpp' - artifactId 'cscore' - version csVersion + artifactId = "${baseArtifactId}-java" + groupId artifactGroupId + version pubVersion } } } diff --git a/settings.gradle b/settings.gradle index 773e145..da7ccc2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1 @@ -include 'native' include 'gmock' - -if (!hasProperty('skipArm')) { - include 'arm' -} diff --git a/java/arm-linux/LICENSE b/src/arm-linux-jni/LICENSE similarity index 100% rename from java/arm-linux/LICENSE rename to src/arm-linux-jni/LICENSE diff --git a/java/arm-linux/jni.h b/src/arm-linux-jni/jni.h similarity index 100% rename from java/arm-linux/jni.h rename to src/arm-linux-jni/jni.h diff --git a/java/arm-linux/linux/jni_md.h b/src/arm-linux-jni/linux/jni_md.h similarity index 100% rename from java/arm-linux/linux/jni_md.h rename to src/arm-linux-jni/linux/jni_md.h diff --git a/src/dev/java/edu/wpi/cscore/DevMain.java b/src/dev/java/edu/wpi/cscore/DevMain.java new file mode 100644 index 0000000..e3ba359 --- /dev/null +++ b/src/dev/java/edu/wpi/cscore/DevMain.java @@ -0,0 +1,12 @@ +package edu.wpi.cscore; + +import edu.wpi.cscore.CameraServerJNI; +import edu.wpi.first.wpiutil.RuntimeDetector; + +public class DevMain { + public static void main(String[] args) { + System.out.println("Hello World!"); + System.out.println(RuntimeDetector.getPlatformPath()); + System.out.println(CameraServerJNI.getHostname()); + } +} diff --git a/src/dev/native/cpp/main.cpp b/src/dev/native/cpp/main.cpp new file mode 100644 index 0000000..4304593 --- /dev/null +++ b/src/dev/native/cpp/main.cpp @@ -0,0 +1,6 @@ +#include +#include "cscore.h" + +int main() { + std::cout << cs::GetHostname() << std::endl; +} diff --git a/java/src/edu/wpi/cscore/AxisCamera.java b/src/main/java/edu/wpi/cscore/AxisCamera.java similarity index 100% rename from java/src/edu/wpi/cscore/AxisCamera.java rename to src/main/java/edu/wpi/cscore/AxisCamera.java diff --git a/java/src/edu/wpi/cscore/CameraServerJNI.java b/src/main/java/edu/wpi/cscore/CameraServerJNI.java similarity index 83% rename from java/src/edu/wpi/cscore/CameraServerJNI.java rename to src/main/java/edu/wpi/cscore/CameraServerJNI.java index c922dfd..08c16bf 100644 --- a/java/src/edu/wpi/cscore/CameraServerJNI.java +++ b/src/main/java/edu/wpi/cscore/CameraServerJNI.java @@ -15,30 +15,20 @@ import java.nio.ByteBuffer; import java.util.function.Consumer; import org.opencv.core.Core; +import edu.wpi.first.wpiutil.RuntimeDetector; public class CameraServerJNI { static boolean libraryLoaded = false; - static boolean cvLibraryLoaded = false; static File jniLibrary = null; + static boolean cvLibraryLoaded = false; + static File cvJniLibrary = null; static { if (!libraryLoaded) { try { System.loadLibrary("cscore"); } catch (UnsatisfiedLinkError e) { try { - String osname = System.getProperty("os.name"); - String resname; - if (osname.startsWith("Windows")) - resname = "/Windows/" + System.getProperty("os.arch") + "/"; - else - resname = "/" + osname + "/" + System.getProperty("os.arch") + "/"; - System.out.println("platform: " + resname); - if (osname.startsWith("Windows")) - resname += "cscore.dll"; - else if (osname.startsWith("Mac")) - resname += "libcscore.dylib"; - else - resname += "libcscore.so"; + String resname = RuntimeDetector.getLibraryResource("cscore"); InputStream is = CameraServerJNI.class.getResourceAsStream(resname); if (is != null) { // create temporary file @@ -72,18 +62,54 @@ else if (System.getProperty("os.name").startsWith("Mac")) } } libraryLoaded = true; - if (!cvLibraryLoaded) { + } + + String opencvName = Core.NATIVE_LIBRARY_NAME; + if (!cvLibraryLoaded) { + try { + + System.loadLibrary(opencvName); + } catch (UnsatisfiedLinkError e) { try { - System.loadLibrary(Core.NATIVE_LIBRARY_NAME); - } catch (UnsatisfiedLinkError ex) { + String resname = RuntimeDetector.getLibraryResource(opencvName); + InputStream is = CameraServerJNI.class.getResourceAsStream(resname); + if (is != null) { + // create temporary file + if (System.getProperty("os.name").startsWith("Windows")) + cvJniLibrary = File.createTempFile("OpenCVJNI", ".dll"); + else if (System.getProperty("os.name").startsWith("Mac")) + cvJniLibrary = File.createTempFile("libOpenCVJNI", ".dylib"); + else + cvJniLibrary = File.createTempFile("libOpenCVJNI", ".so"); + // flag for delete on exit + cvJniLibrary.deleteOnExit(); + OutputStream os = new FileOutputStream(cvJniLibrary); + + byte[] buffer = new byte[1024]; + int readBytes; + try { + while ((readBytes = is.read(buffer)) != -1) { + os.write(buffer, 0, readBytes); + } + } finally { + os.close(); + is.close(); + } + System.load(cvJniLibrary.getAbsolutePath()); + } else { + System.loadLibrary(opencvName); + } + } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } - cvLibraryLoaded = true; } + cvLibraryLoaded = true; } } + public static void ForceLoad() {} + // // Property Functions // diff --git a/java/src/edu/wpi/cscore/CvSink.java b/src/main/java/edu/wpi/cscore/CvSink.java similarity index 100% rename from java/src/edu/wpi/cscore/CvSink.java rename to src/main/java/edu/wpi/cscore/CvSink.java diff --git a/java/src/edu/wpi/cscore/CvSource.java b/src/main/java/edu/wpi/cscore/CvSource.java similarity index 100% rename from java/src/edu/wpi/cscore/CvSource.java rename to src/main/java/edu/wpi/cscore/CvSource.java diff --git a/java/src/edu/wpi/cscore/HttpCamera.java b/src/main/java/edu/wpi/cscore/HttpCamera.java similarity index 100% rename from java/src/edu/wpi/cscore/HttpCamera.java rename to src/main/java/edu/wpi/cscore/HttpCamera.java diff --git a/java/src/edu/wpi/cscore/MjpegServer.java b/src/main/java/edu/wpi/cscore/MjpegServer.java similarity index 100% rename from java/src/edu/wpi/cscore/MjpegServer.java rename to src/main/java/edu/wpi/cscore/MjpegServer.java diff --git a/java/src/edu/wpi/cscore/UsbCamera.java b/src/main/java/edu/wpi/cscore/UsbCamera.java similarity index 100% rename from java/src/edu/wpi/cscore/UsbCamera.java rename to src/main/java/edu/wpi/cscore/UsbCamera.java diff --git a/java/src/edu/wpi/cscore/UsbCameraInfo.java b/src/main/java/edu/wpi/cscore/UsbCameraInfo.java similarity index 100% rename from java/src/edu/wpi/cscore/UsbCameraInfo.java rename to src/main/java/edu/wpi/cscore/UsbCameraInfo.java diff --git a/java/src/edu/wpi/cscore/VideoCamera.java b/src/main/java/edu/wpi/cscore/VideoCamera.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoCamera.java rename to src/main/java/edu/wpi/cscore/VideoCamera.java diff --git a/java/src/edu/wpi/cscore/VideoEvent.java b/src/main/java/edu/wpi/cscore/VideoEvent.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoEvent.java rename to src/main/java/edu/wpi/cscore/VideoEvent.java diff --git a/java/src/edu/wpi/cscore/VideoException.java b/src/main/java/edu/wpi/cscore/VideoException.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoException.java rename to src/main/java/edu/wpi/cscore/VideoException.java diff --git a/java/src/edu/wpi/cscore/VideoListener.java b/src/main/java/edu/wpi/cscore/VideoListener.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoListener.java rename to src/main/java/edu/wpi/cscore/VideoListener.java diff --git a/java/src/edu/wpi/cscore/VideoMode.java b/src/main/java/edu/wpi/cscore/VideoMode.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoMode.java rename to src/main/java/edu/wpi/cscore/VideoMode.java diff --git a/java/src/edu/wpi/cscore/VideoProperty.java b/src/main/java/edu/wpi/cscore/VideoProperty.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoProperty.java rename to src/main/java/edu/wpi/cscore/VideoProperty.java diff --git a/java/src/edu/wpi/cscore/VideoSink.java b/src/main/java/edu/wpi/cscore/VideoSink.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoSink.java rename to src/main/java/edu/wpi/cscore/VideoSink.java diff --git a/java/src/edu/wpi/cscore/VideoSource.java b/src/main/java/edu/wpi/cscore/VideoSource.java similarity index 100% rename from java/src/edu/wpi/cscore/VideoSource.java rename to src/main/java/edu/wpi/cscore/VideoSource.java diff --git a/src/CvSinkImpl.cpp b/src/main/native/cpp/CvSinkImpl.cpp similarity index 100% rename from src/CvSinkImpl.cpp rename to src/main/native/cpp/CvSinkImpl.cpp diff --git a/src/CvSinkImpl.h b/src/main/native/cpp/CvSinkImpl.h similarity index 100% rename from src/CvSinkImpl.h rename to src/main/native/cpp/CvSinkImpl.h diff --git a/src/CvSourceImpl.cpp b/src/main/native/cpp/CvSourceImpl.cpp similarity index 100% rename from src/CvSourceImpl.cpp rename to src/main/native/cpp/CvSourceImpl.cpp diff --git a/src/CvSourceImpl.h b/src/main/native/cpp/CvSourceImpl.h similarity index 100% rename from src/CvSourceImpl.h rename to src/main/native/cpp/CvSourceImpl.h diff --git a/src/Frame.cpp b/src/main/native/cpp/Frame.cpp similarity index 100% rename from src/Frame.cpp rename to src/main/native/cpp/Frame.cpp diff --git a/src/Frame.h b/src/main/native/cpp/Frame.h similarity index 100% rename from src/Frame.h rename to src/main/native/cpp/Frame.h diff --git a/src/Handle.cpp b/src/main/native/cpp/Handle.cpp similarity index 100% rename from src/Handle.cpp rename to src/main/native/cpp/Handle.cpp diff --git a/src/Handle.h b/src/main/native/cpp/Handle.h similarity index 100% rename from src/Handle.h rename to src/main/native/cpp/Handle.h diff --git a/src/HttpCameraImpl.cpp b/src/main/native/cpp/HttpCameraImpl.cpp similarity index 100% rename from src/HttpCameraImpl.cpp rename to src/main/native/cpp/HttpCameraImpl.cpp diff --git a/src/HttpCameraImpl.h b/src/main/native/cpp/HttpCameraImpl.h similarity index 100% rename from src/HttpCameraImpl.h rename to src/main/native/cpp/HttpCameraImpl.h diff --git a/src/HttpUtil.cpp b/src/main/native/cpp/HttpUtil.cpp similarity index 100% rename from src/HttpUtil.cpp rename to src/main/native/cpp/HttpUtil.cpp diff --git a/src/HttpUtil.h b/src/main/native/cpp/HttpUtil.h similarity index 100% rename from src/HttpUtil.h rename to src/main/native/cpp/HttpUtil.h diff --git a/src/HttpUtil.inl b/src/main/native/cpp/HttpUtil.inl similarity index 100% rename from src/HttpUtil.inl rename to src/main/native/cpp/HttpUtil.inl diff --git a/src/Image.h b/src/main/native/cpp/Image.h similarity index 100% rename from src/Image.h rename to src/main/native/cpp/Image.h diff --git a/src/JpegUtil.cpp b/src/main/native/cpp/JpegUtil.cpp similarity index 100% rename from src/JpegUtil.cpp rename to src/main/native/cpp/JpegUtil.cpp diff --git a/src/JpegUtil.h b/src/main/native/cpp/JpegUtil.h similarity index 100% rename from src/JpegUtil.h rename to src/main/native/cpp/JpegUtil.h diff --git a/src/Log.cpp b/src/main/native/cpp/Log.cpp similarity index 100% rename from src/Log.cpp rename to src/main/native/cpp/Log.cpp diff --git a/src/Log.h b/src/main/native/cpp/Log.h similarity index 100% rename from src/Log.h rename to src/main/native/cpp/Log.h diff --git a/src/MjpegServerImpl.cpp b/src/main/native/cpp/MjpegServerImpl.cpp similarity index 100% rename from src/MjpegServerImpl.cpp rename to src/main/native/cpp/MjpegServerImpl.cpp diff --git a/src/MjpegServerImpl.h b/src/main/native/cpp/MjpegServerImpl.h similarity index 100% rename from src/MjpegServerImpl.h rename to src/main/native/cpp/MjpegServerImpl.h diff --git a/src/NetworkListener.cpp b/src/main/native/cpp/NetworkListener.cpp similarity index 100% rename from src/NetworkListener.cpp rename to src/main/native/cpp/NetworkListener.cpp diff --git a/src/NetworkListener.h b/src/main/native/cpp/NetworkListener.h similarity index 100% rename from src/NetworkListener.h rename to src/main/native/cpp/NetworkListener.h diff --git a/src/Notifier.cpp b/src/main/native/cpp/Notifier.cpp similarity index 100% rename from src/Notifier.cpp rename to src/main/native/cpp/Notifier.cpp diff --git a/src/Notifier.h b/src/main/native/cpp/Notifier.h similarity index 100% rename from src/Notifier.h rename to src/main/native/cpp/Notifier.h diff --git a/src/PropertyImpl.h b/src/main/native/cpp/PropertyImpl.h similarity index 100% rename from src/PropertyImpl.h rename to src/main/native/cpp/PropertyImpl.h diff --git a/src/SinkImpl.cpp b/src/main/native/cpp/SinkImpl.cpp similarity index 100% rename from src/SinkImpl.cpp rename to src/main/native/cpp/SinkImpl.cpp diff --git a/src/SinkImpl.h b/src/main/native/cpp/SinkImpl.h similarity index 100% rename from src/SinkImpl.h rename to src/main/native/cpp/SinkImpl.h diff --git a/src/SourceImpl.cpp b/src/main/native/cpp/SourceImpl.cpp similarity index 100% rename from src/SourceImpl.cpp rename to src/main/native/cpp/SourceImpl.cpp diff --git a/src/SourceImpl.h b/src/main/native/cpp/SourceImpl.h similarity index 100% rename from src/SourceImpl.h rename to src/main/native/cpp/SourceImpl.h diff --git a/src/UnlimitedHandleResource.h b/src/main/native/cpp/UnlimitedHandleResource.h similarity index 100% rename from src/UnlimitedHandleResource.h rename to src/main/native/cpp/UnlimitedHandleResource.h diff --git a/src/UsbCameraBuffer.h b/src/main/native/cpp/UsbCameraBuffer.h similarity index 100% rename from src/UsbCameraBuffer.h rename to src/main/native/cpp/UsbCameraBuffer.h diff --git a/src/UsbCameraImpl.cpp b/src/main/native/cpp/UsbCameraImpl.cpp similarity index 100% rename from src/UsbCameraImpl.cpp rename to src/main/native/cpp/UsbCameraImpl.cpp diff --git a/src/UsbCameraImpl.h b/src/main/native/cpp/UsbCameraImpl.h similarity index 100% rename from src/UsbCameraImpl.h rename to src/main/native/cpp/UsbCameraImpl.h diff --git a/src/UsbCameraProperty.cpp b/src/main/native/cpp/UsbCameraProperty.cpp similarity index 100% rename from src/UsbCameraProperty.cpp rename to src/main/native/cpp/UsbCameraProperty.cpp diff --git a/src/UsbCameraProperty.h b/src/main/native/cpp/UsbCameraProperty.h similarity index 100% rename from src/UsbCameraProperty.h rename to src/main/native/cpp/UsbCameraProperty.h diff --git a/src/UsbUtil.cpp b/src/main/native/cpp/UsbUtil.cpp similarity index 100% rename from src/UsbUtil.cpp rename to src/main/native/cpp/UsbUtil.cpp diff --git a/src/UsbUtil.h b/src/main/native/cpp/UsbUtil.h similarity index 100% rename from src/UsbUtil.h rename to src/main/native/cpp/UsbUtil.h diff --git a/src/c_util.h b/src/main/native/cpp/c_util.h similarity index 100% rename from src/c_util.h rename to src/main/native/cpp/c_util.h diff --git a/src/cscore_c.cpp b/src/main/native/cpp/cscore_c.cpp similarity index 100% rename from src/cscore_c.cpp rename to src/main/native/cpp/cscore_c.cpp diff --git a/src/cscore_cpp.cpp b/src/main/native/cpp/cscore_cpp.cpp similarity index 100% rename from src/cscore_cpp.cpp rename to src/main/native/cpp/cscore_cpp.cpp diff --git a/src/cscore_oo.cpp b/src/main/native/cpp/cscore_oo.cpp similarity index 100% rename from src/cscore_oo.cpp rename to src/main/native/cpp/cscore_oo.cpp diff --git a/src/default_init_allocator.h b/src/main/native/cpp/default_init_allocator.h similarity index 100% rename from src/default_init_allocator.h rename to src/main/native/cpp/default_init_allocator.h diff --git a/java/lib/CameraServerJNI.cpp b/src/main/native/cpp/jni/CameraServerJNI.cpp similarity index 100% rename from java/lib/CameraServerJNI.cpp rename to src/main/native/cpp/jni/CameraServerJNI.cpp diff --git a/include/cscore.h b/src/main/native/include/cscore.h similarity index 100% rename from include/cscore.h rename to src/main/native/include/cscore.h diff --git a/include/cscore_c.h b/src/main/native/include/cscore_c.h similarity index 100% rename from include/cscore_c.h rename to src/main/native/include/cscore_c.h diff --git a/include/cscore_cpp.h b/src/main/native/include/cscore_cpp.h similarity index 100% rename from include/cscore_cpp.h rename to src/main/native/include/cscore_cpp.h diff --git a/include/cscore_oo.h b/src/main/native/include/cscore_oo.h similarity index 100% rename from include/cscore_oo.h rename to src/main/native/include/cscore_oo.h diff --git a/include/cscore_oo.inl b/src/main/native/include/cscore_oo.inl similarity index 100% rename from include/cscore_oo.inl rename to src/main/native/include/cscore_oo.inl diff --git a/src/test/java/edu/wpi/cscore/JNITest.java b/src/test/java/edu/wpi/cscore/JNITest.java new file mode 100644 index 0000000..d58890b --- /dev/null +++ b/src/test/java/edu/wpi/cscore/JNITest.java @@ -0,0 +1,11 @@ +package edu.wpi.cscore; + +import org.junit.Test; + +public class JNITest { + @Test + public void jniLinkTest() { + // Test to verify that the JNI test link works correctly. + edu.wpi.cscore.CameraServerJNI.getHostname(); + } +} diff --git a/test/unit/CameraSourceTest.cpp b/src/test/native/cpp/CameraSourceTest.cpp similarity index 88% rename from test/unit/CameraSourceTest.cpp rename to src/test/native/cpp/CameraSourceTest.cpp index aebedb6..9d601fc 100644 --- a/test/unit/CameraSourceTest.cpp +++ b/src/test/native/cpp/CameraSourceTest.cpp @@ -7,7 +7,7 @@ #include "gtest/gtest.h" -#include "cameraserver.h" +#include "cscore.h" namespace cs { @@ -18,7 +18,7 @@ class CameraSourceTest : public ::testing::Test { }; TEST_F(CameraSourceTest, HTTPCamera) { - auto source = HTTPCamera("axis", "http://localhost:8000"); + auto source = HttpCamera("axis", "http://localhost:8000"); } } // namespace cs diff --git a/test/unit/main.cpp b/src/test/native/cpp/main.cpp similarity index 100% rename from test/unit/main.cpp rename to src/test/native/cpp/main.cpp diff --git a/test/tests.gradle b/test/tests.gradle deleted file mode 100644 index 1dc7d48..0000000 --- a/test/tests.gradle +++ /dev/null @@ -1,49 +0,0 @@ -apply plugin: 'google-test' - -model { - testSuites { - cameraserverTest { - if (!project.hasProperty('skipJava')) { - setupJniIncludes(binaries) - } - sources { - cpp { - source { - srcDirs = ["${rootDir}/test/unit"] - includes = ['**/*.cpp'] - } - exportedHeaders { - srcDirs = ["${rootDir}/include", "${rootDir}/src", "${rootDir}/gmock/include", "${rootDir}/gmock/gtest/include"] - includes = ['**/*.h'] - } - } - } - binaries.all { - lib project: ':gmock', library: 'gmock', linkage: 'static' - lib library: 'cameraserver', linkage: 'static' - tasks.withType(CppCompile) { - project.addWpiUtilLibraryLinks(it, linker, targetPlatform) - project.addOpenCvLibraryLinks(it, linker, targetPlatform) - } - } - } - } -} - -model { - binaries { - withType(GoogleTestTestSuiteBinarySpec) { - lib project: ':gmock', library: "gmock", linkage: "static" - lib library: 'cameraserver', linkage: 'static' - tasks.withType(CppCompile) { - project.addWpiUtilLibraryLinks(it, linker, targetPlatform) - } - if (targetPlatform.operatingSystem.windows) { - cppCompiler.args '/EHsc', '/DNOMINMAX', '/D_SCL_SECURE_NO_WARNINGS', '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } else { - cppCompiler.args '-pthread', '-std=c++1y' - linker.args '-pthread' - } - } - } -} diff --git a/toolchains/arm.gradle b/toolchains/arm.gradle deleted file mode 100644 index 90a8758..0000000 --- a/toolchains/arm.gradle +++ /dev/null @@ -1,100 +0,0 @@ -ext.isArm = true -ext.buildPlatform = 'arm' - -def compilerPrefix = project.hasProperty('compilerPrefix') ? project.compilerPrefix : 'arm-frc-linux-gnueabi-' -def toolChainPath = project.hasProperty('toolChainPath') ? project.toolChainPath : null -model { - platforms { - arm { - architecture 'arm' - operatingSystem 'linux' - } - } - toolChains { - armGcc(Gcc) { - if (toolChainPath != null) path(toolChainPath) - target("arm") { - // We use a custom-built cross compiler with the prefix arm-frc-linux-gnueabi- - // If this ever changes, the prefix will need to be changed here - cCompiler.executable = compilerPrefix + cCompiler.executable - 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' << '-pthread' - args.remove('-m32') - } - linker.withArguments { args -> - args << '-rdynamic' << '-pthread' - args.remove('-m32') - } - staticLibArchiver.executable = compilerPrefix + staticLibArchiver.executable - } - } - } -} - -ext.binTools = { tool -> - if (toolChainPath != null) return "${toolChainPath}/${compilerPrefix}${tool}" - return "${compilerPrefix}${tool}" -} - -ext.setupReleaseDefines = { cppCompiler, linker -> - cppCompiler.args '-O2', '-g' -} - -ext.setupDebugDefines = { cppCompiler, linker -> - cppCompiler.args '-g', '-O0' -} - -// Used only on Windows. -ext.setupDef = { linker, deffile -> } - -ext.debugStripSetup = { - if (!project.hasProperty('debug')) { - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - def debugLibrary = task.outputFile.absolutePath + ".debug" - task.doLast { - exec { commandLine binTools('objcopy'), '--only-keep-debug', library, debugLibrary } - exec { commandLine binTools('strip'), '-g', library } - exec { commandLine binTools('objcopy'), "--add-gnu-debuglink=$debugLibrary", library } - } - } - } - } -} - -ext.checkNativeSymbols = { getSymbolFunc -> - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - def nmOutput = new ByteArrayOutputStream() - exec { - commandLine binTools('nm'), library - standardOutput nmOutput - } - // Remove '\r' so we can check for full string contents - String nmSymbols = nmOutput.toString().replace('\r', '') - - def symbolList = getSymbolFunc() - symbolList.each { - //Add \n so we can check for the exact symbol - def found = nmSymbols.contains(it + '\n') - if (!found) { - throw new GradleException("Found a definition that does not have a matching symbol ${it}") - } - } - } - } - } -} diff --git a/toolchains/linux.gradle b/toolchains/linux.gradle deleted file mode 100644 index cea85b4..0000000 --- a/toolchains/linux.gradle +++ /dev/null @@ -1,87 +0,0 @@ -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' << '-pthread' - args << '-m32' - } - linker.withArguments { args -> - args << '-rdynamic' << '-pthread' - 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' << '-pthread' - } - linker.withArguments { args -> - args << '-rdynamic' << '-pthread' - } - } - } - } -} - -ext.setupReleaseDefines = { cppCompiler, linker -> - cppCompiler.args '-O2', '-g' -} - -ext.setupDebugDefines = { cppCompiler, linker -> - cppCompiler.args '-g', '-O0' -} - -// Used only on Windows. -ext.setupDef = { linker, deffile -> } - -ext.debugStripSetup = { - if (!project.hasProperty('debug')) { - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - def debugLibrary = task.outputFile.absolutePath + ".debug" - task.doLast { - exec { commandLine "objcopy", '--only-keep-debug', library, debugLibrary } - exec { commandLine "strip", '-g', library } - exec { commandLine "objcopy", "--add-gnu-debuglink=$debugLibrary", library } - } - } - } - } -} - -ext.checkNativeSymbols = { getSymbolFunc -> - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - def nmOutput = new ByteArrayOutputStream() - exec { - commandLine "nm", library - standardOutput nmOutput - } - // Remove '\r' so we can check for full string contents - String nmSymbols = nmOutput.toString().replace('\r', '') - - def symbolList = getSymbolFunc() - symbolList.each { - //Add \n so we can check for the exact symbol - def found = nmSymbols.contains(it + '\n') - if (!found) { - throw new GradleException("Found a definition that does not have a matching symbol ${it}") - } - } - } - } - } -} diff --git a/toolchains/mac.gradle b/toolchains/mac.gradle deleted file mode 100644 index 902cbb5..0000000 --- a/toolchains/mac.gradle +++ /dev/null @@ -1,74 +0,0 @@ -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' -} - -// Used only on Windows. -ext.setupDef = { linker, deffile -> } - -ext.debugStripSetup = { - if (!project.hasProperty('debug')) { - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - exec { commandLine "dsymutil", library } - exec { commandLine "strip", '-S', library } - } - } - } - } -} - -ext.checkNativeSymbols = { getSymbolFunc -> - project.tasks.whenObjectAdded { task -> - if (task.name.contains('link') && task.name.contains('SharedLibrary')) { - def library = task.outputFile.absolutePath - task.doLast { - def nmOutput = new ByteArrayOutputStream() - exec { - commandLine "nm", library - standardOutput nmOutput - } - // Remove '\r' so we can check for full string contents - String nmSymbols = nmOutput.toString().replace('\r', '') - - def symbolList = getSymbolFunc() - symbolList.each { - //Add \n so we can check for the exact symbol - def found = nmSymbols.contains(it + '\n') - if (!found) { - throw new GradleException("Found a definition that does not have a matching symbol ${it}") - } - } - } - } - } -} diff --git a/toolchains/native.gradle b/toolchains/native.gradle deleted file mode 100644 index b5597eb..0000000 --- a/toolchains/native.gradle +++ /dev/null @@ -1,25 +0,0 @@ -import org.gradle.internal.os.OperatingSystem - -ext.isArm = false -ext.buildPlatform = OperatingSystem.current().getFamilyName() - -if (OperatingSystem.current().isLinux()) { - apply from: "${rootDir}/toolchains/linux.gradle" -} else if (OperatingSystem.current().isMacOsX()) { - apply from: "${rootDir}/toolchains/mac.gradle" -} else if (OperatingSystem.current().isWindows()) { - apply from: "${rootDir}/toolchains/windows.gradle" -} else { - throw new GradleException("${name} does not support building on ${ext.buildPlatform}.") -} - -model { - platforms { - x86 { - architecture 'x86' - } - x64 { - architecture 'x86_64' - } - } -} diff --git a/toolchains/windows.gradle b/toolchains/windows.gradle deleted file mode 100644 index d741414..0000000 --- a/toolchains/windows.gradle +++ /dev/null @@ -1,32 +0,0 @@ -model { - toolChains { - visualCpp(VisualCpp) { - eachPlatform { - cppCompiler.withArguments { args -> - args << '/EHsc' << '/DNOMINMAX' << '/D_SCL_SECURE_NO_WARNINGS' << '/D_WINSOCK_DEPRECATED_NO_WARNINGS' - } - } - } - } -} - -ext.setupReleaseDefines = { cppCompiler, linker -> - cppCompiler.args '/O2', '/Zi', '/FS' -} - -ext.setupDebugDefines = { cppCompiler, linker -> - cppCompiler.args '/Zi', '/FS' - linker.args '/DEBUG' -} - -ext.setupDef = { linker, deffile -> - linker.args "/DEF:${deffile}" -} - -// 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.debugStripSetup = { } - -// This is a noop on Windows. The def file already implicilty checks for the symbols -ext.checkNativeSymbols = { getSymbolFunc -> -}