Adds new build system to repo (#1)

This commit is contained in:
Thad House
2017-07-28 07:29:49 -07:00
committed by Peter Johnson
parent 4f5b5b1377
commit 1243cf04ea
87 changed files with 1278 additions and 39 deletions

89
.clang-format Normal file
View File

@@ -0,0 +1,89 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: true
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^<.*\.h>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IndentCaseLabels: true
IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: false
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never
...

8
.travis-scripts/install.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/bash
if [[ $TRAVIS_OS_NAME != 'osx' ]]; then
# Install custom requirements on Linux
sudo add-apt-repository ppa:wpilib/toolchain -y
sudo apt-get update -q
sudo apt-get install frc-toolchain -y
fi

31
.travis.yml Normal file
View File

@@ -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 assemble -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/

53
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,53 @@
# Contributing to wpiutil
So you want to contribute your changes back to ntcore. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules written here, and behave with Gracious Professionalism.
- [General Contribution Rules](#general-contribution-rules)
- [What to Contribute](#what-to-contribute)
- [Coding Guidelines](#coding-guidelines)
- [Submitting Changes](#submitting-changes)
- [Pull Request Format](#pull-request-format)
- [Merge Process](#merge-process)
- [Licensing](#licensing)
## General Contribution Rules
- Everything in the library must work for the 3000+ teams that will be using it.
- We need to be able to maintain submitted changes, even if you are no longer working on the project.
- Excluding bug fixes, changes in one language generally need to have corresponding changes in other languages.
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
- Protocol changes must be carefully considered. Please open issues for protocol enhancements so we can discuss first.
- Changes should have tests.
- Code should be well documented.
- This often involves ScreenSteps. To add content to ScreenSteps, we will work with you to get the appropriate articles written.
## What to Contribute
- Bug reports and fixes
- We will generally accept bug fixes without too much question. If they are only implemented for one language, we will implement them for any other necessary languages. Bug reports are also welcome, please submit them to our GitHub issue tracker.
- While we do welcome improvements to the API, there are a few important rules to consider:
- Features must be added to both the C++ API and the Java API, with rare exceptions.
- During competition season, we will not merge any new feature additions. We want to ensure that the API is stable during the season to help minimize issues for teams.
- Ask about large changes before spending a bunch of time on them! You can create a new issue on our GitHub tracker for feature request/discussion and talk about it with us there.
- Features that make it easier for teams with less experience to be more successful are more likely to be accepted.
- Features in ntcore should be broadly applicable to all teams. Anything that is team specific should not be submitted.
## Coding Guidelines
ntcore uses Google style guides for both C++ and Java. Autoformatters are available for many popular editors at [https://github.com/google/styleguide]. An online version of the styleguide for [C++](https://google.github.io/styleguide/cppguide.html) and [Java](https://google.github.io/styleguide/javaguide.html) are also available. Additionally, offline copies of the style guide can be found in the style guide directory of the repository.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
## Submitting Changes
### Pull Request Format
Changes should be submitted as a Pull Request against the master branch of ntcore. For most changes, we ask that you squash your changes down to a single commit. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. No change will be merged unless it is up to date with the current master. We will also not merge any changes with merge commits in them; please rebase off of master before submitting a pull request. We do this to make sure that the git history isn't too cluttered.
### Merge Process
When you first submit changes, Travis-CI will attempt to run `./gradlew check` on your change. If this fails, you will need to fix any issues that it sees. Once Travis passes, we will begin the review process in more earnest. One or more WPILib team members will review your change. This will be a back-and-forth process with the WPILib team and the greater community. Once we are satisfied that your change is ready, we will allow our Jenkins instance to test it. This will run the full gamut of checks, including integration tests on actual hardware. Once all tests have passed and the team is satisfied, we will merge your change into the WPILib repository.
## Licensing
By contributing to ntcore, you agree that your code will be distributed with ntcore, and licensed under the license for the ntcore project. You should not contribute code that you do not have permission to relicense in this manner. This includes code that is licensed under the GPL that you do not have permission to relicense, as ntcore is not released under a copyleft license. Our license is the 3-clause BSD license, which you can find [here](license.txt).

26
appveyor.yml Normal file
View File

@@ -0,0 +1,26 @@
version: "{branch} {build}"
image:
- Visual Studio 2015
build:
verbosity: detailed
build_script:
- gradlew.bat assemble --info -PbuildAll
test_script:
- cmd: >-
SET JAVA_HOME=C:\Program Files\Java\jdk1.8.0
gradlew.bat check --info -PbuildAll
SET JAVA_HOME=C:\Program Files (x86)\Java\jdk1.8.0
gradlew.bat check --info -PbuildAll
cache:
- C:\Users\appveyor\.gradle
matrix:
fast_finish: true

109
build.gradle Normal file
View File

@@ -0,0 +1,109 @@
import edu.wpi.first.nativeutils.NativeUtils
buildscript {
repositories {
mavenLocal()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'gradle.plugin.edu.wpi.first:native-utils:1.0'
classpath 'gradle.plugin.edu.wpi.first.wpilib.versioning:wpilib-version-plugin:1.6'
}
}
ext.getClassifier = { binary->
return NativeUtils.getClassifier(binary)
}
ext.getPlatformPath = { binary->
return NativeUtils.getPlatformPath(binary)
}
apply plugin: 'cpp'
apply plugin: 'google-test'
apply plugin: 'visual-studio'
apply plugin: 'edu.wpi.first.NativeUtils'
apply plugin: 'java'
apply from: 'config.gradle'
model {
// Exports config is a utility to enable exporting all symbols in a C++ library on windows to a DLL.
// This removes the need for DllExport on a library. However, the gradle C++ builder has a bug
// where some extra symbols are added that cannot be resolved at link time. This configuration
// lets you specify specific symbols to exlude from exporting.
exportsConfigs {
wpiutil(ExportsConfig) {
x86ExcludeSymbols = [ '_CT??_R0?AV_System_error', '_CT??_R0?AVexception', '_CT??_R0?AVfailure',
'_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?AVruntime_error', '_CT??_R0?AVsystem_error', '_CTA5?AVfailure',
'_TI5?AVfailure' ]
}
}
components {
wpiutil(NativeLibrarySpec) {
sources {
cpp {
source {
srcDirs 'src/main/native/cpp'
include '**/*.cpp'
}
exportedHeaders {
srcDirs 'src/main/native/include'
}
}
}
}
// By default, a development executable will be generated. This is to help the case of
// testing specific functionality of the library.
if (!project.hasProperty('skipDevExe')) {
wpiutilDev(NativeExecutableSpec) {
sources {
cpp {
source {
srcDirs 'src/dev/native/cpp'
include '**/*.cpp'
lib library: "wpiutil"
}
exportedHeaders {
srcDirs 'src/dev/native/include'
}
}
}
}
}
// The TestingBase library is a workaround for an issue with the GoogleTest plugin.
// The plugin by default will rebuild the entire test source set, which increases
// build time. By testing an empty library, and then just linking the already built component
// into the test, we save the extra build
wpiutilTestingBase(NativeLibrarySpec) { }
}
testSuites {
wpiutilTestingBaseTest {
sources {
cpp.source.srcDir 'src/test/native/cpp'
cpp.exportedHeaders.srcDir 'src/test/native/include'
}
}
}
binaries {
withType(GoogleTestTestSuiteBinarySpec) {
if (it.component.testedComponent.name.contains('TestingBase') && !project.hasProperty('onlyAthena')) {
lib project: ':gmock', library: 'gmock', linkage: 'static'
lib library: 'wpiutil', linkage: 'shared'
} else {
it.buildable = false
}
}
}
}
apply from: 'publish.gradle'
task wrapper(type: Wrapper) {
gradleVersion = '4.0.1'
}

226
config.gradle Normal file
View File

@@ -0,0 +1,226 @@
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 = { config->
def arch = System.getProperty("os.arch")
def isWin = OperatingSystem.current().isWindows()
if (buildAll) {
return isWin
} else {
return isWin && arch == 'amd64'
}
}
def windows32PlatformDetect = { config->
def arch = System.getProperty("os.arch")
def isWin = OperatingSystem.current().isWindows()
if (buildAll) {
return isWin
} else {
return isWin && arch == 'x86'
}
}
def linux32IntelPlatformDetect = { config->
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 = { config->
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 = { config->
def arch = System.getProperty("os.arch")
def isIntel = (arch == 'amd64' || arch == 'i386')
return OperatingSystem.current().isLinux() && !isIntel
}
def mac64PlatformDetect = { config->
def arch = System.getProperty("os.arch")
def isMac = OperatingSystem.current().isMacOsX()
if (buildAll) {
return isMac
} else {
return isMac && arch == 'x86_64'
}
}
def mac32PlatformDetect = { config->
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
}
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
}
}
}
}

40
gmock/build.gradle Normal file
View File

@@ -0,0 +1,40 @@
import org.gradle.internal.os.OperatingSystem
if (!project.hasProperty('onlyAthena')) {
apply plugin: 'cpp'
apply plugin: 'visual-studio'
apply plugin: 'edu.wpi.first.NativeUtils'
ext.gmockProject = true
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']
}
}
}
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
}
}
}
}
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Thu Jul 13 10:56:22 PDT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0.1-bin.zip

172
gradlew vendored Executable file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## 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=""
# 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" "$@"

84
gradlew.bat vendored Normal file
View File

@@ -0,0 +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

24
license.txt Normal file
View File

@@ -0,0 +1,24 @@
* Copyright (c) 2009-2016 FIRST
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the FIRST nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY FIRST AND CONTRIBUTORS``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FIRST OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

192
publish.gradle Normal file
View File

@@ -0,0 +1,192 @@
apply plugin: 'maven-publish'
apply plugin: 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin'
def getVersion = {
if (WPILibVersion.version.contains('-'))
return WPILibVersion.version.substring(WPILibVersion.version.indexOf('-'))
else
return ""
}
if (!hasProperty('releaseType')) {
WPILibVersion {
releaseType = 'dev'
}
}
def pubVersion
if (project.hasProperty("publishVersion")) {
pubVersion = project.publishVersion
} else {
pubVersion = WPILibVersion.version
}
def outputsFolder = file("$buildDir/outputs")
def versionFile = file("$outputsFolder/version.txt")
task outputVersions() {
description = 'Prints the versions of wpiutil to a file for use by the downstream packaging project'
group = 'Build'
outputs.files(versionFile)
doFirst {
outputsFolder.mkdir()
}
doLast {
versionFile.write pubVersion
}
}
build.dependsOn outputVersions
def baseArtifactId = 'wpiutil'
def artifactGroupId = 'edu.wpi.first.wpiutil'
def licenseFile = new File("$rootDir/license.txt")
task cppSourcesZip(type: Zip) {
destinationDir = outputsFolder
classifier = "sources"
from(licenseFile) {
into '/'
}
from('src/main/native/cpp') {
into '/'
}
}
task cppHeadersZip(type: Zip) {
destinationDir = outputsFolder
classifier = "headers"
from(licenseFile) {
into '/'
}
from('src/main/native/include') {
into '/'
}
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
archives cppHeadersZip
archives cppSourcesZip
outputVersions.outputs.files.each {
archives it
}
}
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)
}
}
}
}
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 {
archives task
}
}
return taskList
}
model {
publishing {
def wpiutilTaskList = createComponentZipTasks($.components, 'wpiutil', 'zipcppwpiutil', 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'
}
}
}
}
})
publications {
cpp(MavenPublication) {
wpiutilTaskList.each {
artifact it
}
artifact cppHeadersZip
artifact cppSourcesZip
artifactId = "${baseArtifactId}-cpp"
groupId artifactGroupId
version pubVersion
}
}
}
}
publishing {
publications {
java(MavenPublication) {
artifact jar
artifact sourcesJar
artifact javadocJar
artifactId = "${baseArtifactId}-java"
groupId artifactGroupId
version pubVersion
}
}
}

73
readme.md Normal file
View File

@@ -0,0 +1,73 @@
# wpiutil
wpiutil is a utility library designed for making C++ interfacing easier.
## Build Requirements
To build wpiutil, a few requirements must be met:
- Platform Native Toolchain - You must have a toolchain for your native platform installed if you wish to build wpiutil for your machine. On Windows, this is Visual Studio. On Mac, this is Clang, and on Linux, this is GCC. Your toolchain must support the `-std=c++11` language flag.
- Platform Native JDK - In order to compile wpiutil your native platform, you must have the JDK for your platform installed, so that the correct JNI headers can be included.
- ARM Toolchain - To crosscompile wpiutil for the roboRIO, you must have the FRC ARM toolchain installed, which can be found [here](http://first.wpi.edu/FRC/roborio/toolchains/).
- Cross Toolchains (coming soon)
## Building
Gradle is the main build system used by wpiutil. All tasks are run with the `gradlew` wrapper, which is included in the root of the repository. All targets that can be accomplished by Gradle are referred to as tasks. The main task available is `build`. To run Gradle, cd into the build directory and run:
```bash
./gradlew build
```
This will build the roboRIO wpiutil library, in addition to the library for your native platform. Note if the roboRIO compiler cannot be found, the build will skip the roboRIO build. To build for either only the roboRIO, or every platform except the roboRIO, use the following flags:
```bash
-PskipAthena
-PonlyAthena
```
Note if you choose the `onlyAthena` flag, tests will not be ran, as they depend on the current platform being built.
In addition, more platforms can be built. For instance, with additional cross compilers more Arm binaries can be built. In addition, the second bitness for your current platform can be built with an additional flag. To enable every possible platform, use the following flag.
```bash
-PbuildAll
```
If you are building the native version on a 64 bit Linux computer, use a GCC installation which has multilib support enabled (it can compile both 32 and 64 bit programs). The package providing that support on most Linux distributions is called `gcc-multilib`.
By default, debug binaries of the libraries will be built. To switch to instead build release binaries, use the following flag
```bash
-PreleaseBuild
```
### Custom Cross Compilers
Coming soon
### Testing
By default, tests will be built for any native platform, and will be run during any execution of the `build` or `publish` tasks. To skip building and running the tests, use the `-PskipAllTests` command line flag.
### Publishing
to use wpiutil in downstream projects as a Maven-style dependency, use the `publish` command. This will publish the following artifact id's:
- edu.wpi.first.wpiutil:wpiutil-cpp
- edu.wpi.first.wpiutil:wpiutil-java
The `wpiutil-cpp` artifact will contain the following 2 classifiers:
- `headers` (contains C++ headers)
- `sources` (contains C++ sources)
In addition, a classifier will be created for each binary built by the current build. The internal layout of the artifacts will be as follows.
- `/os/arch/shared/` (shared binaries located here)
- `/os/arch/static/` (static binaries located here)
The `wpiutil-java` artifact will contain a jar with no classifiers. This is the java jar file. In addition, the following 2 classifiers will be contained
- `sources` (contains Java sources)
- `javadoc` (contains Javadoc sources)
All of these artifacts by default are published to `~/releases/maven/development`. To switch to the release repository (`~/release/maven/release`), use the flag `-PreleaseType=OFFICIAL`.
All downstream projects are configured to use the individual classifier artifacts. The previouse `desktop` classifier does not exist anymore.

1
settings.gradle Normal file
View File

@@ -0,0 +1 @@
include 'gmock'

View File

@@ -0,0 +1,7 @@
#include "llvm/StringRef.h"
#include <iostream>
int main() {
llvm::StringRef v1("Hello");
std::cout << v1.lower() << std::endl;
}

View File

@@ -0,0 +1,137 @@
package edu.wpi.first.wpiutil;
import java.io.File;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class RuntimeDetector {
private static String filePrefix;
private static String fileExtension;
private static String filePath;
private static synchronized void computePlatform() {
if (fileExtension != null && filePath != null && filePrefix != null) {
return;
}
boolean intel32 = is32BitIntel();
boolean intel64 = is64BitIntel();
if (isWindows()) {
filePrefix = "";
fileExtension = ".dll";
if (intel32) {
filePath = "/windows/x86/";
} else {
filePath = "/windows/x86-64/";
}
} else if (isMac()) {
filePrefix = "lib";
fileExtension = ".dylib";
if (intel32) {
filePath = "/mac/x86";
} else {
filePath = "/mac/x86-64/";
}
} else if (isLinux()) {
filePrefix = "lib";
fileExtension = ".so";
if (intel32) {
filePath = "/linux/x86/";
} else if (intel64) {
filePath = "/linux/x86-64/";
} else if (isAthena()) {
filePath = "/linux/athena/";
} else if (isRaspbian()) {
filePath = "/linux/raspbian/";
} else if (isArmV7()) {
filePath = "/linux/armhf/";
} else if (isAarch64()) {
filePath = "/linux/aarch/";
} else {
filePath = "/linux/arm/";
}
} else {
throw new RuntimeException("Failed to determine OS");
}
}
public static synchronized String getFilePrefix() {
computePlatform();
return filePrefix;
}
public static synchronized String getFileExtension() {
computePlatform();
return fileExtension;
}
public static synchronized String getPlatformPath() {
computePlatform();
return filePath;
}
public static synchronized String getLibraryResource(String libName) {
computePlatform();
return filePath + filePrefix + libName + fileExtension;
}
public static boolean isAthena() {
File runRobotFile = new File("/usr/local/frc/bin/frcRunRobot.sh");
return runRobotFile.exists();
}
public static boolean isRaspbian() {
try {
Process p = Runtime.getRuntime().exec("uname -a");
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
return in.readLine().contains("raspberrypi");
} catch (IOException e) {
return false;
}
}
public static boolean isArmV7() {
try {
Process p = Runtime.getRuntime().exec("uname -a");
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
return in.readLine().contains("armv7");
} catch (IOException e) {
return false;
}
}
public static boolean isAarch64() {
return false;
}
public static boolean isLinux() {
return System.getProperty("os.name").startsWith("Linux");
}
public static boolean isWindows() {
return System.getProperty("os.name").startsWith("Windows");
}
public static boolean isMac() {
return System.getProperty("os.name").startsWith("Mac");
}
public static boolean is32BitIntel() {
String arch = System.getProperty("os.arch");
return arch.equals("x86") || arch.equals("i386");
}
public static boolean is64BitIntel() {
String arch = System.getProperty("os.arch");
return arch.equals("amd64") || arch.equals("x86_64");
}
}

View File

@@ -1,39 +0,0 @@
apply plugin: 'google-test'
model {
testSuites {
wpiutilTest {
sources {
cpp {
source {
srcDirs = ["${rootDir}/wpiutil/unittest"]
includes = ['**/*.cpp']
}
exportedHeaders {
srcDirs = ["${rootDir}/wpiutil/include", "${rootDir}/gmock/include", "${rootDir}/gmock/gtest/include"]
includes = ['**/*.h']
}
}
}
binaries.all {
lib project: ':gmock', library: 'gmock', linkage: 'static'
lib library: 'wpiutil', linkage: 'static'
}
}
}
}
model {
binaries {
withType(GoogleTestTestSuiteBinarySpec) {
lib project: ':gmock', library: "gmock", linkage: "static"
lib library: 'wpiutil', linkage: 'static'
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'
}
}
}
}