Skip to content
Open
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
7 changes: 7 additions & 0 deletions buildPlugin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh
set -e
# This script builds the plugin on Linux

export Version="2024.1-EAP"

./gradlew :buildPlugin
14 changes: 9 additions & 5 deletions src/rider/main/kotlin/run/RunConfiguration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,22 @@ class RunConfiguration(project: Project, factory: ConfigurationFactory, name: St
private fun getRimworldState(environment: ExecutionEnvironment, debugInLinux: Boolean = false): CommandLineState {
return object : CommandLineState(environment) {
override fun startProcess(): ProcessHandler {
var pathToRun = getScriptName()
var arguments = getCommandLineOptions()
val rimworldPath = getScriptName()
var pathToRun = rimworldPath
// Splitting on space will be a source of future bugs. In the future the arguments should be List as early as possible
val arguments = getCommandLineOptions().split(' ').filter { it.isNotEmpty() }.toMutableList()

// If we're debugging in Rimworld, instead of /pwd/RimWorldLinux ...args we want to run /bin/sh /pwd/run.sh /pwd/RimWorldLinux ...args
if (debugInLinux) {
val bashScriptPath = "${Path(pathToRun).parent}/run.sh"
arguments = "$bashScriptPath $pathToRun $arguments"
Copy link
Contributor Author

@cshingle cshingle Jul 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line was messing up the commandline.
When running on linux the command should be /bin/sh and the run script command should be the first argument. Any user provided arguments should come at the end. The println I added makes the issue pretty obvious once you look at the output.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't have been messing it up. The arguments I had should have ended up as /bin/sh as the command and then ["dir/run.sh", "dir/RimWorldLinux", ...userArgs] as the end result. If you take a look at run.sh:75 it should be taking the first argument in as the executable name, so not passing in the executable would mean that if a user defines arguments in the command line options, it would eat the first argument as the executable name.

Perhaps it was the fact that the executable name shouldn't include it's directory?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it work the way you had it you would want
arguments = "$bashScriptPath $arguments"
You already build the run.sh path on this line
val bashScriptPath = "${Path(pathToRun).parent}/run.sh"

The reason I refactored the code some is to do the .split(' ') sooner. I have created a lot of programs that call commandline stuff from Java that needed to run on Windows, Linux and AIX. Splitting on space is fine until some asshole gives you a file path or file name with a space in it.

"Perhaps it was the fact that the executable name shouldn't include it's directory?"
Since we are setting the work directory you could just call run.sh and it would work. It is totally a matter of preference.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had some trouble getting run.sh executable. Setting it as +x in the resources wasn't preserving the permissions when copying it over and setting the permissions manually in Kotlin wasn't working for me, which is why I'm calling run.sh as an argument to /bin/sh instead.

But yeah, I think moving the .split earlier makes sense, I was going to just look into having getCommandLineOptions return a list directly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing a bash script into /bin/sh is a MUCH more portable solution than trying to execute the bash script directly. This was the right call.

"But yeah, I think moving the .split earlier makes sense, I was going to just look into having getCommandLineOptions return a list directly"
I totally support this.

pathToRun = "/bin/sh"
val bashScriptPath = "${Path(rimworldPath).parent}/run.sh"
arguments.add(0, bashScriptPath)
}

println("Calling $pathToRun with arguments ${arguments.joinToString(" ")} with working directory ${Path(rimworldPath).parent}")
val commandLine = GeneralCommandLine(pathToRun)
.withParameters(arguments.split(' ').filter { it.isNotEmpty() })
.withParameters(arguments)
.withWorkingDirectory(Path(rimworldPath).parent)

EnvironmentVariablesData.create(getEnvData(), true).configureCommandLine(commandLine, true)

Expand Down
Binary file modified src/rider/main/resources/UnityDoorstop/Linux/Doorstop/0Harmony.dll
100644 → 100755
Binary file not shown.
4 changes: 2 additions & 2 deletions src/rider/main/resources/UnityDoorstop/Linux/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ enabled="1"

# Path to the assembly to load and execute
# NOTE: The entrypoint must be of format `static void Doorstop.Entrypoint.Start()`
target_assembly="Doorstop.dll"
target_assembly="Doorstop/Doorstop.dll"

# Overrides the default boot.config file path
boot_config_override=
Expand Down Expand Up @@ -277,4 +277,4 @@ else
fi

# shellcheck disable=SC2086
exec "$executable_path" $rest_args
exec "$executable_path" $rest_args | tee debug.log