Commit | Line | Data |
---|---|---|
34e49164 | 1 | #!/usr/bin/perl |
708f4980 | 2 | |
fc1ad971 | 3 | # Author: Yoann Padioleau |
708f4980 | 4 | |
34e49164 C |
5 | ###################################################################### |
6 | # Prelude | |
7 | ###################################################################### | |
8 | ||
9 | # Yes I know about autoconf ... and autoconf sux. | |
10 | ||
11 | # assume standard: diff | |
12 | # assume standard: perl | |
13 | ||
708f4980 | 14 | #TODO check python 2.5 ? |
34e49164 | 15 | |
978fd7e5 C |
16 | # need latex and hevea if want to compile the documentation |
17 | ||
34e49164 C |
18 | #old: --with-menhir=/path/to/menhirLib or `ocamlfind query menhirLib` |
19 | ||
0708f913 | 20 | my $project = |
34e49164 | 21 | "coccinelle"; |
0708f913 | 22 | my $projectcmdline = |
978fd7e5 | 23 | "spatch -sp_file demos/simple.cocci demos/simple.c -o /tmp/new_simple.c"; |
34e49164 | 24 | |
34e49164 C |
25 | ###################################################################### |
26 | # Options | |
27 | ###################################################################### | |
28 | ||
29 | my $prefix="/usr/local"; | |
30 | my $python=1; | |
174d1640 | 31 | my $noocamlscripting=0; |
0708f913 | 32 | my $opt=".opt"; |
978fd7e5 | 33 | my $tarzan=1; |
90aeb998 C |
34 | my $pydir="pycaml"; |
35 | my $menhirdir="menhirlib"; | |
36 | my $sexpdir="ocamlsexp"; | |
34e49164 C |
37 | |
38 | local $_ = join ' ', @ARGV; | |
39 | ||
40 | # Parse options | |
c491d8ee | 41 | /-h/ || /--help/ and die "usage: $0 [--prefix=path] [--without-python] [--without-ocaml] [--no-opt]\n\n\t--no-opt\tDo not use the optimimized version of OCaml\n\t--opt\tUse the optimimized version of OCaml\n\n"; |
34e49164 C |
42 | /--prefix=([^ ]*)/ and $prefix = $1; |
43 | /--without-python/ and $python = 0; | |
c491d8ee | 44 | /--without-ocaml/ and $noocamlscripting = 1; |
0708f913 | 45 | /--no-opt/ and $opt = ""; |
8ba84ae2 | 46 | /--opt/ and $opt = ".opt"; |
34e49164 | 47 | |
978fd7e5 C |
48 | #tarzan by default (used by score file parsing and now also for sexp_ast_c.ml) |
49 | ||
50 | ||
34e49164 C |
51 | #if($ARGV[0] =~ "--prefix=(.*)") { |
52 | # $prefix = $1; | |
53 | #} | |
54 | #if($ARGV[1] =~ "--without-python") { | |
55 | # $python = 0; | |
56 | #} | |
57 | ||
58 | my $src="$prefix/share/$project"; | |
59 | ||
60 | ###################################################################### | |
61 | # Side effects | |
62 | ###################################################################### | |
63 | ||
64 | ||
65 | ###################################################################### | |
66 | # Helpers | |
67 | ###################################################################### | |
68 | #BEGIN { die "need Perl 5 or greater" if $] < 5 ; } | |
69 | ||
70 | #use Common; | |
71 | sub pr2 { print STDERR "@_\n" } | |
0708f913 | 72 | sub cat { |
34e49164 C |
73 | my ($what) = @_; |
74 | my @list; | |
75 | open(TMP, $what); | |
76 | while(<TMP>) { push @list, "$_"; } | |
77 | \@list; | |
78 | } | |
79 | sub notb { !$_[0] } | |
80 | sub mapf { my ($f, $xs) = @_; [ map { &$f($_) } @{$xs} ] } | |
81 | sub plural { my ($e) = @_; if ($e > 1) { "s" } else { "" } } | |
82 | ||
83 | sub check_config { my ($command, $expect, $msggood, $msgbad) = @_; | |
84 | my $error = 0; | |
0708f913 | 85 | |
34e49164 C |
86 | my $full = cat($command); |
87 | my $res = join(" ", @{$full}); | |
88 | # pr2 $res; | |
89 | if(notb($res =~ $expect)) { $error++; pr2 "!!!! $msgbad !!!!"; } | |
90 | else { pr2 $msggood } | |
91 | return $error; | |
92 | } | |
93 | ||
94 | ###################################################################### | |
95 | # Let's go | |
96 | ###################################################################### | |
97 | pr2 "Checking your configuration.\n"; | |
98 | ||
99 | my $error = 0; | |
100 | ||
34e49164 C |
101 | #--------------------------------------------------------------------- |
102 | # Compilers and runtimes | |
103 | #--------------------------------------------------------------------- | |
174d1640 | 104 | |
0708f913 | 105 | $error += |
34e49164 | 106 | check_config("echo \"1;;\\n\" | ocaml |", |
174d1640 | 107 | "Objective(.*) 3.\(09|1[0-9]\)", |
34e49164 C |
108 | "OCaml (the wonderful language) is present.", |
109 | "The program ocaml is missing or is not a good version. We need at least 3.09", | |
110 | ); | |
111 | ||
3a314143 | 112 | unless ($noocamlscripting) { |
174d1640 C |
113 | $noocamlscripting = check_config("echo \"1;;\\n\" | ocaml |", |
114 | "Objective(.*) 3.1[1-9]", | |
115 | "OCaml >= 3.11 is present. OCaml scripting activated.", | |
116 | "OCaml scripting disabled. We need at least OCaml 3.11", | |
117 | ); | |
c491d8ee | 118 | } |
88e71198 | 119 | my $ocamlprefix = $noocamlscripting ? "no" : "yes"; |
174d1640 | 120 | |
0708f913 | 121 | if ($opt eq ".opt") { |
8ba84ae2 C |
122 | my $opt_check = `which ocamlc.opt 2> /dev/null`; |
123 | if($opt_check =~ "/ocamlc.opt\$") { | |
124 | pr2 "ocamlc.opt is present."; | |
125 | } | |
126 | else { | |
127 | $opt=""; | |
128 | pr2 "ocamlc.opt not found"; | |
129 | } | |
130 | ||
131 | my $opt_check = `which ocamlopt.opt 2> /dev/null`; | |
132 | if($opt_check =~ "/ocamlopt.opt\$") { | |
133 | pr2 "ocamlopt.opt is present."; | |
134 | } | |
135 | else { | |
136 | $opt=""; | |
137 | pr2 "ocamlopt.opt not found"; | |
138 | } | |
139 | ||
140 | my $opt_check = `which ocamldep.opt 2> /dev/null`; | |
141 | if($opt_check =~ "/ocamldep.opt\$") { | |
142 | pr2 "ocamldep.opt is present."; | |
143 | } | |
144 | else { | |
0708f913 | 145 | $opt=""; |
8ba84ae2 C |
146 | pr2 "ocamldep.opt not found"; |
147 | } | |
148 | ||
149 | my $opt_check = `which ocamllex.opt 2> /dev/null`; | |
150 | if($opt_check =~ "/ocamllex.opt\$") { | |
151 | pr2 "ocamllex.opt is present."; | |
0708f913 C |
152 | } |
153 | else { | |
8ba84ae2 C |
154 | $opt=""; |
155 | pr2 "ocamllex.opt not found"; | |
156 | } | |
157 | ||
158 | if($opt eq "") { | |
159 | pr2 "At least one native OCaml tool have not been found."; | |
160 | pr2 "Desactivation of all native OCaml tools for compilation."; | |
0708f913 C |
161 | } |
162 | } | |
163 | ||
34e49164 C |
164 | #we have cached the result of menhir in the tgz we build. |
165 | ||
0708f913 | 166 | #$error += |
34e49164 C |
167 | # check_config("menhir --version |", |
168 | # "menhir, version 20071212", | |
169 | ## "menhir, version 2006.*", | |
170 | # "Menhir (the parser generator) is present.", | |
171 | # "The program menhir is missing or is not a good version.", | |
172 | # ); | |
173 | ||
174 | ||
175 | #--------------------------------------------------------------- | |
176 | # Developers tools | |
177 | #--------------------------------------------------------------- | |
178 | ||
179 | pr2 ""; | |
180 | ||
181 | $error += check_config( | |
182 | "make -v 2>&1 |grep Make|", | |
708f4980 | 183 | "GNU Make [^0-9]*3\.[0-9]+.*", #version 3.79.1, 3.81 |
34e49164 C |
184 | "make (gnu version) is present.", |
185 | "The program gnu make is missing or is not a good version. | |
186 | We need 3.XX", | |
187 | ); | |
188 | ||
34e49164 C |
189 | #--------------------------------------------------------------------- |
190 | # More developers tools | |
191 | #--------------------------------------------------------------------- | |
192 | ||
193 | #--------------------------------------------------------------------- | |
194 | # Librairies | |
195 | #--------------------------------------------------------------------- | |
196 | ||
3a314143 | 197 | # Python dev |
b23ff9c7 | 198 | my $PY_VERSION; |
3a314143 C |
199 | if($python) { |
200 | if(check_config( | |
201 | "python --version 2>&1 |", | |
b23ff9c7 | 202 | '^Python 2\.([4567]|[4567]\.\S*)$', |
3a314143 C |
203 | "python is present", |
204 | "python is missing or is not a good version." | |
205 | )) | |
206 | { | |
207 | $python=0; | |
208 | } | |
209 | if($python) { | |
210 | my $PY_PREFIX = `python pycaml/getprefix.py | tr -d '\n'`; | |
b23ff9c7 | 211 | $PY_VERSION = `python pycaml/getversion.py | tr -d '\n'`; |
3a314143 C |
212 | my $python_hdr = "$PY_PREFIX/include/python$PY_VERSION/Python.h"; |
213 | if(check_config( | |
214 | "ls $python_hdr 2> /dev/null | ", | |
215 | $python_hdr, | |
216 | "Python.h found", | |
217 | "Python.h missing - You need to install python-dev" | |
218 | )) | |
219 | { | |
220 | $python=0 | |
221 | } | |
222 | } | |
223 | } | |
224 | ||
ca417fcf C |
225 | my $ocamlfind=!check_config( |
226 | "which ocamlfind 2> /dev/null |", | |
227 | '/ocamlfind$', | |
228 | "ocamlfind is present", | |
229 | "ocamlfind is missing -- Switch to local library copies." | |
230 | ); | |
231 | ||
90aeb998 C |
232 | # pycaml. Binding between Python and OCaml |
233 | my $syspydir=`ocamlfind query pycaml 2> /dev/null | xargs echo -n`; | |
234 | ||
235 | if($syspydir) { | |
236 | $pydir=$syspydir; | |
174d1640 C |
237 | pr2 "'pycaml' library is present in $pydir"; |
238 | } else { | |
239 | pr2 "'pycaml' library is not present. A local copy will be used."; | |
90aeb998 C |
240 | } |
241 | ||
242 | # menhirLib. Runtime system for the parsers generated with menhir | |
243 | my $sysmenhirdir=`ocamlfind query menhirLib 2> /dev/null | xargs echo -n`; | |
244 | ||
245 | if($sysmenhirdir) { | |
246 | $menhirdir=$sysmenhirdir; | |
174d1640 C |
247 | pr2 "'menhirLib' library is present in $menhirdir"; |
248 | } else { | |
249 | pr2 "'menhirLib' library is not present. A local copy will be used.."; | |
90aeb998 C |
250 | } |
251 | ||
252 | # sexplib. Runtime system for the parsers generated with menhir | |
253 | my $syssexpdir=`ocamlfind query sexplib 2> /dev/null | xargs echo -n`; | |
254 | ||
255 | if($syssexpdir) { | |
256 | $sexpdir=$syssexpdir; | |
174d1640 C |
257 | pr2 "'sexplib' library is present in $sexpdir"; |
258 | } else { | |
259 | pr2 "'sexplib' library is not present. A local copy will be used.."; | |
90aeb998 C |
260 | } |
261 | ||
34e49164 C |
262 | ###################################################################### |
263 | # Generate config files (platform/portability issues) | |
264 | ###################################################################### | |
265 | ||
266 | ||
267 | ###################################################################### | |
268 | # Generate globals files (features issues) | |
269 | ###################################################################### | |
270 | ||
271 | ###################################################################### | |
0708f913 | 272 | # Diagnostic |
34e49164 C |
273 | ###################################################################### |
274 | ||
275 | ||
0708f913 | 276 | if($error) { |
34e49164 C |
277 | pr2 " |
278 | ---------------------------------------------------------------------- | |
0708f913 | 279 | !!!! There seems to have problem, we have found $error missing package" . |
34e49164 | 280 | plural($error) . ". |
0708f913 C |
281 | " . (($error > 1) ? "Some of those packages" : "This package") . |
282 | " may be installed by picking " . ($error > 1 ? "them" : "it") . | |
34e49164 C |
283 | " in $project-dependencies.tgz available |
284 | on the $project website. !!!! | |
285 | ---------------------------------------------------------------------- | |
286 | "; | |
0708f913 | 287 | } else { |
34e49164 | 288 | |
174d1640 C |
289 | pr2 |
290 | "---------------------------------------------------------------------- | |
34e49164 C |
291 | |
292 | All seems fine for $project. | |
293 | ||
294 | To compile $project type: | |
708f4980 C |
295 | \$ make depend |
296 | \$ make all | |
297 | ||
298 | Or alternatively, for the optimized version: | |
299 | \$ make all.opt | |
b1b2de81 | 300 | If you want both, you could use: |
708f4980 C |
301 | \$ make world |
302 | ||
34e49164 C |
303 | |
304 | To install type: | |
708f4980 | 305 | \$ make install |
34e49164 C |
306 | |
307 | Then, to test $project simply type: | |
708f4980 | 308 | \$ $projectcmdline |
34e49164 C |
309 | |
310 | "; | |
311 | ||
ca417fcf C |
312 | if($python) { |
313 | pr2 | |
34e49164 | 314 | "To use the python SmPL feature you may have to set some environment variables. |
174d1640 | 315 | However, they are automatically set by the front-end installed in $prefix/bin. |
34e49164 C |
316 | For bash do: |
317 | export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$prefix/lib | |
174d1640 | 318 | export PYTHONPATH=\$PYTHONPATH:$src/python" |
34e49164 | 319 | } |
ca417fcf | 320 | |
174d1640 | 321 | pr2 "----------------------------------------------------------------------"; |
34e49164 C |
322 | } |
323 | ||
34e49164 C |
324 | ###################################################################### |
325 | # Generating the configuration | |
326 | ###################################################################### | |
327 | ||
ca417fcf C |
328 | pr2 " Compilation configuration\n"; |
329 | ||
34e49164 C |
330 | pr2 "$project target prefix: $prefix (you can use --prefix to override it)"; |
331 | pr2 "Generating Makefile.config"; | |
332 | open(CONFIG, ">Makefile.config"); | |
333 | print CONFIG "# autogenerated by configure | |
334 | ||
8ba84ae2 C |
335 | # |
336 | INSTALL_PROGRAM?=install -c -m 755 | |
337 | INSTALL_LIB?= install -c -m 755 | |
338 | INSTALL_DATA?= install -c -m 644 | |
339 | ||
34e49164 C |
340 | # Where to install the binary |
341 | BINDIR=$prefix/bin | |
342 | ||
343 | # Where to install the man pages | |
344 | MANDIR=$prefix/man | |
345 | ||
346 | # Where to install the lib | |
347 | LIBDIR=$prefix/lib | |
348 | ||
349 | # Where to install the configuration files | |
350 | SHAREDIR=$src | |
351 | ||
174d1640 C |
352 | BASH_COMPLETION_DIR=/etc/bash_completion.d |
353 | ||
34e49164 C |
354 | # Features |
355 | FEATURE_PYTHON=$python | |
978fd7e5 | 356 | FEATURE_TARZAN=$tarzan |
b23ff9c7 C |
357 | "; |
358 | ||
359 | if ($python) { | |
360 | print CONFIG "PYVER=$PY_VERSION"; | |
361 | } | |
0708f913 | 362 | |
b23ff9c7 | 363 | print CONFIG " |
90aeb998 C |
364 | PYCAMLDIR=$pydir |
365 | MENHIRDIR=$menhirdir | |
366 | SEXPDIR=$sexpdir | |
88e71198 | 367 | DYNLINK=$ocamlprefix |
90aeb998 | 368 | |
0708f913 C |
369 | # The OPTBIN variable is here to allow to use ocamlc.opt instead of |
370 | # ocaml, when it is available, which speeds up compilation. So | |
371 | # if you want the fast version of the ocaml chain tools, set this var | |
372 | # or setenv it to \".opt\" in your startup script. | |
373 | OPTBIN=$opt | |
34e49164 C |
374 | "; |
375 | ||
174d1640 C |
376 | |
377 | my $pythonprefix = $python ? "yes" : "no"; | |
ca417fcf | 378 | pr2 "Support for python scripting: $pythonprefix"; |
174d1640 | 379 | `cd python; ln -sf ${pythonprefix}_pycocci.ml pycocci.ml; `; |
34e49164 C |
380 | `cd python; make depend`; |
381 | ||
ca417fcf | 382 | pr2 "Support for ocaml scripting: $ocamlprefix"; |
174d1640 C |
383 | `cd ocaml; ln -sf ${ocamlprefix}_prepare_ocamlcocci.ml prepare_ocamlcocci.ml;`; |
384 | `cd ocaml; make depend`; | |
385 | ||
386 | pr2 "Modifying globals/config.ml"; | |
b1b2de81 | 387 | my $command = "perl -p -e 's#Not_found.\*#Not_found->\\\"$src\\\"#' globals/config.ml.in > globals/config.ml"; |
34e49164 C |
388 | `$command`; |
389 | ||
ca417fcf C |
390 | pr2 "----------------------------------------------------------------------"; |
391 | pr2 " Runtime dependency\n"; | |
392 | ||
393 | if ($ocamlfind) { | |
394 | pr2 "Support for external ocaml library in ocaml scripting: yes (ocamlfind found)"; | |
395 | } | |
396 | else { | |
397 | pr2 "Support for external ocaml library in ocaml scripting: no (ocamlfind may be required at runtime)"; | |
398 | } | |
399 | ||
400 | pr2 ""; |