Xtool: cross-platform Xcode replacement. Build iOS apps on Linux and more!

Hi folks! A few months ago I shared my Swift SDK for Darwin, which allows you to build iOS Swift Packages on Linux, amongst other things. I mentioned that a lot of work still needed to be done, such as handling codesigning, packaging, and bundling.

I'm super excited to share that we've finally reached the point where all of these things are now possible with cross-platform, open source software. Enter, xtool!

About

xtool does a lot of things (because Xcode does a lot of things :sweat_smile:) but the headline features are

:white_check_mark: Build a SwiftPM package into an iOS app

:white_check_mark: Sign and install iOS apps

:white_check_mark: Interact with Apple Developer Services programmatically

This means it's finally possible to build and deploy iOS apps from Linux and Windows (WSL). At the same time, xtool is SwiftPM-based and fully declarative, which means you can also use it to replace Xcode on macOS for building iOS software!

Using xtool

I put together some DocC Articles + a DocC Tutorial on how to get started with xtool. You can find these at xtool.sh.

Gotchas

The aim so far has been to flesh out the core functionality in a typical build-run-edit loop for an iOS application. There's some things that are infeasible outside macOS, and others that are possible but still need to be implemented:

  • Interface builder: would require a lot of effort to replicate, probably not worth it since SwiftUI mostly supersedes it at this point
  • Asset catalogs: require reverse engineering to implement, might be worth it. You can still add images as raw files in the absence of asset catalogs, it's just less efficient.
  • Proprietary macros: The ones that are also in the Linux toolchain (e.g. @Observable) work just fine, but Apple-proprietary macros (such as the SwiftData ones) will need to be reverse-engineered and rebuilt from source if we want them to work. Or Apple could ship these as WebAssembly Macros which would make them host-independent :folded_hands:
  • App Extensions: Right now you can only build "Application"-type targets. I think App Extensions should be easy to implement as an addition to the xtool.yml spec, but just require engineering effort.
  • LLDB debugging: this used to be pretty easy before iOS 17, and xtool has all of the pieces in place to support lldb with those old versions, but Apple has recently made a number of changes to the way you invoke LLDB's debugserver on iOS. There are a few modern tools that support the new approach (notably pymobiledevice3), and it's already possible to use these tools to connect to lldb, but I definitely want to integrate this into xtool down the road. This will require a good amount of work since the new RemoteXPC protocol is entirely different from the legacy mechanism, but it'll probably be necessary in the future for other functionality as well.
  • App Store deployment: You can build and run on your own device with xtool, but it doesn't let you deploy builds to App Store Connect yet. Luckily 1) iTMSTransporter is cross-platform and 2) we have all the other infra in place to interact with the ASC API, so this should be achievable too, but remains to be done.

xtool is a culmination of 8 years of work around iOS app deployment (the commit history has some nuggets!) but I'm the sole developer on this project and replicating Xcode is a massive undertaking. Now that I'm ready to share the project more widely, I'd be very happy to accept external contributions to flesh out the feature set. And if you end up using xtool, please let me know!

64 Likes

My understanding has always been that building iOS apps on other OSes is more of a legal/licensing challenge than a technical one. For example, quoting from the Apple Developer Program License Agreement:

2.1 Permitted Uses and Restrictions; Program Services

Subject to the terms and conditions of this Agreement, Apple hereby grants You during the Term, a limited, non-exclusive, personal, revocable, non-sublicensable and non-transferable license to:

  1. Install a reasonable number of copies of the Apple Software provided to You under the Program on Apple-branded products owned or controlled by You, to be used internally by You or Your Authorized Developers for the sole purpose of developing or testing Covered Products designed to operate on the applicable Apple-branded products, except as otherwise expressly permitted in this Agreement;

2.6 No Other Permitted Uses

Except as otherwise set forth in this Agreement, You agree not to rent, lease, lend, upload to or host on any website or server, sell, redistribute, or sublicense the Apple Software, Apple Certificates, or any Services, in whole or in part, or to enable others to do so. You may not use the Apple Software, Apple Certificates, or any Services provided hereunder for any purpose not expressly permitted by this Agreement, including any applicable Attachments and Schedules. You agree not to install, use or run the Apple SDKs on any non-Apple-branded computer, and not to install, use or run iOS, iPadOS, macOS, tvOS, visionOS, watchOS, and Provisioning Profiles on or in connection with devices other than Apple-branded products, or to enable others to do so. You may not and You agree not to, or to enable others to, copy (except as expressly permitted under this Agreement), decompile, reverse engineer, disassemble, attempt to derive the source code of, modify, decrypt, or create derivative works of the Apple Software, Apple Certificates or any Services provided by the Apple Software or otherwise provided hereunder, or any part thereof (except as and only to the extent any foregoing restriction is prohibited by applicable law or to the extent as may be permitted by licensing terms governing use of open-sourced components or sample code included with the Apple Software).

Now, I am not a lawyer, so I can't give a very informed opinion about whether this falls within the permitted use or whether these terms are even enforceable. I am aware that the copyright situation with regard to reverse engineering for compatibility has changed recently (see Oracle vs Google), but I'm not sure to what extent that affects the terms in the license agreement.

At the very least, I can say that it seems risky, and certainly if you do deploy directly to the AppStore (as it is suggested is coming) I would not be surprised if you were found to be in violation of the agreement. Again, not a lawyer, but my understanding of the Epic Games vs Apple case is that Apple has pretty wide latitude to terminate developer accounts.

Can you comment on this? I assume you know better than I do. What's your understanding of the licensing issue?

1 Like

I've personally been using xtool on Mac hardware, where it's still very useful in that it's a lot more lightweight and declarative than Xcode, and for that matter when dual-booting a different OS (think Asahi Linux / Bootcamp Windows.)

xtool itself doesn't vend any traces of the Apple SDKs / toolchains, which is why the setup process asks users to download and provide a copy of Xcode.xip themselves, and builds the iOS SDK on the spot. I'm not a lawyer but one should definitely read the license agreement and determine whether their use case in compliance — you do have to agree to it before you download Xcode.xip.

And regarding distribution: since xtool works on both Linux and macOS, if someone is wary of publishing from Linux CI (say their CI provider doesn’t guarantee that their Linux jobs will run on macOS hardware) they're definitely free to perform the final App Store build on macOS CI instead.

2 Likes

This would be very interesting for cross platform frameworks, Flutter and Dioxus come to mind.
And for people that have been looking to develop for iOS from Linux. I hope Apple doesn't try to end this repo but instead embraces the value of it.

Does this allow for debugging with a device as well or is it just for installing apps atm?

I briefly mentioned this in the gotchas section, but xtool can’t start a debugging session itself quite yet, though it’s on the roadmap. In the meantime you can use a tool like pymobiledevice3 to start a debug session on your device, and then attach to it with lldb’s remote functionality. I realize that it might not be super clear how to do this, so I might write some documentation on the pymobiledevice3 setup even before we're able to integrate this into xtool.

1 Like

This sounds great, but I would like to be able to build a normal xcode like project. Is there a reason why it only supports writing swift packages? (Or maybe it doesnt even matter? I have never built a sp so idk if theres any limitations.”)

Thanks for your amazing effort.

2 Likes

It is fascinating and extremely motivating to see what a few motivated individuals can accomplish, to be creating tools and opportunities that many others would've disregarded as 'practically impossible' over the last decade. Kudos to you @kabiroberai and everyone else who made this possible.

4 Likes

The tooling to parse Swift Packages is all open-source, and with its support for Swift SDKs we’re able to build such an SDK and then invoke swift build --swift-sdk arm64-apple-ios to build the iOS app executable.

Now that swift-build exists, we're closer to being able to build the xcodeproj format on Linux/WSL as well, but afaik there's still a huge missing piece in that one would need to convert the xcodeproj into the PIF format expected by swift-build. Plus, it's not fun to edit an xcodeproj without the Xcode.app GUI; anyone who's tried to solve a merge conflict in an Xcode project knows this too well.

That said, I do think it's worth investing in a tool that scans an Xcode project and converts it into an xtool project. I've been chatting with the Tuist folks about the work they've done in this area, I think there's some fun possibilities here.

1 Like

It’d be really cool to see how this could be used for an environment with Jules / Codex / etc.

Is it possible to integrate a Swift library such as Swift Snapshot Testing in a swift package written with XTool? https://swiftpackageindex.com/pointfreeco/swift-snapshot-testing

I want to allow my QA team to be able to write tests for my xcode project without needing to buy a mac.
My thought is that maybe xtool can allow us to write code into a SP for the tests, then somehow execute the tests by iinstalling the SP in a simulator.