Fix Linux arm32 and arm64 cross builds (#36)

This commit is contained in:
Tyler Veness 2024-09-18 11:44:52 -07:00 committed by GitHub
parent e06eda365a
commit 287b9d939e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 736 additions and 734 deletions

View File

@ -11,12 +11,12 @@ jobs:
- container: wpilib/roborio-cross-ubuntu:2024-22.04
artifact-name: Athena
build-options: "-Ponlylinuxathena"
# - container: wpilib/raspbian-cross-ubuntu:bullseye-22.04
# artifact-name: Arm32
# build-options: "-Ponlylinuxarm32"
# - container: wpilib/aarch64-cross-ubuntu:bullseye-22.04
# artifact-name: Arm64
# build-options: "-Ponlylinuxarm64"
- container: wpilib/raspbian-cross-ubuntu:bullseye-22.04
artifact-name: Arm32
build-options: "-Ponlylinuxarm32"
- container: wpilib/aarch64-cross-ubuntu:bullseye-22.04
artifact-name: Arm64
build-options: "-Ponlylinuxarm64"
- container: wpilib/ubuntu-base:22.04
artifact-name: Linux
build-options: ""

View File

@ -1,74 +1,74 @@
{
"fileName": "ExampleVendorJson.json",
"name": "ExampleVendorDep",
"version": "0.0.1",
"frcYear": "2024",
"uuid": "Generate A Unique GUID https://guidgenerator.com/online-guid-generator.aspx and insert it here", This line is to purposely make this fail to parse
"mavenUrls": [
"ThisNeedsToBeTheRootMavenUrl"
],
"jsonUrl": "InsertSomeUrlHere",
"javaDependencies": [
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-java",
"version": "0.0.1"
}
],
"jniDependencies": [
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-driver",
"version": "0.0.1",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"windowsx86",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
],
"cppDependencies": [
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-cpp",
"version": "0.0.1",
"libName": "Vendor",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"windowsx86",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-driver",
"version": "0.0.1",
"libName": "VendorDriver",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"windowsx86",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
]
}
{
"fileName": "ExampleVendorJson.json",
"name": "ExampleVendorDep",
"version": "0.0.1",
"frcYear": "2024",
"uuid": "Generate A Unique GUID https://guidgenerator.com/online-guid-generator.aspx and insert it here", This line is to purposely make this fail to parse
"mavenUrls": [
"ThisNeedsToBeTheRootMavenUrl"
],
"jsonUrl": "InsertSomeUrlHere",
"javaDependencies": [
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-java",
"version": "0.0.1"
}
],
"jniDependencies": [
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-driver",
"version": "0.0.1",
"skipInvalidPlatforms": true,
"isJar": false,
"validPlatforms": [
"windowsx86-64",
"windowsx86",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
],
"cppDependencies": [
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-cpp",
"version": "0.0.1",
"libName": "Vendor",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"windowsx86",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
},
{
"groupId": "com.vendor.frc",
"artifactId": "Vendor-driver",
"version": "0.0.1",
"libName": "VendorDriver",
"headerClassifier": "headers",
"sharedLibrary": false,
"skipInvalidPlatforms": true,
"binaryPlatforms": [
"windowsx86-64",
"windowsx86",
"linuxarm64",
"linuxx86-64",
"linuxathena",
"linuxarm32",
"osxuniversal"
]
}
]
}

View File

@ -1,25 +1,25 @@
# WPILib Vendor Template
This is the base WPILib vendor template for 2023.
## Layout
The build is split into 3 libraries. A java library is built. This has access to all of wpilib, and also can JNI load the driver library.
A driver library is built. This should contain all low level code you want to access from both C++, Java and any other text based language. This will not work with LabVIEW. This library has access to the WPILib HAL and wpiutil. This library can only export C symbols. It cannot export C++ symbols at all, and all C symbols must be explicitly listed in the symbols.txt file in the driver folder. JNI symbols must be listed in this file as well. This library however can be written in C++. If you attempt to change this library to have access to all of wpilib, you will break JNI access and it will no longer work.
A native C++ library is built. This has access to all of wpilib, and access to the driver library. This should implment the standard wpilib interfaces.
## Customizing
For Java, the library name will be the folder name the build is started from, so rename the folder to the name of your choosing.
For the native impl, you need to change the library name in the exportsConfigs block of build.gradle, the components block of build.gradle, and the taskList input array name in publish.gradle.
For the driver, change the library name in privateExportsConfigs, the driver name in components, and the driverTaskList input array name. In addition, you'll need to change the `lib library` in the native C++ impl component, and the JNI library name in the JNI java class.
For the maven artifact names, those are all in publish.gradle about 40 lines down.
## Building and editing
This uses gradle, and uses the same base setup as a standard GradleRIO robot project. This means you build with `./gradlew build`, and can install the native toolchain with `./gradlew installRoboRIOToolchain`. If you open this project in VS Code with the wpilib extension installed, you will get intellisense set up for both C++ and Java.
# WPILib Vendor Template
This is the base WPILib vendor template for 2023.
## Layout
The build is split into 3 libraries. A java library is built. This has access to all of wpilib, and also can JNI load the driver library.
A driver library is built. This should contain all low level code you want to access from both C++, Java and any other text based language. This will not work with LabVIEW. This library has access to the WPILib HAL and wpiutil. This library can only export C symbols. It cannot export C++ symbols at all, and all C symbols must be explicitly listed in the symbols.txt file in the driver folder. JNI symbols must be listed in this file as well. This library however can be written in C++. If you attempt to change this library to have access to all of wpilib, you will break JNI access and it will no longer work.
A native C++ library is built. This has access to all of wpilib, and access to the driver library. This should implment the standard wpilib interfaces.
## Customizing
For Java, the library name will be the folder name the build is started from, so rename the folder to the name of your choosing.
For the native impl, you need to change the library name in the exportsConfigs block of build.gradle, the components block of build.gradle, and the taskList input array name in publish.gradle.
For the driver, change the library name in privateExportsConfigs, the driver name in components, and the driverTaskList input array name. In addition, you'll need to change the `lib library` in the native C++ impl component, and the JNI library name in the JNI java class.
For the maven artifact names, those are all in publish.gradle about 40 lines down.
## Building and editing
This uses gradle, and uses the same base setup as a standard GradleRIO robot project. This means you build with `./gradlew build`, and can install the native toolchain with `./gradlew installRoboRIOToolchain`. If you open this project in VS Code with the wpilib extension installed, you will get intellisense set up for both C++ and Java.
By default, this template builds against the latest WPILib development build. To build against the last WPILib tagged release, build with `./gradlew build -PreleaseMode`.

View File

@ -1,130 +1,130 @@
plugins {
id 'cpp'
id 'java'
id 'google-test'
id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2020.2'
id 'edu.wpi.first.NativeUtils' version '2024.7.2'
id 'edu.wpi.first.GradleJni' version '1.1.0'
id 'edu.wpi.first.GradleVsCode' version '2.1.0'
}
repositories {
mavenCentral()
}
if (project.hasProperty('releaseMode')) {
wpilibRepositories.addAllReleaseRepositories(project)
} else {
wpilibRepositories.addAllDevelopmentRepositories(project)
}
// Apply C++ configuration
apply from: 'config.gradle'
// Apply Java configuration
dependencies {
implementation 'edu.wpi.first.cscore:cscore-java:2024.+'
implementation 'edu.wpi.first.cameraserver:cameraserver-java:2024.+'
implementation 'edu.wpi.first.ntcore:ntcore-java:2024.+'
implementation 'edu.wpi.first.wpilibj:wpilibj-java:2024.+'
implementation 'edu.wpi.first.wpiutil:wpiutil-java:2024.+'
implementation 'edu.wpi.first.wpimath:wpimath-java:2024.+'
implementation 'edu.wpi.first.wpiunits:wpiunits-java:2024.+'
implementation 'edu.wpi.first.hal:hal-java:2024.+'
implementation "org.ejml:ejml-simple:0.43.1"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-core:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-databind:2.15.2"
implementation 'edu.wpi.first.thirdparty.frc2024.opencv:opencv-java:4.8.0-2'
}
// 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.linuxarm32)
jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.linuxarm64)
sources {
cpp {
source {
srcDirs 'src/main/driver/cpp'
include '**/*.cpp'
}
exportedHeaders {
srcDirs 'src/main/driver/include'
}
}
}
nativeUtils.useRequiredLibrary(it, "driver_shared")
}
}
testSuites {
VendorTest {
sources.cpp {
source {
srcDir 'src/test/native/cpp'
include '**/*.cpp'
}
}
binaries.all {
lib library: 'VendorDriver', linkage: 'shared'
}
nativeUtils.useRequiredLibrary(it, "wpilib_executable_shared", "googletest_static")
}
VendorDriverTest {
sources.cpp {
source {
srcDir 'src/test/driver/cpp'
include '**/*.cpp'
}
}
nativeUtils.useRequiredLibrary(it, "wpilib_executable_shared", "googletest_static")
}
}
}
apply from: 'publish.gradle'
wrapper {
gradleVersion '8.5'
}
plugins {
id 'cpp'
id 'java'
id 'google-test'
id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2020.2'
id 'edu.wpi.first.NativeUtils' version '2024.7.2'
id 'edu.wpi.first.GradleJni' version '1.1.0'
id 'edu.wpi.first.GradleVsCode' version '2.1.0'
}
repositories {
mavenCentral()
}
if (project.hasProperty('releaseMode')) {
wpilibRepositories.addAllReleaseRepositories(project)
} else {
wpilibRepositories.addAllDevelopmentRepositories(project)
}
// Apply C++ configuration
apply from: 'config.gradle'
// Apply Java configuration
dependencies {
implementation 'edu.wpi.first.cscore:cscore-java:2024.+'
implementation 'edu.wpi.first.cameraserver:cameraserver-java:2024.+'
implementation 'edu.wpi.first.ntcore:ntcore-java:2024.+'
implementation 'edu.wpi.first.wpilibj:wpilibj-java:2024.+'
implementation 'edu.wpi.first.wpiutil:wpiutil-java:2024.+'
implementation 'edu.wpi.first.wpimath:wpimath-java:2024.+'
implementation 'edu.wpi.first.wpiunits:wpiunits-java:2024.+'
implementation 'edu.wpi.first.hal:hal-java:2024.+'
implementation "org.ejml:ejml-simple:0.43.1"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-core:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-databind:2.15.2"
implementation 'edu.wpi.first.thirdparty.frc2024.opencv:opencv-java:4.8.0-2'
}
// 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.linuxarm32)
jniCrossCompileOptions << JniCrossCompileOptions(nativeUtils.wpi.platforms.linuxarm64)
sources {
cpp {
source {
srcDirs 'src/main/driver/cpp'
include '**/*.cpp'
}
exportedHeaders {
srcDirs 'src/main/driver/include'
}
}
}
nativeUtils.useRequiredLibrary(it, "driver_shared")
}
}
testSuites {
VendorTest {
sources.cpp {
source {
srcDir 'src/test/native/cpp'
include '**/*.cpp'
}
}
binaries.all {
lib library: 'VendorDriver', linkage: 'shared'
}
nativeUtils.useRequiredLibrary(it, "wpilib_executable_shared", "googletest_static")
}
VendorDriverTest {
sources.cpp {
source {
srcDir 'src/test/driver/cpp'
include '**/*.cpp'
}
}
nativeUtils.useRequiredLibrary(it, "wpilib_executable_shared", "googletest_static")
}
}
}
apply from: 'publish.gradle'
wrapper {
gradleVersion '8.5'
}

View File

@ -1,177 +1,179 @@
import org.gradle.internal.os.OperatingSystem
nativeUtils.addWpiNativeUtils()
nativeUtils.withCrossRoboRIO()
nativeUtils {
wpi {
configureDependencies {
wpiVersion = "2024.+"
opencvYear = "frc2024"
googleTestYear = "frc2024"
niLibVersion = "2024.2.1"
opencvVersion = "4.8.0-2"
googleTestVersion = "1.14.0-1"
}
}
}
nativeUtils.wpi.addWarnings()
nativeUtils.wpi.addWarningsAsErrors()
nativeUtils.setSinglePrintPerPlatform()
model {
// Uncomment this, and remove lines below it to enable builds for just roborio
// components {
// all {
// targetPlatform nativeUtils.wpi.platforms.roborio
// }
// }
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
destinationDirectory = outputsFolder
archiveClassifier = key
archiveBaseName = '_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"
destinationDirectory = outputsFolder
classifier = "all"
archiveBaseName = base
duplicatesStrategy = 'exclude'
list.each {
if (it.name.endsWith('debug')) return
from project.zipTree(it.archiveFile)
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'
}
}
}
}
}
import org.gradle.internal.os.OperatingSystem
nativeUtils.addWpiNativeUtils()
nativeUtils.withCrossRoboRIO()
nativeUtils.withCrossLinuxArm32()
nativeUtils.withCrossLinuxArm64()
nativeUtils {
wpi {
configureDependencies {
wpiVersion = "2024.+"
opencvYear = "frc2024"
googleTestYear = "frc2024"
niLibVersion = "2024.2.1"
opencvVersion = "4.8.0-2"
googleTestVersion = "1.14.0-1"
}
}
}
nativeUtils.wpi.addWarnings()
nativeUtils.wpi.addWarningsAsErrors()
nativeUtils.setSinglePrintPerPlatform()
model {
// Uncomment this, and remove lines below it to enable builds for just roborio
// components {
// all {
// targetPlatform nativeUtils.wpi.platforms.roborio
// }
// }
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
destinationDirectory = outputsFolder
archiveClassifier = key
archiveBaseName = '_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"
destinationDirectory = outputsFolder
classifier = "all"
archiveBaseName = base
duplicatesStrategy = 'exclude'
list.each {
if (it.name.endsWith('debug')) return
from project.zipTree(it.archiveFile)
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'
}
}
}
}
}

View File

@ -1,205 +1,205 @@
apply plugin: 'maven-publish'
ext.licenseFile = files("$rootDir/LICENSE.txt")
def pubVersion = '0.0.1'
def outputsFolder = file("$buildDir/outputs")
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 file("$buildDir/allOutputs")
from versionFile
dependsOn outputVersions
}
build.dependsOn copyAllOutputs
copyAllOutputs.dependsOn outputVersions
ext.addTaskToCopyAllOutputs = { task ->
copyAllOutputs.dependsOn task
copyAllOutputs.inputs.file task.archiveFile
copyAllOutputs.from task.archiveFile
}
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) {
destinationDirectory = outputsFolder
archiveBaseName = zipBaseName
archiveClassifier = "headers"
from(licenseFile) {
into '/'
}
from('src/main/native/include') {
into '/'
}
}
task cppSourceZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = zipBaseName
archiveClassifier = "sources"
from(licenseFile) {
into '/'
}
from('src/main/native/cpp') {
into '/'
}
}
task cppDriverHeadersZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = driverZipBaseName
archiveClassifier = "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) {
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
archiveClassifier = 'javadoc'
from javadoc.destinationDir
}
task outputJar(type: Jar, dependsOn: classes) {
archiveBaseName = javaBaseName
destinationDirectory = outputsFolder
from sourceSets.main.output
}
task outputSourcesJar(type: Jar, dependsOn: classes) {
archiveBaseName = javaBaseName
destinationDirectory = outputsFolder
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
task outputJavadocJar(type: Jar, dependsOn: javadoc) {
archiveBaseName = javaBaseName
destinationDirectory = outputsFolder
archiveClassifier = '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, ['VendorDriver'], 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
}
}
}
}
apply plugin: 'maven-publish'
ext.licenseFile = files("$rootDir/LICENSE.txt")
def pubVersion = '0.0.1'
def outputsFolder = file("$buildDir/outputs")
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 file("$buildDir/allOutputs")
from versionFile
dependsOn outputVersions
}
build.dependsOn copyAllOutputs
copyAllOutputs.dependsOn outputVersions
ext.addTaskToCopyAllOutputs = { task ->
copyAllOutputs.dependsOn task
copyAllOutputs.inputs.file task.archiveFile
copyAllOutputs.from task.archiveFile
}
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) {
destinationDirectory = outputsFolder
archiveBaseName = zipBaseName
archiveClassifier = "headers"
from(licenseFile) {
into '/'
}
from('src/main/native/include') {
into '/'
}
}
task cppSourceZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = zipBaseName
archiveClassifier = "sources"
from(licenseFile) {
into '/'
}
from('src/main/native/cpp') {
into '/'
}
}
task cppDriverHeadersZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = driverZipBaseName
archiveClassifier = "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) {
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
archiveClassifier = 'javadoc'
from javadoc.destinationDir
}
task outputJar(type: Jar, dependsOn: classes) {
archiveBaseName = javaBaseName
destinationDirectory = outputsFolder
from sourceSets.main.output
}
task outputSourcesJar(type: Jar, dependsOn: classes) {
archiveBaseName = javaBaseName
destinationDirectory = outputsFolder
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
task outputJavadocJar(type: Jar, dependsOn: javadoc) {
archiveBaseName = javaBaseName
destinationDirectory = outputsFolder
archiveClassifier = '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, ['VendorDriver'], 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
}
}
}
}

View File

@ -1,22 +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<void**>(&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;
}
#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<void**>(&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;
}

View File

@ -1,7 +1,7 @@
#include "driverheader.h"
extern "C" {
void c_doThing() {
}
}
#include "driverheader.h"
extern "C" {
void c_doThing() {
}
}

View File

@ -1,11 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void c_doThing();
#ifdef __cplusplus
} // extern "C"
#endif
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
void c_doThing();
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -1,60 +1,60 @@
package com.vendor.jni;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Demo class for loading the driver via JNI.
*/
public class VendorJNI {
static boolean libraryLoaded = false;
/**
* Helper class for determining whether or not to load the driver on static initialization.
*/
public static class Helper {
private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true);
/**
* Get whether to load the driver on static init.
* @return true if the driver will load on static init
*/
public static boolean getExtractOnStaticLoad() {
return extractOnStaticLoad.get();
}
/**
* Set whether to load the driver on static init.
* @param load the new value
*/
public static void setExtractOnStaticLoad(boolean load) {
extractOnStaticLoad.set(load);
}
}
static {
if (Helper.getExtractOnStaticLoad()) {
System.loadLibrary("VendorDriver");
libraryLoaded = true;
}
}
/**
* Force load the library.
*/
public static synchronized void forceLoad() {
if (libraryLoaded) {
return;
}
System.loadLibrary("VendorDriver");
libraryLoaded = true;
}
/**
* Tells the driver to initialize.
* This is a demo of a native JNI method from the driver.
*
* @return the int returned by the driver
* @see "VendorJNI.cpp"
*/
public static native int initialize();
}
package com.vendor.jni;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Demo class for loading the driver via JNI.
*/
public class VendorJNI {
static boolean libraryLoaded = false;
/**
* Helper class for determining whether or not to load the driver on static initialization.
*/
public static class Helper {
private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true);
/**
* Get whether to load the driver on static init.
* @return true if the driver will load on static init
*/
public static boolean getExtractOnStaticLoad() {
return extractOnStaticLoad.get();
}
/**
* Set whether to load the driver on static init.
* @param load the new value
*/
public static void setExtractOnStaticLoad(boolean load) {
extractOnStaticLoad.set(load);
}
}
static {
if (Helper.getExtractOnStaticLoad()) {
System.loadLibrary("VendorDriver");
libraryLoaded = true;
}
}
/**
* Force load the library.
*/
public static synchronized void forceLoad() {
if (libraryLoaded) {
return;
}
System.loadLibrary("VendorDriver");
libraryLoaded = true;
}
/**
* Tells the driver to initialize.
* This is a demo of a native JNI method from the driver.
*
* @return the int returned by the driver
* @see "VendorJNI.cpp"
*/
public static native int initialize();
}

View File

@ -1,6 +1,6 @@
#include "header.h"
#include "driverheader.h"
void func() {
c_doThing();
}
#include "header.h"
#include "driverheader.h"
void func() {
c_doThing();
}

View File

@ -1,6 +1,6 @@
#include "gtest/gtest.h"
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#include "gtest/gtest.h"
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -1,6 +1,6 @@
#include "gtest/gtest.h"
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#include "gtest/gtest.h"
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}