import java.nio.file.Path ext { nativeName = "photonlib" includePhotonTargeting = true // Include the generated Version file generatedHeaders = "src/generate/native/include" } 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", "src/generate/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") } } 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' } } 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.mustRunAfter generateVendorJson publish.mustRunAfter 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 writeCurrentVersion { def versionFileIn = file("${rootDir}/shared/PhotonVersion.java.in") writePhotonVersionFile(versionFileIn, Path.of("$projectDir", "src", "main", "java", "org", "photonvision", "PhotonVersion.java"), versionString) versionFileIn = file("${rootDir}/shared/PhotonVersion.cpp.in") writePhotonVersionFile(versionFileIn, Path.of("$projectDir", "src", "generate", "native", "cpp", "PhotonVersion.cpp"), versionString) } build.mustRunAfter writeCurrentVersion cppHeadersZip.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 ":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("$projectDir/src/generate/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') mustRunAfter(':photon-lib:cppHeadersZip', ':photon-targeting:cppHeadersZip') 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') mustRunAfter(':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 } } } }