Coccinelle release-1.0.0-rc11
[bpt/coccinelle.git] / configure
CommitLineData
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 20my $project =
34e49164 21 "coccinelle";
0708f913 22my $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
29my $prefix="/usr/local";
30my $python=1;
993936c0 31my $pcre=1;
174d1640 32my $noocamlscripting=0;
0708f913 33my $opt=".opt";
978fd7e5 34my $tarzan=1;
90aeb998
C
35my $pydir="pycaml";
36my $menhirdir="menhirlib";
37my $sexpdir="ocamlsexp";
97111a47
C
38my $python_cmd="python";
39
40# generic ocaml libraries (set entries to 0 to disable by default)
41# 0: disabled, 1: use global library, >1: use local library
42my %libs=
43 ( "pycaml" => 1
44 , "menhirLib" => 1
45 , "sexplib" => 1
46 , "pcre" => 1
47 , "dynlink" => 0
48 , "extlib" => 0
49 );
50
51# add additional dependencies that some of these libraries may have
52# these will then be added automatically
53# (we don't really make use of this here)
54my %deps=
55 ( # "pycaml" => ["str"] # example
56 # "sexplib" => ["unix", "bigarray", "num"]
57 );
34e49164
C
58
59local $_ = join ' ', @ARGV;
60
61# Parse options
993936c0
C
62/-h/ || /--help/ and die "usage: $0 [--prefix=path] [--without-FEATURE] [--no-opt]\n
63\t--without-python\tDisable scripting in Python
64\t--without-ocaml\t\tDisable scripting in Ocaml
65\t--without-pcre\t\tDisable regexp with PCRE
97111a47 66\t--with-pyton=PATH\t\tSpecify path to python executable
993936c0
C
67\t--no-opt\t\tDo not use the optimimized version of OCaml
68\t--opt\t\t\tUse the optimimized version of OCaml\n\n";
34e49164 69/--prefix=([^ ]*)/ and $prefix = $1;
993936c0 70/--without-pcre/ and $pcre = 0;
34e49164 71/--without-python/ and $python = 0;
c491d8ee 72/--without-ocaml/ and $noocamlscripting = 1;
0708f913 73/--no-opt/ and $opt = "";
8ba84ae2 74/--opt/ and $opt = ".opt";
97111a47
C
75/--with-python=([^ ]*)/ and $python_cmd = $1;
76
77# todo: also print these options as part of the help message...
78foreach my $lib (keys %libs) {
79 /--with-$lib/ and $libs{$lib} = 1;
80 /--with-local-$lib/ and $libs{$lib} = 2;
81 /--without-$lib/ and $libs{$lib} = 0;
82}
34e49164 83
978fd7e5
C
84#tarzan by default (used by score file parsing and now also for sexp_ast_c.ml)
85
86
97111a47
C
87# extend the feature set based on their dependencies
88my $changedLibs = 1;
89while($changedLibs) {
90 $changedLibs = 0;
91 foreach $dep (keys %deps) {
92 if ($libs{$dep}) {
93 my $reqs = $deps{$dep};
94 foreach $req (@$reqs) {
95 if (!$libs{$req}) {
96 $libs{$req} = 1;
97 $changedLibs = 1;
98 }
99 }
100 }
101 }
102}
103
17ba0788
C
104if (!$python) {
105 $libs{'pycaml'} = 0;
106}
107
34e49164
C
108#if($ARGV[0] =~ "--prefix=(.*)") {
109# $prefix = $1;
110#}
111#if($ARGV[1] =~ "--without-python") {
112# $python = 0;
113#}
114
115my $src="$prefix/share/$project";
116
117######################################################################
118# Side effects
119######################################################################
120
121
122######################################################################
123# Helpers
124######################################################################
125#BEGIN { die "need Perl 5 or greater" if $] < 5 ; }
126
127#use Common;
128sub pr2 { print STDERR "@_\n" }
0708f913 129sub cat {
34e49164
C
130 my ($what) = @_;
131 my @list;
132 open(TMP, $what);
133 while(<TMP>) { push @list, "$_"; }
134 \@list;
135}
136sub notb { !$_[0] }
137sub mapf { my ($f, $xs) = @_; [ map { &$f($_) } @{$xs} ] }
138sub plural { my ($e) = @_; if ($e > 1) { "s" } else { "" } }
139
140sub check_config { my ($command, $expect, $msggood, $msgbad) = @_;
141 my $error = 0;
0708f913 142
34e49164
C
143 my $full = cat($command);
144 my $res = join(" ", @{$full});
145# pr2 $res;
146 if(notb($res =~ $expect)) { $error++; pr2 "!!!! $msgbad !!!!"; }
147 else { pr2 $msggood }
148 return $error;
149}
150
151######################################################################
152# Let's go
153######################################################################
154pr2 "Checking your configuration.\n";
155
156my $error = 0;
157
34e49164
C
158#---------------------------------------------------------------------
159# Compilers and runtimes
160#---------------------------------------------------------------------
174d1640 161
0708f913 162$error +=
34e49164 163 check_config("echo \"1;;\\n\" | ocaml |",
174d1640 164 "Objective(.*) 3.\(09|1[0-9]\)",
34e49164
C
165 "OCaml (the wonderful language) is present.",
166 "The program ocaml is missing or is not a good version. We need at least 3.09",
167 );
168
3a314143 169unless ($noocamlscripting) {
174d1640
C
170$noocamlscripting = check_config("echo \"1;;\\n\" | ocaml |",
171 "Objective(.*) 3.1[1-9]",
172 "OCaml >= 3.11 is present. OCaml scripting activated.",
173 "OCaml scripting disabled. We need at least OCaml 3.11",
174 );
c491d8ee 175}
88e71198 176my $ocamlprefix = $noocamlscripting ? "no" : "yes";
174d1640 177
0708f913 178if ($opt eq ".opt") {
17ba0788
C
179 my $opt_check1 = `ocamlc.opt -version 2>/dev/null`;
180 if($opt_check1 =~ /[0-9\.]+/) {
8ba84ae2
C
181 pr2 "ocamlc.opt is present.";
182 }
183 else {
184 $opt="";
185 pr2 "ocamlc.opt not found";
186 }
187
17ba0788
C
188 my $opt_check2 = `ocamlopt.opt -version 2>/dev/null`;
189 if($opt_check2 =~ /[0-9\.]+/) {
8ba84ae2
C
190 pr2 "ocamlopt.opt is present.";
191 }
192 else {
193 $opt="";
194 pr2 "ocamlopt.opt not found";
195 }
196
17ba0788
C
197 my $opt_check3 = `ocamldep.opt -version 2>/dev/null`;
198 if($opt_check3 =~ /[0-9\.]+/) {
8ba84ae2
C
199 pr2 "ocamldep.opt is present.";
200 }
201 else {
0708f913 202 $opt="";
8ba84ae2
C
203 pr2 "ocamldep.opt not found";
204 }
205
17ba0788
C
206 my $opt_check4 = `ocamllex.opt -version 2>/dev/null`;
207 if($opt_check4 =~ /[0-9\.]+/) {
8ba84ae2 208 pr2 "ocamllex.opt is present.";
0708f913
C
209 }
210 else {
8ba84ae2
C
211 $opt="";
212 pr2 "ocamllex.opt not found";
213 }
214
215 if($opt eq "") {
216 pr2 "At least one native OCaml tool have not been found.";
217 pr2 "Desactivation of all native OCaml tools for compilation.";
0708f913
C
218 }
219}
220
34e49164
C
221#we have cached the result of menhir in the tgz we build.
222
0708f913 223#$error +=
34e49164
C
224# check_config("menhir --version |",
225# "menhir, version 20071212",
226## "menhir, version 2006.*",
227# "Menhir (the parser generator) is present.",
228# "The program menhir is missing or is not a good version.",
229# );
230
231
232#---------------------------------------------------------------
233# Developers tools
234#---------------------------------------------------------------
235
236pr2 "";
237
238$error += check_config(
239 "make -v 2>&1 |grep Make|",
708f4980 240 "GNU Make [^0-9]*3\.[0-9]+.*", #version 3.79.1, 3.81
34e49164
C
241 "make (gnu version) is present.",
242 "The program gnu make is missing or is not a good version.
243We need 3.XX",
244);
245
34e49164
C
246#---------------------------------------------------------------------
247# More developers tools
248#---------------------------------------------------------------------
249
250#---------------------------------------------------------------------
251# Librairies
252#---------------------------------------------------------------------
253
3a314143 254# Python dev
b23ff9c7 255my $PY_VERSION;
3a314143
C
256if($python) {
257 if(check_config(
97111a47
C
258 "$python_cmd --version 2>&1 |",
259 '^Python [23]\.',
260 "$python_cmd is present",
261 "$python_cmd is missing or is not a good version."
3a314143
C
262 ))
263 {
264 $python=0;
265 }
266 if($python) {
97111a47
C
267 my $PY_PREFIX = `$python_cmd pycaml/getprefix.py | tr -d '\n'`;
268 $PY_VERSION = `$python_cmd pycaml/getversion.py | tr -d '\n'`;
3a314143
C
269 my $python_hdr = "$PY_PREFIX/include/python$PY_VERSION/Python.h";
270 if(check_config(
271 "ls $python_hdr 2> /dev/null | ",
272 $python_hdr,
273 "Python.h found",
274 "Python.h missing - You need to install python-dev"
275 ))
276 {
277 $python=0
278 }
279 }
280}
281
ca417fcf 282my $ocamlfind=!check_config(
17ba0788
C
283 "ocamlfind ocamlc -version 2> /dev/null | ",
284 '^[0-9\.]+',
ca417fcf
C
285 "ocamlfind is present",
286 "ocamlfind is missing -- Switch to local library copies."
287 );
288
90aeb998
C
289# pycaml. Binding between Python and OCaml
290my $syspydir=`ocamlfind query pycaml 2> /dev/null | xargs echo -n`;
291
292if($syspydir) {
97111a47
C
293 pr2 "'pycaml' library is present in $syspydir";
294 if ($libs{'pycaml'} > 1) {
295 pr2 "... but a local copy of 'pycaml' will be used.";
296 }
297 else {
298 $pydir=$syspydir;
299 }
174d1640
C
300} else {
301 pr2 "'pycaml' library is not present. A local copy will be used.";
90aeb998
C
302}
303
304# menhirLib. Runtime system for the parsers generated with menhir
305my $sysmenhirdir=`ocamlfind query menhirLib 2> /dev/null | xargs echo -n`;
306
307if($sysmenhirdir) {
308 $menhirdir=$sysmenhirdir;
174d1640
C
309 pr2 "'menhirLib' library is present in $menhirdir";
310} else {
993936c0 311 pr2 "'menhirLib' library is not present. A local copy will be used.";
90aeb998
C
312}
313
97111a47 314# sexplib.
90aeb998
C
315my $syssexpdir=`ocamlfind query sexplib 2> /dev/null | xargs echo -n`;
316
317if($syssexpdir) {
318 $sexpdir=$syssexpdir;
174d1640
C
319 pr2 "'sexplib' library is present in $sexpdir";
320} else {
993936c0
C
321 pr2 "'sexplib' library is not present. A local copy will be used.";
322}
323
324# Check if libpcre-ocaml is available
325# when pcre feature is enabled.
326my $pcredir="";
327if($pcre) {
328 $pcredir=`ocamlfind query pcre 2> /dev/null | xargs echo -n `;
329 if(check_config(
330 "echo -n $pcredir | ",
331 '^/.*$',
332 "'pcre-ocaml' library is present in $pcredir",
333 "'pcre-ocaml' library is not present - You need to install libpcre-ocaml-dev"
334 ))
335 {
336 $pcre=0
337 }
90aeb998
C
338}
339
97111a47
C
340######################################################################
341# Printing of library selection
342######################################################################
343
344
345pr2 "----------------------------------------------------------------------";
346pr2 "Library configuration:";
347
17ba0788 348my %libPaths;
97111a47
C
349foreach my $lib (keys %libs) {
350 my $isSelected = $libs{$lib};
351 if ($isSelected) {
352 my $libdir = `ocamlfind query $lib 2> /dev/null | xargs echo -n`;
353 if ($libdir && $libs{$lib} <= 1) {
354 $libs{$lib} = 1;
355 $libPaths{$lib} = $libdir;
356 }
357 else {
358 if (-d $lib) { # test if local directory exists
359 $libs{$lib} = 2; # use local version
360 $libPaths{$lib} = $lib;
361 } else {
362 $libs{$lib} = 0; # disable the feature
363 $libPaths{$lib} = "";
364 }
365 }
366 }
367
368 my $choice = $libs{$lib};
369 if ($choice == 0) {
370 pr2 "$lib: disabled";
371 } elsif ($choice == 1) {
372 pr2 "$lib: global version in $libPaths{$lib}";
373 } else {
374 pr2 "$lib: local version selected";
375 }
376}
377
34e49164
C
378######################################################################
379# Generate config files (platform/portability issues)
380######################################################################
381
382
383######################################################################
384# Generate globals files (features issues)
385######################################################################
386
387######################################################################
0708f913 388# Diagnostic
34e49164
C
389######################################################################
390
0708f913 391if($error) {
34e49164
C
392 pr2 "
393----------------------------------------------------------------------
0708f913 394!!!! There seems to have problem, we have found $error missing package" .
34e49164 395plural($error) . ".
0708f913
C
396" . (($error > 1) ? "Some of those packages" : "This package") .
397 " may be installed by picking " . ($error > 1 ? "them" : "it") .
34e49164
C
398 " in $project-dependencies.tgz available
399on the $project website. !!!!
400----------------------------------------------------------------------
401";
0708f913 402} else {
34e49164 403
174d1640
C
404 pr2
405"----------------------------------------------------------------------
34e49164
C
406
407All seems fine for $project.
408
409To compile $project type:
708f4980
C
410 \$ make depend
411 \$ make all
412
413Or alternatively, for the optimized version:
414 \$ make all.opt
b1b2de81 415If you want both, you could use:
708f4980
C
416 \$ make world
417
34e49164
C
418
419To install type:
708f4980 420 \$ make install
34e49164
C
421
422Then, to test $project simply type:
708f4980 423 \$ $projectcmdline
34e49164
C
424
425";
426
ca417fcf
C
427 if($python) {
428 pr2
34e49164 429"To use the python SmPL feature you may have to set some environment variables.
174d1640 430However, they are automatically set by the front-end installed in $prefix/bin.
34e49164
C
431For bash do:
432export LD_LIBRARY_PATH=\$LD_LIBRARY_PATH:$prefix/lib
174d1640 433export PYTHONPATH=\$PYTHONPATH:$src/python"
34e49164 434 }
ca417fcf 435
174d1640 436 pr2 "----------------------------------------------------------------------";
34e49164
C
437}
438
34e49164
C
439######################################################################
440# Generating the configuration
441######################################################################
442
ca417fcf
C
443pr2 " Compilation configuration\n";
444
34e49164
C
445pr2 "$project target prefix: $prefix (you can use --prefix to override it)";
446pr2 "Generating Makefile.config";
447open(CONFIG, ">Makefile.config");
448print CONFIG "# autogenerated by configure
449
8ba84ae2
C
450#
451INSTALL_PROGRAM?=install -c -m 755
452INSTALL_LIB?= install -c -m 755
453INSTALL_DATA?= install -c -m 644
454
34e49164
C
455# Where to install the binary
456BINDIR=$prefix/bin
457
458# Where to install the man pages
459MANDIR=$prefix/man
460
461# Where to install the lib
462LIBDIR=$prefix/lib
463
464# Where to install the configuration files
465SHAREDIR=$src
466
174d1640
C
467BASH_COMPLETION_DIR=/etc/bash_completion.d
468
34e49164
C
469# Features
470FEATURE_PYTHON=$python
978fd7e5 471FEATURE_TARZAN=$tarzan
b23ff9c7
C
472";
473
474if ($python) {
97111a47
C
475print CONFIG "PYVER=$PY_VERSION\n";
476print CONFIG "PYCMD=$python_cmd\n";
b23ff9c7 477}
0708f913 478
993936c0
C
479if($pcre) {
480print CONFIG "
481PCREDIR=$pcredir"
482}
483
b23ff9c7 484print CONFIG "
90aeb998
C
485PYCAMLDIR=$pydir
486MENHIRDIR=$menhirdir
487SEXPDIR=$sexpdir
88e71198 488DYNLINK=$ocamlprefix
90aeb998 489
0708f913
C
490# The OPTBIN variable is here to allow to use ocamlc.opt instead of
491# ocaml, when it is available, which speeds up compilation. So
492# if you want the fast version of the ocaml chain tools, set this var
493# or setenv it to \".opt\" in your startup script.
494OPTBIN=$opt
34e49164
C
495";
496
97111a47
C
497#
498# Generate variables for handling the ocaml libraries
499#
500
501my @sellibs = ();
502my @makelibs = ();
503my @cleanlibs = ();
504my @deplibs = ();
505my @lnklibs = ();
506my @optlnklibs = ();
507my @inclibs = ();
508my @flagslibs = ();
509my @featurelibs = ();
510my @pathlibs = ();
511
512sub strVar {
513 return "\$(" . $_[0] . "_" . $_[1] . ")";
514}
515
516foreach $lib (keys %libs) {
517 my $sel = $libs{$lib};
518 my $path = $libPaths{$lib};
519 my $pathvar = strVar("PATH", $lib);
520
521 if ($sel == 1) { # global version
522 push(@lnklibs, strVar("GLOBAL", $lib));
523 push(@optlnklibs, strVar("GLOBALOPT", $lib));
524 } elsif ($sel > 1) { # local version
525 push(@lnklibs, strVar("LOCAL", $lib));
526 push(@optlnklibs, strVar("LOCALOPT", $lib));
527 if (-e "$path/Makefile") { # does it have a Makefile?
528 push(@makelibs, $pathvar);
529 push(@cleanlibs, $pathvar);
530 push(@deplibs, $pathvar);
531 }
532 }
533
534 if ($sel >= 1) { # indifferent of global/local
535 push(@sellibs, $lib);
536 push(@inclibs, $pathvar);
537 push(@flagslibs, strVar("FLAGS", $lib));
538
539 push(@featurelibs, "FEATURE_$lib=1");
540 push(@pathlibs, "PATH_$lib=$path");
541 }
542}
543
544my $strSellibs = join(" ", @sellibs);
545my $strMakelibs = join(" ", @makelibs);
546my $strCleanlibs = join(" ", @cleanlibs);
547my $strDeplibs = join(" ", @deplibs);
548my $strLnklibs = join(" ", @lnklibs);
549my $strOptlnklibs = join(" ", @optlnklibs);
550my $strInclibs = join(" ", @inclibs);
551my $strFlagslibs = join(" ", @flagslibs);
552my $strFeatures = join("\n", @featurelibs);
553my $strPaths = join("\n", @pathlibs);
554
555print CONFIG "
556# selected libraries
557$strFeatures
558
559# library paths
560$strPaths
561
562# collected config vars
563SELLIBS=$strSellibs
564MAKELIBS=$strMakelibs
565CLEANLIBS=$strCleanlibs
566DEPLIBS=$strDeplibs
567LNKLIBS=$strLnklibs
568OPTLNKLIBS=$strOptlnklibs
569INCLIBS=$strInclibs
570FLAGSLIBS=$strFlagslibs
17ba0788
C
571
572# selected ocaml modules
97111a47
C
573";
574
17ba0788
C
575sub repl {
576 my $src = $_[0];
577 my $dest = $_[1];
578 my $key = $_[2];
579 my $val = ucfirst($_[3]);
580 my $cmd = "sed -e 's|${key}|${val}|g' ${src} > ${dest}";
581 if (-e $dest) {
582 unlink($dest);
583 }
584 `$cmd`;
585}
174d1640
C
586
587my $pythonprefix = $python ? "yes" : "no";
ca417fcf 588pr2 "Support for python scripting: $pythonprefix";
17ba0788
C
589repl('python/pycocci.ml.in', 'python/pycocci.ml', '@PYCOCCI_FILE@', "${pythonprefix}_pycocci");
590print CONFIG "PYCOCCI_FILE=${pythonprefix}_pycocci.ml\n";
591# `cd python; ln -sf ${pythonprefix}_pycocci.ml pycocci.ml; `;
34e49164
C
592`cd python; make depend`;
593
ca417fcf 594pr2 "Support for ocaml scripting: $ocamlprefix";
17ba0788
C
595repl('ocaml/prepare_ocamlcocci.ml.in', 'ocaml/prepare_ocamlcocci.ml', '@OCAMLCOCCI_FILE@', "${ocamlprefix}_prepare_ocamlcocci");
596print CONFIG "OCAMLCOCCI_FILE=${ocamlprefix}_prepare_ocamlcocci.ml\n";
597# `cd ocaml; ln -sf ${ocamlprefix}_prepare_ocamlcocci.ml prepare_ocamlcocci.ml;`;
174d1640
C
598`cd ocaml; make depend`;
599
993936c0
C
600my $pcresuffix = $pcre ? "pcre" : "str";
601pr2 "Support for regexp: $pcresuffix";
17ba0788
C
602repl('globals/regexp.ml.in', 'globals/regexp.ml', '@REGEXP_FILE@', "Regexp_${pcresuffix}");
603print CONFIG "REGEXP_FILE=regexp_${pcresuffix}.ml";
604# `cd globals; ln -sf regexp_${pcresuffix}.ml regexp.ml; touch regexp.ml;`;
993936c0
C
605`cd globals; make depend`;
606
174d1640 607pr2 "Modifying globals/config.ml";
17ba0788
C
608my $version = `cat ./version | tr -d '\n'`;
609`echo -n "$version" > ./version`; # make sure that there are no newlines after version
610my $command1 = "sed -i -e 's|^let version = \".*\"\$|let version = \"$version\"|g' globals/config.ml.in"; # substitute version
611my $command2 = "perl -p -e 's#Not_found.\*#Not_found->\\\"$src\\\"#' globals/config.ml.in > globals/config.ml";
612`$command1`;
613`$command2`;
34e49164 614
ca417fcf
C
615pr2 "----------------------------------------------------------------------";
616pr2 " Runtime dependency\n";
617
618if ($ocamlfind) {
619pr2 "Support for external ocaml library in ocaml scripting: yes (ocamlfind found)";
620}
621else {
8babbc8f
C
622pr2 "Support for external ocaml library in ocaml scripting: no";
623pr2 "!!!!!!! WARNING !!!!!!! ocamlfind may be required at runtime";
ca417fcf
C
624}
625
626pr2 "";