blob: ef6df36af60826a74eb765e6d4141b5d1d6b08d1 [file] [log] [blame]
#!/bin/sh -e
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
# next steps:
# try running this, figure out what to do with the vars in the generated files
# in the bottom
# cd into this script’s directory
rootdir="$(cd "${0%/*}" 2>/dev/null; echo "$PWD")"
basename=`basename $0`
PACKAGE_AUTHOR_NAME="The Apache Software Foundation"
REBAR3_BRANCH="3.21.0"
ERLFMT_VERSION="v1.3.0"
# TEST=0
WITH_PROPER="true"
WITH_FAUXTON=1
WITH_DOCS=1
WITH_NOUVEAU="false"
WITH_CLOUSEAU=0
ERLANG_MD5="false"
SKIP_DEPS=0
WITH_SPIDERMONKEY="true"
run_erlang() {
erl -noshell -eval "$1" -eval "halt()."
}
COUCHDB_USER="$(whoami 2>/dev/null || echo couchdb)"
JS_ENGINE=${JS_ENGINE:-"spidermonkey"}
SM_VSN=${SM_VSN:-"91"}
CLOUSEAU_MTH=${CLOUSEAU_MTH:-"dist"}
CLOUSEAU_URI=${CLOUSEAU_URI:-"https://github.com/cloudant-labs/clouseau/releases/download/%s/clouseau-%s-dist.zip"}
CLOUSEAU_VSN=${CLOUSEAU_VSN:-"2.22.0"}
CLOUSEAU_DIR="$(pwd)"/clouseau
ARCH="$(uname -m)"
ERLANG_VER="$(run_erlang 'io:put_chars(erlang:system_info(otp_release)).')"
ERLANG_OS="$(run_erlang 'case os:type() of {OS, _} -> io:format("~s~n", [OS]) end.')"
. ${rootdir}/version.mk
COUCHDB_VERSION=${vsn_major}.${vsn_minor}.${vsn_patch}
display_help () {
cat << EOF
Usage: $basename [OPTION]
The $basename command is responsible for generating the build
system for Apache CouchDB.
Options:
-h | --help display a short help message and exit
-u | --user USER set the username to run as (defaults to $COUCHDB_USER)
--disable-fauxton do not build Fauxton
--disable-docs do not build any documentation or manpages
--enable-nouveau enable the new experimental search module
--enable-clouseau enable the Clouseau search module
--erlang-md5 use erlang for md5 hash operations
--dev alias for --disable-docs --disable-fauxton
--spidermonkey-version VSN specify the version of SpiderMonkey to use (defaults to $SM_VSN)
--clouseau-method MTH specify the method for Clouseau to deploy: git or dist (defaults to $CLOUSEAU_MTH)
--clouseau-uri URI specify the location for retrieving Clouseau (defaults $(printf "$CLOUSEAU_URI" "$CLOUSEAU_VSN" "$CLOUSEAU_VSN"))
--clouseau-version VSN specify the version (tag/branch for git) of Clouseau to use (defaults to $CLOUSEAU_VSN)
--skip-deps do not update erlang dependencies
--rebar=PATH use rebar by specified path (version >=2.6.0 && <3.0 required)
--rebar3=PATH use rebar3 by specified path
--erlfmt=PATH use erlfmt by specified path
--js-engine=ENGINE use js engine: spidermonkey or quickjs, defaults to spidermonkey
--disable-spidermonkey disable spidermonkey, don't try to build it
EOF
}
parse_opts() {
while :; do
case $1 in
-h|--help)
display_help
exit
;;
--without-proper)
WITH_PROPER="false"
shift
continue
;;
--disable-fauxton)
WITH_FAUXTON=0
shift
continue
;;
--disable-docs)
WITH_DOCS=0
shift
continue
;;
--enable-nouveau)
WITH_NOUVEAU="true"
shift
continue
;;
--enable-clouseau)
if [ "${ERLANG_VER}" -gt 25 ]; then
echo "Warning: Clouseau is not working with OTP 26 or later at the moment, therefore it is not configured. Continue in 5 seconds..."
sleep 5
else
WITH_CLOUSEAU=1
fi
shift
continue
;;
--erlang-md5)
ERLANG_MD5="true"
shift
continue
;;
--dev)
WITH_DOCS=0
WITH_FAUXTON=0
shift
continue
;;
--dev-with-nouveau)
WITH_DOCS=0
WITH_FAUXTON=0
WITH_NOUVEAU="true"
shift
continue
;;
--skip-deps)
SKIP_DEPS=1
shift
continue
;;
--rebar)
if [ -x "$2" ]; then
version=`$2 --version 2> /dev/null | grep -o "2\.[6-9]\.[0-9]"`
if [ $? -ne 0 ]; then
printf 'Rebar >=2.6.0 and <3.0.0 required' >&2
exit 1
fi
eval REBAR=$2
shift 2
continue
else
printf 'ERROR: "--rebar" requires valid path to executable.\n' >&2
exit 1
fi
;;
--rebar3)
if [ -x "$2" ]; then
eval REBAR3=$2
shift 2
continue
else
printf 'ERROR: "--rebar3" requires valid path to executable.\n' >&2
exit 1
fi
;;
--erlfmt)
if [ -x "$2" ]; then
eval ERLFMT=$2
shift 2
continue
else
printf 'ERROR: "--erlfmt" requires valid path to executable.\n' >&2
exit 1
fi
;;
--user|-u)
if [ -n "$2" ]; then
eval COUCHDB_USER=$2
shift 2
continue
else
printf 'ERROR: "--user" requires a non-empty argument.\n' >&2
exit 1
fi
;;
--user=?*)
eval COUCHDB_USER=${1#*=}
;;
--user=)
printf 'ERROR: "--user" requires a non-empty argument.\n' >&2
exit 1
;;
--spidermonkey-version)
if [ -n "$2" ]; then
eval SM_VSN=$2
shift 2
continue
else
printf 'ERROR: "--spidermonkey-version" requires a non-empty argument.\n' >&2
exit 1
fi
;;
--spidermonkey-version=?*)
eval SM_VSN=${1#*=}
;;
--spidermonkey-version=)
printf 'ERROR: "--spidermonkey-version" requires a non-empty argument.\n' >&2
exit 1
;;
--js-engine)
if [ -n "$2" ]; then
eval JS_ENGINE=$2
shift 2
continue
else
printf 'ERROR: "--js-engine" requires a non-empty argument.\n' >&2
exit 1
fi
;;
--js-engine=?*)
eval JS_ENGINE=${1#*=}
;;
--js-engine=)
printf 'ERROR: "--js-engine" requires a non-empty argument.\n' >&2
exit 1
;;
--disable-spidermonkey)
WITH_SPIDERMONKEY="false"
shift
continue
;;
--clouseau-version)
if [ -n "$2" ]; then
eval CLOUSEAU_VSN=$2
shift 2
continue
else
printf 'ERROR: "--clouseau-version" requires a non-empty argument.\n' >&2
exit 1
fi
;;
--clouseau-version=?*)
eval CLOUSEAU_VSN=${1#*=}
;;
--clouseau-version=)
printf 'ERROR: "--clouseau-version" requires a non-empty argument.\n' >&2
exit 1
;;
--clouseau-method)
if [ -n "$2" ]; then
eval CLOUSEAU_MTH=$2
shift 2
continue
else
printf 'ERROR: "--clouseau-method" requires a non-empty argument.\n' >&2
exit 1
fi
;;
--clouseau-method=?*)
eval CLOUSEAU_MTH=${1#*=}
;;
--clouseau-method=)
printf 'ERROR: "--clouseau-method" requires a non-empty argument.\n' >&2
exit 1
;;
--clouseau-uri)
if [ -n "$2" ]; then
eval CLOUSEAU_URI=$2
shift 2
continue
else
printf 'ERROR: "--clouseau-uri" requires a non-empty argument.\n' >&2
exit 1
fi
;;
--clouseau-uri=?*)
eval CLOUSEAU_URI=${1#*=}
;;
--clouseau-uri=)
printf 'ERROR: "--clouseau-uri" requires a non-empty argument.\n' >&2
exit 1
;;
--) # End of options
shift
break
;;
-?*)
echo "WARNING: Unknown option '$1', ignoring" >&2
shift
;;
*) # Done
break
esac
shift
done
}
parse_opts $@
if [ "${WITH_SPIDERMONKEY}" = "true" ] && [ "${ARCH}" = "aarch64" ] && [ "${SM_VSN}" = "60" ]; then
echo "ERROR: SpiderMonkey 60 is known broken on ARM 64 (aarch64). Use another version instead."
exit 1
fi
if [ "${WITH_SPIDERMONKEY}" = "true" ] && [ "${ERLANG_OS}" = "unix" ]; then
case "${SM_VSN}" in
1.8.5)
SM_HEADERS="js"
;;
*) SM_HEADERS="mozjs-${SM_VSN}"
;;
esac
# This list is taken from src/couch/rebar.config.script, please keep them in sync.
if [ ! -d "/usr/include/${SM_HEADERS}" ] && \
[ ! -d "/usr/local/include/${SM_HEADERS}" ] && \
[ ! -d "/opt/homebrew/include/${SM_HEADERS}" ]; then
echo "ERROR: SpiderMonkey ${SM_VSN} is not found. Please specify with --spidermonkey-version."
exit 1
fi
fi
# If spidermonkey was disabled but JS_ENGINE set to "spidermonkey", reset it to "quickjs"
if [ "${WITH_SPIDERMONKEY}" = "false" ] && [ "${JS_ENGINE}" = "spidermonkey" ]; then
echo "NOTICE: Spidermonkey was disabled, but JS_ENGINE=spidermonkey. Setting JS_ENGINE=quickjs"
JS_ENGINE="quickjs"
fi
# If we're in a release tarball and we don't have proper, then mark it as skipped
if [ ! -d .git ] && [ "$WITH_PROPER" = "true" ] && [ ! -d src/proper ]; then
WITH_PROPER="false"
fi
# If we're in a release tarball and we don't have spidermonkey, then mark it as skipped and enable quickjs
if [ ! -d .git ] && [ "$WITH_SPIDERMONKEY" = "true" ] && [ ! -d src/couch/priv/couch_js ]; then
echo "NOTICE: Spidermonkey was disabled in release tarball. Setting JS_ENGINE=quickjs"
WITH_SPIDERMONKEY="false"
JS_ENGINE="quickjs"
fi
echo "==> configuring couchdb in rel/couchdb.config"
cat > rel/couchdb.config << EOF
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.
%
% The contents of this file are auto-generated by configure
%
{package_author_name, "$PACKAGE_AUTHOR_NAME"}.
{prefix, "."}.
{data_dir, "./data"}.
{view_index_dir, "./data"}.
{nouveau_enable, "$WITH_NOUVEAU"}.
{nouveau_index_dir, "./data/nouveau"}.
{nouveau_url, "http://127.0.0.1:5987"}.
{nouveau_port, 5987}.
{nouveau_admin_port, 5988}.
{state_dir, "./data"}.
{log_file, "$LOG_FILE"}.
{fauxton_root, "./share/www"}.
{user, "$COUCHDB_USER"}.
{js_engine, "$JS_ENGINE"}.
{spidermonkey_version, "$SM_VSN"}.
{with_spidermonkey, "$WITH_SPIDERMONKEY"}.
{node_name, "-name couchdb@127.0.0.1"}.
{cluster_port, 5984}.
{backend_port, 5986}.
{prometheus_port, 17986}.
EOF
cat > install.mk << EOF
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# The contents of this file are auto-generated by configure
#
package_author_name = $PACKAGE_AUTHOR_NAME
with_fauxton = $WITH_FAUXTON
with_docs = $WITH_DOCS
with_nouveau = $WITH_NOUVEAU
with_clouseau = $WITH_CLOUSEAU
user = $COUCHDB_USER
js_engine = $JS_ENGINE
spidermonkey_version = $SM_VSN
with_spidermonkey = $WITH_SPIDERMONKEY
EOF
cat > $rootdir/config.erl << EOF
{with_proper, $WITH_PROPER}.
{erlang_md5, $ERLANG_MD5}.
{js_engine, "$JS_ENGINE"}.
{spidermonkey_version, "$SM_VSN"}.
{with_spidermonkey, "$WITH_SPIDERMONKEY"}.
EOF
install_local_rebar() {
if [ ! -x "${rootdir}/bin/rebar" ]; then
if [ ! -d "${rootdir}/src/rebar" ]; then
git clone --depth 1 https://github.com/apache/couchdb-rebar.git ${rootdir}/src/rebar
fi
make -C ${rootdir}/src/rebar
mv ${rootdir}/src/rebar/rebar ${rootdir}/bin/rebar
make -C ${rootdir}/src/rebar clean
fi
}
install_local_rebar3() {
if [ ! -x "${rootdir}/bin/rebar3" ]; then
if [ ! -d "${rootdir}/src/rebar3" ]; then
git clone --depth 1 --branch ${REBAR3_BRANCH} https://github.com/erlang/rebar3.git ${rootdir}/src/rebar3
fi
cd src/rebar3
./bootstrap
mv ${rootdir}/src/rebar3/rebar3 ${rootdir}/bin/rebar3
cd ../..
fi
}
install_local_erlfmt() {
if [ ! -x "${rootdir}/bin/erlfmt" ]; then
if [ ! -d "${rootdir}/src/erlfmt" ]; then
git clone --depth 1 --branch "${ERLFMT_VERSION}" https://github.com/WhatsApp/erlfmt.git ${rootdir}/src/erlfmt
fi
cd "${rootdir}"/src/erlfmt
${REBAR3} as release escriptize
mv ${rootdir}/src/erlfmt/_build/release/bin/erlfmt ${rootdir}/bin/erlfmt
${REBAR3} clean
cd ../..
fi
}
check_local_clouseau_dir() {
_dir="$1"
if [ -e "$_dir" ]; then
printf "ERROR: \"%s\" already exists. Please remove or move it away first.\n" "$_dir" >&2
exit 1
fi
}
install_local_clouseau() {
case "$CLOUSEAU_MTH" in
dist)
_DIST_URL=$(printf "$CLOUSEAU_URI" "$CLOUSEAU_VSN" "$CLOUSEAU_VSN")
_MAVEN_BASE_URI=https://repo1.maven.org/maven2
_SLF4J_SIMPLE_VSN=${SLF4J_SIMPLE_VERSION:-1.7.36}
_SLF4J_SIMPLE_JAR=slf4j-simple-"$_SLF4J_SIMPLE_VSN".jar
_SLF4J_SIMPLE_URL="$_MAVEN_BASE_URI"/org/slf4j/slf4j-simple/"$_SLF4J_SIMPLE_VSN"/"$_SLF4J_SIMPLE_JAR"
check_local_clouseau_dir "$CLOUSEAU_DIR"
mkdir -p "$CLOUSEAU_DIR"
echo "Fetching Clouseau from $_DIST_URL..."
if ! curl -sSL --max-redirs 1 -o clouseau.zip "$_DIST_URL"; then
printf "ERROR: %s could not be downloaded.\n" "$_DIST_URL" >&2
exit 1
fi
if ! unzip -q -j clouseau.zip -d "$CLOUSEAU_DIR"; then
printf "ERROR: Clouseau distribution package (clouseau.zip) could not be extracted.\n" >&2
exit 1
fi
rm clouseau.zip
if ! curl -sSL --max-redirs 1 -o "$CLOUSEAU_DIR"/"$_SLF4J_SIMPLE_JAR" "$_SLF4J_SIMPLE_URL"; then
printf "ERROR: %s could not be downloaded.\n" "$_SLF4J_SIMPLE_URL" >&2
exit 1
fi
;;
git)
echo "Cloning Clouseau from $CLOUSEAU_URI ($CLOUSEAU_VSN)..."
check_local_clouseau_dir "$CLOUSEAU_DIR"
git clone --depth 1 --branch "$CLOUSEAU_VSN" "$CLOUSEAU_URI" "$CLOUSEAU_DIR"
;;
*) printf "ERROR: Invalid deployment method for Clouseau. Please use either \`dist\` or \`git\` verbatim.\n" >&2
exit 1
esac
}
if [ -z "${REBAR}" ]; then
install_local_rebar
REBAR=${rootdir}/bin/rebar
fi
if [ -z "${REBAR3}" ]; then
install_local_rebar3
REBAR3=${rootdir}/bin/rebar3
fi
if [ -z "${ERLFMT}" ]; then
install_local_erlfmt
ERLFMT=${rootdir}/bin/erlfmt
fi
if [ $WITH_CLOUSEAU -ne 0 ]; then
install_local_clouseau
fi
# only update dependencies, when we are not in a release tarball
if [ -d .git -a $SKIP_DEPS -ne 1 ]; then
echo "==> updating dependencies"
${REBAR} get-deps update-deps
fi
# External repos frequently become integrated with the primary repo,
# resulting in obsolete .git directories, and possible confusion.
# It is usually a good idea to delete these .git directories.
for path in $(find src -name .git -type d); do
git ls-files --error-unmatch $(dirname $path) > /dev/null 2>&1 && \
echo "WARNING unexpected .git directory $path"
done
echo "You have configured Apache CouchDB, time to relax. Relax."