Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
build:
needs: validation
runs-on: ubuntu-24.04
env:
MAVEN_LOCAL_REPO: ${{ github.workspace }}/ci-maven-repository
Comment thread
ThadHouse marked this conversation as resolved.
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -23,21 +25,23 @@ jobs:
java-version: 25
distribution: temurin
- name: Publish to Maven Local
run: ./gradlew build publishToMavenLocal --stacktrace -PlocalPublish
run: ./gradlew -Dmaven.repo.local="$MAVEN_LOCAL_REPO" build publishToMavenLocal --stacktrace -PlocalPublish
- name: Check output
run: git --no-pager diff --exit-code HEAD
- uses: actions/upload-artifact@v4
with:
name: Maven
path: ~/.m2/repository/
path: ${{ env.MAVEN_LOCAL_REPO }}/

test_examples:
needs: build
runs-on: ubuntu-24.04
container: wpilib/debian-base:trixie
env:
MAVEN_LOCAL_REPO: ${{ github.workspace }}/ci-maven-repository
strategy:
matrix:
language: [cpp, java] #, asm, jni]
language: [cpp, java, kotlin] #, asm, jni]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
Expand All @@ -47,14 +51,14 @@ jobs:
- uses: actions/download-artifact@v4
with:
name: Maven
path: ~/.m2/repository/
path: ${{ env.MAVEN_LOCAL_REPO }}/

- name: Setup SystemCore Toolchain
if: ${{ (matrix.language == 'cpp') || (matrix.language == 'asm') }}
run: ../../gradlew installSystemCoreToolchain
run: ../../gradlew -Dmaven.repo.local="$MAVEN_LOCAL_REPO" installSystemCoreToolchain
working-directory: testing/${{ matrix.language }}
- name: Test ${{ matrix.language }} Build
run: ../../gradlew build
run: ../../gradlew -Dmaven.repo.local="$MAVEN_LOCAL_REPO" build
working-directory: testing/${{ matrix.language }}

publish:
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def processstarterToolVersion = "2027.0.0-alpha-6-68-g5a7d7d50e"
dependencies {
api 'com.google.code.gson:gson:2.13.1'

api 'org.wpilib:native-utils:2027.9.0'
api 'org.wpilib:native-utils:2027.10.0'

api 'de.undercouch:gradle-download-task:5.6.0'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import javax.inject.Inject;

import org.wpilib.deployutils.deploy.artifact.JavaArtifact;
import org.wpilib.deployutils.deploy.artifact.JavaClasspathArtifact;
import org.wpilib.deployutils.deploy.context.DeployContext;
import org.wpilib.deployutils.deploy.sessions.IPSessionController;
import org.wpilib.deployutils.deploy.target.RemoteTarget;

public class DebuggableJavaArtifact extends JavaArtifact implements DebuggableArtifact {
public class DebuggableJavaArtifact extends JavaClasspathArtifact implements DebuggableArtifact {

private int debugPort = 8349;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
package org.wpilib.gradlerio.deploy.systemcore;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import javax.inject.Inject;

import org.wpilib.deployutils.deploy.artifact.FileArtifact;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.FileCollection;
import org.wpilib.deployutils.PathUtils;
import org.wpilib.deployutils.deploy.artifact.CommandArtifact;
import org.wpilib.deployutils.deploy.artifact.FileCollectionArtifact;
import org.wpilib.deployutils.deploy.context.DeployContext;
import org.wpilib.gradlerio.deploy.DeployStage;
import org.wpilib.gradlerio.deploy.StagedDeployTarget;

public class RobotCommandArtifact extends FileArtifact {
public class RobotCommandArtifact extends CommandArtifact {

private Function<DeployContext, String> startCommandFunc;
public static final String ROBOT_COMMAND_FILE = "robotCommand";
public static final String ARG_FILE = "robotCommand.args";

private Function<DeployContext, String> robotCommandFunc;
private Function<DeployContext, String> argFileFunc;

@Inject
public RobotCommandArtifact(String name, StagedDeployTarget target) {
Expand All @@ -20,20 +30,42 @@ public RobotCommandArtifact(String name, StagedDeployTarget target) {
target.setDeployStage(this, DeployStage.FileDeploy);
}

public Function<DeployContext, String> getStartCommandFunc() {
return startCommandFunc;
public Function<DeployContext, String> getRobotCommandFunc() {
return robotCommandFunc;
}

public void setRobotCommandFunc(Function<DeployContext, String> robotCommandFunc) {
this.robotCommandFunc = robotCommandFunc;
}

public Function<DeployContext, String> getArgFileFunc() {
return argFileFunc;
}

public void setStartCommandFunc(Function<DeployContext, String> startCommandFunc) {
this.startCommandFunc = startCommandFunc;
public void setArgFileFunc(Function<DeployContext, String> argFileFunc) {
this.argFileFunc = argFileFunc;
}

@Override
public void deploy(DeployContext ctx) {
String content = startCommandFunc.apply(ctx);
String robotCommandContent = robotCommandFunc.apply(ctx);

ctx.execute("echo '" + content + "' > /home/systemcore/robotCommand");
ctx.execute("chmod +x /home/systemcore/robotCommand; chown systemcore /home/systemcore/robotCommand");
}
var robotCommandPath = PathUtils.combine(ctx.getWorkingDir(), ROBOT_COMMAND_FILE);
var argsPath = PathUtils.combine(ctx.getWorkingDir(), ARG_FILE);

Map<String, String> files = new HashMap<>();
files.put(robotCommandPath, robotCommandContent);

if (argFileFunc != null) {
String argFileContent = argFileFunc.apply(ctx);
files.put(argsPath, argFileContent);
}

ctx.putStringFiles(files);

ctx.execute("chmod +x " + robotCommandPath + "; chown systemcore " + robotCommandPath);
if (argFileFunc != null) {
ctx.execute("chmod +x " + argsPath + "; chown systemcore " + argsPath);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package org.wpilib.gradlerio.deploy.systemcore;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import org.gradle.api.tasks.TaskProvider;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.plugins.JavaApplication;
import org.gradle.api.plugins.internal.JavaPluginHelper;
import org.gradle.api.plugins.jvm.internal.JvmFeatureInternal;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.bundling.Jar;

import org.wpilib.deployutils.PathUtils;
import org.wpilib.deployutils.deploy.context.DeployContext;
import org.wpilib.gradlerio.deploy.DebuggableJavaArtifact;
Expand All @@ -16,6 +20,7 @@
import org.wpilib.gradlerio.wpi.WPIExtension;

public class WPILibJavaArtifact extends DebuggableJavaArtifact {
public static final String CLASSPATH_PATH = "/home/systemcore/wpilib/classpath";

private final RobotCommandArtifact robotCommandArtifact;

Expand All @@ -26,14 +31,24 @@ public class WPILibJavaArtifact extends DebuggableJavaArtifact {

private final SystemCore systemCore;

private final Property<String> mainClass;

private GarbageCollectorType gcType = GarbageCollectorType.ZGC;

private String javaCommand = "/usr/bin/java";

private final Property<Boolean> debugJni;

public Property<Boolean> getDebugJni() {
return debugJni;
}

@Inject
public WPILibJavaArtifact(String name, SystemCore target) {
super(name, target);
systemCore = target;
debugJni = target.getProject().getObjects().property(Boolean.class);
debugJni.set(false);

jvmArgs.add("-Djava.library.path=" + WPILibDeployPlugin.LIB_DEPLOY_DIR);
jvmArgs.add("--add-opens");
Expand All @@ -45,16 +60,24 @@ public WPILibJavaArtifact(String name, SystemCore target) {
var debugConfiguration = target.getProject().getConfigurations().create("systemcoreDebug");
var releaseConfiguration = target.getProject().getConfigurations().create("systemcoreRelease");

this.mainClass = target.getProject().getObjects().property(String.class);

this.getDirectory().set(CLASSPATH_PATH);
this.getDeleteOldFiles().set(true);

robotCommandArtifact = target.getArtifacts().create("robotCommand" + name, RobotCommandArtifact.class, art -> {
art.setStartCommandFunc(this::generateStartCommand);
art.setRobotCommandFunc(this::generateStartCommand);
art.setArgFileFunc(this::generateArgFile);
art.dependsOn(getJarProvider());
art.dependsOn(getConfigurationProvider());
art.dependsOn(this.getDeployTask());
});

nativeZipArtifact = target.getArtifacts().create("nativeZips" + name, WPILibJNILibraryArtifact.class, artifact -> {
target.setDeployStage(artifact, DeployStage.FileDeploy);

var cbl = target.getProject().getProviders().provider(() -> {
boolean debug = target.getProject().getExtensions().getByType(WPIExtension.class).getJava().getDebugJni().get();
boolean debug = getDebugJni().get();
if (debug) {
return debugConfiguration;
} else {
Expand Down Expand Up @@ -89,20 +112,11 @@ public void setGcType(GarbageCollectorType gcType) {
this.gcType = gcType;
}

private String getBinFile(DeployContext ctx) {
return PathUtils.combine(ctx.getWorkingDir(), getFilename().getOrElse(getFile().get().getName()));
}

@Override
public void setJarTask(Jar jarTask) {
robotCommandArtifact.getDeployTask().configure(x -> x.dependsOn(jarTask));
super.setJarTask(jarTask);
}

@Override
public void setJarTask(TaskProvider<Jar> jarTask) {
robotCommandArtifact.getDeployTask().configure(x -> x.dependsOn(jarTask));
super.setJarTask(jarTask);
public void configureApplication(JavaApplication javaApplication) {
JvmFeatureInternal mainFeature = JavaPluginHelper.getJavaComponent(getTarget().getProject()).getMainFeature();
setConfiguration(mainFeature.getRuntimeClasspathConfiguration());
setJar(mainFeature.getJarTask().get());
this.mainClass.set(javaApplication.getMainClass());
Comment thread
ThadHouse marked this conversation as resolved.
}

public RobotCommandArtifact getRobotCommandArtifact() {
Expand All @@ -121,29 +135,50 @@ public List<String> getArguments() {
return arguments;
}

private String generateStartCommand(DeployContext ctx) {
StringBuilder builder = new StringBuilder();
builder.append(javaCommand);
builder.append(" ");
builder.append(String.join(" ", gcType.getGcArguments()));
builder.append(" ");
builder.append(String.join(" ", jvmArgs));
builder.append(" ");
private String generateArgFile(DeployContext ctx) {
List<String> args = new ArrayList<>();
args.addAll(gcType.getGcArguments());
args.addAll(jvmArgs);

args.add("-cp \"\\");

// Put the entire deploy classpath
String deployDirectory = getDirectory().get();

List<File> files = new ArrayList<>(getFiles().get().getFiles());

for (int i = 0; i < files.size(); i++) {
File file = files.get(i);
String path = PathUtils.combine(deployDirectory, file.getName());
Comment thread
ThadHouse marked this conversation as resolved.
if (i != files.size() - 1) {
args.add(path + ":\\");
} else {
args.add(path + "\"");
}
}

// Debug stuff
boolean debug = systemCore.getDebug().get();
if (debug) {
builder.append("-XX:+UsePerfData -agentlib:jdwp=transport=dt_socket,address=0.0.0.0:");
builder.append(getDebugPort());
builder.append(",server=y,suspend=y ");
args.add("-XX:+UsePerfData -agentlib:jdwp=transport=dt_socket,address=0.0.0.0:" + getDebugPort() + ",server=y,suspend=y");
}

String binFile = getBinFile(ctx);
args.add(mainClass.get());

args.addAll(arguments);

args.add("");

return String.join("\n", args);
}

private String generateStartCommand(DeployContext ctx) {
StringBuilder builder = new StringBuilder();

builder.append(javaCommand);

builder.append("-jar \"");
builder.append(binFile);
builder.append("\" ");
builder.append(String.join(" ", arguments));
builder.append(" @");
builder.append(PathUtils.combine(ctx.getWorkingDir(), RobotCommandArtifact.ARG_FILE));

return builder.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public WPILibNativeArtifact(String name, SystemCore target) {
});

robotCommandArtifact = target.getArtifacts().create("robotCommand" + name, RobotCommandArtifact.class, art -> {
art.setStartCommandFunc(this::generateStartCommand);
art.setRobotCommandFunc(this::generateStartCommand);
art.dependsOn(getInstallTaskProvider());
});

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/wpilib/gradlerio/simulation/HalSimPair.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ public HalSimPair(String name, String libName, boolean defaultEnabled) {
this.libName = libName;
this.defaultEnabled = defaultEnabled;
}

public HalSimPair withDefaultEnabled(boolean defaultEnabled) {
return new HalSimPair(this.name, this.libName, defaultEnabled);
}
}
Loading
Loading