aboutsummaryrefslogtreecommitdiff
path: root/Makefile.build
diff options
context:
space:
mode:
Diffstat (limited to 'Makefile.build')
-rw-r--r--Makefile.build845
1 files changed, 845 insertions, 0 deletions
diff --git a/Makefile.build b/Makefile.build
new file mode 100644
index 0000000000..34d7ce42f7
--- /dev/null
+++ b/Makefile.build
@@ -0,0 +1,845 @@
+##########################################################################
+## # The Coq Proof Assistant / The Coq Development Team ##
+## v # INRIA, CNRS and contributors - Copyright 1999-2018 ##
+## <O___,, # (see CREDITS file for the list of authors) ##
+## \VV/ ###############################################################
+## // # This file is distributed under the terms of the ##
+## # GNU Lesser General Public License Version 2.1 ##
+## # (see LICENSE file for the text of the license) ##
+##########################################################################
+
+# This makefile is normally called by the main Makefile after setting
+# some variables.
+
+###########################################################################
+# User-customizable variables
+###########################################################################
+
+# The following variables could be modified via the command-line of make,
+# either with the syntax 'make XYZ=1' or 'XYZ=1 make'
+
+# To see the actual commands launched by make instead of shortened versions,
+# set this variable to 1 (or any non-empty value):
+VERBOSE ?=
+
+# When non-empty, a time command is performed at each .v compilation.
+# To collect compilation timings of .v and import them in a spreadsheet,
+# you could hence consider: make TIMED=1 2> timings.csv
+TIMED ?=
+
+# When $(TIMED) is set, the time command used by default is $(STDTIME)
+# (see below), unless the following variable is non-empty. For instance,
+# it could be set to "'/usr/bin/env time -p'".
+TIMECMD ?=
+
+# When non-empty, -time is passed to coqc and the output is recorded
+# in a timing file for each .v file. If set to "before" or "after",
+# the file name for foo.v is foo.v.$(TIMING)-timing; otherwise, it is
+# foo.v.timing
+TIMING ?=
+
+# Non-empty skips the update of all dependency .d files:
+NO_RECALC_DEPS ?=
+
+# Non-empty runs the checker on all produced .vo files:
+VALIDATE ?=
+
+# When non-empty, passed as extra arguments to coqtop/coqc:
+COQUSERFLAGS ?=
+
+# Output file names for timed builds
+TIME_OF_BUILD_FILE ?= time-of-build.log
+TIME_OF_BUILD_BEFORE_FILE ?= time-of-build-before.log
+TIME_OF_BUILD_AFTER_FILE ?= time-of-build-after.log
+TIME_OF_PRETTY_BUILD_FILE ?= time-of-build-pretty.log
+TIME_OF_PRETTY_BOTH_BUILD_FILE ?= time-of-build-both.log
+TIME_OF_PRETTY_BUILD_EXTRA_FILES ?= - # also output to the command line
+BEFORE ?=
+AFTER ?=
+
+###########################################################################
+# Default starting rule
+###########################################################################
+
+# build the different subsystems:
+
+world: coq coqide documentation revision
+
+coq: coqlib coqbinaries tools
+
+world.timing.diff: coq.timing.diff
+coq.timing.diff: coqlib.timing.diff
+
+# Note: 'world' does not build the bytecode binaries anymore.
+# For that, you can use the 'byte' rule. Native and byte compilations
+# shouldn't be done in a same make -j... run, otherwise both ocamlc and
+# ocamlopt might race for access to the same .cmi files.
+
+byte: coqbyte coqide-byte pluginsbyte printers
+
+.PHONY: world coq byte world.timing.diff coq.timing.diff
+
+###########################################################################
+# Includes
+###########################################################################
+
+# This list of ml files used to be in the main Makefile, we moved it here
+# to avoid exhausting the variable env in Win32
+MLFILES := $(MLSTATICFILES) $(GENMLFILES)
+
+include Makefile.common
+include Makefile.vofiles
+include Makefile.doc ## provides the 'documentation' rule
+include Makefile.checker
+include Makefile.ide ## provides the 'coqide' rule
+include Makefile.install
+include Makefile.dev ## provides the 'printers' and 'revision' rules
+
+###########################################################################
+# Timing targets
+###########################################################################
+make-pretty-timed-before:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_BEFORE_FILE)
+make-pretty-timed-after:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_AFTER_FILE)
+make-pretty-timed make-pretty-timed-before make-pretty-timed-after::
+ $(HIDE)rm -f pretty-timed-success.ok
+ $(HIDE)($(MAKE) --no-print-directory $(TGTS) TIMED=1 2>&1 && touch pretty-timed-success.ok) | tee -a $(TIME_OF_BUILD_FILE)
+ $(HIDE)rm pretty-timed-success.ok # must not be -f; must fail if the touch failed
+print-pretty-timed::
+ $(HIDE)$(COQMAKE_ONE_TIME_FILE) $(TIME_OF_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES)
+print-pretty-timed-diff::
+ $(HIDE)$(COQMAKE_BOTH_TIME_FILES) $(TIME_OF_BUILD_BEFORE_FILE) $(TIME_OF_BUILD_AFTER_FILE) $(TIME_OF_PRETTY_BOTH_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES)
+ifeq (,$(BEFORE))
+print-pretty-single-time-diff::
+ @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff BEFORE=path/to/file.v.before-timing AFTER=path/to/file.v.after-timing'
+ $(HIDE)false
+else
+ifeq (,$(AFTER))
+print-pretty-single-time-diff::
+ @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff BEFORE=path/to/file.v.before-timing AFTER=path/to/file.v.after-timing'
+ $(HIDE)false
+else
+print-pretty-single-time-diff::
+ $(HIDE)$(COQMAKE_BOTH_SINGLE_TIMING_FILES) $(BEFORE) $(AFTER) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES)
+endif
+endif
+pretty-timed:
+ $(HIDE)$(MAKE) --no-print-directory make-pretty-timed
+ $(HIDE)$(MAKE) --no-print-directory print-pretty-timed
+.PHONY: pretty-timed make-pretty-timed make-pretty-timed-before make-pretty-timed-after print-pretty-timed print-pretty-timed-diff
+
+ifneq (,$(TIMING))
+TIMING_ARG=-time
+ifeq (after,$(TIMING))
+TIMING_EXT=after-timing
+else
+ifeq (before,$(TIMING))
+TIMING_EXT=before-timing
+else
+TIMING_EXT=timing
+endif
+endif
+else
+TIMING_ARG=
+endif
+
+###########################################################################
+
+# This include below will lauch the build of all .d.
+# The - at front is for disabling warnings about currently missing ones.
+# For creating the missing .d, make will recursively build things like
+# coqdep_boot (for the .v.d files) or coqpp (for .mlg -> .ml -> .ml.d).
+
+VDFILE := .vfiles
+MLDFILE := .mlfiles
+PLUGMLDFILE := plugins/.mlfiles
+MLLIBDFILE := .mllibfiles
+PLUGMLLIBDFILE := plugins/.mllibfiles
+
+DEPENDENCIES := \
+ $(addsuffix .d, $(MLDFILE) $(MLLIBDFILE) $(PLUGMLDFILE) $(PLUGMLLIBDFILE) $(CFILES) $(VDFILE))
+
+-include $(DEPENDENCIES)
+
+# All dependency includes must be declared secondary, otherwise make will
+# delete them if it decided to build them by dependency instead of because
+# of include, and they will then be automatically deleted, leading to an
+# infinite loop.
+
+.SECONDARY: $(DEPENDENCIES) $(GENFILES) $(MLGFILES:.mlg=.ml)
+
+###########################################################################
+# Compilation options
+###########################################################################
+
+# Default timing command
+# Use /usr/bin/env time on linux, gtime on Mac OS
+TIMEFMT?="$* (real: %e, user: %U, sys: %S, mem: %M ko)"
+ifneq (,$(TIMED))
+ifeq (0,$(shell /usr/bin/env time -f $(TIMEFMT) true >/dev/null 2>/dev/null; echo $$?))
+STDTIME?=/usr/bin/env time -f $(TIMEFMT)
+else
+ifeq (0,$(shell gtime -f $(TIMEFMT) true >/dev/null 2>/dev/null; echo $$?))
+STDTIME?=gtime -f $(TIMEFMT)
+else
+STDTIME?=time
+endif
+endif
+else
+STDTIME?=/usr/bin/env time -f $(TIMEFMT)
+endif
+
+TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD))
+
+# NB: do not use a variable named TIME, since this variable controls
+# the output format of the unix command time. For instance:
+# TIME="%C (%U user, %S sys, %e total, %M maxres)"
+
+COQOPTS=$(NATIVECOMPUTE) $(COQWARNERROR) $(COQUSERFLAGS)
+BOOTCOQC=$(TIMER) $(COQTOPBEST) -boot $(COQOPTS) -compile
+
+LOCALINCLUDES=$(addprefix -I ,$(SRCDIRS))
+MLINCLUDES=$(LOCALINCLUDES)
+
+OCAMLC := $(OCAMLFIND) ocamlc $(CAMLFLAGS)
+OCAMLOPT := $(OCAMLFIND) opt $(CAMLFLAGS)
+
+BYTEFLAGS=$(CAMLDEBUG) $(USERFLAGS)
+OPTFLAGS=$(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS) $(FLAMBDA_FLAGS)
+DEPFLAGS=$(LOCALINCLUDES) -map gramlib/.pack/gramlib.ml $(if $(filter plugins/%,$@),, -I ide -I ide/protocol)
+
+# On MacOS, the binaries are signed, except our private ones
+ifeq ($(shell which codesign > /dev/null 2>&1 && echo $(ARCH)),Darwin)
+LINKMETADATA=$(if $(filter $(PRIVATEBINARIES),$@),,-ccopt "-sectcreate __TEXT __info_plist config/Info-$(notdir $@).plist")
+CODESIGN=$(if $(filter $(PRIVATEBINARIES),$@),true,codesign -s -)
+CODESIGN_HIDE=$(CODESIGN)
+else
+LINKMETADATA=
+CODESIGN=true
+CODESIGN_HIDE=$(HIDE)true
+endif
+
+ifeq ($(STRIP),true)
+STRIP_HIDE=$(HIDE)true
+else
+STRIP_HIDE=$(STRIP)
+endif
+
+# Best OCaml compiler, used in a generic way
+
+ifeq ($(BEST),opt)
+OPT:=opt
+BESTOBJ:=.cmx
+BESTLIB:=.cmxa
+BESTDYN:=.cmxs
+else
+OPT:=
+BESTOBJ:=.cmo
+BESTLIB:=.cma
+BESTDYN:=.cma
+endif
+
+define bestobj
+$(patsubst %.cma,%$(BESTLIB),$(patsubst %.cmo,%$(BESTOBJ),$(1)))
+endef
+
+define bestocaml
+$(if $(OPT),\
+$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) $(LINKMETADATA) -o $@ -linkpkg $(1) $^ && $(STRIP) $@ && $(CODESIGN) $@,\
+$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ -linkpkg $(1) $^)
+endef
+
+define ocamlbyte
+$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ -linkpkg $(1) $^
+endef
+
+# Main packages linked by Coq.
+SYSMOD:=-package num,str,unix,dynlink,threads
+
+###########################################################################
+# Infrastructure for the rest of the Makefile
+###########################################################################
+
+# The SHOW and HIDE variables control whether make will echo complete commands
+# or only abbreviated versions.
+# Quiet mode is ON by default except if VERBOSE=1 option is given to make
+
+SHOW := $(if $(VERBOSE),@true "",@echo "")
+HIDE := $(if $(VERBOSE),,@)
+
+define order-only-template
+ ifeq "order-only" "$(1)"
+ ORDER_ONLY_SEP:=|
+ endif
+endef
+
+$(foreach f,$(.FEATURES),$(eval $(call order-only-template,$(f))))
+
+ifndef ORDER_ONLY_SEP
+$(error This Makefile needs GNU Make 3.81 or later (that is a version that supports the order-only dependency feature without major bugs.))
+endif
+
+VO_TOOLS_DEP := $(COQTOPBEST)
+ifdef VALIDATE
+ VO_TOOLS_DEP += $(CHICKEN)
+endif
+
+D_DEPEND_BEFORE_SRC := $(if $(NO_RECALC_DEPS),|,)
+D_DEPEND_AFTER_SRC := $(if $(NO_RECALC_DEPS),,|)
+
+## When a rule redirects stdout of a command to the target file : cmd > $@
+## then the target file will be created even if cmd has failed.
+## Hence relaunching make will go further, as make thinks the target has been
+## done ok. To avoid this, we use the following macro:
+
+TOTARGET = > "$@" || (RV=$$?; rm -f "$@"; exit $${RV})
+
+###########################################################################
+# Compilation of .c files
+###########################################################################
+
+CINCLUDES= -I $(CAMLHLIB)
+
+# NB: We used to do a ranlib after ocamlmklib, but it seems that
+# ocamlmklib is already doing it
+
+$(LIBCOQRUN): kernel/byterun/coq_jumptbl.h $(BYTERUN)
+ cd $(dir $(LIBCOQRUN)) && \
+ $(OCAMLFIND) ocamlmklib -oc $(COQRUN) $(notdir $(BYTERUN))
+
+kernel/byterun/coq_jumptbl.h : kernel/byterun/coq_instruct.h kernel/byterun/make_jumptbl.sh
+ kernel/byterun/make_jumptbl.sh $< $@
+
+kernel/copcodes.ml: kernel/byterun/coq_instruct.h kernel/make_opcodes.sh kernel/make-opcodes
+ kernel/make_opcodes.sh $< $@
+
+%.o: %.c
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)cd $(dir $<) && $(OCAMLC) -ccopt "$(CFLAGS)" -c $(notdir $<)
+
+%_stubs.c.d: $(D_DEPEND_BEFORE_SRC) %_stubs.c $(D_DEPEND_AFTER_SRC)
+ $(SHOW)'CCDEP $<'
+ $(HIDE)echo "$@ $(@:.c.d=.o): $(@:.c.d=.c)" > $@
+
+%.c.d: $(D_DEPEND_BEFORE_SRC) %.c $(D_DEPEND_AFTER_SRC) $(GENHFILES)
+ $(SHOW)'CCDEP $<'
+ $(HIDE)$(OCAMLC) -ccopt "-MM -MQ $@ -MQ $(<:.c=.o) -isystem $(CAMLHLIB)" $< $(TOTARGET)
+
+COQPPCMO := $(addsuffix .cmo, $(addprefix coqpp/, coqpp_parse coqpp_lex))
+
+coqpp/coqpp_parse.cmi: coqpp/coqpp_ast.cmi
+coqpp/coqpp_parse.cmo: coqpp/coqpp_ast.cmi coqpp/coqpp_parse.cmi
+coqpp/coqpp_lex.cmo: coqpp/coqpp_ast.cmi coqpp/coqpp_parse.cmo
+
+$(COQPP): $(COQPPCMO) coqpp/coqpp_main.ml
+ $(SHOW)'OCAMLC -a $@'
+ $(HIDE)$(OCAMLC) -I coqpp $^ -linkall -o $@
+
+###########################################################################
+# Main targets (coqtop.opt, coqtop.byte)
+###########################################################################
+
+.PHONY: coqbinaries coqbyte
+
+coqbinaries: $(TOPBINOPT) $(COQTOPEXE) $(CHICKEN) $(CSDPCERT) $(FAKEIDE)
+coqbyte: $(TOPBYTE) $(CHICKENBYTE)
+
+# Special rule for coqtop, we imitate `ocamlopt` can delete the target
+# to avoid #7666
+$(COQTOPEXE): $(TOPBINOPT:.opt=.$(BEST))
+ rm -f $@ && cp $< $@
+
+bin/%.opt$(EXE): topbin/%_bin.ml $(LINKCMX) $(LIBCOQRUN)
+ $(SHOW)'COQMKTOP -o $@'
+ $(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) \
+ $(SYSMOD) \
+ $(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
+ $(STRIP_HIDE) $@
+ $(CODESIGN_HIDE) $@
+
+bin/%.byte$(EXE): topbin/%_bin.ml $(LINKCMO) $(LIBCOQRUN)
+ $(SHOW)'COQMKTOP -o $@'
+ $(HIDE)$(OCAMLC) -linkall -linkpkg $(MLINCLUDES) \
+ -I kernel/byterun/ -cclib -lcoqrun $(VMBYTEFLAGS) \
+ $(SYSMOD) \
+ $(LINKCMO) $(BYTEFLAGS) $< -o $@
+
+COQTOP_BYTE=topbin/coqtop_byte_bin.ml
+
+# Special rule for coqtop.byte
+# VMBYTEFLAGS will either contain -custom of the right -dllpath for the VM
+$(COQTOPBYTE): $(LINKCMO) $(LIBCOQRUN) $(COQTOP_BYTE)
+ $(SHOW)'COQMKTOP -o $@'
+ $(HIDE)$(OCAMLC) -linkall -linkpkg -I lib -I vernac -I toplevel \
+ -I kernel/byterun/ -cclib -lcoqrun $(VMBYTEFLAGS) \
+ $(SYSMOD) -package compiler-libs.toplevel \
+ $(LINKCMO) $(BYTEFLAGS) $(COQTOP_BYTE) -o $@
+
+# For coqc
+COQCCMO:=config/config.cma clib/clib.cma lib/lib.cma toplevel/usage.cmo tools/coqc.cmo
+
+$(COQC): $(call bestobj, $(COQCCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, $(SYSMOD))
+
+$(COQCBYTE): $(COQCCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, $(SYSMOD))
+
+###########################################################################
+# other tools
+###########################################################################
+
+.PHONY: tools
+tools: $(TOOLS) $(OCAMLLIBDEP) $(COQDEPBOOT)
+
+# coqdep_boot : a basic version of coqdep, with almost no dependencies.
+# We state these dependencies here explicitly, since some .ml.d files
+# may still be missing or not taken in account yet by make when coqdep_boot
+# is being built.
+
+# Remember to update the dependencies below when you add files!
+
+COQDEPBOOTSRC := \
+ clib/segmenttree.cmo clib/unicodetable.cmo clib/unicode.cmo clib/minisys.cmo \
+ tools/coqdep_lexer.cmo tools/coqdep_common.cmo tools/coqdep_boot.cmo
+
+clib/segmenttree.cmo : clib/segmenttree.cmi
+clib/segmenttree.cmx : clib/segmenttree.cmi
+clib/unicodetable.cmo : clib/segmenttree.cmo
+clib/unicodetable.cmx : clib/segmenttree.cmx
+clib/unicode.cmo : clib/unicodetable.cmo clib/unicode.cmi
+clib/unicode.cmx : clib/unicodetable.cmx clib/unicode.cmi
+clib/minisys.cmo : clib/unicode.cmo
+clib/minisys.cmx : clib/unicode.cmx
+tools/coqdep_lexer.cmo : clib/unicode.cmi tools/coqdep_lexer.cmi
+tools/coqdep_lexer.cmx : clib/unicode.cmx tools/coqdep_lexer.cmi
+tools/coqdep_common.cmo : clib/minisys.cmo tools/coqdep_lexer.cmi tools/coqdep_common.cmi
+tools/coqdep_common.cmx : clib/minisys.cmx tools/coqdep_lexer.cmx tools/coqdep_common.cmi
+tools/coqdep_boot.cmo : tools/coqdep_common.cmi
+tools/coqdep_boot.cmx : tools/coqdep_common.cmx
+
+$(COQDEPBOOT): $(call bestobj, $(COQDEPBOOTSRC))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -I tools -package unix)
+
+$(COQDEPBOOTBYTE): $(COQDEPBOOTSRC)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -I tools -package unix)
+
+$(OCAMLLIBDEP): $(call bestobj, tools/ocamllibdep.cmo)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -I tools -package unix)
+
+$(OCAMLLIBDEPBYTE): tools/ocamllibdep.cmo
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call ocamlbyte, -I tools -package unix)
+
+# The full coqdep (unused by this build, but distributed by make install)
+
+COQDEPCMO:=config/config.cma clib/clib.cma lib/lib.cma tools/coqdep_lexer.cmo \
+ tools/coqdep_common.cmo tools/coqdep.cmo
+
+$(COQDEP): $(call bestobj, $(COQDEPCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, $(SYSMOD))
+
+$(COQDEPBYTE): $(COQDEPCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, $(SYSMOD))
+
+COQMAKEFILECMO:=config/config.cma clib/clib.cma lib/lib.cma tools/coq_makefile.cmo
+
+$(COQMAKEFILE): $(call bestobj,$(COQMAKEFILECMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -package str)
+
+$(COQMAKEFILEBYTE): $(COQMAKEFILECMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str,unix,threads)
+
+$(COQTEX): $(call bestobj, tools/coq_tex.cmo)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -package str)
+
+$(COQTEXBYTE): tools/coq_tex.cmo
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str)
+
+$(COQWC): $(call bestobj, tools/coqwc.cmo)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -package str)
+
+$(COQWCBYTE): tools/coqwc.cmo
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str)
+
+COQDOCCMO:=config/config.cma clib/clib.cma lib/lib.cma $(addprefix tools/coqdoc/, \
+ cdglobals.cmo alpha.cmo index.cmo tokens.cmo output.cmo cpretty.cmo main.cmo )
+
+$(COQDOC): $(call bestobj, $(COQDOCCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -package str,unix)
+
+$(COQDOCBYTE): $(COQDOCCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package str,unix)
+
+COQWORKMGRCMO:=config/config.cma clib/clib.cma lib/lib.cma stm/spawned.cmo stm/coqworkmgrApi.cmo tools/coqworkmgr.cmo
+
+$(COQWORKMGR): $(call bestobj, $(COQWORKMGRCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, $(SYSMOD))
+
+$(COQWORKMGRBYTE): $(COQWORKMGRCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, $(SYSMOD))
+
+# fake_ide : for debugging or test-suite purpose, a fake ide simulating
+# a connection to coqidetop
+
+FAKEIDECMO:=config/config.cma clib/clib.cma lib/lib.cma ide/protocol/ideprotocol.cma ide/document.cmo ide/fake_ide.cmo
+
+$(FAKEIDE): $(call bestobj, $(FAKEIDECMO)) | $(IDETOP)
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -I ide -I ide/protocol -package str -package dynlink)
+
+$(FAKEIDEBYTE): $(FAKEIDECMO) | $(IDETOPBYTE)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -I ide -package str,unix,threads)
+
+# votour: a small vo explorer (based on the checker)
+
+VOTOURCMO:=clib/cObj.cmo checker/analyze.cmo checker/values.cmo checker/votour.cmo
+
+bin/votour: $(call bestobj, $(VOTOURCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -I checker)
+
+bin/votour.byte: $(VOTOURCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -I checker)
+
+###########################################################################
+# Csdp to micromega special targets
+###########################################################################
+
+CSDPCERTCMO:=clib/clib.cma $(addprefix plugins/micromega/, \
+ mutils.cmo micromega.cmo \
+ sos_types.cmo sos_lib.cmo sos.cmo csdpcert.cmo )
+
+$(CSDPCERT): $(call bestobj, $(CSDPCERTCMO))
+ $(SHOW)'OCAMLBEST -o $@'
+ $(HIDE)$(call bestocaml, -package num,unix)
+
+$(CSDPCERTBYTE): $(CSDPCERTCMO)
+ $(SHOW)'OCAMLC -o $@'
+ $(HIDE)$(call ocamlbyte, -package num,unix)
+
+###########################################################################
+# tests
+###########################################################################
+
+.PHONY: validate check test-suite $(ALLSTDLIB).v
+
+VALIDOPTS=$(if $(VERBOSE),,-silent) -o -m
+
+validate: $(CHICKEN) | $(ALLVO)
+ $(SHOW)'COQCHK <theories & plugins>'
+ $(HIDE)$(CHICKEN) -boot $(VALIDOPTS) $(ALLMODS)
+
+$(ALLSTDLIB).v:
+ $(SHOW)'MAKE $(notdir $@)'
+ $(HIDE)echo "Require $(ALLMODS)." > $@
+
+MAKE_TSOPTS=-C test-suite -s VERBOSE=$(VERBOSE)
+
+check: validate test-suite
+
+test-suite: world byte $(ALLSTDLIB).v
+ $(MAKE) $(MAKE_TSOPTS) clean
+ $(MAKE) $(MAKE_TSOPTS) all
+
+###########################################################################
+# Default rules for compiling ML code
+###########################################################################
+
+gramlib/.pack:
+ mkdir -p $@
+
+# gramlib.ml contents
+gramlib/.pack/gramlib.ml: | gramlib/.pack
+ echo " \
+module Ploc = Gramlib__Ploc \
+module Plexing = Gramlib__Plexing \
+module Gramext = Gramlib__Gramext \
+module Grammar = Gramlib__Grammar" > $@
+
+gramlib/.pack/gramlib__P%: gramlib/p% | gramlib/.pack
+ printf '# 1 "%s"\n' $< > $@
+ cat $< >> $@
+gramlib/.pack/gramlib__G%: gramlib/g% | gramlib/.pack
+ printf '# 1 "%s"\n' $< > $@
+ cat $< >> $@
+
+# Specific rules for gramlib to pack it Dune / OCaml 4.08 style
+GRAMOBJS=$(addsuffix .cmo, $(GRAMFILES))
+
+gramlib/.pack/%: COND_BYTEFLAGS+=-no-alias-deps -w -49
+gramlib/.pack/%: COND_OPTFLAGS+=-no-alias-deps -w -49
+
+gramlib/.pack/gramlib.%: COND_OPENFLAGS=
+gramlib/.pack/gramlib__%: COND_OPENFLAGS=-open Gramlib
+
+gramlib/.pack/gramlib.cma: $(GRAMOBJS) gramlib/.pack/gramlib.cmo
+ $(SHOW)'OCAMLC -a -o $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -a -o $@ $^
+
+gramlib/.pack/gramlib.cmxa: $(GRAMOBJS:.cmo=.cmx) gramlib/.pack/gramlib.cmx
+ $(SHOW)'OCAMLOPT -a -o $@'
+ $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -a -o $@ $^
+
+# Specific rule for kernel.cma, with $(VMBYTEFLAGS).
+# This helps loading dllcoqrun.so during an ocamldebug
+kernel/kernel.cma: kernel/kernel.mllib
+ $(SHOW)'OCAMLC -a -o $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(VMBYTEFLAGS) -a -o $@ $(filter-out %.mllib, $^)
+
+# Specific rule for kernel.cmxa as to adjoin -cclib -lcoqrun
+kernel/kernel.cmxa: kernel/kernel.mllib
+ $(SHOW)'OCAMLOPT -a -o $@'
+ $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -I kernel/byterun/ -cclib -lcoqrun -a -o $@ $(filter-out %.mllib, $^)
+
+# Target for libraries .cma and .cmxa
+
+# The dependency over the .mllib is somewhat artificial, since
+# ocamlc -a won't use this file, hence the $(filter-out ...) below.
+# But this ensures that the .cm(x)a is rebuilt when needed,
+# (especially when removing a module in the .mllib).
+# We used to have a "order-only" dependency over .mllib.d here,
+# but the -include mechanism should already ensure that we have
+# up-to-date dependencies.
+
+%.cma: %.mllib
+ $(SHOW)'OCAMLC -a -o $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -a -o $@ $(filter-out %.mllib, $^)
+
+%.cmxa: %.mllib
+ $(SHOW)'OCAMLOPT -a -o $@'
+ $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -a -o $@ $(filter-out %.mllib, $^)
+
+# For plugin packs
+
+%.cmo: %.mlpack
+ $(SHOW)'OCAMLC -pack -o $@'
+ $(HIDE)$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) -pack -o $@ $(filter-out %.mlpack, $^)
+
+%.cmx: %.mlpack
+ $(SHOW)'OCAMLOPT -pack -o $@'
+ $(HIDE)$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -pack -o $@ $(filter-out %.mlpack, $^)
+
+COND_IDEFLAGS=$(if $(filter ide/fake_ide% tools/coq_makefile%,$<), -I ide -I ide/protocol,)
+COND_PRINTERFLAGS=$(if $(filter dev/%,$<), -I dev,)
+
+# For module packing
+COND_OPENFLAGS=
+
+COND_BYTEFLAGS= \
+ $(COND_IDEFLAGS) $(COND_PRINTERFLAGS) $(MLINCLUDES) $(BYTEFLAGS) $(COND_OPENFLAGS)
+
+COND_OPTFLAGS= \
+ $(COND_IDEFLAGS) $(MLINCLUDES) $(OPTFLAGS) $(COND_OPENFLAGS)
+
+plugins/micromega/%.cmi: plugins/micromega/%.mli
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -package unix,num -c $<
+
+plugins/nsatz/%.cmi: plugins/nsatz/%.mli
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -package unix,num -c $<
+
+kernel/%.cmi: COND_BYTEFLAGS+=-w +a-4-44-50
+
+%.cmi: %.mli
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -c $<
+
+plugins/micromega/%.cmo: plugins/micromega/%.ml
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -package unix,num -c $<
+
+plugins/nsatz/%.cmo: plugins/nsatz/%.ml
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -package unix,num -c $<
+
+kernel/%.cmo: COND_BYTEFLAGS+=-w +a-4-44-50
+
+%.cmo: %.ml
+ $(SHOW)'OCAMLC $<'
+ $(HIDE)$(OCAMLC) $(COND_BYTEFLAGS) -c $<
+
+## NB: for the moment ocamlopt erases and recreates .cmi if there's no .mli around.
+## This can lead to nasty things with make -j. To avoid that:
+## 1) We make .cmx always depend on .cmi
+## 2) This .cmi will be created from the .mli, or trigger the compilation of the
+## .cmo if there's no .mli (see rule below about MLWITHOUTMLI)
+## 3) We tell ocamlopt to use the .cmi as the interface source file. With this
+## hack, everything goes as if there is a .mli, and the .cmi is preserved
+## and the .cmx is checked with respect to this .cmi
+
+HACKMLI = $(if $(wildcard $<i),,-intf-suffix .cmi)
+
+define diff
+ $(strip $(foreach f, $(1), $(if $(filter $(f),$(2)),,$f)))
+endef
+
+MLWITHOUTMLI := $(call diff, $(MLFILES), $(MLIFILES:.mli=.ml))
+
+$(MLWITHOUTMLI:.ml=.cmx): %.cmx: %.cmi # for .ml with .mli this is already the case
+
+$(MLWITHOUTMLI:.ml=.cmi): %.cmi: %.cmo
+
+# NB: the *_FORPACK variables are generated in *.mlpack.d by ocamllibdep
+# The only exceptions are the sources of the csdpcert binary.
+# To avoid warnings, we set them manually here:
+plugins/micromega/sos_lib_FORPACK:=
+plugins/micromega/sos_FORPACK:=
+plugins/micromega/sos_print_FORPACK:=
+plugins/micromega/csdpcert_FORPACK:=
+
+plugins/micromega/%.cmx: plugins/micromega/%.ml
+ $(SHOW)'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) $(COND_OPTFLAGS) $(HACKMLI) $($(@:.cmx=_FORPACK)) -package unix,num -c $<
+
+plugins/nsatz/%.cmx: plugins/nsatz/%.ml
+ $(SHOW)'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) $(COND_OPTFLAGS) $(HACKMLI) $($(@:.cmx=_FORPACK)) -package unix,num -c $<
+
+plugins/%.cmx: plugins/%.ml
+ $(SHOW)'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) $(COND_OPTFLAGS) $(HACKMLI) $($(@:.cmx=_FORPACK)) -c $<
+
+kernel/%.cmx: COND_OPTFLAGS+=-w +a-4-44-50
+
+%.cmx: %.ml
+ $(SHOW)'OCAMLOPT $<'
+ $(HIDE)$(OCAMLOPT) $(COND_OPTFLAGS) $(HACKMLI) -c $<
+
+%.cmxs: %.cmx
+ $(SHOW)'OCAMLOPT -shared -o $@'
+ $(HIDE)$(OCAMLOPT) -shared -o $@ $<
+
+%.cmxs: %.cmxa
+ $(SHOW)'OCAMLOPT -shared -o $@'
+ $(HIDE)$(OCAMLOPT) -linkall -shared -o $@ $<
+
+%.ml: %.mll
+ $(SHOW)'OCAMLLEX $<'
+ $(HIDE)$(OCAMLLEX) -o $@ "$*.mll"
+
+%.ml %.mli: %.mly
+ $(SHOW)'OCAMLYACC $<'
+ $(HIDE)$(OCAMLYACC) --strict "$*.mly"
+
+%.ml: %.mlg $(COQPP)
+ $(SHOW)'COQPP $<'
+ $(HIDE)$(COQPP) $<
+
+###########################################################################
+# Dependencies of ML code
+###########################################################################
+
+# Ocamldep is now used directly again (thanks to -ml-synonym in OCaml >= 3.12)
+OCAMLDEP = $(OCAMLFIND) ocamldep -slash -ml-synonym .mlpack
+
+MAINMLFILES := $(filter-out gramlib/.pack/% checker/% plugins/%, $(MLFILES) $(MLIFILES))
+MAINMLLIBFILES := $(filter-out gramlib/.pack/% checker/% plugins/%, $(MLLIBFILES) $(MLPACKFILES))
+
+$(MLDFILE).d: $(D_DEPEND_BEFORE_SRC) $(MAINMLFILES) $(D_DEPEND_AFTER_SRC) $(GENFILES) $(GENGRAMFILES)
+ $(SHOW)'OCAMLDEP MLFILES MLIFILES'
+ $(HIDE)$(OCAMLDEP) $(DEPFLAGS) -passrest $(MAINMLFILES) -open Gramlib $(GRAMMLFILES) $(TOTARGET)
+#NB: -passrest is needed to avoid ocamlfind reordering the -open Gramlib
+
+$(MLLIBDFILE).d: $(D_DEPEND_BEFORE_SRC) $(MAINMLLIBFILES) $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP MLLIBFILES MLPACKFILES'
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) $(MAINMLLIBFILES) $(TOTARGET)
+
+$(PLUGMLDFILE).d: $(D_DEPEND_BEFORE_SRC) $(filter plugins/%, $(MLFILES) $(MLIFILES)) $(D_DEPEND_AFTER_SRC) $(GENFILES)
+ $(SHOW)'OCAMLDEP plugins/MLFILES plugins/MLIFILES'
+ $(HIDE)$(OCAMLDEP) $(DEPFLAGS) $(filter plugins/%, $(MLFILES) $(MLIFILES)) $(TOTARGET)
+
+$(PLUGMLLIBDFILE).d: $(D_DEPEND_BEFORE_SRC) $(filter plugins/%, $(MLLIBFILES) $(MLPACKFILES)) $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP plugins/MLLIBFILES plugins/MLPACKFILES'
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) $(filter plugins/%, $(MLLIBFILES) $(MLPACKFILES)) $(TOTARGET)
+
+###########################################################################
+# Compilation of .v files
+###########################################################################
+
+# NB: for make world, no need to mention explicitly the .cmxs of the plugins,
+# since they are all mentioned in at least one Declare ML Module in some .v
+
+coqlib: theories plugins
+coqlib.timing.diff: theories.timing.diff plugins.timing.diff
+
+theories: $(THEORIESVO)
+plugins: $(PLUGINSVO)
+
+theories.timing.diff: $(THEORIESVO:.vo=.v.timing.diff)
+plugins.timing.diff: $(PLUGINSVO:.vo=.v.timing.diff)
+
+.PHONY: coqlib theories plugins coqlib.timing.diff theories.timing.diff plugins.timing.diff
+
+# The .vo files in Init are built with the -noinit option
+
+ifneq (,$(TIMING))
+TIMING_EXTRA = > $<.$(TIMING_EXT)
+else
+TIMING_EXTRA =
+endif
+
+theories/Init/%.vo theories/Init/%.glob: theories/Init/%.v $(VO_TOOLS_DEP)
+ $(SHOW)'COQC -noinit $<'
+ $(HIDE)rm -f theories/Init/$*.glob
+ $(HIDE)$(BOOTCOQC) $< -noinit -R theories Coq $(TIMING_ARG) $(TIMING_EXTRA)
+
+# The general rule for building .vo files :
+
+%.vo %.glob: %.v theories/Init/Prelude.vo $(VO_TOOLS_DEP)
+ $(SHOW)'COQC $<'
+ $(HIDE)rm -f $*.glob
+ $(HIDE)$(BOOTCOQC) $< $(TIMING_ARG) $(TIMING_EXTRA)
+ifdef VALIDATE
+ $(SHOW)'COQCHK $(call vo_to_mod,$@)'
+ $(HIDE)$(CHICKEN) -boot -silent -norec $(call vo_to_mod,$@) \
+ || ( RV=$$?; rm -f "$@"; exit $${RV} )
+endif
+
+%.v.timing.diff: %.v.before-timing %.v.after-timing
+ $(SHOW)PYTHON TIMING-DIFF $<
+ $(HIDE)$(MAKE) --no-print-directory print-pretty-single-time-diff BEFORE=$*.v.before-timing AFTER=$*.v.after-timing TIME_OF_PRETTY_BUILD_FILE="$@"
+
+
+# Dependencies of .v files
+
+$(VDFILE).d: $(D_DEPEND_BEFORE_SRC) $(VFILES) $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT)
+ $(SHOW)'COQDEP VFILES'
+ $(HIDE)$(COQDEPBOOT) -boot $(DYNDEP) $(VFILES) $(TOTARGET)
+
+###########################################################################
+
+# To speed-up things a bit, let's dissuade make to attempt rebuilding makefiles
+
+Makefile $(wildcard Makefile.*) config/Makefile : ;
+
+# Final catch-all rule.
+# Usually, 'make' would display such an error itself.
+# But if the target has some declared dependencies (e.g. in a .d)
+# but no building rule, 'make' succeeds silently (see bug #4812).
+
+%:
+ @echo "Error: no rule to make target $@ (or missing .PHONY)" && false
+
+# For emacs:
+# Local Variables:
+# mode: makefile
+# End: