import org.wpilib.toolchain.* buildscript { repositories { maven { url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn' } } } plugins { id 'base' id 'idea' id 'visual-studio' alias(libs.plugins.wpilib.versioning) alias(libs.plugins.wpilib.repositories) // NativeUtils and GradleVsCode are on the classpath for buildSrc, which doesn't carry version information. // We're forced to use the string-based syntax here instead. id 'org.wpilib.NativeUtils' apply false id 'org.wpilib.GradleVsCode' apply false // alias(libs.plugins.wpilib.native.utils) apply false // alias(libs.plugins.wpilib.gradle.vscode) alias(libs.plugins.wpilib.gradle.jni) alias(libs.plugins.lint.errorprone) apply false alias(libs.plugins.lint.spotbugs) apply false alias(libs.plugins.lint.spotless) apply false } wpilibVersioning.buildServerMode = project.hasProperty('buildServer') wpilibVersioning.releaseMode = project.hasProperty('releaseMode') allprojects { repositories { maven { url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn' } } if (project.hasProperty('releaseMode')) { wpilibRepositories.addAllReleaseRepositories(it) } else { wpilibRepositories.addAllDevelopmentRepositories(it) } tasks.withType(AbstractTestTask).configureEach { failOnNoDiscoveredTests = false } } develocity { buildScan { termsOfUseUrl = "https://gradle.com/help/legal-terms-of-use" termsOfUseAgree = "yes" } } import com.github.spotbugs.snom.Effort ext.spotbugsEffort = Effort.MAX ext.licenseFile = files("$rootDir/LICENSE.md", "$rootDir/ThirdPartyNotices.txt") if (project.hasProperty("publishVersion")) { wpilibVersioning.version.set(project.publishVersion) } wpilibVersioning.version.finalizeValue() def mrclibVersionConfiguration = configurations.create('mrclibVersion') { canBeConsumed = false canBeResolved = true transitive = false resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds' } dependencies { add(mrclibVersionConfiguration.name, 'org.wpilib.mrclib:mrclib-cpp:+:windowsx86-64@zip') } tasks.register('updateMrclibVersion') { description = 'Updates the version catalog to the latest available mrclib version' group = 'WPILib' doLast { def resolvedArtifacts = mrclibVersionConfiguration.resolvedConfiguration.resolvedArtifacts if (resolvedArtifacts.size() != 1) { throw new GradleException("Expected one mrclib artifact, but resolved ${resolvedArtifacts.size()}") } def resolvedArtifact = resolvedArtifacts.iterator().next() def latestVersion = resolvedArtifact.moduleVersion.id.version def versionCatalog = file('gradle/libs.versions.toml') def versionCatalogText = versionCatalog.getText('UTF-8') def mrclibVersionRegex = ~/(?m)^mrclib\s*=\s*"[^"]*"\s*$/ if (!mrclibVersionRegex.matcher(versionCatalogText).find()) { throw new GradleException("Could not find the mrclib version in ${versionCatalog}") } versionCatalog.setText( mrclibVersionRegex.matcher(versionCatalogText).replaceFirst("mrclib = \"${latestVersion}\""), 'UTF-8' ) logger.lifecycle("Updated mrclib to ${latestVersion}") def pythonCommand = System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows') ? ['python'] : ['python3'] def integrityHelper = file('shared/bazel/thirdparty/integrity_helper.py') logger.lifecycle('Updating third-party integrity hashes') providers.exec { workingDir(rootDir) commandLine(pythonCommand + [integrityHelper.absolutePath]) }.result.get() } } def outputsFolder = file("$buildDir/allOutputs") def versionFile = file("$outputsFolder/version.txt") task outputVersions() { description = 'Prints the versions of wpilib to a file for use by the downstream packaging project' group = 'Build' outputs.files(versionFile) doFirst { buildDir.mkdir() outputsFolder.mkdir() } doLast { versionFile.write wpilibVersioning.version.get() } } task libraryBuild() {} build.dependsOn outputVersions task copyAllOutputs(type: Copy) { destinationDir = outputsFolder } build.dependsOn copyAllOutputs copyAllOutputs.dependsOn outputVersions def copyReleaseOnly = project.hasProperty('ciReleaseOnly') ext.addTaskToCopyAllOutputs = { task -> if (copyReleaseOnly && task.name.contains('debug')) { return } copyAllOutputs.dependsOn task copyAllOutputs.inputs.file task.archiveFile copyAllOutputs.from task.archiveFile } ext.makeZipBaseName = { group, artifactId -> return "_GROUP_${group.replace(".", "_")}_ID_${artifactId}_CLS" } def versionCatalogZip = tasks.register('versionCatalogZip', Zip) { description = 'Packages the dependency version catalog for publication' group = 'Build' archiveBaseName = makeZipBaseName('org.wpilib', 'wpilib-versions') archiveVersion = '' destinationDirectory = outputsFolder from "$rootDir/gradle/libs.versions.toml" } copyAllOutputs.dependsOn versionCatalogZip subprojects { apply plugin: 'eclipse' apply plugin: 'idea' def subproj = it plugins.withType(NativeComponentPlugin) { subproj.apply plugin: MultiBuilds } apply from: "${rootDir}/shared/java/javastyle.gradle" tasks.withType(JavaCompile).configureEach { options.release = 25 options.encoding = "UTF-8" options.compilerArgs = [ "-Werror", "-XDstringConcat=inline", "-Xlint:all", // ignore AutoCloseable warnings "-Xlint:-try", // ignore missing serialVersionUID warnings "-Xlint:-serial", // ignore unclaimed annotation warning from annotation processing "-Xlint:-processing", "-Xlint:-preview", // ignore modules requiring automatic library modules "-Xlint:-requires-automatic", "-Xlint:-requires-transitive-automatic", // Java modules warn about module names with trailing digits "-Xlint:-module", "-Xlint:-classfile", // ignore warnings for classes missing explicit constructors "-Xlint:-missing-explicit-ctor", ] } // Enables UTF-8 support in Javadoc, disables 4 MB of fonts being added to every Javadoc JAR, add our styles tasks.withType(Javadoc).configureEach { options.addStringOption("charset", "utf-8") options.addStringOption("docencoding", "utf-8") options.addStringOption("encoding", "utf-8") options.addBooleanOption("-no-fonts", true) options.addStringOption("-add-stylesheet", "${rootDir}/docs/javadoc.css") if (project.name != "docs") { options.addBooleanOption('Xdoclint:none', true) } } // Sign outputs with Developer ID tasks.withType(AbstractLinkTask).configureEach { task -> task.inputs.property "HasDeveloperId", project.hasProperty("developerID") if (project.hasProperty("developerID")) { // Don't sign any executables because codesign complains // about relative rpath. if (!(task instanceof LinkExecutable)) { doLast { // Get path to binary. String path = task.getLinkedFile().getAsFile().get().getAbsolutePath() providers.exec { setWorkingDir(rootDir) def args = [ "sh", "-c", "codesign --force --strict --timestamp --options=runtime " + "--verbose -s ${project.findProperty("developerID")} ${path}" ] commandLine(args) }.result.get() } } } } } ext.getCurrentArch = { return NativePlatforms.desktop } wrapper { gradleVersion = '9.4.1' }