How to compile an iOS app using the Swift compiler built from master?

Hi all,

I'm trying to diagnose a bug in the compiler that happens when I try to compile Swift files in an iOS app. To do that, I built a version of the compiler locally (from git) and I wanted to use that version to try the compilation process, but I can't seem to get that to work.

Here's what I did so far:

  • Using Xcode and the built-in Swift toolchain, I compiled the app successfully.
  • I went to Xcode's Report Navigator, selected the last successful build, and found the command used to compile the Swift sources there.
  • I copied that command to a .sh file and ran it successfully. That command uses Xcode's Swift compiler at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc.
  • I replaced the path to Xcode's Swift compiler with the path to my locally built Swift compiler.
  • When I run the new command, I get the following error multiple times:
169
{
  "kind": "signalled",
  "name": "compile",
  "pid": -1011,
  "process": {
    "real_pid": 66363
  },
  "error-message": "cancelled batch constituent",
  "signal": 2
}

TLDR: I suppose using a custom Swift compiler to build files from an iOS app might be complicated, but I really have no idea where to start. Can anyone point me in the right direction? Thanks a lot!

That error means that you're using batch mode and another file in the batch had an error. You can pretty much ignore it, but probably the thing to do is drop -parseable-output from your invocation.

For the record, the supported way to do this is to build a full toolchain, which you can do with the build-toolchain script in the utils/ directory. The unsupported way is to use the hidden SWIFT_EXEC build setting, setting that to the path to your own swiftc. This isn't quite as good because you don't get SourceKit or LLDB support, but it's better than copying commands to a .sh file. :-)

(Please don't use this in production, because Xcode might change how it interprets the setting, but it's fine for trying things out.)

(We should probably write this down in docs/ somewhere. It's not supposed to be a secret.)

3 Likes

No problems, I'm just doing some tests.

This seems more like what I'm looking for. If I build a full toolchain, I suppose I'll still be able to somehow attach LLDB to the swift compiler while it's running, right? Though I guess I'll have to learn to do it manually on the terminal, as there won't be an Xcode project like in utils/build-script -x, which is what I've been using until now...

What did you have in mind? Something like adding "if you want to build an iOS app, use the build-toolchain script" to the readme?

This is for using LLDB with the built Swift app, not for debugging the compiler. You can debug the compiler with any version of LLDB, since it's C++.

If build-toolchain's not already mentioned as the "right" way to do this then yes, it should be written down; but I was referring more to the "quick-and-dirty" way of SWIFT_EXEC.

Now I'm a bit confused... I want to debug the Swift compiler as it compiles my app. I just have to attach LLDB to the Swift compiler (inside the built toolchain), then build the app with Xcode using that toolchain, right?

Also, do I have to pass any special flags to the build-toolchain script for it to include debug information? I tried running build-toolchain --help but it didn't mention anything like that.

Yes, this is correct. Or build the app using SWIFT_EXEC, or do the manual command-line changing you were doing originally.

Looks like the preset it builds has debug info enabled by default, so you should be good.