commit 615b12a5287c848f6b02a9709c35dfe1ff55f66f Author: Thad House Date: Fri Sep 27 11:31:25 2019 -0700 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a332fb2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,160 @@ +# Created by https://www.gitignore.io/api/c++,java,linux,macos,gradle,windows,visualstudiocode + +### C++ ### +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### Gradle ### +.gradle +/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +# # VS Code Specific Java Settings +.classpath +.project +.settings/ +bin/ + + +# End of https://www.gitignore.io/api/c++,java,linux,macos,gradle,windows,visualstudiocode diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cfccbf4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic", + "files.exclude": { + "**/.classpath": true, + "**/.project": true, + "**/.settings": true, + "**/.factorypath": true + }, + "C_Cpp.default.configurationProvider": "vscode-wpilib" +} \ No newline at end of file diff --git a/.wpilib/wpilib_preferences.json b/.wpilib/wpilib_preferences.json new file mode 100644 index 0000000..0c8975e --- /dev/null +++ b/.wpilib/wpilib_preferences.json @@ -0,0 +1,6 @@ +{ + "enableCppIntellisense": true, + "currentLanguage": "cpp", + "projectYear": "2019", + "teamNumber": 0 +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..c3f4841 --- /dev/null +++ b/build.gradle @@ -0,0 +1,97 @@ + +plugins { + id 'cpp' + id 'java' + id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2020.1' + id 'edu.wpi.first.NativeUtils' version '2020.1.0' + id 'edu.wpi.first.GradleJni' version '0.9.1' + id 'edu.wpi.first.GradleVsCode' version '0.9.4' +} + +repositories { + mavenCentral() +} +if (project.hasProperty('releaseMode')) { + wpilibRepositories.addAllReleaseRepositories(project) +} else { + wpilibRepositories.addAllDevelopmentRepositories(project) +} + +// Apply C++ configuration +apply from: 'config.gradle' + +// Apply Java configuration +dependencies { + compile 'edu.wpi.first.cscore:cscore-java:2019.+' + compile 'edu.wpi.first.cameraserver:cameraserver-java:2019.+' + compile 'edu.wpi.first.ntcore:ntcore-java:2019.+' + compile 'edu.wpi.first.wpilibj:wpilibj-java:2019.+' + compile 'edu.wpi.first.wpiutil:wpiutil-java:2019.+' + compile 'edu.wpi.first.hal:hal-java:2019.+' + compile 'edu.wpi.first.thirdparty.frc2020.opencv:opencv-java:3.4.7-1' +} + +// Set up exports properly +nativeUtils { + exportsConfigs { + // Main library is just default empty. This will export everything + Vendor { + } + } + privateExportsConfigs { + // Only export explicit symbols from driver library + VendorDriver { + exportsFile = project.file("src/main/driver/symbols.txt") + } + } +} + +model { + components { + Vendor(NativeLibrarySpec) { + sources { + cpp { + source { + srcDirs 'src/main/native/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/main/native/include' + } + } + } + binaries.all { + lib library: 'VendorDriver', linkage: 'shared' + } + nativeUtils.useRequiredLibrary(it, 'wpilib_shared') + } + + VendorDriver(JniNativeLibrarySpec) { + enableCheckTask true + javaCompileTasks << compileJava + jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.roborio) + // Leave these for future proofing + jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.raspbian) + jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.aarch64bionic) + sources { + cpp { + source { + srcDirs 'src/main/driver/cpp' + include '**/*.cpp' + } + exportedHeaders { + srcDirs 'src/main/driver/include' + } + } + } + + nativeUtils.useRequiredLibrary(it, "driver_shared") + } + } +} + +apply from: 'publish.gradle' + +wrapper { + gradleVersion '5.4.1' +} diff --git a/config.gradle b/config.gradle new file mode 100644 index 0000000..672cb8f --- /dev/null +++ b/config.gradle @@ -0,0 +1,175 @@ +import org.gradle.internal.os.OperatingSystem + +nativeUtils.addWpiNativeUtils() +nativeUtils.withRoboRIO() + +nativeUtils { + wpi { + configureDependencies { + wpiVersion = "2019.+" + niLibVersion = "2019.12.2" + opencvVersion = "3.4.7-1" + googleTestVersion = "1.9.0-3-437e100" + } + } +} + +nativeUtils.wpi.addWarnings() +nativeUtils.wpi.addWarningsAsErrors() + +nativeUtils.setSinglePrintPerPlatform() + +model { + components { + all { + targetPlatform nativeUtils.wpi.platforms.roborio + } + } + // Uncomment this, and remove above lines to enable builds for all platforms + // components { + // all { + // nativeUtils.useAllPlatforms(it) + // } + // } + binaries { + withType(NativeBinarySpec).all { + nativeUtils.usePlatformArguments(it) + } + } +} + +ext.appendDebugPathToBinaries = { binaries-> + binaries.withType(StaticLibraryBinarySpec) { + if (it.buildType.name.contains('debug')) { + def staticFileDir = it.staticLibraryFile.parentFile + def staticFileName = it.staticLibraryFile.name + def staticFileExtension = staticFileName.substring(staticFileName.lastIndexOf('.')) + staticFileName = staticFileName.substring(0, staticFileName.lastIndexOf('.')) + staticFileName = staticFileName + 'd' + staticFileExtension + def newStaticFile = new File(staticFileDir, staticFileName) + it.staticLibraryFile = newStaticFile + } + } + binaries.withType(SharedLibraryBinarySpec) { + if (it.buildType.name.contains('debug')) { + def sharedFileDir = it.sharedLibraryFile.parentFile + def sharedFileName = it.sharedLibraryFile.name + def sharedFileExtension = sharedFileName.substring(sharedFileName.lastIndexOf('.')) + sharedFileName = sharedFileName.substring(0, sharedFileName.lastIndexOf('.')) + sharedFileName = sharedFileName + 'd' + sharedFileExtension + def newSharedFile = new File(sharedFileDir, sharedFileName) + + def sharedLinkFileDir = it.sharedLibraryLinkFile.parentFile + def sharedLinkFileName = it.sharedLibraryLinkFile.name + def sharedLinkFileExtension = sharedLinkFileName.substring(sharedLinkFileName.lastIndexOf('.')) + sharedLinkFileName = sharedLinkFileName.substring(0, sharedLinkFileName.lastIndexOf('.')) + sharedLinkFileName = sharedLinkFileName + 'd' + sharedLinkFileExtension + def newLinkFile = new File(sharedLinkFileDir, sharedLinkFileName) + + it.sharedLibraryLinkFile = newLinkFile + it.sharedLibraryFile = newSharedFile + } + } +} + +ext.createComponentZipTasks = { components, names, base, type, project, func -> + def stringNames = names.collect {it.toString()} + def configMap = [:] + components.each { + if (it in NativeLibrarySpec && stringNames.contains(it.name)) { + it.binaries.each { + if (!it.buildable) return + def target = nativeUtils.getPublishClassifier(it) + if (configMap.containsKey(target)) { + configMap.get(target).add(it) + } else { + configMap.put(target, []) + configMap.get(target).add(it) + } + } + } + } + def taskList = [] + def outputsFolder = file("$project.buildDir/outputs") + configMap.each { key, value -> + def task = project.tasks.create(base + "-${key}", type) { + description = 'Creates component archive for platform ' + key + destinationDir = outputsFolder + classifier = key + baseName = '_M_' + base + duplicatesStrategy = 'exclude' + + from(licenseFile) { + into '/' + } + + func(it, value) + } + taskList.add(task) + + project.build.dependsOn task + + project.artifacts { + task + } + addTaskToCopyAllOutputs(task) + } + return taskList +} + +ext.createAllCombined = { list, name, base, type, project -> + def outputsFolder = file("$project.buildDir/outputs") + + def task = project.tasks.create(base + "-all", type) { + description = "Creates component archive for all classifiers" + destinationDir = outputsFolder + classifier = "all" + baseName = base + duplicatesStrategy = 'exclude' + + list.each { + if (it.name.endsWith('debug')) return + from project.zipTree(it.archivePath) + dependsOn it + } + } + + project.build.dependsOn task + + project.artifacts { + task + } + + return task + +} + +ext.includeStandardZipFormat = { task, value -> + value.each { binary -> + if (binary.buildable) { + if (binary instanceof SharedLibraryBinarySpec) { + task.dependsOn binary.tasks.link + task.from(new File(binary.sharedLibraryFile.absolutePath + ".debug")) { + into nativeUtils.getPlatformPath(binary) + '/shared' + } + def sharedPath = binary.sharedLibraryFile.absolutePath + sharedPath = sharedPath.substring(0, sharedPath.length() - 4) + + task.from(new File(sharedPath + '.pdb')) { + into nativeUtils.getPlatformPath(binary) + '/shared' + } + task.from(binary.sharedLibraryFile) { + into nativeUtils.getPlatformPath(binary) + '/shared' + } + task.from(binary.sharedLibraryLinkFile) { + into nativeUtils.getPlatformPath(binary) + '/shared' + } + } else if (binary instanceof StaticLibraryBinarySpec) { + task.dependsOn binary.tasks.createStaticLib + task.from(binary.staticLibraryFile) { + into nativeUtils.getPlatformPath(binary) + '/static' + } + } + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..5c2d1cf Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f4d7b2b --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..b0d6d0a --- /dev/null +++ b/gradlew @@ -0,0 +1,188 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..15e1ee3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@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="-Xmx64m" "-Xms64m" + +@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/publish.gradle b/publish.gradle new file mode 100644 index 0000000..2792553 --- /dev/null +++ b/publish.gradle @@ -0,0 +1,203 @@ +apply plugin: 'maven-publish' + +ext.licenseFile = files("$rootDir/LICENSE.txt") + +def pubVersion = '0.0.1' + +def outputsFolder = file("$buildDir/allOutputs") + +def versionFile = file("$outputsFolder/version.txt") + +task outputVersions() { + description = 'Prints the versions of wpilib to a file for use by the downstream packaging project' + group = 'Build' + outputs.files(versionFile) + + doFirst { + buildDir.mkdir() + outputsFolder.mkdir() + } + + doLast { + versionFile.write pubVersion + } +} + +task libraryBuild() {} + +build.dependsOn outputVersions + +task copyAllOutputs(type: Copy) { + destinationDir outputsFolder +} + +build.dependsOn copyAllOutputs +copyAllOutputs.dependsOn outputVersions + +ext.addTaskToCopyAllOutputs = { task -> + copyAllOutputs.dependsOn task + copyAllOutputs.inputs.file task.archivePath + copyAllOutputs.from task.archivePath +} + +def artifactGroupId = 'com.vendor.frc' +def baseArtifactId = 'Vendor' +def driverZipBaseName = "_GROUP_com_vendor_frc_ID_${baseArtifactId}-driver_CLS" +def zipBaseName = "_GROUP_com_vendor_frc_ID_${baseArtifactId}-cpp_CLS" +def javaBaseName = "_GROUP_com_vendor_frc_ID_${baseArtifactId}-java_CLS" + +task cppHeadersZip(type: Zip) { + destinationDir = outputsFolder + baseName = zipBaseName + classifier = "headers" + + from(licenseFile) { + into '/' + } + + from('src/main/native/include') { + into '/' + } +} + +task cppSourceZip(type: Zip) { + destinationDir = outputsFolder + baseName = zipBaseName + classifier = "source" + + from(licenseFile) { + into '/' + } + + from('src/main/native/cpp') { + into '/' + } +} + +task cppDriverHeadersZip(type: Zip) { + destinationDir = outputsFolder + baseName = driverZipBaseName + classifier = "headers" + + from(licenseFile) { + into '/' + } + + from('src/main/driver/include') { + into '/' + } +} + +build.dependsOn cppHeadersZip +addTaskToCopyAllOutputs(cppHeadersZip) +build.dependsOn cppSourceZip +addTaskToCopyAllOutputs(cppSourceZip) +build.dependsOn cppDriverHeadersZip +addTaskToCopyAllOutputs(cppDriverHeadersZip) + +task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource +} + +task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir +} + +task outputJar(type: Jar, dependsOn: classes) { + baseName javaBaseName + destinationDir outputsFolder + from sourceSets.main.output +} + +task outputSourcesJar(type: Jar, dependsOn: classes) { + baseName javaBaseName + destinationDir outputsFolder + classifier = 'sources' + from sourceSets.main.allSource +} + +task outputJavadocJar(type: Jar, dependsOn: javadoc) { + baseName javaBaseName + destinationDir outputsFolder + classifier = 'javadoc' + from javadoc.destinationDir +} + +artifacts { + archives sourcesJar + archives javadocJar + archives outputJar + archives outputSourcesJar + archives outputJavadocJar +} + +addTaskToCopyAllOutputs(outputSourcesJar) +addTaskToCopyAllOutputs(outputJavadocJar) +addTaskToCopyAllOutputs(outputJar) + +build.dependsOn outputSourcesJar +build.dependsOn outputJavadocJar +build.dependsOn outputJar + +libraryBuild.dependsOn build + +def releasesRepoUrl = "$buildDir/repos/releases" + +publishing { + repositories { + maven { + + url = releasesRepoUrl + } + } +} + +task cleanReleaseRepo(type: Delete) { + delete releasesRepoUrl +} + +tasks.matching {it != cleanReleaseRepo}.all {it.dependsOn cleanReleaseRepo} + +model { + publishing { + def taskList = createComponentZipTasks($.components, ['Vendor'], zipBaseName, Zip, project, includeStandardZipFormat) + + def driverTaskList = createComponentZipTasks($.components, ['Vendor'], driverZipBaseName, Zip, project, includeStandardZipFormat) + + publications { + cpp(MavenPublication) { + taskList.each { + artifact it + } + artifact cppHeadersZip + artifact cppSourceZip + + artifactId = "${baseArtifactId}-cpp" + groupId artifactGroupId + version pubVersion + } + driver(MavenPublication) { + driverTaskList.each { + artifact it + } + artifact cppDriverHeadersZip + + artifactId = "${baseArtifactId}-driver" + groupId artifactGroupId + version pubVersion + } + + java(MavenPublication) { + artifact jar + artifact sourcesJar + artifact javadocJar + + artifactId = "${baseArtifactId}-java" + groupId artifactGroupId + version pubVersion + } + } + } +} diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..588dcaf --- /dev/null +++ b/settings.gradle @@ -0,0 +1,6 @@ +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + } +} \ No newline at end of file diff --git a/src/main/driver/cpp/VendorJNI.cpp b/src/main/driver/cpp/VendorJNI.cpp new file mode 100644 index 0000000..0a3ce66 --- /dev/null +++ b/src/main/driver/cpp/VendorJNI.cpp @@ -0,0 +1,22 @@ +#include "jni.h" +#include "com_vendor_jni_VendorJNI.h" + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { + // Check to ensure the JNI version is valid + + JNIEnv* env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) + return JNI_ERR; + + // In here is also where you store things like class references + // if they are ever needed + + return JNI_VERSION_1_6; +} + +JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) {} + +JNIEXPORT jint JNICALL Java_com_vendor_jni_VendorJNI_initialize + (JNIEnv *, jclass) { + return 0; +} diff --git a/src/main/driver/cpp/driversource.cpp b/src/main/driver/cpp/driversource.cpp new file mode 100644 index 0000000..15716a4 --- /dev/null +++ b/src/main/driver/cpp/driversource.cpp @@ -0,0 +1,7 @@ +#include "driverheader.h" + +extern "C" { +void c_doThing() { + +} +} diff --git a/src/main/driver/include/driverheader.h b/src/main/driver/include/driverheader.h new file mode 100644 index 0000000..4fc60e1 --- /dev/null +++ b/src/main/driver/include/driverheader.h @@ -0,0 +1,5 @@ +#pragma once + +extern "C" { +void c_doThing(); +} diff --git a/src/main/driver/symbols.txt b/src/main/driver/symbols.txt new file mode 100644 index 0000000..2f9b641 --- /dev/null +++ b/src/main/driver/symbols.txt @@ -0,0 +1,4 @@ +JNI_OnLoad +JNI_OnUnload +Java_com_vendor_jni_VendorJNI_initialize +c_doThing diff --git a/src/main/java/com/vendor/jni/VendorJNI.java b/src/main/java/com/vendor/jni/VendorJNI.java new file mode 100644 index 0000000..88d3d5d --- /dev/null +++ b/src/main/java/com/vendor/jni/VendorJNI.java @@ -0,0 +1,51 @@ +package com.vendor.jni; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; + +import edu.wpi.first.wpiutil.RuntimeLoader; + +public class VendorJNI { + static boolean libraryLoaded = false; + static RuntimeLoader loader = null; + + public static class Helper { + private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true); + + public static boolean getExtractOnStaticLoad() { + return extractOnStaticLoad.get(); + } + + public static void setExtractOnStaticLoad(boolean load) { + extractOnStaticLoad.set(load); + } + } + + static { + if (Helper.getExtractOnStaticLoad()) { + try { + loader = new RuntimeLoader<>("Vendor", RuntimeLoader.getDefaultExtractionRoot(), VendorJNI.class); + loader.loadLibrary(); + } catch (IOException ex) { + ex.printStackTrace(); + System.exit(1); + } + libraryLoaded = true; + } + } + + /** + * Force load the library. + * @throws java.io.IOException thrown if the native library cannot be found + */ + public static synchronized void forceLoad() throws IOException { + if (libraryLoaded) { + return; + } + loader = new RuntimeLoader<>("VendorJNI", RuntimeLoader.getDefaultExtractionRoot(), VendorJNI.class); + loader.loadLibrary(); + libraryLoaded = true; + } + + public static native int initialize(); +} diff --git a/src/main/native/cpp/source.cpp b/src/main/native/cpp/source.cpp new file mode 100644 index 0000000..3990d40 --- /dev/null +++ b/src/main/native/cpp/source.cpp @@ -0,0 +1,6 @@ +#include "header.h" +#include "driverheader.h" + +void func() { + c_doThing(); +} diff --git a/src/main/native/include/header.h b/src/main/native/include/header.h new file mode 100644 index 0000000..e69de29