1
# Copyright 2012, INRIA
2
# Julia Lawall, Gilles Muller
3
# Copyright 2010-2011, INRIA, University of Copenhagen
4
# Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
5
# Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
6
# Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
7
# This file is part of Coccinelle.
9
# Coccinelle is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, according to version 2 of the License.
13
# Coccinelle is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with Coccinelle. If not, see <http://www.gnu.org/licenses/>.
21
# The authors reserve the right to distribute this or future versions of
22
# Coccinelle under other licenses.
25
#############################################################################
26
# Configuration section
27
#############################################################################
31
# 'distclean' does not require configure to have run, and should also
32
# clean all the bundled directories. Hence, a special case.
33
ifeq ($(MAKECMDGOALS),distclean)
34
MAKELIBS:=$(dir $(wildcard ./bundles/*/Makefile))
36
ifneq ($(MAKECMDGOALS),configure)
37
-include Makefile.config
41
-include /etc/lsb-release
42
-include Makefile.override # local customizations, if any
43
-include /etc/Makefile.coccinelle # local customizations, if any
46
VERSION=$(shell cat ./version | tr -d '\n')
47
CCVERSION=$(shell cat scripts/coccicheck/README | egrep -o '[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+' | head -n1)
48
PKGVERSION=$(shell dpkg-parsechangelog -ldebian/changelog.$(DISTRIB_CODENAME) 2> /dev/null \
49
| sed -n 's/^Version: \(.*\)/\1/p' )
51
##############################################################################
53
##############################################################################
57
SRC=flag_cocci.ml cocci.ml testing.ml test.ml $(LEXER_SOURCES:.mll=.ml) main.ml
59
ifeq ($(FEATURE_PYTHON),1)
60
PYTHON_INSTALL_TARGET=install-python
62
PYTHON_INSTALL_TARGET=
65
SYSLIBS=str.cma unix.cma bigarray.cma nums.cma
66
LIBS=commons/commons.cma \
67
commons/commons_sexp.cma \
70
parsing_cocci/cocci_parser.cma parsing_c/parsing_c.cma \
71
engine/cocciengine.cma popl09/popl.cma \
72
extra/extra.cma python/coccipython.cma ocaml/cocciocaml.cma
74
MAKESUBDIRS=$(MAKELIBS) commons \
75
globals ctl parsing_cocci parsing_c \
76
engine popl09 extra python ocaml
78
CLEANSUBDIRS=commons \
79
globals ctl parsing_cocci parsing_c \
80
engine popl09 extra python ocaml docs \
83
INCLUDEDIRSDEP=commons commons/ocamlextra \
85
parsing_cocci parsing_c engine popl09 extra python ocaml \
88
INCLUDEDIRS=$(INCLUDEDIRSDEP) $(PCREDIR) $(INCLIBS)
90
##############################################################################
92
##############################################################################
94
# sort to remove duplicates
95
INCLUDESET=$(sort $(INCLUDEDIRS))
96
INCLUDES=$(INCLUDESET:%=-I %)
99
OPTOBJS= $(SRC:.ml=.cmx)
103
##############################################################################
104
# Generic ocaml variables
105
##############################################################################
109
# for profiling add -p -inline 0
110
# but 'make forprofiling' below does that for you.
111
# This flag is also used in subdirectories so don't change its name here.
112
# To enable backtrace support for native code, you need to put -g in OPTFLAGS
113
# to also link with -g.
116
OCAMLC_CMD=$(OCAMLC) $(OCAMLCFLAGS) $(INCLUDES)
117
OCAMLOPT_CMD=$(OCAMLOPT) $(OPTFLAGS) $(INCLUDES)
118
OCAMLYACC_CMD=$(OCAMLYACC) -v
119
OCAMLDEP_CMD=$(OCAMLDEP) $(INCLUDEDIRSDEP:%=-I %)
120
OCAMLMKTOP_CMD=$(OCAMLMKTOP) -g -custom $(INCLUDES)
122
# can also be set via 'make static'
123
CFLAGS=-pie -fPIE -fpic -fPIC -static
124
STATICCFLAGS=$(CFLAGS:%=-ccopt %)
125
STATIC= # $(STATICCFLAGS)
127
# can also be unset via 'make purebytecode'
128
BYTECODE_STATIC=-custom
130
##############################################################################
132
##############################################################################
133
.PHONY:: all all.opt byte opt top clean distclean configure opt-compil
134
.PHONY:: $(MAKESUBDIRS:%=%.all) $(MAKESUBDIRS:%=%.opt) subdirs.all subdirs.opt
135
.PHONY:: all-opt all-byte byte-only opt-only
138
# All make targets that are expected to be an entry point have a dependency on
139
# 'Makefile.config' to ensure that if Makefile.config is not present, an error
140
# message is printed first before any other actions are executed.
141
# In addition, the targets that actually build something have a dependency on
142
# '.depend' and 'version.ml'.
144
# dispatches to either 'all-without-opt' or 'all-with-opt'
145
all: Makefile.config .depend $(TARGET_ALL)
147
# make "all" comes in three flavours
148
world: Makefile.config .depend version.ml
149
@echo "building both versions of spatch"
155
@echo -e "\tcoccinelle can now be installed via 'make install'"
157
# note: the 'all-dev' target excludes the documentation
158
all-dev: Makefile.config .depend version.ml
159
@echo "building the unoptimized version of spatch"
163
@echo -e "\tcoccinelle can now be installed via 'make install'"
165
all-release: Makefile.config .depend version.ml
166
@echo building the optimized version of spatch
171
@echo -e "\tcoccinelle can now be installed via 'make install'"
173
all.opt: Makefile.config opt-only preinstall
175
# aliases for "byte" and "opt-compil"
176
opt opt-only: Makefile.config opt-compil
177
byte-only: Makefile.config byte
179
byte: Makefile.config .depend version.ml
182
@echo the compilation of $(EXEC) finished
183
@echo $(EXEC) can be installed or used
185
opt-compil: Makefile.config .depend version.ml
188
@echo the compilation of $(EXEC).opt finished
189
@echo $(EXEC).opt can be installed or used
194
+for D in $(MAKESUBDIRS); do $(MAKE) $$D.all || exit 1 ; done
195
$(MAKE) -C commons sexp.all OCAMLCFLAGS="$(OCAMLCFLAGS)"
198
+for D in $(MAKESUBDIRS); do $(MAKE) $$D.opt || exit 1 ; done
199
$(MAKE) -C commons sexp.opt OPTFLAGS="$(OPTFLAGS)"
201
$(MAKESUBDIRS:%=%.all):
202
$(MAKE) -C $(@:%.all=%) -j1 OCAMLCFLAGS="$(OCAMLCFLAGS)" all
204
$(MAKESUBDIRS:%=%.opt):
205
$(MAKE) -C $(@:%.opt=%) -j1 OPTFLAGS="$(OPTFLAGS)" all.opt
211
# parsing_cocci: commons globals menhirLib
212
# parsing_c:parsing_cocci
213
# ctl:globals commons
214
# engine: parsing_cocci parsing_c ctl
216
# extra: parsing_cocci parsing_c ctl
218
# python:pycaml parsing_cocci parsing_c
220
clean:: Makefile.config
221
set -e; for i in $(CLEANSUBDIRS); do $(MAKE) -C $$i -j1 $@; done
222
$(MAKE) -C demos/spp $@
224
$(LIBS): $(MAKESUBDIRS:%=%.all)
225
$(LIBS:.cma=.cmxa): $(MAKESUBDIRS:%=%.opt)
226
$(LNKLIBS) : $(MAKESUBDIRS:%=%.all)
227
$(LNKOPTLIBS) : $(MAKESUBDIRS:%=%.opt)
230
$(OPTOBJS):$(LIBS:.cma=.cmxa)
232
$(EXEC): $(LIBS) $(OBJS)
233
$(OCAMLC_CMD) $(BYTECODE_STATIC) $(FLAGSLIBS) -o $@ $(SYSLIBS) $(LNKLIBS) $^
235
$(EXEC).opt: $(LIBS:.cma=.cmxa) $(OPTOBJS)
236
$(OCAMLOPT_CMD) $(STATIC) $(FLAGSLIBS) -o $@ $(SYSLIBS:.cma=.cmxa) $(OPTLNKLIBS) $^
238
$(EXEC).top: $(LIBS) $(OBJS) $(LNKLIBS)
239
$(OCAMLMKTOP_CMD) -custom -o $@ $(SYSLIBS) $(FLAGSLIBS) $(LNKLIBS) $^
242
rm -f $(TARGET) $(TARGET).opt $(TARGET).top
244
.PHONY:: tools configure
250
@echo "Makefile.config is missing. Run ./configure to generate it."
253
tools: $(LIBS) $(LNKLIBS)
257
if [ -d tools ] ; then $(MAKE) -C tools distclean ; fi
260
rm -f spatch.opt spatch
261
$(MAKE) STATIC="$(STATICCFLAGS)" opt-only
265
rm -f spatch.opt spatch
266
$(MAKE) BYTECODE_STATIC="" byte-only
267
# disabled the following command because it does not match
268
# perl -p -i -e 's/^#!.*/#!\/usr\/bin\/ocamlrun/' spatch
270
##############################################################################
271
# Build version information
272
##############################################################################
275
@echo "version.ml is missing. Run ./configure to generate it."
278
##############################################################################
279
# Build documentation
280
##############################################################################
284
@$(MAKE) -C docs || (echo "warning: ignored the failed construction of the manual" 1>&2)
285
@if test "x$(FEATURE_OCAML)" = x1; then \
286
if test -f ./parsing_c/ast_c.cmo; then \
287
$(MAKE) -C ocaml doc; \
288
else echo "note: to obtain coccilib documenation, it is required to build 'spatch' first so that ./parsing_c/ast_c.cmo gets build."; \
290
@echo "finished building manuals"
292
clean:: Makefile.config
293
$(MAKE) -C docs clean
294
$(MAKE) -C ocaml cleandoc
296
##############################################################################
297
# Pre-Install (customization of spatch frontend script)
298
##############################################################################
300
preinstall: docs/spatch.1 scripts/spatch scripts/spatch.opt scripts/spatch.byte
302
docs/spatch.1: Makefile.config
303
$(MAKE) -C docs spatch.1
305
# user will use spatch to run spatch.opt (native)
306
scripts/spatch: Makefile.config scripts/spatch.sh
307
cp scripts/spatch.sh scripts/spatch
308
chmod +x scripts/spatch
310
# user will use spatch to run spatch (bytecode)
311
scripts/spatch.byte: Makefile.config scripts/spatch.sh
312
cp scripts/spatch.sh scripts/spatch.byte
313
chmod +x scripts/spatch.byte
315
# user will use spatch.opt to run spatch.opt (native)
316
scripts/spatch.opt: Makefile.config scripts/spatch.sh
317
cp scripts/spatch.sh scripts/spatch.opt
318
chmod +x scripts/spatch.opt
321
rm -f scripts/spatch scripts/spatch.byte scripts/spatch.opt
323
##############################################################################
325
##############################################################################
327
# don't remove DESTDIR, it can be set by package build system like ebuild
328
# for staged installation.
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/
344
@echo "Installing manuals in: ${DESTDIR}${MANDIR}"
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/
351
@echo "Installing bash completion in: ${DESTDIR}${BASH_COMPLETION_DIR}"
352
$(MKDIR_P) $(DESTDIR)$(BASH_COMPLETION_DIR)
353
$(INSTALL_DATA) scripts/spatch.bash_completion \
354
$(DESTDIR)$(BASH_COMPLETION_DIR)/spatch
357
@echo "Installing tools in: ${DESTDIR}${BINDIR}"
358
$(MKDIR_P) $(DESTDIR)$(BINDIR)
359
$(INSTALL_PROGRAM) tools/splitpatch \
360
$(DESTDIR)$(BINDIR)/splitpatch
361
$(INSTALL_PROGRAM) tools/cocci-send-email.perl \
362
$(DESTDIR)$(BINDIR)/cocci-send-email.perl
365
@echo "Installing python support in: ${DESTDIR}${SHAREDIR}/python"
366
$(MKDIR_P) $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
367
$(INSTALL_DATA) python/coccilib/*.py \
368
$(DESTDIR)$(SHAREDIR)/python/coccilib
369
$(INSTALL_DATA) python/coccilib/coccigui/*.py \
370
$(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
371
$(INSTALL_DATA) python/coccilib/coccigui/pygui.glade \
372
$(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
373
$(INSTALL_DATA) python/coccilib/coccigui/pygui.gladep \
374
$(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
376
install: install-man install-common $(PYTHON_TARGET)
377
@if test -x spatch -o -x spatch.opt; then \
378
$(MAKE) install-def;fi
379
@if test -x spatch ; then \
380
$(MAKE) install-byte; fi
381
@if test -x spatch.opt ; then \
382
$(MAKE) install-opt;fi
383
@if test ! -x spatch -a ! -x spatch.opt ; then \
384
echo -e "\n\n\t==> Run 'make', 'make opt', or both first. <==\n\n";fi
386
@echo -e "\tYou can also install spatch by copying the program spatch"
387
@echo -e "\t(available in this directory) anywhere you want and"
388
@echo -e "\tgive it the right options to find its configuration files."
392
# Installation of spatch and spatch.opt and their wrappers
395
# user will use spatch to run one of the binaries
397
$(INSTALL_PROGRAM) scripts/spatch $(DESTDIR)$(BINDIR)/spatch
399
# user will use spatch.byte to run spatch (bytecode)
401
$(INSTALL_PROGRAM) spatch $(DESTDIR)$(SHAREDIR)
402
$(INSTALL_PROGRAM) scripts/spatch.byte $(DESTDIR)$(BINDIR)/spatch.byte
404
# user will use spatch.opt to run spatch.opt (native)
406
$(INSTALL_PROGRAM) spatch.opt $(DESTDIR)$(SHAREDIR)
407
$(INSTALL_PROGRAM) scripts/spatch.opt $(DESTDIR)$(BINDIR)/spatch.opt
410
rm -f $(DESTDIR)$(BINDIR)/spatch
411
rm -f $(DESTDIR)$(BINDIR)/spatch.opt
412
rm -f $(DESTDIR)$(BINDIR)/spatch.byte
413
rm -f $(DESTDIR)$(LIBDIR)/dllpycaml_stubs.so
414
rm -f $(DESTDIR)$(SHAREDIR)/spatch
415
rm -f $(DESTDIR)$(SHAREDIR)/spatch.opt
416
rm -f $(DESTDIR)$(SHAREDIR)/standard.h
417
rm -f $(DESTDIR)$(SHAREDIR)/standard.iso
418
rm -f $(DESTDIR)$(SHAREDIR)/ocaml/coccilib.cmi
419
rm -f $(DESTDIR)$(SHAREDIR)/parsing_c/*.cmi
420
rm -f $(DESTDIR)$(SHAREDIR)/commons/*.cmi
421
rm -f $(DESTDIR)$(SHAREDIR)/globals/*.cmi
422
rm -f $(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui/*
423
rm -f $(DESTDIR)$(SHAREDIR)/python/coccilib/*.py
424
rmdir --ignore-fail-on-non-empty -p \
425
$(DESTDIR)$(SHAREDIR)/python/coccilib/coccigui
426
rmdir $(DESTDIR)$(SHAREDIR)/globals
427
rmdir $(DESTDIR)$(SHAREDIR)/commons
428
rmdir $(DESTDIR)$(SHAREDIR)/parsing_c
429
rmdir $(DESTDIR)$(SHAREDIR)/ocaml
430
rmdir $(DESTDIR)$(SHAREDIR)
431
rm -f $(DESTDIR)$(MANDIR)/man1/spatch.1
432
rm -f $(DESTDIR)$(MANDIR)/man3/Coccilib.3cocci
435
rm -f $(DESTDIR)$(BASH_COMPLETION_DIR)/spatch
436
rmdir --ignore-fail-on-non-empty -p \
437
$(DESTDIR)$(BASH_COMPLETION_DIR)
440
rm -f $(DESTDIR)$(BINDIR)/splitpatch
441
rm -f $(DESTDIR)$(BINDIR)/cocci-send-email.perl
444
@echo "spatch $(VERSION)"
445
@echo "spatch $(PKGVERSION) ($(DISTRIB_ID))"
446
@echo "coccicheck $(CCVERSION)"
449
##############################################################################
450
# Deb package (for Ubuntu) and release rules
451
##############################################################################
453
include Makefile.release
455
##############################################################################
457
##############################################################################
459
-include Makefile.dev
465
./$(TARGET) -D standard.h -parse_c -dir tests/
468
./$(TARGET) --testall --no-update-score-file \
469
--iso-file ./standard.iso \
470
--macro-file-builtins ./standard.h
473
# -inline 0 to see all the functions in the profile.
474
# Can also use the profile framework in commons/ and run your program
477
$(MAKE) OPTFLAGS="-p -inline 0 " opt
483
otags -no-mli-tags -r .
486
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
487
ocamldot -lr /tmp/dependfull.depend > /tmp/dependfull.dot
488
dot -Tps /tmp/dependfull.dot > /tmp/dependfull.ps
489
ps2pdf /tmp/dependfull.ps /tmp/dependfull.pdf
491
##############################################################################
493
##############################################################################
495
# each member of the project can have its own test.ml. this file is
498
echo "let foo_ctl () = failwith \"there is no foo_ctl formula\"" \
501
##############################################################################
502
# Generic ocaml rules
503
##############################################################################
505
.SUFFIXES: .ml .mli .cmo .cmi .cmx
512
$(OCAMLOPT_CMD) -c $<
519
rm -f *.cm[iox] *.o *.annot
520
rm -f *~ .*~ *.exe #*#
523
set -e; for i in $(CLEANSUBDIRS); do $(MAKE) -C $$i -j1 $@; done
526
rm -f tests/SCORE_actual.sexp
527
rm -f tests/SCORE_best_of_both.sexp
528
find . -name ".#*1.*" | xargs rm -f
529
rm -f $(EXEC) $(EXEC).opt $(EXEC).top
532
.depend: Makefile.config test.ml version
533
touch .depend # prevents infinite recursion with 'make depend'
536
depend: Makefile.config test.ml version
537
@echo constructing '.depend'
539
set -e; for i in $(MAKESUBDIRS); do $(MAKE) -j1 -C $$i depend; done
540
$(OCAMLDEP_CMD) *.mli *.ml > .depend
542
##############################################################################
544
##############################################################################
547
@echo "cleaning configured files"
548
if test -z "${KEEP_CONFIG}"; then rm -f Makefile.config; fi
549
rm -rf autom4te.cache
553
rm -f globals/config.ml
554
rm -f globals/regexp.ml python/pycocci.ml ocaml/prepare_ocamlcocci.ml
555
rm -f scripts/spatch.sh
556
@echo "run 'configure' again prior to building coccinelle"
559
# prevent building or using dependencies when cleaning
560
ifneq ($(MAKECMDGOALS),clean)
561
ifneq ($(MAKECMDGOALS),distclean)
562
ifneq ($(MAKECMDGOALS),configure)
563
ifneq ($(MAKECMDGOALS),prerelease)
564
ifneq ($(MAKECMDGOALS),release)
565
ifneq ($(MAKECMDGOALS),package)