A wishlist: remote building and other peculiarities for Darling development
(I've asked about this on IRC a couple of times, but it's much better to write everything down on one page, so here goes.)
I'm hacking on Darling, a project to make macOS apps magically runnable on Linux (aside: come join us, it's fun!), and I'd love to use Builder for that.
The problem is, we have a somewhat peculiar workflow for building/installing/running/debugging things, which Builder can't support yet:
- The first rule of Darling development is: only ever run Darling in VMs, not on the real system. I use VirtualBox VMs that I connect to using SSH.
- Building is actually pretty straightforward, it's a fairly normal
cmake
/make
orcmake
/ninja
invocation. There are separate CMake goals to build/install our Linux kernel module, but I guess I can invoke those manually. - Installing is also pretty straightforward, it's
make install
orninja install
, except all running Darling containers have to be stopped before installation (using a custom command,darling shutdown
, for each container). - Running is the most complicated part. At the moment, you have to start apps by getting a shell inside a Darling container (
darling shell
, which boots the container up if necessary; similar tomachinectl shell
orflatpak run --command=sh
) and launching the app executable from that shell.- We may need to run/debug the
darling
command itself (in which case there's no app to run, just the command). - We may need to debug a daemon running in the container, such as
launchd
. - We may need to debug an app.
- We may need to debug a library/framework used by an app (e.g.
AppKit.framework
). This is the most common case for me.
- We may need to run/debug the
- Normally, the time from editing a line of code inside a library is to running the new version ("
ninja
, close the app,darling shutdown
,sudo ninja install
,darling shell
, run the app") is overly long. That's why I came up with a certain hack (overlaying some libraries/frameworks with symlinks to my build directory) that eliminates restarting the container andninja install
steps (so I'm only doing "close the app,ninja
, run the app", which is much faster). - Using a debugger is... tricky. Right now, you can't run a debugger from inside a Darling container; you have to run
gdb -p PID
from the outside (and then it won't have any debuginfo, not even symbols, because it doesn't support Mach-O; so you have to stare at disassembly and try to figure stuff out). In the future, we hope to getlldb
working inside Darling containers.
Now, I'd love to use Builder for this all. For that to happen,
- Builder itself should be running on my host, integrated with the rest of the system.
- But it should only build, lint, run clang for completion info, etc on the VM, not on the host.
- Ideally, there should be no need to store a copy of Darling source tree (which is huge) on the host (but I'm fine with mounting the VM file tree with GVFS/SSHFS).
- There has to be a setting for what kind of installation to perform (
sudo ninja install
? nothing? should it restart the container?) - There should be a way to select what command/app/process to run (just
darling shell
? some app inside of that?) - Preferably, there should be some way to use the debugger.
- Builder needs to support Objective-C (!72 (merged))
Of course it doesn't make sense to include any of the Darling-specific functionality in the upstream Builder; rather, it should be implemented in a plugin (I doubt it makes sense to include that plugin upstream either). I'm willing to write that plugin (if it's me who needs some weird functionality, it's my job to implement it), but I would need Builder to support:
- An abstraction like
IdeDevice
that allows Builder to build/lint/etc on a remote device (not just deploy binaries to a remote device).- I guess this includes any
clang
subprocesses and language servers Builder uses. - Things like
ide_runtime_has_program_in_path()
also have to take working on a remote device into account. Generally, it's a "non-local runtime" support.
- I guess this includes any
- Same for installation.
- An abstraction to customize what "running" means, in terms of launching an app to "run" a library/framework.
- This is orthogonal to, and should compose well with, the abstraction of runtimes (Flatpak runtime, Darling container) which can also be located on a remote device, and the abstraction that allows running an app under debugger/valgrind/sysprof.
- Either running debugger on a remote device, possibly inside a runtime, or running a debugger on the host, but connecting to a remote debugserver.
- Debugging with LLDB.
... and it'd be great if Builder/libide internals were better documented.
I realize none of this is nowhere near being a priority (except maybe for building on a remote device), so I'm not setting my hopes too high. Still, maybe you'll find it entertaining (if not interesting, useful, or insightful) to know what Builder needs to support in order for us to be able to use it in Darling development.