File: Makefile

package info (click to toggle)
menhir 20181113-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,992 kB
  • sloc: ml: 21,252; makefile: 425; sh: 90; lisp: 8
file content (215 lines) | stat: -rw-r--r-- 8,207 bytes parent folder | download | duplicates (2)
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)