Plasma GitLab Archive
Projects Blog Knowledge

#! /bin/sh
# $Id$
# ----------------------------------------------------------------------
#

# Some functions

#set -x

version="$(sed -ne 's/^version: *"\(.*\)\.git".*/\1/p' opam)"

if test -z "$version"; then
  echo "Internal error: failed to parse version number from opam file" 1>&2
	exit 1
fi

# Remember the old IFS value:
oldifs="$IFS"


in_path () {
    # Does $1 exist in $PATH?
    IFS=":"
    for d in $PATH; do
	if test -x "$d/$1"; then
	    IFS="$oldifs"
	    return 0
	fi
    done
    IFS="$oldifs"
    return 1
#--- The following is not portable enough:
#    if test -x `type -p ls`; then
#	# type -p works!
#        type -p $1 >/dev/null
#    else
#        # use 'which' instead
#        p=`which $1`
#	test -x "$p"
#    fi
}


get_path () {
    IFS=":"
    for d in $PATH; do
	if test -x "$d/$1"; then
	    IFS="$oldifs"
	    echo "$d/$1"
	    return
	fi
    done
    IFS="$oldifs"
#--- The following is not portable enough:
#    if test -x `type -p ls`; then
#	# type -p works!
#        type -p $1
#    else
#        # use 'which' instead
#        p=`which $1`
#	test -x "$p" && echo $p
#    fi
}


get_stdlib () {
    # Older versions of ocamlc do not accept -where, so there is a fallback
    # method:
    ocamlc -where 2>/dev/null | tr -d '\015' || {
	ocamlc -v | sed -n -e "/Standard library directory/s/.*: \(.*\)/\1/p"; }
}


get_lib () {
    # $1: name of a library to search for
    # $2...: places to test
    libname="$1"
    while [ "$#" != "0" ]; do
	if [ -f "$1/lib${libname}.so" ] || [ -f "$1/lib${libname}.a" ]; then
	    echo "$1"
	    return 0
	fi
	shift
    done
    return 1
}


get_lib_file () {
    # $1: name of library without "lib" and suffix
    # $2: directory
    # returns full path of library
    if [ -f "$2/lib$1.so" ]; then
	echo "$2/lib$1.so"
    elif [ -f "$2/lib$1.a" ]; then
	echo "$2/lib$1.a"
    else
	echo ""
    fi
}


cygpath_to_unix () {
    v=$1
    eval "p=\"\$$v\""
    p="`cygpath -w -s \"$p\"`"
    p="`cygpath -u \"$p\"`"
    eval "$v=\"$p\""
}


######################################################################
# Here the main program begins:

######################################################################
# Interpret the command line

ocamlfind_bin=""
ocamlfind_man=""
ocaml_sitelib=""
ocamlfind_config=""
with_toolbox=0
with_topfind=1
with_camlp4=1
custom=-custom
system=""
sh=""

while [ "$#" != "0" ]; do
    case "$1" in
        -bindir) ocamlfind_bin=$2
	         shift 2
		 ;;
        -mandir) ocamlfind_man=$2
	         shift 2
		 ;;
        -sitelib) ocaml_sitelib=$2
	          shift 2
		  ;;
        -config) ocamlfind_config=$2
	         shift 2
		 ;;
        -no-custom) custom=
                shift
                ;;
	-cygpath) system=mingw
	         shift
		 ;;
	-system) system=$2
	         shift 2
		 ;;
	-with-toolbox) with_toolbox=1
	         shift
		 ;;
	-no-topfind) with_topfind=0
	         shift
		 ;;
	-no-camlp4) with_camlp4=0
	         shift
	         ;;
	-version)
	         echo "$version"
		 exit 0
		 ;;
        -h|-help|--help) echo "usage: configure [options]" 1>&2
		  echo "  -bindir path         where binaries are installed" 1>&2
		  echo "  -mandir path         where manual pages are installed" 1>&2
		  echo "  -sitelib path        set the location of the site-specific packages" 1>&2
                  echo "  -config path         set the location of the configuration file" 1>&2
                  echo "  -no-custom           don't link in custom runtime mode" 1>&2
		  echo "  -system <systype>    override system type (esp. mingw and win32)" 1>&2
		  echo "  -with-toolbox        also build the toolbox" 1>&2
		  echo "  -no-topfind          don't install topfind script into stdlib directory" 1>&2
		  echo "  -no-camlp4           don't install the camlp4 META file" 1>&2
		  exit
		  ;;
         *)       echo "configure: run 'configure -h' to get help" 1>&2
		  exit 1
		  ;;
    esac
done

echo "Welcome to findlib version $version"
echo "Configuring core..."


#######################################################################
# inspect the system

# Some standard Unix tools must be available:

for tool in sed ocaml ocamlc uname rm make cat dirname basename; do
    if in_path $tool; then true; else
	echo "configure: $tool not in PATH; this is required" 1>&2
	exit 1
    fi
done

lib_suffix=`ocamlc -config 2>/dev/null|tr -d '\015'|sed -n -e 's/^ext_lib: //p'`

# Check for Cygwin:

exec_suffix=
pure_mingw="no"
mingw_lib=
case `uname` in
  CYGWIN*)
    exec_suffix=.exe
    echo "Cygwin build environment found; using .exe as suffix for binaries"
    ;;
  MSYS_NT*)
    exec_suffix=.exe
    echo "MSYS_NT build environment found; using .exe as suffix for binaries"
    ;;
  MINGW*)
    exec_suffix=.exe
    pure_mingw="yes"
    echo "MinGW build environment found; using .exe as suffix for binaries"
    mingw_lib=`get_path gcc`
    mingw_lib=`dirname "$mingw_lib"`/../lib
    ;;
  *)
    true ;;
esac

######################################################################
# Is the target Win32?

use_cygpath=0
# Whether we have to translate Unix paths to/from Windows paths.

if [ -z "$system" ]; then
    system=`ocamlc -config 2>/dev/null|tr -d '\015'|sed -n -e 's/^system: //p'`
    # This may be
    # - mingw or mingw64
    # - win32
    # - win64
    # - cygwin
    # - some other string means Unix
    # - empty means ocamlc does not support -config
fi

case "$system" in
    mingw|mingw64)
	if [ "$pure_mingw" = "no" ];  then
	    # CYGWIN
	    use_cygpath=1
	fi
	;;
    win32) use_cygpath=1;;
    win64) use_cygpath=1;;
esac

######################################################################
# check for presence of /bin/sh

if [ ! -f /bin/sh ]; then
    sh=sh
fi

######################################################################
# Find out standard library location

ocaml_core_stdlib=`get_stdlib`
if [ ! -d "$ocaml_core_stdlib" ]; then
   echo "configure: cannot determine ocaml's standard library directory" 1>&2
    exit 1
fi

if [ ${use_cygpath} -gt 0 ]; then
    cygpath_to_unix ocaml_core_stdlib
    # This makes ocaml_core_stdlib a Unix-type path
fi

# Set site-lib directory:

if [ -z "$ocaml_sitelib" ]; then
    case "$ocaml_core_stdlib" in
	/opt/*)		ocaml_sitelib=`dirname "${ocaml_core_stdlib}"`/site-lib
			;;
	*)		ocaml_sitelib="${ocaml_core_stdlib}/site-lib"
			;;
    esac
fi

# Find out the directory where ocamlc is:

ocamlc=`get_path ocamlc`
ocaml_core_bin=`dirname "${ocamlc}"`

# Set the directory of ocamlfind:

test -n "$ocamlfind_bin" || ocamlfind_bin="$ocaml_core_bin"

# Find the directory for the manual:

# Fallback:
ocaml_core_man=/usr/local/man

d="$ocaml_core_bin"
while [ "$d" != '/' ]; do
    f=0
    if [ -d "$d/man/man1" ]; then
	if [ -f "$d/man/man1/ocamlc.1" ] ||
	   [ -f "$d/man/man1/ocamlc.1.gz" ] ||
	   [ -f "$d/man/man1/ocamlc.1.Z" ]; then
	     f=1
	fi
    else
	if [ -d "$d/man/mann" ]; then
	    if [ -f "$d/man/mann/ocamlc.n" ] ||
		   [ -f "$d/man/mann/ocamlc.n.gz" ] ||
		   [ -f "$d/man/mann/ocamlc.n.Z" ]; then
		f=1
	    fi
	fi
    fi
    if [ "$f" = "1" ]; then
	ocaml_core_man="$d/man"
	d="/"
    else
	d=`dirname "$d"`
    fi
done

# Set the directory for ocamlfind's manuals:

test -n "$ocamlfind_man" || ocamlfind_man="$ocaml_core_man"

# Guess the right directory for the configuration file:

if [ -z "${ocamlfind_config}" ]; then
    d="$ocaml_core_bin"
    case "$d" in
        */bin)
            if [ -f `dirname "$d"`/lib/findlib.conf ]; then
	        ocamlfind_config=`dirname "$d"`/lib/findlib.conf
            else
	        ocamlfind_config=`dirname "$d"`/etc/findlib.conf
            fi
	    ;;
	*)
	    ocamlfind_config=/usr/local/etc/findlib.conf
	    # Fallback value
	    ;;
    esac
fi

######################################################################
# do we have #remove_directory?

echo "Checking for #remove_directory..."
have_remdir=1
ocaml itest-aux/remdir.ml >/dev/null 2>/dev/null || have_remdir=0

######################################################################
# Test the threading model

echo "Testing threading model..."

if ocamlc -vmthread >/dev/null 2>/dev/null; then
    ocaml_threads="vm"
else
    ocaml_threads="none"
fi

if ocamlc -config >/dev/null 2>/dev/null; then
    # Good. ocamlc tells us the threading model.
    if ocamlc -config | grep 'systhread_supported: true'; then
	ocaml_threads="posix"
    fi
else
    # Old ocamlc do not have -config.
    rm -f itest-aux/simple
    ocamlc -w a -custom -thread -o itest-aux/simple -I +unix unix.cma threads.cma itest-aux/simple_threads.ml \
	>itest-aux/err.out 2>&1
    output=`cat itest-aux/err.out`

    if [ -z "$output" ]; then
	ocaml_threads="posix"
    fi
fi

######################################################################
# Does this version of OCaml support autolinking?

# Works for OCaml >= 3.00 on. Because findlib can only be compiled
# with these OCaml versions, we can safely assume that autolinking
# is enabled.

ocaml_autolink="true"

######################################################################
# Does this version of OCaml support DLLs?

echo "Testing DLLs..."

have_dlls="yes"

ocaml -I +unix unix.cma itest-aux/simple.ml >/dev/null || have_dlls="no"

######################################################################
# Does this version of OCaml support extension points?

echo "Testing whether ppxopt can be supported..."

with_ppxopt=1
enable_topfind_ppxopt=true

ocaml -I +compiler-libs itest-aux/ppx.ml >/dev/null || {
    with_ppxopt=0
    enable_topfind_ppxopt=false
}

######################################################################
# Check for -opaque

echo "Checking for ocamlc -opaque..."

opaque="-opaque"
ocamlc -opaque >/dev/null 2>/dev/null || opaque=""

######################################################################
# Configure libraries

check_before_install=0
findlib_installed_meta=''
if [ -d "${ocaml_sitelib}" ]; then
    previous_config="${ocaml_sitelib}/findlib/Makefile.packages"
    if [ -f "${previous_config}" ]; then
        echo "Querying installation: found list of findlib-generated META files"
        eval "$(sed -ne 's/ /,/g' -e 's/^SITELIB_META,*=,*\([^,].*[^,]\),*/findlib_installed_meta="\1"/p' "$previous_config")"
        echo "Installation has: $findlib_installed_meta"
    else
        previous_config=''
        check_before_install=1
        echo "Querying installation: META list not found"
        echo "make install will double-check installed META files"
    fi
else
    previous_config=''
fi

echo "Configuring libraries..."

# Only succeeds if ${ocaml_sitelib}/$1/META exists and we're **certain**
# it wasn't installed by a previous findlib installation.
is_third_party_META () {
    if [ $check_before_install -eq 0 ]; then
        if [ -f "${ocaml_sitelib}/$1/META" ]; then
            case ",$findlib_installed_meta," in
                *,$1,*)
                    return 1;;
                *)
                return 0;;
            esac
        else
            return 1
        fi
    else
        return 1
    fi
}

check_library () {
    if is_third_party_META $1; then
        echo "$1: package already present"
        # Library is present - exit code is 0 because the library is found
        # (e.g. detection for Unix) but we don't actually add it to the
        # generated_META list.
        return 0
    fi

    if [ -z "$3" ]; then
        check_library "$1" "$2" "$1.cmi"
        return $?
    fi

    package="$1"
    if [ -z "$2" ]; then
        msg=''
    else
        msg=" ($2)"
    fi

    shift 2
    for file; do
        if [ -e "${ocaml_core_stdlib}/${file}" ]; then
            package_dir="$(dirname "${file}")"
            if [ "${package_dir}" = '.' ]; then
                echo "${package}: found"
                package_dir='^'
            else
                package_dir="+${package_dir}"
                echo "${package}: found (in ${package_dir})"
            fi
            eval "${package}_dir=\"${package_dir}\""
            if [ "$package" = 'num' ]; then
                generated_META="${generated_META} num num-top"
                numtop='num-top'
            else
                generated_META="${generated_META} ${package}"
            fi
            return 0
        fi
    done

    echo "$package: not present${msg}"
    return 1
}

generated_META='stdlib'
numtop=''

if ! check_library unix 'possible since 4.08' unix/unix.cmi unix.cmi; then
    echo "configure: ocamlfind requires OCaml's Unix library" 1>&2
    exit 1
fi

check_library dynlink '' dynlink/dynlink.cmi dynlink.cmi
check_library bigarray 'possible since 4.08'
check_library compiler-libs '' 'compiler-libs'
check_library dbm 'normal since 4.00'
check_library graphics 'normal since 4.09'
check_library num 'normal since 4.06'
check_library ocamlbuild 'normal since 4.03' ocamlbuild/ocamlbuildlib.cma
check_library ocamldoc '' ocamldoc/odoc.cmi
check_library raw_spacetime 'normal since 4.12' raw_spacetime_lib.cmxa
check_library threads '' threads/thread.cmi vmthreads/thread.cmi;
check_library runtime_events '' runtime_events/runtime_events.cmi

# Need to know if str and labltk are available for the toolbox
if check_library str 'possible since 4.08' str/str.cmi str.cmi; then
    have_str=1
else
    have_str=0
fi

if check_library labltk 'normal since 4.02' labltk/labltk.cma; then
    have_labltk=1
else
    have_labltk=0
fi

# Dynlink check.

have_natdynlink=0
natdynlink=""
camlp4_dynlink=""
if [ -f "${ocaml_core_stdlib}/${dynlink_dir#+}/dynlink.cmxa" ]; then
    have_natdynlink=1
    natdynlink="archive(native) = \"dynlink.cmxa\""
    camlp4_dynlink="dynlink"
    echo "native dynlink: found"
else
    natdynlink="archive(native) = \"\""
    echo "native dynlink: not found"
fi

# Check on camlp4:

if [ $with_camlp4 -eq 0 ]; then
    echo "camlp4: disabled"
else if in_path camlp4; then
    if is_third_party_META camlp4; then
        echo "camlp4: third-party"
    fi
    camlp4_dir=`camlp4 -where | tr -d '\015'`
    if [ ${use_cygpath} -gt 0 ]; then
	camlp4_dir=`echo x | env USE_CYGPATH=1 tools/patch x "$camlp4_dir"`
        # This makes camlp4_dir a windows path
    elif [ "${pure_mingw}" = "yes" ]; then
	# Must double the backslahes
	camlp4_dir="$(echo "${camlp4_dir}" | sed -e 's;\\;\\\\;g')"
    fi
    camlp4_version=`camlp4 -v 2>&1`
    if [ "$have_dlls" = "yes" ]; then
	camlp4_cmd="camlp4"
    else
	camlp4_cmd="safe_camlp4"
    fi
    # Check whether 3.09 or 3.10 style:
    if camlp4 -loaded-modules >/dev/null 2>/dev/null; then
	camlp4style=310
    else
	camlp4style=309
    fi
    generated_META="${generated_META} camlp4"
    rm -rf "site-lib-src/camlp4"
    mkdir "site-lib-src/camlp4"
    cp "site-lib-src/camlp4.$camlp4style/META.in" "site-lib-src/camlp4/"
    echo "camlp4: using $camlp4_cmd, style $camlp4style"
else
    with_camlp4=0
    echo "camlp4: not present (normal since OCaml-4.02)"
fi
fi

# bytes?
# (NB. This is always ours, and it doesn't go into generated_META)

req_bytes=""
if [ -f "${ocaml_core_stdlib}/bytes.cmi" ] ||
   [ -f "${ocaml_core_stdlib}/stdlib__bytes.cmi" ] ||
   [ -f "${ocaml_core_stdlib}/stdlib__Bytes.cmi" ]; then
    echo "bytes: found, installing fake library"
    lbytes="bytes"
    cbytes=0
else
    echo "bytes: not found, installing compat library"
    lbytes=""
    req_bytes="bytes"
    cbytes=1
fi


if [ $with_toolbox -gt 0 ]; then
    if [ $have_str -eq 0 ] || [ $have_labltk -eq 0 ]; then
	echo "Sorry, toolbox requires str and labltk - omitting toolbox."
        with_toolbox=0
    fi
fi

# Generate the META files now.

for dir in site-lib-src/*; do
    # We do not really know if $dir is a directory.
    rm -f $dir/META
done

for lib in $generated_META $lbytes; do
    if=""
    if [ -f site-lib-src/$lib/interfaces.out ]; then
	if=`cat site-lib-src/$lib/interfaces.out`
    fi
    sed -e "s|%%os%%|${os}|g" \
        -e "s|%%type_of_threads%%|${ocaml_threads}|g" \
        -e "s|%%camlp4_dir%%|${camlp4_dir}|g" \
        -e "s|%%camlp4_version%%|${camlp4_version}|g" \
        -e "s|%%camlp4_cmd%%|${camlp4_cmd}|g" \
        -e "s|%%camlp4_dynlink%%|${camlp4_dynlink}|g" \
        -e "s|%%interfaces%%|${if}|g" \
        -e "s|%%findlib_version%%|${version}|g" \
        -e "s|%%natdynlink%%|${natdynlink}|g" \
        -e "s|%%dynlink_dir%%|${dynlink_dir}|g" \
        -e "s|%%unix_dir%%|${unix_dir}|g" \
        -e "s|%%str_dir%%|${str_dir}|g" \
        site-lib-src/$lib/META.in > site-lib-src/$lib/META

    echo "Configuration for $lib written to site-lib-src/$lib/META"
done

for part in `cd src; echo *`; do
    if [ -f "src/$part/META.in" ]; then
	sed -e "s/@VERSION@/$version/g" \
            -e "s/@REQUIRES@/${req_bytes}/g" \
            src/$part/META.in >src/$part/META
    fi
done

######################################################################

printf "Detecting compiler arguments: "

( cd tools/extract_args && make ) >ocargs.log 2>&1
if [ "$?" -eq 0 ]; then
    printf "(extractor built) "
    tools/extract_args/extract_args -o src/findlib/ocaml_args.ml ocamlc ocamlcp ocamloptp ocamlmklib ocamlmktop ocamlopt ocamldep ocamldoc >>ocargs.log 2>&1
    # ocamlbrowser does not work!
    if [ $? -eq 0 ]; then
	echo "ok"
    else
	echo "FAILED (see the file ocargs.log for details)"
	exit 1
    fi
else
    echo "FAILED (see the file ocargs.log for details)"
    exit 1
fi

######################################################################
# Write Makefile.config

parts="findlib"
ocamlfind_ocamlflags="-I +unix -I +dynlink"
ocamlfind_archives="findlib.cma unix.cma"
if [ $with_toolbox -gt 0 ]; then
    parts="$parts findlib-toolbox"
fi
if [ $cbytes -gt 0 ]; then
    # bytes first, because findlib needs it
    parts="bytes $parts"
    ocamlfind_ocamlflags="${ocamlfind_archives} -I ../bytes"
    ocamlfind_archives="bytes.cma ${ocamlfind_archives}"
fi

echo "# Makefile.config written by configure" >Makefile.config
echo "OCAML_CORE_STDLIB=${ocaml_core_stdlib}" >>Makefile.config
echo "OCAML_CORE_BIN=${ocaml_core_bin}" >>Makefile.config
echo "OCAML_CORE_MAN=${ocaml_core_man}" >>Makefile.config
echo "OCAML_SITELIB=${ocaml_sitelib}" >>Makefile.config
echo "OCAML_THREADS=${ocaml_threads}" >>Makefile.config
echo "OCAMLFIND_BIN=${ocamlfind_bin}" >>Makefile.config
echo "OCAMLFIND_MAN=${ocamlfind_man}" >>Makefile.config
echo "OCAMLFIND_CONF=${ocamlfind_config}" >>Makefile.config
echo "OCAMLFIND_OCAMLFLAGS=${ocamlfind_ocamlflags}" >>Makefile.config
echo "OCAMLFIND_ARCHIVES=${ocamlfind_archives}" >>Makefile.config
echo "OCAML_AUTOLINK=${ocaml_autolink}" >>Makefile.config
echo "OCAML_REMOVE_DIRECTORY=${have_remdir}" >>Makefile.config
echo "EXEC_SUFFIX=${exec_suffix}" >>Makefile.config
echo "LIB_SUFFIX=${lib_suffix}" >>Makefile.config
echo "CUSTOM=${custom}" >>Makefile.config
echo "PARTS=${parts}" >>Makefile.config
echo "INSTALL_TOPFIND=${with_topfind}" >>Makefile.config
echo "USE_CYGPATH=${use_cygpath}" >>Makefile.config
echo "HAVE_NATDYNLINK=${have_natdynlink}" >>Makefile.config
echo "VERSION=${version}" >>Makefile.config
echo "ENABLE_TOPFIND_PPXOPT=${enable_topfind_ppxopt}" >>Makefile.config
echo "SYSTEM=${system}" >>Makefile.config
echo "NUMTOP=${numtop}" >>Makefile.config
echo "SH=${sh}" >>Makefile.config
if [ "$mingw_lib" != "" ]; then
    echo "OCAMLC_FLAGS=-I \"${mingw_lib}\"" >>Makefile.config
    echo "OCAMLOPT_FLAGS=-I \"${mingw_lib}\"" >>Makefile.config
fi
echo "OPAQUE=${opaque}" >>Makefile.config
echo "CHECK_BEFORE_INSTALL=${check_before_install}" >>Makefile.config
echo "INSTALLDIR = install -d" >>Makefile.config
echo "# change to INSTALLDIR = mkdir -p   when BSD install is unavavailable" >>Makefile.config
echo "INSTALLFILE = install -c" >>Makefile.config
echo "# change to INSTALLFILE = cp   when BSD install is unavailable" >>Makefile.config
echo "SITELIB_META=${generated_META}" >Makefile.packages

# All OK

echo
echo "About the OCAML core installation:"
echo "    Standard library:      ${ocaml_core_stdlib}"
echo "    Binaries:              ${ocaml_core_bin}"
echo "    Manual pages:          ${ocaml_core_man}"
echo "    Multi-threading type:  ${ocaml_threads}"
echo "The directory of site-specific packages will be"
echo "    site-lib:              ${ocaml_sitelib}"
echo "The configuration file is written to:"
echo "    findlib config file:   ${ocamlfind_config}"
echo "Software will be installed:"
echo "    Libraries:             in <site-lib>/findlib"
echo "    Binaries:              ${ocamlfind_bin}"
echo "    Manual pages:          ${ocamlfind_man}"
if [ $with_topfind -gt 0 ]; then
    echo "    topfind script:        ${ocaml_core_stdlib}"
else
    echo "    topfind script:        omitted"
fi

if [ $with_ppxopt -gt 0 ]; then
    echo "Topfind ppxopt support:    yes"
else
    echo "Topfind ppxopt support:    no"
fi

if [ $with_toolbox -gt 0 ]; then
    echo "Toolbox:                   yes"
else
    echo "Toolbox:                   no"
fi

if [ -z "$custom" ]; then
    echo "Link custom runtime:       no"
else
    echo "Link custom runtime:       yes"
fi

if [ $cbytes -gt 0 ]; then
    echo "Need bytes compatibility:  yes"
else
    echo "Need bytes compatibility:  no"
fi

echo
echo "Configuration has been written to Makefile.config"
echo
echo "You can now do 'make all', and optionally 'make opt', to build ocamlfind."


This web site is published by Informatikbüro Gerd Stolpmann
Powered by Caml