2a492926229b5dcfd8d16e7d23c50ea8897a4f8f
[bpt/coccinelle.git] / Makefile
1 # Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
2 # Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
3 # This file is part of Coccinelle.
4 #
5 # Coccinelle is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, according to version 2 of the License.
8 #
9 # Coccinelle is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # The authors reserve the right to distribute this or future versions of
18 # Coccinelle under other licenses.
19
20
21 #############################################################################
22 # Configuration section
23 #############################################################################
24
25 -include Makefile.config
26
27 VERSION=$(shell cat globals/config.ml.in |grep version |perl -p -e 's/.*"(.*)".*/$$1/;')
28
29 ##############################################################################
30 # Variables
31 ##############################################################################
32 TARGET=spatch
33
34 SRC=flag_cocci.ml cocci.ml testing.ml test.ml main.ml
35
36 ifeq ($(FEATURE_PYTHON),1)
37 PYCMA=pycaml/pycaml.cma
38 PYDIR=pycaml
39 PYLIB=dllpycaml_stubs.so
40 # the following is essential for Coccinelle to compile under gentoo (weird)
41 OPTLIBFLAGS=-cclib dllpycaml_stubs.so
42 else
43 PYCMA=
44 PYDIR=
45 PYLIB=
46 OPTLIBFLAGS=
47 endif
48
49 SEXPSYSCMA=bigarray.cma nums.cma
50
51 SYSLIBS=str.cma unix.cma $(SEXPSYSCMA)
52 LIBS=commons/commons.cma \
53 ocamlsexp/sexplib1.cma commons/commons_sexp.cma \
54 globals/globals.cma \
55 ctl/ctl.cma \
56 parsing_cocci/cocci_parser.cma parsing_c/parsing_c.cma \
57 engine/cocciengine.cma \
58 extra/extra.cma $(PYCMA) python/coccipython.cma
59
60 #used for clean: and depend: and a little for rec & rec.opt
61 MAKESUBDIRS=commons ocamlsexp \
62 globals menhirlib $(PYDIR) ctl parsing_cocci parsing_c \
63 engine extra python
64 INCLUDEDIRS=commons commons/ocamlextra ocamlsexp \
65 globals menhirlib $(PYDIR) ctl \
66 parsing_cocci parsing_c engine extra python
67
68 ##############################################################################
69 # Generic variables
70 ##############################################################################
71
72 INCLUDES=$(INCLUDEDIRS:%=-I %)
73
74 OBJS= $(SRC:.ml=.cmo)
75 OPTOBJS= $(SRC:.ml=.cmx)
76
77 EXEC=$(TARGET)
78
79 ##############################################################################
80 # Generic ocaml variables
81 ##############################################################################
82
83 OCAMLCFLAGS= #-g -dtypes # -w A
84
85 # for profiling add -p -inline 0
86 # but 'make forprofiling' below does that for you.
87 # This flag is also used in subdirectories so don't change its name here.
88 OPTFLAGS=
89 # the following is essential for Coccinelle to compile under gentoo
90 # but is now defined above in this file
91 #OPTLIBFLAGS=-cclib dllpycaml_stubs.so
92
93 OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
94 OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
95 OCAMLLEX=ocamllex #-ml # -ml for debugging lexer, but slightly slower
96 OCAMLYACC=ocamlyacc -v
97 OCAMLDEP=ocamldep $(INCLUDES)
98 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
99
100 # can also be set via 'make static'
101 STATIC= #-ccopt -static
102
103 # can also be unset via 'make purebytecode'
104 BYTECODE_STATIC=-custom
105
106 ##############################################################################
107 # Top rules
108 ##############################################################################
109 .PHONY:: all all.opt byte opt top clean distclean configure
110 .PHONY:: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt) subdirs subdirs.opt
111
112 all: byte
113 $(MAKE) preinstall
114
115 opt: all.opt
116 all.opt: opt-compil
117 $(MAKE) preinstall
118
119 world:
120 $(MAKE) byte
121 $(MAKE) opt
122 $(MAKE) preinstall
123
124 byte: .depend
125 $(MAKE) subdirs
126 $(MAKE) $(EXEC)
127
128 opt-compil: .depend
129 $(MAKE) subdirs.opt
130 $(MAKE) $(EXEC).opt
131
132 top: $(EXEC).top
133
134 subdirs:
135 $(MAKE) -C commons OCAMLCFLAGS="$(OCAMLCFLAGS)"
136 $(MAKE) -C ocamlsexp OCAMLCFLAGS="$(OCAMLCFLAGS)"
137 $(MAKE) -C commons sexp OCAMLCFLAGS="$(OCAMLCFLAGS)"
138 +for D in $(MAKESUBDIRS); do $(MAKE) $$D || exit 1 ; done
139
140 subdirs.opt:
141 $(MAKE) -C commons all.opt OCAMLCFLAGS="$(OCAMLCFLAGS)"
142 $(MAKE) -C ocamlsexp all.opt OCAMLCFLAGS="$(OCAMLCFLAGS)"
143 $(MAKE) -C commons sexp.opt OCAMLCFLAGS="$(OCAMLCFLAGS)"
144 +for D in $(MAKESUBDIRS); do $(MAKE) $$D.opt || exit 1 ; done
145
146 $(MAKESUBDIRS):
147 $(MAKE) -C $@ OCAMLCFLAGS="$(OCAMLCFLAGS)" all
148
149 $(MAKESUBDIRS:%=%.opt):
150 $(MAKE) -C $(@:%.opt=%) OCAMLCFLAGS="$(OCAMLCFLAGS)" all.opt
151
152 #dependencies:
153 # commons:
154 # globals:
155 # menhirlib:
156 # parsing_cocci: commons globals menhirlib
157 # parsing_c:parsing_cocci
158 # ctl:globals commons
159 # engine: parsing_cocci parsing_c ctl
160 # extra: parsing_cocci parsing_c ctl
161 # pycaml:
162 # python:pycaml parsing_cocci parsing_c
163
164 clean::
165 set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i $@; done
166
167 $(LIBS): $(MAKESUBDIRS)
168 $(LIBS:.cma=.cmxa): $(MAKESUBDIRS:%=%.opt)
169
170 $(OBJS):$(LIBS)
171 $(OPTOBJS):$(LIBS:.cma=.cmxa)
172
173 $(EXEC): $(LIBS) $(OBJS)
174 $(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS) $^
175
176 $(EXEC).opt: $(LIBS:.cma=.cmxa) $(OPTOBJS)
177 $(OCAMLOPT) $(STATIC) -o $@ $(SYSLIBS:.cma=.cmxa) $(OPTLIBFLAGS) $^
178
179 $(EXEC).top: $(LIBS) $(OBJS)
180 $(OCAMLMKTOP) -custom -o $@ $(SYSLIBS) $^
181
182 clean::
183 rm -f $(TARGET) $(TARGET).opt $(TARGET).top
184
185 clean::
186 rm -f dllpycaml_stubs.so
187
188
189 .PHONY:: tools configure
190
191 configure:
192 ./configure
193
194 tools:
195 $(MAKE) -C tools
196
197 clean::
198 $(MAKE) -C tools clean
199
200 static:
201 rm -f spatch.opt spatch
202 $(MAKE) STATIC="-ccopt -static" spatch.opt
203 cp spatch.opt spatch
204
205 purebytecode:
206 rm -f spatch.opt spatch
207 $(MAKE) BYTECODE_STATIC="" spatch
208
209
210 ##############################################################################
211 # Build documentation
212 ##############################################################################
213 .PHONY:: docs
214
215 docs:
216 make -C docs
217
218 clean::
219 make -C docs clean
220
221 distclean::
222 make -C docs distclean
223
224 ##############################################################################
225 # Pre-Install (customization of spatch frontend script)
226 ##############################################################################
227 .PHONY:: preinstall preinstall-def preinstall-byte preinstall-opt
228
229 preinstall: preinstall-def preinstall-byte preinstall-opt
230
231 # user will use spatch to run spatch.opt (native)
232 preinstall-def:
233 cp scripts/spatch.sh scripts/spatch.tmp2
234 sed "s|SHAREDIR|$(SHAREDIR)|g" scripts/spatch.tmp2 > scripts/spatch.tmp
235 sed "s|LIBDIR|$(LIBDIR)|g" scripts/spatch.tmp > scripts/spatch
236 rm -f scripts/spatch.tmp2 scripts/spatch.tmp
237
238 # user will use spatch to run spatch (bytecode)
239 preinstall-byte:
240 cp scripts/spatch.sh scripts/spatch.tmp3
241 sed "s|\.opt||" scripts/spatch.tmp3 > scripts/spatch.tmp2
242 sed "s|SHAREDIR|$(SHAREDIR)|g" scripts/spatch.tmp2 > scripts/spatch.tmp
243 sed "s|LIBDIR|$(LIBDIR)|g" scripts/spatch.tmp > scripts/spatch.byte
244 rm -f scripts/spatch.tmp3 scripts/spatch.tmp2 scripts/spatch.tmp
245
246 # user will use spatch.opt to run spatch.opt (native)
247 preinstall-opt:
248 cp scripts/spatch.sh scripts/spatch.opt.tmp2
249 sed "s|SHAREDIR|$(SHAREDIR)|g" scripts/spatch.opt.tmp2 > scripts/spatch.opt.tmp
250 sed "s|LIBDIR|$(LIBDIR)|g" scripts/spatch.opt.tmp > scripts/spatch.opt
251 rm -f scripts/spatch.opt.tmp scripts/spatch.opt.tmp2
252
253 clean::
254 rm -f scripts/spatch scripts/spatch.byte scripts/spatch.opt
255
256 ##############################################################################
257 # Install
258 ##############################################################################
259
260 # don't remove DESTDIR, it can be set by package build system like ebuild
261 # for staged installation.
262 install-common:
263 mkdir -p $(DESTDIR)$(BINDIR)
264 mkdir -p $(DESTDIR)$(LIBDIR)
265 mkdir -p $(DESTDIR)$(SHAREDIR)
266 mkdir -p $(DESTDIR)$(MANDIR)/man1
267 $(INSTALL_DATA) standard.h $(DESTDIR)$(SHAREDIR)
268 $(INSTALL_DATA) standard.iso $(DESTDIR)$(SHAREDIR)
269 $(INSTALL_DATA) docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/
270 @if [ $(FEATURE_PYTHON) -eq 1 ]; then $(MAKE) install-python; fi
271 @echo ""
272 @echo "You can also install spatch by copying the program spatch"
273 @echo "(available in this directory) anywhere you want and"
274 @echo "give it the right options to find its configuration files."
275 @echo ""
276
277 install-python:
278 mkdir -p $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
279 $(INSTALL_DATA) python/coccilib/*.py \
280 $(DESTDIR)$(SHAREDIR)/python/coccilib
281 $(INSTALL_DATA) python/coccilib/coccigui/*.py \
282 $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
283 $(INSTALL_DATA) python/coccilib/coccigui/pygui.glade \
284 $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
285 $(INSTALL_DATA) python/coccilib/coccigui/pygui.gladep \
286 $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
287 $(INSTALL_LIB) dllpycaml_stubs.so $(DESTDIR)$(LIBDIR)
288
289 install:
290 @if test -x spatch -a ! -x spatch.opt ; then \
291 $(MAKE) install-byte;fi
292 @if test ! -x spatch -a -x spatch.opt ; then \
293 $(MAKE) install-def; $(MAKE) install-opt;fi
294 @if test -x spatch -a -x spatch.opt ; then \
295 $(MAKE) install-byte; $(MAKE) install-opt;fi
296 @if test ! -x spatch -a ! -x spatch.opt ; then \
297 echo "\n\n\t==> Run 'make', 'make opt', or both first. <==\n\n";fi
298
299 # user will use spatch to run spatch.opt (native)
300 install-def: install-common
301 $(INSTALL_PROGRAM) spatch.opt $(DESTDIR)$(SHAREDIR)
302 $(INSTALL_PROGRAM) scripts/spatch $(DESTDIR)$(BINDIR)/spatch
303
304 # user will use spatch to run spatch (bytecode)
305 install-byte: install-common
306 $(INSTALL_PROGRAM) spatch $(DESTDIR)$(SHAREDIR)
307 $(INSTALL_PROGRAM) scripts/spatch.byte $(DESTDIR)$(BINDIR)/spatch
308
309 # user will use spatch.opt to run spatch.opt (native)
310 install-opt: install-common
311 $(INSTALL_PROGRAM) spatch.opt $(DESTDIR)$(SHAREDIR)
312 $(INSTALL_PROGRAM) scripts/spatch.opt $(DESTDIR)$(BINDIR)/spatch.opt
313
314 uninstall:
315 rm -f $(DESTDIR)$(BINDIR)/spatch
316 rm -f $(DESTDIR)$(BINDIR)/spatch.opt
317 rm -f $(DESTDIR)$(LIBDIR)/dllpycaml_stubs.so
318 rm -f $(DESTDIR)$(SHAREDIR)/standard.h
319 rm -f $(DESTDIR)$(SHAREDIR)/standard.iso
320 rm -rf $(DESTDIR)$(SHAREDIR)/python/coccilib
321 rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1
322
323 version:
324 @echo $(VERSION)
325
326
327 ##############################################################################
328 # Package rules
329 ##############################################################################
330
331 PACKAGE=coccinelle-$(VERSION)
332
333 BINSRC=spatch env.sh env.csh standard.h standard.iso \
334 *.txt \
335 docs/options.pdf docs/grammar/cocci_syntax.pdf docs/spatch.1 \
336 docs/cocci-python.txt \
337 demos/foo.* demos/simple.*
338 # $(PYLIB) python/coccilib/ demos/printloc.*
339 BINSRC2=$(BINSRC:%=$(PACKAGE)/%)
340
341 TMP=/tmp
342 OCAMLVERSION=$(shell ocaml -version |perl -p -e 's/.*version (.*)/$$1/;')
343
344 # Procedure to do first time:
345 # cd ~/release
346 # cvs checkout coccinelle
347 # cd coccinelle
348 # cvs update -d -P
349 # touch **/*
350 # make licensify
351 # remember to comment the -g -dtypes in this Makefile
352 # You can also remove a few things, for instance I removed in this
353 # Makefile things related to popl/ and popl09/
354
355 # Procedure to do each time:
356 # cvs update
357 # make sure that ocaml is the distribution ocaml of /usr/bin, not ~pad/...
358 # modify globals/config.ml
359 # cd globals/; cvs commit -m"new version" (do not commit from the root!)
360 # ./configure --without-python
361 # make package
362 # make website
363 # Check that run an ocaml in /usr/bin
364
365 # To test you can try compile and run spatch from different instances
366 # like my ~/coccinelle, ~/release/coccinelle, and the /tmp/coccinelle-0.X
367 # downloaded from the website.
368
369 # For 'make srctar' it must done from a clean
370 # repo such as ~/release/coccinelle. It must also be a repo where
371 # the scripts/licensify has been run at least once.
372 # For the 'make bintar' I can do it from my original repo.
373
374
375 package:
376 make srctar
377 ./configure --without-python
378 make docs
379 make bintar
380 make staticbintar
381 make bytecodetar
382
383 # I currently pre-generate the parser so the user does not have to
384 # install menhir on his machine. We could also do a few cleanups.
385 # You may have first to do a 'make licensify'.
386 #
387 # update: make docs generates pdf but also some ugly .log files, so
388 # make clean is there to remove them while not removing the pdf
389 # (only distclean remove the pdfs).
390 srctar:
391 make distclean
392 make docs
393 make clean
394 cp -a . $(TMP)/$(PACKAGE)
395 cd $(TMP)/$(PACKAGE); cd parsing_cocci/; make parser_cocci_menhir.ml
396 cd $(TMP); tar cvfz $(PACKAGE).tgz --exclude-vcs $(PACKAGE)
397 rm -rf $(TMP)/$(PACKAGE)
398
399
400 bintar: all
401 rm -f $(TMP)/$(PACKAGE)
402 ln -s `pwd` $(TMP)/$(PACKAGE)
403 cd $(TMP); tar cvfz $(PACKAGE)-bin-x86.tgz --exclude-vcs $(BINSRC2)
404 rm -f $(TMP)/$(PACKAGE)
405
406 staticbintar: all.opt
407 rm -f $(TMP)/$(PACKAGE)
408 ln -s `pwd` $(TMP)/$(PACKAGE)
409 make static
410 cd $(TMP); tar cvfz $(PACKAGE)-bin-x86-static.tgz --exclude-vcs $(BINSRC2)
411 rm -f $(TMP)/$(PACKAGE)
412
413 # add ocaml version in name ?
414 bytecodetar: all
415 rm -f $(TMP)/$(PACKAGE)
416 ln -s `pwd` $(TMP)/$(PACKAGE)
417 make purebytecode
418 cd $(TMP); tar cvfz $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz --exclude-vcs $(BINSRC2)
419 rm -f $(TMP)/$(PACKAGE)
420
421 clean::
422 rm -f $(PACKAGE)
423 rm -f $(PACKAGE)-bin-x86.tgz
424 rm -f $(PACKAGE)-bin-x86-static.tgz
425 rm -f $(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz
426
427
428
429 TOLICENSIFY=ctl engine parsing_cocci python
430 licensify:
431 ocaml tools/licensify.ml
432 set -e; for i in $(TOLICENSIFY); do cd $$i; ocaml ../tools/licensify.ml; cd ..; done
433
434 # When checking out the source from diku sometimes I have some "X in the future"
435 # error messages.
436 fixdates:
437 echo do 'touch **/*.*'
438
439 #fixCVS:
440 # cvs update -d -P
441 # echo do 'rm -rf **/CVS'
442
443 ocamlversion:
444 @echo $(OCAMLVERSION)
445
446
447 ##############################################################################
448 # Pad specific rules
449 ##############################################################################
450
451 #TOP=/home/pad/mobile/project-coccinelle
452 WEBSITE=/home/pad/mobile/homepage/software/project-coccinelle
453
454 website:
455 cp $(TMP)/$(PACKAGE).tgz $(WEBSITE)
456 cp $(TMP)/$(PACKAGE)-bin-x86.tgz $(WEBSITE)
457 cp $(TMP)/$(PACKAGE)-bin-x86-static.tgz $(WEBSITE)
458 cp $(TMP)/$(PACKAGE)-bin-bytecode-$(OCAMLVERSION).tgz $(WEBSITE)
459 rm -f $(WEBSITE)/LATEST* $(WEBSITE)/coccinelle-latest.tgz
460 cp changes.txt $(WEBSITE)/changes-$(VERSION).txt
461 cd $(WEBSITE); touch LATEST_IS_$(VERSION); ln -s $(PACKAGE).tgz coccinelle-latest.tgz
462
463
464 #TXT=$(wildcard *.txt)
465 syncwiki:
466 # unison ~/public_html/wiki/wiki-LFS/data/pages/ docs/wiki/
467 # set -e; for i in $(TXT); do unison $$i docs/wiki/$$i; done
468
469 darcsweb:
470 # @echo pull from ~/public_html/darcs/c-coccinelle and c-commons and lib-xxx
471
472 DARCSFORESTS=commons \
473 parsing_c parsing_cocci engine
474
475 update_darcs:
476 darcs pull
477 set -e; for i in $(DARCSFORESTS); do cd $$i; darcs pull; cd ..; done
478
479 #darcs diff -u
480 diff_darcs:
481 set -e; for i in $(DARCSFORESTS); do cd $$i; darcs diff -u; cd ..; done
482
483 ##############################################################################
484 # Git Developer rules
485 ##############################################################################
486 gitupdate:
487 git cvsimport -d :ext:topps:/var/cvs/cocci coccinelle
488
489 ##############################################################################
490 # Developer rules
491 ##############################################################################
492
493 test: $(TARGET)
494 ./$(TARGET) -testall
495
496 testparsing:
497 ./$(TARGET) -D standard.h -parse_c -dir tests/
498
499
500
501 # -inline 0 to see all the functions in the profile.
502 # Can also use the profile framework in commons/ and run your program
503 # with -profile.
504 forprofiling:
505 $(MAKE) OPTFLAGS="-p -inline 0 " opt
506
507 clean::
508 rm -f gmon.out
509
510 tags:
511 otags -no-mli-tags -r .
512
513 dependencygraph:
514 find -name "*.ml" |grep -v "scripts" | xargs ocamldep -I commons -I globals -I ctl -I parsing_cocci -I parsing_c -I engine -I extra > /tmp/dependfull.depend
515 ocamldot -lr /tmp/dependfull.depend > /tmp/dependfull.dot
516 dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
517 ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
518
519 ##############################################################################
520 # Misc rules
521 ##############################################################################
522
523 # each member of the project can have its own test.ml. this file is
524 # not under CVS.
525 test.ml:
526 echo "let foo_ctl () = failwith \"there is no foo_ctl formula\"" \
527 > test.ml
528
529 beforedepend:: test.ml
530
531
532 #INC=$(dir $(shell which ocaml))
533 #INCX=$(INC:/=)
534 #INCY=$(dir $(INCX))
535 #INCZ=$(INCY:/=)/lib/ocaml
536 #
537 #prim.o: prim.c
538 # gcc -c -o prim.o -I $(INCZ) prim.c
539
540
541 ##############################################################################
542 # Generic ocaml rules
543 ##############################################################################
544
545 .SUFFIXES: .ml .mli .cmo .cmi .cmx
546
547 .ml.cmo:
548 $(OCAMLC) -c $<
549 .mli.cmi:
550 $(OCAMLC) -c $<
551 .ml.cmx:
552 $(OCAMLOPT) -c $<
553
554 .ml.mldepend:
555 $(OCAMLC) -i $<
556
557 clean::
558 rm -f *.cm[iox] *.o *.annot
559 rm -f *~ .*~ *.exe #*#
560
561 distclean:: clean
562 set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i $@; done
563 rm -f .depend
564 rm -f Makefile.config
565 rm -f python/coccilib/output.py
566 rm -f python/pycocci.ml
567 rm -f python/pycocci_aux.ml
568 rm -f globals/config.ml
569 rm -f TAGS
570 rm -f tests/SCORE_actual.sexp
571 rm -f tests/SCORE_best_of_both.sexp
572 find -name ".#*1.*" | xargs rm -f
573
574 beforedepend::
575
576 depend:: beforedepend
577 $(OCAMLDEP) *.mli *.ml > .depend
578 set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i $@; done
579
580 .depend::
581 @if [ ! -f .depend ] ; then $(MAKE) depend ; fi
582
583 -include .depend