|
| 1 | +#!/usr/bin/env bash |
| 2 | +# shellcheck disable=SC2294 |
| 3 | + |
| 4 | +purge_list=() |
| 5 | + |
| 6 | +set_centos_ulimit() { |
| 7 | + # this is a bug affecting buildkit with yum when ulimit is unlimited |
| 8 | + # https://github.com/docker/buildx/issues/379#issuecomment-1196517905 |
| 9 | + ulimit -n 1024000 |
| 10 | +} |
| 11 | + |
| 12 | +install_packages() { |
| 13 | + if grep -i ubuntu /etc/os-release; then |
| 14 | + apt-get update |
| 15 | + |
| 16 | + for pkg in "${@}"; do |
| 17 | + if ! dpkg -L "${pkg}" >/dev/null 2>/dev/null; then |
| 18 | + apt-get install --assume-yes --no-install-recommends "${pkg}" |
| 19 | + |
| 20 | + purge_list+=( "${pkg}" ) |
| 21 | + fi |
| 22 | + done |
| 23 | + else |
| 24 | + set_centos_ulimit |
| 25 | + for pkg in "${@}"; do |
| 26 | + if ! yum list installed "${pkg}" >/dev/null 2>/dev/null; then |
| 27 | + yum install -y "${pkg}" |
| 28 | + |
| 29 | + purge_list+=( "${pkg}" ) |
| 30 | + fi |
| 31 | + done |
| 32 | + fi |
| 33 | +} |
| 34 | + |
| 35 | +purge_packages() { |
| 36 | + if (( ${#purge_list[@]} )); then |
| 37 | + if grep -i ubuntu /etc/os-release; then |
| 38 | + apt-get purge --assume-yes --auto-remove "${purge_list[@]}" |
| 39 | + else |
| 40 | + yum remove -y "${purge_list[@]}" |
| 41 | + fi |
| 42 | + fi |
| 43 | +} |
| 44 | + |
| 45 | +if_centos() { |
| 46 | + if grep -q -i centos /etc/os-release; then |
| 47 | + eval "${@}" |
| 48 | + fi |
| 49 | +} |
| 50 | + |
| 51 | +if_ubuntu() { |
| 52 | + if grep -q -i ubuntu /etc/os-release; then |
| 53 | + eval "${@}" |
| 54 | + fi |
| 55 | +} |
| 56 | + |
| 57 | +if_ubuntu_ge() { |
| 58 | + if grep -q -i ubuntu /etc/os-release; then |
| 59 | + local ver |
| 60 | + ver="$(source /etc/os-release; echo $VERSION_ID)" |
| 61 | + if dpkg --compare-versions "$ver" "ge" "$1"; then |
| 62 | + shift |
| 63 | + eval "${@}" |
| 64 | + fi |
| 65 | + fi |
| 66 | +} |
| 67 | + |
| 68 | + |
| 69 | +GNU_MIRRORS=( |
| 70 | + "https://ftp.gnu.org/gnu/" |
| 71 | + "https://ftpmirror.gnu.org/" |
| 72 | +) |
| 73 | + |
| 74 | +download_mirrors() { |
| 75 | + local relpath="${1}" |
| 76 | + shift |
| 77 | + local filename="${1}" |
| 78 | + shift |
| 79 | + |
| 80 | + for mirror in "${@}"; do |
| 81 | + if curl -4 --retry 3 -sSfL "${mirror}/${relpath}/${filename}" -O; then |
| 82 | + break |
| 83 | + fi |
| 84 | + done |
| 85 | + if [[ ! -f "${filename}" ]]; then |
| 86 | + echo "Unable to download ${filename}" >&2 |
| 87 | + exit 1 |
| 88 | + fi |
| 89 | +} |
| 90 | + |
| 91 | +download_binutils() { |
| 92 | + local mirror |
| 93 | + local version="${1}" |
| 94 | + local ext="${2}" |
| 95 | + local filename="binutils-${version}.tar.${ext}" |
| 96 | + |
| 97 | + download_mirrors "binutils" "${filename}" "${GNU_MIRRORS[@]}" |
| 98 | +} |
| 99 | + |
| 100 | +download_gcc() { |
| 101 | + local mirror |
| 102 | + local version="${1}" |
| 103 | + local ext="${2}" |
| 104 | + local filename="gcc-${version}.tar.${ext}" |
| 105 | + |
| 106 | + download_mirrors "gcc/gcc-${version}" "${filename}" "${GNU_MIRRORS[@]}" |
| 107 | +} |
| 108 | + |
| 109 | +docker_to_qemu_arch() { |
| 110 | + local arch="${1}" |
| 111 | + case "${arch}" in |
| 112 | + arm64) |
| 113 | + echo "aarch64" |
| 114 | + ;; |
| 115 | + 386) |
| 116 | + echo "i386" |
| 117 | + ;; |
| 118 | + amd64) |
| 119 | + echo "x86_64" |
| 120 | + ;; |
| 121 | + arm|ppc64le|riscv64|s390x) |
| 122 | + echo "${arch}" |
| 123 | + ;; |
| 124 | + *) |
| 125 | + echo "Unknown Docker image architecture, got \"${arch}\"." >&2 |
| 126 | + exit 1 |
| 127 | + ;; |
| 128 | + esac |
| 129 | +} |
| 130 | + |
| 131 | +docker_to_linux_arch() { |
| 132 | + # variant may not be provided |
| 133 | + local oldstate |
| 134 | + oldstate="$(set +o)" |
| 135 | + set +u |
| 136 | + |
| 137 | + local arch="${1}" |
| 138 | + local variant="${2}" |
| 139 | + case "${arch}" in |
| 140 | + arm64) |
| 141 | + echo "aarch64" |
| 142 | + ;; |
| 143 | + 386) |
| 144 | + echo "i686" |
| 145 | + ;; |
| 146 | + amd64) |
| 147 | + echo "x86_64" |
| 148 | + ;; |
| 149 | + ppc64le) |
| 150 | + echo "powerpc64le" |
| 151 | + ;; |
| 152 | + arm) |
| 153 | + case "${variant}" in |
| 154 | + v6) |
| 155 | + echo "arm" |
| 156 | + ;; |
| 157 | + ""|v7) |
| 158 | + echo "armv7" |
| 159 | + ;; |
| 160 | + *) |
| 161 | + echo "Unknown Docker image variant, got \"${variant}\"." >&2 |
| 162 | + exit 1 |
| 163 | + ;; |
| 164 | + esac |
| 165 | + ;; |
| 166 | + riscv64|s390x) |
| 167 | + echo "${arch}" |
| 168 | + ;; |
| 169 | + *) |
| 170 | + echo "Unknown Docker image architecture, got \"${arch}\"." >&2 |
| 171 | + exit 1 |
| 172 | + ;; |
| 173 | + esac |
| 174 | + |
| 175 | + eval "${oldstate}" |
| 176 | +} |
| 177 | + |
| 178 | +find_argument() { |
| 179 | + # Extracts the value from an argument of the form VARIABLE=VALUE |
| 180 | + local needle="$1" |
| 181 | + local return_var="$2" |
| 182 | + shift 2 |
| 183 | + local prefix="${needle}=" |
| 184 | + for var in "${@}"; do |
| 185 | + case "$var" in |
| 186 | + "$prefix"*) |
| 187 | + eval "$return_var=${var#"${prefix}"}" |
| 188 | + return 0 ;; |
| 189 | + *) ;; |
| 190 | + esac |
| 191 | + done |
| 192 | + echo "Missing argument ${needle}" |
| 193 | + exit 1 |
| 194 | +} |
| 195 | + |
| 196 | +symlinkify_if_same() { |
| 197 | + local file1="$1" |
| 198 | + local file2="$2" |
| 199 | + # Only make a symlink if the files are identical, and the destination file isn't already a symlink |
| 200 | + if [ ! -L "${file2}" ] && cmp "$file1" "$file2"; then |
| 201 | + ln -sf "$file1" "$file2" |
| 202 | + fi |
| 203 | +} |
| 204 | + |
| 205 | +symlinkify_and_strip_toolchain() { |
| 206 | + local target="$1" |
| 207 | + local gcc_ver="$2" |
| 208 | + |
| 209 | + local target_bin="/usr/local/${target}/bin" |
| 210 | + local local_bin="/usr/local/bin" |
| 211 | + |
| 212 | + # The first set of tools appear as /usr/local/bin/<target>-<tool> and /usr/local/<target>/bin/<tool> |
| 213 | + |
| 214 | + # Special case: ld is itself usually hardlinked to ld.bfd |
| 215 | + symlinkify_if_same "${local_bin}/ld" "${local_bin}/ld.bfd" |
| 216 | + |
| 217 | + # Turn hard links or otherwise identical files into symlinks |
| 218 | + for tool in ar as ld ld.bfd nm objcopy objdump ranlib readelf strip; do |
| 219 | + local src="${local_bin}/${target}-${tool}" |
| 220 | + local dest="${target_bin}/${tool}" |
| 221 | + symlinkify_if_same "${src}" "${dest}" |
| 222 | + strip "${src}" |
| 223 | + done |
| 224 | + |
| 225 | + # The second set of tools only appear as /usr/local/bin/<target>-<tool> |
| 226 | + |
| 227 | + # Special case: c++ and g++ are usually the same file |
| 228 | + symlinkify_if_same "${local_bin}/${target}-c++" "${local_bin}/${target}-g++" |
| 229 | + # Special case: gcc and gcc-<version> |
| 230 | + symlinkify_if_same "${local_bin}/${target}-gcc" "${local_bin}/${target}-gcc-${gcc_ver}" |
| 231 | + |
| 232 | + for tool in addr2line c++ c++filt cpp elfedit g++ gcc gcc-${gcc_ver} gcc-ar gcc-nm gcc-ranlib gcov gcov-dump gcov-tool gfortran gprof size strings; do |
| 233 | + strip "${local_bin}/${target}-${tool}" |
| 234 | + done |
| 235 | +} |
0 commit comments