Relationship between swift-build, xcodebuild, and Xcode

How is swift-build related to xcodebuild and Xcode? Can I simply use swbuild to build an Xcode project, or would I need to write additional scaffolding around the swift-build library in order to do that?

swift-build (the Swift Build project/repository) is the build system engine that builds both Xcode projects and Swift packages. However, it doesn't by itself interpret the user-facing on disk configuration format like .xcodeproj or Package.swift.

Instead, Swift Build uses an internal project representation called "PIF". Higher level clients like swift-build (the user facing command line tool that's part of the SwiftPM repository) or Xcode/xcodebuild first transform the user-facing on-disk configuration formats like .xcodeproj and Package.swift into PIF before handing off to Swift Build to complete the rest of the build process.

Also, the swbuild command line tool is a debugging utility for developers of the build system itself, not meant to be used by end users.

So to answer your question: yes, you could use swbuild to build an Xcode project, but you'd first need to convert it to PIF using xcodebuild. There are some examples in the Swift Build codebase of how to invoke xcodebuild to do so. But I'd like to stress that this is not an intended use case outside of debugging, and end users should be using swift-build (from SwiftPM) or xcodebuild to perform command line builds of their projects.

5 Likes

By this, do you mean that swift-build (of SwiftPM) would build SwiftPM projects and that xcodebuild would build Xcode projects? Or can swift-build also build Xcode projects?

Do the higher-level clients store the PIF representation on disk, or is it stored only in memory?

First, I want to clarify the term swift-build. There's two things called that:

  • swift-build: (usually invoked as swift build) the user facing command line tool used to build Swift Packages. That's part of the swiftlang/swift-package-manager repository.
  • swift-build: the swiftlang/swift-build repository containing the Swift Build build system engine (but not the command line tool).

Let's use swift-build to refer to the SwiftPM command line tool, and "Swift Build" to refer to the build system engine.

swift-build builds only SwiftPM projects (Package.swift), while xcodebuild can build both SwiftPM projects and Xcode projects.

The Swift Build build system engine underlies both xcodebuild and (once Create an alternate SwiftPM build system called Swift Build by cmcgee1024 · Pull Request #8271 · swiftlang/swift-package-manager · GitHub is merged) swift-build when using the --build-system=swiftbuild flag.

Hopefully that helps clarify!

Swift Build itself performs the actual storage, and there are a combination of in-memory and on-disk caches involved. Higher level clients transmit the PIF to Swift Build via API calls based on their own logic of interpreting their own higher level project formats.

Much of that caching logic lives in swift-build/Sources/SWBBuildService/Session.swift, so that'd be a good starting point if you're interested in digging deeper.

There's also some architecture documentation in the repo, which covers PIF and more: swift-build/SwiftBuild.docc/Architecture/build-system-architecture.md at main · swiftlang/swift-build · GitHub

If you feel there are any gaps in the documentation there, please feel free to file GitHub issues or raise PRs for improvements!

6 Likes

Just so I understand it correctly: As long as something converts the manifest to a "PIF" and passes it via the API calls, Swift Build can build it will all options PIF representation supports?
So in theory the manifest could be an Excel file?

1 Like

Yes.