#!/bin/sh -eu # Very quick and simple "configure" script for the debugger, ocamlbuild and # ocamldoc. # Arguments: # $1: tool to configure for: "debugger", "ocamlbuild" or "ocamldoc" # Environment variables: # UNINSTALLED_OCAML_DESTDIR: see below # UNINSTALLED_OCAML_PREFIX: see below TOOL="${1:="none"}" # Configuration from the user through environment variables: # - UNINSTALLED_OCAML_DESTDIR: if the OCaml compiler has been installed # temporarily, the location it has been installed to. # - UNINSTALLED_OCAML_PREFIX: the -prefix used for the ocaml compilation; only # used if UNINSTALLED_OCAML_PREFIX is set. : ${UNINSTALLED_OCAML_DESTDIR:=""} : ${UNINSTALLED_OCAML_PREFIX:=/usr/local} # Helper functions # test_ocaml_tool: test that the command named "$1" and provided as "$2" runs; # this is a simple test which runs "$1 -version 2>/dev/null >/dev/null". test_ocaml_tool() { local NAME="${1}" # This is only used to give a better error message local COMMAND="${2}" if ${COMMAND} -version 2>/dev/null >/dev/null; then echo "${COMMAND}" else echo "Couldn't find a way to invoke '${NAME}'." 1>&2 fi } # bytecode_or_native: turn the command name provided through "$1" into a # command to invoke it, either by prepending ${OCAMLRUN} or by appending .opt # (basically). bytecode_or_native() { local EXECUTABLE="${1}" if [ -z "${OPT}" ]; then test_ocaml_tool "${EXECUTABLE}" "${OCAMLRUN}${U_BINDIR}${EXECUTABLE}" else test_ocaml_tool "${EXECUTABLE}" "${U_BINDIR}${EXECUTABLE}.opt" fi } # Test the given code in the toplevel; useful to check that a given # functionality is available. test_in_toplevel() { CODE="${1}" MODULES="${2}" ( export CAML_LD_LIBRARY_PATH=${CAML_LD_LIBRARY_PATH} printf "${CODE}" | ${OCAML} ${MODULES} >/dev/null ) } # Body if [ -n "${UNINSTALLED_OCAML_DESTDIR}" ]; then U_BINDIR="${UNINSTALLED_OCAML_DESTDIR}/${UNINSTALLED_OCAML_PREFIX}/bin/" else U_BINDIR="" fi # Determine whether we can use .opt binaries for the compilation; the test is # fairly simple but should cover > 95% of uses and since it's only a speed # improvement it doesn't have to be perfect. # NOTE: if your .opt binaries don't work for one reason or another, simply run # "chmod -x" on (one of) them. if [ -x "${U_BINDIR}ocamlc.opt" ] && [ -x "${U_BINDIR}ocamlopt.opt" ]; then echo "Will use .opt binaries." OPT=".opt" else echo "Will not use .opt binaries." OPT="" fi : ${OCAMLRUN:="${U_BINDIR}ocamlrun "} : ${OCAML:="${OCAMLRUN}${U_BINDIR}ocaml"} : ${OCAMLC:="$(bytecode_or_native ocamlc)"} : ${OCAMLOPT:="$(bytecode_or_native ocamlopt)"} : ${OCAMLLEX:="$(bytecode_or_native ocamllex)"} : ${OCAMLDEP:="$(bytecode_or_native ocamldep)"} : ${OCAMLYACC:="${U_BINDIR}ocamlyacc"} : ${OCAMLDOC_RUN:="${OCAMLRUN}./ocamldoc"} if [ -z "${OCAMLC}" ] || [ -z "${OCAMLLEX}" ] || [ -z "${OCAMLDEP}" ]; then printf '\nERROR: some required tools were not found.\n\n' 1>&2 exit 1 fi # If the compiler is in an uninstalled state, we need to invoke it with # "-nostdlib -I $DESTDIR/$LIBDIR" so determine that. It will also be useful for # the Makefile "include" directive. LIBDIR="$(${OCAMLC} -config | awk -F' ' '/^standard_library_default: / { print $2; }')" if [ -z "${UNINSTALLED_OCAML_DESTDIR}" ]; then CLFLAGS="-I +compiler-libs" OCAML_MAKEFILE_CONFIG="${LIBDIR}/Makefile.config" CAML_LD_LIBRARY_PATH="" else CLFLAGS="-nostdlib -I ${UNINSTALLED_OCAML_DESTDIR}/${LIBDIR} -I ${UNINSTALLED_OCAML_DESTDIR}/${LIBDIR}/compiler-libs" OCAML_MAKEFILE_CONFIG="${UNINSTALLED_OCAML_DESTDIR}/${LIBDIR}/Makefile.config" CAML_LD_LIBRARY_PATH="${UNINSTALLED_OCAML_DESTDIR}/${LIBDIR}/stublibs" fi # Now that we have the compiler and linker search flags, append them. OCAML="${OCAML} ${CLFLAGS}" OCAMLC="${OCAMLC} ${CLFLAGS}" OCAMLOPT="${OCAMLOPT} ${CLFLAGS}" # Log to the user echo "ocamlrun: ${OCAMLRUN}" echo "ocaml: ${OCAML}" echo "ocamlc: ${OCAMLC}" echo "ocamlopt: ${OCAMLOPT}" echo "ocamllex: ${OCAMLLEX}" echo "ocamldep: ${OCAMLDEP}" echo "ocamlyacc: ${OCAMLYACC}" echo "ocamldoc_run: ${OCAMLDOC_RUN}" echo "uninstalled libdir: ${LIBDIR}" # Check the tool-specific dependencies case "${TOOL}" in 'debugger') echo 'Checking for sockets...' test_in_toplevel \ 'open Unix;;\nlet sock = socket PF_INET SOCK_STREAM 0;;' \ 'unix.cma' ;; 'ocamldoc') ;; 'ocamlbuild') ;; *) printf '\nERROR: you need to select a tool: "debugger", "ocamlbuild" or "ocamldoc".\n\n' exit 1 ;; esac # Write the configuration summary to Makefile.local_config cat > "${TOOL}/Makefile.local" << EOF OCAML_MAKEFILE_CONFIG=${OCAML_MAKEFILE_CONFIG} include \$(OCAML_MAKEFILE_CONFIG) OCAML=${OCAML} OCAMLC=${OCAMLC} OCAMLOPT=${OCAMLOPT} OCAMLLEX=${OCAMLLEX} OCAMLDEP=${OCAMLDEP} OCAMLYACC=${OCAMLYACC} OCAMLDOC_RUN=${OCAMLDOC_RUN} export CAML_LD_LIBRARY_PATH=${CAML_LD_LIBRARY_PATH} UNINSTALLED_LIBDIR="${LIBDIR}" EOF echo "Successfully configured for '${TOOL}'."