2011-09-06 10:13:32 -05:00
#!/usr/bin/env bash
2014-11-26 20:01:38 -08:00
#
2016-01-15 09:10:05 -05:00
# Usage: ruby-build [-kpv] <definition> <prefix>
2014-11-26 20:01:38 -08:00
# ruby-build --definitions
2016-01-15 09:24:33 -05:00
# ruby-build --version
2014-11-26 20:01:38 -08:00
#
# -k/--keep Do not remove source tree after installation
# -p/--patch Apply a patch from stdin before building
2016-01-15 09:10:05 -05:00
# -v/--verbose Verbose mode: print compilation status to stdout
2015-04-19 18:26:39 +09:00
# -4/--ipv4 Resolve names to IPv4 addresses only
# -6/--ipv6 Resolve names to IPv6 addresses only
2020-03-20 18:08:04 +09:00
# --definitions List all local definitions
2020-03-06 22:14:45 +09:00
# -l/--list List latest stable releases for each Ruby
2016-01-15 09:24:33 -05:00
# --version Show version of ruby-build
2014-11-26 20:01:38 -08:00
#
2011-08-02 08:46:34 -05:00
2022-08-25 20:43:06 +02:00
RUBY_BUILD_VERSION="20220825"
2011-09-06 14:56:07 -05:00
2015-10-28 12:17:43 +01:00
OLDIFS="$IFS"
2011-08-07 15:41:20 -05:00
set -E
exec 3<&2 # preserve original stderr at fd 3
2011-08-02 08:46:34 -05:00
2012-08-15 13:28:01 -05:00
lib() {
parse_options() {
OPTIONS=()
ARGUMENTS=()
local arg option index
for arg in "$@"; do
if [ "${arg:0:1}" = "-" ]; then
if [ "${arg:1:1}" = "-" ]; then
OPTIONS[${#OPTIONS[*]}]="${arg:2}"
else
index=1
while option="${arg:$index:1}"; do
[ -n "$option" ] || break
OPTIONS[${#OPTIONS[*]}]="$option"
index=$(($index+1))
done
fi
else
ARGUMENTS[${#ARGUMENTS[*]}]="$arg"
fi
done
}
if [ "$1" == "--$FUNCNAME" ]; then
declare -f "$FUNCNAME"
2012-08-15 14:43:44 -05:00
echo "$FUNCNAME \"\$1\";"
2012-08-15 13:28:01 -05:00
exit
fi
}
lib "$1"
2011-08-16 23:22:52 +02:00
resolve_link() {
2011-12-30 13:58:12 -06:00
$(type -p greadlink readlink | head -1) "$1"
2011-08-16 23:22:52 +02:00
}
2011-08-07 12:36:08 -05:00
abs_dirname() {
local cwd="$(pwd)"
local path="$1"
while [ -n "$path" ]; do
cd "${path%/*}"
local name="${path##*/}"
2011-08-16 23:22:52 +02:00
path="$(resolve_link "$name" || true)"
2011-08-07 12:36:08 -05:00
done
pwd
cd "$cwd"
}
2013-02-04 16:15:07 -06:00
capitalize() {
printf "%s" "$1" | tr a-z A-Z
}
2013-04-18 20:15:55 -05:00
sanitize() {
printf "%s" "$1" | sed "s/[^A-Za-z0-9.-]/_/g; s/__*/_/g"
}
2014-02-10 20:11:22 +01:00
colorize() {
if [ -t 1 ]; then printf "\e[%sm%s\e[m" "$1" "$2"
else echo -n "$2"
fi
}
2014-09-06 02:20:39 -07:00
os_information() {
if type -p lsb_release >/dev/null; then
lsb_release -sir | xargs echo
elif type -p sw_vers >/dev/null; then
2020-06-22 22:31:11 -07:00
echo "$(sw_vers -productName) $(sw_vers -productVersion)"
2014-09-08 22:58:05 -07:00
elif [ -r /etc/os-release ]; then
source /etc/os-release
echo "$NAME" $VERSION_ID
2014-09-06 02:20:39 -07:00
else
local os="$(cat /etc/{centos,redhat,fedora,system}-release /etc/debian_version 2>/dev/null | head -1)"
echo "${os:-$(uname -sr)}"
fi
}
2015-12-26 22:29:56 +01:00
is_mac() {
[ "$(uname -s)" = "Darwin" ] || return 1
[ $# -eq 0 ] || [ "$(osx_version)" "$@" ]
}
2014-10-27 12:47:33 +01:00
# 9.1 -> 901
# 10.9 -> 1009
# 10.10 -> 1010
osx_version() {
2014-10-31 04:08:00 +01:00
local -a ver
IFS=. ver=( `sw_vers -productVersion` )
2015-10-28 12:17:43 +01:00
IFS="$OLDIFS"
2014-10-31 04:08:00 +01:00
echo $(( ${ver[0]}*100 + ${ver[1]} ))
2014-10-27 12:47:33 +01:00
}
2011-08-07 15:41:20 -05:00
build_failed() {
{ echo
2014-09-06 01:23:17 -07:00
colorize 1 "BUILD FAILED"
2014-09-06 02:20:39 -07:00
echo " ($(os_information) using $(version))"
2011-08-07 15:41:20 -05:00
echo
2011-10-21 09:22:05 -05:00
2012-04-28 14:09:06 -07:00
if ! rmdir "${BUILD_PATH}" 2>/dev/null; then
echo "Inspect or clean up the working tree at ${BUILD_PATH}"
2011-10-30 10:39:07 -05:00
if file_is_not_empty "$LOG_PATH"; then
2014-09-06 02:17:11 -07:00
colorize 33 "Results logged to ${LOG_PATH}"
printf "\n\n"
2011-10-30 10:39:07 -05:00
echo "Last 10 log lines:"
tail -n 10 "$LOG_PATH"
fi
2011-10-21 09:22:05 -05:00
fi
2011-08-07 15:41:20 -05:00
} >&3
exit 1
2011-08-07 12:38:14 -05:00
}
2011-10-21 09:22:05 -05:00
file_is_not_empty() {
local filename="$1"
local line_count="$(wc -l "$filename" 2>/dev/null || true)"
if [ -n "$line_count" ]; then
words=( $line_count )
[ "${words[0]}" -gt 0 ]
else
return 1
fi
}
2013-10-27 22:24:12 +01:00
num_cpu_cores() {
2014-09-08 09:11:39 -07:00
local num
case "$(uname -s)" in
Darwin | *BSD )
2013-10-27 22:24:12 +01:00
num="$(sysctl -n hw.ncpu 2>/dev/null || true)"
2014-09-08 09:11:39 -07:00
;;
2017-12-15 09:36:20 +01:00
SunOS )
num="$(getconf NPROCESSORS_ONLN 2>/dev/null || true)"
;;
2014-09-08 09:11:39 -07:00
* )
2017-11-09 09:28:49 +02:00
num="$({ getconf _NPROCESSORS_ONLN ||
grep -c ^processor /proc/cpuinfo; } 2>/dev/null)"
2014-09-08 09:11:39 -07:00
num="${num#0}"
;;
esac
2013-10-27 22:24:12 +01:00
echo "${num:-2}"
}
2011-08-02 08:46:34 -05:00
install_package() {
2013-02-08 16:47:52 -06:00
install_package_using "tarball" 1 "$@"
2011-09-12 22:12:44 -07:00
}
install_git() {
2013-02-08 16:47:52 -06:00
install_package_using "git" 2 "$@"
2011-09-12 22:12:44 -07:00
}
2012-10-06 09:17:08 +09:00
install_svn() {
2013-02-08 16:47:52 -06:00
install_package_using "svn" 2 "$@"
2012-10-06 09:17:08 +09:00
}
2011-09-12 22:12:44 -07:00
install_package_using() {
local package_type="$1"
local package_type_nargs="$2"
local package_name="$3"
shift 3
2013-02-08 16:47:52 -06:00
local fetch_args=( "$package_name" "${@:1:$package_type_nargs}" )
local make_args=( "$package_name" )
local arg last_arg
for arg in "${@:$(( $package_type_nargs + 1 ))}"; do
if [ "$last_arg" = "--if" ]; then
"$arg" || return 0
elif [ "$arg" != "--if" ]; then
make_args["${#make_args[@]}"]="$arg"
fi
last_arg="$arg"
done
2012-04-28 14:09:06 -07:00
pushd "$BUILD_PATH" >&4
2013-02-08 16:47:52 -06:00
"fetch_${package_type}" "${fetch_args[@]}"
make_package "${make_args[@]}"
2011-09-14 10:49:06 -05:00
popd >&4
2011-09-12 22:12:44 -07:00
2012-11-15 14:58:57 -06:00
{ echo "Installed ${package_name} to ${PREFIX_PATH}"
echo
} >&2
2011-09-12 22:12:44 -07:00
}
make_package() {
2011-08-02 08:46:34 -05:00
local package_name="$1"
2011-09-12 22:12:44 -07:00
shift
2011-08-02 08:46:34 -05:00
2011-09-14 10:49:06 -05:00
pushd "$package_name" >&4
2011-12-01 17:09:27 -06:00
before_install_package "$package_name"
2011-08-02 08:46:34 -05:00
build_package "$package_name" $*
2011-08-02 20:55:10 -05:00
after_install_package "$package_name"
2011-09-14 10:49:06 -05:00
popd >&4
2011-08-02 08:46:34 -05:00
}
2014-04-15 16:45:57 +02:00
compute_sha2() {
local output
if type shasum &>/dev/null; then
output="$(shasum -a 256 -b)" || return 1
echo "${output% *}"
elif type openssl &>/dev/null; then
2015-01-26 15:07:55 -08:00
local openssl="$(command -v "$(brew --prefix openssl 2>/dev/null || true)"/bin/openssl openssl | head -1)"
2014-10-28 15:28:48 +01:00
output="$("$openssl" dgst -sha256 2>/dev/null)" || return 1
2014-04-15 16:45:57 +02:00
echo "${output##* }"
elif type sha256sum &>/dev/null; then
2017-02-23 20:01:44 +00:00
output="$(sha256sum -b)" || return 1
2017-09-06 01:16:07 +00:00
echo "${output%% *}"
2014-04-15 16:45:57 +02:00
else
return 1
fi
}
2012-11-14 19:53:57 -06:00
compute_md5() {
2014-04-15 16:45:57 +02:00
local output
2012-11-14 19:53:57 -06:00
if type md5 &>/dev/null; then
md5 -q
2012-11-15 15:24:44 -06:00
elif type openssl &>/dev/null; then
2014-04-15 16:45:57 +02:00
output="$(openssl md5)" || return 1
2012-11-16 00:48:17 -06:00
echo "${output##* }"
2012-11-14 19:53:57 -06:00
elif type md5sum &>/dev/null; then
2014-04-15 16:45:57 +02:00
output="$(md5sum -b)" || return 1
2017-09-06 01:16:07 +00:00
echo "${output%% *}"
2012-11-14 19:53:57 -06:00
else
2012-11-15 16:03:39 -06:00
return 1
2012-11-14 19:53:57 -06:00
fi
}
2016-01-18 11:44:14 -05:00
has_checksum_support() {
local checksum_command="$1"
2016-01-18 21:28:36 -05:00
local has_checksum_var="HAS_CHECKSUM_SUPPORT_${checksum_command}"
if [ -z "${!has_checksum_var+defined}" ]; then
printf -v "$has_checksum_var" "$(echo test | "$checksum_command" >/dev/null; echo $?)"
fi
return "${!has_checksum_var}"
2016-01-18 11:44:14 -05:00
}
2012-11-14 19:53:57 -06:00
verify_checksum() {
2016-01-15 16:47:54 -05:00
local checksum_command
2016-01-15 16:47:34 -05:00
local filename="$1"
local expected_checksum="$(echo "$2" | tr [A-Z] [a-z])"
2012-11-15 16:03:39 -06:00
2012-11-19 23:45:00 -06:00
# If the specified filename doesn't exist, return success
[ -e "$filename" ] || return 0
2012-11-14 19:53:57 -06:00
2016-01-15 16:36:39 -05:00
case "${#expected_checksum}" in
2016-01-18 21:55:09 -05:00
0) return 0 ;; # empty checksum; return success
2016-01-18 11:44:14 -05:00
32) checksum_command="compute_md5" ;;
64) checksum_command="compute_sha2" ;;
2016-01-18 21:55:09 -05:00
*)
{ echo
echo "unexpected checksum length: ${#expected_checksum} (${expected_checksum})"
echo "expected 0 (no checksum), 32 (MD5), or 64 (SHA2-256)"
echo
} >&4
return 1 ;;
2016-01-15 16:36:39 -05:00
esac
2014-04-17 00:35:56 +02:00
2016-01-18 11:44:14 -05:00
# If chosen provided checksum algorithm isn't supported, return success
has_checksum_support "$checksum_command" || return 0
2012-11-15 16:05:05 -06:00
# If the computed checksum is empty, return failure
2014-04-17 00:35:56 +02:00
local computed_checksum=`echo "$($checksum_command < "$filename")" | tr [A-Z] [a-z]`
2012-11-15 16:05:05 -06:00
[ -n "$computed_checksum" ] || return 1
2012-11-14 19:53:57 -06:00
if [ "$expected_checksum" != "$computed_checksum" ]; then
{ echo
echo "checksum mismatch: ${filename} (file is corrupt)"
echo "expected $expected_checksum, got $computed_checksum"
echo
} >&4
return 1
fi
}
2012-11-15 14:58:57 -06:00
http() {
local method="$1"
2018-08-22 13:09:20 +02:00
[ -n "$2" ] || return 1
shift 1
2012-11-15 14:58:57 -06:00
2019-11-04 17:11:28 +01:00
RUBY_BUILD_HTTP_CLIENT="${RUBY_BUILD_HTTP_CLIENT:-$(detect_http_client 2>&3)}"
2018-08-22 13:09:20 +02:00
[ -n "$RUBY_BUILD_HTTP_CLIENT" ] || return 1
"http_${method}_${RUBY_BUILD_HTTP_CLIENT}" "$@"
}
detect_http_client() {
local client
for client in aria2c curl wget; do
if type "$client" &>/dev/null; then
echo "$client"
return
2018-04-26 02:07:32 +00:00
fi
2018-08-22 13:09:20 +02:00
done
2019-11-04 14:44:03 +01:00
echo "error: install \`curl\`, \`wget\`, or \`aria2c\` to download packages" >&2
2018-08-22 13:09:20 +02:00
return 1
2012-04-23 16:13:56 -05:00
}
2012-03-12 10:06:25 -07:00
2016-02-13 03:43:25 +00:00
http_head_aria2c() {
2016-06-22 00:37:56 +00:00
aria2c --dry-run --no-conf=true ${ARIA2_OPTS} "$1" >&4 2>&1
2016-02-13 03:43:25 +00:00
}
http_get_aria2c() {
2016-06-02 01:58:02 +00:00
local out="${2:-$(mktemp "out.XXXXXX")}"
2016-06-22 00:37:56 +00:00
if aria2c --allow-overwrite=true --no-conf=true -o "${out}" ${ARIA2_OPTS} "$1" >&4; then
2016-06-02 01:58:02 +00:00
[ -n "$2" ] || cat "${out}"
else
false
fi
2016-02-13 03:43:25 +00:00
}
2012-11-15 14:58:57 -06:00
http_head_curl() {
2016-02-13 03:51:31 +00:00
curl -qsILf ${CURL_OPTS} "$1" >&4 2>&1
2012-11-15 14:58:57 -06:00
}
http_get_curl() {
2016-02-13 03:51:31 +00:00
curl -q -o "${2:--}" -sSLf ${CURL_OPTS} "$1"
2012-11-15 14:58:57 -06:00
}
http_head_wget() {
2016-02-13 03:51:31 +00:00
wget -q --spider ${WGET_OPTS} "$1" >&4 2>&1
2012-11-15 14:58:57 -06:00
}
http_get_wget() {
2016-02-13 03:51:31 +00:00
wget -nv ${WGET_OPTS} -O "${2:--}" "$1"
2012-11-15 14:58:57 -06:00
}
2011-09-12 22:12:44 -07:00
fetch_tarball() {
2011-08-02 08:46:34 -05:00
local package_name="$1"
local package_url="$2"
2012-11-14 20:33:48 -06:00
local mirror_url
2012-11-16 10:30:49 -06:00
local checksum
2018-08-21 13:25:48 +02:00
local extracted_dir
2012-11-13 17:38:37 -06:00
2012-11-16 10:30:49 -06:00
if [ "$package_url" != "${package_url/\#}" ]; then
checksum="${package_url#*#}"
2012-11-14 19:53:57 -06:00
package_url="${package_url%%#*}"
2012-11-14 20:33:48 -06:00
if [ -n "$RUBY_BUILD_MIRROR_URL" ]; then
2015-12-12 23:33:33 +09:00
if [[ -z "$RUBY_BUILD_DEFAULT_MIRROR" || $package_url != */cache.ruby-lang.org/* ]]; then
mirror_url="${RUBY_BUILD_MIRROR_URL}/$checksum"
fi
2020-07-18 00:36:59 +08:00
elif [ -n "$RUBY_BUILD_MIRROR_PACKAGE_URL" ]; then
mirror_url="$RUBY_BUILD_MIRROR_PACKAGE_URL"
2012-11-14 20:33:48 -06:00
fi
2012-11-14 19:53:57 -06:00
fi
2014-08-17 19:07:08 -07:00
local tar_args="xzf"
2012-11-14 19:53:57 -06:00
local package_filename="${package_name}.tar.gz"
2013-10-23 15:32:42 +02:00
if [ "$package_url" != "${package_url%bz2}" ]; then
2016-01-07 09:49:19 -06:00
if ! type -p bzip2 >/dev/null; then
echo "warning: bzip2 not found; consider installing \`bzip2\` package" >&4
fi
2013-10-23 15:32:42 +02:00
package_filename="${package_filename%.gz}.bz2"
tar_args="${tar_args/z/j}"
fi
2014-03-25 04:15:50 +01:00
if ! reuse_existing_tarball "$package_filename" "$checksum"; then
2018-08-21 22:03:47 +02:00
local tarball_filename="$(basename "$package_url")"
2014-04-26 16:15:10 +01:00
echo "Downloading ${tarball_filename}..." >&2
2013-10-26 06:39:12 +02:00
http head "$mirror_url" &&
download_tarball "$mirror_url" "$package_filename" "$checksum" ||
2012-11-15 14:58:57 -06:00
download_tarball "$package_url" "$package_filename" "$checksum"
2013-10-26 06:39:12 +02:00
fi
2012-11-14 19:53:57 -06:00
2018-08-21 12:06:46 +02:00
{ if tar $tar_args "$package_filename"; then
2018-08-21 13:25:48 +02:00
if [ ! -d "$package_name" ]; then
2018-08-21 22:03:47 +02:00
extracted_dir="$(find_extracted_directory)"
2018-08-21 13:25:48 +02:00
mv "$extracted_dir" "$package_name"
fi
2013-03-12 16:49:17 +08:00
if [ -z "$KEEP_BUILD_PATH" ]; then
rm -f "$package_filename"
else
true
fi
fi
2012-11-14 19:53:57 -06:00
} >&4 2>&1
}
2018-08-21 13:25:48 +02:00
find_extracted_directory() {
for f in *; do
if [ -d "$f" ]; then
echo "$f"
return
fi
done
echo "Extracted directory not found" >&2
return 1
}
2014-03-25 04:15:50 +01:00
reuse_existing_tarball() {
2012-11-14 20:33:48 -06:00
local package_filename="$1"
local checksum="$2"
2014-03-25 04:15:50 +01:00
# Reuse existing file in build location
if [ -e "$package_filename" ] && verify_checksum "$package_filename" "$checksum"; then
return 0
fi
# Reuse previously downloaded file in cache location
[ -n "$RUBY_BUILD_CACHE_PATH" ] || return 1
local cached_package_filename="${RUBY_BUILD_CACHE_PATH}/$package_filename"
2012-11-19 23:45:00 -06:00
[ -e "$cached_package_filename" ] || return 1
verify_checksum "$cached_package_filename" "$checksum" >&4 2>&1 || return 1
ln -s "$cached_package_filename" "$package_filename" >&4 2>&1 || return 1
2012-11-14 19:53:57 -06:00
}
2011-08-02 08:46:34 -05:00
2012-11-14 19:53:57 -06:00
download_tarball() {
local package_url="$1"
2012-11-14 20:33:48 -06:00
[ -n "$package_url" ] || return 1
2012-11-14 19:53:57 -06:00
local package_filename="$2"
local checksum="$3"
2012-11-15 14:58:57 -06:00
echo "-> $package_url" >&2
2013-10-26 06:32:03 +02:00
if http get "$package_url" "$package_filename" >&4 2>&1; then
verify_checksum "$package_filename" "$checksum" >&4 2>&1 || return 1
else
echo "error: failed to download $package_filename" >&2
return 1
fi
2012-11-14 19:53:57 -06:00
if [ -n "$RUBY_BUILD_CACHE_PATH" ]; then
local cached_package_filename="${RUBY_BUILD_CACHE_PATH}/$package_filename"
{ mv "$package_filename" "$cached_package_filename"
ln -s "$cached_package_filename" "$package_filename"
2012-11-14 20:33:48 -06:00
} >&4 2>&1 || return 1
2012-11-13 17:39:48 -06:00
fi
2011-08-02 08:46:34 -05:00
}
2011-09-12 22:12:44 -07:00
fetch_git() {
2011-08-02 08:46:34 -05:00
local package_name="$1"
2011-09-12 22:12:44 -07:00
local git_url="$2"
local git_ref="$3"
2011-08-02 08:46:34 -05:00
2011-09-12 22:12:44 -07:00
echo "Cloning ${git_url}..." >&2
2012-04-23 16:19:41 -05:00
2012-04-23 16:24:20 -05:00
if type git &>/dev/null; then
2013-03-23 19:27:13 -04:00
if [ -n "$RUBY_BUILD_CACHE_PATH" ]; then
pushd "$RUBY_BUILD_CACHE_PATH" >&4
2013-04-18 20:15:55 -05:00
local clone_name="$(sanitize "$git_url")"
2013-03-23 19:27:13 -04:00
if [ -e "${clone_name}" ]; then
2014-04-17 00:35:38 +09:00
{ cd "${clone_name}"
2013-04-18 20:15:55 -05:00
git fetch --force "$git_url" "+${git_ref}:${git_ref}"
2014-04-17 00:35:38 +09:00
} >&4 2>&1
2013-03-23 19:27:13 -04:00
else
git clone --bare --branch "$git_ref" "$git_url" "${clone_name}" >&4 2>&1
fi
2013-03-25 07:58:57 -04:00
git_url="$RUBY_BUILD_CACHE_PATH/${clone_name}"
2013-03-23 19:27:13 -04:00
popd >&4
fi
2014-04-13 17:33:04 +09:00
if [ -e "${package_name}" ]; then
( cd "${package_name}"
2014-04-17 00:35:38 +09:00
git fetch --depth 1 origin "+${git_ref}"
git checkout -q -B "$git_ref" "origin/${git_ref}"
2014-04-13 17:33:04 +09:00
) >&4 2>&1
else
git clone --depth 1 --branch "$git_ref" "$git_url" "${package_name}" >&4 2>&1
fi
2012-04-23 16:19:41 -05:00
else
echo "error: please install \`git\` and try again" >&2
exit 1
fi
2011-08-02 08:46:34 -05:00
}
2012-10-06 09:17:08 +09:00
fetch_svn() {
local package_name="$1"
local svn_url="$2"
local svn_rev="$3"
2012-10-07 08:07:35 +09:00
echo "Checking out ${svn_url}..." >&2
2012-10-06 09:17:08 +09:00
if type svn &>/dev/null; then
svn co -r "$svn_rev" "$svn_url" "${package_name}" >&4 2>&1
2015-10-30 16:31:13 +01:00
elif type svnlite &>/dev/null; then
svnlite co -r "$svn_rev" "$svn_url" "${package_name}" >&4 2>&1
2012-10-06 09:17:08 +09:00
else
2014-11-15 13:28:35 +02:00
echo "error: please install Subversion and try again" >&2
2012-10-06 09:17:08 +09:00
exit 1
fi
}
2011-08-02 08:46:34 -05:00
build_package() {
local package_name="$1"
shift
if [ "$#" -eq 0 ]; then
local commands="standard"
else
local commands="$*"
fi
echo "Installing ${package_name}..." >&2
2013-12-11 21:16:47 +01:00
[ -n "$HAS_PATCH" ] && apply_ruby_patch "$package_name"
2011-08-02 08:46:34 -05:00
for command in $commands; do
2013-01-31 09:49:01 -06:00
"build_package_${command}" "$package_name"
2011-08-02 08:46:34 -05:00
done
}
2013-02-04 16:15:07 -06:00
package_option() {
local package_name="$1"
local command_name="$2"
local variable="$(capitalize "${package_name}_${command_name}")_OPTS_ARRAY"
local array="$variable[@]"
shift 2
local value=( "${!array}" "$@" )
eval "$variable=( \"\${value[@]}\" )"
}
2016-04-29 21:59:56 -07:00
build_package_warn_eol() {
local package_name="$1"
{ echo
echo "WARNING: $package_name is past its end of life and is now unsupported."
echo "It no longer receives bug fixes or critical security updates."
echo
} >&3
}
build_package_warn_unsupported() {
local package_name="$1"
{ echo
echo "WARNING: $package_name is nearing its end of life."
echo "It only receives critical security updates, no bug fixes."
echo
} >&3
}
2017-06-12 18:27:00 +09:00
build_package_standard_build() {
2011-08-02 08:46:34 -05:00
local package_name="$1"
2011-12-30 13:00:47 -06:00
2012-03-30 13:06:50 -07:00
if [ "${MAKEOPTS+defined}" ]; then
2011-12-30 13:00:47 -06:00
MAKE_OPTS="$MAKEOPTS"
elif [ -z "${MAKE_OPTS+defined}" ]; then
2013-10-27 22:24:12 +01:00
MAKE_OPTS="-j $(num_cpu_cores)"
2011-09-26 16:26:09 -06:00
fi
2011-12-30 13:00:47 -06:00
2013-01-31 09:49:01 -06:00
# Support YAML_CONFIGURE_OPTS, RUBY_CONFIGURE_OPTS, etc.
2013-02-04 16:15:07 -06:00
local package_var_name="$(capitalize "${package_name%%-*}")"
2013-01-23 22:03:53 -07:00
local PACKAGE_CONFIGURE="${package_var_name}_CONFIGURE"
local PACKAGE_PREFIX_PATH="${package_var_name}_PREFIX_PATH"
2013-01-31 09:49:01 -06:00
local PACKAGE_CONFIGURE_OPTS="${package_var_name}_CONFIGURE_OPTS"
2013-02-04 14:05:09 -06:00
local PACKAGE_CONFIGURE_OPTS_ARRAY="${package_var_name}_CONFIGURE_OPTS_ARRAY[@]"
2013-01-31 09:49:01 -06:00
local PACKAGE_MAKE_OPTS="${package_var_name}_MAKE_OPTS"
2013-02-04 14:05:09 -06:00
local PACKAGE_MAKE_OPTS_ARRAY="${package_var_name}_MAKE_OPTS_ARRAY[@]"
2013-02-27 11:12:41 -06:00
local PACKAGE_CFLAGS="${package_var_name}_CFLAGS"
2013-01-31 09:49:01 -06:00
2016-11-27 18:38:17 +09:00
if [ "$package_var_name" = "RUBY" ]; then
use_homebrew_readline || use_freebsd_pkg ||true
fi
2013-12-11 23:49:18 +01:00
2013-05-06 18:03:54 -05:00
( if [ "${CFLAGS+defined}" ] || [ "${!PACKAGE_CFLAGS+defined}" ]; then
2013-05-06 19:44:35 -05:00
export CFLAGS="$CFLAGS ${!PACKAGE_CFLAGS}"
2013-05-06 18:03:54 -05:00
fi
2015-12-26 22:29:56 +01:00
if [ -z "$CC" ] && is_mac -ge 1010; then
2014-10-28 10:49:09 +01:00
export CC=clang
fi
2014-09-06 01:29:28 -07:00
${!PACKAGE_CONFIGURE:-./configure} --prefix="${!PACKAGE_PREFIX_PATH:-$PREFIX_PATH}" \
2021-04-22 12:36:42 +02:00
"${!PACKAGE_CONFIGURE_OPTS_ARRAY}" $CONFIGURE_OPTS ${!PACKAGE_CONFIGURE_OPTS} || return 1
2013-05-06 18:03:54 -05:00
) >&4 2>&1
2021-05-03 12:52:47 +02:00
{ "$MAKE" "${!PACKAGE_MAKE_OPTS_ARRAY}" $MAKE_OPTS ${!PACKAGE_MAKE_OPTS}
2017-06-09 14:40:34 +09:00
} >&4 2>&1
2017-06-12 18:27:00 +09:00
}
2017-06-09 14:40:34 +09:00
2017-06-12 18:27:00 +09:00
build_package_standard_install() {
local package_name="$1"
local package_var_name="$(capitalize "${package_name%%-*}")"
local PACKAGE_MAKE_INSTALL_OPTS="${package_var_name}_MAKE_INSTALL_OPTS"
local PACKAGE_MAKE_INSTALL_OPTS_ARRAY="${package_var_name}_MAKE_INSTALL_OPTS_ARRAY[@]"
2017-06-09 14:40:34 +09:00
2022-05-01 12:39:10 +02:00
{ "$MAKE" ${MAKE_INSTALL_TARGET:-install} "${!PACKAGE_MAKE_INSTALL_OPTS_ARRAY}" $MAKE_INSTALL_OPTS ${!PACKAGE_MAKE_INSTALL_OPTS}
2011-08-07 15:41:20 -05:00
} >&4 2>&1
2011-08-02 08:46:34 -05:00
}
2017-06-12 18:27:00 +09:00
build_package_standard_install_with_bundled_gems() {
{ "$MAKE" update-gems
"$MAKE" extract-gems
} >&4 2>&1
2017-06-12 21:39:26 +09:00
build_package_standard_install "$@"
2017-06-12 18:27:00 +09:00
}
2019-10-11 16:11:21 +08:00
# Backward Compatibility for standard function
2017-06-12 18:27:00 +09:00
build_package_standard() {
2017-06-12 21:39:26 +09:00
build_package_standard_build "$@"
build_package_standard_install "$@"
2017-06-12 18:27:00 +09:00
}
2011-09-12 22:12:44 -07:00
build_package_autoconf() {
2021-04-02 18:33:24 +09:00
{ autoreconf -i
2011-09-12 22:12:44 -07:00
} >&4 2>&1
}
2011-08-02 08:46:34 -05:00
build_package_ruby() {
local package_name="$1"
{ "$RUBY_BIN" setup.rb
2011-08-07 15:41:20 -05:00
} >&4 2>&1
2011-08-02 08:46:34 -05:00
}
2011-09-22 11:49:16 -04:00
build_package_ree_installer() {
2013-10-28 00:25:02 +01:00
build_package_auto_tcltk
2011-09-22 11:49:16 -04:00
local options=""
2015-12-26 22:29:56 +01:00
is_mac && options="--no-tcmalloc"
2011-09-28 13:19:50 -05:00
2013-04-19 11:36:02 -05:00
local option
2021-04-22 12:36:42 +02:00
for option in ${RUBY_CONFIGURE_OPTS_ARRAY[@]} $RUBY_CONFIGURE_OPTS; do
2013-04-19 11:36:02 -05:00
options="$options -c $option"
done
2011-09-22 11:49:16 -04:00
# Work around install_useful_libraries crash with --dont-install-useful-gems
mkdir -p "$PREFIX_PATH/lib/ruby/gems/1.8/gems"
2011-10-21 10:53:09 -05:00
{ ./installer --auto "$PREFIX_PATH" --dont-install-useful-gems $options $CONFIGURE_OPTS
2011-09-22 11:49:16 -04:00
} >&4 2>&1
}
2011-08-05 10:12:06 -05:00
build_package_rbx() {
local package_name="$1"
2014-10-28 15:21:00 +01:00
{ [ ! -e "Gemfile" ] || bundle --path=vendor/bundle
2014-10-28 15:22:14 +01:00
if [ -n "$RUBY_BUILD_CACHE_PATH" ]; then
mkdir -p vendor
ln -s "$RUBY_BUILD_CACHE_PATH" vendor/prebuilt
fi
2015-12-26 22:51:27 +01:00
local opt
local -a configure_opts
for opt in "${RUBY_CONFIGURE_OPTS_ARRAY[@]}"; do
if [[ $opt == --with-openssl-dir=* ]]; then
local openssl_dir="${opt#*=}"
configure_opts[${#configure_opts[@]}]="--with-lib-dir=${openssl_dir}/lib"
configure_opts[${#configure_opts[@]}]="--with-include-dir=${openssl_dir}/include"
else
configure_opts[${#configure_opts[@]}]="$opt"
fi
done
2021-04-22 12:36:42 +02:00
RUBYOPT="-rrubygems $RUBYOPT" ./configure --prefix="$PREFIX_PATH" "${configure_opts[@]}" $RUBY_CONFIGURE_OPTS
2011-08-05 10:12:06 -05:00
rake install
2013-10-20 02:18:29 +02:00
fix_rbx_gem_binstubs "$PREFIX_PATH"
2013-12-11 18:38:53 +01:00
fix_rbx_irb "$PREFIX_PATH"
2011-08-07 15:41:20 -05:00
} >&4 2>&1
2011-08-05 10:12:06 -05:00
}
2013-04-05 08:23:34 -06:00
build_package_mruby() {
2019-11-05 11:03:49 +01:00
{ ./minirake
2013-04-05 08:23:34 -06:00
mkdir -p "$PREFIX_PATH"
2019-11-05 11:03:49 +01:00
cp -fR build/host/* include "$PREFIX_PATH"
ln -fs mruby "$PREFIX_PATH/bin/ruby"
ln -fs mirb "$PREFIX_PATH/bin/irb"
2013-04-05 08:23:34 -06:00
} >&4 2>&1
}
2022-06-28 15:18:51 +09:00
build_package_picoruby() {
{ ./minirake
mkdir -p "$PREFIX_PATH"
cp -fR build/host/* include "$PREFIX_PATH"
ln -fs picoruby "$PREFIX_PATH/bin/ruby"
ln -fs picoirb "$PREFIX_PATH/bin/irb"
} >&4 2>&1
}
2011-10-28 17:19:25 -07:00
build_package_maglev() {
build_package_copy
{ cd "${PREFIX_PATH}"
./install.sh
2011-11-01 14:17:06 -07:00
cd "${PREFIX_PATH}/bin"
echo "Creating symlink for ruby*"
ln -fs maglev-ruby ruby
echo "Creating symlink for irb*"
ln -fs maglev-irb irb
2011-10-28 17:19:25 -07:00
} >&4 2>&1
echo
2011-11-01 14:17:06 -07:00
echo "Run 'maglev start' to start up the stone before using 'ruby' or 'irb'"
2011-10-28 17:19:25 -07:00
}
2013-04-07 11:14:44 +02:00
build_package_topaz() {
build_package_copy
{ cd "${PREFIX_PATH}/bin"
echo "Creating symlink for ruby*"
ln -fs topaz ruby
} >&4 2>&1
}
topaz_architecture() {
case "$(uname -s)" in
"Darwin") echo "osx64";;
"Linux") [[ "$(uname -m)" = "x86_64" ]] && echo "linux64" || echo "linux32";;
*)
echo "no nightly builds available" >&2
exit 1;;
esac
}
2011-09-25 14:30:52 -05:00
build_package_jruby() {
build_package_copy
cd "${PREFIX_PATH}/bin"
ln -fs jruby ruby
2014-02-09 15:25:42 +00:00
chmod +x ruby
2011-09-25 14:30:52 -05:00
install_jruby_launcher
remove_windows_files
2013-12-17 19:35:54 +01:00
fix_jruby_shebangs
2011-09-25 14:30:52 -05:00
}
install_jruby_launcher() {
2016-01-01 12:01:39 +00:00
cd "${PREFIX_PATH}/bin"
{ ./ruby gem install jruby-launcher
} >&4 2>&1
2011-09-25 14:30:52 -05:00
}
2013-12-17 19:35:54 +01:00
fix_jruby_shebangs() {
for file in "${PREFIX_PATH}/bin"/*; do
2020-05-18 16:35:53 +02:00
if [ "$(head -c 20 "$file" | tr -d '\0')" = "#!/usr/bin/env jruby" ]; then
2014-01-17 10:06:38 -05:00
sed -i.bak "1 s:.*:#\!${PREFIX_PATH}\/bin\/jruby:" "$file"
2013-12-20 14:26:41 -08:00
rm "$file".bak
2013-12-17 19:35:54 +01:00
fi
done
}
2018-06-15 19:29:48 +02:00
build_package_truffleruby() {
2021-07-26 15:40:11 +02:00
clean_prefix_path_truffleruby || return $?
2018-06-15 19:29:48 +02:00
build_package_copy
cd "${PREFIX_PATH}"
2019-11-21 12:23:11 +01:00
"${PREFIX_PATH}/lib/truffle/post_install_hook.sh"
2018-06-15 19:29:48 +02:00
}
2020-07-13 20:53:14 +02:00
build_package_truffleruby_graalvm() {
2021-07-26 15:40:11 +02:00
clean_prefix_path_truffleruby || return $?
2020-07-12 12:55:39 +02:00
build_package_copy_to "${PREFIX_PATH}/graalvm"
cd "${PREFIX_PATH}/graalvm"
2020-07-26 18:09:45 +02:00
if is_mac; then
cd Contents/Home || return $?
fi
2020-07-12 12:55:39 +02:00
bin/gu install ruby || return $?
local ruby_home
ruby_home=$(bin/ruby -e 'print RbConfig::CONFIG["prefix"]')
# Make gu available in PATH (useful to install other languages)
2020-07-26 18:09:45 +02:00
ln -s "$PWD/bin/gu" "$ruby_home/bin/gu"
2020-07-12 12:55:39 +02:00
cd "${PREFIX_PATH}"
ln -s "${ruby_home#"$PREFIX_PATH/"}/bin" . || return $?
"$ruby_home/lib/truffle/post_install_hook.sh"
}
2020-04-29 22:59:52 +02:00
build_package_artichoke() {
build_package_copy
mkdir -p "$PREFIX_PATH/bin"
cd "${PREFIX_PATH}/bin"
ln -fs ../artichoke ruby
ln -fs ../airb irb
ln -fs ../artichoke artichoke
ln -fs ../airb airb
}
2011-09-25 14:30:52 -05:00
remove_windows_files() {
cd "$PREFIX_PATH"
rm -f bin/*.exe bin/*.dll bin/*.bat bin/jruby.sh
}
2021-07-26 15:40:11 +02:00
clean_prefix_path_truffleruby() {
2022-04-08 20:06:48 -06:00
if [ -d "$PREFIX_PATH" ] &&
[ ! -e "$PREFIX_PATH/bin/truffleruby" ] &&
[ ! -z "$(ls -A $PREFIX_PATH)" ]; then
2021-07-26 15:40:11 +02:00
echo
echo "ERROR: cannot install TruffleRuby to $PREFIX_PATH, which does not look like a valid TruffleRuby prefix" >&2
2022-04-08 20:06:48 -06:00
echo "TruffleRuby only supports being installed to a not existing directory, an empty directory, or replacing an existing TruffleRuby installation"
2021-07-26 15:40:11 +02:00
echo "See https://github.com/oracle/truffleruby/issues/1389 for details" >&2
return 1
fi
2020-02-13 22:03:53 +01:00
# Make sure there are no leftover files in $PREFIX_PATH
rm -rf "$PREFIX_PATH"
2020-07-12 12:55:39 +02:00
}
build_package_copy_to() {
to="$1"
mkdir -p "$to"
cp -fR . "$to"
}
build_package_copy() {
build_package_copy_to "$PREFIX_PATH"
2011-08-02 20:21:23 -05:00
}
2011-12-01 17:09:27 -06:00
before_install_package() {
local stub=1
}
2011-08-02 20:55:10 -05:00
after_install_package() {
local stub=1
}
2013-10-20 02:18:29 +02:00
fix_rbx_gem_binstubs() {
local prefix="$1"
local gemdir="${prefix}/gems/bin"
local bindir="${prefix}/bin"
Fix `irb`, `rake`, `rdoc`, `ri` for rbx-2.2.1
We symlink Rubinius' `PREFIX/gems/bin` into `PREFIX/bin` so that new
RubyGems binstubs get added to the main bin directory and therefore
become available to rbenv.
However, by throwing away `irb`, `rake`, `rdoc`, and `ri` binstubs
during this process (which are non-executable and have an invalid
shebang), we break the same commands in latest versions of Rubinius.
This change ensures that these binstubs get preserved, their shebang
corrected to `#!PREFIX/bin/rbx`, their executable bit flipped on, and
copied over to the main bin directory.
Fixes #468
2013-12-11 18:17:26 +01:00
local file binstub
2013-10-20 02:18:29 +02:00
# Symlink Rubinius' `gems/bin/` into `bin/`
2014-10-28 15:24:39 +01:00
if [ -d "$gemdir" ] && [ ! -L "$gemdir" ]; then
2013-10-20 02:18:29 +02:00
for file in "$gemdir"/*; do
Fix `irb`, `rake`, `rdoc`, `ri` for rbx-2.2.1
We symlink Rubinius' `PREFIX/gems/bin` into `PREFIX/bin` so that new
RubyGems binstubs get added to the main bin directory and therefore
become available to rbenv.
However, by throwing away `irb`, `rake`, `rdoc`, and `ri` binstubs
during this process (which are non-executable and have an invalid
shebang), we break the same commands in latest versions of Rubinius.
This change ensures that these binstubs get preserved, their shebang
corrected to `#!PREFIX/bin/rbx`, their executable bit flipped on, and
copied over to the main bin directory.
Fixes #468
2013-12-11 18:17:26 +01:00
binstub="${bindir}/${file##*/}"
rm -f "$binstub"
2014-04-05 21:29:38 +02:00
{ echo "#!${bindir}/ruby"
2015-01-29 01:32:38 -08:00
grep -v '^#!' "$file"
2014-04-05 21:29:38 +02:00
} > "$binstub"
Fix `irb`, `rake`, `rdoc`, `ri` for rbx-2.2.1
We symlink Rubinius' `PREFIX/gems/bin` into `PREFIX/bin` so that new
RubyGems binstubs get added to the main bin directory and therefore
become available to rbenv.
However, by throwing away `irb`, `rake`, `rdoc`, and `ri` binstubs
during this process (which are non-executable and have an invalid
shebang), we break the same commands in latest versions of Rubinius.
This change ensures that these binstubs get preserved, their shebang
corrected to `#!PREFIX/bin/rbx`, their executable bit flipped on, and
copied over to the main bin directory.
Fixes #468
2013-12-11 18:17:26 +01:00
chmod +x "$binstub"
2013-10-20 02:18:29 +02:00
done
rm -rf "$gemdir"
ln -s ../bin "$gemdir"
fi
}
2013-12-11 18:38:53 +01:00
fix_rbx_irb() {
local prefix="$1"
"${prefix}/bin/irb" --version &>/dev/null ||
"${prefix}/bin/gem" install rubysl-tracer -v '~> 2.0' --no-rdoc --no-ri &>/dev/null ||
true
}
2019-11-02 11:33:08 +01:00
require_java() {
local required="$1"
2019-11-02 13:09:38 +01:00
local java_version="$(java -version 2>&1)"
2021-09-28 12:38:04 +02:00
local version_string="$(grep 'java version' <<<"$java_version" | head -1 | grep -o '[0-9.]\+' | head -1 || true)"
[ -n "$version_string" ] || version_string="$(grep 'openjdk version' <<<"$java_version" | head -1 | grep -o '[0-9.]\+' | head -1 || true)"
2019-11-02 13:09:38 +01:00
IFS="."
local nums=($version_string)
IFS="$OLDIFS"
local found_version="${nums[0]}"
[ "$found_version" -gt 1 ] 2>/dev/null || found_version="${nums[1]}"
[ "$found_version" -ge "$required" ] 2>/dev/null && return 0
colorize 1 "ERROR" >&3
2021-09-28 12:38:04 +02:00
echo ": Java >= ${required} required, but your Java version was:" >&3
2019-11-02 13:09:38 +01:00
cat <<<"$java_version" >&3
return 1
2014-02-10 15:22:21 +00:00
}
2019-11-02 11:33:08 +01:00
# keep for backwards compatibility
require_java7() {
require_java 7
}
2011-10-20 17:46:33 -05:00
require_gcc() {
2011-10-20 17:33:31 -05:00
local gcc="$(locate_gcc || true)"
2012-04-23 15:45:08 -05:00
2011-10-20 17:33:31 -05:00
if [ -z "$gcc" ]; then
{ echo
2014-02-10 20:12:21 +01:00
colorize 1 "ERROR"
echo ": This package must be compiled with GCC, but ruby-build couldn't"
2012-04-23 15:18:57 -05:00
echo "find a suitable \`gcc\` executable on your system. Please install GCC"
echo "and try again."
2011-10-20 17:33:31 -05:00
echo
2015-12-26 22:29:56 +01:00
if is_mac; then
2014-02-10 20:12:21 +01:00
colorize 1 "DETAILS"
echo ": Apple no longer includes the official GCC compiler with Xcode"
2012-04-23 15:45:08 -05:00
echo "as of version 4.2. Instead, the \`gcc\` executable is a symlink to"
echo "\`llvm-gcc\`, a modified version of GCC which outputs LLVM bytecode."
2011-10-30 10:31:40 -05:00
echo
2012-04-23 15:18:57 -05:00
echo "For most programs the \`llvm-gcc\` compiler works fine. However,"
echo "versions of Ruby older than 1.9.3-p125 are incompatible with"
echo "\`llvm-gcc\`. To build older versions of Ruby you must have the official"
echo "GCC compiler installed on your system."
2011-10-20 17:33:31 -05:00
echo
2013-04-05 12:19:39 -05:00
2014-02-10 20:12:21 +01:00
colorize 1 "TO FIX THE PROBLEM"
2013-04-05 12:19:39 -05:00
if type brew &>/dev/null; then
2018-11-11 17:42:19 -05:00
echo ": Install Homebrew's GCC package with this"
2014-02-10 20:12:21 +01:00
echo -n "command: "
2018-11-11 17:42:19 -05:00
colorize 4 "brew install gcc@4.9"
2013-04-05 12:19:39 -05:00
else
2014-02-10 20:12:21 +01:00
echo ": Install the official GCC compiler using these"
echo -n "packages: "
colorize 4 "https://github.com/kennethreitz/osx-gcc-installer/downloads"
2013-04-05 12:19:39 -05:00
fi
2014-02-10 20:12:21 +01:00
echo
2012-04-23 15:18:57 -05:00
echo
echo "You will need to install the official GCC compiler to build older"
echo "versions of Ruby even if you have installed Apple's Command Line Tools"
echo "for Xcode package. The Command Line Tools for Xcode package only"
echo "includes \`llvm-gcc\`."
2011-10-20 17:33:31 -05:00
fi
} >&3
return 1
2011-08-03 23:47:23 -05:00
fi
2011-10-20 17:33:31 -05:00
export CC="$gcc"
2015-12-26 22:29:56 +01:00
if is_mac -ge 1010; then
2014-10-27 12:47:33 +01:00
export MACOSX_DEPLOYMENT_TARGET=10.9
fi
2011-10-20 17:33:31 -05:00
}
locate_gcc() {
local gcc gccs
2011-12-30 13:35:18 -06:00
IFS=: gccs=($(gccs_in_path))
2015-10-28 12:17:43 +01:00
IFS="$OLDIFS"
2011-10-20 17:33:31 -05:00
verify_gcc "$CC" ||
verify_gcc "$(command -v gcc || true)" || {
for gcc in "${gccs[@]}"; do
verify_gcc "$gcc" && break || true
done
}
return 1
}
2011-12-30 13:35:18 -06:00
gccs_in_path() {
local gcc path paths
local gccs=()
IFS=: paths=($PATH)
2015-10-28 12:17:43 +01:00
IFS="$OLDIFS"
2011-12-30 13:35:18 -06:00
shopt -s nullglob
for path in "${paths[@]}"; do
for gcc in "$path"/gcc-*; do
gccs["${#gccs[@]}"]="$gcc"
done
done
shopt -u nullglob
printf :%s "${gccs[@]}"
}
2011-10-20 17:33:31 -05:00
verify_gcc() {
local gcc="$1"
if [ -z "$gcc" ]; then
return 1
fi
2014-10-27 12:59:26 +01:00
local version="$("$gcc" --version 2>/dev/null || true)"
2011-10-20 17:33:31 -05:00
if [ -z "$version" ]; then
return 1
fi
if echo "$version" | grep LLVM >/dev/null; then
return 1
fi
echo "$gcc"
2011-08-03 23:47:23 -05:00
}
2014-10-28 15:15:36 +01:00
require_llvm() {
local llvm_version="$1"
2015-12-26 22:29:56 +01:00
if is_mac -ge 1010; then
2014-10-28 15:15:36 +01:00
if [[ "$RUBY_CONFIGURE_OPTS" != *--llvm-* ]]; then
2015-05-26 10:50:20 +02:00
case "$llvm_version" in
3.2 )
2015-01-02 11:56:44 -08:00
package_option ruby configure --prebuilt-name="llvm-3.2-x86_64-apple-darwin13.tar.bz2"
2015-05-26 10:50:20 +02:00
;;
2016-09-18 01:27:46 +01:00
3.[56] )
2015-05-26 10:50:20 +02:00
local llvm_config="$(locate_llvm "$llvm_version")"
if [ -n "$llvm_config" ]; then
2015-01-02 11:56:44 -08:00
package_option ruby configure --llvm-config="$llvm_config"
else
2017-03-14 11:28:18 +09:00
local homebrew_package="llvm@$llvm_version"
2015-01-02 11:56:44 -08:00
{ echo
colorize 1 "ERROR"
echo ": Rubinius will not be able to compile using Apple's LLVM-based "
2016-09-18 01:27:46 +01:00
echo "build tools on OS X. You will need to install LLVM $llvm_version first."
2015-01-02 11:56:44 -08:00
echo
colorize 1 "TO FIX THE PROBLEM"
echo ": Install Homebrew's llvm package with this"
echo -n "command: "
2017-03-14 11:28:18 +09:00
colorize 4 "brew install $homebrew_package"
2015-01-02 11:56:44 -08:00
echo
} >&3
return 1
fi
2015-05-26 10:50:20 +02:00
;;
esac
2014-10-28 15:15:36 +01:00
fi
fi
}
2015-05-26 10:50:20 +02:00
locate_llvm() {
local llvm_version="$1"
local package llvm_config
shopt -s nullglob
for package in `brew list 2>/dev/null | grep "^llvm"`; do
llvm_config="$(echo "$(brew --prefix "$package")/bin/llvm-config"*)"
if [ -n "$llvm_config" ] && [[ "$("$llvm_config" --version)" = "$llvm_version"* ]]; then
echo "$llvm_config"
break
fi
done
shopt -u nullglob
}
2013-07-09 20:40:45 -04:00
needs_yaml() {
[[ "$RUBY_CONFIGURE_OPTS" != *--with-libyaml-dir=* ]] &&
! use_homebrew_yaml
}
use_homebrew_yaml() {
local libdir="$(brew --prefix libyaml 2>/dev/null || true)"
if [ -d "$libdir" ]; then
2019-06-24 13:31:13 +06:00
echo "ruby-build: using libyaml from homebrew"
2013-07-09 20:40:45 -04:00
package_option ruby configure --with-libyaml-dir="$libdir"
else
return 1
fi
}
2016-11-04 15:55:31 +09:00
use_freebsd_pkg() {
2016-11-04 17:16:46 +09:00
# check if FreeBSD
2016-11-04 15:55:31 +09:00
if [ "FreeBSD" = "$(uname -s)" ]; then
2016-12-28 21:34:38 +09:00
# use openssl if installed from Ports Collection
if [ -f /usr/local/include/openssl/ssl.h ]; then
package_option ruby configure --with-openssl-dir="/usr/local"
fi
2016-11-04 17:16:46 +09:00
2016-12-28 21:34:38 +09:00
# check if 11-R or later
release="$(uname -r)"
if [ "${release%%.*}" -ge 11 ]; then
# prefers readline to compile most of ruby versions
if pkg info -e readline > /dev/null; then
# use readline from Ports Collection
package_option ruby configure --with-readline-dir="/usr/local"
elif pkg info -e libedit > /dev/null; then
# use libedit from Ports Collection
package_option ruby configure --enable-libedit
package_option ruby configure --with-libedit-dir="/usr/local"
2016-11-04 15:55:31 +09:00
fi
2016-12-28 21:34:38 +09:00
fi
2016-11-04 15:55:31 +09:00
fi
}
2013-12-11 23:49:18 +01:00
use_homebrew_readline() {
if [[ "$RUBY_CONFIGURE_OPTS" != *--with-readline-dir=* ]]; then
local libdir="$(brew --prefix readline 2>/dev/null || true)"
if [ -d "$libdir" ]; then
2019-06-24 13:31:13 +06:00
echo "ruby-build: using readline from homebrew"
2013-12-11 23:49:18 +01:00
package_option ruby configure --with-readline-dir="$libdir"
else
return 1
fi
fi
}
2013-02-04 17:50:12 -06:00
has_broken_mac_openssl() {
2017-06-12 17:21:32 +02:00
is_mac || return 1
local openssl_version="$(/usr/bin/openssl version 2>/dev/null || true)"
2022-07-10 12:37:44 +02:00
[[ $openssl_version = "OpenSSL 0.9.8"?* || $openssl_version = "LibreSSL"* ]]
2013-02-04 17:50:12 -06:00
}
2013-01-23 22:03:53 -07:00
2022-07-10 12:37:44 +02:00
system_openssl_version() {
2022-07-25 18:36:29 +02:00
local version_text=$(printf '#include <openssl/opensslv.h>\nOPENSSL_VERSION_TEXT\n' | cc -xc -E - 2>/dev/null | tail -n 1)
2022-07-10 12:37:44 +02:00
if [[ $version_text == *"OpenSSL "* ]]; then
local version=${version_text#*OpenSSL }
version=${version%% *}
echo $version | sed 's/[^0-9]//g' | sed 's/^0*//'
else
2022-07-25 18:36:29 +02:00
echo "No system openssl version was found, ensure openssl headers are installed (https://github.com/rbenv/ruby-build/wiki#suggested-build-environment)" >&2
2022-07-10 12:37:44 +02:00
echo 000
fi
}
# openssl gem 1.1.1
needs_openssl_096_102() {
[[ "$RUBY_CONFIGURE_OPTS" == *--with-openssl-dir=* ]] && return 1
has_broken_mac_openssl && return 0
local version=$(system_openssl_version)
(( $version < 96 || $version >= 110 ))
}
# openssl gem 2.2.1
needs_openssl_101_111() {
[[ "$RUBY_CONFIGURE_OPTS" == *--with-openssl-dir=* ]] && return 1
has_broken_mac_openssl && return 0
local version=$(system_openssl_version)
(( $version < 101 || $version >= 300 ))
}
# openssl gem 3.0.0
needs_openssl_102_300() {
[[ "$RUBY_CONFIGURE_OPTS" == *--with-openssl-dir=* ]] && return 1
has_broken_mac_openssl && return 0
local version=$(system_openssl_version)
(( $version < 102 || $version >= 400 ))
2022-05-11 13:29:18 +09:00
}
2019-11-08 15:31:13 -05:00
use_homebrew_openssl() {
local ssldir="$(brew --prefix openssl@1.1 2>/dev/null || true)"
if [ -d "$ssldir" ]; then
echo "ruby-build: using openssl from homebrew"
package_option ruby configure --with-openssl-dir="$ssldir"
else
2019-11-21 15:59:28 +01:00
colorize 1 "ERROR openssl@1.1 from Homebrew is required, run 'brew install openssl@1.1'"
2019-11-08 15:31:13 -05:00
return 1
fi
}
2022-05-11 13:29:18 +09:00
build_package_openssl() {
2013-02-04 17:50:12 -06:00
# Install to a subdirectory since we don't want shims for bin/openssl.
OPENSSL_PREFIX_PATH="${PREFIX_PATH}/openssl"
2013-01-23 22:03:53 -07:00
2013-02-04 17:50:12 -06:00
# Put openssl.conf, certs, etc in ~/.rbenv/versions/*/openssl/ssl
OPENSSLDIR="${OPENSSLDIR:-$OPENSSL_PREFIX_PATH/ssl}"
2013-01-23 22:03:53 -07:00
2013-02-04 17:50:12 -06:00
# Tell Ruby to use this openssl for its extension.
package_option ruby configure --with-openssl-dir="$OPENSSL_PREFIX_PATH"
2017-11-06 20:53:31 -06:00
# Make sure pkg-config finds our build first.
export PKG_CONFIG_PATH="${OPENSSL_PREFIX_PATH}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
2013-02-08 14:54:54 -07:00
# Hint OpenSSL that we prefer a 64-bit build.
export KERNEL_BITS="64"
OPENSSL_CONFIGURE="${OPENSSL_CONFIGURE:-./config}"
2013-02-04 17:50:12 -06:00
2017-02-01 18:30:27 +01:00
local nokerberos
[[ "$1" != openssl-1.0.* ]] || nokerberos=1
2022-07-15 11:27:30 +09:00
if [[ "$1" == openssl-1.1.1q ]]; then
# https://github.com/rbenv/ruby-build/discussions/2009#discussioncomment-3146585
2022-07-21 18:59:59 +09:00
# https://github.com/openssl/openssl/commit/f9e578e720bb35228948564192adbe3bc503d5fb.diff
patch -p1 <<EOF
diff --git a/test/v3ext.c b/test/v3ext.c
index 926f3884b13..a8ab64b2714 100644
--- a/test/v3ext.c
+++ b/test/v3ext.c
@@ -8,6 +8,7 @@
*/
#include <stdio.h>
+#include <string.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/pem.h>
EOF
2022-07-15 11:27:30 +09:00
fi
2017-02-01 18:30:27 +01:00
# Compile a shared lib with zlib dynamically linked.
package_option openssl configure --openssldir="$OPENSSLDIR" zlib-dynamic no-ssl3 shared ${nokerberos:+no-ssl2 no-krb5}
2013-02-04 17:50:12 -06:00
# Default MAKE_OPTS are -j 2 which can confuse the build. Thankfully, make
# gives precedence to the last -j option, so we can override that.
package_option openssl make -j 1
2022-05-11 13:24:21 +02:00
# Use install_sw install_ssldirs instead of install to skip building docs which is slow.
# OpenSSL 1.1+ also needs install_ssldirs, 1.0 does not have that target.
if [[ "$1" == openssl-1.0.* ]]; then
MAKE_INSTALL_TARGET="install_sw" build_package_standard "$@"
else
MAKE_INSTALL_TARGET="install_sw install_ssldirs" build_package_standard "$@"
fi
2013-01-23 22:03:53 -07:00
2013-02-24 20:06:08 -07:00
local pem_file="$OPENSSLDIR/cert.pem"
2022-05-11 13:29:18 +09:00
if is_mac; then
# Extract root certs from the system keychain in .pem format.
security find-certificate -a -p /Library/Keychains/System.keychain > "$pem_file"
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >> "$pem_file"
elif [ -e /etc/pki/tls/cert.pem ]; then # RedHat
# See https://github.com/rubygems/rubygems/issues/2415#issuecomment-509806259
rm -rf "$OPENSSLDIR/certs" "$pem_file"
ln -s /etc/pki/tls/certs "$OPENSSLDIR/certs"
ln -s /etc/pki/tls/cert.pem "$pem_file"
elif [ -e /etc/ssl/certs/ca-certificates.crt ]; then # Debian
# See https://github.com/rubygems/rubygems/issues/2415#issuecomment-509806259
rm -rf "$OPENSSLDIR/certs" "$pem_file"
ln -s /etc/ssl/certs "$OPENSSLDIR/certs"
ln -s /etc/ssl/certs/ca-certificates.crt "$pem_file"
elif type -p openssl >/dev/null; then
# symlink to the system openssl certs
local SYSTEM_OPENSSLDIR
SYSTEM_OPENSSLDIR=$(openssl version -d 2>/dev/null | cut -d'"' -f2)
if [ -n "$SYSTEM_OPENSSLDIR" ]; then
ln -sf "$SYSTEM_OPENSSLDIR/cert.pem" "$OPENSSLDIR/cert.pem"
ln -snf "$SYSTEM_OPENSSLDIR/certs" "$OPENSSLDIR/certs"
fi
else
echo "Could not find OpenSSL certificates" >&2
exit 1
fi
2013-01-23 22:03:53 -07:00
}
# Post-install check that the openssl extension was built.
build_package_verify_openssl() {
2014-09-06 00:22:50 -07:00
"$RUBY_BIN" -e '
manager = ARGV[0]
packages = {
"apt-get" => Hash.new {|h,k| "lib#{k}-dev" }.update(
"openssl" => "libssl-dev",
"zlib" => "zlib1g-dev"
),
"yum" => Hash.new {|h,k| "#{k}-devel" }.update(
"yaml" => "libyaml-devel"
)
}
failed = %w[openssl readline zlib yaml].reject do |lib|
begin
require lib
rescue LoadError
$stderr.puts "The Ruby #{lib} extension was not compiled."
end
end
if failed.size > 0
$stderr.puts "ERROR: Ruby install aborted due to missing extensions"
$stderr.print "Try running `%s install -y %s` to fetch missing dependencies.\n\n" % [
manager,
failed.map { |lib| packages.fetch(manager)[lib] }.join(" ")
] unless manager.empty?
$stderr.puts "Configure options used:"
require "rbconfig"; require "shellwords"
RbConfig::CONFIG.fetch("configure_args").shellsplit.each { |arg| $stderr.puts " #{arg}" }
exit 1
end
' "$(basename "$(type -p yum apt-get | head -1)")" >&4 2>&1
2013-01-23 22:03:53 -07:00
}
2013-10-27 21:32:18 +01:00
# Ensure that directories listed in LDFLAGS exist
build_package_ldflags_dirs() {
2015-11-16 11:07:18 +01:00
local arg dir
set - $LDFLAGS
while [ $# -gt 0 ]; do
dir=""
case "$1" in
-L ) dir="$2" ;;
-L* ) dir="${1#-L}" ;;
2013-10-27 21:32:18 +01:00
esac
2015-11-16 11:07:18 +01:00
[ -z "$dir" ] || mkdir -p "$dir"
shift 1
2013-10-27 21:32:18 +01:00
done
}
2022-07-13 14:20:27 +00:00
build_package_enable_yjit() {
2022-07-14 13:37:08 +00:00
# If YJIT is explicitly enabled or disabled, don't change the config
2022-07-14 15:19:18 +01:00
if [[ " ${RUBY_CONFIGURE_OPTS} " == *" --enable-yjit"* || " ${RUBY_CONFIGURE_OPTS} " == *" --disable-yjit"* ]]; then
return 0
fi
2022-07-13 14:20:27 +00:00
2022-07-14 13:37:08 +00:00
# If we aren't on x86_64, don't enable YJIT
2022-07-14 15:21:06 +01:00
[ "$(uname -m)" = "x86_64" ] || return 0
2022-07-14 08:47:59 +00:00
2022-07-14 15:20:23 +01:00
local rustc_ver="$(rustc --version 2>/dev/null)"
[ -n "$rustc_ver" ] || return 0
2022-07-14 13:37:08 +00:00
# Some kind of built-in bash comparison for dotted version strings would be awesome.
2022-07-14 19:39:51 +02:00
if [[ "${rustc_ver}" == *"rustc 1."[6789]* ]]; then
2022-07-14 13:38:43 +00:00
echo "Building with YJIT by default because ${rustc_ver} is installed; add RUBY_CONFIGURE_OPTS='--disable-yjit' to disable explicitly" >&3
2022-07-14 13:37:08 +00:00
package_option ruby configure --enable-yjit
else
2022-07-14 13:38:43 +00:00
echo "rustc 1.60+ is not installed, YJIT will not be built; if you want to use YJIT, install rustc 1.60+ and rerun this command." >&3
2022-07-13 14:20:27 +00:00
fi
}
2016-03-13 16:23:20 -07:00
build_package_enable_shared() {
2021-05-03 12:52:47 +02:00
if [[ " ${RUBY_CONFIGURE_OPTS} " != *" --disable-shared"* ]]; then
package_option ruby configure --enable-shared
fi
2016-03-13 16:23:20 -07:00
}
2013-10-28 00:25:02 +01:00
build_package_auto_tcltk() {
2015-12-26 22:29:56 +01:00
if is_mac && [ ! -d /usr/include/X11 ]; then
2013-10-28 00:25:02 +01:00
if [ -d /opt/X11/include ]; then
if [[ "$CPPFLAGS" != *-I/opt/X11/include* ]]; then
export CPPFLAGS="-I/opt/X11/include $CPPFLAGS"
fi
else
package_option ruby configure --without-tk
fi
fi
}
2013-10-26 15:48:25 +02:00
rake() {
if [ -e "./Gemfile" ]; then
bundle exec rake "$@"
else
2013-10-26 17:39:55 +02:00
isolated_gem_dependency "rake --version" rake -v '~> 10.1.0'
2013-10-26 15:48:25 +02:00
command rake "$@"
fi
}
2013-10-26 17:39:55 +02:00
bundle() {
isolated_gem_dependency "bundle --version" bundler -v '~> 1.3.5'
command bundle "$@"
}
isolated_gem_dependency() {
2013-10-29 14:03:26 +01:00
set +E
( command $1 &>/dev/null ) || {
set -E
2013-10-26 17:39:55 +02:00
shift 1
isolated_gem_install "$@"
2013-10-29 14:03:26 +01:00
}
set -E
2013-10-26 17:39:55 +02:00
}
isolated_gem_install() {
export GEM_HOME="${PWD}/.gem"
export PATH="${GEM_HOME}/bin:${PATH}"
gem install "$@"
}
2013-12-11 21:16:47 +01:00
apply_ruby_patch() {
2014-04-21 16:01:06 +02:00
local patchfile
2013-12-11 21:16:47 +01:00
case "$1" in
2018-06-15 18:04:28 +02:00
ruby-* | jruby-* | rubinius-* | truffleruby-* )
2014-04-21 17:24:11 +02:00
patchfile="$(mktemp "${TMP}/ruby-patch.XXXXXX")"
2014-04-21 16:01:06 +02:00
cat "${2:--}" >"$patchfile"
local striplevel=0
2018-07-27 11:24:01 +02:00
grep -q '^--- a/' "$patchfile" && striplevel=1
2014-04-21 16:01:06 +02:00
patch -p$striplevel --force -i "$patchfile"
2013-12-11 21:16:47 +01:00
;;
esac
}
2011-09-06 14:56:07 -05:00
version() {
2014-08-14 17:35:39 -07:00
local git_revision
# Read the revision from git if the remote points to "ruby-build" repository
if GIT_DIR="$RUBY_BUILD_INSTALL_PREFIX/.git" git remote -v 2>/dev/null | grep -q /ruby-build; then
git_revision="$(GIT_DIR="$RUBY_BUILD_INSTALL_PREFIX/.git" git describe --tags HEAD 2>/dev/null || true)"
git_revision="${git_revision#v}"
fi
echo "ruby-build ${git_revision:-$RUBY_BUILD_VERSION}"
2011-09-06 14:56:07 -05:00
}
2011-08-02 08:46:34 -05:00
usage() {
2014-11-26 20:01:38 -08:00
sed -ne '/^#/!q;s/.\{1,2\}//;1,2d;p' < "$0"
2014-11-26 19:51:11 -08:00
[ -z "$1" ] || exit "$1"
2011-08-02 08:46:34 -05:00
}
2020-03-06 22:14:45 +09:00
# list all versions
2011-08-07 12:38:47 -05:00
list_definitions() {
2014-08-16 20:01:00 -07:00
{ for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
[ -d "$DEFINITION_DIR" ] && ls "$DEFINITION_DIR"
2011-08-07 12:38:47 -05:00
done
2014-09-28 09:11:42 -06:00
} | sort_versions | uniq
2011-08-07 12:38:47 -05:00
}
2020-03-06 22:14:45 +09:00
# list only latest stable versions excluding RC, preview, dev and EoL'ed
2020-03-07 21:06:01 +09:00
list_maintained_versions() {
2020-01-30 14:48:43 +09:00
{ for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
2020-03-03 15:13:39 +09:00
[ -d "$DEFINITION_DIR" ] && \
2020-03-07 21:26:47 +09:00
grep -L -e warn_eol "$DEFINITION_DIR"/* 2>/dev/null | \
sed 's|.*/||' | \
2020-03-03 15:13:39 +09:00
grep -v -e '-rc[0-9]*$' -e '-preview[0-9]*$' -e '-dev$'
2020-01-30 14:48:43 +09:00
done
2020-03-07 21:06:01 +09:00
} | extract_latest_versions | sort_versions | uniq
2020-03-06 22:14:45 +09:00
}
2020-03-07 21:06:01 +09:00
extract_latest_versions() {
2020-03-06 22:14:45 +09:00
# sort in this function looks redundunt but it is necessary
# rbx-3.99 appears latest unless the sort
2020-07-13 20:53:14 +02:00
sed 'h; s/[-]/./g; s/.p\([[:digit:]]\)/.z.\1/; s/$/.z/; G; s/\n/ /' | \
2020-03-06 22:14:45 +09:00
LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | \
2020-07-13 20:53:14 +02:00
sed 's/[.]/ /; s/[0-9].*z //; s/^\([0-9].[0-9]\)/mri\1 \1/' | \
2020-03-06 22:14:45 +09:00
awk '{ latest[$1] =$2 } END{ for(key in latest) { print latest[key] } }'
2020-01-30 14:48:43 +09:00
}
2014-09-08 13:06:48 -07:00
sort_versions() {
2020-07-13 20:53:14 +02:00
sed 'h; s/[-]/./g; s/.p\([[:digit:]]\)/.z.\1/; s/$/.z/; G; s/\n/ /' | \
2014-09-08 13:06:48 -07:00
LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}'
}
2011-08-07 12:38:47 -05:00
2011-08-02 08:46:34 -05:00
2011-08-07 12:38:14 -05:00
unset VERBOSE
2012-08-15 13:28:01 -05:00
unset KEEP_BUILD_PATH
2013-12-11 21:16:47 +01:00
unset HAS_PATCH
2014-07-14 15:48:56 +09:00
unset IPV4
unset IPV6
2014-08-16 19:58:43 -07:00
2014-08-14 17:35:39 -07:00
RUBY_BUILD_INSTALL_PREFIX="$(abs_dirname "$0")/.."
2011-08-07 12:36:08 -05:00
2014-08-14 17:35:39 -07:00
IFS=: RUBY_BUILD_DEFINITIONS=($RUBY_BUILD_DEFINITIONS ${RUBY_BUILD_ROOT:-$RUBY_BUILD_INSTALL_PREFIX}/share/ruby-build)
2014-08-16 20:01:00 -07:00
IFS="$OLDIFS"
2012-08-15 13:28:01 -05:00
parse_options "$@"
2011-08-07 12:38:14 -05:00
2012-08-15 13:28:01 -05:00
for option in "${OPTIONS[@]}"; do
case "$option" in
"h" | "help" )
2014-11-26 20:01:38 -08:00
version
echo
usage 0
2012-08-15 13:28:01 -05:00
;;
"definitions" )
list_definitions
exit 0
;;
2020-02-19 11:01:43 +09:00
"l" | "list")
2020-03-07 21:06:01 +09:00
list_maintained_versions
2020-01-30 14:48:43 +09:00
exit 0
;;
2012-08-15 13:28:01 -05:00
"k" | "keep" )
KEEP_BUILD_PATH=true
;;
"v" | "verbose" )
VERBOSE=true
;;
2013-12-11 21:16:47 +01:00
"p" | "patch" )
HAS_PATCH=true
;;
2014-07-14 15:48:56 +09:00
"4" | "ipv4")
IPV4=true
;;
"6" | "ipv6")
IPV6=true
;;
2012-08-15 13:28:01 -05:00
"version" )
version
exit 0
;;
esac
done
2011-08-07 12:38:14 -05:00
2014-11-26 19:51:11 -08:00
[ "${#ARGUMENTS[@]}" -eq 2 ] || usage 1 >&2
2014-11-26 19:45:52 -08:00
2012-08-15 13:28:01 -05:00
DEFINITION_PATH="${ARGUMENTS[0]}"
2011-08-02 08:46:34 -05:00
if [ -z "$DEFINITION_PATH" ]; then
2014-11-26 19:51:11 -08:00
usage 1 >&2
2014-02-26 04:23:56 -05:00
elif [ ! -f "$DEFINITION_PATH" ]; then
2014-08-16 20:01:00 -07:00
for DEFINITION_DIR in "${RUBY_BUILD_DEFINITIONS[@]}"; do
if [ -f "${DEFINITION_DIR}/${DEFINITION_PATH}" ]; then
DEFINITION_PATH="${DEFINITION_DIR}/${DEFINITION_PATH}"
break
fi
done
if [ ! -f "$DEFINITION_PATH" ]; then
2011-08-07 12:36:08 -05:00
echo "ruby-build: definition not found: ${DEFINITION_PATH}" >&2
2013-03-21 12:40:53 -05:00
exit 2
2011-08-07 12:36:08 -05:00
fi
2011-08-02 08:46:34 -05:00
fi
2012-08-15 13:28:01 -05:00
PREFIX_PATH="${ARGUMENTS[1]}"
2011-09-06 16:49:38 -05:00
if [ -z "$PREFIX_PATH" ]; then
2014-11-26 19:51:11 -08:00
usage 1 >&2
2013-10-26 05:24:25 +02:00
elif [ "${PREFIX_PATH#/}" = "$PREFIX_PATH" ]; then
PREFIX_PATH="${PWD}/${PREFIX_PATH}"
2011-08-02 08:46:34 -05:00
fi
2011-09-06 13:42:44 -05:00
if [ -z "$TMPDIR" ]; then
TMP="/tmp"
else
TMP="${TMPDIR%/}"
fi
2014-09-08 10:43:57 -07:00
# Check if TMPDIR is accessible and can hold executables.
tmp_executable="${TMP}/ruby-build-test.$$"
noexec=""
if mkdir -p "$TMP" && touch "$tmp_executable" 2>/dev/null; then
2014-10-17 11:15:42 -04:00
cat > "$tmp_executable" <<-EOF
#!${BASH}
exit 0
EOF
2014-09-08 10:43:57 -07:00
chmod +x "$tmp_executable"
else
2013-10-28 00:44:15 +01:00
echo "ruby-build: TMPDIR=$TMP is set to a non-accessible location" >&2
exit 1
fi
2014-09-08 10:43:57 -07:00
"$tmp_executable" 2>/dev/null || noexec=1
rm -f "$tmp_executable"
if [ -n "$noexec" ]; then
echo "ruby-build: TMPDIR=$TMP cannot hold executables (partition possibly mounted with \`noexec\`)" >&2
exit 1
fi
2013-10-28 00:44:15 +01:00
2017-01-19 10:05:20 +09:00
# Apply following work around, if gcc is not installed.
2017-01-18 11:02:37 +09:00
if [ -z "$(locate_gcc)" ]; then
# Work around warnings building Ruby 2.0 on Clang 2.x:
# pass -Wno-error=shorten-64-to-32 if the compiler accepts it.
#
# When we set CFLAGS, Ruby won't apply its default flags, though. Since clang
# builds 1.9.x and 2.x only, where -O3 is default, we can safely set that flag.
# Ensure it's the first flag since later flags take precedence.
if "${CC:-cc}" -x c /dev/null -E -Wno-error=shorten-64-to-32 &>/dev/null; then
RUBY_CFLAGS="-O3 -Wno-error=shorten-64-to-32 $RUBY_CFLAGS"
fi
2013-02-27 12:45:26 -06:00
fi
2013-02-04 16:15:30 -06:00
2013-01-29 18:09:13 -06:00
if [ -z "$MAKE" ]; then
2016-04-14 05:11:23 +09:00
if [ "FreeBSD" = "$(uname -s)" ]; then
2019-11-20 18:11:43 +09:00
# Workaround for Ruby bug 16331: https://bugs.ruby-lang.org/issues/16331
# Due to this bug, build will fail with FreeBSD's make after #1368
# The bug is already fixed in upstream but GNU make is still required
# when building older releases of Ruby. Use GNU make rather than switching
# depending of Ruby version.
export MAKE="gmake"
2013-02-21 22:11:17 +01:00
else
export MAKE="make"
fi
2013-01-29 18:09:13 -06:00
fi
2012-11-13 17:36:39 -06:00
if [ -n "$RUBY_BUILD_CACHE_PATH" ] && [ -d "$RUBY_BUILD_CACHE_PATH" ]; then
2012-11-13 17:38:37 -06:00
RUBY_BUILD_CACHE_PATH="${RUBY_BUILD_CACHE_PATH%/}"
2012-11-13 17:36:39 -06:00
else
unset RUBY_BUILD_CACHE_PATH
Simple, optional tarball cache support
Rationale:
Both in development and in production, some usage patterns of ruby-build
are slowed down by the download phase. In scenarios such as
troubleshooting failing builds or with provisioning situations (chef,
vagrant...) the repeated download is unnerving, bandwidth wasting and
simply against etiquette towards tarball hosters.
It also happens that some source sites happen to be down and in such
cases it is helpful to be able to sideload sources to rbenv.
Behavior:
By default nothing changes.
If the variable CACHE_PATH is set, then ruby-build will use that
directory to store a successful download, and will check before
downloading if the tarball is already there, in which case downloading
is skipped.
The file is first downloaded as before in the tmp subdirectory and only
moved afterwards, thus ensuring consistency.
There is no default cache path and the optional variable is to be set by
hand, ensuring people know what they're doing when using ruby-build.
Additionnally, rbenv-install will helpfully set CACHE_PATH if and only
if a RBENV_ROOT/cache directory exists. Again, the directory has to be
created manually.
The CACHE_PATH variable internally ends with a slash to mutualize
non-cached cases. Still, consistency is ensured whether or not a slash
is provided externally.
Notes:
I'm not quite sure CACHE_PATH is a good name, maybe
RUBY_BUILD_CACHE_PATH is better and less conflicting.
2012-11-07 16:43:15 +01:00
fi
2020-07-18 00:36:59 +08:00
if [ -z "$RUBY_BUILD_MIRROR_URL" -a -z "$RUBY_BUILD_MIRROR_PACKAGE_URL" ]; then
2014-09-03 12:52:20 -07:00
RUBY_BUILD_MIRROR_URL="https://dqw8nmjcqpjn7.cloudfront.net"
2015-12-12 23:33:33 +09:00
RUBY_BUILD_DEFAULT_MIRROR=1
2012-11-14 20:33:48 -06:00
else
RUBY_BUILD_MIRROR_URL="${RUBY_BUILD_MIRROR_URL%/}"
2015-12-12 23:33:33 +09:00
RUBY_BUILD_DEFAULT_MIRROR=
2012-11-14 20:33:48 -06:00
fi
2016-01-18 11:44:14 -05:00
if [ -n "$RUBY_BUILD_SKIP_MIRROR" ] || ! has_checksum_support compute_sha2; then
2020-07-18 00:36:59 +08:00
unset RUBY_BUILD_MIRROR_URL RUBY_BUILD_MIRROR_PACKAGE_URL
2012-11-15 16:03:39 -06:00
fi
2016-02-13 03:51:31 +00:00
ARIA2_OPTS="${RUBY_BUILD_ARIA2_OPTS} ${IPV4+--disable-ipv6=true} ${IPV6+--disable-ipv6=false}"
CURL_OPTS="${RUBY_BUILD_CURL_OPTS} ${IPV4+--ipv4} ${IPV6+--ipv6}"
WGET_OPTS="${RUBY_BUILD_WGET_OPTS} ${IPV4+--inet4-only} ${IPV6+--inet6-only}"
2011-08-07 12:33:09 -05:00
SEED="$(date "+%Y%m%d%H%M%S").$$"
2011-09-06 13:42:44 -05:00
LOG_PATH="${TMP}/ruby-build.${SEED}.log"
2011-08-02 08:46:34 -05:00
RUBY_BIN="${PREFIX_PATH}/bin/ruby"
CWD="$(pwd)"
2012-11-13 17:44:07 -06:00
if [ -z "$RUBY_BUILD_BUILD_PATH" ]; then
2019-11-02 19:17:41 +01:00
BUILD_PATH="$(mktemp -d "${LOG_PATH%.log}.XXXXXX")"
2012-04-28 14:09:06 -07:00
else
2012-11-13 17:44:07 -06:00
BUILD_PATH="$RUBY_BUILD_BUILD_PATH"
2012-04-28 14:09:06 -07:00
fi
2011-08-07 15:41:20 -05:00
exec 4<> "$LOG_PATH" # open the log file at fd 4
if [ -n "$VERBOSE" ]; then
tail -f "$LOG_PATH" &
2013-02-25 11:43:36 +09:00
TAIL_PID=$!
trap "kill $TAIL_PID" SIGINT SIGTERM EXIT
2022-08-06 12:39:15 +02:00
else
if [ -z "$RUBY_BUILD_TESTING" ]; then
echo "To follow progress, use 'tail -f $LOG_PATH' or pass --verbose" >&2
fi
2011-08-07 15:41:20 -05:00
fi
2013-10-27 13:49:59 +09:00
export LDFLAGS="-L${PREFIX_PATH}/lib ${LDFLAGS}"
export CPPFLAGS="-I${PREFIX_PATH}/include ${CPPFLAGS}"
2011-08-05 11:29:36 -05:00
unset RUBYOPT
unset RUBYLIB
2011-08-02 08:46:34 -05:00
2011-08-07 15:41:20 -05:00
trap build_failed ERR
2012-04-28 14:09:06 -07:00
mkdir -p "$BUILD_PATH"
2011-08-02 08:46:34 -05:00
source "$DEFINITION_PATH"
2012-04-28 14:15:01 -07:00
[ -z "${KEEP_BUILD_PATH}" ] && rm -fr "$BUILD_PATH"
2011-08-07 15:41:20 -05:00
trap - ERR