diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4e4c5ac5..e4163c54 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,6 +29,9 @@ jobs: - name: InstallArm64Tc run: ../../gradlew installArm64Toolchain working-directory: testing/cpp + - name: InstallSystemCoreTc + run: ../../gradlew installSystemCoreToolchain + working-directory: testing/cpp - name: Build Test run: ../../gradlew build working-directory: testing/cpp diff --git a/README.md b/README.md index 5ef9a8bb..62e63c47 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ nativeUtils.wpi.configureDependencies { nativeUtils.wpi.platforms.roborio nativeUtils.wpi.platforms.linuxarm32 nativeUtils.wpi.platforms.linuxarm64 +nativeUtils.wpi.platforms.systemcore nativeUtils.wpi.platforms.windowsx64 nativeUtils.wpi.platforms.osxuniversal nativeUtils.wpi.platforms.linuxx64 diff --git a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/roborio/FrcHome.java b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/FrcHome.java similarity index 95% rename from ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/roborio/FrcHome.java rename to ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/FrcHome.java index 3744598f..bf57aee4 100644 --- a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/roborio/FrcHome.java +++ b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/FrcHome.java @@ -1,4 +1,4 @@ -package edu.wpi.first.toolchain.roborio; +package edu.wpi.first.toolchain; import org.gradle.internal.os.OperatingSystem; diff --git a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/NativePlatforms.java b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/NativePlatforms.java index 0ec5fc6f..7ba2459a 100644 --- a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/NativePlatforms.java +++ b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/NativePlatforms.java @@ -8,6 +8,7 @@ public class NativePlatforms { public static final String desktop = desktopOS() + desktopArch(); public static final String roborio = "linuxathena"; + public static final String systemcore = "linuxsystemcore"; public static final String linuxarm32 = "linuxarm32"; public static final String linuxarm64 = "linuxarm64"; diff --git a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/ToolchainExtension.java b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/ToolchainExtension.java index c062fb2b..8a51b7bf 100644 --- a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/ToolchainExtension.java +++ b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/ToolchainExtension.java @@ -17,6 +17,7 @@ import edu.wpi.first.toolchain.arm32.Arm32ToolchainPlugin; import edu.wpi.first.toolchain.arm64.Arm64ToolchainPlugin; +import edu.wpi.first.toolchain.systemcore.SystemCoreToolchainPlugin; import edu.wpi.first.toolchain.configurable.CrossCompilerConfiguration; import edu.wpi.first.toolchain.roborio.RoboRioToolchainPlugin; @@ -111,6 +112,10 @@ public void withCrossLinuxArm64() { } } + public void withCrossSystemCore() { + project.getPluginManager().apply(SystemCoreToolchainPlugin.class); + } + private boolean removeInvalidWindowsToolchains = true; public void setRemoveInvalidWindowsToolchains(boolean remove) { diff --git a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/roborio/RoboRioToolchainPlugin.java b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/roborio/RoboRioToolchainPlugin.java index 1bcd84cd..89d78871 100644 --- a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/roborio/RoboRioToolchainPlugin.java +++ b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/roborio/RoboRioToolchainPlugin.java @@ -9,6 +9,7 @@ import org.gradle.api.provider.Provider; import org.gradle.process.ExecOperations; +import edu.wpi.first.toolchain.FrcHome; import edu.wpi.first.toolchain.NativePlatforms; import edu.wpi.first.toolchain.ToolchainDescriptor; import edu.wpi.first.toolchain.ToolchainDiscoverer; diff --git a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/systemcore/SystemCoreToolchainExtension.java b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/systemcore/SystemCoreToolchainExtension.java new file mode 100644 index 00000000..48d620b7 --- /dev/null +++ b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/systemcore/SystemCoreToolchainExtension.java @@ -0,0 +1,18 @@ +package edu.wpi.first.toolchain.systemcore; + +import javax.inject.Inject; + +import edu.wpi.first.toolchain.opensdk.OpenSdkToolchainExtension; + +public abstract class SystemCoreToolchainExtension extends OpenSdkToolchainExtension { + public static final String TOOLCHAIN_VERSION = "2025-12.2.0"; + public static final String INSTALL_SUBDIR = "systemcore"; + + @Inject + public SystemCoreToolchainExtension() { + super(); + getVersionLow().convention("12.2.0"); + getVersionHigh().convention("12.2.0"); + getToolchainVersion().convention(TOOLCHAIN_VERSION); + } +} diff --git a/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/systemcore/SystemCoreToolchainPlugin.java b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/systemcore/SystemCoreToolchainPlugin.java new file mode 100644 index 00000000..18a1424a --- /dev/null +++ b/ToolchainPlugin/src/main/java/edu/wpi/first/toolchain/systemcore/SystemCoreToolchainPlugin.java @@ -0,0 +1,80 @@ +package edu.wpi.first.toolchain.systemcore; + +import java.io.File; + +import javax.inject.Inject; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.provider.Provider; +import org.gradle.process.ExecOperations; + +import edu.wpi.first.toolchain.FrcHome; +import edu.wpi.first.toolchain.NativePlatforms; +import edu.wpi.first.toolchain.ToolchainDescriptor; +import edu.wpi.first.toolchain.ToolchainDiscoverer; +import edu.wpi.first.toolchain.ToolchainExtension; +import edu.wpi.first.toolchain.configurable.CrossCompilerConfiguration; +import edu.wpi.first.toolchain.opensdk.OpenSdkToolchainBase; + +public class SystemCoreToolchainPlugin implements Plugin { + + public static final String toolchainName = "systemCore"; + public static final String baseToolchainName = "arm64-bookworm"; + + private SystemCoreToolchainExtension systemcoreExt; + private Project project; + private OpenSdkToolchainBase opensdk; + private ExecOperations operations; + + @Inject + public SystemCoreToolchainPlugin(ExecOperations operations) { + this.operations = operations; + } + + @Override + public void apply(Project project) { + this.project = project; + + systemcoreExt = project.getExtensions().create("systemcoreToolchain", SystemCoreToolchainExtension.class); + + ToolchainExtension toolchainExt = project.getExtensions().getByType(ToolchainExtension.class); + + opensdk = new OpenSdkToolchainBase(baseToolchainName, systemcoreExt, project, + SystemCoreToolchainExtension.INSTALL_SUBDIR, "bookworm", project.provider(() -> "aarch64-bookworm-linux-gnu"), toolchainExt.getToolchainGraphService(), operations); + + CrossCompilerConfiguration configuration = project.getObjects().newInstance(CrossCompilerConfiguration.class, NativePlatforms.systemcore); + + configuration.getArchitecture().set("arm64"); + configuration.getOperatingSystem().set("linux"); + configuration.getCompilerPrefix().set(""); + configuration.getOptional().convention(true); + + ToolchainDescriptor descriptor = new ToolchainDescriptor( + project, + toolchainName, + toolchainName + "Gcc", + configuration.getOptional()); + descriptor.getToolchainPlatform().set(NativePlatforms.systemcore); + descriptor.getVersionLow().set(systemcoreExt.getVersionLow()); + descriptor.getVersionHigh().set(systemcoreExt.getVersionHigh()); + configuration.getToolchainDescriptor().set(descriptor); + + toolchainExt.getCrossCompilers().add(configuration); + + populateDescriptor(descriptor); + } + + public void populateDescriptor(ToolchainDescriptor descriptor) { + Provider fp = project.provider(() -> { + String year = systemcoreExt.getToolchainVersion().get().split("-")[0].toLowerCase(); + File frcHomeLoc = new File(new FrcHome(year).get(), "systemcore"); + return frcHomeLoc; + }); + + // Add FRC Home first, as we want it searched first + descriptor.getDiscoverers().add(ToolchainDiscoverer.createProperty("FRCHome", descriptor, fp, opensdk::composeTool, project)); + + opensdk.populatePathAndDownloadDescriptors(descriptor); + } +} diff --git a/ToolchainPlugin/src/test/groovy/edu/wpi/first/toolchain/systemcore/SystemCoreDownloadTest.groovy b/ToolchainPlugin/src/test/groovy/edu/wpi/first/toolchain/systemcore/SystemCoreDownloadTest.groovy new file mode 100644 index 00000000..5d6833ac --- /dev/null +++ b/ToolchainPlugin/src/test/groovy/edu/wpi/first/toolchain/systemcore/SystemCoreDownloadTest.groovy @@ -0,0 +1,48 @@ +package edu.wpi.first.toolchain.systemcore + +import org.gradle.testkit.runner.GradleRunner +import static org.gradle.testkit.runner.TaskOutcome.* +import edu.wpi.first.toolchain.opensdk.OpenSdkToolchainBase + +import spock.lang.Shared +import spock.lang.TempDir +import spock.lang.Specification +import spock.lang.IgnoreIf + +@IgnoreIf({ !Boolean.valueOf(env['SPOCK_RUN_TOOLCHAINS']) }) +class Arm64DownloadTest extends Specification { + @TempDir File testProjectDir + File buildFile + @Shared File toolchainDir + + def setup() { + buildFile = new File(testProjectDir, 'build.gradle') + } + + def setupSpec() { + String year = SystemCoreToolchainExtension.TOOLCHAIN_VERSION.split("-")[0].toLowerCase(); + toolchainDir = OpenSdkToolchainBase.toolchainInstallLoc(year, SystemCoreToolchainExtension.INSTALL_SUBDIR); + def result = toolchainDir.deleteDir() // Returns true if all goes well, false otherwise. + assert result + } + + def "Toolchain Can Download"() { + given: + buildFile << """plugins { + id 'cpp' + id 'edu.wpi.first.Toolchain' +} + +toolchainsPlugin.withCrossSystemCore() +""" + when: + def result = GradleRunner.create() + .withProjectDir(testProjectDir) + .withArguments('installSystemCoreToolchain', '--stacktrace') + .withPluginClasspath() + .build() + + then: + result.task(':installSystemCoreToolchain').outcome == SUCCESS + } +} diff --git a/build.gradle b/build.gradle index 6a034c09..7336dd29 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ java { allprojects { group = "edu.wpi.first" - version = "2025.7.0" + version = "2025.7.1" if (project.hasProperty('publishVersion')) { version = project.publishVersion diff --git a/src/main/java/edu/wpi/first/nativeutils/NativeUtilsExtension.java b/src/main/java/edu/wpi/first/nativeutils/NativeUtilsExtension.java index 61c2215d..dec633eb 100644 --- a/src/main/java/edu/wpi/first/nativeutils/NativeUtilsExtension.java +++ b/src/main/java/edu/wpi/first/nativeutils/NativeUtilsExtension.java @@ -50,6 +50,7 @@ import edu.wpi.first.toolchain.arm64.Arm64ToolchainPlugin; import edu.wpi.first.toolchain.configurable.CrossCompilerConfiguration; import edu.wpi.first.toolchain.roborio.RoboRioToolchainPlugin; +import edu.wpi.first.toolchain.systemcore.SystemCoreToolchainPlugin; public class NativeUtilsExtension { @@ -366,6 +367,10 @@ public void withCrossRoboRIO() { project.getPluginManager().apply(RoboRioToolchainPlugin.class); } + public void withCrossSystemCore() { + project.getPluginManager().apply(SystemCoreToolchainPlugin.class); + } + public void withCrossLinuxArm32() { if (!NativePlatforms.desktop.equals(NativePlatforms.linuxarm32)) { project.getPluginManager().apply(Arm32ToolchainPlugin.class); diff --git a/src/main/java/edu/wpi/first/nativeutils/WPINativeUtilsExtension.java b/src/main/java/edu/wpi/first/nativeutils/WPINativeUtilsExtension.java index 67f8dce1..d495a4ee 100644 --- a/src/main/java/edu/wpi/first/nativeutils/WPINativeUtilsExtension.java +++ b/src/main/java/edu/wpi/first/nativeutils/WPINativeUtilsExtension.java @@ -95,6 +95,7 @@ public static class DefaultArguments { public static class Platforms { public final String roborio = "linuxathena"; + public final String systemcore = "linuxsystemcore"; public final String linuxarm32 = "linuxarm32"; public final String linuxarm64 = "linuxarm64"; public final String windowsx64 = "windowsx86-64"; @@ -102,7 +103,7 @@ public static class Platforms { public final String windowsarm64 = "windowsarm64"; public final String osxuniversal = "osxuniversal"; public final String linuxx64 = "linuxx86-64"; - public final List allPlatforms = List.of(roborio, linuxarm32, linuxarm64, windowsx64, + public final List allPlatforms = List.of(roborio, systemcore, linuxarm32, linuxarm64, windowsx64, windowsx86, windowsarm64, osxuniversal, linuxx64); public final List desktopPlatforms = List.of(windowsx64, windowsx86, windowsarm64, osxuniversal, linuxx64); } @@ -219,15 +220,20 @@ public WPINativeUtilsExtension(NativeUtilsExtension nativeExt, Project project) PlatformConfig linuxathena = nativeExt.getPlatformConfigs().create(platforms.roborio); PlatformConfig linuxarm32 = nativeExt.getPlatformConfigs().create(platforms.linuxarm32); PlatformConfig linuxarm64 = nativeExt.getPlatformConfigs().create(platforms.linuxarm64); + PlatformConfig linuxsystemcore = nativeExt.getPlatformConfigs().create(platforms.systemcore); unixPlatforms.put(platforms.linuxx64, linuxx86_64); unixPlatforms.put(platforms.osxuniversal, osxuniversal); unixPlatforms.put(platforms.linuxarm32, linuxarm32); unixPlatforms.put(platforms.roborio, linuxathena); unixPlatforms.put(platforms.linuxarm64, linuxarm64); + unixPlatforms.put(platforms.systemcore, linuxsystemcore); linuxathena.getPlatformPath().set("linux/athena"); addLinuxCrossArgs(linuxathena, 12); + linuxsystemcore.getPlatformPath().set("linux/systemcore"); + addLinuxCrossArgs(linuxsystemcore, 12); + linuxarm32.getPlatformPath().set("linux/arm32"); addLinuxCrossArgs(linuxarm32, 10); diff --git a/testing/cpp/build.gradle b/testing/cpp/build.gradle index d7c01786..b5f4817d 100644 --- a/testing/cpp/build.gradle +++ b/testing/cpp/build.gradle @@ -3,17 +3,19 @@ import edu.wpi.first.nativeutils.vendordeps.WPIVendorDepsPlugin plugins { id "cpp" - id "edu.wpi.first.NativeUtils" version "2025.7.0" + id "edu.wpi.first.NativeUtils" version "2025.7.1" } nativeUtils.addWpiNativeUtils() nativeUtils.withCrossRoboRIO() nativeUtils.withCrossLinuxArm32() nativeUtils.withCrossLinuxArm64() +nativeUtils.withCrossSystemCore(); nativeUtils.crossCompilers.getByName(NativePlatforms.roborio).optional = false nativeUtils.crossCompilers.getByName(NativePlatforms.linuxarm32).optional = false nativeUtils.crossCompilers.getByName(NativePlatforms.linuxarm64).optional = false +nativeUtils.crossCompilers.getByName(NativePlatforms.systemcore).optional = false project.getPlugins().apply(WPIVendorDepsPlugin.class)