#!/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.27.0" ERLFMT_VERSION="v1.8.0" # TEST=0 WITH_PROPER="true" WITH_FAUXTON="true" WITH_DOCS="true" WITH_NOUVEAU="false" WITH_CLOUSEAU="false" WITH_ZIOSE="true" ERLANG_MD5="false" SKIP_DEPS="false" 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:-"128"} 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:-"3.0.0"} CLOUSEAU_DIR="$(pwd)"/clouseau ARCH="$(uname -m)" MULTIARCH_NAME="$(command -v dpkg-architecture > /dev/null && dpkg-architecture -q DEB_HOST_MULTIARCH || true)" 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.')" 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) --dev alias for --disable-docs --disable-fauxton --disable-spidermonkey --disable-fauxton do not build Fauxton --disable-docs do not build any documentation or manpages --disable-spidermonkey disable spidermonkey, don't try to build it --spidermonkey-version VSN specify the version of SpiderMonkey to use (defaults to $SM_VSN) --js-engine=ENGINE use js engine: spidermonkey or quickjs, defaults to spidermonkey --with-nouveau build the new experimental search module --with-clouseau build the Clouseau search module --erlang-md5 use erlang for md5 hash operations --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 EOF } parse_opts() { while :; do case $1 in -h|--help) display_help exit ;; --without-proper) WITH_PROPER="false" shift continue ;; --disable-fauxton) WITH_FAUXTON="false" shift continue ;; --disable-docs) WITH_DOCS="false" shift continue ;; --with-nouveau) WITH_NOUVEAU="true" shift continue ;; --with-clouseau) WITH_CLOUSEAU="true" shift continue ;; --erlang-md5) ERLANG_MD5="true" shift continue ;; --dev) WITH_DOCS="false" WITH_FAUXTON="false" WITH_SPIDERMONKEY="false" shift continue ;; --dev-with-nouveau) WITH_DOCS="false" WITH_FAUXTON="false" WITH_NOUVEAU="true" WITH_SPIDERMONKEY="false" shift continue ;; --skip-deps) SKIP_DEPS="true" 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 [ "$(echo "$CLOUSEAU_VSN" | cut -d '.' -f 1)" -lt "3" ]; then WITH_ZIOSE="false" fi 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}" ] && \ [ -n "${MULTIARCH_NAME}" -a ! -d "/usr/include/${MULTIARCH_NAME}/${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 [ ! -e .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 [ ! -e .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_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 } fetch_file() { _file_name="$1" _file_url="$2" if ! curl -sSL --max-redirs 1 -o "$_file_name" "$_file_url"; then printf "ERROR: %s could not be downloaded.\n" "$_file_url" >&2 exit 1 fi } install_local_clouseau() { case "$CLOUSEAU_MTH" in dist) _DIST_URL=$(printf "$CLOUSEAU_URI" "$CLOUSEAU_VSN" "$CLOUSEAU_VSN") if [ "${WITH_ZIOSE}" = "false" ]; then _MAVEN_BASE_URI=https://repo1.maven.org/maven2 _LOGBACK_DIST_URL="$_MAVEN_BASE_URI"/ch/qos/logback : "${LOGBACK_VERSION:=1.2.13}" _LOGBACK_CORE_JAR=logback-core-"$LOGBACK_VERSION".jar _LOGBACK_CORE_URL="$_LOGBACK_DIST_URL"/logback-core/"$LOGBACK_VERSION"/"$_LOGBACK_CORE_JAR" _LOGBACK_CLASSIC_JAR=logback-classic-"$LOGBACK_VERSION".jar _LOGBACK_CLASSIC_URL="$_LOGBACK_DIST_URL"/logback-classic/"$LOGBACK_VERSION"/"$_LOGBACK_CLASSIC_JAR" fi check_local_clouseau_dir "$CLOUSEAU_DIR" mkdir -p "$CLOUSEAU_DIR" echo "Fetching Clouseau from $_DIST_URL..." fetch_file clouseau.zip "$_DIST_URL" 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 [ "${WITH_ZIOSE}" = "false" ]; then echo "Fetching Logback $LOGBACK_VERSION from $_LOGBACK_DIST_URL..." fetch_file "$CLOUSEAU_DIR"/"$_LOGBACK_CORE_JAR" "$_LOGBACK_CORE_URL" fetch_file "$CLOUSEAU_DIR"/"$_LOGBACK_CLASSIC_JAR" "$_LOGBACK_CLASSIC_URL" fi if [ "${WITH_ZIOSE}" = "true" ]; then touch "$CLOUSEAU_DIR"/.ziose 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" = "true" ]; then install_local_clouseau fi # only update dependencies, when we are not in a release tarball if [ -e .git ] && [ "$SKIP_DEPS" = "false" ]; 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."