Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2022 Hugging Face SAS.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

LICENSE.md

Making the community's best AI chat models available to everyone.


HuggingChat macOS

![Static Badge](https://img.shields.io/badge/License-Apache-orange)
[![swift-version](https://img.shields.io/badge/Swift-6.0-brightgreen.svg)](https://github.com/apple/swift)
[![platform](https://img.shields.io/badge/Platform-macOS_14.0-blue.svg)](https://github.com/apple/swift)

### About
HuggingChat macOS is a native chat interface designed specifically for macOS users, leveraging the power of open-source language models. It brings the capabilities of advanced AI conversation right to your desktop, offering a seamless and intuitive experience.

### Demo
https://github.com/user-attachments/assets/dacc87b2-2242-4ef5-84d5-9f9aae50c453

### Installation

1. Go to the [Releases](https://github.com/huggingface/chat-macOS/releases) section of this repository.
2. Download the latest `HuggingChat-macOS.zip` file.
3. Unzip the downloaded file.
4. Drag the `HuggingChat.app` to your Applications folder.

#### Homebrew
HuggingChat is also available via Homebrew. Simply run:

```bash
brew install --cask huggingchat
```

That's it! You can now launch HuggingChat from your Applications folder or using the dedicated keyboard shortcut: `⌘ + Shift + Return`.

#### VSCode Integration
In order to use HuggingChat in VSCode, you'll need to install the [HuggingChat Extension](https://github.com/cyrilzakka/huggingchat-helper). After downloading it, add it to VSCode by navigating to the Extensions tab and selecting "Install from VSIX". Choose the downloaded file and restart VSCode. HuggingChat can now use context from your code editor to provide more accurate responses.

### Development Setup
#### Prerequisites
- Xcode 16.0 or later
- macOS 14.0 or later

#### Building the Project
1. Clone the repository:
   ```bash
   git clone https://github.com/huggingface/chat-macOS.git
   cd HuggingChat-macOS
   ```
2. Open `HuggingChat-macOS.xcodeproj` in Xcode
3. Select your development team in the project settings if you plan to run on a physical device
4. Build and run the project (⌘ + R)

### Making Contributions
#### 1. Choose or Create an Issue
- Check existing [issues](https://github.com/huggingface/chat-macOS/issues) for something you'd like to work on
- Create a new issue if you have a bug fix or feature proposal
- Comment on the issue to let maintainers know you're working on it

#### 2. Fork and Branch
1. Fork the repository to your GitHub account
2. Create a new branch for your work:
   ```bash
   git checkout -b feature/your-feature-name
   # or
   git checkout -b fix/your-bug-fix
   ```

#### 3. Code Style Guidelines
- Follow Apple's [Swift API Design Guidelines](https://swift.org/documentation/api-design-guidelines/)
- Use SwiftLint rules defined in the project
- Maintain consistent spacing and formatting
- Write meaningful commit messages
- Add comments for complex logic

### Feedback

We value your input! If you have any suggestions, encounter issues, or want to share your experience, please feel free to reach out:

2. **GitHub Issues**: For bug reports or feature requests, please create an issue in this repository.
    - Provide a clear title and description of your feedback
   - Include steps to reproduce the issue (for bugs) or detailed explanation (for feature requests)
   - Include the app version number and macOS version
   - Submit the issue

Your feedback helps improve HuggingChat macOS for everyone. Thank you for your support!

README.md


Swift Build
=======

Swift Build is a high-level build system based on [llbuild](https://github.com/swiftlang/swift-llbuild) with great support for building Swift. It is used by Xcode to build Xcode projects and Swift packages, and by Swift Playground. It can also be used as the Swift Package Manager build system in preview form when passing `--build-system swiftbuild`.

Usage
-----

### With SwiftPM

When building SwiftPM from sources which include Swift Build integration, passing `--build-system swiftbuild` will enable the new build-system. This functionality is not currently available in nightly toolchains.

### With Xcode

Changes to swift-build can also be tested in Xcode using the `launch-xcode` command plugin provided by the package. Run `swift package --disable-sandbox launch-xcode` from your checkout of swift-build to launch a copy of the currently `xcode-select`ed Xcode.app configured to use your modified copy of the build system service. This workflow is currently supported when using Xcode 16.2.

### With xcodebuild

Changes to swift-build can also be tested in xcodebuild using the `run-xcodebuild` command plugin provided by the package. Run `swift package --disable-sandbox run-xcodebuild` from your checkout of swift-build to run xcodebuild from the currently `xcode-select`ed Xcode.app configured to use your modified copy of the build system service. Arguments followed by `--` will be forwarded to xcodebuild unmodified. This workflow is currently supported when using Xcode 16.2.

Documentation
-------------

[SwiftBuild.docc](SwiftBuild.docc) contains additional technical documentation.

To view the documentation in browser, run the following command at the root of the project:
```bash
docc preview SwiftBuild.docc
```

On macOS, use:
```bash
xcrun docc preview SwiftBuild.docc
```

Testing
-------------
Before submitting the pull request, please make sure you have tested your changes. You can run the full test suite by running `swift test` from the root of the repository. The test suite is organized into a number of different test targets, with each corresponding to a specific component. For example, `SWBTaskConstructionTests` contains tests for the `SWBTaskConstruction` module which plan builds and then inspect the resulting build graph. Many tests in Swift Build operate on test project model objects which emulate those constructed by a higher level client and validate behavior at different layers. You can learn more about how these tests are written and organized in [Project Tests](SwiftBuild.docc/Development/test-development-project-tests.md).

Contributing to Swift Build
------------

Contributions to Swift Build are welcomed and encouraged! Please see the
[Contributing to Swift guide](https://swift.org/contributing/).

Before submitting the pull request, please make sure that they follow the Swift project [guidelines for contributing
 code](https://swift.org/contributing/#contributing-code). Bug reports should be
 filed in [the issue tracker](https://github.com/swiftlang/swift-build/issues) of
 `swift-build` repository on GitHub.

To be a truly great community, [Swift.org](https://swift.org/) needs to welcome
developers from all walks of life, with different backgrounds, and with a wide
range of experience. A diverse and friendly community will have more great
ideas, more unique perspectives, and produce more great code. We will work
diligently to make the Swift community welcoming to everyone.

To give clarity of what is expected of our members, Swift has adopted the
code of conduct defined by the Contributor Covenant. This document is used
across many open source communities, and we think it articulates our values
well. For more, see the [Code of Conduct](https://swift.org/code-of-conduct/).

License
-------
See https://swift.org/LICENSE.txt for license information.

README.md

A high-level build system based on llbuild, used by Xcode, Swift Playground, and the Swift Package Manager


_[Put a one line description of your change into the PR title, please be specific]_

_[Explain the context, and why you're making that change. What is the problem you're trying to solve.]_

_[Tests can be run by commenting `@swift-ci` test on the pull request, for more information see [this](https://github.com/swiftlang/swift-build/blob/main/README.md)]_

.github/PULL_REQUEST_TEMPLATE.md


# Swift Build

@Metadata {
   @TechnologyRoot
}

Swift Build is a high-level build system based on (llbuild)[https://github.com/swiftlang/swift-llbuild] with great support for building Swift. It is used by Xcode to build Xcode projects and Swift packages. It can also be used as the Swift Package Manager build system in preview form when passing `--build-system swiftbuild`.

## Overview

Swift Build is structured in layers of framework targets, which is described in <doc:build-system-architecture>.

## Topics

### Architecture

- <doc:build-system-architecture>
- <doc:dynamic-tasks>
- <doc:indexing-support>
- <doc:swift-driver>

### Development

This section contains notes on developing Swift Build.

- <doc:build-debugging>
- <doc:test-development>
- <doc:test-development-project-tests>

### Core

This section describes selected subsystems of the core infrastructure of Swift Build.

- <doc:target-specialization>
- <doc:macro-evaluation>
- <doc:project-interchange-format>
- <doc:xcspecs>

### Task Construction

- <doc:discovered-dependencies>
- <doc:mutable-outputs>
- <doc:mergeable-libraries>

SwiftBuild.docc/swift-build.md


This target is used to pull in some additional C headers underneath SWBLibc since SwiftPM can't build C and Swift sources in the same target.


# Build System Architecture

This document surveys the architecture of the Swift Build build system, from the lowest layers to the highest.

## General Structure

Swift Build runs as a service process separate from the SwiftPM or Xcode process it's associated with.  Clients start a SWBBuildService process on demand, and there is a single SWBBuildService process per client process.  Clients and SWBBuildService communicate via serialized messages across a pipe.

Swift Build is structured in layers of framework targets.  For the most part this is a vertical stack of frameworks, although in some places there are multiple peer frameworks.  Swift Build makes extensive use of protocols to achieve this layering, and to control access to data.

Swift Build is built on top of the [llbuild](https://github.com/apple/swift-llbuild) project, an open-source build system.  llbuild is included as a library in SWBBuildService's address space, as opposed to running as a separate process. SWBBuildService and llbuild will communicate bidirectionally, with SWBBuildService instructing llbuild to perform work, and llbuild calling back to SWBBuildService for additional information it needs.

- - -

## Low-Level Build System

**Framework:** SWBLLBuild

The low-level build system is little more than a shim layer on top of llbuild and its own `BuildSystem` subcomponent, providing Swift bindings on top of the C API in a form suitable for use by Swift Build.

This layer ideally would eventually be replaced by official llbuild Swift bindings supplied directly from the project.

## Utility Frameworks

**Frameworks:** SWBUtil, SWBCSupport

SWBUtil contains utility code used across all other layers of Swift Build frameworks.  These include extensions to standard libraries, implementations of standard-library-like classes (e.g., *OrderedSet*), covers for Foundation code (e.g. *PropertyList*), covers for POSIX code (e.g., *FSProxy*, *Process*) and other utility code.  Code in SWBUtil is arguably not specific to Swift Build and might be of interest to any project.

SWBCSupport contains a small amount of C or Objective-C code bridged into Swift.

**Testing:** SWBUtil tests are often true "unit" tests, exercising small and well-defined behaviors.  Tests of SWBUtil classes should be reasonably complete along with the implementation of the classes.

There are presently no tests for SWBCSupport code.  Ideally all code will will eventually be ported to Swift inside the proper framework with proper tests written.  If we determine that some of this code should remain non-Swift code, we should still consider whether it should be moved elsewhere, and we should still write tests to exercise it.

## Core Framework

**Framework:** SWBCore

SWBCore contains classes which are used at multiple higher layers of Swift Build, but unlike SWBUtil are specific to Swift Build.  It includes several key subsystems:

### Macros

This is the engine used for build setting evaluation.  Build settings are declared as having a type (usually string or string-list), string expressions are parsed so they can be evaluated when requested, and then those expressions are evaluated using a `MacroEvaluationScope` for a particular context.

### Settings

The `Settings` class contains build settings and other information bound for a particular target (or, occasionally, other configurations) to be able to build that target.  A `Settings` object has a complicated creation procedure (encapsulated in the class) in order to bind all of the relevant information.  This is a central class for other parts of Swift Build to get information about what is being built.

### Project Model

This is the Swift Build representation of a package graph in SwiftPM or workspace in Xcode, including all model objects and all data that they contain.  This representation very closely matches the higher-level representations, although some transforms or derived information are present in some cases where it is considered beneficial.  The term "PIF" (Project Interchange Format) is used both to describe the serialized representation used to transfer the model from clients to Swift Build, and as a shorthand for the Swift Build-side representation of the model.

### Specifications

Specifications ("specs") are a data-driven representation of certain objects used by the build system.  Specs are most often used for build tools (compilers, linkers, etc.), but are used for a few other concepts such as file types.

### Platforms and SDKs

A platform corresponds to a particular device target, such as macOS, iOS, iOS Simulator, etc.  A platform will have one or more SDKs, which contain the headers and libraries to build against.  Platforms and SDKs often contain information to direct Swift Build how to build for that target (from the platform's `Info.plist` and the SDK's `SDKSettings.plist`), and Swift Build loads that information to make use of it.

### Task Planning Support Classes

One of Swift Build's central concerns is analyzing the inputs (workspace, build parameters) and generating a dependency graph (a.k.a. build description) from those inputs.  This is called "task planning" or "task construction".  Several classes used to represent files to build (nodes), commands to run (tasks), and information from clients (the build request, provisioning info, etc.) are defined at the core level as they are used at multiple higher levels.

**Testing:** SWBCore tests are often true "unit" tests, exercising well-defined behaviors.  Many classes in SWBCore will have reasonably complete tests written alongside them, although there are exceptions, such as:

* Some simple structs and extensions such as in `SigningSupport` may not be tested in isolation but instead tested by implication at a higher layer.

## Task Construction

**Framework:** SWBTaskConstruction

This framework sits on top of SWBCore, and defines all of the high-level "business logic" for constructing concrete tasks to execute for a build from a project model, including the full command lines to use.

Task construction (a.k.a. task planning) involves taking a set of inputs (typically a `WorkspaceContext` and a `BuildRequest`) and generating a collection of tasks and nodes representing the dependency graph of work to be done.  This output is encapsulated in a `BuildPlan` which is used by the higher-level build system framework to create a build description and generate the llbuild manifest file.

The `ProductPlanner` will create a `ProductPlan` for each target to build, and a `TaskProducer` for each chunk of work needed to plan that target. A task producer roughly corresponds to a build phase in the product model, although there are some additional task producers which do not have concrete build phases, and the role of build phases is being deemphasized over time.  The product planner launches all the task producers in parallel to create their tasks, and then collects them via a serial aggregation queue to create the build plan.

Much of the interesting work in task construction is in the individual task producer subclasses, and those in turn often invoke individual tool specifications in SWBCore to create individual tasks to process input files to output files.

Most of the dependency graph must be created up-front, but there are some exceptions (e.g. Clang and Swift compilation) where a static node in the dependency graph may request dynamic work as an input.  Some tool specifications, such as that for the Core Data compiler, also run preflight operations during task construction to learn what output files will be generated for an input file so that inputs and outputs of a task can be declared during task construction.

*To be documented:* `PlannedTask`, `ExecutableTask`, `TaskPayload`

**Testing:** Task construction testing has supporting infrastructure in the form of the `TaskConstructionTester` class which is used to perform task construction from a set of inputs, and then vend the results to a checker block.  The checker block typically checks for the presence of expected targets and tasks (and sometimes the absence of ones which should not exist), and examines the rule info, command line, environment, and inputs and outputs of those tasks for the expected values.

There are also supporting classes in `TestWorkspaces.swift` which are used to describe a test project or workspace in-memory (i.e., without needing to create a test workspace on disk).

While there are a few large task construction tests which test the most common set of task construction logic, most newer tests are scenario-based, covering new functionality or fixed bugs.

Enhancement of the supporting task construction test infrastructure is encouraged, when additional functionality will make writing tests easier.

## Task Execution

**Framework:** SWBTaskExecution; in principle this should be a peer to SWBTaskConstruction, but the `BuildDescription` class currently imports that framework.

This framework sits on top of SWBCore, and defines the code which *executes* during an actual build. We make this strongly separated from SWBTaskConstruction because in general we expect task construction to be cached, and we don't use the actual objects constructed there during a build. Separating the modules makes it more clear what code is allowed in each place.

The task execution framework governs the running of tasks during a build, and it consists of two major subsystems:

### Build Description & Build Manifest

The term "build description" is often used to mean both the build description itself (the `BuildDescription` class), and the build manifest, which is the file Swift Build writes for llbuild to use to drive its build logic.

The manifest is a JSON file consisting of a list of commands and some auxiliary information.  This is essentially a serialized representation of the dependency graph.  For any given build, there is a single description-manifest pair.

The build description is additional information which Swift Build needs to provide to llbuild during the build, for example task actions and build settings.  There is some overlap of information between the manifest and the build description, but ultimately we hope to eliminate this redundancy by allowing Swift Build to query llbuild for information in the manifest.

When Swift Build is handed a build request to build a workspace, the `BuildDescriptionManager` first checks whether it already has a cached (in-memory or on-disk) build description for those inputs, and if it does, then it will use it.  Consequently, it should never be assumed that task planning will occur for every build; it may be bypassed entirely.  But if no cached build description is found, then a build plan will be generated from the inputs, and a new build description and manifest will be created from the build plan.

### Task Actions

Task actions are in-process commands which run during a build.  These are, literally, tasks which run inside Swift Build's address space rather than as subprocesses running on-disk tools.  Some task actions are in-process for historical reasons, while others require information only available inside Swift Build (for example, to to request dynamic inputs or implement custom behaviors).  llbuild will call back to Swift Build when a task specifies a task action.

*To be documented:* `Task`, `TaskAction`

**Testing:** Tests for task actions are scenario-based, typically using a pseudo file system, to check that running a task action behaves as expected.

There are some some simple build description tests, but the more interesting tests are up in SWBBuildSystem.

## Build System Framework

**Framework:** SWBBuildSystem; this is the parent to SWBTaskConstruction and SWBTaskExecution

This framework sits on top of SWBCore, SWBTaskConstruction, and SWBTaskExecution. It coordinates the construction and planning of build operations, defines the concrete tasks used to execute them, manages their execution, and handles dispatching status back to clients.

The `BuildManager` class manages the build operations in the Swift Build process, while the `BuildOperation` class represents a single build operation.

**Testing:** As in SWBTaskConstruction tests, the SWBBuildSystem tests include a helped class `BuildOperationTester` which is used to construct a build description from build inputs, and then to run that build and examine the results.  Most of the tests which run builds involve performing real builds rather than simulated builds, as the simulation support is still in development.

## Build Service

**Framework:** SWBBuildService

This framework sits atop the rest of the service-level ones, and it implements the actual service logic.

This is the layer that communicates with the client via serialized messages.  This layer also manages the individual sessions, one for each workspace open in the client.

The `ClientExchangeDelegate.swift` file contains communications channels where SWBBuildService will call back to clients for information it needs during task construction or task execution.  There is a slightly different mechanism for retrieving signing & provisioning inputs, which should probably be migrated to the `ClientExchangeDelegate` model.

**Framework:** SWBServiceCore

This framework implements general-purpose logic for a service. It is intended to be decoupled from the concrete service Swift Build implements; i.e. it could be reused to build another similar service.

**Bundle:** SWBBuildServiceBundle

This is the actual SWBBuildService service. It is a bundle which contains an executable which implements the service over a pipe.

This is just a thin shim on the SWBBuildService framework.

**Testing:** There is no testing at this layer yet.

## Protocol

**Framework:** SWBProtocol

This framework contains the shared protocol definitions for messages exchanged between the client framework (SwiftBuild.framework) and build service (SWBBuildService).

## Public API

**Framework:** SwiftBuild

This is the client facing framework which provides access to swift-build, for integration into clients.

## Command Line Tools

- **swbuild:** This is the command line tool for interacting with public API and service, and for testing.


# Dynamic Tasks

## Architecture Overview

Swift Build uses llbuild to invoke a planned build by creating a build manifest (see `BuildDescription` and related files). This manifest is created during task construction and is immutable.
llbuild's execution mechanism on the other hand doesn't require an immutable manifest. It needs tasks to provide their inputs (files or other tasks), a callback to indicate if a previously produced build value is still valid and another callback to produce that build value. To create the tasks, llbuild uses the manifest with its command/inputs/outputs declarations.
A file that is an output to a task has a reference to this task as its producer. Other tasks using this file as an input define it as input.

Dynamic tasks in Swift Build use this API for tasks that are unknown at task construction time and get discovered during task execution. Since downstream tasks need to be blocked until the yet unknown tasks finished, there needs to be an upfront planned task that provides gates around dynamic tasks.
Example: Swift compilation frontend invocations are dynamic tasks but they need to block linking which is planned upfront. Take make this work, there's an upfront planned task that requests those dynamic tasks but also specifies their expected outputs as its own outputs. That blocks downstream tasks until the requested dynamic tasks all finished.

## Concrete Implementation

Tasks in llbuild implement the abstract class `Command` - most that are used in Swift Build are using `ExternalCommand`. `ExternalCommand` encodes the logic to define input and output nodes, it requests inputs and checks for outputs on incremental builds. It also creates parent directories for expected outputs. Subclasses override `executeExternalCommand` to perform the actual work.
Tools that Swift Build invokes outside via their command line interface use `ShellCommand` which spawns a process using the provided command line options. Dynamic tasks go through `CAPIExternalCommand` which wraps the API to the Swift interface.
Swift Build implements those via `InProcessCommand` that represents task actions (in-process work) and dynamic tasks that get created by their defined `DynamicTaskSpec` (`DynamicTaskSpecRegistry.implementations`).

### Execution Flow

Let's use a simplified example of tasks to compile two Swift files with a following link step. With the Swift driver implementation utilizing dynamic tasks, there's one upfront planned task to request dynamic tasks which blocks the downstream linker task. The linker produces the product of interest, so llbuild reads the manifest and creates a command for it. The command (`ShellCommand`) specifies a command line and inputs/outputs. The inputs are .o files, so when they get requested, llbuild will request each producer of those files.
In this simplified example, the only producer is the upfront planned task which has both Swift files as inputs and the .o files as outputs. But it doesn't create them, it requests dynamic tasks. First, the driver planning task that runs in process and initializes the driver and let's it create a planned build. It then uses this planned build to request other dynamic tasks for the frontend invocations. Those create the actual .o files that the gate-task expects so it finishes and unblocks llbuild in executing the linker task.

![](dynamic-tasks-execution-flow.png)

### Setup

Here's an overview of the classes in llbuild (green) and Swift Build (blue) that are required to request and execute dynamic tasks:

![](dynamic-tasks-setup.png)

The callbacks in TaskAction use defined state and allow for different work:

#### taskSetup

This might get called multiple times on the same `TaskAction` instance and should reset every state. It allows the task action to request tasks (`dynamicExecutionDelegate.requestDynamicTask`) or file inputs (`dynamicExecutionDelegate.requestInputNode`). Every request takes an identifier that needs to be unique over all inputs (files and tasks) represented by the `nodeID`/`taskID` of the interface.
Example: Swift driver planning is requested for a Swift driver job scheduling action in taskSetup - it needs to be requested, no matter what.

#### taskDependencyReady

This gets called for every input (potentially multiple times). The provided `dependencyID` matches the previously provided `nodeID`/`taskID`. This callback also allows to request more work.
Example: Once driver planning finishes, this callback is used to use the result of planning and schedule driver jobs itself.

#### performTaskAction

In this state it's not possible to request any more inputs. It is guaranteed that all requested inputs successfully provided a build value in the `taskDependencyReady` callback. Keep in mind that the value does not necessarily represents a successful state - it might be failed, missing or invalid.
`performTaskAction` is meant to validate local state like previously generated errors (failed inputs) and to do the actual work of the task action.
Example: Swift driver planning is a dynamic task that calls the driver in `performTaskAction`, SwiftDriverJobTaskAction executes the compiler frontend invocation via the provided llbuild spawn interface.


# Indexing Support

Swift Build, Xcode, and the low-level compilation tools work together to provide semantic functionality in the Xcode editor, like code-completion, jump-to-definition, global rename, etc.

## Overview

There are two forms of indexing in Xcode, both of which cooperatively utilize the (raw) Index Data Store in Derived Data.

- Index while Building
- Background Indexing

### Index while Building

Index-while-Building is controlled via the `INDEX_ENABLE_DATA_STORE` build setting and is enabled by default for debug builds, and the index store directory path is controlled by the `INDEX_DATA_STORE_DIR` setting.

When enabled, the index data store is populated by the compilers during the build process. The `-index-store-path` flag (both for clang and swiftc) indicates the directory root in which raw index data should be placed. The individual data files written by the compilers are not considered part of the build intermediates or outputs and therefore are not tracked by the dependency system.

> Note: The format and directory structure of the Index Data Store is an implementation detail of the compiler and indexing system. However, it's worth mentioning that the filenames of some of the files within the index data store are based on a hash of the absolute file path of the related translation unit. The compilers accept a `-index-unit-output-path` flag which can be used to base this hash on a relocatable path (which may or may not exist in the underlying filesystem). This is important for distributed systems where part of the raw index data may be generated on a remote server.

### Background Indexing

Background indexing uses the same raw data store, but uses dedicated build system APIs (see `generateIndexingInfo` and in `SWBBuildServiceSession`) to extract the compiler command line invocations that the build system would normally perform, and then re-invokes those command lines outside the context of the build system when appropriate, in order to achieve higher performance compared to performing a full build each time the raw index data store needs to be updated for a given translation unit.


# Swift Driver

This document will explain specifics about the Swift driver planning invocation and execution.

Check out <doc:dynamic-tasks> for background about how dynamic tasks in Swift Build work.

## Difference to clang

Swift has no header files, so it needs to generate modules that downstream targets can depend their compilation on. Due to the absence of header files the compiler also needs to parse in multiple files (in fact, all files of the same target + Swift modules from upstream targets) to reason about declarations within the source.
Swift uses different compilation modes for that to split up that work. Whole module optimization *(which is also an optimization level, we focus on the compilation mode here)* parses and compiles all files within the context of one long running process that also produces all .o files of that target. Single file *(not available in the build settings editor anymore)* spawns one process per file - each process needs to parse all files but compilation is focused on this one file. And batch mode, the default - now called incremental, is in between. It spawns n processes for m files and forms batches to compile a given number of source files per process.
The creation of those processes and the orchestration between them is owned by Swift driver.

## Legacy Swift Driver

The legacy Swift driver integration in Swift Build calls `swiftc` as a command line utility, waits for it to finish and parses a JSON based stdout protocol to show sub-processes in the build log:

![](swift-driver-legacy.png)

This has fundamental problems for the build system:

* `swiftc` spawns processes to parallelize work and utilize the CPU. Swift Build tries the same but without a complex communication protocol they compete against each other bringing the system to a halt in the worst case
  * Example:
    * Swift Build spawns cpu.count processes in parallel (if possible, given the dependency graph)
    * Swift driver spawns cpu.count frontend processes in parallel (for compilation those are always independent)
    * This results in n*n processes, so the problem grows with the number of cores
* Swift Build always needs to wait for `swiftc` to finish although the necessary products to unblock downstream tasks (Swift module) can get created eagerly
* Process spawning is a complex operation with many parameters, Swift Build uses llbuild for that which spawns every build system task the same way. Swift driver needs to replicate this or do it differently

## New architecture

![](swift-driver-new1.png)

With the new integration of Swift driver, Swift Build calls into it using a library interface (libSwiftDriver.dylib → part of Xcode toolchain). Instead of one task to call the Swift driver (swiftc before), there are two tasks. SwiftDriver Compilation does the actual compilation of the files, creating .o files to unblock the linker. SwiftDriver Compilation Requirements on the other hand only produces the Swift module. It can and should run in parallel to compilation to eagerly unblock downstream tasks.
Here’s an overview of the dynamic tasks that are scheduled in the different buckets (Emit-Module and Compile are using the same task action SwiftDriverJobTaskAction):

![](swift-driver-new2.png)

## Incremental Builds

Usually llbuild decides if a task needs to re-run based on a) an input has changed or b) the output is not valid anymore. An invalid output has multiple possible causes, it could be a missing/deleted/never created file but it could also be that a task defines that the previous output is always invalid - meaning the task always needs to re-run.
Swift driver does something similar, it keeps an incremental state and collects timestamps. On subsequent builds it reads in the incremental state and schedules only driver jobs that need to re-run.
For the integration of Swift driver in Swift Build the decision was made to give Swift driver the sovereignty of incremental state for Swift. So Swift Build will always ask the driver about what tasks to run.


# Macro Evaluation

Swift Build supports macro evaluation using `make`-like `$(X)` syntax.  String values that contain macro references are called *macro expressions*, and can be evaluated to obtain literal values within *macro evaluation scopes*.

## Macro Types

There are two fundamental kinds of macro expression: *string* and *string list*.  A third type, *boolean*, is a subtype of *string* whose evaluated literal value is interpreted in the manner of NSString's `boolValue` method.

## Macro Declarations

A *macro declaration* maps a name to a type (string, string list, or boolean) in a macro namespace.  A macro name cannot be empty, and there can be only one declaration of a macro with a particular name in a macro namespace.  It follows that each macro name can be associated with at most one type in a macro namespace.

A macro declaration can also specify an unknown type, which is used for macros that are assigned but never explicitly declared.  They are treated as either strings, string lists, or booleans depending on usage.

## Macro Namespaces

A *macro namespace* defines a domain in which macros can be declared.  Each macro namespace maintains a mapping from macro name to the corresponding macro declaration.  All occurrences of a macro with a given name have the same type within a namespace (but may of course have different types in different namespaces).

Namespaces are also responsible for parsing strings and arrays of strings into macro expressions of the appropriate type.  The parsing semantics depend on the type (string or list) of the macro.  Macro expression parsing may yield parse errors -- an expression of the appropriate type is always returned, but it also carries an optional error description.

## Macro Definition Tables

A *macro definition table* associates macro declarations with lists of parsed macro expressions.  Each of the associated macro expressions can be associated with an optional *condition* that indicates when the expression should be used.

## Macro Evaluation Scopes

A *macro evaluation scope* represents a stack of macro definition tables in association with a set of condition parameter values, allowing unambiguous evaluation of macros to literals.

## Macro Conditions

A *macro condition* allows a macro definition to be used only some of the time.  In particular, a condition specifies a pattern that is matched against the value of that condition within the evaluation scope in which the condition is being tested.

## Macro Condition Parameter

A *macro condition parameter* is a predefined parameter of conditionality in terms of which a macro condition can be specified. Swift Build currently defines five macro condition parameters:  *config*, *sdk*, *variant*, *arch*, and *compiler*.


# Project Interchange Format

The Project Interchange Format (PIF) is a structured representation of the project model created by clients to send to Swift Build.  A single PIF can represent a workspace and all of the projects inside it.

## Overview

### What's Included in a PIF

The PIF is a representation of the SwiftPM/Xcode project model describing the static objects which contribute to building products from the package/project, independent of "how" the user has chosen to build those products in any particular build.  This information can be cached by Swift Build between builds (even between builds which use different schemes or run destinations), and can be incrementally updated by clients when something changes.

The PIF format and exchange mechanisms are designed under the assumption that the PIF changes rarely relatively to other requests, because active edits to the project model are rare.

### What's Not Included

The PIF is only a representation of the project model, and does not contain all relevant information for a particular build.  Two classes of information are excluded.

First, information which persists throughout a run of the client, such as:

* **Environment variables:**
* **Specifications:** Including tool specs, product and package type specs, etc.
* **Platforms and SDK definitions**
* **Toolchain definitions**

This information is loaded by Swift Build directly via the *Core* object or explicitly sent through the service interface (in the case of environment variables).

Second, information which describes a particular build and which may change from build to build, and is sent as part of individual build requests:

* **Scheme information:** Which targets are to be built, whether Parallelize Targets and Implicit Dependencies are turned on.
* **Run Destination information:** Including the target device and the active architecture.
* **Build parameters:** Including the build action, per-target overrides of build settings, the workspace arena and more.

### Incremental Updates

The PIF format is designed to support incremental update of certain objects (like projects and targets). This mechanism is designed so that the service can maintain a *persistent* cache of objects, and efficiently negotiate with the client the smallest set of objects which need to be transferred in response to model changes.

The incremental update mechanism works by assigning unique *signatures* to each of the objects in the PIF which can be independently replaced. A single PIF can contain definitions for multiple objects, identified by signature. Within any individual object, references to other objects are encoded indirectly via the same signature. When a client wishes to transfer a PIF to Swift Build, it incrementally negotiates the exact set of objects which are required (i.e., missing from swift-build) using the [PIF exchange protocol](#exchange-protocol). Once all the required objects have been transferred, then Swift Build has a complete set of objects and can load the workspace.

### Global Identifiers

Identifiers for objects in the PIF are needed to support looking up objects across top-level boundaries (such as project references). Objects that require this have an identifier (GUID) which is:

* *Unique* within the entire PIF.
* *Stable*, such that clients can generate the same GUID consistently for an object even if the object changes, unless that change makes it fundamentally a different object.

## Exchange Protocol

When a client wishes to transfer a PIF to Swift Build, it uses the PIF exchange protocol described here:

1. The client initiates a PIF transfer and sends a PIF containing the top-level object it wishes to transfer, typically the workspace.

2. Swift Build scans the set of objects it has received via the PIF transfer, and replies with a list of references which it does not have and requires transfer of.

3. The client transfers a PIF containing the additional requested objects.

4. Steps 2 and 3 repeat until Swift Build has all the objects it requires, at which point it acknowledges the receipt of the PIF and constructs the appropriate object.

## Format Description

The low-level encoding of the PIF is as [JSON](http://json.org).

PIFs are transferred using the [PIF exchange protocol](#exchange-protocol), and are encoded using the format described here.

Each PIF consists of a sequence of top-level objects (*PIFObject*). These define the objects which can be incrementally replaced by the PIF exchange protocol. Each entry in the PIF is a dictionary of the form:

* *signature*: A string signature uniquely representing the PIF object. This signature **must** completely define the PIF object; i.e. any other PIF entry with the same signature and type must define an identical object.
* *type*: The type of the top-level object. This is one of *workspace*, *project*, or *target*.
* *contents*: The contents of the object.

### Object Description

The remainder of this document defines the exact encoding for each object which can be represented in the PIF.

Objects which require it will have the following data in addition to their content:

* **GUID**: The object's [unique identifier](#global-identifiers) within the PIF.

For brevity, this item is not included in the structures described below.

Where the *value* of items below refer to a **GUID**, that indicates that the GUID of the referenced object has been captured and will be resolved by Swift Build to a concrete object elsewhere in the PIF.

The PIF structure has a few notable differences from the structure of the project model itself:

* Xcode models file references and product references as fairly similar objects with overlapping sets of data.  The PIF models these differently.  For example, neither product references nor proxies will have their own path and source tree information.
* Product references are not captured in the list of references of the project, but instead are captured as the product of the target which generates them.  Thus the fact that the reference is produced by the target is modeled by it being contained inside the target's PIF, and not by being a discrete references with a pointer to its producing target.  This more concisely captures the hierarchical relationship of the objects.
* There are no project references or reference proxies directly represented in the PIF, because since the whole workspace is being captured they can be fully resolved to the GUIDs of the objects they really represent.

#### Object References

Any place where an object can refer to a top-level PIF object uses the following encoding: If the item consists of a single string value, then that value is the signature for the object which is expected to be present at the top-level of the PIF (or previously loaded and available independently to the loader, in which case the PIF is incomplete).


# Build Target Specialization

Target specialization is the feature which allows Swift Build to build multiple
instances of a target within a single build.

This is used as part of Xcode's Swift package support to provide
"build to order" features for Swift packages, as well as multi-platform targets.

## Overview

Within Swift Build, we maintain a distinction between the `Target` model object and
the `ConfiguredTarget` which is a specific instance of a target plus build
parameters, as used within a particular build. While Xcode traditionally only
ever would allow one target to exist in one instance in a build, Swift Build can
allow the target to participate multiple times.

Conceptually, the `Target` can be thought of as the template for how the
something is built, and the `ConfiguredTarget` is a specific instance of that
template based on the run destination and other build parameters.

We use this generally capability in order to provide the "build to order"
feature used by Swift packages, as well as multi-platform targets.

## Mechanism

Target specialization occurs as part of resolving an incoming build request into
a complete `TargetBuildGraph`.

The mechanism by which this happens is that `PackageProductTarget` are
considered to be a "build to order" target type. When a target depends on a
`PackageProductTarget`, rather than use the targets own settings to determine
how it is built, it propagates _some of_ the settings from the target which
depends on it. This propagation continues along the full dependency chain, and
thus it impacts the `StandardTarget` instances used by the product type.

## Platform-Based Limitation

Target specialization currently *only* allows specializing based on the
platform. That is, we will at most produce one instance of a target per
platform.

While there are valid scenarios in which one could want a target to be built
multiple time for a single platform (one could imagine an XPC service that has a
newer deployment target, and could benefit by compiling its dependency for a
newer version), this limitation:

1. Allows us to piggy back on the existing platform-specific build directories,
   rather than have to invent a new mechanism to segregate different
   specializations.
2. Is conceptually simple to understand, which was desirable for the first
   attempts to take advantage of our `Target` vs `ConfiguredTarget`
   architecture.
3. Allows us to avoid the complicated question of exactly when we should be
   trying to create a separate specialization based on the wide variety of
   settings (or even based on user authored intent).

## Specialization Consolidation

Although conceptually targets are specialized based on the parameters of their
dependents, this mechanism alone would result in more specialized targets than
we currently support (or would want to support). For example, a package product
depended upon by a target with a 10.11 deployment target and a 10.12 deployment
target should typically only build the dependency for 10.11, rather than attempt
to specialize twice.

We implement this by first doing a prepass over the dependency graph, to gather
all of the configured targets before performing any specialization. Once
complete, we run the real dependency graph computation, which then searches
configured targets before it ever creates a specialization. We can extend this
over time to support a more complex aggregation of the specializations.

Finally, once this process is complete we perform a post-processing pass to
check that all of the specializations are valid. For example, in the current
implementation it is an serious bug to ever have ended up with multiple
specializations in the same platform.


# Specifications

Swift Build uses external data files known as `xcspec` files for storing the specification data used for various tasks when constructing the build tasks.

> Note: This document is not finished and does not fully reflect how support for some specs was implemented in Swift Build.

 For example, there are specifications which describe each of the tools that are run.

The `xcspec` files are automatically discovered and loaded by Swift Build during initialization.

## Basic Format

`xcspec` files are stored in property lists containing the specification data. Each property list file may contain one or more specs, multiple specs are encoded as elements in an array. Each individual spec is encoded as a dictionary in the property list.

Each property list has several required keys which specify the basic information of the spec, and the remainder of the keys in the dictionary are determined by the exact type of spec. See [Spec Types](#spec-types) for the list of supported types.

The common keys supported by all specs are:

* *"Identifier"* (**required**) (**not inherited**)

    The identifier of the spec. This must be unique within any particular domain, and should generally follow reverse domain name syntax (a la Java).

* *"Type"* (**required**) (**not inherited**)

    The type of the spec. See [Spec Types](#spec-types).

* *"Domain"* (**optional**) (**not inherited**)

    The domain the spec should be registered within. If not provided, the spec will be registered in the domain appropriate to its location, for example specs in the shared locations will be registered in the default domain and specs in platforms will be registered in the platform's domain. See [Spec Types](#spec-types).

* *"BasedOn"* (**optional**) (**not inherited**)

    If provided, a specifier for the spec which this one is "based on" (i.e., the one it inherits from). That spec will be loaded first and its spec properties will be inherited. The exact details and meaning of inheritance depend on the spec type. The base spec **must** be of the same `"Type"` (although the `"Class"` need not be).

  The specifier should be of the form `( domain ':' ) identifier` (e.g,  `macosx:com.apple.tool.foo`), where the domain defaults to the domain of the current spec if not specified.

* *"Class"* (**optional**) (**inherited**)

    If provided, the name of a specific class which should be instantiated to implement the spec behavior, as opposed to using the generic implementation appropriate for the type.

    This key *may be* provided in the the base specification.

## Spec Discovery

Specs are automatically discovered and loaded from plugins. These plugins are provided by the Swift Build project itself.

## Spec Types

The following types of specs are supported:

* **["Architecture"](#specs-architecture)**

    These specs define actual architecture names or virtual names for groups of architectures.

* **"BuildPhase"**

   > Note: FIXME: Document, or eliminate. This is used by Swift but might not be necessary anymore.

* **["FileType"](#specs-filetype)**

    These specs define information about the file types used by Swift Build.

* **["PackageType"](#specs-packagetype)**

    These specs define information used to implement the different kinds of product packages (i.e., executable, static library, framework, app extensions, etc.).

* **["ProductType"](#specs-producttype)**

    These specs define information about specific product types that can be produced by the build system.

* **"Platform"**

    Each platform also contributes a spec definition properties of the platform.

    > Note: FIXME: We don't currently have these, and may not need them. Eliminate if never used.

* **[*Property Domain Specs*](#specs-propertydomain)**

    Property domain specs are not a concrete type that can be instantiated, but are a common base class shared by the *BuildSystem* specs and the *Tool* specs. This base class factors out the common code for defining information about groups of build settings.

* **"BuildSettings"**

    > Note: FIXME: Document. This is used by Swift, but may no longer be necessary.

* **["BuildSystem"](#specs-buildsystem)**

    These specs define basic information about the build system, for example information about all the build settings.

    Internally, there are separate "build system" definitions for external targets, aggregate, and "native" targets. These correspond to distinct *BuildSystem* specs.

* **["Tool"](#specs-tool)**

    Each tool that can be executed by the build system has a defining spec containing information on the tool, how to invoke it, the settings it supports, and so on.

    The tool type is a superclass of the *Compiler* and *Linker* specs, but can also be concretely instantiated for tools that match neither of those types (for example, `strip` or `dsymutil`).

* **["*Generic* Tool"](#specs-generictool)**

    Generic tool specs do not have a backing class but are (usually) entirely specified by the data in their spec plist.

* **["Compiler"](#specs-compiler)**

    These specs are used for "compiler-like" tools, i.e., tools which operate on and input and transform it into an output of another type.

* **["Linker"](#specs-linker)**

    These specs are used for `ld` and linker-like tools (like `libtool`).

## Spec Object Types

The following kinds of objects may be encoded in the spec files.

|Type|Description|
|----|-----------|
|Bool|A boolean value, which should be encoded as either the string `"YES"` or `"NO"` (several other spellings are support for backwards compatibility, but these are the preferred spellings).|
|String|An individual string, encoded as part of the property list format.|
|StringList|A list of strings, encoded as part of the property list format.|
|BuildSettingsDict|A dictionary defining a group of build settings. This should be encoded as a dictionary mapping setting names (and optionally, conditions) to values. Also note that there is no ordering in these objects, which can be a problem when using conditional build settings.|
|CommandLineStringList|A string or list of strings, encoded as part of the property list format. If the string form is used, then it will be separated into arguments following the shell quoting rules.|

> Note: define `BuildSettingsDict` a bit more.

### Architecture Specs

> Note: FIXME: Document Architecture specs.

|Name|Type|Attributes|Description|
|----|----|----------|-----------|
|CompatibilityArchitectures|`CommandLineStringList`|**Optional**|The list of architectures which can are compatible with this one. A `VALID_ARCHS` including this arch will implicitly include all of the ones listed here.|

### FileType Specs

> Note: FIXME: Document FileType specs.

### PackageType Specs

> Note: FIXME: Completely document PackageType specs.

|Name|Type|Attributes|Description|
|----|----|----------|-----------|
|DefaultBuildSettings|`BuildSettingsDict`|**Required**|The default build settings included for all instances of this package type.|

### ProductType Specs

> Note: FIXME: Completely document ProductType specs.

| Name | Type | Attributes | Description |
|------|------|------------|-------------|
| DefaultBuildProperties | `BuildSettingsDict` | **Required** | The default build settings included for all instances of this product type. |

### Property Domain Specs

Property domain specs are an abstract class used by all specs which define groups of supported build options (for example, the build system specs and the compiler specs).

The property domain primarily consists of definitions of each of these options, including information on how the option should drive command line arguments for tool specs which make use of the automatic command line generation
infrastructure.

| Name | Type | Attributes | Description |
|------|------|------------|-------------|
| Properties | `StringList` | **Optional** | The list of properties associated with this spec, in the order they should be processed. For legacy compatibility these values may be specified under `"Options"`. The list should be an array of items which will be parsed following the information in [Build Option Definitions](#specs-buildoptiondefs).|
| DeletedProperties | `StringList` | **Optional** | The names of build options to remove from the base spec's build option list, when creating the flattened list of options supported by this spec. |

### Build Option Definitions

Each build option definition is a property dictionary defining information on
the option.

The following keys are supported:

| Name | Type | Attributes | Description |
|------|------|------------|-------------|
| Name | String | **Required** | The name of the option and the build setting that controls it. |
| Type | String | **Optional** **Default="String"** | The string identifying the type of the option. |
| DefaultValue | String | **Optional** | The default value for the build setting, if any. This must always be a string, but it will be parsed as a macro expression appropriate for the type of the option (string or string list). |
| Values | *Custom* | **Required (Enumeration Options)** **Optional (Boolean Options)** **Unsupported (Other)** | This is an array of [Build Option Value Definitions](#specs-buildoptionvaluedefs). This entry is **required** for *Enumeration* option types, **optional** for *boolean* types, and **unsupported** for all other option types. This entry is used to describe the set of possible values for the option, and possibly additional information about how to handle instances of that value (for example, what command line options should be used for values of that type). See [Build Option Value Definitions](#specs-buildoptionvaluedefs) for more information on the supported features. There is no technical reason we cannot support this feature for non-enumeration scalar types. Supporting that is tracked by <rdar://problem/22444795>. |
| CommandLineArgs | *Custom* | **Optional** | This is a string, string list, or dictionary describing how this option should translate to command line arguments. For the string and string list forms, they will be parsed as macro expression strings and subject to macro evaluation, then added to the command line. The macro expression may make use of `$(value)` to refer to the dynamic value of the option. For the dictionary form, the dictionary entries map possible dynamic values to the string or string list forms to substitute -- similar to the handling of `"Values"` but only supporting definition of the command line template. Those individual forms are subject to the same macro evaluation behavior as the string or string list forms of `"CommandLineArgs"`. The value entry of `"<<otherwise>>"` is a special sentinel value that defines the behavior to be used for any dynamic value not explicitly mentioned (that is, a default behavior). If a value appears in `"CommandLineArgs"` and `"Values"`, it **may not** define a command line template form in the `"Values"` entry. For boolean types, only the `"YES"` or `"NO"` values may be defined. |
| AdditionalLinkerArgs | *Custom* | **Optional** | If present, this should be a dictionary mapping possible values to a string or string list supplying additional linker command line arguments to add if the option is enabled. |
| CommandLineFlag | String | **Optional** | If present, defines the flag to use when translating this option to command line arguments. This key **may not** be combined with `"CommandLineArgs"` or `"CommandLinePrefixFlag"`. For boolean options, the given flag will be added to the auto-generated command line if the dynamic value for the option is true. For non-boolean option types, the given flag will be added followed by dynamic value of the option. For list option types, there will be one instance of the flag and the item per item in the dynamic value list. In both cases, the empty string is treated as a special case and signifies that only the dynamic value should appear in the arguments (that is, no empty string is added to the arguments). |
| CommandLinePrefixFlag | String | **Optional** **Unsupported (Boolean Options)** | If present, defines the flag to use when translating this option to command line arguments. This key **may not** be combined with `"CommandLineArgs"` or `"CommandLineFlag"`. The given flag will be added as a single argument joined with the dynamic value of the option. For list option types, there will be one instance of the flag and the item per item in the dynamic value list. |
| Condition | String | **Optional** | If present, a "macro condition expression" which defines when the option should be considered active. This can be used to evaluate a more complicated set of macros to determine when the command line option should be present. |
| FileTypes | StringList | **Optional** | If present, a list of file type identifiers that define when this option should be active. |
| AppearsAfter | String | **Optional** | The name of a build option which this option should immediately succeed. This is useful for controlling the order of generated arguments and the order of options in the UI. |

Supported values for `Type`:

| Type | Description |
|------|-------------|
| Boolean | A boolean build setting. |
| Enumeration | An enumeration build setting, encoded as a string. |
| Path | A build setting which represents a path string. |
| PathList | A build setting which represents a list of path strings. |
| String | A string build setting. |
| StringList | A build setting which is a list of strings. |
| MacroString | A string build setting, which is parsed as a macro expression and subject to macro evaluation when used. |

> Note: For legacy compatibility, the type can be spelled in several other variants, but these should be considered the canonical forms. FIXME: Several other types are supported, but these are the primary ones.

> Note: FIXME: For `CommandLinArgs`, Document string splitting semantics (are these shell-escaped strings?).

### Build Option Value Definitions

Each build option value definition is a property dictionary defining information about a particular possible value for a *Boolean* or *Enumeration* build option. The following keys are supported:

| Name | Type | Attributes | Description |
|------|------|------------|-------------|
| Value | String | **Required** | The string identifying the value. For boolean types, only the values `"YES"` and `"NO"` are allowed. |
| DisplayName | String | **Optional** | The human readable string used to describe this value. |
| CommandLine | String | **Optional** | If present, defines a "shell"-escaped string to use when translating this option to command line arguments (if the containing option's dynamic value matches this one). The string will be broken into separate individual arguments following the shell rules, and will be subject to macro expression evaluation. The macro expression may make use of `$(value)` to refer to the dynamic value of the option. |
| CommandLineArgs | StringList | **Optional** | If present, defines a list of "shell"-escaped strings to use when translating this option to command line arguments (if the containing option's dynamic value matches this one). Each item in the string list will be broken into separate individual arguments following the shell rules, and will be subject to macro expression evaluation. The macro expression may make use of `$(value)` to refer to the dynamic value of the option. |
| CommandLineFlag | String | **Optional** | If present, defines a single command line flag to pass on the command line when this dynamic value is present for the containing option. |

### BuildSystem Specs

> Note: FIXME: Document BuildSystem specs.

### Tool Specs

Command-line tool specs support the following keys, in addition to those supported by its base class ([Property Domain Specs](#specs-propertydomain)).

| Name | Type | Attributes | Description |
|------|------|------------|-------------|
| SourceFileOption | String | **Optional** | The option to pass to indicate what kind of source files are being processed. This will commonly default to `-c` for typical compilation tools, but alternate uses of tools (for example, the clang static analyzer) will use a different option. |

> Note: FIXME: There are other keys currently used by tool specs which are not yet documented, including: `ExecDescription`, `InputFileTypes`, `FileTypes`, `SynthesizeBuildRule`, and `InputFileGroupings`.

### *"Generic"* Tool Specs

*"Generic"* command line tool specs (those which *do not* use a custom subclass) support additional keys which are used to drive the generic machinery.

| Name | Type | Attributes | Description |
|------|------|------------|-------------|
| CommandLine | `CommandLineStringList` | **Required** | This property defines the template which is used to construct command lines for the tool. The template should be a "command line" string list of arguments or placeholders to create the command line from. Each individual argument may either be a macro expression string or a placeholder expression of the form `[NAME]`. The following placeholders are supported: `[exec-path]`, `[input]`, `[inputs]`, `[options]`, `[output]`, and `[special-args]`. This property must be provided by the spec or its base spec. |
| RuleName | `CommandLineStringList` | **Required** | This property defines the template which is used to the "rule info" (short description) for the tool. The template should be a "command line" string list of arguments or placeholders to create the rule info. Each individual argument may either be a macro expression string or a placeholder expression of the form `[NAME]`. The following placeholders are supported: `[input]` and `[output]`. |
| ExecPath | `MacroString` | **Optional** | This property defines the name or path of the executable invoked by the command. |
| EnvironmentVariables | *Custom* | **Optional** | If defined, this property should be a dictionary mapping environment variable names (as strings) to environment variable values (as strings). The values will be subject to macro evaluation. These environment variables will be added to the default set when invoking the command. |
| IncludeInUnionedToolDefaults | `Boolean` | **Optional** **Default=true** | Specifies whether the tool's settings should be included in the unioned tool defaults which are added to all settings tables. |
| Outputs | `StringList` | **Optional** | If present, defines the names of the output files created by the tool. These values will be subject to macro evaluation. They can make use of the special macro `$(OutputPath)` to refer to the automatically output path used in phases such as the resources phase, or they can define the output purely in terms of the input macros. |
| WantsBuildSettingsInEnvironment | `Boolean` | **Optional** **Default=false** **Deprecated** | Specifies whether all of the available build settings should be pushed into the environment for use by the tool. **DO NOT** use this without talking to a member of the build system team, there are usually better ways to accomplish the same task. |
| GeneratedInfoPlistContentFilePath | `MacroString` | **Optional** | If used, specifies a macro string expression which should expand to the path of a file produced as an additional output of the command. The file is expected to be a property list containing additional content to be included in the `Info.plist` for the product being built. |

Placeholders for the `CommandLine` property:

| Placeholder | Description |
|-------------|-------------|
| `[exec-path]` | Expands to the dynamically computed path of the tool. |
| `[input]` | Expands to the path of the first input. May not be used by tools which accept multiple inputs. |
| `[options]` | Expands to the automatically generated list of command line options derived from the tool's `Properties` spec data. |
| `[output]` | Expands to the path of the first output. |
| `[special-args]` | Expands to an tool specific list of arguments (this is an extension point for subclasses which wish to reuse the generic tool machinery). |

Placeholders for the `RuleName` property:

| Placeholder | Description |
|-------------|-------------|
| `[input]` | Expands to the path of the first input. |
| `[output]` | Expands to the path of the first output. |

### Compiler Specs

Compiler specs support the following keys, in addition to those supported by its base class ([Tool Specs](#specs-tool)).

| Name | Type | Attributes | Description |
|------|------|------------|-------------|
| Architectures | `StringList` | **Optional** | A specifier for the architectures the compiler supports. If omitted, the compiler is expected to support any architecture. If present, the value must be either a string list containing the exact names of real architectures which are supported, or it can be the sentinel value `$(VALID_ARCHS)` indicating that the compiler supports all current valid architectures. |

> Note: FIXME: Why is that necessary? Wouldn't such a compiler just declare itself as supporting any architecture?

### Linker Specs

> Note: FIXME: Document Linker specs.


# Build Debugging

Swift Build has a few facilities for debugging build problems.

## User Defaults

Currently, you can enable various debugging facilities by setting user defaults.

### Debug activity logs

```
defaults write org.swift.swift-build EnableDebugActivityLogs -bool YES
```

This will cause Swift Build to emit more detailed note diagnostics to the build log
which is deemed to verbose for normal usage.

### Incremental build debugging

```
defaults write org.swift.swift-build EnableBuildBacktraceRecording -bool YES
```

This will cause Swift Build to print build backtraces for each task to the build log. Build backtraces read top to bottom describe how a task was invalidated and the chain of events which triggered that invalidation. For example:
```
Build Backtrace:
an input of 'Create static library libllbuildBuildSystem.a (arm64)' changed
the producer of file '/Users/user/Library/Developer/Xcode/DerivedData/swift-build-cexiveldpggehwhajfsbrdvdsiuf/Build/Intermediates.noindex/InstallIntermediates/macosx/Intermediates.noindex/llbuild.build/Debug/llbuildBuildSystem.build/Objects-normal/arm64/BuildSystemFrontend.o' ran
an input of 'Compile BuildSystemFrontend.cpp (arm64)' changed
file '/Users/user/Development/llbuild/include/llbuild/BuildSystem/BuildSystem.h' changed
```

### Additional tracing for post-mortem analysis

```
defaults write org.swift.swift-build EnableBuildDebugging -bool YES
```

This will cause Swift Build to enable `llbuild`'s tracing feature and also to create
a copy of any existing database, adjacent to the normal database location
(currently `$(OBJROOT)/swift-buildData`).

The database can be inspected using `llbuild`'s UI to see the contents of the
database at the time the build was started. The trace file provides a *very*
low-level description of what the build engine did during the build. The
intention is that eventually llbuild will gain facilities to ingest the pre- and
post- database files and the trace file and provide additional information about
what happened.

## Debugging *llbuild*

If you ever need to inspect the contents of the llbuild database (for example, to see discovered dependencies), the *llbuild* project has a basic web UI which can be used to explore the database.

To do this, check out `llbuild/products/ui/README.md` and follow the instructions to install and start the web viewer, then give it the path (in the web UI) to the database you want to see.

## Multi-process Debugging

The service nature of Swift Build can make debugging painful, when a problem only manifests when Swift Build is running as an inferior service of Xcode.

The recommended way to deal with this is by writing isolated tests that reproduce the problem directly in *SWBBuildService* (without going through IPC). This avoids the need for doing multi-process debugging in the first place, while also increasing our test coverage (and you already have a test case for the bug you want to fix).

If that fails, it is possible to manually attach to the service. Once launched, you can attach to it manually using Xcode or lldb.

If that fails, you can fall back to launch Swift Build in a mode where the service will run entirely in process with the client-side framework (on background queues). This is done by setting `XCBUILD_LAUNCH_IN_PROCESS=1` in the environment.

Xcode also supports using a custom copy of the Swift Build service by overriding `XCBBUILDSERVICE_PATH` in the launched Xcode environment. For example, this can be used to run with a development copy of the service using an installed set of Xcode tools:

    env XCBBUILDSERVICE_PATH=/path/to/SWBBuildService.bundle/Contents/MacOS/SWBBuildService \
        xcodebuild --workspace .../path/to/foo.xcworkspace --scheme All


# Project Tests

This document describes how to write "project tests", a set of specific types of integration tests used to test build system functionality.

## Overview

Like most software projects, Swift Build has numerous kinds of tests, including unit tests, integration tests, and performance tests. By far the most important kind of tests in the build system domain however are project tests.

There are two main approaches to writing project tests in Swift Build, based on the different layers in the build system’s overall architecture.

### Task Construction Tests

Task construction tests validate the contents of the task graph generated as part of a build’s initial planning stage, including the input and output dependency edges of tasks, the command like invocation used to perform the task, and other metadata. In a task construction test, the underlying task commands are NOT run, similar in concept to dry run builds.

### Build Operation Tests

Build operation tests encompass both the task planning stage covered by task construction tests, as well as the subsequent execution of the underlying commands associated with each task in the graph. Build operation tests are usually chiefly focused on validating the outputs (files) produced by a build operation rather than the structure of the task graph, though they often do some combination of the two.

### Core Qualification Tests

The intent is that these are the highest level of tests (in terms of abstraction layer). They go directly through the public API and spawn a build service process, unlike build operation tests which only test the build operation execution, or task construction tests which only test construction of the task graph but don't execute tools. These tests are focused on end to end experiences where exercising the communication between the client framework and the build service process adds additional coverage.

## Setup

Both task construction and build operation tests usually involve setting up a test project or workspace, which is an in-memory representation of a workspace, project, or Swift package.

It's also customary to wrap the test in `withTemporaryDirectory` in order to provide a location for any files written during the test execution to be placed, and which will automatically be cleaned up once the test ends.

A minimal test case might look something like this:

```swift
func testProject() throws {
    try withTemporaryDirectory { tmpDir in
        let project = TestProject(
            "aProject",
            sourceRoot: tmpDir,
            groupTree: TestGroup(
                "SomeFiles",
                children: [
                    TestFile("Assets.xcassets"),
                    TestFile("Class.swift"),
                ]),
            buildConfigurations: [
                TestBuildConfiguration(
                    "Debug",
                    buildSettings: [
                        "PRODUCT_NAME": "$(TARGET_NAME)",
                        "PRODUCT_BUNDLE_IDENTIFIER": "com.apple.project",
                        "SWIFT_VERSION": "5.0",
                    ]),
            ],
            targets: [
                TestStandardTarget(
                    "SomeLibrary",
                    type: .framework,
                    buildConfigurations: [
                        TestBuildConfiguration("Debug"),
                    ],
                    buildPhases: [
                        TestSourcesBuildPhase([
                            "Class.swift"
                        ]),
                        TestResourcesBuildPhase([
                            TestBuildFile("Assets.xcassets"),
                        ]),
                    ]
                ),
            ])
    }
}
```

These test methods are normally placed in a test class derived from `XCTestCase` and conforming to `CoreBasedTests`.

## Evaluation

The next phase involves building the project, which requires setting up a test harness which operates on the project or workspace set up in the previous section, and allows operations to be performed on it.

For task construction tests, create a `TaskConstructionTester`:

```swift
let tester = try TaskConstructionTester(core, testProject)
```

For build operation tests, create a `BuildOperationTester`:

```swift
let tester = try BuildOperationTester(core, testProject)
```

_Both test harness' initializers require a `Core` object. The `CoreBasedTests` protocol provides a `getCore()` instance method which can be used to retrieve a Core instance within a test method._

The `tester` object has several methods to perform some kind of build and subsequently provide a results object to perform analysis on it. The most widely used is `checkBuild` (and `checkIndexBuild` for index builds), which accepts a build request and is common to both `TaskConstructionTester` and `BuildOperationTester`.

`checkBuildDescription` and `checkNullBuild` are exclusive to `BuildOperationTester`.

For example:

```swift
await tester.checkBuild(BuildParameters(configuration: "Debug")) { results in
    // ...
}
```

All of the "check" methods can be invoked multiple times on the same `tester` object, which can be useful for testing incremental build behavior.

## Analysis

Once a build has been performed via a call to one of the "check" methods, the `results` parameter in the results analysis closure provides an opportunity to inspect the task graph and (for build operation tests), the output files produced in the file system.

There are numerous "check" methods on the `results` object, many of which are provided via protocols common to both task construction and build operation tests.

The two most common families of checking methods relate to checking for build tasks, and checking for diagnostic messages. They operate on a consumer model: clients are expected to call `checkTask` multiple times with various parameters to "consume" all of the tasks in a graph, finally calling `checkNoTask` to ensure that no unchecked tasks remained. The same is true for diagnostics.

#### checkNoDiagnostics

For tests validating a successful build, it's good practice to call `checkNoDiagnostics` at the beginning of the analysis closure to ensure that the build completed successfully without any warnings or errors.

For tests where a build is expected to fail, call `checkError` and `checkWarning` as needed to consume the expected diagnostic messages.

```swift
await tester.checkBuild(BuildParameters(configuration: "Debug")) { results in
    results.checkError(.equal("The build encountered an error."))
    results.checkNoDiagnostics()
}
```

#### checkTask

In task construction tests, the `checkTask` and related methods check if a task merely exists in the graph. In build operation tests, these methods check if the task exists in the graph _and actually executed_.

This distinction can be important for build operation tests validating incremental build behavior, which want to ensure that certain tasks did or did not run in an incremental build, based on the changes made to persistent state between builds.

The `checkTask` method accepts a `TaskCondition` object which allows searching for a task based on varying match criteria, such as its rule info array (or subparts of it), command line arguments, or associated target.

It is an error if the match criteria passed to `checkTask` returns more than a single task. For this reason, `checkTask` often needs to be given a more specific (or multiple) match criteria. To search for multiple tasks at once, use the `checkTasks` overload, which instead returns an array of zero or more tasks.

If a task matching the given criteria is found, the trailing closure passed to `checkTask` will be called, and APIs to inspect various state about the task will be provided via the `task` object. The most useful attributes of a task to validate are usually its command line invocation and input and output dependency edges.

```swift
await tester.checkBuild(BuildParameters(configuration: "Debug")) { results in
    results.checkTask(.matchRuleType("Ld")) { task in
        task.checkCommandLine(["ld", "-o", "/tmp/file.dylib", "/tmp/input1.o", "/tmp/input2.o"])
        task.checkInputs([.path("/tmp/input1.o"), .path("/tmp/input2.o")])
        task.checkOutputs([.path("/tmp/file.dylib")])
    }
}
```

#### consumeTasksMatchingRuleTypes

Most tests only want to check the behavior of a handful of specific build tasks or build tasks of a given type. `consumeTasksMatchingRuleTypes` is a convenience method to consume or "skip" tasks of certain rule types that a given test is not interested in observing.

By default, it skips invisible `Gate` tasks, empty directory creation tasks, and a handful of others, and can be passed a custom list of task types to skip.

```swift
await tester.checkBuild(BuildParameters(configuration: "Debug")) { results in
    results.consumeTasksMatchingRuleTypes() // ignore the default set of tasks
    results.consumeTasksMatchingRuleTypes(["Ld", "Lipo"]) // ignore tasks related to linking
}
```

#### checkTaskFollows, checkTaskDoesNotFollow

`checkTaskFollows` and `checkTaskDoesNotFollow` provide the ability to to test whether two tasks have a direct or transitive dependency on one another (or not). Overloads are provided to check specific task instances, or a task instance in combination with a match criteria to identify some other matching task in the graph.

```swift
await tester.checkBuild(BuildParameters(configuration: "Debug")) { results in
    results.checkTaskFollows(task1, antecedent: task2)

    results.checkTaskFollows(task1, .matchRuleType("Ld"))
}
```


# Test Development

This document contains various advice related to unit and integration test development in Swift Build.

## Working With PIF Files from Xcode

Sometimes it is useful to have a [PIF](doc:project-interchange-format) to test Swift Build independently of Xcode. To get one, you can run:

    xcrun xcodebuild -dumpPIF path/to/output.pif -project path/to/project.xcodeproj

## Saving Temporary Directories

Many of our tests create temporary directories on the file system and automatically destroy them when complete. If you would like to not have these destroyed (so you can inspect them), you can run with `SAVE_TEMPS=1` set in the environment.

## Writing Project Tests

Project tests are a kind of integration test used to test build system functionality, and one of the most important classes of test in Swift Build.

<doc:test-development-project-tests>


# Discovered Dependencies

Swift Build can discover dependencies from tools it runs during the build.

## Overview

The way this works is that a task must be constructed to emit a dependency file in one of two formats:

- **Makefile format**, currently used only by `clang` and `swiftc`.  This is literally a make-based file of dependency info, and is also used by makefiles which are using those tools.
- **Dependency info format**, which is an Xcode-defined format described below.

Then the backing class for the xcspec which created the task must supply a `DependencyDataStyle` enum with the path to the file containing the dependency information, during task creation. Then llbuild will process the file in the appropriate format and use the dependencies as part of its dependency database.

## Dependency info format

A file in dependency info format is a list of <opcode/cstring> pairs.  Each opcode is one byte followed by a variable length, null-byte-terminated UTF-8 string.   The defined opcodes are:

| Code | Name | Description |
| ---- | ---- | ----------- |
| 0x10 | Input dependency | The string is the absolute path to a file used directly or indirectly as an input to the tool. |
| 0x11 | Missing input dependency | The string is the absolute path to a file the tool tried to use as an input, but which could not be found.  This is useful to observe that a location in a search path was examined but no match was found, so that if a file is placed there (and no other changes were made), a later rebuild will notice that it is now present. |
| 0x40 | Output dependency | An output file generated by the tool. |

There are presently some limitations in Swift Build in processing these codes.  Specifically:

- **Missing input dependency** is presently unimplemented in Swift Build/llbuild.  This was due to concerns that the dependency file would become large and expensive to process and handle.  We have no plans to implement this code.
- **Output dependency** is not yet implemented in Swift Build/llbuild.