Makefile 8.01 KB
Newer Older
1
# This is the main Makefile that is shipped as part of the source package.
2

3
# Keep in mind that the hierarchy that is shipped is not identical to the
4 5 6 7 8
# 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.
9 10 11 12 13

# The hierarchy that is shipped includes:
#   demos
#   menhir.1
#   manual.pdf
14
#   manual.html
15 16 17 18 19
#   src
#   Makefile (this one)

# ----------------------------------------------------------------------------

fpottier's avatar
fpottier committed
20 21 22 23 24 25 26 27 28 29 30 31
# The following variables must/can be configured.

ifndef PREFIX
  $(error Please define PREFIX)
endif

ifndef TARGET
  TARGET := native
endif

# ----------------------------------------------------------------------------

POTTIER Francois's avatar
Typo.  
POTTIER Francois committed
32
# By default, we attempt to use ocamlfind (if present in the PATH), but it
33 34
# is possible to prevent that externally by setting USE_OCAMLFIND to false.

35 36 37 38 39
# 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.

40 41 42 43
ifndef USE_OCAMLFIND
  USE_OCAMLFIND = ocamlfind ocamlc -v >/dev/null 2>&1
endif

44 45
# ----------------------------------------------------------------------------
# Installation paths.
46 47
# These may be overridden from outside; e.g., our opam package description
# provides its own values of docdir, libdir, and mandir.
48

49 50 51 52
bindir          := $(PREFIX)/bin
docdir		:= $(PREFIX)/share/doc/menhir
libdir	        := $(PREFIX)/share/menhir
mandir          := $(PREFIX)/share/man/man1
53 54
MANS            := doc/menhir.1
DOCS            := doc/manual.pdf doc/manual.html doc/manual*.png demos
55 56
MLYLIB          := src/standard.mly

57 58
# ----------------------------------------------------------------------------

59 60
# The following incantations should work on both Windows and Unix,
# and allow us to abstract away the differences.
61

62 63 64
# The extension of object files.
OBJ := $(shell ocamlc -config | sed -n '/^ext_obj:/p' | sed 's/ext_obj: //')
# The extension of executable files.
POTTIER Francois's avatar
POTTIER Francois committed
65 66 67
# 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.
68 69 70
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: //')
71

72 73
# The path $(installation_libdir), which is recorded in src/installation.ml (see
# below), must sometimes be translated using cygpath.
74 75 76 77 78 79 80 81 82 83

# 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
POTTIER Francois's avatar
Typo.  
POTTIER Francois committed
84
# performed if "os_type" is "Win32" or "Win64", and must not be performed if
85 86
# "os_type" is "Cygwin" or "Unix".

87 88
ifeq ($(OS_TYPE),$(filter $(OS_TYPE),Win32 Win64))
  installation_libdir := $(shell cygpath -m $(libdir) || echo $(libdir))
89
else
90
  installation_libdir := $(libdir)
91
endif
92

93 94 95 96 97 98 99
# -------------------------------------------------------------------------

# 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)

100 101
# ----------------------------------------------------------------------------

POTTIER Francois's avatar
POTTIER Francois committed
102
# The directories where things are built.
103

POTTIER Francois's avatar
POTTIER Francois committed
104
# For Menhir and MenhirLib.
105
BUILDDIR := src/_stage2
POTTIER Francois's avatar
POTTIER Francois committed
106 107
# For MenhirSdk.
SDKDIR   := src/_sdk
108

109 110 111
# ----------------------------------------------------------------------------

# Compilation.
112 113 114 115

.PHONY: all install uninstall

all:
116 117
# Installation time settings are recorded within src/installation.ml.
# This file is recreated every time so as to avoid becoming stale.
118
	@ rm -f src/installation.ml
119
	@ echo "let libdir = \"$(installation_libdir)\"" > src/installation.ml
120
	@ if $(USE_OCAMLFIND) ; then \
121 122 123 124
	  echo "let ocamlfind = true" >> src/installation.ml ; \
	else \
	  echo "let ocamlfind = false" >> src/installation.ml ; \
	fi
125 126
# Compile the Menhir executable.
# This causes MenhirLib to be compiled, too, as it is used inside Menhir.
POTTIER Francois's avatar
POTTIER Francois committed
127 128
# Compile MenhirSdk.
	@ $(MAKE) -C src bootstrap sdk
129 130 131 132 133
# 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).
134 135
	@ echo "Creating menhirLib.ml"
	@ rm -f $(BUILDDIR)/menhirLib.ml
136
	@ for m in $(MENHIRLIB_MODULES) ; do \
137 138 139
	  echo "module $$m = struct" >> $(BUILDDIR)/menhirLib.ml ; \
	  cat src/$$m.ml >> $(BUILDDIR)/menhirLib.ml ; \
	  echo "end" >> $(BUILDDIR)/menhirLib.ml ; \
140 141 142 143 144
	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.
145 146
	@ echo "Creating menhirLib.mli"
	@ rm -f $(BUILDDIR)/menhirLib.mli
147
	@ for m in $(MENHIRLIB_MODULES) ; do \
148
	  echo "module $$m : sig" >> $(BUILDDIR)/menhirLib.mli ; \
149
	  if [ -f src/$$m.mli ] ; then \
150
	    cat src/$$m.mli >> $(BUILDDIR)/menhirLib.mli ; \
151
	  else \
152
	    cat src/$$m.ml >> $(BUILDDIR)/menhirLib.mli ; \
153
	  fi ; \
154
	  echo "end" >> $(BUILDDIR)/menhirLib.mli ; \
155 156 157 158 159 160 161 162
	done

# -------------------------------------------------------------------------

# The files that should be installed as part of menhirLib.

MENHIRLIB       := menhirLib.mli menhirLib.ml menhirLib.cmi menhirLib.cmo
ifneq ($(TARGET),byte)
163
MENHIRLIB       := $(MENHIRLIB) menhirLib.cmx menhirLib.cmxs menhirLib$(OBJ)
164
endif
165

POTTIER Francois's avatar
POTTIER Francois committed
166 167 168 169 170 171
# -------------------------------------------------------------------------

# The files that should be installed as part of menhirSdk.

MENHIRSDK       := menhirSdk.cmi menhirSdk.cmo
ifneq ($(TARGET),byte)
172
MENHIRSDK       := $(MENHIRSDK) menhirSdk.cmx menhirSdk.cmxs menhirSdk$(OBJ)
POTTIER Francois's avatar
POTTIER Francois committed
173 174
endif

175 176 177
# ----------------------------------------------------------------------------
# Installation.

178
install:
179
# Install the executable.
180
	mkdir -p $(bindir)
181
	install $(BUILDDIR)/menhir.$(TARGET) $(bindir)/menhir$(EXE)
POTTIER Francois's avatar
POTTIER Francois committed
182
# Install Menhir's standard library.
183
	mkdir -p $(libdir)
184
	install -m 644 $(MLYLIB) $(libdir)
POTTIER Francois's avatar
POTTIER Francois committed
185
# Install MenhirLib and MenhirSdk.
186
	@if `$(BUILDDIR)/menhir.$(TARGET) --suggest-ocamlfind | tr -d '\r'` ; then \
POTTIER Francois's avatar
POTTIER Francois committed
187 188 189 190 191 192
	  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 ; \
193
	else \
POTTIER Francois's avatar
POTTIER Francois committed
194
	  echo 'Installing MenhirLib and MenhirSdk manually.' ; \
fpottier's avatar
fpottier committed
195
	  install -m 644 $(patsubst %,$(BUILDDIR)/%,$(MENHIRLIB)) $(libdir) ; \
POTTIER Francois's avatar
POTTIER Francois committed
196
	  install -m 644 $(patsubst %,$(SDKDIR)/%,$(MENHIRSDK)) $(libdir) ; \
197
	fi
198 199 200 201 202 203 204
# 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
205 206

uninstall:
207
	@if `$(bindir)/menhir$(EXE) --suggest-ocamlfind` ; then \
POTTIER Francois's avatar
POTTIER Francois committed
208
	  echo 'Un-installing MenhirLib and MenhirSdk via ocamlfind.' ; \
209
	  ocamlfind remove menhirLib ; \
POTTIER Francois's avatar
POTTIER Francois committed
210
	  ocamlfind remove menhirSdk ; \
211
	fi
212
	rm -rf $(bindir)/menhir$(EXE)
213
	rm -rf $(libdir)
214 215
	rm -rf $(docdir)
	rm -rf $(mandir)/$(MANS)