# [Windows](#Windows)
This file describes how to install, or build, and use Julia on Windows.
For more general information about Julia, please see the [main README](https://github.com/JuliaLang/julia/blob/master/README.md) or the [documentation](https://docs.julialang.org).


## [General Information for Windows](#General-Information-for-Windows)
We highly recommend running Julia using a modern terminal application, in particular Windows Terminal, which can be installed from the [Microsoft Store](https://aka.ms/terminal).


### [Line endings](#Line-endings)
Julia uses binary-mode files exclusively. Unlike many other Windows programs, if you write `\n` to a file, you get a `\n` in the file, not some other bit pattern. This matches the behavior exhibited by other operating systems. If you have installed Git for Windows, it is suggested, but not required, that you configure your system Git to use the same convention:
```sh
git config --global core.eol lf
git config --global core.autocrlf input
```
or edit `%USERPROFILE%\.gitconfig` and add/edit the lines:
```julia
[core]
    eol = lf
    autocrlf = input
```


## [Binary distribution](#Binary-distribution)
For the binary distribution installation notes on Windows please see the instructions at <https://julialang.org/downloads/platform/#windows>. Note, however, that on all platforms [using `juliaup`](https://julialang.org/install/) is recommended over manually installing binaries.


## [Source distribution](#Source-distribution)


### [Cygwin-to-MinGW cross-compiling](#Cygwin-to-MinGW-cross-compiling)
The recommended way of compiling Julia from source on Windows is by cross compiling from [Cygwin](https://www.cygwin.com), using versions of the MinGW-w64 compilers available through Cygwin's package manager.
1.  Download and run Cygwin setup for [32 bit](https://cygwin.com/setup-x86.exe) or [64 bit](https://cygwin.com/setup-x86_64.exe). Note, that you can compile either 32 or 64 bit Julia from either 32 or 64 bit Cygwin. 64 bit Cygwin has a slightly smaller but often more up-to-date selection of packages.
    *Advanced*: you may skip steps 2-4 by running:
    ```sh
    setup-x86_64.exe -s <url> -q -P cmake,gcc-g++,git,make,patch,curl,m4,python3,p7zip,mingw64-i686-gcc-g++,mingw64-i686-gcc-fortran,mingw64-x86_64-gcc-g++,mingw64-x86_64-gcc-fortran
    ```
    replacing `<url>` with a site from <https://cygwin.com/mirrors.html> or run setup manually first and select a mirror.
2.  Select installation location and a mirror to download from.
3.  At the *Select Packages* step, select the following:
    1.  From the *Devel* category: `cmake`, `gcc-g++`, `git`, `make`, `patch`
    2.  From the *Net* category: `curl`
    3.  From *Interpreters* (or *Python*) category: `m4`, `python3`
    4.  From the *Archive* category: `p7zip`
    5.  For 32 bit Julia, and also from the *Devel* category: `mingw64-i686-gcc-g++` and `mingw64-i686-gcc-fortran`
    6.  For 64 bit Julia, and also from the *Devel* category: `mingw64-x86_64-gcc-g++` and `mingw64-x86_64-gcc-fortran`


### [Cygwin-to-MinGW cross-compiling](#Cygwin-to-MinGW-cross-compiling)
4.  Allow Cygwin installation to finish, then start from the installed shortcut *'Cygwin Terminal'*, or *'Cygwin64 Terminal'*, respectively.
5.  Build Julia and its dependencies from source:
    1.  Get the Julia sources
        ```sh
        git clone https://github.com/JuliaLang/julia.git
        cd julia
        ```
        Tip: If you get an `error: cannot fork() for fetch-pack: Resource temporarily unavailable` from git, add `alias git="env PATH=/usr/bin git"` to `~/.bashrc` and restart Cygwin.
    2.  Set the `XC_HOST` variable in `Make.user` to indicate MinGW-w64 cross compilation
        ```sh
        echo 'XC_HOST = i686-w64-mingw32' > Make.user     # for 32 bit Julia
        # or
        echo 'XC_HOST = x86_64-w64-mingw32' > Make.user   # for 64 bit Julia
        ```
    3.  Start the build
        ```sh
        make -j 4       # Adjust the number of threads (4) to match your build environment.
        make -j 4 debug # This builds julia-debug.exe
        ```
6.  Run Julia using the Julia executables directly
    ```sh
    usr/bin/julia.exe
    usr/bin/julia-debug.exe
    ```


### [Cygwin-to-MinGW cross-compiling](#Cygwin-to-MinGW-cross-compiling)
```sh
make O=julia-win32 configure
make O=julia-win64 configure
echo 'XC_HOST = i686-w64-mingw32' > julia-win32/Make.user
echo 'XC_HOST = x86_64-w64-mingw32' > julia-win64/Make.user
echo 'ifeq ($(BUILDROOT),$(JULIAHOME))
        $(error "in-tree build disabled")
      endif' >> Make.user
make -C julia-win32  # build for Windows x86 in julia-win32 folder
make -C julia-win64  # build for Windows x86-64 in julia-win64 folder
```


### [Compiling with MinGW/MSYS2](#Compiling-with-MinGW/MSYS2)
[MSYS2](https://www.msys2.org/) is a software distribution and build environment for Windows.
Note: MSYS2 requires **64 bit** Windows 7 or newer.
1.  Install and configure MSYS2.
    1.  Download and run the latest installer for the [64-bit](https://github.com/msys2/msys2-installer/releases/latest) distribution. The installer will have a name like `msys2-x86_64-yyyymmdd.exe`.
    2.  Open the MSYS2 shell. Update the package database and base packages:
        `pacman -Syu`
    3.  Exit and restart MSYS2. Update the rest of the base packages:
        `pacman -Syu`
    4.  Then install tools required to build julia:
        `pacman -S cmake diffutils git m4 make patch tar p7zip curl python`
        For 64 bit Julia, install the x86_64 version:
        `pacman -S mingw-w64-x86_64-gcc`
        For 32 bit Julia, install the i686 version:
        `pacman -S mingw-w64-i686-gcc`
    5.  Configuration of MSYS2 is complete. Now `exit` the MSYS2 shell.
2.  Build Julia and its dependencies with pre-build dependencies.
    1.  Open a new [**MINGW64/MINGW32 shell**](https://www.msys2.org/docs/environments/#overview). Currently we can't use both mingw32 and mingw64, so if you want to build the x86_64 and i686 versions, you'll need to build them in each environment separately.
    2.  Clone the Julia sources:
        `git clone https://github.com/JuliaLang/julia.git  cd julia`
    3.  Start the build
        `make -j$(nproc)`


### [Compiling with MinGW/MSYS2](#Compiling-with-MinGW/MSYS2)
```sh
make O=julia-mingw-w64 configure
echo 'ifeq ($(BUILDROOT),$(JULIAHOME))
        $(error "in-tree build disabled")
      endif' >> Make.user
make -C julia-mingw-w64
```


### [Cross-compiling from Unix (Linux/Mac/WSL)](#Cross-compiling-from-Unix-(Linux/Mac/WSL))
You can also use MinGW-w64 cross compilers to build a Windows version of Julia from Linux, Mac, or the Windows Subsystem for Linux (WSL).
First, you will need to ensure your system has the required dependencies. We need wine (>=1.7.5), a system compiler, and some downloaders. Note: a Cygwin install might interfere with this method if using WSL.
**On Ubuntu** (on other Linux systems the dependency names are likely to be similar):
```sh
apt-get install wine-stable gcc wget p7zip-full winbind mingw-w64 gfortran-mingw-w64
dpkg --add-architecture i386 && apt-get update && apt-get install wine32 # add sudo to each if needed
# switch all of the following to their "-posix" variants (interactively):
for pkg in i686-w64-mingw32-g++ i686-w64-mingw32-gcc i686-w64-mingw32-gfortran x86_64-w64-mingw32-g++ x86_64-w64-mingw32-gcc x86_64-w64-mingw32-gfortran; do
    sudo update-alternatives --config $pkg
done
```
**On Mac**: Install XCode, XCode command line tools, X11 (now [XQuartz](https://www.xquartz.org/)), and [MacPorts](https://www.macports.org/install.php) or [Homebrew](https://brew.sh/). Then run `port install wine wget mingw-w64`, or `brew install wine wget mingw-w64`, as appropriate.
**Then run the build:**
1.  `git clone https://github.com/JuliaLang/julia.git julia-win32`
2.  `cd julia-win32`
3.  `echo override XC_HOST = i686-w64-mingw32 >> Make.user`
4.  `make`
5.  `make win-extras` (Necessary before running `make binary-dist`)


### [Cross-compiling from Unix (Linux/Mac/WSL)](#Cross-compiling-from-Unix-(Linux/Mac/WSL))
6.  `make binary-dist` then `make exe` to create the Windows installer.
7.  move the `julia-*.exe` installer to the target machine
If you are building for 64-bit Windows, the steps are essentially the same. Just replace `i686` in `XC_HOST` with `x86_64`. (Note: on Mac, wine only runs in 32-bit mode).


## [Debugging a cross-compiled build under wine](#Debugging-a-cross-compiled-build-under-wine)
The most effective way to debug a cross-compiled version of Julia on the cross-compilation host is to install a Windows version of GDB and run it under wine as usual. The pre-built packages available [as part of the MSYS2 project](https://packages.msys2.org/) are known to work. Apart from the GDB package you may also need the python and termcap packages. Finally, GDB's prompt may not work when launched from the command line. This can be worked around by prepending `wineconsole` to the regular GDB invocation.


## [After compiling](#After-compiling)
Compiling using one of the options above creates a basic Julia build, but not some extra components that are included if you run the full Julia binary installer. If you need these components, the easiest way to get them is to build the installer yourself using `make win-extras` followed by `make binary-dist` and `make exe`. Then run the resulting installer.


## [Windows Build Debugging](#Windows-Build-Debugging)


### [GDB hangs with Cygwin mintty](#GDB-hangs-with-Cygwin-mintty)
-   Run GDB under the Windows console (cmd) instead. GDB [may not function properly](https://www.cygwin.com/ml/cygwin/2009-02/msg00531.html) under mintty with non- Cygwin applications. You can use `cmd /c start` to start the Windows console from mintty if necessary.


### [GDB not attaching to the right process](#GDB-not-attaching-to-the-right-process)
-   Use the PID from the Windows task manager or `WINPID` from the `ps` command instead of the PID from unix-style command line tools (e.g. `pgrep`). You may need to add the PID column if it is not shown by default in the Windows task manager.


### [GDB not showing the right backtrace](#GDB-not-showing-the-right-backtrace)
-   When attaching to the julia process, GDB may not be attaching to the right thread. Use `info threads` command to show all the threads and `thread <threadno>` to switch threads.
-   Be sure to use a 32 bit version of GDB to debug a 32 bit build of Julia, or a 64 bit version of GDB to debug a 64 bit build of Julia.


### [Build process is slow/eats memory/hangs my computer](#Build-process-is-slow/eats-memory/hangs-my-computer)
-   Disable the Windows [Superfetch](https://en.wikipedia.org/wiki/Windows_Vista_I/O_technologies#SuperFetch) and [Program Compatibility Assistant](https://blogs.msdn.com/b/cjacks/archive/2011/11/22/managing-the-windows-7-program-compatibility-assistant-pca.aspx) services, as they are known to have [spurious interactions](https://cygwin.com/ml/cygwin/2011-12/msg00058.html) with MinGW/Cygwin.
    As mentioned in the link above: excessive memory use by `svchost` specifically may be investigated in the Task Manager by clicking on the high-memory `svchost.exe` process and selecting `Go to Services`. Disable child services one-by-one until a culprit is found.
-   Beware of [BLODA](https://cygwin.com/faq/faq.html#faq.using.bloda). The [vmmap](https://technet.microsoft.com/en-us/sysinternals/dd535533.aspx) tool is indispensable for identifying such software conflicts. Use vmmap to inspect the list of loaded DLLs for bash, mintty, or another persistent process used to drive the build. Essentially *any* DLL outside of the Windows System directory is potential BLODA.
------------------------------------------------------------------------


# FreeBSD · The Julia Language
Source: https://docs.julialang.org/en/v1/devdocs/build/freebsd/


# [FreeBSD](#FreeBSD)
Clang is the default compiler on FreeBSD 11.0-RELEASE and above. The remaining build tools are available from the Ports Collection, and can be installed using `pkg install git gcc gmake cmake pkgconf`. To build Julia, simply run `gmake`. (Note that `gmake` must be used rather than `make`, since `make` on FreeBSD corresponds to the incompatible BSD Make rather than GNU Make.)
As mentioned above, it is important to note that the `USE_SYSTEM_*` flags should be used with caution on FreeBSD. This is because many system libraries, and even libraries from the Ports Collection, link to the system's `libgcc_s.so.1`, or to another library which links to the system `libgcc_s`. This library declares its GCC version to be 4.6, which is too old to build Julia, and conflicts with other libraries when linking. Thus it is highly recommended to simply allow Julia to build all of its dependencies. If you do choose to use the `USE_SYSTEM_*` flags, note that `/usr/local` is not on the compiler path by default, so you may need to add `LDFLAGS=-L/usr/local/lib` and `CPPFLAGS=-I/usr/local/include` to your `Make.user`, though doing so may interfere with other dependencies.
Note that the x86 architecture does not support threading due to lack of compiler runtime library support, so you may need to set `JULIA_THREADS=0` in your `Make.user` if you're on a 32-bit system.
------------------------------------------------------------------------


# ARM (Linux) · The Julia Language
Source: https://docs.julialang.org/en/v1/devdocs/build/arm/


# [ARM (Linux)](#ARM-(Linux))
Julia fully supports ARMv8 (AArch64) processors, and supports ARMv7 and ARMv6 (AArch32) with some caveats. This file provides general guidelines for compilation, in addition to instructions for specific devices.
A list of [known issues](https://github.com/JuliaLang/julia/labels/arm) for ARM is available. If you encounter difficulties, please create an issue including the output from `cat /proc/cpuinfo`.


## [32-bit (ARMv6, ARMv7)](#32-bit-(ARMv6,-ARMv7))
Julia has been successfully compiled on several variants of the following ARMv6 & ARMv7 devices:
-   ARMv7 / Cortex A15 Samsung Chromebooks running Ubuntu Linux under Crouton;
-   [Raspberry Pi](https://www.raspberrypi.org).
-   [Odroid](https://www.hardkernel.com).
Julia requires at least the `armv6` and `vfpv2` instruction sets. It's recommended to use `armv7-a`. `armv5` or soft float are not supported.


### [Raspberry Pi 1 / Raspberry Pi Zero](#Raspberry-Pi-1-/-Raspberry-Pi-Zero)
If the type of ARM CPU used in the Raspberry Pi is not detected by LLVM, then explicitly set the CPU target by adding the following to `Make.user`:
```julia
JULIA_CPU_TARGET=arm1176jzf-s
```
To complete the build, you may need to increase the swap file size. To do so, edit `/etc/dphys-swapfile`, changing the line:
```julia
CONF_SWAPSIZE=100
```
to:
```julia
CONF_SWAPSIZE=512
```
before restarting the swapfile service:
```julia
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start
```


### [Raspberry Pi 2](#Raspberry-Pi-2)
The type of ARM CPU used in the Raspberry Pi 2 is not detected by LLVM. Explicitly set the CPU target by adding the following to `Make.user`:
`JULIA_CPU_TARGET=cortex-a7`
Depending on the exact compiler and distribution, there might be a build failure due to unsupported inline assembly. In that case, add `MCPU=armv7-a` to `Make.user`.


## [AArch64 (ARMv8)](#AArch64-(ARMv8))
Julia is expected to work and build on ARMv8 cpus. One should follow the general [build instructions](https://github.com/JuliaLang/julia/blob/master/README.md). Julia expects to have around 8GB of ram or swap enabled to build itself.


### [Known issues](#Known-issues)
Starting from Julia v1.10, [JITLink](https://llvm.org/docs/JITLink.html) is automatically enabled on this architecture for all operating systems when linking to LLVM 15 or later versions. Due to a [bug in LLVM memory manager](https://github.com/llvm/llvm-project/issues/63236), non-trivial workloads may generate too many memory mappings that on Linux can exceed the limit of memory mappings (`mmap`) set in the file `/proc/sys/vm/max_map_count`, resulting in an error like
```julia
JIT session error: Cannot allocate memory
```
Should this happen, ask your system administrator to increase the limit of memory mappings for example with the command
```julia
sysctl -w vm.max_map_count=262144
```
------------------------------------------------------------------------


# Binary distributions · The Julia Language
Source: https://docs.julialang.org/en/v1/devdocs/build/distributing/


# [Binary distributions](#Binary-distributions)
These notes are for those wishing to compile a binary distribution of Julia for distribution on various platforms. We love users spreading Julia as far and wide as they can, trying it out on as wide an array of operating systems and hardware configurations as possible. As each platform has specific gotchas and processes that must be followed in order to create a portable, working Julia distribution, we have separated most of the notes by OS.
Note that while the code for Julia is [MIT-licensed, with a few exceptions](https://github.com/JuliaLang/julia/blob/master/LICENSE.md), the distribution created by the techniques described herein will be GPL licensed, as various dependent libraries such as `SuiteSparse` are GPL licensed. We do hope to have a non-GPL distribution of Julia in the future.


## [Versioning and Git](#Versioning-and-Git)
The Makefile uses both the `VERSION` file and commit hashes and tags from the git repository to generate the `base/version_git.jl` with information we use to fill the splash screen and the `versioninfo()` output. If you for some reason don't want to have the git repository available when building you should pregenerate the `base/version_git.jl` file with:
```julia
make -C base version_git.jl.phony
```
Julia has lots of build dependencies where we use patched versions that has not yet been included by the popular package managers. These dependencies will usually be automatically downloaded when you build, but if you want to be able to build Julia on a computer without internet access you should create a full-source-dist archive with the special make target
```julia
make full-source-dist
```
that creates a julia-version-commit.tar.gz archive with all required dependencies.
When compiling a tagged release in the git repository, we don't display the branch/commit hash info in the splash screen. You can use this line to show a release description of up to 45 characters. To set this line you have to create a Make.user file containing:
```julia
override TAGGED_RELEASE_BANNER = "my-package-repository build"
```


## [Target Architectures](#Target-Architectures)
By default, Julia optimizes its system image to the native architecture of the build machine. This is usually not what you want when building packages, as it will make Julia fail at startup on any machine with incompatible CPUs (in particular older ones with more restricted instruction sets).
We therefore recommend that you pass the `MARCH` variable when calling `make`, setting it to the baseline target you intend to support. This will determine the target CPU for both the Julia executable and libraries, and the system image (the latter can also be set using [`JULIA_CPU_TARGET`](../../../manual/environment-variables/#JULIA_CPU_TARGET)). Typically useful values for x86 CPUs are `x86-64` and `core2` (for 64-bit builds) and `pentium4` (for 32-bit builds). Unfortunately, CPUs older than Pentium 4 are currently not supported (see [this issue](https://github.com/JuliaLang/julia/issues/7185)).
The full list of CPU targets supported by LLVM can be obtained by running `llc -mattr=help`.


## [Linux](#Linux)
On Linux, `make binary-dist` creates a tarball that contains a fully functional Julia installation. If you wish to create a distribution package such as a `.deb`, or `.rpm`, some extra effort is needed. See the [julia-debian](https://github.com/staticfloat/julia-debian) repository for an example of what metadata is needed for creating `.deb` packages for Debian and Ubuntu-based systems. See the [Fedora package](https://src.fedoraproject.org/rpms/julia) for RPM-based distributions. Although we have not yet experimented with it, [Alien](https://wiki.debian.org/Alien) could be used to generate Julia packages for various Linux distributions.
Julia supports overriding standard installation directories via `prefix` and other environment variables you can pass when calling `make` and `make install`. See Make.inc for their list. `DESTDIR` can also be used to force the installation into a temporary directory.
By default, Julia loads `$prefix/etc/julia/startup.jl` as an installation-wide initialization file. This file can be used by distribution managers to set up custom paths or initialization code. For Linux distribution packages, if `$prefix` is set to `/usr`, there is no `/usr/etc` to look into. This requires the path to Julia's private `etc` directory to be changed. This can be done via the `sysconfdir` make variable when building. Simply pass `sysconfdir=/etc` to `make` when building and Julia will first check `/etc/julia/startup.jl` before trying `$prefix/etc/julia/startup.jl`.


## [OS X](#OS-X)
To create a binary distribution on OSX, build Julia first, then cd to `contrib/mac/app`, and run `make` with the same makevars that were used with `make` when building Julia proper. This will then create a `.dmg` file in the `contrib/mac/app` directory holding a completely self-contained Julia.app.
Alternatively, Julia may be built as a framework by invoking `make` with the `darwinframework` target and `DARWIN_FRAMEWORK=1` set. For example, `make DARWIN_FRAMEWORK=1 darwinframework`.


## [Windows](#Windows)
Instructions for reating a Julia distribution on Windows are described in the [build devdocs for Windows](https://github.com/JuliaLang/julia/blob/master/doc/src/devdocs/build/windows.md).


## [Notes on BLAS and LAPACK](#Notes-on-BLAS-and-LAPACK)
Julia builds OpenBLAS by default, which includes the BLAS and LAPACK libraries. On 32-bit architectures, Julia builds OpenBLAS to use 32-bit integers, while on 64-bit architectures, Julia builds OpenBLAS to use 64-bit integers (ILP64). It is essential that all Julia functions that call BLAS and LAPACK API routines use integers of the correct width.
Most BLAS and LAPACK distributions provided on linux distributions, and even commercial implementations ship libraries that use 32-bit APIs. In many cases, a 64-bit API is provided as a separate library.
When using vendor provided or OS provided libraries, a `make` option called `USE_BLAS64` is available as part of the Julia build. When doing `make USE_BLAS64=0`, Julia will call BLAS and LAPACK assuming a 32-bit API, where all integers are 32-bit wide, even on a 64-bit architecture.
Other libraries that Julia uses, such as SuiteSparse also use BLAS and LAPACK internally. The APIs need to be consistent across all libraries that depend on BLAS and LAPACK. The Julia build process will build all these libraries correctly, but when overriding defaults and using system provided libraries, this consistency must be ensured.


## [Notes on BLAS and LAPACK](#Notes-on-BLAS-and-LAPACK)
Also note that Linux distributions sometimes ship several versions of OpenBLAS, some of which enable multithreading, and others only working in a serial fashion. For example, in Fedora, `libopenblasp.so` is threaded, but `libopenblas.so` is not. We recommend using the former for optimal performance. To choose an OpenBLAS library whose name is different from the default `libopenblas.so`, pass `LIBBLAS=-l$(YOURBLAS)` and `LIBBLASNAME=lib$(YOURBLAS)` to `make`, replacing `$(YOURBLAS)` with the name of your library. You can also add `.so.0` to the name of the library if you want your package to work without requiring the unversioned `.so` symlink.
Finally, OpenBLAS includes its own optimized version of LAPACK. If you set `USE_SYSTEM_BLAS=1` and `USE_SYSTEM_LAPACK=1`, you should also set `LIBLAPACK=-l$(YOURBLAS)` and `LIBLAPACKNAME=lib$(YOURBLAS)`. Else, the reference LAPACK will be used and performance will typically be much lower.
Starting with Julia 1.7, Julia uses [libblastrampoline](https://github.com/JuliaLinearAlgebra/libblastrampoline) to pick a different BLAS at runtime.


# [Point releasing 101](#Point-releasing-101)
Creating a point/patch release consists of several distinct steps.


## [Backporting commits](#Backporting-commits)
Some pull requests are labeled "backport pending x.y", e.g. "backport pending 0.6". This designates that the next subsequent release tagged from the release-x.y branch should include the commit(s) in that pull request. Once the pull request is merged into master, each of the commits should be [cherry picked](https://git-scm.com/docs/git-cherry-pick) to a dedicated branch that will ultimately be merged into release-x.y.


### [Creating a backports branch](#Creating-a-backports-branch)
First, create a new branch based on release-x.y. The typical convention for Julia branches is to prefix the branch name with your initials if it's intended to be a personal branch. For the sake of example, we'll say that the author of the branch is Jane Smith.
```julia
git fetch origin
git checkout release-x.y
git rebase origin/release-x.y
git checkout -b js/backport-x.y
```
This ensures that your local copy of release-x.y is up to date with origin before you create a new branch from it.


### [Cherry picking commits](#Cherry-picking-commits)
Now we do the actual backporting. Find all merged pull requests labeled "backport pending x.y" in the GitHub web UI. For each of these, scroll to the bottom where it says "someperson merged commit `123abc` into `master` XX minutes ago". Note that the commit name is a link; if you click it, you'll be shown the contents of the commit. If this page shows that `123abc` is a merge commit, go back to the PR page–-we don't want merge commits, we want the actual commits. However, if this does not show a merge commit, it means that the PR was squash-merged. In that case, use the git SHA of the commit, listed next to commit on this page.
Once you have the SHA of the commit, cherry-pick it onto the backporting branch:
```julia
git cherry-pick -x -e <sha>
```
There may be conflicts which need to be resolved manually. Once conflicts are resolved (if applicable), add a reference to the GitHub pull request that introduced the commit in the body of the commit message.
After all of the relevant commits are on the backports branch, push the branch to GitHub.


## [Checking for performance regressions](#Checking-for-performance-regressions)
Point releases should never introduce performance regressions. Luckily the Julia benchmarking bot, Nanosoldier, can run benchmarks against any branch, not just master. In this case we want to check the benchmark results of js/backport-x.y against release-x.y. To do this, awaken the Nanosoldier from his robotic slumber using a comment on your backporting pull request:
```markdown
@nanosoldier `runbenchmarks(ALL, vs=":release-x.y")`
```
This will run all registered benchmarks on release-x.y and js/backport-x.y and produce a summary of results, marking all improvements and regressions.
If Nanosoldier finds any regressions, try verifying locally and rerun Nanosoldier if necessary. If the regressions are deemed to be real rather than just noise, you'll have to find a commit on master to backport that fixes it if one exists, otherwise you should determine what caused the regression and submit a patch (or get someone who knows the code to submit a patch) to master, then backport the commit once that's merged. (Or submit a patch directly to the backport branch if appropriate.)


## [Building test binaries](#Building-test-binaries)
After the backport PR has been merged into the `release-x.y` branch, update your local clone of Julia, then get the SHA of the branch using
```julia
git rev-parse origin/release-x.y
```
Keep that handy, as it's what you'll enter in the "Revision" field in the buildbot UI.
For now, all you need are binaries for Linux x86-64, since this is what's used for running PackageEvaluator. Go to https://buildog.julialang.org, submit a job for `nuke_linux64`, then queue up a job for `package_linux64`, providing the SHA as the revision. When the packaging job completes, it will upload the binary to the `julialang2` bucket on AWS. Retrieve the URL, as it will be used for PackageEvaluator.


## [Checking for package breakages](#Checking-for-package-breakages)
Point releases should never break packages, with the possible exception of packages that are doing some seriously questionable hacks using Base internals that are not intended to be user-facing. (In those cases, maybe have a word with the package author.)
Checking whether changes made in the forthcoming new version will break packages can be accomplished using [PackageEvaluator](https://github.com/JuliaCI/PackageEvaluator.jl), often called "PkgEval" for short. PkgEval is what populates the status badges on GitHub repos and on pkg.julialang.org. It typically runs on one of the non-benchmarking nodes of Nanosoldier and uses Vagrant to perform its duties in separate, parallel VirtualBox virtual machines.


### [Setting up PackageEvaluator](#Setting-up-PackageEvaluator)
Clone PackageEvaluator and create a branch called `backport-x.y.z`, and check it out. Note that the required changes are a little hacky and confusing, and hopefully that will be addressed in a future version of PackageEvaluator. The changes to make will be modeled off of [this commit](https://github.com/JuliaCI/PackageEvaluator.jl/commit/5ba6a3b000e7a3793391d16f695c8704b91d6016).
The setup script takes its first argument as the version of Julia to run and the second as the range of package names (AK for packages named A-K, LZ for L-Z). The basic idea is that we're going to tweak that a bit to run only two versions of Julia, the current x.y release and our backport version, each with three ranges of packages.
In the linked diff, we're saying that if the second argument is LZ, use the binaries built from our backport branch, otherwise (AK) use the release binaries. Then we're using the first argument to run a section of the package list: A-F for input 0.4, G-N for 0.5, and O-Z for 0.6.


### [Running PackageEvaluator](#Running-PackageEvaluator)
To run PkgEval, find a hefty enough machine (such as Nanosoldier node 1), then run
```julia
git clone https://github.com/JuliaCI/PackageEvaluator.jl.git
cd PackageEvaluator.jl/scripts
git checkout backport-x.y.z
./runvagrant.sh
```
This produces some folders in the scripts/ directory. The folder names and their contents are decoded below:
| Folder name | Julia version | Package range |
|:-----------:|:-------------:|:-------------:|
|    0.4AK    |    Release    |      A-F      |
|    0.4LZ    |   Backport    |      A-F      |
|    0.5AK    |    Release    |      G-N      |
|    0.5LZ    |   Backport    |      G-N      |
|    0.6AK    |    Release    |      O-Z      |
|    0.6LZ    |   Backport    |      O-Z      |


### [Investigating results](#Investigating-results)
Once that's done, you can use `./summary.sh` from that same directory to produce a summary report of the findings. We'll do so for each of the folders to aggregate overall results by version.
```julia
./summary.sh 0.4AK/*.json > summary_release.txt
./summary.sh 0.5AK/*.json >> summary_release.txt
./summary.sh 0.6AK/*.json >> summary_release.txt
./summary.sh 0.4LZ/*.json > summary_backport.txt
./summary.sh 0.5LZ/*.json >> summary_backport.txt
./summary.sh 0.6LZ/*.json >> summary_backport.txt
```
Now we have two files, `summary_release.txt` and `summary_backport.txt`, containing the PackageEvaluator test results (pass/fail) for each package for the two versions.
To make these easier to ingest into a Julia, we'll convert them into CSV files then use the DataFrames package to process the results. To convert to CSV, copy each .txt file to a corresponding .csv file, then enter Vim and execute `ggVGI"<esc>` then `:%s/\.json /",/g`. (You don't have to use Vim; this just is one way to do it.) Now process the results with Julia code similar to the following.


### [Investigating results](#Investigating-results)
```julia
using DataFrames

release = readtable("summary_release.csv", header=false, names=[:package, :release])
backport = readtable("summary_backport.csv", header=false, names=[:package, :backport])

results = join(release, backport, on=:package, kind=:outer)

for result in eachrow(results)
    a = result[:release]
    b = result[:backport]
    if (isna(a) && !isna(b)) || (isna(b) && !isna(a))
        color = :yellow
    elseif a != b && occursin("pass", b)
        color = :green
    elseif a != b
        color = :red
    else
        continue
    end
    printstyled(result[:package], ": Release ", a, " -> Backport ", b, "\n", color=color)
end
```
This will write color-coded lines to `stdout`. All lines in red must be investigated as they signify potential breakages caused by the backport version. Lines in yellow should be looked into since it means a package ran on one version but not on the other for some reason. If you find that your backported branch is causing breakages, use `git bisect` to identify the problematic commits, `git revert` those commits, and repeat the process.


## [Merging backports into the release branch](#Merging-backports-into-the-release-branch)
After you have ensured that
-   the backported commits pass all of Julia's unit tests,
-   there are no performance regressions introduced by the backported commits as compared to the release branch, and
-   the backported commits do not break any registered packages,
then the backport branch is ready to be merged into release-x.y. Once it's merged, go through and remove the "backport pending x.y" label from all pull requests containing the commits that have been backported. Do not remove the label from PRs that have not been backported.
The release-x.y branch should now contain all of the new commits. The last thing we want to do to the branch is to adjust the version number. To do this, submit a PR against release-x.y that edits the VERSION file to remove `-pre` from the version number. Once that's merged, we're ready to tag.


## [Tagging the release](#Tagging-the-release)
It's time! Check out the release-x.y branch and make sure that your local copy of the branch is up to date with the remote branch. At the command line, run
```julia
git tag v$(cat VERSION)
git push --tags
```
This creates the tag locally and pushes it to GitHub.
After tagging the release, submit another PR to release-x.y to bump the patch number and add `-pre` back to the end. This denotes that the branch state reflects a prerelease version of the next point release in the x.y series.
Follow the remaining directions in the Makefile.


## [Signing binaries](#Signing-binaries)
Some of these steps will require secure passwords. To obtain the appropriate passwords, contact Elliot Saba (staticfloat) or Alex Arslan (ararslan). Note that code signing for each platform must be performed on that platform (e.g. Windows signing must be done on Windows, etc.).


### [Linux](#Linux-2)
Code signing must be done manually on Linux, but it's quite simple. First obtain the file `julia.key` from the CodeSigning folder in the `juliasecure` AWS bucket. Add this to your GnuPG keyring using
```julia
gpg --import julia.key
```
This will require entering a password that you must obtain from Elliot or Alex. Next, set the trust level for the key to maximum. Start by entering a `gpg` session:
```julia
gpg --edit-key julia
```
At the prompt, type `trust`, then when asked for a trust level, provide the maximum available (likely 5). Exit GnuPG.
Now, for each of the Linux tarballs that were built on the buildbots, enter
```julia
gpg -u julia --armor --detach-sig julia-x.y.z-linux-<arch>.tar.gz
```
This will produce a corresponding .asc file for each tarball. And that's it!


### [macOS](#macOS)
Code signing should happen automatically on the macOS buildbots. However, it's important to verify that it was successful. On a system or virtual machine running macOS, download the .dmg file that was built on the buildbots. For the sake of example, say that the .dmg file is called `julia-x.y.z-osx.dmg`. Run
```julia
mkdir ./jlmnt
hdiutil mount -readonly -mountpoint ./jlmnt julia-x.y.z-osx.dmg
codesign -v jlmnt/Julia-x.y.app
```
Be sure to note the name of the mounted disk listed when mounting! For the sake of example, we'll assume this is `disk3`. If the code signing verification exited successfully, there will be no output from the `codesign` step. If it was indeed successful, you can detach the .dmg now:
```julia
hdiutil eject /dev/disk3
rm -rf ./jlmnt
```
If you get a message like
> Julia-x.y.app: code object is not signed at all
then you'll need to sign manually.
To sign manually, first retrieve the OS X certificates from the CodeSigning folder in the `juliasecure` bucket on AWS. Add the .p12 file to your keychain using Keychain.app. Ask Elliot Saba (staticfloat) or Alex Arslan (ararslan) for the password for the key. Now run
```julia
hdiutil convert julia-x.y.z-osx.dmg -format UDRW -o julia-x.y.z-osx_writable.dmg
mkdir ./jlmnt
hdiutil mount -mountpoint julia-x.y.z-osx_writable.dmg
codesign -s "AFB379C0B4CBD9DB9A762797FC2AB5460A2B0DBE" --deep jlmnt/Julia-x.y.app
```
This may fail with a message like
> Julia-x.y.app: resource fork, Finder information, or similar detritus not allowed
If that's the case, you'll need to remove extraneous attributes:


### [macOS](#macOS)
```julia
xattr -cr jlmnt/Julia-x.y.app
```
Then retry code signing. If that produces no errors, retry verification. If all is now well, unmount the writable .dmg and convert it back to read-only:
```julia
hdiutil eject /dev/disk3
rm -rf ./jlmnt
hdiutil convert julia-x.y.z-osx_writable.dmg -format UDZO -o julia-x.y.z-osx_fixed.dmg
```
Verify that the resulting .dmg is in fact fixed by double clicking it. If everything looks good, eject it then drop the `_fixed` suffix from the name. And that's it!


### [Windows](#Windows-2)
Signing must be performed manually on Windows. First obtain the Windows 10 SDK, which contains the necessary signing utilities, from the Microsoft website. We need the `SignTool` utility which should have been installed somewhere like `C:\Program Files (x86)\Windows Kits\10\App Certification Kit`. Grab the Windows certificate files from CodeSigning on `juliasecure` and put them in the same directory as the executables. Open a Windows CMD window, `cd` to where all the files are, and run
```julia
set PATH=%PATH%;C:\Program Files (x86)\Windows Kits\10\App Certification Kit;
signtool sign /f julia-windows-code-sign_2017.p12 /p "PASSWORD" ^
   /t http://timestamp.verisign.com/scripts/timstamp.dll ^
   /v julia-x.y.z-win32.exe
```
Note that `^` is a line continuation character in Windows CMD and `PASSWORD` is a placeholder for the password for this certificate. As usual, contact Elliot or Alex for passwords. If there are no errors, we're all good!


## [Uploading binaries](#Uploading-binaries)
Now that everything is signed, we need to upload the binaries to AWS. You can use a program like Cyberduck or the `aws` command line utility. The binaries should go in the `julialang2` bucket in the appropriate folders. For example, Linux x86-64 goes in `julialang2/bin/linux/x.y`. Be sure to delete the current `julia-x.y-latest-linux-<arch>.tar.gz` file and replace it with a duplicate of `julia-x.y.z-linux-<arch>.tar.gz`.
We also need to upload the checksums for everything we've built, including the source tarballs and all release binaries. This is simple:
```julia
shasum -a 256 julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.sha256
md5sum julia-x.y.z* | grep -v -e sha256 -e md5 -e asc > julia-x.y.z.md5
```
Note that if you're running those commands on macOS, you'll get very slightly different output, which can be reformatted by looking at an existing file. Mac users will also need to use `md5 -r` instead of `md5sum`. Upload the .md5 and .sha256 files to `julialang2/bin/checksums` on AWS.
Ensure that the permissions on AWS for all uploaded files are set to "Everyone: READ."
For each file we've uploaded, we need to purge the Fastly cache so that the links on the website point to the updated files. As an example:
```julia
curl -X PURGE https://julialang-s3.julialang.org/bin/checksums/julia-x.y.z.sha256
```
Sometimes this isn't necessary but it's good to do anyway.
------------------------------------------------------------------------