stackotter / swift-bundler

An Xcodeproj-less tool for creating cross-platform Swift apps.
https://swiftbundler.dev
Apache License 2.0
303 stars 14 forks source link

Implement debugging mode #25

Open stackotter opened 2 years ago

stackotter commented 2 years ago

When using swift bundler run to build and run an app, Swift Bundler simply starts the app's main executable as a child process and waits for it to finish (similar to what swift run does), however, often you need to debug apps and Swift Bundler has no simple way to do so. I often end up running lldb .build/bundler/MyApp.app/Contents/MacOS/MyApp and then typing run in lldb; very cumbersome!

A good way to implement this would be to add a --lldb flag to the RunCommand struct, and then modify Runner.run to take an extra boolean argument labelled debug. My reason for not calling the --lldb flag --debug is that in many build systems (such as Rust's cargo), --debug affects the optimization of the executable instead of whether the executable should be run in a debugger or not. I'm open to better suggestions! After modifying Runner.run, you'll need to also update all of Runner's other platform specific run... methods to support running in a debugger. If you can't figure out a way to do so for some of the more obscure platforms such as visionOS or iOSSimulator, I'm happy for that to be completed in a future issue.

benjiwolff commented 10 months ago

Hi If you are using VSCode, here is a launch.json with a configuration that will launch your app with the LLDB Debugger. Simply replace occurences of [appname] and [workspacefolder] with the name of your app and the VSCode workspace folder respectively. You will need the CodeLLDB extension.

{
  "configurations": [
    {
      "type": "lldb",
      "request": "launch",
      "sourceLanguages": ["swift"],
      "args": [],
      "cwd": "${workspaceFolder:[workspacefolder]}",
      "name": "Debug",
      "program": "${workspaceFolder:[workspacefolder]}/.build/bundler/[appname].App",
      "preLaunchTask": "swift-bundler bundle debug"
    }
  ]
}

You will also need a tasks.json file in your .vscode directory with

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "swift-bundler bundle debug",
      "type": "shell",
      "command": "swift bundler bundle -c debug"
    }
  ]
}

Feel free to add this to the swift-bundler templates.

stackotter commented 10 months ago

Awesome, thanks for the config!

stackotter commented 10 months ago

I've added a new --vscode flag to swift bundler create now. The flag just applies the VSCode overlay template to the project, providing both a launch.json and tasks.json. I updated your configuration to also include a way to debug release builds (I often find I need to do that for varying reasons).

I updated the settings referring to ${workspaceFolder:...} to just use ${workspaceFolder} since it is more robust against the project's root directory being renamed. If people want to use multi-root workspaces they can update the launch.json themselves I think (the reason the Swift extension uses the ${workspaceFolder:...} syntax is that it has functionality to update launch.json accordingly when a project's root directory is renamed).

Again, thanks for the config file examples! I've never used CodeLLDB myself so it might've taken me a bit longer to figure it out.

benjiwolff commented 10 months ago

Nice. I was under the impression I could not use breakpoints in the release build but I was wrong. 😃

There is a small issue with the --vscode flag. It seems to only be applied when --template is set. I accidently ran

swift bundler create Test --vscode --identifier com.test.Test

and no .vscode directory was generated.

stackotter commented 10 months ago

Nice. I was under the impression I could not use breakpoints in the release build but I was wrong. 😃

Oh you can? I also assumed that you couldn't 😅 The only reason I debug with release builds is if the crash only happens in release builds, or if the program is so slow in debug builds that it's impossible to debug.

It seems to only be applied when --template is set.

Ah, my bad, good catch! I never use create without a template so I didn't even remember that it was optional lol