summaryrefslogtreecommitdiffstats
path: root/configure_tool
blob: 499ab5dc290d59779adeb49516b1e0f6a273d33b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/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}'."