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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
# This is the main Makefile that is shipped as part of the source package.
# Keep in mind that the hierarchy that is shipped is not identical to the
# hierarchy within the git repository. Some sub-directories are not shipped.
# The documentation (manual.pdf, menhir.1) is pre-built and stored at the root.
# This Makefile can also be used directly in the repository. In that case,
# the documentation and demos are not installed.
# The hierarchy that is shipped includes:
# demos
# menhir.1
# manual.pdf
# manual.html
# src
# Makefile (this one)
# ----------------------------------------------------------------------------
# The following variables must/can be configured.
ifndef PREFIX
$(error Please define PREFIX)
endif
ifndef TARGET
TARGET := native
endif
# ----------------------------------------------------------------------------
# By default, we attempt to use ocamlfind (if present in the PATH), but it
# is possible to prevent that externally by setting USE_OCAMLFIND to false.
# USE_OCAMLFIND is used only at build time (i.e., by "make all"). At
# (un)installation time, instead, we query menhir using --suggest-ocamlfind.
# This should protect us against people who pass USE_OCAMLFIND at build time
# and forget to pass it at (un)installation time.
ifndef USE_OCAMLFIND
USE_OCAMLFIND = ocamlfind ocamlc -v >/dev/null 2>&1
endif
# ----------------------------------------------------------------------------
# Installation paths.
# These may be overridden from outside; e.g., our opam package description
# provides its own values of docdir, libdir, and mandir.
bindir := $(PREFIX)/bin
docdir := $(PREFIX)/share/doc/menhir
libdir := $(PREFIX)/share/menhir
mandir := $(PREFIX)/share/man/man1
MANS := doc/menhir.1
DOCS := doc/manual.pdf doc/manual.html doc/manual*.png demos
MLYLIB := src/standard.mly
# ----------------------------------------------------------------------------
# The following incantations should work on both Windows and Unix,
# and allow us to abstract away the differences.
# The extension of object files.
OBJ := $(shell ocamlc -config | sed -n '/^ext_obj:/p' | sed 's/ext_obj: //')
# The extension of executable files.
# Note: the field "ext_exe" seems to have appeared in OCaml 4.05.
# With earlier versions of OCaml, this incantation defines $(EXE)
# as the empty string, which could be a problem under Windows.
EXE := $(shell ocamlc -config | sed -n '/^ext_exe:/p' | sed 's/ext_exe: //')
# The OS type.
OS_TYPE := $(shell ocamlc -config | sed -n '/^os_type:/p' | sed 's/os_type: //')
# The path $(installation_libdir), which is recorded in src/installation.ml (see
# below), must sometimes be translated using cygpath.
# This one is tricky. To summarize, if I understood correctly, we can assume
# that Cygwin always exists when Menhir is compiled and installed (because
# executing a Makefile, like this one, requires Cygwin), but we cannot assume
# that Menhir will be executed under Cygwin. If the OCaml compiler is
# configured to produce a Cygwin executable, then, yes, Cygwin is there at
# execution time, so path translation is not necessary (and should not be
# performed). On the other hand, if the OCaml compiler is configured to
# produce a native Windows executable, then Cygwin is not there at execution
# time and path translation is required. In summary, path translation must be
# performed if "os_type" is "Win32" or "Win64", and must not be performed if
# "os_type" is "Cygwin" or "Unix".
ifeq ($(OS_TYPE),$(filter $(OS_TYPE),Win32 Win64))
installation_libdir := $(shell cygpath -m $(libdir) || echo $(libdir))
else
installation_libdir := $(libdir)
endif
# -------------------------------------------------------------------------
# The names of the modules in MenhirLib are obtained by reading the
# non-comment lines in menhirLib.mlpack.
MENHIRLIB_MODULES := $(shell grep -ve "^[ \t\n\r]*\#" src/menhirLib.mlpack)
# ----------------------------------------------------------------------------
# The directories where things are built.
# For Menhir and MenhirLib.
BUILDDIR := src/_stage2
# For MenhirSdk.
SDKDIR := src/_sdk
# ----------------------------------------------------------------------------
# Compilation.
.PHONY: all install uninstall
all:
# Installation time settings are recorded within src/installation.ml.
# This file is recreated every time so as to avoid becoming stale.
@ rm -f src/installation.ml
@ echo "let libdir = \"$(installation_libdir)\"" > src/installation.ml
@ if $(USE_OCAMLFIND) ; then \
echo "let ocamlfind = true" >> src/installation.ml ; \
else \
echo "let ocamlfind = false" >> src/installation.ml ; \
fi
# Compile the Menhir executable.
# This causes MenhirLib to be compiled, too, as it is used inside Menhir.
# Compile MenhirSdk.
@ $(MAKE) -C src bootstrap sdk
# The source file menhirLib.ml is created by concatenating all of the source
# files that make up MenhirLib. This file is not needed to compile Menhir or
# MenhirLib. It is installed at the same time as MenhirLib and is copied by
# Menhir when the user requests a self-contained parser (one that is not
# dependent on MenhirLib).
@ echo "Creating menhirLib.ml"
@ rm -f $(BUILDDIR)/menhirLib.ml
@ for m in $(MENHIRLIB_MODULES) ; do \
echo "module $$m = struct" >> $(BUILDDIR)/menhirLib.ml ; \
cat src/$$m.ml >> $(BUILDDIR)/menhirLib.ml ; \
echo "end" >> $(BUILDDIR)/menhirLib.ml ; \
done
# The source file menhirLib.mli is created in the same way. If a module
# does not have an .mli file, then we assume that its .ml file contains
# type (and module type) definitions only, so we copy it instead of the
# (non-existent) .mli file.
@ echo "Creating menhirLib.mli"
@ rm -f $(BUILDDIR)/menhirLib.mli
@ for m in $(MENHIRLIB_MODULES) ; do \
echo "module $$m : sig" >> $(BUILDDIR)/menhirLib.mli ; \
if [ -f src/$$m.mli ] ; then \
cat src/$$m.mli >> $(BUILDDIR)/menhirLib.mli ; \
else \
cat src/$$m.ml >> $(BUILDDIR)/menhirLib.mli ; \
fi ; \
echo "end" >> $(BUILDDIR)/menhirLib.mli ; \
done
# -------------------------------------------------------------------------
# The files that should be installed as part of menhirLib.
MENHIRLIB := menhirLib.mli menhirLib.ml menhirLib.cmi menhirLib.cmo
ifneq ($(TARGET),byte)
MENHIRLIB := $(MENHIRLIB) menhirLib.cmx menhirLib.cmxs menhirLib$(OBJ)
endif
# -------------------------------------------------------------------------
# The files that should be installed as part of menhirSdk.
MENHIRSDK := menhirSdk.cmi menhirSdk.cmo
ifneq ($(TARGET),byte)
MENHIRSDK := $(MENHIRSDK) menhirSdk.cmx menhirSdk.cmxs menhirSdk$(OBJ)
endif
# ----------------------------------------------------------------------------
# Installation.
install:
# Install the executable.
mkdir -p $(bindir)
install $(BUILDDIR)/menhir.$(TARGET) $(bindir)/menhir$(EXE)
# Install Menhir's standard library.
mkdir -p $(libdir)
install -m 644 $(MLYLIB) $(libdir)
# Install MenhirLib and MenhirSdk.
@if `$(BUILDDIR)/menhir.$(TARGET) --suggest-ocamlfind | tr -d '\r'` ; then \
echo 'Installing MenhirLib and MenhirSdk via ocamlfind.' ; \
cp -f src/menhirLib.META META ; \
ocamlfind install menhirLib META $(patsubst %,$(BUILDDIR)/%,$(MENHIRLIB)) ; \
cp -f src/menhirSdk.META META ; \
ocamlfind install menhirSdk META $(patsubst %,$(SDKDIR)/%,$(MENHIRSDK)) ; \
rm -f META ; \
else \
echo 'Installing MenhirLib and MenhirSdk manually.' ; \
install -m 644 $(patsubst %,$(BUILDDIR)/%,$(MENHIRLIB)) $(libdir) ; \
install -m 644 $(patsubst %,$(SDKDIR)/%,$(MENHIRSDK)) $(libdir) ; \
fi
# Install the documentation. (If building from the repository, the documentation
# may be absent.)
if [ -f doc/manual.pdf ] ; then \
mkdir -p $(docdir) $(mandir) ; \
cp -r $(DOCS) $(docdir) ; \
cp -r $(MANS) $(mandir) ; \
fi
uninstall:
@if `$(bindir)/menhir$(EXE) --suggest-ocamlfind` ; then \
echo 'Un-installing MenhirLib and MenhirSdk via ocamlfind.' ; \
ocamlfind remove menhirLib ; \
ocamlfind remove menhirSdk ; \
fi
rm -rf $(bindir)/menhir$(EXE)
rm -rf $(libdir)
rm -rf $(docdir)
rm -rf $(mandir)/$(MANS)
|