mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-19 00:41:41 +00:00
## Description Update to use our fork of the WPILib tool plugin. WPILib has indicated that it won't be maintained past 2026, so we're forking it under our org. We also fixed a bug that results in native libraries for multiple platforms being included in a jar when only the native libraries for the platform being built should be included. ## Meta Merge checklist: - [x] Pull Request title is [short, imperative summary](https://cbea.ms/git-commit/) of proposed changes - [x] The description documents the _what_ and _why_ - [ ] If this PR changes behavior or adds a feature, user documentation is updated - [ ] If this PR touches photon-serde, all messages have been regenerated and hashes have not changed unexpectedly - [ ] If this PR touches configuration, this is backwards compatible with settings back to v2025.3.2 - [ ] If this PR touches pipeline settings or anything related to data exchange, the frontend typing is updated - [ ] If this PR addresses a bug, a regression test for it is added --------- Co-authored-by: Gold856 <117957790+Gold856@users.noreply.github.com> Co-authored-by: samfreund <samf.236@proton.me>
377 lines
13 KiB
Groovy
377 lines
13 KiB
Groovy
apply plugin: 'org.photonvision.tools.WpilibTools'
|
|
|
|
import java.nio.file.Path
|
|
|
|
ext {
|
|
nativeName = "photonlib"
|
|
includePhotonTargeting = true
|
|
// Include the generated Version file
|
|
generatedHeaders = "src/generate/native/include"
|
|
licenseFile = file("LICENSE")
|
|
}
|
|
|
|
apply plugin: 'cpp'
|
|
apply plugin: 'google-test-test-suite'
|
|
apply plugin: 'edu.wpi.first.NativeUtils'
|
|
|
|
apply from: "${rootDir}/shared/config.gradle"
|
|
apply from: "${rootDir}/shared/javacommon.gradle"
|
|
|
|
apply from: "${rootDir}/versioningHelper.gradle"
|
|
|
|
nativeUtils {
|
|
exportsConfigs {
|
|
"${nativeName}" {}
|
|
}
|
|
}
|
|
|
|
model {
|
|
components {
|
|
"${nativeName}"(NativeLibrarySpec) {
|
|
sources {
|
|
cpp {
|
|
source {
|
|
srcDirs 'src/main/native/cpp', "$buildDir/generated/source/proto/main/cpp", "$buildDir/generated/native/cpp"
|
|
include '**/*.cpp', '**/*.cc'
|
|
}
|
|
exportedHeaders {
|
|
srcDirs 'src/main/native/include', "$buildDir/generated/source/proto/main/cpp"
|
|
if (project.hasProperty('generatedHeaders')) {
|
|
srcDir generatedHeaders
|
|
}
|
|
include "**/*.h"
|
|
}
|
|
}
|
|
}
|
|
|
|
binaries.all {
|
|
it.tasks.withType(CppCompile) {
|
|
it.dependsOn generateProto
|
|
}
|
|
if(project.hasProperty('includePhotonTargeting')) {
|
|
lib project: ':photon-targeting', library: 'photontargeting', linkage: 'shared'
|
|
}
|
|
}
|
|
|
|
nativeUtils.useRequiredLibrary(it, "wpilib_shared")
|
|
nativeUtils.useRequiredLibrary(it, "apriltag_shared")
|
|
nativeUtils.useRequiredLibrary(it, "opencv_shared")
|
|
nativeUtils.useRequiredLibrary(it, "cscore_shared")
|
|
nativeUtils.useRequiredLibrary(it, "cameraserver_shared")
|
|
}
|
|
}
|
|
testSuites {
|
|
"${nativeName}Test"(GoogleTestTestSuiteSpec) {
|
|
for(NativeComponentSpec c : $.components) {
|
|
if (c.name == nativeName) {
|
|
testing c
|
|
break
|
|
}
|
|
}
|
|
sources {
|
|
cpp {
|
|
source {
|
|
srcDirs 'src/test/native/cpp'
|
|
include '**/*.cpp'
|
|
}
|
|
exportedHeaders {
|
|
srcDirs 'src/test/native/include', "$buildDir/generated/source/proto/main/cpp"
|
|
}
|
|
}
|
|
}
|
|
|
|
binaries.all {
|
|
it.tasks.withType(CppCompile) {
|
|
it.dependsOn generateProto
|
|
}
|
|
if(project.hasProperty('includePhotonTargeting')) {
|
|
lib project: ':photon-targeting', library: 'photontargeting', linkage: 'shared'
|
|
lib project: ':photon-targeting', library: 'photontargetingJNI', linkage: 'shared'
|
|
}
|
|
}
|
|
|
|
nativeUtils.useRequiredLibrary(it, "cscore_shared")
|
|
nativeUtils.useRequiredLibrary(it, "cameraserver_shared")
|
|
nativeUtils.useRequiredLibrary(it, "wpilib_executable_shared")
|
|
nativeUtils.useRequiredLibrary(it, "googletest_static")
|
|
nativeUtils.useRequiredLibrary(it, "apriltag_shared")
|
|
nativeUtils.useRequiredLibrary(it, "opencv_shared")
|
|
}
|
|
}
|
|
|
|
tasks {
|
|
def c = $.testSuites
|
|
project.tasks.create('runCpp', Exec) {
|
|
description = "Run the photon-lib executable"
|
|
def found = false
|
|
def systemArch = getCurrentArch()
|
|
c.each {
|
|
if (it in GoogleTestTestSuiteSpec && it.name == "${nativeName}Test") {
|
|
it.binaries.each {
|
|
if (!found) {
|
|
def arch = it.targetPlatform.name
|
|
if (arch == systemArch) {
|
|
dependsOn it.tasks.install
|
|
commandLine it.tasks.install.runScriptFile.get().asFile.toString()
|
|
def filePath = it.tasks.install.installDirectory.get().toString() + File.separatorChar + 'lib'
|
|
test.dependsOn it.tasks.install
|
|
test.systemProperty 'java.library.path', filePath
|
|
test.environment 'LD_LIBRARY_PATH', filePath
|
|
test.environment 'DYLD_LIBRARY_PATH', filePath
|
|
test.workingDir filePath
|
|
|
|
found = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
apply from: "${rootDir}/shared/javacpp/publish.gradle"
|
|
|
|
// Include the version file in the distributed sources
|
|
cppHeadersZip {
|
|
from('src/generate/native/include') {
|
|
into '/'
|
|
}
|
|
}
|
|
|
|
def photonlibFileInput = file("src/generate/photonlib.json.in")
|
|
ext.photonlibFileOutput = file("$buildDir/generated/vendordeps/photonlib.json")
|
|
|
|
task generateVendorJson() {
|
|
description = "Generates the vendor JSON file"
|
|
group = "PhotonVision"
|
|
|
|
outputs.file photonlibFileOutput
|
|
inputs.file photonlibFileInput
|
|
|
|
println "Writing vendor JSON ${pubVersion} to $photonlibFileOutput"
|
|
|
|
if (photonlibFileOutput.exists()) {
|
|
photonlibFileOutput.delete()
|
|
}
|
|
photonlibFileOutput.parentFile.mkdirs()
|
|
|
|
def read = photonlibFileInput.text
|
|
.replace('${photon_version}', pubVersion)
|
|
.replace('${frc_year}', frcYear)
|
|
photonlibFileOutput.text = read
|
|
|
|
outputs.upToDateWhen { false }
|
|
}
|
|
|
|
build.dependsOn generateVendorJson
|
|
|
|
task publishVendorJsonToLocalOutputs(type: Copy) {
|
|
from photonlibFileOutput
|
|
into "$allOutputsFolder/vendordeps/"
|
|
|
|
// Rename to match the name of the JSON we publish to maven to avoid user confusion
|
|
rename { String fileName ->
|
|
fileName.replace(".json", "-json-1.0.json")
|
|
}
|
|
|
|
publish.dependsOn it
|
|
}
|
|
|
|
task copyVendorJsonToExamples {
|
|
outputs.upToDateWhen { false }
|
|
jar.finalizedBy it
|
|
}
|
|
|
|
[
|
|
"photonlib-cpp-examples",
|
|
"photonlib-java-examples"
|
|
].each { exampleFolder ->
|
|
file("${rootDir}/${exampleFolder}")
|
|
.listFiles()
|
|
.findAll {
|
|
return (it.isDirectory()
|
|
&& !it.isHidden()
|
|
&& !it.name.startsWith(".")
|
|
&& it.toPath().resolve("build.gradle").toFile().exists())
|
|
}
|
|
.collect { it.name }
|
|
.each { exampleVendordepFolder ->
|
|
task "copyVendorJsonTo${exampleFolder}-${exampleVendordepFolder}"(type: Copy) {
|
|
from photonlibFileOutput
|
|
|
|
into "${rootDir}/${exampleFolder}/${exampleVendordepFolder}/vendordeps/"
|
|
outputs.upToDateWhen { false }
|
|
copyVendorJsonToExamples.dependsOn it
|
|
}
|
|
}
|
|
}
|
|
|
|
clean {
|
|
[
|
|
"photonlib-cpp-examples",
|
|
"photonlib-java-examples"
|
|
].each { exampleFolder ->
|
|
file("${rootDir}/${exampleFolder}")
|
|
.listFiles()
|
|
.findAll {
|
|
return (it.isDirectory()
|
|
&& !it.isHidden()
|
|
&& !it.name.startsWith(".")
|
|
&& it.toPath().resolve("build.gradle").toFile().exists())
|
|
}
|
|
.collect { it.name }
|
|
.each { exampleVendordepFolder ->
|
|
delete "${rootDir}/${exampleFolder}/${exampleVendordepFolder}/vendordeps/"
|
|
}
|
|
}
|
|
}
|
|
|
|
task writeCurrentVersion {
|
|
doLast {
|
|
def versionFileIn = file("${rootDir}/shared/PhotonVersion.java.in")
|
|
writePhotonVersionFile(versionFileIn, Path.of("$buildDir", "generated", "java", "org", "photonvision", "PhotonVersion.java"),
|
|
versionString)
|
|
versionFileIn = file("${rootDir}/shared/PhotonVersion.cpp.in")
|
|
writePhotonVersionFile(versionFileIn, Path.of("$buildDir", "generated", "native", "cpp", "PhotonVersion.cpp"),
|
|
versionString)
|
|
}
|
|
}
|
|
|
|
// https://github.com/wpilibsuite/allwpilib/blob/main/wpilibj/build.gradle#L52
|
|
sourceSets.main.java.srcDir "${buildDir}/generated/java/"
|
|
compileJava.dependsOn writeCurrentVersion
|
|
|
|
// Building photon-lib requires photon-targeting to generate its proto files. This technically shouldn't be required but is needed for it to build.
|
|
model {
|
|
components {
|
|
all {
|
|
it.sources.each {
|
|
it.exportedHeaders {
|
|
srcDirs "src/main/native/include"
|
|
srcDirs "src/generate/native/include"
|
|
}
|
|
}
|
|
it.binaries.all {
|
|
it.tasks.withType(CppCompile) {
|
|
it.dependsOn writeCurrentVersion
|
|
it.dependsOn ":photon-targeting:generateProto"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
testSuites {
|
|
all {
|
|
it.binaries.all {
|
|
it.tasks.withType(CppCompile) {
|
|
it.dependsOn ":photon-targeting:generateProto"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def vendorJson = artifacts.add('archives', file("$photonlibFileOutput"))
|
|
|
|
if (!project.hasProperty('copyOfflineArtifacts')) {
|
|
// Publish the vendordep json
|
|
publishing {
|
|
publications {
|
|
vendorjson(MavenPublication) {
|
|
artifact vendorJson
|
|
|
|
artifactId = "${nativeName}-json"
|
|
groupId = "org.photonvision"
|
|
version = "1.0"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add photonversion to cpp sources zip
|
|
tasks.named('cppSourcesZip') {
|
|
dependsOn writeCurrentVersion
|
|
|
|
from("$buildDir/generated/native/cpp") {
|
|
into '/'
|
|
}
|
|
}
|
|
|
|
// Publish an uberzip with photon-lib and photon-targeting. This makes python binding easier to have it in one place
|
|
def zipBaseNameCombined = '_GROUP_org.photonvision_combinedcpp_ID_photonvision-combinedcpp_CLS'
|
|
task combinedCppSourcesZip(type: Zip) {
|
|
dependsOn(':photon-lib:cppSourcesZip', ':photon-targeting:cppSourcesZip')
|
|
|
|
destinationDirectory = file("$buildDir/outputs")
|
|
archiveBaseName = zipBaseNameCombined
|
|
archiveClassifier = "sources"
|
|
|
|
// Include the contents of the photon-lib cppSourcesZip. Magic chatgpt nonsense
|
|
from(zipTree(project(':photon-lib').tasks.cppSourcesZip.archiveFile.get().asFile)) {
|
|
into 'photon-lib'
|
|
}
|
|
from(zipTree(project(':photon-targeting').tasks.cppSourcesZip.archiveFile.get().asFile)) {
|
|
into 'photon-targeting'
|
|
}
|
|
|
|
duplicatesStrategy = DuplicatesStrategy.FAIL
|
|
}
|
|
task combinedHeadersZip(type: Zip) {
|
|
dependsOn(':photon-lib:cppHeadersZip', ':photon-targeting:cppHeadersZip')
|
|
|
|
destinationDirectory = file("$buildDir/outputs")
|
|
archiveBaseName = zipBaseNameCombined
|
|
archiveClassifier = "headers"
|
|
|
|
// Include the contents of the photon-lib cppHeadersZip. Magic chatgpt nonsense
|
|
from(zipTree(project(':photon-lib').tasks.cppHeadersZip.archiveFile.get().asFile)) {
|
|
into 'photon-lib'
|
|
}
|
|
from(zipTree(project(':photon-targeting').tasks.cppHeadersZip.archiveFile.get().asFile)) {
|
|
into 'photon-targeting'
|
|
}
|
|
|
|
duplicatesStrategy = DuplicatesStrategy.FAIL
|
|
}
|
|
|
|
// Add the uberzip to our maven publications
|
|
publishing {
|
|
publications {
|
|
// Don't publish if we're creating an offline zip
|
|
if (!project.hasProperty('copyOfflineArtifacts')) {
|
|
combinedcpp(MavenPublication) {
|
|
artifact combinedCppSourcesZip
|
|
artifact combinedHeadersZip
|
|
|
|
artifactId = "${nativeName}-combinedcpp"
|
|
groupId = artifactGroupId
|
|
version = pubVersion
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// setup wpilib bundled native libs
|
|
wpilibTools.deps.wpilibVersion = wpi.versions.wpilibVersion.get()
|
|
|
|
def nativeConfigName = 'wpilibNatives'
|
|
def nativeConfig = configurations.create(nativeConfigName)
|
|
|
|
def nativeTasks = wpilibTools.createExtractionTasks {
|
|
configurationName = nativeConfigName
|
|
}
|
|
|
|
nativeTasks.addToSourceSetResources(sourceSets.test)
|
|
|
|
dependencies {
|
|
wpilibNatives project(":photon-targeting")
|
|
}
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilib("wpimath")
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilib("wpinet")
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilib("wpiutil")
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilib("ntcore")
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilib("cscore")
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilib("apriltag")
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilib("hal")
|
|
nativeConfig.dependencies.add wpilibTools.deps.wpilibOpenCv("frc" + openCVYear, wpi.versions.opencvVersion.get())
|