xcode_workspace

Xcode project seed.

Description#

Reads an existing Xcode project or workspace and lowers every native target it finds into the Apple target kinds, so Once compiles and tests the project directly. The .xcodeproj remains the source of truth: targets, build settings, and file membership are read from it rather than restated in once.toml.

The resolver converts project.pbxproj with plutil, flattens layered build settings from the project, the target, and any .xcconfig includes, resolves file references from both classic build phases and Xcode 16 file-system synchronized groups, reads schemes to identify testable targets, replays shell script phases as prebuild actions, and lowers Swift package dependencies into Apple libraries.

Pointing project at an .xcworkspace resolves every .xcodeproj the workspace references and merges their targets into one graph, so dependencies that cross a project boundary are wired. A referenced project that is not on disk is skipped instead of failing the graph.

Xcode projects, including projects in nested packages, are recognized automatically, so their seeds are supplied without any once.toml.

When an Xcode project uses a workspace-level Package.resolved, Once uses its matching pinned revisions while lowering remote Swift packages. Checksum-pinned binary package archives download as normal cacheable dependencies instead of being fetched while the graph loads.

Projects with multiple destination platforms receive separate package and binary-framework targets per platform. Generated target names include the platform when the workspace has more than one destination. Native consumers depend on the matching variant, while package manifest parsing is shared.

Swift package traits requested by dependencies are combined across the package graph and applied to compilation, compiler settings, and optional target dependencies. Packages referenced directly by the Xcode project enable their default traits. Package library targets are force-loaded into whatever links them so conformances declared in an extension survive.

See Xcode Projects for a walkthrough.

Attributes#

explicit_modules is a boolean, defaulting to false, that enables compiler-scanned, cacheable Swift and Clang module actions. dependency_check accepts "off" (the default) or "error"; checking requires explicit modules. See explicit modules for native propagation, dependency errors, and current limitations.

AttributeTypeRequiredDefaultDescription
projectstringnosingle *.xcodeproj in the packagePackage-relative path to the .xcodeproj or .xcworkspace
configurationstringnoDebugXcode build configuration whose settings drive target lowering
sdk_variantstringnosimulatorsimulator or device selection applied to lowered targets on non-macOS platforms
xcode_developer_dirstringnoactive XcodeDEVELOPER_DIR override folded into lowered targets' cache keys
binary_artifact_authorization_envstringnoEnvironment-variable name that supplies a web Authorization header while downloading private binary package archives. Its value is not recorded.
resolver_inputslist<string>no[]Package-relative text globs supplied to resolution. Defaults to srcs when empty

None of these attributes are configurable by platform select.

Dependency Edges#

EdgeAcceptsDescription
depsapple_linkable, apple_application, apple_test_bundle, native_linkableNative Xcode targets lowered into Apple application, library, framework, and test targets

Lowering#

Xcode product typeEmitted target kind
Application, iMessage app, App Clipapple_application
App extension, embedded watch appapple_application with application_extension
Frameworkapple_framework
Static framework, static or dynamic libraryapple_library
Unit test and interface test bundleapple_test_bundle
Bundleapple_resource_bundle
Referenced .xcframeworkapple_xcframework_import
Remote binary Swift package targetarchive_download, then apple_xcframework_import

Providers#

The target emits xcode_workspace. The lowered targets emit the providers of their own kinds, so downstream targets depend on them normally.

Capabilities#

CapabilityOutput groups
buildnone

Building the seed builds application roots, or every non-test product in a library-only project. Resolver metadata selects first-party test bundles for targetless once test. Lowered targets can also be built, run, and tested individually by name.

Tools#

ToolExecutables
xcodeplutil, xcrun

Limitations#

Resolver inputs are read as text, so srcs must not glob binary files.

Once compiles the project rather than delegating to xcodebuild, so anything supplied by an external dependency manager or bootstrap step, including CocoaPods build integration and vendored binaries a repository fetches, has to be in place before the build.

App extensions and embedded watch apps compile as application bundles. The .appex wrapper and its extension-point metadata are not modeled yet.

Targets without compilable sources are skipped, and dependency edges to targets that were not emitted are dropped so the remaining graph stays loadable.

Example#

toml
[[target]]
name = "App"
kind = "xcode_workspace"
srcs = ["App.xcodeproj/project.pbxproj"]
[target.attrs]
project = "App.xcodeproj"