apple_library

Swift, Objective-C, C, and C++ static library.

Description#

Routes each source file through the driver that matches its extension and emits a .a archive together with the Swift module triple, ObjC interop header, and (optionally) a clang modulemap and binary header map. Multi-arch targets fan out per-arch compiles and merge them with lipo.

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. The resolver-owned _declared_deps metadata preserves declarations before import inference and should not be authored manually.

AttributeTypeRequiredDefaultDescription
platformstringyesApple platform such as ios, macos, tvos, watchos, or visionos
minimum_osstringnoMinimum supported OS version (deployment target)
target_sdk_versionstringnominimum_osBuild-time SDK version baked into the triple
sdk_variantstringno"simulator"simulator or device. Ignored on macOS (always macosx)
archslist<string>no[]Target architectures (arm64, x86_64, arm64e, arm64_32). Empty defaults to the host arch; multi-arch fans out per-arch compiles and combines them with lipo
mac_catalystboolnofalseBuild the iOSMac (Mac Catalyst) variant. Requires platform = macos; rewrites the triple to <arch>-apple-ios<minOS>-macabi
module_namestringnotarget nameCompiled module name (not configurable)
xcode_developer_dirstringnoPin a specific Xcode by overriding DEVELOPER_DIR. Folded into the action cache key
headerslist<string>no[]Public or private C-family headers compiled with this target
exported_headerslist<string>no[]Headers made available to dependent targets
exported_header_dirslist<string>no[]Header search directories made available to dependent targets
private_header_dirslist<string>no[]Header search directories used only while compiling this target
private_headerslist<string>no[]Private header files required while compiling this target
resourceslist<string>no[]Files and directory roots placed in this library's propagated resource bundle
structured_resourceslist<string>no[]Resource directory roots whose own basename is preserved inside the propagated bundle
resource_bundle_namestringnoName of the propagated resource bundle. The .bundle suffix is added when omitted
resource_bundle_idstringnoBundle identifier written to the propagated resource bundle metadata
bridging_headerstringnoObjC bridging header that lets Swift sources see ObjC symbols
prefix_headerstringnoPrefix header included before every C-family source
swift_flagslist<string>no[]Extra Swift compiler flags
clang_flagslist<string>no[]Extra Clang compiler flags
per_source_clang_flagsmap<string, string>no{}Clang flag lists encoded as JavaScript Object Notation (JSON) and keyed by source path. Xcode adapters use this to retain per-file compiler settings
defineslist<string>no[]Compatibility conditions passed to both Swift and Clang
swift_defineslist<string>no[]Swift conditional compilation conditions
clang_defineslist<string>no[]C-family preprocessor definitions
enable_testingboolnofalseCompile Swift with testability enabled for dependent tests
swift_testingboolnofalseCompile sources that import the Swift Testing framework
xctest_supportboolnofalseCompile sources that import the XCTest framework
library_evolutionboolnofalseEmit stable Swift module interfaces for binary compatibility
enable_modulesboolnofalseEmit a module.modulemap and .hmap from exported_headers and pass -fmodules to Clang
emit_dsymboolnofalseEmit DWARF debug info so downstream target kinds can extract a .dSYM bundle
sdk_frameworkslist<string>no[]Apple SDK frameworks linked by name, propagated transitively
weak_sdk_frameworkslist<string>no[]Apple SDK frameworks linked weakly, propagated transitively
sdk_dylibslist<string>no[]Apple SDK dynamic libraries linked by name, propagated transitively
linkoptslist<string>no[]Extra linker flags, propagated transitively
alwayslinkboolnofalseHint to downstream linker target kinds to force-load this archive (-Wl,-force_load)
exported_depslist<string>no[]Target ids from deps whose module interface flows through to consumers' compile path
prebuild_actionslist<string>no[]Adapter-owned serialized build preparation actions that run before compilation. Records may opt into caching when they declare complete inputs and outputs; always-run records remain uncached
modulemapstringnoAuthored Clang module map retained instead of generating one
modulemap_headerslist<string>no[]Headers named by the authored module map, including private explicit submodules
auxiliary_modulemapslist<string>no[]Additional Clang module maps referenced by this module's public Swift interface

The prepackage_actions attribute accepts an ordered list<string> of serialized script records, defaulting to []. These run after linking and before resource processing, so generated resources feed packaging.

The postbuild_actions attribute accepts an ordered list<string> of serialized script records, defaulting to []. These actions run after product assembly and before final signing. Complete declarations may be cached; untracked scripts rerun and publish changes to known product files. See native script phases for mapped build settings and file-list variables.

Dependency Edges#

EdgeAcceptsDescription
depsapple_linkable, apple_resource, apple_swift_plugin, native_linkableLibraries, frameworks, resources, native linkables, or Swift compiler plugins consumed by this library

A dependency that exposes a compiler-plugin executable (see swift_macro) is auto-detected and loaded with its declaring module. The resulting transitive_plugin_executables field keeps the host tool available to downstream targets that use a macro declared by the library. Library-style compiler plugins remain supported through transitive_plugin_dylibs.

When resource_bundle_name is set, the target creates a resource bundle and propagates it through static library dependencies to the final application. Directory roots are merged at the bundle root unless listed in structured_resources. Localized directories retain their structure, interface files are compiled, and managed object models are compiled into runtime model bundles. The final application embeds and signs each propagated resource bundle before signing its outer bundle.

Providers#

The target emits apple_linkable and apple_module.

Capabilities#

CapabilityOutput groups
builddefault, binary, swiftmodule, generated_sources

Compile pipeline#

Each source extension routes to a different driver:

  • Swift sources use one compiler action to emit the module, compatibility header, and object files. A separate archive action packages the objects. A bridging_header plumbs in via -import-objc-header so Swift can see Objective-C symbols.
  • ObjC, C, and C++ sources each become an independent xcrun --sdk <sdk> clang -c action that writes one .o per source. The clang invocation pulls the SDK sysroot from xcrun --show-sdk-path, targets the active triple, and enables ARC for ObjC.
  • Mixed-language libraries combine the Swift archive and per-source Clang objects with the platform archive tool. Swift-only libraries use their Swift archive directly, while Clang-only libraries archive their objects once.
  • Multi-arch targets repeat the swift + clang + libtool chain per architecture, then run xcrun lipo -create on the per-arch archives to produce the final universal archive. Single-arch targets skip lipo entirely.

Dep swiftmodule directories are forwarded as -I search paths so import statements resolve. With enable_modules = true the impl writes a module.modulemap from exported_headers, threads it into consumers through the provider, and also writes a binary header map (<module_name>.hmap) mapping each exported header's basename and <module_name>/<basename> form to its workspace-relative path. The hmap is passed to clang and swiftc via -I, covering the #include "Foo.h" and #include <Module/Foo.h> lookup styles a modulemap alone does not.

The action cache key composes the resolved toolchain identity (each of swiftc, clang, libtool, and lipo carries its own xcrun-resolved path, version banner, and any DEVELOPER_DIR override), source content, and declared generated inputs. Imported Swift modules are fingerprinted by their artifact content. A private implementation edit that preserves a module can therefore reuse downstream compilation, while the changed archive still participates in later link actions.

Provider record#

apple_library returns a record consumers read through ctx["deps"]. Fields:

FieldTypeMeaning
label_idstringCanonical target id
swiftmodule_dirstringDirectory holding the .swiftmodule, added to -I by consumers
archivestringFinal static archive path
objc_headerstringGenerated -Swift.h ObjC interop header
modulemapstringPath to the emitted module.modulemap, or empty
hmapstringPath to the emitted .hmap, or empty
exported_headerslist<string>Headers this target re-exposes to consumers
exported_header_dirslist<string>Parent directories of the exported headers, added to -I by consumers
alwayslinkboolHint propagated for force-load
transitive_swiftmodule_dirslist<string>Module search paths (gated by exported_deps)
transitive_swiftmodule_inputslist<string>Exact architecture-matching module artifacts consumed by downstream compiler actions, propagated through exported_deps
transitive_exported_headerslist<string>Header paths from this and exported deps
transitive_generated_headerslist<string>Generated compatibility headers required by downstream compile actions
transitive_exported_header_dirslist<string>Header search dirs from this and exported deps
transitive_modulemapslist<string>Modulemap paths to feed downstream consumers
transitive_hmapslist<string>Header-map paths to feed downstream consumers
transitive_framework_search_dirslist<string>Framework search paths required by downstream compile actions
transitive_framework_fileslist<string>Complete generated framework file sets required as action inputs
transitive_vfs_overlayslist<string>Virtual file system overlay manifests that preserve source-header identity through generated framework paths
transitive_archiveslist<string>Archive paths for the link line
transitive_alwayslink_archiveslist<string>Subset of archives that should be force-loaded
transitive_sdk_frameworkslist<string>SDK frameworks to link
transitive_weak_sdk_frameworkslist<string>Weakly linked SDK frameworks
transitive_sdk_dylibslist<string>SDK dynamic libraries to link
transitive_linkoptslist<string>Extra linker flags
transitive_plugin_dylibslist<string>Host-loaded Swift compiler plugins required by downstream source
transitive_plugin_executableslist<string>Host executable and declaring-module descriptors required by downstream source
transitive_defineslist<string>Preprocessor / conditional compilation flags
transitive_link_framework_bundleslist<record>Dynamic framework bundles carried to the next link action
transitive_framework_bundleslist<record>Dynamic framework bundles carried to the final application or test bundle
transitive_frameworkslist<string>Compatibility view of runtime framework paths
transitive_resource_bundleslist<record>Resource bundle paths and complete file sets carried to the final application

Downstream Apple targets use this record to collect the complete compile and link context without inspecting the dependency's target kind. Dynamic framework dependencies continue through static libraries automatically, so a final application or test does not repeat dependencies that it never imports.

Configurable attributes#

Every attribute except module_name, archs, platform, sdk_variant, and mac_catalyst accepts a select value. Configuration tokens for matching come from the target's resolved literal values:

Token groupSourceExample values
Platformplatformios, macos, tvos, watchos, visionos
SDK variantsdk_variantsimulator, device
Architectureeach entry of archsarm64, x86_64, arm64e, arm64_32
Mac Catalystliteral token when mac_catalyst = truemac_catalyst

Branch keys can combine tokens with : (e.g. ios:simulator); when several branches match the longest matching key wins. A default branch is selected when no other branch matches.

toml
[target.attrs]
sdk_frameworks = { select = { ios = ["UIKit"], macos = ["AppKit"] } }

See Choose Values by Configuration for the guided overview.

Outputs#

OutputLocation
Static archive.once/out/<target>/<module_name>.a
Swift module.once/out/<target>/<module_name>.swiftmodule (single arch) or .swiftmodule/<arch>.swiftmodule (universal)
Swift doc.once/out/<target>/<module_name>.swiftdoc or .swiftmodule/<arch>.swiftdoc
ObjC interop header.once/out/<target>/<module_name>-Swift.h
Modulemap.once/out/<target>/module.modulemap (when enable_modules = true)
Header map.once/out/<target>/<module_name>.hmap (when enable_modules = true)
Resource bundle.once/out/<target>/<resource_bundle_name>.bundle (when resource_bundle_name is set)
Per-source clang objects.once/out/<target>/<sanitised_source>[-<arch>].o

Example#

toml
[[target]]
name = "AppCore"
kind = "apple_library"
srcs = ["Sources/**/*.swift", "Sources/**/*.m"]
deps = ["./StringifyMacro"]
[target.attrs]
platform = "ios"
minimum_os = "17.0"
archs = ["arm64", "x86_64"]
sdk_frameworks = ["UIKit"]
enable_modules = true
exported_headers = ["include/AppCore.h"]