Commit | Line | Data |
---|---|---|
d6ce1786 C |
1 | .PHONY: clean |
2 | ||
3 | COLD += clean | |
4 | ||
5 | # ---------------------------------------------------------------------------- | |
6 | ||
7 | # A few settings differ on Windows versus Unix. | |
8 | ||
9 | include ../Makefile.arch | |
10 | ||
11 | # ---------------------------------------------------------------------------- | |
12 | # Locating the ocaml compilers. | |
13 | # If ocamlfind is available, then it is used for that purpose. | |
14 | ||
15 | CAMLTOP := ocaml | |
16 | ||
17 | CAMLC := $(shell if ocamlfind ocamlc -v >/dev/null 2>&1 ; \ | |
18 | then echo ocamlfind ocamlc ; \ | |
19 | elif ocamlc.opt -v >/dev/null 2>&1 ; \ | |
20 | then echo ocamlc.opt ; \ | |
21 | else echo ocamlc ; fi) | |
22 | ||
23 | CAMLOPT := $(shell if ocamlfind ocamlopt -v >/dev/null 2>&1 ; \ | |
24 | then echo ocamlfind ocamlopt ; \ | |
25 | elif ocamlopt.opt -v >/dev/null 2>&1 ; \ | |
26 | then echo ocamlopt.opt ; \ | |
27 | else echo ocamlopt ; fi) | |
28 | ||
29 | CAMLDEP := $(shell if ocamlfind ocamldep -version >/dev/null 2>&1 ; \ | |
30 | then echo ocamlfind ocamldep ; \ | |
31 | elif ocamldep.opt -version >/dev/null 2>&1 ; \ | |
32 | then echo ocamldep.opt ; \ | |
33 | else echo ocamldep ; fi) | |
34 | ||
35 | CAMLDEPWRAPPER := ../demos/ocamldep.wrapper | |
36 | ||
37 | CAMLLEX := ocamllex | |
38 | ||
39 | CAMLYACC := ocamlyacc -v | |
40 | ||
41 | # ------------------------------------------------------------------------- | |
42 | ||
43 | # Compilation flags. | |
44 | ||
45 | BFLAGS := -g | |
46 | OFLAGS := -inline 1000 | |
47 | LNKBFLAGS := -g | |
48 | LNKOFLAGS := | |
49 | BLIBS := unix.cma | |
50 | OLIBS := unix.cmxa | |
51 | PGFLAGS := -v -lg 1 -la 1 -lc 1 --comment --infer --error-recovery --stdlib . --strict | |
52 | ||
53 | # ------------------------------------------------------------------------- | |
54 | ||
55 | # A list of the source files that must be generated prior to dependency | |
56 | # analysis. | |
57 | ||
58 | GENERATED := installation.ml lexmli.ml lexer.ml parser.mli parser.ml \ | |
59 | lineCount.ml lexdep.ml sentenceParser.mli sentenceParser.ml sentenceLexer.ml | |
60 | ||
61 | # ------------------------------------------------------------------------- | |
62 | ||
63 | # A list of the modules that must be linked into the MenhirLib library. | |
64 | ||
65 | # This library is used both at compile time (i.e., within Menhir itself) | |
66 | # and at run time (i.e., it is made available to Menhir users, who need | |
67 | # to link it with their own executables if they have used the --table | |
68 | # option). | |
69 | ||
70 | # If you change this list, please also update the files LICENSE and | |
71 | # GNUmakefile in the toplevel directory. | |
72 | ||
73 | LIBMODULES := infiniteArray packedIntArray rowDisplacement engineTypes \ | |
74 | engine tableFormat tableInterpreter convert | |
75 | ||
76 | # ------------------------------------------------------------------------- | |
77 | ||
78 | # A list of the modules that must be linked into the Menhir executable. | |
79 | ||
80 | MODULES := menhirLib Fix stringSet stringMap mark compressedBitSet \ | |
81 | unionFind tarjan nonpositiveCycles patricia misc option \ | |
82 | breadth listMonad dot installation version settings time \ | |
83 | positions error parameters keyword lineCount printer \ | |
84 | rawPrinter action parserAux parser lexer partialGrammar \ | |
85 | parameterizedGrammar reachability unparameterizedPrinter \ | |
86 | preFront codeBits tokenType interface IO lexmli lexdep \ | |
87 | infer nonTerminalDefinitionInlining front grammar item lr0 \ | |
88 | slr lr1 lr1partial derivation conflict invariant codePieces \ | |
89 | sentenceParser sentenceLexer pprint cst \ | |
90 | referenceInterpreter interpret tableBackend codeBackend \ | |
91 | coqBackend traverse inliner back | |
92 | ||
93 | # ------------------------------------------------------------------------- | |
94 | ||
95 | # How to bootstrap. | |
96 | ||
97 | # Set TARGET to byte or opt depending on the desired architecture. | |
98 | ||
99 | ifndef TARGET | |
100 | TARGET := opt | |
101 | endif | |
102 | ||
103 | # The variable GOAL is the name of the executable file. | |
104 | ||
105 | GOAL := menhir.$(TARGET) | |
106 | ||
107 | # We create a symbolic link of GOAL to MENHIREXE. | |
108 | ||
109 | $(MENHIREXE): .versioncheck | |
110 | # Build a stage one executable using ocamlyacc. | |
111 | $(MAKE) -s PGEN="$(CAMLYACC)" PARSER=parser $(GOAL) | |
112 | # Remove the ocamlyacc-built parser. | |
113 | @/bin/rm -f parser.ml parser.mli | |
114 | # Build a stage two executable using the stage one executable (which is overwritten). | |
115 | $(MAKE) -s PGEN="./$(GOAL) $(PGFLAGS)" PARSER=fancy-parser $(GOAL) | |
116 | # Create a stage three parser and make sure that it is identical. | |
117 | @./$(GOAL) $(PGFLAGS) -b reference fancy-parser.mly 2>/dev/null | |
118 | @if diff parser.mli reference.mli 2>&1 >/dev/null ; then \ | |
119 | if diff parser.ml reference.ml 2>&1 >/dev/null ; then \ | |
120 | echo "Bootstrap successful." ; \ | |
121 | else \ | |
122 | echo "Bootstrap FAILED: the implementation files differ." && false ; \ | |
123 | fi ; \ | |
124 | else \ | |
125 | echo "Bootstrap FAILED: the interface files differ." && false ; \ | |
126 | fi | |
127 | @rm -f reference.ml reference.mli | |
128 | # Rename the stage two executable to the desired name. | |
129 | # Use a symbolic link, so that further development builds implicitly update | |
130 | # menhir. | |
131 | @ln -sf $(GOAL) $@ | |
132 | ||
133 | # ------------------------------------------------------------------------- | |
134 | ||
135 | # Linking. | |
136 | ||
137 | menhirLib.cmo menhirLib.cmi: $(LIBMODULES:=.cmo) | |
138 | $(CAMLC) $(BFLAGS) -pack -o menhirLib.cmo $^ | |
139 | ||
140 | menhirLib.cmx menhirLib.o: $(LIBMODULES:=.cmx) | |
141 | $(CAMLOPT) -pack -o menhirLib.cmx $^ | |
142 | ||
143 | menhir.byte: $(MODULES:=.cmo) | |
144 | $(CAMLC) -o $@ $(LNKBFLAGS) $(BLIBS) $^ | |
145 | ||
146 | menhir.opt: $(MODULES:=.cmx) | |
147 | $(CAMLOPT) -o $@ $(LNKOFLAGS) $(OLIBS) $^ | |
148 | ||
149 | # ------------------------------------------------------------------------- | |
150 | ||
151 | # Computing dependencies. This can be done in a simple way, even though | |
152 | # we exploit --infer, because we compile in two stages. Not a good example | |
153 | # of how to do it yourself -- have a look at demos/Makefile.shared. | |
154 | ||
155 | # For completeness, we must force ocamldep to understand that MenhirLib | |
156 | # is a module name. We do this by creating phantom source files for it. | |
157 | ||
158 | .depend: $(wildcard *.ml *.mli) $(GENERATED) | |
159 | @/bin/rm -f .depend | |
160 | for i in *.ml *.mli; do \ | |
161 | $(CAMLDEPWRAPPER) menhirLib.ml menhirLib.mli - $(CAMLDEP) $$i \ | |
162 | >> $@; \ | |
163 | done | |
164 | ||
165 | ifeq ($(findstring $(MAKECMDGOALS),$(COLD)),) | |
166 | -include .depend | |
167 | endif | |
168 | ||
169 | # ------------------------------------------------------------------------- | |
170 | ||
171 | # Cleaning up. | |
172 | ||
173 | clean:: | |
174 | /bin/rm -f menhir.byte menhir.opt $(MENHIREXE) | |
175 | /bin/rm -f *.cmi *.cmx *.cmo *.$(OBJ) *~ .*~ | |
176 | /bin/rm -f reference.ml reference.mli $(GENERATED) | |
177 | /bin/rm -f .depend *.conflicts *.automaton *.annot *.output | |
178 | ||
179 | # ------------------------------------------------------------------------- | |
180 | ||
181 | # Compiling. The parser source is found in $(PARSER).mly and is | |
182 | # processed using $(PGEN). | |
183 | ||
184 | # These two default definitions really shouldn't be necessary, but | |
185 | # there are corner cases where they are needed (e.g. when make is | |
186 | # invoked without a target and the .depend file is regenerated). | |
187 | ||
188 | ifndef PGEN | |
189 | PGEN := $(CAMLYACC) | |
190 | endif | |
191 | ifndef PARSER | |
192 | PARSER := parser | |
193 | endif | |
194 | ||
195 | %.cmi: %.mli | |
196 | $(CAMLC) $(BFLAGS) -c $< | |
197 | ||
198 | %.cmo: %.ml | |
199 | $(CAMLC) $(BFLAGS) -c $< | |
200 | ||
201 | # If the module that is being compiled is part of MenhirLib, add the | |
202 | # -for-pack option to the command line. This is required only when | |
203 | # compiling to native code (the bytecode compiler accepts but ignores | |
204 | # this option). | |
205 | ||
206 | PACK = $(shell if echo $(LIBMODULES) | grep $* >/dev/null ; then echo -for-pack MenhirLib ; else echo ; fi) | |
207 | ||
208 | %.cmx %.o: %.ml | |
209 | $(CAMLOPT) $(OFLAGS) $(PACK) -c $< | |
210 | ||
211 | # The source file for this parser varies. It is either parser.mly or | |
212 | # fancy-parser.mly. | |
213 | # | |
214 | parser.ml parser.mli: $(PARSER).mly | |
215 | @/bin/rm -f parser.ml parser.mli | |
216 | $(PGEN) -b parser $< | |
217 | ||
218 | # This parser must be built with ocamlyacc, because its client | |
219 | # watches for Parsing.Parse_error! | |
220 | # | |
221 | # Using ocamlyacc or Menhir interchangeably would be possible, | |
222 | # via an ocamlyacc wrapper that adds the definition "exception | |
223 | # Error = Parsing.Parse_error" at the end of the generated .ml | |
224 | # and .mli files. | |
225 | # | |
226 | sentenceParser.ml sentenceParser.mli : sentenceParser.mly | |
227 | @/bin/rm -f sentenceParser.ml sentenceParser.mli | |
228 | $(CAMLYACC) -b sentenceParser $< | |
229 | ||
230 | %.ml: %.mll | |
231 | @/bin/rm -f $@ | |
232 | $(CAMLLEX) $< | |
233 | ||
234 | # ---------------------------------------------------------------------------- | |
235 | # Checking the version of the ocaml compiler. | |
236 | # | |
237 | # We check the bytecode compiler only, because some architectures don't have | |
238 | # the native code compiler. We assume that both compilers, if present, are in | |
239 | # sync. | |
240 | ||
241 | # We build a bytecode executable (rather than use the toplevel loop) because | |
242 | # we need to load str.cma and some ocaml ports do not support dynamic loading | |
243 | # (e.g. ocaml 3.09, MacOS/Intel). | |
244 | ||
245 | .versioncheck: | |
246 | @ echo Checking that Objective Caml is recent enough... | |
247 | @ $(CAMLC) -o check-ocaml-version str.cma checkOCamlVersion.ml | |
248 | @ ./check-ocaml-version --verbose --gt "3.09" | |
249 | @ rm check-ocaml-version | |
250 | @ touch .versioncheck | |
251 | ||
252 | clean:: | |
253 | rm -f .versioncheck | |
254 |