799663b65b96a00ac0d7d0e169ceea459fc2c7b5
[bpt/coccinelle.git] / Makefile
1 # Copyright 2010, INRIA, University of Copenhagen
2 # Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
3 # Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
4 # Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
5 # This file is part of Coccinelle.
6 #
7 # Coccinelle is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, according to version 2 of the License.
10 #
11 # Coccinelle is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
18 #
19 # The authors reserve the right to distribute this or future versions of
20 # Coccinelle under other licenses.
21
22
23
24 #############################################################################
25 # Configuration section
26 #############################################################################
27
28 -include Makefile.config
29 -include /etc/lsb-release
30
31 VERSION=$(shell cat globals/config.ml.in |grep version |perl -p -e 's/.*"(.*)".*/$$1/;')
32 CCVERSION=$(shell cat scripts/coccicheck/README |grep "Coccicheck version" |perl -p -e 's/.*version (.*)[ ]*/$$1/;')
33 PKGVERSION=$(shell dpkg-parsechangelog -ldebian/changelog.$(DISTRIB_CODENAME) 2> /dev/null \
34 | sed -n 's/^Version: \(.*\)/\1/p' )
35
36 ##############################################################################
37 # Variables
38 ##############################################################################
39 TARGET=spatch
40 PRJNAME=coccinelle
41
42 LEXER_SOURCES =
43 SRC=flag_cocci.ml cocci.ml testing.ml test.ml $(LEXER_SOURCES:.mll=.ml) main.ml
44
45 ifeq ($(FEATURE_PYTHON),1)
46 PYCMA=pycaml.cma
47 # the following is essential for Coccinelle to compile under gentoo (weird)
48 #OPTLIBFLAGS=-cclib dllpycaml_stubs.so
49 else
50 PYCMA=
51 endif
52 OPTLIBFLAGS=
53
54 ifeq ("$(SEXPDIR)","ocamlsexp")
55 SEXPLIB=sexplib.cmo
56 OPTSEXPLIB=sexplib.cmx
57 else
58 SEXPLIB=sexplib.cma
59 OPTSEXPLIB=sexplib.cmxa
60 endif
61
62 ifeq ("$(DYNLINK)","no")
63 DYNLINK=
64 else
65 DYNLINK=dynlink.cma
66 endif
67
68 ifdef PCREDIR
69 PCRELIB=pcre.cma
70 else
71 PCRELIB=
72 PCREDIR=
73 endif
74
75 SEXPSYSCMA=bigarray.cma nums.cma
76
77 SYSLIBS=str.cma unix.cma $(SEXPSYSCMA) $(PYCMA) $(DYNLINK) $(PCRELIB) # threads.cma
78 LIBS=commons/commons.cma \
79 commons/commons_sexp.cma \
80 globals/globals.cma \
81 ctl/ctl.cma \
82 parsing_cocci/cocci_parser.cma parsing_c/parsing_c.cma \
83 engine/cocciengine.cma popl09/popl.cma \
84 extra/extra.cma python/coccipython.cma ocaml/cocciocaml.cma
85
86 # Should we use the local version of pycaml
87 ifeq ($(FEATURE_PYTHON),1)
88 ifeq ("$(PYCAMLDIR)","pycaml")
89 LOCALPYCAML=pycaml
90 else
91 LOCALPYCAML=
92 endif
93 endif
94
95 # Should we use the local version of menhirLib
96 ifeq ("$(MENHIRDIR)","menhirlib")
97 LOCALMENHIR=menhirlib
98 else
99 LOCALMENHIR=
100 endif
101
102 # Should we use the local version of ocamlsexp
103 ifeq ("$(SEXPDIR)","ocamlsexp")
104 LOCALSEXP=ocamlsexp
105 else
106 LOCALSEXP=
107 endif
108
109 # used for depend: and a little for rec & rec.opt
110 MAKESUBDIRS=$(LOCALPYCAML) $(LOCALSEXP) commons \
111 globals $(LOCALMENHIR) ctl parsing_cocci parsing_c \
112 engine popl09 extra python ocaml
113
114 # used for clean:
115 # It is like MAKESUBDIRS but also
116 # force cleaning of local library copies
117 CLEANSUBDIRS=pycaml ocamlsexp commons \
118 globals menhirlib ctl parsing_cocci parsing_c \
119 engine popl09 extra python ocaml
120
121 INCLUDEDIRSDEP=commons commons/ocamlextra $(LOCALSEXP) \
122 globals $(LOCALMENHIR) $(LOCALPYCAML) ctl \
123 parsing_cocci parsing_c engine popl09 extra python ocaml
124
125 INCLUDEDIRS=$(INCLUDEDIRSDEP) $(SEXPDIR) $(MENHIRDIR) $(PYCAMLDIR) $(PCREDIR)
126
127 ##############################################################################
128 # Generic variables
129 ##############################################################################
130
131 INCLUDES=$(INCLUDEDIRS:%=-I %)
132
133 OBJS= $(SRC:.ml=.cmo)
134 OPTOBJS= $(SRC:.ml=.cmx)
135
136 EXEC=$(TARGET)
137
138 ##############################################################################
139 # Generic ocaml variables
140 ##############################################################################
141
142 OCAMLCFLAGS=
143
144 # for profiling add -p -inline 0
145 # but 'make forprofiling' below does that for you.
146 # This flag is also used in subdirectories so don't change its name here.
147 # To enable backtrace support for native code, you need to put -g in OPTFLAGS
148 # to also link with -g.
149 OPTFLAGS= -g
150
151 OCAMLC=ocamlc$(OPTBIN) $(OCAMLCFLAGS) $(INCLUDES)
152 OCAMLOPT=ocamlopt$(OPTBIN) $(OPTFLAGS) $(INCLUDES)
153 OCAMLLEX=ocamllex #-ml # -ml for debugging lexer, but slightly slower
154 OCAMLYACC=ocamlyacc -v
155 OCAMLDEP=ocamldep $(INCLUDEDIRSDEP:%=-I %)
156 OCAMLMKTOP=ocamlmktop -g -custom $(INCLUDES)
157
158 # can also be set via 'make static'
159 CFLAGS=-pie -fPIE -fpic -fPIC -static
160 STATICCFLAGS=$(CFLAGS:%=-ccopt %)
161 STATIC= # $(STATICCFLAGS)
162
163 # can also be unset via 'make purebytecode'
164 BYTECODE_STATIC=-custom
165
166 ##############################################################################
167 # Top rules
168 ##############################################################################
169 .PHONY:: all all.opt byte opt top clean distclean configure
170 .PHONY:: $(MAKESUBDIRS) $(MAKESUBDIRS:%=%.opt) subdirs subdirs.opt
171
172 all: Makefile.config byte preinstall
173
174 opt: all.opt
175 all.opt: opt-compil preinstall
176
177 world: preinstall
178 $(MAKE) byte
179 $(MAKE) opt-compil
180
181 byte: .depend
182 $(MAKE) subdirs
183 $(MAKE) $(EXEC)
184
185 opt-compil: .depend
186 $(MAKE) subdirs.opt
187 $(MAKE) $(EXEC).opt
188
189 top: $(EXEC).top
190
191 subdirs:
192 +for D in $(MAKESUBDIRS); do $(MAKE) $$D || exit 1 ; done
193 $(MAKE) -C commons sexp OCAMLCFLAGS="$(OCAMLCFLAGS)"
194
195 subdirs.opt:
196 +for D in $(MAKESUBDIRS); do $(MAKE) $$D.opt || exit 1 ; done
197 $(MAKE) -C commons sexp.opt OPTFLAGS="$(OPTFLAGS)"
198
199 $(MAKESUBDIRS):
200 $(MAKE) -C $@ OCAMLCFLAGS="$(OCAMLCFLAGS)" all
201
202 $(MAKESUBDIRS:%=%.opt):
203 $(MAKE) -C $(@:%.opt=%) OPTFLAGS="$(OPTFLAGS)" all.opt
204
205 #dependencies:
206 # commons:
207 # globals:
208 # menhirlib:
209 # parsing_cocci: commons globals menhirlib
210 # parsing_c:parsing_cocci
211 # ctl:globals commons
212 # engine: parsing_cocci parsing_c ctl
213 # popl09:engine
214 # extra: parsing_cocci parsing_c ctl
215 # pycaml:
216 # python:pycaml parsing_cocci parsing_c
217
218 clean::
219 set -e; for i in $(CLEANSUBDIRS); do $(MAKE) -C $$i $@; done
220 $(MAKE) -C demos/spp $@
221
222 $(LIBS): $(MAKESUBDIRS)
223 $(LIBS:.cma=.cmxa): $(MAKESUBDIRS:%=%.opt)
224
225 $(OBJS):$(LIBS)
226 $(OPTOBJS):$(LIBS:.cma=.cmxa)
227
228 $(EXEC): $(LIBS) $(OBJS)
229 $(OCAMLC) $(BYTECODE_STATIC) -o $@ $(SYSLIBS) $(SEXPLIB) $^
230
231 $(EXEC).opt: $(LIBS:.cma=.cmxa) $(OPTOBJS)
232 $(OCAMLOPT) $(STATIC) -o $@ $(SYSLIBS:.cma=.cmxa) $(OPTSEXPLIB) $(OPTLIBFLAGS) $^
233
234 $(EXEC).top: $(LIBS) $(OBJS)
235 $(OCAMLMKTOP) -custom -o $@ $(SYSLIBS) $(SEXPLIB) $^
236
237 clean::
238 rm -f $(TARGET) $(TARGET).opt $(TARGET).top
239
240 .PHONY:: tools configure
241
242 configure:
243 ./configure
244
245 Makefile.config:
246 @echo "Makefile.config is missing. Have you run ./configure?"
247 @exit 1
248
249 tools: $(LIBS)
250 $(MAKE) -C tools
251
252 distclean::
253 if [ -d tools ] ; then $(MAKE) -C tools distclean ; fi
254
255 static:
256 rm -f spatch.opt spatch
257 $(MAKE) STATIC="$(STATICCFLAGS)" spatch.opt
258 cp spatch.opt spatch
259
260 purebytecode:
261 rm -f spatch.opt spatch
262 $(MAKE) BYTECODE_STATIC="" spatch
263 perl -p -i -e 's/^#!.*/#!\/usr\/bin\/ocamlrun/' spatch
264
265
266 ##############################################################################
267 # Build documentation
268 ##############################################################################
269 .PHONY:: docs
270
271 docs:
272 $(MAKE) -C docs
273 if [ -x "$(TARGET)" -o -x "$(TARGET).opt" ]; \
274 then $(MAKE) -C ocaml doc; fi
275
276 clean::
277 $(MAKE) -C docs clean
278 $(MAKE) -C ocaml cleandoc
279
280 distclean::
281 $(MAKE) -C docs distclean
282
283 ##############################################################################
284 # Pre-Install (customization of spatch frontend script)
285 ##############################################################################
286
287 preinstall: docs/spatch.1 scripts/spatch scripts/spatch.opt scripts/spatch.byte
288
289 docs/spatch.1: Makefile.config
290 $(MAKE) -C docs spatch.1
291
292 # user will use spatch to run spatch.opt (native)
293 scripts/spatch: Makefile.config
294 cp scripts/spatch.sh scripts/spatch.tmp2
295 sed "s|SHAREDIR|$(SHAREDIR)|g" scripts/spatch.tmp2 > scripts/spatch.tmp
296 sed "s|LIBDIR|$(LIBDIR)|g" scripts/spatch.tmp > scripts/spatch
297 rm -f scripts/spatch.tmp2 scripts/spatch.tmp
298
299 # user will use spatch to run spatch (bytecode)
300 scripts/spatch.byte: Makefile.config
301 cp scripts/spatch.sh scripts/spatch.byte.tmp3
302 sed "s|\.opt||" scripts/spatch.byte.tmp3 > scripts/spatch.byte.tmp2
303 sed "s|SHAREDIR|$(SHAREDIR)|g" scripts/spatch.byte.tmp2 \
304 > scripts/spatch.byte.tmp
305 sed "s|LIBDIR|$(LIBDIR)|g" scripts/spatch.byte.tmp \
306 > scripts/spatch.byte
307 rm -f scripts/spatch.byte.tmp3 \
308 scripts/spatch.byte.tmp2 \
309 scripts/spatch.byte.tmp
310
311 # user will use spatch.opt to run spatch.opt (native)
312 scripts/spatch.opt: Makefile.config
313 cp scripts/spatch.sh scripts/spatch.opt.tmp2
314 sed "s|SHAREDIR|$(SHAREDIR)|g" scripts/spatch.opt.tmp2 \
315 > scripts/spatch.opt.tmp
316 sed "s|LIBDIR|$(LIBDIR)|g" scripts/spatch.opt.tmp \
317 > scripts/spatch.opt
318 rm -f scripts/spatch.opt.tmp scripts/spatch.opt.tmp2
319
320 clean::
321 rm -f scripts/spatch scripts/spatch.byte scripts/spatch.opt
322
323 ##############################################################################
324 # Install
325 ##############################################################################
326
327 # don't remove DESTDIR, it can be set by package build system like ebuild
328 # for staged installation.
329 install-common:
330 mkdir -p $(DESTDIR)$(BINDIR)
331 mkdir -p $(DESTDIR)$(LIBDIR)
332 mkdir -p $(DESTDIR)$(SHAREDIR)/ocaml
333 mkdir -p $(DESTDIR)$(SHAREDIR)/commons
334 mkdir -p $(DESTDIR)$(SHAREDIR)/globals
335 mkdir -p $(DESTDIR)$(SHAREDIR)/parsing_c
336 $(INSTALL_DATA) standard.h $(DESTDIR)$(SHAREDIR)
337 $(INSTALL_DATA) standard.iso $(DESTDIR)$(SHAREDIR)
338 $(INSTALL_DATA) ocaml/coccilib.cmi $(DESTDIR)$(SHAREDIR)/ocaml/
339 $(INSTALL_DATA) parsing_c/*.cmi $(DESTDIR)$(SHAREDIR)/parsing_c/
340 $(INSTALL_DATA) commons/*.cmi $(DESTDIR)$(SHAREDIR)/commons/
341 $(INSTALL_DATA) globals/iteration.cmi $(DESTDIR)$(SHAREDIR)/globals/
342 @if [ $(FEATURE_PYTHON) -eq 1 ]; then $(MAKE) install-python; fi
343
344 install-man:
345 mkdir -p $(DESTDIR)$(MANDIR)/man1
346 mkdir -p $(DESTDIR)$(MANDIR)/man3
347 $(INSTALL_DATA) docs/spatch.1 $(DESTDIR)$(MANDIR)/man1/
348 $(INSTALL_DATA) docs/Coccilib.3cocci $(DESTDIR)$(MANDIR)/man3/
349
350 install-bash:
351 mkdir -p $(DESTDIR)$(BASH_COMPLETION_DIR)
352 $(INSTALL_DATA) scripts/spatch.bash_completion \
353 $(DESTDIR)$(BASH_COMPLETION_DIR)/spatch
354
355 install-tools:
356 mkdir -p $(DESTDIR)$(BINDIR)
357 $(INSTALL_PROGRAM) tools/splitpatch \
358 $(DESTDIR)$(BINDIR)/splitpatch
359 $(INSTALL_PROGRAM) tools/cocci-send-email.perl \
360 $(DESTDIR)$(BINDIR)/cocci-send-email.perl
361
362 install-python:
363 mkdir -p $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
364 $(INSTALL_DATA) python/coccilib/*.py \
365 $(DESTDIR)$(SHAREDIR)/python/coccilib
366 $(INSTALL_DATA) python/coccilib/coccigui/*.py \
367 $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
368 $(INSTALL_DATA) python/coccilib/coccigui/pygui.glade \
369 $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
370 $(INSTALL_DATA) python/coccilib/coccigui/pygui.gladep \
371 $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
372 if [ -f pycaml/dllpycaml_stubs.so ]; then \
373 $(INSTALL_LIB) pycaml/dllpycaml_stubs.so $(DESTDIR)$(LIBDIR) ; fi
374
375 install: install-man install-common
376 @if test -x spatch -a ! -x spatch.opt ; then \
377 $(MAKE) install-byte;fi
378 @if test ! -x spatch -a -x spatch.opt ; then \
379 $(MAKE) install-def; $(MAKE) install-opt;fi
380 @if test -x spatch -a -x spatch.opt ; then \
381 $(MAKE) install-byte; $(MAKE) install-opt;fi
382 @if test ! -x spatch -a ! -x spatch.opt ; then \
383 echo "\n\n\t==> Run 'make', 'make opt', or both first. <==\n\n";fi
384 @echo ""
385 @echo "\tYou can also install spatch by copying the program spatch"
386 @echo "\t(available in this directory) anywhere you want and"
387 @echo "\tgive it the right options to find its configuration files."
388 @echo ""
389
390 # user will use spatch to run spatch.opt (native)
391 install-def:
392 $(INSTALL_PROGRAM) spatch.opt $(DESTDIR)$(SHAREDIR)
393 $(INSTALL_PROGRAM) scripts/spatch $(DESTDIR)$(BINDIR)/spatch
394
395 # user will use spatch to run spatch (bytecode)
396 install-byte:
397 $(INSTALL_PROGRAM) spatch $(DESTDIR)$(SHAREDIR)
398 $(INSTALL_PROGRAM) scripts/spatch.byte $(DESTDIR)$(BINDIR)/spatch
399
400 # user will use spatch.opt to run spatch.opt (native)
401 install-opt:
402 $(INSTALL_PROGRAM) spatch.opt $(DESTDIR)$(SHAREDIR)
403 $(INSTALL_PROGRAM) scripts/spatch.opt $(DESTDIR)$(BINDIR)/spatch.opt
404
405 uninstall:
406 rm -f $(DESTDIR)$(BINDIR)/spatch
407 rm -f $(DESTDIR)$(BINDIR)/spatch.opt
408 rm -f $(DESTDIR)$(LIBDIR)/dllpycaml_stubs.so
409 rm -f $(DESTDIR)$(SHAREDIR)/spatch
410 rm -f $(DESTDIR)$(SHAREDIR)/spatch.opt
411 rm -f $(DESTDIR)$(SHAREDIR)/standard.h
412 rm -f $(DESTDIR)$(SHAREDIR)/standard.iso
413 rm -f $(DESTDIR)$(SHAREDIR)/ocaml/coccilib.cmi
414 rm -f $(DESTDIR)$(SHAREDIR)/parsing_c/*.cmi
415 rm -f $(DESTDIR)$(SHAREDIR)/commons/*.cmi
416 rm -f $(DESTDIR)$(SHAREDIR)/globals/*.cmi
417 rm -f $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui/*
418 rm -f $(DESTDIR)$(SHAREDIR)/python/coccilib/*.py
419 rmdir --ignore-fail-on-non-empty -p \
420 $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
421 rmdir $(DESTDIR)$(SHAREDIR)/globals
422 rmdir $(DESTDIR)$(SHAREDIR)/commons
423 rmdir $(DESTDIR)$(SHAREDIR)/parsing_c
424 rmdir $(DESTDIR)$(SHAREDIR)/ocaml
425 rmdir $(DESTDIR)$(SHAREDIR)
426 rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1
427 rm -f $(DESTDIR)$(MANDIR)/man3/Coccilib.3cocci
428
429 uninstall-bash:
430 rm -f $(DESTDIR)$(BASH_COMPLETION_DIR)/spatch
431 rmdir --ignore-fail-on-non-empty -p \
432 $(DESTDIR)$(BASH_COMPLETION_DIR)
433
434 uninstall-tools:
435 rm -f $(DESTDIR)$(BINDIR)/splitpatch
436 rm -f $(DESTDIR)$(BINDIR)/cocci-send-email.perl
437
438 version:
439 @echo "spatch $(VERSION)"
440 @echo "spatch $(PKGVERSION) ($(DISTRIB_ID))"
441 @echo "coccicheck $(CCVERSION)"
442
443
444 ##############################################################################
445 # Deb package (for Ubuntu) and release rules
446 ##############################################################################
447
448 include Makefile.release
449
450 ##############################################################################
451 # Developer rules
452 ##############################################################################
453
454 -include Makefile.dev
455
456 test: $(TARGET)
457 ./$(TARGET) -testall
458
459 testparsing:
460 ./$(TARGET) -D standard.h -parse_c -dir tests/
461
462
463
464 # -inline 0 to see all the functions in the profile.
465 # Can also use the profile framework in commons/ and run your program
466 # with -profile.
467 forprofiling:
468 $(MAKE) OPTFLAGS="-p -inline 0 " opt
469
470 clean::
471 rm -f gmon.out
472
473 tags:
474 otags -no-mli-tags -r .
475
476 dependencygraph:
477 find -name "*.ml" |grep -v "scripts" | xargs ocamldep -I commons -I globals -I ctl -I parsing_cocci -I parsing_c -I engine -I popl09 -I extra > /tmp/dependfull.depend
478 ocamldot -lr /tmp/dependfull.depend > /tmp/dependfull.dot
479 dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
480 ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
481
482 ##############################################################################
483 # Misc rules
484 ##############################################################################
485
486 # each member of the project can have its own test.ml. this file is
487 # not under CVS.
488 test.ml:
489 echo "let foo_ctl () = failwith \"there is no foo_ctl formula\"" \
490 > test.ml
491
492 beforedepend:: test.ml
493
494
495 #INC=$(dir $(shell which ocaml))
496 #INCX=$(INC:/=)
497 #INCY=$(dir $(INCX))
498 #INCZ=$(INCY:/=)/lib/ocaml
499 #
500 #prim.o: prim.c
501 # gcc -c -o prim.o -I $(INCZ) prim.c
502
503
504 ##############################################################################
505 # Generic ocaml rules
506 ##############################################################################
507
508 .SUFFIXES: .ml .mli .cmo .cmi .cmx
509
510 .ml.cmo:
511 $(OCAMLC) -c $<
512 .mli.cmi:
513 $(OCAMLC) -c $<
514 .ml.cmx:
515 $(OCAMLOPT) -c $<
516
517 .ml.mldepend:
518 $(OCAMLC) -i $<
519
520 $(LEXER_SOURCES:.mll=.ml) : $(LEXER_SOURCES)
521 $(OCAMLLEX) $(LEXER_SOURCES)
522
523 clean::
524 rm -f *.cm[iox] *.o *.annot
525 rm -f *~ .*~ *.exe #*#
526
527 distclean:: clean
528 set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i $@; done
529 rm -f .depend
530 rm -f Makefile.config
531 rm -f globals/config.ml test.ml
532 rm -f TAGS
533 rm -f tests/SCORE_actual.sexp
534 rm -f tests/SCORE_best_of_both.sexp
535 find -name ".#*1.*" | xargs rm -f
536
537 beforedepend::
538
539 depend:: beforedepend
540 $(OCAMLDEP) *.mli *.ml > .depend
541 set -e; for i in $(MAKESUBDIRS); do $(MAKE) -C $$i $@; done
542
543 .depend::
544 @if [ ! -f .depend ] ; then $(MAKE) depend ; fi
545
546 -include .depend