From 3fe3500d98034504ddb493a406b736d5027258d2 Mon Sep 17 00:00:00 2001 From: Varun Gandhi Date: Sat, 23 May 2020 17:32:49 -0700 Subject: [PATCH] [docs] Add First Pull Request guide and Getting Started guide. This improves upon the existing documentation to provide a clearer end-to-end workflow for new contributors and people who wish to build the toolchain locally but do not intend to submit patches. We also provide more directions for systematically utilizing our existing documentation. --- Brewfile | 1 + README.md | 270 +----------- docs/GitHubCreatePRScreenshot.png | Bin 0 -> 63140 bytes docs/HowToGuides/FAQ.md | 101 +++++ docs/HowToGuides/FirstPullRequest.md | 179 ++++++++ docs/HowToGuides/GettingStarted.md | 609 +++++++++++++++++++++++++++ docs/README.md | 8 + 7 files changed, 915 insertions(+), 253 deletions(-) create mode 100644 docs/GitHubCreatePRScreenshot.png create mode 100644 docs/HowToGuides/FAQ.md create mode 100644 docs/HowToGuides/FirstPullRequest.md create mode 100644 docs/HowToGuides/GettingStarted.md diff --git a/Brewfile b/Brewfile index cbb504596de6d..d965eb21aaefa 100644 --- a/Brewfile +++ b/Brewfile @@ -1,2 +1,3 @@ brew "cmake" brew "ninja" +brew "sccache" diff --git a/README.md b/README.md index c772c53ac4dbb..14cc61b4d0a70 100644 --- a/README.md +++ b/README.md @@ -50,14 +50,9 @@ To learn more about the programming language, visit [swift.org](https://swift.or - [Contributing to Swift](#contributing-to-swift) - [Getting Started](#getting-started) - - [System Requirements](#system-requirements) - - [Getting Sources for Swift and Related Projects](#getting-sources-for-swift-and-related-projects) - - [Building Swift](#building-swift) - [Swift Toolchains](#swift-toolchains) - [Build Failures](#build-failures) -- [Testing Swift](#testing-swift) - [Learning More](#learning-more) -- [Build Dependencies](#build-dependencies) ## Contributing to Swift @@ -77,206 +72,15 @@ well. For more, see the [Code of Conduct](https://swift.org/community/#code-of-c ## Getting Started -These instructions give the most direct path to a working Swift development -environment. To build from source you will need about 2 GB of disk space for the -source code and up to 70 GB of disk space for the build artifacts with full -debugging. Depending on your machine, a clean build can take a few minutes to -several hours. Naturally, incremental builds are much faster. +If you are interested in: +- Contributing fixes and features to the compiler: See our + [How to Submit Your First Pull Request guide](/docs/HowToGuides/FirstPullRequest.md). +- Building the compiler as a one-off: See our [Getting Started guide][]. +- Building a toolchain as a one-off: Follow the [Getting Started guide][] + up until the "Building the project" section. After that, follow the + instructions in the [Swift Toolchains](#swift-toolchains) section below. -Once you are able to build things successfully and have a compile-test-debug -loop going, check out the [development tips](docs/DevelopmentTips.md) for -better productivity while working on the compiler. - -You can also skim [docs/README.md](/docs/README.md) to understand what -high-level documentation is available. - -### System Requirements - -macOS, Ubuntu Linux LTS, and the latest Ubuntu Linux release are currently -supported as host development operating systems. - -Please make sure you use Python 2.x. Python 3.x is not supported currently. - -#### macOS - -To build for macOS, you need [Xcode 12 beta 3](https://developer.apple.com/xcode/resources/). -The required version of Xcode changes frequently, and is often a beta release. -Check this document or the host information on for the -current required version. - -Swift's build tooling is meant to support spaces in the paths passed to them, -but using spaces sometimes tickles bugs in Swift's build scripts or the tools -they rely on. For example, [SR-13441](https://bugs.swift.org/browse/SR-13441) -is caused by a space in the Xcode path used on macOS. If you see Swift's build -tooling misbehave due to a space in a path, please -[report the bug on the Swift bug tracker](https://swift.org/contributing/#reporting-bugs) -and then change the path to work around it. - -You will also need [CMake](https://cmake.org) and [Ninja](https://ninja-build.org), -which can be installed via a package manager: - -**[Homebrew](https://brew.sh/)** - - brew install cmake ninja - -You can also use [homebrew-bundle](https://github.com/Homebrew/homebrew-bundle) -from the root of this repository's working directory to install all of these -dependencies: - - brew bundle - -**[MacPorts](https://macports.org)** - - sudo port install cmake ninja - -Instructions for installing CMake and Ninja directly can be found [below](#build-dependencies). - -#### Linux - -For Ubuntu, you'll need the following development dependencies: - -``` -sudo apt-get install \ - clang \ - cmake \ - git \ - icu-devtools \ - libcurl4-openssl-dev \ - libedit-dev \ - libicu-dev \ - libncurses5-dev \ - libpython-dev \ - libsqlite3-dev \ - libxml2-dev \ - ninja-build \ - pkg-config \ - python \ - python-six \ - rsync \ - swig \ - systemtap-sdt-dev \ - tzdata \ - uuid-dev -``` - -**Note:** LLDB currently requires at least `swig-1.3.40` but will successfully build -with version 2 shipped with Ubuntu. - -**Note:** For Ubuntu 20.04, use `libpython2-dev` in place of the libpython-dev package above. - -### Getting Sources for Swift and Related Projects - -First create a directory for all of the Swift sources: - - mkdir swift-source - cd swift-source - -**Note:** This is important since update-checkout (see below) checks out -repositories next to the Swift source directory. This means that if one clones -Swift and has other unrelated repositories, update-checkout may not clone those -repositories and will update them instead. Be aware that `update-checkout` -currently does not support paths with non-ASCII characters. If such characters -are present in the path to `swift-source`, `update-checkout` will fail. - -**Via HTTPS** For those checking out sources as read-only, HTTPS works best: - - git clone https://github.com/apple/swift.git - ./swift/utils/update-checkout --clone - -**Via SSH** For those who plan on regularly making direct commits, -cloning over SSH may provide a better experience (which requires -[uploading SSH keys to GitHub](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/)): - - git clone git@github.com:apple/swift.git - ./swift/utils/update-checkout --clone-with-ssh - -### Building Swift - -The `build-script` is a high-level build automation script that supports basic -options such as building a Swift-compatible LLDB, building the Swift Package -Manager, building for various platforms, running tests after builds, and more. - -There are two primary build systems to use: Xcode and Ninja. The Xcode build -system allows you to work in Xcode, but Ninja is a bit faster and supports -more environments. - -First, make sure that you're in the swift directory: - - cd swift - -To build using Ninja, run: - - utils/build-script --release-debuginfo - -When developing Swift, it helps to build what you're working on in a debug -configuration while building the rest of the project with optimizations. Below -are some examples of using debug variants: - - utils/build-script --release-debuginfo --debug-swift # Swift frontend built in debug - utils/build-script --release-debuginfo --debug-swift-stdlib # Standard library built in debug - utils/build-script --release-debuginfo --debug-swift --force-optimized-typechecker # Swift frontend sans type checker built in debug - -Limiting the amount of debug code in the compiler has a very large impact on -Swift compile times, and in turn the test execution time. If you want to build -the entire project in debug, you can run: - - utils/build-script --debug - -For documentation of all available arguments, as well as additional usage -information, see the inline help: - - utils/build-script -h - -#### Xcode - -To build using Xcode, specify the `--xcode` argument on any of the above commands. -Xcode can be used to edit the Swift source code, but it is not currently -fully supported as a build environment for SDKs other than macOS. The generated -Xcode project does not integrate with the test runner, but the tests can be run -with the 'check-swift' target. - -#### Build Products - -All of the build products are placed in `swift-source/build/${TOOL}-${MODE}/${PRODUCT}-${PLATFORM}/`. -If macOS Swift with Ninja in DebugAssert mode was built, all of the products -would be in `swift-source/build/Ninja-DebugAssert/swift-macosx-x86_64/`. It -helps to save this directory as an environment variable for future use. - - export SWIFT_BUILD_DIR="~/swift-source/build/Ninja-DebugAssert/swift-macosx-x86_64" - -#### Ninja - -Once the first build has completed, Ninja can perform fast incremental builds of -various products. These incremental builds are a big timesaver when developing -and debugging. - - cd ${SWIFT_BUILD_DIR} - ninja swift-frontend - -This will build the Swift compiler, but will not rebuild the standard library or -any other target. Building the `swift-stdlib` target as an additional layer of -testing from time to time is also a good idea. To build just the standard -library, run: - - ninja swift-stdlib - -It is always a good idea to do a full build after using `update-checkout`. - -#### Using Xcode - -To open the Swift project in Xcode, open `${SWIFT_BUILD_DIR}/Swift.xcodeproj`. -It will auto-create a *lot* of schemes for all of the available targets. A -common debug flow would involve: - - - Select the 'swift-frontend' scheme. - - Pull up the scheme editor (⌘⇧<). - - Select the 'Arguments' tab and click the '+'. - - Add the command line options. - - Close the scheme editor. - - Build and run. - -Another option is to change the scheme to "Wait for executable to be launched", -then run the build product in Terminal. +[Getting Started guide]: /docs/HowToGuides/GettingStarted.md ### Swift Toolchains @@ -335,7 +139,12 @@ compiler crashes. ### Build Failures -Make sure you are using the [correct release](#macos) of Xcode. +Try the suggestions in +[Troubleshooting build issues](/docs/HowToGuides/GettingStarted.md#troubleshooting-build-issues). + +Make sure you are using the +[correct release](/docs/HowToGuides/GettingStared.md#installing-dependencies) +of Xcode. If you have changed Xcode versions but still encounter errors that appear to be related to the Xcode version, try passing `--clean` to `build-script`. @@ -343,18 +152,11 @@ be related to the Xcode version, try passing `--clean` to `build-script`. When a new version of Xcode is released, you can update your build without recompiling the entire project by passing the `--reconfigure` option. -Make sure all repositories are up to date with the `update-checkout` command -described above. - -## Testing Swift - -See [docs/Testing.md](docs/Testing.md), in particular the section on [lit.py](docs/Testing.md#using-litpy). - ## Learning More -Be sure to look through the [docs](https://github.com/apple/swift/tree/master/docs) -directory for more information about the compiler. In particular, the documents -titled [Debugging the Swift Compiler](docs/DebuggingTheCompiler.md) and +Be sure to look at the [documentation index](/docs/README.md) for a bird's eye +view of the available documentation. In particular, the documents titled +[Debugging the Swift Compiler](docs/DebuggingTheCompiler.md) and [Continuous Integration for Swift](docs/ContinuousIntegration.md) are very helpful to understand before submitting your first PR. @@ -378,41 +180,3 @@ Another source of documentation is the standard library itself, located in `stdlib`. Much of the language is actually implemented in the library (including `Int`), and the standard library gives some examples of what can be expressed today. - -## Build Dependencies - -### CMake -[CMake](https://cmake.org) is the core infrastructure used to configure builds of -Swift and its companion projects; at least version 3.16.5 is required. - -On macOS, you can download the [CMake Binary Distribution](https://cmake.org/download), -bundled as an application, copy it to `/Applications`, and add the embedded -command line tools to your `PATH`: - - export PATH=/Applications/CMake.app/Contents/bin:$PATH - -On Linux, if you have not already installed Swift's [development -dependencies](#linux), you can download and install the CMake -package separately using the following command: - - sudo apt-get install cmake - - -### Ninja -[Ninja](https://ninja-build.org) is the current recommended build system -for building Swift and is the default configuration generated by CMake. [Pre-built -packages](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) -are available for macOS and Linux distributions. You can also clone Ninja -next to the other projects and it will be bootstrapped automatically: - -**Via HTTPS** - - git clone https://github.com/ninja-build/ninja.git && cd ninja - git checkout release - cat README - -**Via SSH** - - git clone git@github.com:ninja-build/ninja.git && cd ninja - git checkout release - cat README diff --git a/docs/GitHubCreatePRScreenshot.png b/docs/GitHubCreatePRScreenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e98f4c00aa7a7b81a4e5b45253cb24d3f8073f16 GIT binary patch literal 63140 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 H+}VEtV0W$? literal 0 HcmV?d00001 diff --git a/docs/HowToGuides/FAQ.md b/docs/HowToGuides/FAQ.md new file mode 100644 index 0000000000000..f4c5002cb01fb --- /dev/null +++ b/docs/HowToGuides/FAQ.md @@ -0,0 +1,101 @@ +# Frequently Asked Questions + +## Build System and CMake Configuration + +### How do I add a new file to CMake? + +If you forget to add a new file to the CMake configuration, you may end up with +undefined symbol errors at link time. + +There should be a `CMakeLists.txt` in the directory where you added the new +file, which has the list of different .h/.cpp files to be included in the build. +Add your new file to that list. + +### How do I speed up iterating on changes to the build system? + +The general idea is to build as little as you can. +- [Use `sccache`](/docs/HowToGuides/GettingStarted.md) or `ccache` if you + aren't doing so already. +- Use `build-script`'s various `--skip-*` flags to skip configuring for + platforms that you do not care about. +- If you're on macOS, use `--swift-darwin-supported-archs="x86_64"`. +- Use a release build without assertions (`--release --no-assertions`). + While debuginfo and assertions are valuable to enable when working on the + toolchain itself, they are not so useful if you are working only on changes + to the build system. + +## Using a Locally Built Toolchain + +### How do I use a locally built compiler to build X? + +You can use the `SWIFT_EXEC` environment variable to use a locally +built compiler to compile both packages and Xcode projects. + +1. For SwiftPM packages, pass the environment variable when invoking SwiftPM. + ```sh + # Assuming the current working directory contains the package, build the + # package using a custom compiler. + SWIFT_EXEC=/path/to/swiftc swift build + ``` +2. For Xcode projects, select the project in the Project Navigator. In the + Build Settings tab, click '+' and then 'Add User-Defined Setting'. + Create a build setting `SWIFT_EXEC` with the value set to `/path/to/swiftc`. + If you now do a clean build, your locally built compiler will be used. + + At the time of writing, in the latest Xcode 12 beta, `SWIFT_EXEC` does not + work for SwiftPM integration inside Xcode, so this will not work for Xcode + projects that depend on SwiftPM packages. + +**Note:** Even thought the variable says 'SWIFT', it needs to point to +'swift**c**', not 'swift'. The extra 'c' is not a typo. + +## Testing and CI + +### How do I reproduce/fix a test that fails in CI but passes for me locally? + +TODO: Write some tips here, point to Testing.md for simulator setup. + +## Documentation + +### Where can I find documentation on X? + +This very depends on what X is, but some broad guidelines are: + +1. Do a case-insensitive recursive string search. + - Use a specialized tool like [ripgrep](https://github.com/BurntSushi/ripgrep) + or [ag](https://github.com/ggreer/the_silver_searcher). + - Use 'Find in Workspace' in Xcode (++F). + - Use `grep -i -r "mypattern" .`. +2. Go through the [Documentation Index](/docs/README.md). + +## Pull Request Workflow + +### How do I format my changes? + +First, install `clang-format` using your system's package manager. This should +also install the `git-clang-format` script (try `git-clang-format --help`). +In case it doesn't, you can replace `git-clang-format` in the following +commands with `../llvm-project/clang/tools/clang-format/git-clang-format`. + +Start out at the tip of the branch where you want to reformat the commits. + +``` +# If there is only one commit that needs to be reformatted. +git-clang-format HEAD~1 +git add . +git commit --amend --no-edit + +# Say the last N commits need to be reformatted. +# Mark them as 'edit' instead of 'pick'. +git rebase -i HEAD~N +# Re-run N times, reformatting each commit. +git-clang-format HEAD~1 +git add . +git commit --amend --no-edit +git rebase --continue +``` + +### How do I clean up my git history? + +TODO: Link to a beginner-friendly external resource, or (less preferably) +describe basic usage of rebase here. diff --git a/docs/HowToGuides/FirstPullRequest.md b/docs/HowToGuides/FirstPullRequest.md new file mode 100644 index 0000000000000..ea7d5232aab72 --- /dev/null +++ b/docs/HowToGuides/FirstPullRequest.md @@ -0,0 +1,179 @@ +# How to Submit Your First Pull Request + +So you've decided to contribute to the Swift toolchain, welcome! +Maybe this is your first time contributing to an open source project, or maybe +you are an experienced open source contributor who is excited about Swift, or +maybe you are somewhere in-between. Regardless of your background, we are +excited to have you contribute and improve the developer experience for Swift +programmers all over the globe. +:sparkles::child::student::woman_technologist::technologist::man_technologist::sparkles: + +This document provides a high-level overview of different parts of the +contribution process. + +## How do I pick something to work on? + +In case you don't have something specific you'd like to work on, such as +implementing something for a Swift Evolution pitch, you could start off by +working on a bug labeled `StarterBug` on [Swift JIRA][StarterBug]. If the +bug hasn't been assigned to someone, check the comments in case someone has +already started working on it. If not, feel free to assign it to yourself and +start working on it! + +[StarterBug]: https://bugs.swift.org/issues/?jql=labels%20%3D%20StarterBug%20AND%20(status%20%3D%20Open%20OR%20status%20%3D%20Reopened)%20AND%20project%20%3D%20Swift + +## Getting Help + +Usually, Starter Bugs try to provide some instructions to help you get started. +In case those are missing, please ask the bug reporter for more detailed steps +and they will be happy to help. + +Once you start working on the bug, you will inevitably end up having a lot of +questions. Don't be afraid to ask for help! The codebase is large and wrapping +your head around it will take time. For example, you might have questions like: + +- Where can I find documentation on X? +- I'm seeing a cryptic error E when trying to build the compiler. How do I fix + it or work around it? +- I'm seeing very long build times even for incremental builds. How do I speed + up iteration time? +- I'm not sure how to implement X. Any suggestions on where I should start? +- What is the difference between types T1 and T2? They look very similar. +- Should I split my new X into a separate file? +- Should I create a new test file or update an existing test? +- How should I test that I actually fixed this bug? +- Test X is failing and I can't understand why. What might be going wrong here? +- Test X is failing in CI but passing locally. Any tips for debugging? +- I made some change but that seems to be not getting picked up. What should + I do to fix it? +- I need to update the CMake but I'm not familiar with CMake. Could you give me + more guidance? +- How do I do X in git? + +Some of these already have answers in our [FAQ](/docs/HowToGuides/FAQ.md). +Maybe you have a question that's not on this list. That's fine. +We're here to help. There are a couple of options to ask for help: + +- [Development category on the Swift forums](https://forums.swift.org/c/development): + Prefer using the forums for broad questions, such as those related to + building the toolchain, or understanding how something works at a high-level. + Since more people are likely to see and be able to answer your question, the + question is likely to get an answer sooner. Another benefit of asking in + public is that the answers you receive will be helpful to bystanders too. +- Bug report/Pull request comments: Prefer asking in the bug report/pull request + when the question involves additional context specific to the + bug report/pull request. + +These are suggestions, not rules. For example, it's okay if you ask a broad +question in a bug report or a pull request. + +When asking for help, prefer giving as much information as possible, while +highlighting the parts that you think are important. + +Remember that the [Swift Code of Conduct][] applies whenever you are +participating in the Swift project. + +[Swift Code of Conduct]: https://swift.org/community/#code-of-conduct + +### I didn't get a response from someone. What should I do? + +It's possible that you ask someone a question in a bug report/pull request and +you don't get a response as quickly as you'd like. Maybe they are juggling +several tasks and the discussion with you accidentally slipped by. Maybe they +are on vacation or on leave for some reason. If you don't get a response +within a week, it's okay to politely ping them using an `@` mention with a +reminder. If you don't get a response for 2-3 weeks in a row, please ping +someone else. + +## Working on a change + +Please see our [Getting Started guide][] to understand how to build the code, +make changes, run tests and debug issues. + +[Getting Started guide]: /docs/HowToGuides/GettingStarted.md + +## Submitting a pull request + +### Tidying up + +Alright! You've implemented a change and would like to submit it. +Double-check that you've tidied your Git history, such as squashing +work-in-progress commits, and that your commit messages provide context. +For example, if a commit fixes a bug, then include a "Fixes SR-NNNNN" with the +bug number in the commit message. + +Next, [format your changes](/docs/HowToGuides/FAQ.md#how-do-i-format-my-changes) +using `clang-format`. + +### Pushing and creating a pull request + +Assuming you followed the steps in our [Getting Started guide][], you should now +be able to push your latest changes to GitHub using `git push`. + +Next, [create a pull request][] (PR). Usually, if you navigate to +https://github.com/apple/swift right after pushing your change, GitHub will +show a helpful "Compare & Pull Request" button. + +![Compare & Pull Request button in GitHub UI](/docs/GitHubCreatePRScreenshot.png) + +[create a pull request]: https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request#creating-the-pull-request + +## Asking for code review + +If you had an active discussion with someone on how to implement your change, +you can `@` mention them in the PR description and ask for code review. +If you directly implemented the change without any guidance from anyone else, +`@` mention someone from GitHub's suggested reviewers. If GitHub doesn't +make any suggestions, ask the [Code Owner](/CODE_OWNERS.txt) based on the +component for your change. Please ask someone though! We don't want you to get +stuck because you were not sure who to ask for code review. + +At the beginning, contributors are not able to run the continuous integration +(CI) bot, which builds the project and runs tests. Please ask your code +reviewer(s) to invoke the bot for you. + +## Responding to code review comments + +During the process of code review, someone might suggest changes or have +questions about the implementation. If something is unclear, such as someone +using a technical term you don't recognize, check our +[Lexicon](/docs/Lexicon.md) or ask someone instead of trying to figure out +everything by yourself. Code review does not need to be a one-way +street. It is also a good opportunity for you to ask highly contextual +questions on topics that you struggled with or were unable to understand. + +While making changes based on code review, if you are comfortable with +rebasing, prefer rebasing and force-pushing for small patches (say < 100 lines). +For larger patches, you can add fixup commits (`git commit --fixup ...`) +addressing the suggestions and rebase after it the patch has been approved +to clean up the history. + +When you push again and want the tests to be re-run, please ask the reviewer +to invoke `swift-ci` for you. + +At the end, once the tests are passing, the pull request is approved by +the reviewer, and you are satisfied with your changes, ask your reviewer +to merge your changes. :tada: + +## I can't finish the contribution I started. :frowning_face: + +That's totally okay! There is no shame in that. You only have limited time and +energy in a day. If you can, leave a comment on the bug report/pull request +that you will not be able to continue and unassign yourself from the bug on +JIRA. Don't worry about trying to explain _why_ you aren't able to contribute +further. We understand. Unanticipated things come up all the time and you +should do what _works for you_. + +This point also applies if you don't have time right now but hope to get to +something in the near future. Please don't feel sad or apologetic! + +## I submitted and merged my first pull request. What now? + +Awesome! You could try fixing a few more Starter Bugs until you feel some +level of comfort working with the codebase. You could also start looking at +other bugs which interest you and you think you might be able to tackle. +Don't forget to ask for help if you need directions or you get stuck! + +Once you've made multiple substantial contributions, you can +[ask for commit access](https://swift.org/contributing/#commit-access), +which will allow you to pick reviewers, trigger the CI bot and merge changes. diff --git a/docs/HowToGuides/GettingStarted.md b/docs/HowToGuides/GettingStarted.md new file mode 100644 index 0000000000000..bda3f2a11ea06 --- /dev/null +++ b/docs/HowToGuides/GettingStarted.md @@ -0,0 +1,609 @@ +# How to Set Up an Edit-Build-Test-Debug Loop + +This document describes how to set up a development loop for people interested +in contributing to Swift. + +If you are only interested in building the +toolchain as a one-off, there are a couple of differences: +1. You can ignore the parts related to Sccache. +2. You can stop reading after + [Building the project for the first time](#building-the-project-for-the-first-time). + +## Table of Contents + +- [System Requirements](#system-requirements) +- [Cloning the project](#cloning-the-project) + - [Troubleshooting cloning issues](#troubleshooting-cloning-issues) +- [Installing dependencies](#installing-dependencies) + - [macOS](#macOS) + - [Ubuntu Linux](#ubuntu-linux) +- [Building the project for the first time](#building-the-project-for-the-first-time) + - [Spot check dependencies](#spot-check-dependencies) + - [Understanding the pieces](#understanding-the-pieces) + - [The actual build](#the-actual-build) + - [Troubleshooting build issues](#troubleshooting-build-issues) +- [Editing code](#editing-code) + - [Setting up your fork](#setting-up-your-fork) + - [First time Xcode setup](#first-time-xcode-setup) + - [Editing](#editing) + - [Incremental builds with Ninja](#incremental-builds-with-ninja) + - [Incremental builds with Xcode](#incremental-builds-with-xcode) + - [Spot checking an incremental build](#spot-checking-an-incremental-build) +- [Reproducing an issue](#reproducing-an-issue) +- [Running tests](#running-tests) +- [Debugging issues](#debugging-issues) + - [Print debugging](#print-debugging) + - [Debugging using LLDB](#debugging-using-lldb) +- [Next steps](#next-steps) + +## System Requirements + +1. Operating system: + The supported operating systems for developing the Swift toolchain are: + macOS, Ubuntu Linux LTS, and the latest Ubuntu Linux release. + At the moment, Windows is not supported as a host development operating + system. Experimental instructions for Windows are available under + [Windows.md](/docs/Windows.md). +2. Python 3: Several utility scripts are written in Python. +3. Disk space: + Make sure that you have enough available disk space before starting. + The source code, including full git history, requires about 3.5 GB. + Build artifacts take anywhere between 5 GB to 70 GB, depending on the + build settings. +4. Time: + Depending on your machine and build settings, + a from-scratch build can take a few minutes to several hours, + so you might want to grab a beverage while you follow the instructions. + Incremental builds are much faster. + +## Cloning the project + +1. Create a directory for the whole project: + ```sh + mkdir -p swift-project/swift + cd swift-project/swift + ``` +2. Clone the sources: + - Via SSH (recommended): + If you plan on contributing regularly, cloning over SSH provides a better + experience. After you've [uploaded your SSH keys to GitHub][]: + ```sh + git clone git@github.com:apple/swift.git . + utils/update-checkout --clone-with-ssh + ``` + - Via HTTPS: + If you want to check out the sources as read-only, + or are not familiar with setting up SSH, + you can use HTTPS instead: + ```sh + git clone https://github.com/apple/swift.git . + utils/update-checkout --clone + ``` + **Note:** If you've already forked the project on GitHub at this stage, + **do not clone your fork** to start off. We describe + [how to setup your fork](#setting-up-your-fork) in a subsection below. + +3. Double-check that `swift`'s sibling directories are present. + ```sh + ls .. + ``` + This should list directories like `llvm-project`, `swiftpm` and so on. +4. Checkout the right branch/tag: + If you are building the toolchain for local development, you can skip this + step, as Step 2 will checkout `swift`'s `master` branch and matching + branches for other projects. + If you are building the toolchain as a one-off, it is more likely that you + want a specific branch or a tag, often corresponding to a specific release + or a specific snapshot. You can update the branch/tag for all repositories + as follows: + ```sh + utils/update-checkout --branch mybranchname + # OR + utils/update-checkout --tag mytagname + ``` + Detailed branching information, including names for release branches, can + be found in [Branches.md](/docs/Branches.md). + +**Note:** +The commands used in the rest of this guide assumes that the absolute path +to your working directory is something like `/path/to/swift-project/swift`. +Double-check that running `pwd` prints a path ending with `swift`. + +[uploaded your SSH keys to GitHub]: https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/ + +### Troubleshooting cloning issues + +- If `update-checkout` failed, double-check that the absolute path to your + working directory does not have non-ASCII characters. +- If `update-checkout` failed and the absolute path to your working directory + had spaces in it, please [file a bug report][Swift JIRA] and change the path + to work around it. +- Before running `update-checkout`, double-check that `swift` is the only + repository inside the `swift-project` directory. Otherwise, + `update-checkout` may not clone the necessary dependencies. + +## Installing dependencies + +### macOS + +1. Install [Xcode 12 beta 3][Xcode] or newer: + The required version of Xcode changes frequently and is often a beta release. + Check this document or the host information on for the + current required version. +2. Install [CMake][], [Ninja][] and [Sccache][]: + - Via [Homebrew][] (recommended): + ```sh + brew install cmake ninja sccache + ``` + - Via [Homebrew Bundle][]: + ```sh + brew bundle + ``` + +[Xcode]: https://developer.apple.com/xcode/resources/ +[CMake]: https://cmake.org +[Ninja]: https://ninja-build.org +[Sccache]: https://github.com/mozilla/sccache +[Homebrew]: https://brew.sh/ +[Homebrew Bundle]: https://github.com/Homebrew/homebrew-bundle + +### Ubuntu Linux + +1. For Ubuntu 16.04 LTS and 18.04 LTS, run the following: + + ```sh + sudo apt-get install \ + clang \ + cmake \ + git \ + icu-devtools \ + libcurl4-openssl-dev \ + libedit-dev \ + libicu-dev \ + libncurses5-dev \ + libpython3-dev \ + libsqlite3-dev \ + libxml2-dev \ + ninja-build \ + pkg-config \ + python \ + python-six \ + rsync \ + swig \ + systemtap-sdt-dev \ + tzdata \ + uuid-dev + sudo snap install sccache --candidate --classic + ``` + + **Note:** LLDB currently requires at least `swig-1.3.40` but will + successfully build with version 2 shipped with Ubuntu. + +## Building the project for the first time + +### Spot check dependencies + +* Run `cmake --version`: This should be 3.18.1 or higher for macOS. +* Run `python3 --version`: Check that this succeeds. +* Run `ninja --version`: Check that this succeeds. +* Run `sccache --version`: Check that this succeeds. + +### The roles of different tools + +At this point, it is worthwhile to pause for a moment +to understand what the different tools do: + +1. On macOS and Windows, IDEs (Xcode and Visual Studio resp.) serve as an + easy way to install development dependencies such as a C++ compiler, + a linker, header files, etc. The IDE's build system need not be used to + build Swift. On Linux, these dependencies are installed by the + distribution's package manager. +2. CMake is a cross-platform build system for C and C++. + It forms the core infrastructure used to _configure_ builds of + Swift and its companion projects. +3. Ninja is a low-level build system that can be used to _build_ the project, + as an alternative to Xcode's build system. Ninja is somewhat faster, + especially for incremental builds, and supports more build environments. +4. Sccache is a caching tool: + If you ever delete your build directory and rebuild from scratch + (i.e. do a "clean build"), Sccache can accelerate the new build + significantly. There are few things more satisfying than seeing Sccache + cut through build times. +5. `utils/update-checkout` is a script to help you work with all the individual + git repositories together, instead of manually cloning/updating each one. +6. `utils/build-script` (we will introduce this shortly) + is a high-level automation script that handles configuration (via CMake), + building (via Ninja or Xcode), caching (via Sccache), running tests and more. + +> **Pro Tip**: Most tools support `--help` flags describing the options they +> support. Additionally, both Clang and the Swift compiler have hidden flags +> (`clang --help-hidden`/`swiftc --help-hidden`) and frontend flags +> (`clang -cc1 --help`/`swiftc -frontend --help`) and the Swift compiler +> even has hidden frontend flags (`swiftc -frontend --help-hidden`). Sneaky! + +Phew, that's a lot to digest! Now let's proceed to the actual build itself! + +### The actual build + +1. Make sure you have Sccache running. + ```sh + sccache --start-server + ``` + (Optional) Sccache defaults to a cache size of 10GB, which is relatively + small compared to build artifacts. You can bump it up, say by setting + `export SCCACHE_CACHE_SIZE="50G"` in your dotfile(s). For more details, + see the [Sccache README][Sccache]. +2. Decide if you would like to build the toolchain using Ninja or using Xcode. + - If you use an editor other than Xcode and/or you want somewhat faster builds, + go with Ninja. + - If you are comfortable with using Xcode and would prefer to use it, + go with Xcode. + There is also a third option, which is somewhat more involved: + [using both Ninja and Xcode](#using-both-ninja-and-xcode). +3. Build the toolchain with optimizations, debuginfo, and assertions and run + the tests. + - Via Ninja: + ```sh + utils/build-script --skip-build-benchmarks \ + --skip-ios --skip-watchos --skip-tvos --swift-darwin-supported-archs "x86_64" \ + --cmake-c-launcher="$(which sccache)" --cmake-cxx-launcher="$(which sccache)" \ + --release-debuginfo --test + ``` + - Via Xcode: + ```sh + utils/build-script --skip-build-benchmarks \ + --skip-ios --skip-watchos --skip-tvos --swift-darwin-supported-archs "x86_64" \ + --cmake-c-launcher="$(which sccache)" --cmake-cxx-launcher="$(which sccache)" \ + --release-debuginfo --test \ + --xcode + ``` + This will create a directory + `swift-project/build/Ninja-RelWithDebInfoAssert` + (with `Xcode` instead of `Ninja` if you used `--xcode`) + containing the build artifacts. + - If the build succeeds: Once the build is complete, the tests will run. + - If the tests are passing: Great! We can go to the next step. + - If some tests are failing: + - Consider [filing a bug report](https://swift.org/contributing/#reporting-bugs). + - Note down which tests are failing as a baseline. This baseline will be + handy later when you run the tests after making a change. + - If the build fails: + See [Troubleshooting build issues](#troubleshooting-build-issues). + +In the following sections, for simplicity, we will assume that you are using a +`Ninja-RelWithDebInfoAssert` build on macOS running on an Intel-based Mac, +unless explicitly mentioned otherwise. You will need to slightly tweak the paths +for other build configurations. + +#### Using both Ninja and Xcode + +Some contributors find it more convenient to use both Ninja and Xcode. +Typically this configuration consists of: + +1. A Ninja build created with `--release-debuginfo`. +2. An Xcode build created with `--release-debuginfo --debug-swift`. + +The Ninja build can be used for fast incremental compilation and running tests +quickly. The Xcode build can be used for debugging with high fidelity. + +The additional flexibility comes with two issues: (1) consuming much more disk +space and (2) you need to maintain the two builds in sync, which needs extra +care when moving across branches. + +### Troubleshooting build issues + +- Double-check that all projects are checked out at the right branches. + A common failure mode is using `git checkout` to change the branch only + for `swift` (often to a release branch), leading to an unsupported + configuration. See Step 4 of [Cloning the Project](#cloning-the-project) + on how to fix this. +- Double-check that all your dependencies + [meet the minimum required versions](#spot-check-dependencies). +- Check if there are spaces in the paths being used by `build-script` in + the log. While `build-script` should work with paths containing spaces, + sometimes bugs do slip through, such as + [SR-13441](https://bugs.swift.org/browse/SR-13441). + If this is the case, please [file a bug report][Swift JIRA] and change the path + to work around it. +- Check that your `build-script` invocation doesn't have typos. You can compare + the flags you passed against the supported flags listed by + `utils/build-script --help`. +- Check the error logs and see if there is something you can fix. + In many situations, there are several errors, so scrolling further back + and looking at the first error may be more helpful than simply looking + at the last error. +- Check if others have encountered the same issue on the Swift forums or on + [Swift JIRA][]. +- Create a new Swift forums thread in the Development category. Include + information about your configuration and the errors you are seeing. + - You can [create a gist](https://gist.github.com) with the entire build + output and link it, while highlighting the most important part of the + build log in the post. + - Include the output of `utils/update-checkout --dump-hashes`. + +[Swift JIRA]: https://bugs.swift.org + +## Editing code + +### Setting up your fork + +If you are building the toolchain for development and submitting patches, +you will need to setup a GitHub fork. + +First fork the `apple/swift` [repository](https://github.com/apple/swift.git), +using the "Fork" button in the web UI, near the top-right. This will create a +repository `username/swift` for your GitHub username. Next, add it as a remote: +```sh +# Using 'my-remote' as a placeholder name. + +# If you set up SSH in step 2 +git remote add my-remote git@github.com:username/swift.git + +# If you used HTTPS in step 2 +git remote add my-remote https://github.com/username/swift.git +``` +Finally, create a new branch. +```sh +# Using 'my-branch' as a placeholder name +git checkout my-branch +git push --set-upstream my-remote my-branch +``` + +### First time Xcode setup + +If you used `--xcode` earlier, you will see an Xcode project generated under +`../build/Xcode-RelWithDebInfoAssert/swift-macosx-x86_64`. When you open the +project, Xcode might helpfully suggest "Automatically Create Schemes". Most of +those schemes are not required in day-to-day work, so you can instead manually +select the following schemes: +- `swift-frontend`: If you will be working on the compiler. +- `check-swift-all`: This can be used to run the tests. The test runner does + not integrate with Xcode though, so it may be easier to run tests directly + on the commandline for more fine-grained control over which exact tests are + run. + + +### Editing + +Make changes to the code as appropriate. Implement a shiny new feature! +Or fix a nasty bug! Update the documentation as you go! +The codebase is your oyster! + +:construction::construction_worker::building_construction: + +Now that you have made some changes, you will need to rebuild... + +### Incremental rebuilds with Ninja + +To rebuild the compiler: +```sh +ninja -C ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64 swift-frontend +``` + +To rebuild everything, including the standard library: +```sh +ninja -C ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64 +``` + +### Incremental builds with Xcode + +Rebuilding works the same way as with any other Xcode project; you can use ++B or Product → Build. + +### Spot checking an incremental build + +As a quick test, go to `lib/Basic/Version.cpp` and tweak the version +printing code slightly. Next, do an incremental build as above. This incremental +build should be much faster than the from-scratch build at the beginning. +Now check if the version string has been updated: + +```sh +../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/bin/swift-frontend --version +``` + +This should print your updated version string. + +## Reproducing an issue + +Starter bugs typically have small code examples that fit within a single file. +You can reproduce such an issue in various ways, such as compiling it from the +commandline using `/path/to/swiftc MyFile.swift`, pasting the code into +[Compiler Explorer][] (aka godbolt) or using an Xcode Playground. + +[Compiler Explorer]: https://godbolt.org + +For files using frameworks from an SDK bundled with Xcode, you need the pass +the SDK explicitly. Here are a couple of examples: +```sh +# Compile a file to an executable for your local machine. +xcrun -sdk macosx /path/to/swiftc MyFile.swift + +# Say you are trying to compile a file importing an iOS-only framework. +xcrun -sdk iphoneos /path/to/swiftc -target arm64-apple-ios13.0 MyFile.swift +``` +You can see the full list of `-sdk` options using `xcodebuild -showsdks`, +and check some potential `-target` options for different operating systems by +skimming the compiler's test suite under `test/`. + +Sometimes bug reports come with SwiftPM packages or Xcode projects as minimal +reproducers. While we do not add packages or projects to the compiler's test +suite, it is generally helpful to first reproduce the issue in context before +trying to create a minimal self-contained test case. If that's the case with +the bug you're working on, check out our +[instructions on building packages and Xcode projects with a locally built compiler](/docs/HowToGuides/FAQ.md#how-do-i-use-a-locally-built-compiler-to-build-x). + +## Running tests + +There are two main ways to run tests: + +1. `utils/run-test`: By default, `run-test` builds the tests' dependencies + before running them. + ```sh + # Rebuild all test dependencies and run all tests under test/. + utils/run-test --lit ../llvm-project/llvm/utils/lit/lit.py \ + ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64 + + # Rebuild all test dependencies and run tests containing "MyTest". + utils/run-test --lit ../llvm-project/llvm/utils/lit/lit.py \ + ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64 \ + --filter="MyTest" + ``` +2. `lit.py`: lit doesn't know anything about dependencies. It just runs tests. + ```sh + # Run all tests under test/. + ../llvm-project/llvm/utils/lit/lit.py -s -vv \ + ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64 + + # Run tests containing "MyTest" + ../llvm-project/llvm/utils/lit/lit.py -s -vv \ + ../build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/test-macosx-x86_64 \ + --filter="MyTest" + ``` + The `-s` and `-vv` flags print a progress bar and the executed commands + respectively. + +If you making small changes to the compiler or some other component, you'll +likely want to [incrementally rebuild](#editing-code) only the relevant +Ninja/Xcode target and use `lit.py` with `--filter`. One potential failure +mode with this approach is accidental use of stale binaries. For example, say +that you want to rerun a SourceKit test but you only incrementally rebuilt the +compiler. Then your changes will not be reflected when the test runs because the +`sourcekitd` binary was not rebuilt. Using `run-test` instead is the safer +option, but it will lead to a longer feedback loop due to more things getting +rebuilt. + +If you want to rerun all the tests, you can either rebuild the whole project +and use `lit.py` without `--filter` or use `run-test` to handle both aspects. + +Recall the baseline failures mentioned in +[the build section](#the-actual-build). If your baseline had failing tests, make +sure you compare the failures seen after your changes to the baseline. If some +test failures look totally unrelated to your changes, there is a good chance +that they were already failing as part of the baseline. + +For more details on running tests and understanding the various Swift-specific +lit customizations, see [Testing.md](/docs/Testing.md). Also check out the +[lit documentation](https://llvm.org/docs/CommandGuide/lit.html) to understand +how the different lit commands work. + +## Debugging issues + +In this section, we briefly describe two common ways of debugging: print +debugging and using LLDB. + +Depending on the code you're interested in, LLDB may be significantly more +effective when using a debug build. Depending on what components you are +working on, you could turn off optimizations for only a few things. +Here are some example invocations: + +```sh +# optimized Stdlib + debug Swiftc + optimized Clang/LLVM +utils/build-script --release-debuginfo --debug-swift # other flags... + +# debug Stdlib + optimized Swiftc + optimized Clang/LLVM +utils/build-script --release-debuginfo --debug-swift-stdlib # other flags... + +# optimized Stdlib + debug Swiftc (expect typechecker) + optimized Clang/LLVM +utils/build-script --release-debuginfo --debug-swift --force-optimized-typechecker + +# Last resort option, it is highly unlikely that you will need this +# debug Stdlib + debug Swiftc + debug Clang/LLVM +utils/build-script --debug # other flags... +``` + +Debug builds have two major drawbacks: +- A debug compiler is much slower, leading to longer feedback loops in case you + need to repeatedly compile the Swift standard library and/or run a large + number of tests. +- The build artifacts consume a lot more disk space. + +[DebuggingTheCompiler.md](/docs/DebuggingTheCompiler.md) goes into a LOT +more detail on how you can level up your debugging skills! Make sure you check +it out in case you're trying to debug a tricky issue and aren't sure how to +go about it. + +### Print debugging + +A large number of types have `dump(..)`/`print(..)` methods which can be used +along with `llvm::errs()` or other LLVM streams. For example, if you have a +variable `std::vector canTypes` that you want to print, you could do: +```cpp +auto &e = llvm::errs(); +e << "canTypes = ["; +llvm::interleaveComma(canTypes, e, [&](auto ty) { ty.dump(e); }); +e << "]\n"; +``` +You can also crash the compiler using `assert`/`llvm_unreachable`/ +`llvm::report_fatal_error`, after accumulating the result in a stream: +```cpp +std::string msg; llvm::raw_string_ostream os(msg); +os << "unexpected canTypes = ["; +llvm::interleaveComma(canTypes, os, [&](auto ty) { ty.dump(os); }); +os << "] !!!\n"; +llvm::report_fatal_error(os.str()); +``` + +### Debugging using LLDB + +When the compiler crashes, the commandline arguments passed to it will be +printed to stderr. It will likely look something like: + +``` +/path/to/swift-frontend +``` + +- Using LLDB on the commandline: Copy the entire invocation and pass it to LLDB. + ```sh + lldb -- /path/to/swift-frontend + ``` + Now you can use the usual LLDB commands like `run`, `breakpoint set` and so + on. If you are new to LLDB, check out the [official LLDB documentation][] and + [nesono's LLDB cheat sheet][]. +- Using LLDB within Xcode: + Select the current scheme 'swift-frontend' → Edit Scheme → Run phase → + Arguments tab. Under "Arguments Passed on Launch", copy-paste the `` + and make sure that "Expand Variables Based On" is set to swift-frontend. + Close the scheme editor. If you now run the compiler + (+R or Product → Run), you will be able to use the + Xcode debugger. + + Xcode also has the ability to attach to and debug Swift processes launched + elsewhere. Under Debug → Attach to Process by PID or name..., you can enter + a compiler process's PID or name (`swift-frontend`) to debug a compiler + instance invoked elsewhere. This can be helpful if you have a single compiler + process being invoked by another tool, such as SwiftPM or another open Xcode + project. + + > **Pro Tip**: Xcode 12's terminal does not support colors, so you may see + > explicit color codes printed by `dump()` methods on various types. To avoid + > color codes in dumped output, run `expr llvm::errs().enable_color(false)`. + +[official LLDB documentation]: https://lldb.llvm.org +[nesono's LLDB cheat sheet]: https://www.nesono.com/sites/default/files/lldb%20cheat%20sheet.pdf + +## Next steps + +Make sure you check out the following resources: + +* [LLVM Coding Standards](https://llvm.org/docs/CodingStandards.html): A style + guide followed by both LLVM and Swift. If there is a mismatch between the LLVM + Coding Standards and the surrounding code that you are editing, please match + the style of existing code. +* [LLVM Programmer's Manual](https://llvm.org/docs/ProgrammersManual.html): + A guide describing common programming idioms and data types used by LLVM and + Swift. +* [docs/README.md](/docs/README.md): Provides a bird's eye view of the available + documentation. +* [Lexicon.md](/docs/Lexicon.md): Provides definitions for jargon. If you run + into a term frequently that you don't recognize, it's likely that this file + has a definition for it. +* [Testing.md](/docs/Testing.md) and + [DebuggingTheCompiler.md](/docs/DebuggingTheCompiler.md): These cover more + ground on testing and debugging respectively. +* [Development Tips](/docs/DevelopmentTips.md): Tips for being more productive. + + +If you see mistakes in the documentation (including typos, not just major +errors) or identify gaps that you could potentially improve the contributing +experience, please start a discussion on the forums, submit a pull request +or file a bug report on [Swift JIRA][]. Thanks! diff --git a/docs/README.md b/docs/README.md index d5b028f34b736..0c10bb1502a94 100644 --- a/docs/README.md +++ b/docs/README.md @@ -55,6 +55,14 @@ documentation, please create a thread on the Swift forums under the ## How-To Guides +- [FAQ.md](/docs/HowToGuides/FAQ.md): + Answers "How do I do X?" for a variety of common tasks. +- [FirstPullRequest.md](/docs/HowToGuides/FirstPullRequest.md): + Describes how to submit your first pull request. This is the place to start + if you're new to the project! +- [GettingStarted.md](/docs/HowToGuides/GettingStarted.md): + Describes how to set up a working Swift development environment + for Linux and macOS, and get an edit-build-test-debug loop going. - [DebuggingTheCompiler.md](/docs/DebuggingTheCompiler.md): Describes a variety of techniques for debugging. - Building for Android: