├── .github └── workflows │ ├── compilation.yml │ └── docker.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── config └── ps2toolchain-config.sh ├── depends ├── check-gcc.sh ├── check-git.sh ├── check-make.sh ├── check-patch.sh ├── check-texinfo.sh └── check-wget.sh ├── scripts ├── 001-dvp.sh ├── 002-iop.sh └── 003-ee.sh ├── toolchain-sudo.sh └── toolchain.sh /.github/workflows/compilation.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | repository_dispatch: 7 | types: [run_build] 8 | workflow_dispatch: {} 9 | 10 | jobs: 11 | build: 12 | runs-on: ${{ matrix.os[0] }} 13 | strategy: 14 | matrix: 15 | os: [ 16 | [macos-latest, arm64, bash], 17 | [macos-13, x86_64, bash], 18 | [ubuntu-latest, x86_64, bash], 19 | [windows-latest, x86_64, msys2] 20 | ] 21 | fail-fast: false 22 | defaults: 23 | run: 24 | shell: ${{ matrix.os[2] }} {0} 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - name: Install Ubuntu packages 30 | if: matrix.os[0] == 'ubuntu-latest' 31 | run: | 32 | sudo apt-get update 33 | sudo apt-get -y install texinfo bison flex gettext libgmp3-dev libmpfr-dev libmpc-dev 34 | 35 | - name: Install macOS packages 36 | if: startsWith(matrix.os[0], 'macos') 37 | run: | 38 | brew update 39 | brew install texinfo bison flex gnu-sed gsl gmp mpfr libmpc 40 | 41 | - name: Install MSYS2 packages 42 | if: matrix.os[0] == 'windows-latest' 43 | uses: msys2/setup-msys2@v2 44 | with: 45 | msystem: MINGW32 46 | install: | 47 | base-devel git make texinfo flex bison patch binutils mpc-devel tar 48 | mingw-w64-i686-readline mingw-w64-i686-gcc mingw-w64-i686-cmake 49 | mingw-w64-i686-make mingw-w64-i686-libogg 50 | update: true 51 | 52 | - name: Runs all the stages in the shell 53 | run: | 54 | export PS2DEV=$PWD/ps2dev 55 | export PS2SDK=$PS2DEV/ps2sdk 56 | export PATH="$(brew --prefix gnu-sed)/libexec/gnubin:$PATH" # This is just needed for MacOS 57 | export PATH=$PATH:$PS2DEV/bin:$PS2DEV/ee/bin:$PS2DEV/iop/bin:$PS2DEV/dvp/bin:$PS2SDK/bin 58 | ./toolchain.sh 59 | 60 | - name: Get short SHA 61 | id: slug 62 | run: echo "sha8=${MSYSTEM}-sha[$(echo ${GITHUB_SHA} | cut -c1-8)" >> $GITHUB_OUTPUT 63 | 64 | - name: Prepare ps2dev folder 65 | run: | 66 | tar -zcvf ps2dev-${{matrix.os[0]}}.tar.gz ps2dev 67 | 68 | - uses: actions/upload-artifact@v4 69 | with: 70 | name: ps2dev-${{matrix.os[0]}}-ps2dev-${{matrix.os[1]}}-${{ steps.slug.outputs.sha8 }} 71 | path: ps2dev-${{matrix.os[0]}}.tar.gz 72 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: CI-Docker 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - v* 9 | repository_dispatch: 10 | types: [run_build] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | env: 16 | DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} 17 | DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} 18 | DISPATCH_TOKEN: ${{ secrets.DISPATCH_TOKEN }} 19 | 20 | steps: 21 | - uses: actions/checkout@v4 22 | 23 | - name: Extract DOCKER_TAG using tag name 24 | if: startsWith(github.ref, 'refs/tags/') 25 | run: | 26 | echo "DOCKER_TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV 27 | 28 | - name: Use default DOCKER_TAG 29 | if: startsWith(github.ref, 'refs/tags/') != true 30 | run: | 31 | echo "DOCKER_TAG=latest" >> $GITHUB_ENV 32 | 33 | - name: Set up QEMU 34 | uses: docker/setup-qemu-action@v3 35 | 36 | - name: Set up Docker Buildx 37 | uses: docker/setup-buildx-action@v3 38 | 39 | - name: Login to DockerHub 40 | uses: docker/login-action@v3 41 | if: env.DOCKER_USERNAME != null 42 | with: 43 | username: ${{ secrets.DOCKER_USERNAME }} 44 | password: ${{ secrets.DOCKER_PASSWORD }} 45 | 46 | - name: Login to Github Container Registry 47 | uses: docker/login-action@v3 48 | with: 49 | registry: ghcr.io 50 | username: ${{ github.actor }} 51 | password: ${{ secrets.GITHUB_TOKEN }} 52 | 53 | - name: Set docker tag list to include DockerHub if credentials available 54 | if: env.DOCKER_USERNAME != null 55 | run: | 56 | echo "DOCKER_TAG_LIST=ghcr.io/${{ github.repository }}:${{ env.DOCKER_TAG }},${{ github.repository }}:${{ env.DOCKER_TAG }}" >> $GITHUB_ENV 57 | 58 | - name: Set docker tag list to not include DockerHub if credentials not available 59 | if: env.DOCKER_USERNAME == null 60 | run: | 61 | echo "DOCKER_TAG_LIST=ghcr.io/${{ github.repository }}:${{ env.DOCKER_TAG }}" >> $GITHUB_ENV 62 | 63 | - name: Build and Push to container registry 64 | uses: docker/build-push-action@v5 65 | with: 66 | push: true 67 | tags: ${{ env.DOCKER_TAG_LIST }} 68 | build-args: | 69 | BASE_DOCKER_DVP_IMAGE=ghcr.io/${{ github.repository_owner }}/ps2toolchain-dvp:${{ env.DOCKER_TAG }} 70 | BASE_DOCKER_IOP_IMAGE=ghcr.io/${{ github.repository_owner }}/ps2toolchain-iop:${{ env.DOCKER_TAG }} 71 | BASE_DOCKER_EE_IMAGE=ghcr.io/${{ github.repository_owner }}/ps2toolchain-ee:${{ env.DOCKER_TAG }} 72 | 73 | - name: Send Compile action 74 | run: | 75 | export DISPATCH_ACTION="$(echo run_build)" 76 | echo "NEW_DISPATCH_ACTION=$DISPATCH_ACTION" >> $GITHUB_ENV 77 | 78 | - name: Repository Dispatch 79 | uses: peter-evans/repository-dispatch@v3 80 | if: env.DISPATCH_TOKEN != null 81 | with: 82 | repository: ${{ github.repository_owner }}/ps2sdk 83 | token: ${{ secrets.DISPATCH_TOKEN }} 84 | event-type: ${{ env.NEW_DISPATCH_ACTION }} 85 | client-payload: '{"ref": "${{ github.ref }}"}' 86 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE! Please use 'git ls-files -i --exclude-standard -c' 3 | # command after changing this file, to see if there are 4 | # any tracked files which get ignored after the change. 5 | # 6 | # Normal rules 7 | # 8 | build/ 9 | .* 10 | 11 | # 12 | # files that we don't want to ignore 13 | # 14 | !.gitignore 15 | !.gitattributes 16 | !.github 17 | !.editorconfig 18 | !.clang-format 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # ARGS for defining tags 2 | ARG BASE_DOCKER_DVP_IMAGE 3 | ARG BASE_DOCKER_IOP_IMAGE 4 | ARG BASE_DOCKER_EE_IMAGE 5 | 6 | # dvp stage of Dockerfile 7 | FROM $BASE_DOCKER_DVP_IMAGE 8 | 9 | # iop stage of Dockerfile 10 | FROM $BASE_DOCKER_IOP_IMAGE 11 | 12 | # ee stage of Dockerfile 13 | FROM $BASE_DOCKER_EE_IMAGE 14 | 15 | # Second stage of Dockerfile 16 | FROM alpine:latest 17 | 18 | ENV PS2DEV /usr/local/ps2dev 19 | ENV PS2SDK $PS2DEV/ps2sdk 20 | ENV PATH $PATH:${PS2DEV}/bin:${PS2DEV}/ee/bin:${PS2DEV}/iop/bin:${PS2DEV}/dvp/bin:${PS2SDK}/bin 21 | 22 | COPY --from=0 ${PS2DEV} ${PS2DEV} 23 | COPY --from=1 ${PS2DEV} ${PS2DEV} 24 | COPY --from=2 ${PS2DEV} ${PS2DEV} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2019, ps2dev members 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![CI](https://github.com/ps2dev/ps2toolchain/workflows/CI/badge.svg) 2 | ![CI-Docker](https://github.com/ps2dev/ps2toolchain/workflows/CI-Docker/badge.svg) 3 | 4 | # ps2toolchain 5 | 6 | ## **ATTENTION** 7 | 8 | If you are confused on how to start developing for PS2, see the 9 | [getting started](https://ps2dev.github.io/#getting-started) section on 10 | the ps2dev main page. 11 | 12 | ## Introduction 13 | 14 | This program will automatically build and install the compiler tools used in the creation of homebrew software for the Sony PlayStation® 2 videogame system. 15 | 16 | ## What these scripts do 17 | 18 | These scripts download (with `git clone`) and install: 19 | 20 | - [binutils 2.14](http://www.gnu.org/software/binutils/ "binutils") (iop, dvp) 21 | - [binutils 2.35.1](http://www.gnu.org/software/binutils/ "binutils") (ee), 22 | - [gcc 3.2.3](https://gcc.gnu.org/ "gcc") (iop) 23 | - [gcc 10.2.0](https://gcc.gnu.org/ "gcc") (ee) 24 | - [newlib 4.0.0](https://sourceware.org/newlib/ "newlib") (ee) 25 | 26 | ## Requirements 27 | 28 | 1. Install gcc/clang, make, patch, git, texinfo, flex, bison, gsl, gmp, mpfr, mpc and gettext if you don't have those packages. 29 | 2. Ensure that you have enough permissions for managing PS2DEV location (which defaults to `/usr/local/ps2dev`). PS2DEV location MUST NOT have spaces or special characters in it's path! For example, on Linux systems, you can set access for current user by running commands: 30 | ```bash 31 | export PS2DEV=/usr/local/ps2dev 32 | sudo mkdir -p $PS2DEV 33 | sudo chown -R $USER: $PS2DEV 34 | ``` 35 | 3. Add this to your login script (example: `~/.bash_profile`) 36 | ```bash 37 | export PS2DEV=/usr/local/ps2dev 38 | export PS2SDK=$PS2DEV/ps2sdk 39 | export PATH=$PATH:$PS2DEV/bin:$PS2DEV/ee/bin:$PS2DEV/iop/bin:$PS2DEV/dvp/bin:$PS2SDK/bin 40 | ``` 41 | 4. Run toolchain.sh 42 | `./toolchain.sh` 43 | 44 | ## Community 45 | 46 | Links for discussion and chat are available 47 | [here](https://ps2dev.github.io/#community). 48 | -------------------------------------------------------------------------------- /config/ps2toolchain-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PS2TOOLCHAIN_DVP_REPO_URL="https://github.com/ps2dev/ps2toolchain-dvp.git" 4 | PS2TOOLCHAIN_DVP_DEFAULT_REPO_REF="main" 5 | PS2TOOLCHAIN_IOP_REPO_URL="https://github.com/ps2dev/ps2toolchain-iop.git" 6 | PS2TOOLCHAIN_IOP_DEFAULT_REPO_REF="main" 7 | PS2TOOLCHAIN_EE_REPO_URL="https://github.com/ps2dev/ps2toolchain-ee.git" 8 | PS2TOOLCHAIN_EE_DEFAULT_REPO_REF="main" 9 | 10 | if test -f "$PS2DEV_CONFIG_OVERRIDE"; then 11 | source "$PS2DEV_CONFIG_OVERRIDE" 12 | fi 13 | -------------------------------------------------------------------------------- /depends/check-gcc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # check-gcc.sh by Naomi Peori (naomi@peori.ca) 3 | 4 | ## Check for gcc. 5 | gcc --version 1> /dev/null || { echo "ERROR: Install gcc before continuing."; exit 1; } 6 | -------------------------------------------------------------------------------- /depends/check-git.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # check-git.sh by Mathias Lafeldt 3 | 4 | ## Check for git. 5 | git --version > /dev/null || { echo "ERROR: Install Git before continuing."; exit 1; } 6 | -------------------------------------------------------------------------------- /depends/check-make.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # check-make.sh by Naomi Peori (naomi@peori.ca) 3 | 4 | ## Check for make. 5 | make -v 1> /dev/null || { echo "ERROR: Install make before continuing."; exit 1; } 6 | -------------------------------------------------------------------------------- /depends/check-patch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # check-patch.sh by Naomi Peori (naomi@peori.ca) 3 | 4 | ## Check for patch. 5 | patch -v 1> /dev/null || { echo "ERROR: Install patch before continuing."; exit 1; } 6 | -------------------------------------------------------------------------------- /depends/check-texinfo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # check-texinfo.sh by Dan Peori (danpeori@oopo.net) 3 | 4 | ## Check for texinfo. 5 | makeinfo --version 1> /dev/null || { echo "ERROR: Install texinfo before continuing."; exit 1; } 6 | -------------------------------------------------------------------------------- /depends/check-wget.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # check-wget.sh by Naomi Peori (naomi@peori.ca) 3 | 4 | ## Check for wget. 5 | wget -V 1> /dev/null || { echo "ERROR: Install wget before continuing."; exit 1; } 6 | -------------------------------------------------------------------------------- /scripts/001-dvp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 001-dvp.sh by ps2dev developers 3 | 4 | ## Exit with code 1 when any command executed returns a non-zero exit code. 5 | onerr() 6 | { 7 | exit 1; 8 | } 9 | trap onerr ERR 10 | 11 | ## Read information from the configuration file. 12 | source "$(dirname "$0")/../config/ps2toolchain-config.sh" 13 | 14 | ## Download the source code. 15 | REPO_URL="$PS2TOOLCHAIN_DVP_REPO_URL" 16 | REPO_REF="$PS2TOOLCHAIN_DVP_DEFAULT_REPO_REF" 17 | REPO_FOLDER="$(s="$REPO_URL"; s=${s##*/}; printf "%s" "${s%.*}")" 18 | 19 | # Checking if a specific Git reference has been passed in parameter $1 20 | if test -n "$1"; then 21 | REPO_REF="$1" 22 | printf 'Using specified repo reference %s\n' "$REPO_REF" 23 | fi 24 | 25 | if test ! -d "$REPO_FOLDER"; then 26 | git clone --depth 1 -b "$REPO_REF" "$REPO_URL" "$REPO_FOLDER" 27 | else 28 | git -C "$REPO_FOLDER" remote set-url origin "$REPO_URL" 29 | git -C "$REPO_FOLDER" fetch origin "$REPO_REF" --depth=1 30 | git -C "$REPO_FOLDER" checkout -f FETCH_HEAD 31 | fi 32 | 33 | cd "$REPO_FOLDER" 34 | 35 | ## Build and install. 36 | ./toolchain.sh 37 | -------------------------------------------------------------------------------- /scripts/002-iop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 002-iop.sh by ps2dev developers 3 | 4 | ## Exit with code 1 when any command executed returns a non-zero exit code. 5 | onerr() 6 | { 7 | exit 1; 8 | } 9 | trap onerr ERR 10 | 11 | ## Read information from the configuration file. 12 | source "$(dirname "$0")/../config/ps2toolchain-config.sh" 13 | 14 | ## Download the source code. 15 | REPO_URL="$PS2TOOLCHAIN_IOP_REPO_URL" 16 | REPO_REF="$PS2TOOLCHAIN_IOP_DEFAULT_REPO_REF" 17 | REPO_FOLDER="$(s="$REPO_URL"; s=${s##*/}; printf "%s" "${s%.*}")" 18 | 19 | # Checking if a specific Git reference has been passed in parameter $1 20 | if test -n "$1"; then 21 | REPO_REF="$1" 22 | printf 'Using specified repo reference %s\n' "$REPO_REF" 23 | fi 24 | 25 | if test ! -d "$REPO_FOLDER"; then 26 | git clone --depth 1 -b "$REPO_REF" "$REPO_URL" "$REPO_FOLDER" 27 | else 28 | git -C "$REPO_FOLDER" remote set-url origin "$REPO_URL" 29 | git -C "$REPO_FOLDER" fetch origin "$REPO_REF" --depth=1 30 | git -C "$REPO_FOLDER" checkout -f FETCH_HEAD 31 | fi 32 | 33 | cd "$REPO_FOLDER" 34 | 35 | ## Build and install. 36 | ./toolchain.sh 37 | -------------------------------------------------------------------------------- /scripts/003-ee.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 003-ee.sh by ps2dev developers 3 | 4 | ## Exit with code 1 when any command executed returns a non-zero exit code. 5 | onerr() 6 | { 7 | exit 1; 8 | } 9 | trap onerr ERR 10 | 11 | ## Read information from the configuration file. 12 | source "$(dirname "$0")/../config/ps2toolchain-config.sh" 13 | 14 | ## Download the source code. 15 | REPO_URL="$PS2TOOLCHAIN_EE_REPO_URL" 16 | REPO_REF="$PS2TOOLCHAIN_EE_DEFAULT_REPO_REF" 17 | REPO_FOLDER="$(s="$REPO_URL"; s=${s##*/}; printf "%s" "${s%.*}")" 18 | 19 | # Checking if a specific Git reference has been passed in parameter $1 20 | if test -n "$1"; then 21 | REPO_REF="$1" 22 | printf 'Using specified repo reference %s\n' "$REPO_REF" 23 | fi 24 | 25 | if test ! -d "$REPO_FOLDER"; then 26 | git clone --depth 1 -b "$REPO_REF" "$REPO_URL" "$REPO_FOLDER" 27 | else 28 | git -C "$REPO_FOLDER" remote set-url origin "$REPO_URL" 29 | git -C "$REPO_FOLDER" fetch origin "$REPO_REF" --depth=1 30 | git -C "$REPO_FOLDER" checkout -f FETCH_HEAD 31 | fi 32 | 33 | cd "$REPO_FOLDER" 34 | 35 | ## Build and install. 36 | ./toolchain.sh 37 | -------------------------------------------------------------------------------- /toolchain-sudo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # toolchain-sudo.sh by Naomi Peori (naomi@peori.ca) 3 | 4 | ## Enter the ps2toolchain directory. 5 | cd "$(dirname "$0")" || { echo "ERROR: Could not enter the ps2toolchain directory."; exit 1; } 6 | 7 | ## Set up the environment. 8 | export PS2DEV=/usr/local/ps2dev 9 | export PS2SDK=$PS2DEV/ps2sdk 10 | export PATH=$PATH:$PS2DEV/bin 11 | export PATH=$PATH:$PS2DEV/ee/bin 12 | export PATH=$PATH:$PS2DEV/iop/bin 13 | export PATH=$PATH:$PS2DEV/dvp/bin 14 | export PATH=$PATH:$PS2SDK/bin 15 | 16 | ## Run the toolchain script. 17 | ./toolchain.sh "$@" || { echo "ERROR: Could not run the toolchain script."; exit 1; } 18 | -------------------------------------------------------------------------------- /toolchain.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # toolchain.sh by Naomi Peori (naomi@peori.ca) 3 | 4 | ## Enter the ps2toolchain directory. 5 | cd "$(dirname "$0")" || { echo "ERROR: Could not enter the ps2toolchain directory."; exit 1; } 6 | 7 | ## Create the build directory. 8 | mkdir -p build || { echo "ERROR: Could not create the build directory."; exit 1; } 9 | 10 | ## Enter the build directory. 11 | cd build || { echo "ERROR: Could not enter the build directory."; exit 1; } 12 | 13 | ## Fetch the depend scripts. 14 | DEPEND_SCRIPTS=$(ls ../depends/*.sh | sort) 15 | 16 | ## Run all the depend scripts. 17 | for SCRIPT in ${DEPEND_SCRIPTS[@]}; do "$SCRIPT" || { echo "$SCRIPT: Failed."; exit 1; } done 18 | 19 | ## Check if repo is in a tag, to install this specfic PS2 Dev environment 20 | if git describe --exact-match --tags $(git log -n1 --pretty='%h') >/dev/null 2>&1; then 21 | TAG=$(git describe --exact-match --tags $(git log -n1 --pretty='%h')) 22 | echo "Instaling specific version $TAG"; 23 | else 24 | echo "Installing latest environment status" 25 | TAG="" 26 | fi 27 | 28 | ## Fetch the build scripts. 29 | BUILD_SCRIPTS=$(ls ../scripts/*.sh | sort) 30 | 31 | ## If specific steps were requested... 32 | if [ "$1" ]; then 33 | 34 | ## Run the requested build scripts. 35 | for STEP in "$@"; do "${BUILD_SCRIPTS[$STEP-1]}" "$TAG" || { echo "${BUILD_SCRIPTS[$STEP-1]}: Failed."; exit 1; } done 36 | 37 | else 38 | 39 | ## Run the all build scripts. 40 | for SCRIPT in ${BUILD_SCRIPTS[@]}; do "$SCRIPT" "$TAG" || { echo "$SCRIPT: Failed."; exit 1; } done 41 | 42 | fi 43 | --------------------------------------------------------------------------------