@ -11,6 +11,13 @@ include $(ROOT_DIR)/Makefile.config
#### Global declarations ####
ETC_DIR = $( INFER_DIR) /etc
i f e q ( $( TEST ) , 1 )
BASE_BUILD_DIR = $( BUILD_DIR) /test
e l s e
BASE_BUILD_DIR = $( BUILD_DIR)
e n d i f
STUBS_BUILD_DIR = $( BASE_BUILD_DIR) /stubs
INFER_BUILD_DIR = $( BASE_BUILD_DIR) /infer
ATDGEN_SUFFIXES = _t.ml _t.mli _j.ml _j.mli
@ -24,7 +31,6 @@ OCAMLBUILD_OPTIONS = \
-r \
-use-menhir -menhir '$(MENHIR) --explain --strict' \
-use-ocamlfind \
-lflags -cclib,-lffi \
-cflags -g -lflags -g \
-cflags -short-paths \
-cflags -safe-string \
@ -32,10 +38,10 @@ OCAMLBUILD_OPTIONS = \
-cflags -strict-formats \
-cflags -strict-sequence \
-cflags -w,$( OCAML_FATAL_WARNINGS) -4-9-32-40-41-42-45-48 \
-tag-line "<*{clang/clang_ast_*,backend/jsonbug_*,checkers/stacktree_* }>: warn(-27-32-35-39)" \
-tag-line "<*{clang/clang_ast_*,backend/jsonbug_*,checkers/stacktree_* ,ffi/gen/* }>: warn(-27-32-34 -35-39)" \
-tag-line "<*/{,*/}*.{ml,re}{,i}>: package(ppx_compare)" \
-tag thread \
-pkgs atdgen,core,ctypes.foreign ,extlib,oUnit,str,unix,xmlm,yojson,zip
-pkgs atdgen,core,ctypes.stubs ,extlib,oUnit,str,unix,xmlm,yojson,zip
i f e q ( $( ENABLE_OCAML_BINANNOT ) , y e s )
OCAMLBUILD_OPTIONS += -cflags -bin-annot
@ -49,6 +55,10 @@ ifneq (,$(findstring s,$(MAKEFLAGS)))
OCAMLBUILD_OPTIONS += -quiet
e n d i f
i f e q ( $( TEST ) , 1 )
OCAMLBUILD_OPTIONS += -cflags -warn-error,$( OCAML_FATAL_WARNINGS)
e n d i f
#### Backend declarations ####
@ -121,10 +131,16 @@ else
EXTRA_DEPS = opensource
e n d i f
DEPENDENCIES = IR backend base checkers eradicate harness integration quandary bufferoverrun $( EXTRA_DEPS)
DEPENDENCIES = \
IR backend base checkers eradicate ffi ffi/gen harness integration quandary bufferoverrun \
$( EXTRA_DEPS)
# ocamlbuild command with options common to all build targets
OCAMLBUILD_BASE = $( REBUILD) $( OCAMLBUILD_OPTIONS) -j $( NCPU) $( addprefix -I , $( DEPENDENCIES) )
OCAMLBUILD_BASE = \
$( REBUILD) $( OCAMLBUILD_OPTIONS) -j $( NCPU) $( addprefix -I , $( DEPENDENCIES) ) \
OCAMLBUILD_EXTRA_BYTE = -lflags -custom,$( INFER_BUILD_DIR) /ffi/gen/extern_stubs.o
OCAMLBUILD_EXTRA_NATIVE = -lflag $( INFER_BUILD_DIR) /ffi/gen/extern_stubs.o
# ocamlbuild with options necessary to build all targets at once, regardless of configure flags
OCAMLBUILD_ALL = $( OCAMLBUILD_BASE) $( JAVA_OCAMLBUILD_OPTIONS)
@ -154,6 +170,9 @@ DEPENDENCIES += clang unit/clang
e l s e
DEPENDENCIES += unit/clang_stubs
e n d i f
i f e q ( $( TEST ) , 1 )
INFER_CONFIG_TARGETS += $( INFERUNIT_MAIN) .native
e n d i f
OCAML_BASE_SOURCES = \
$( wildcard $( DEPENDENCIES:= /[ a-zA-Z] *.ml) $( DEPENDENCIES:= /[ a-zA-Z] *.mli) \
@ -171,11 +190,43 @@ export OCAMLFIND_IGNORE_DUPS_IN=$(shell $(OCAMLC) -where)/compiler-libs
.PHONY : all
all : infer
# witness that generators have been built
STUBS_HAVE_BEEN_BUILT = $( INFER_BUILD_DIR) /ffi/gen/generate_caml_types.c
# witness that generators have been run
STUBS_HAVE_RUN = ffi/gen/IOCtl_types.ml
# to make sure everything Cstubs-related has been done
STUBS_DEPS = $( STUBS_HAVE_RUN) $( INFER_BUILD_DIR) /ffi/gen/extern_stubs.o
$(STUBS_HAVE_BEEN_BUILT) : $( wildcard ffi /*.ml ) $( MAKEFILE_LIST )
$( MKDIR_P) $( BASE_BUILD_DIR) $( @D)
$( OCAMLBUILD_CONFIG) -build-dir $( STUBS_BUILD_DIR) \
ffi/GenerateML.native ffi/GenerateC.native ffi/GenerateCGenerator.native
$( STUBS_BUILD_DIR) /ffi/GenerateML.native > ffi/gen/ExternStubs.ml
$( STUBS_BUILD_DIR) /ffi/GenerateC.native > $( @D) /extern_stubs.c
$( STUBS_BUILD_DIR) /ffi/GenerateCGenerator.native > $( @D) /generate_caml_types.c
@touch $@
$(STUBS_HAVE_RUN) : $( STUBS_HAVE_BEEN_BUILT ) $( MAKEFILE_LIST )
# create .o file using the right flags, which ocamlfind knows about
cd $( INFER_BUILD_DIR) /$( @D) && \
$( OCAMLFIND) ocamlc -package ctypes.stubs generate_caml_types.c
# link the executable by calling CC directly (no idea how to do it with ocaml*)
cd $( INFER_BUILD_DIR) /$( @D) && \
$( CC) generate_caml_types.o -o generate_caml_types
$( INFER_BUILD_DIR) /$( @D) /generate_caml_types > $@
@touch $@
$(INFER_BUILD_DIR)/ffi/gen/extern_stubs.o : $( STUBS_HAVE_BEEN_BUILT )
cd $( @D) && $( OCAMLFIND) ocamlc -package ctypes.stubs extern_stubs.c
@touch $@
# single out infer.native as the source of truth for make, knowing that in fact several targets are
# produced by the build
$(INFER_BUILD_DIR)/$(INFER_MAIN).native : base /Version .ml $( BUILD_DIR ) $( OCAML_CONFIG_SOURCES ) \
$( MAKEFILE_LIST)
$( OCAMLBUILD_CONFIG) -build-dir $( INFER_BUILD_DIR) $( INFER_CONFIG_TARGETS)
$(INFER_BUILD_DIR)/$(INFER_MAIN).native : base /Version .ml $( OCAML_CONFIG_SOURCES ) \
$( STUBS_DEPS) $( MAKEFILE_LIST)
$( MKDIR_P) $( BASE_BUILD_DIR)
$( OCAMLBUILD_CONFIG) -build-dir $( INFER_BUILD_DIR) $( OCAMLBUILD_EXTRA_NATIVE) \
$( INFER_CONFIG_TARGETS)
# let make know that the target is up-to-date even if ocamlbuild cached it
@touch $@
@ -199,8 +250,9 @@ ifeq ($(BUILD_C_ANALYZERS),yes)
infer : $( CLANG_BINIOU_DICT )
e n d i f
$(INFER_BUILD_DIR)/$(INFER_MAIN).byte : base /Version .ml $( BUILD_DIR ) $( OCAML_CONFIG_SOURCES )
$( OCAMLBUILD_CONFIG) -build-dir $( INFER_BUILD_DIR) \
$(INFER_BUILD_DIR)/$(INFER_MAIN).byte : base /Version .ml $( STUBS_DEPS ) $( OCAML_CONFIG_SOURCES )
$( MKDIR_P) $( BASE_BUILD_DIR)
$( OCAMLBUILD_CONFIG) -build-dir $( INFER_BUILD_DIR) $( OCAMLBUILD_EXTRA_BYTE) \
$( INFER_CONFIG_TARGETS:.native= .byte) $( INFERUNIT_MAIN) .byte
@touch $@
@ -225,21 +277,12 @@ M=
MFLAGS =
.PHONY : module
module : base /Version .ml $( BUILD_DIR ) $( OCAML_ALL_SOURCES )
$( OCAMLBUILD_ALL) -build-dir $( INFER_BUILD_DIR) \
module : base /Version .ml $( OCAML_ALL_SOURCES )
$( MKDIR_P) $( BASE_BUILD_DIR)
$( OCAMLBUILD_ALL) -build-dir $( INFER_BUILD_DIR) $( OCAMLBUILD_EXTRA_BYTE) \
$( MFLAGS) \
$( M)
$(TEST_BUILD_DIR)/$(INFER_MAIN).byte : base /Version .ml $( BUILD_DIR ) $( OCAML_CONFIG_SOURCES ) \
toplevel.mlpack $( MAKEFILE_LIST)
$( OCAMLBUILD_CONFIG) -build-dir $( TEST_BUILD_DIR) \
-cflags -warn-error,$( OCAML_FATAL_WARNINGS) \
$( INFER_CONFIG_TARGETS:.native= .byte) $( INFERUNIT_MAIN) .byte toplevel.cmo
@touch $@
.PHONY : test_build
test_build : $( TEST_BUILD_DIR ) /$( INFER_MAIN ) .byte
# to generate interface file.mli from implementation file.ml execute:
# make M=file mli
mli :
@ -285,7 +328,7 @@ $(shell \
| awk 'BEGIN { FS = "/"; OFS = "/" } ; {$$NF=toupper(substr($$NF,1,1))substr($$NF,2); print $$0}' )
e n d e f
toplevel.mlpack : base /Version .ml $( OCAML_CONFIG_SOURCES) $( MAKEFILE_LIST )
toplevel.mlpack : base /Version .ml $( STUBS_DEPS) $( OCAML_CONFIG_SOURCES) $( MAKEFILE_LIST )
# We need to pack all the infer modules into another module to avoid name clashes with some
# of them coming from ocaml libraries (Ident for example). To do that, we generate a .mlpack
# file containing namespaced modules.
@ -297,13 +340,16 @@ toplevel.mlpack: base/Version.ml $(OCAML_CONFIG_SOURCES) $(MAKEFILE_LIST)
$( foreach module,\
$( filter-out $( foreach root,$( roots) ,%/$( root) ) ,\
$( foreach source,\
$( filter-out unit/%,$( OCAML_CONFIG_SOURCES) ) ,\
$( filter-out unit/% ffi/% ,$( OCAML_CONFIG_SOURCES) ) ,\
$( call to_ocaml_module,$( source ) ) ) ) ,\
$( shell echo $( module) >> $( $@ _tmp) ) )
mv $( $@ _tmp) $@
$(INFER_BUILD_DIR)/toplevel.cmo : toplevel .mlpack $( BUILD_DIR )
$( OCAMLBUILD_CONFIG) -build-dir $( INFER_BUILD_DIR) toplevel.cmo
$(INFER_BUILD_DIR)/toplevel.cmo : toplevel .mlpack
$( MKDIR_P) $( BASE_BUILD_DIR)
$( OCAMLBUILD_CONFIG) -build-dir $( INFER_BUILD_DIR) $( OCAMLBUILD_EXTRA_BYTE) toplevel.cmo
cd $( INFER_BUILD_DIR) /ffi/gen && \
ocamlmklib -o externstubslib ExternStubs.cmo extern_stubs.o
@touch $@
.PHONY : toplevel
@ -312,12 +358,13 @@ toplevel: $(INFER_BUILD_DIR)/toplevel.cmo
.PHONY : checkCopyright
checkCopyright : $( CHECKCOPYRIGHT_BIN )
$(CHECKCOPYRIGHT_BIN) : $( BUILD_DIR ) $( CHECKCOPYRIGHT_MAIN ) .ml Makefile
$( REBUILD) -quiet -r -j $( NCPU) -build-dir $( BUILD_DIR) /checkCopyright \
$(CHECKCOPYRIGHT_BIN) : $( CHECKCOPYRIGHT_MAIN ) .ml $( MAKEFILE_LIST )
$( MKDIR_P) $( BASE_BUILD_DIR)
$( REBUILD) -quiet -r -j $( NCPU) -build-dir $( BASE_BUILD_DIR) /checkCopyright \
-cflags -g,-safe-string -lflags -g \
-pkgs core,str -tag thread -use-ocamlfind $( CHECKCOPYRIGHT_MAIN) .native
$( INSTALL_PROGRAM) \
$( BUILD_DIR) /checkCopyright/$( CHECKCOPYRIGHT_MAIN) .native $( CHECKCOPYRIGHT_BIN)
$( BASE_B UILD_DIR) /checkCopyright/$( CHECKCOPYRIGHT_MAIN) .native $( CHECKCOPYRIGHT_BIN)
d e f i n e g e n _ a t d g e n _ r u l e s
# generate files using atdgen
@ -382,13 +429,6 @@ base/Version.ml: base/Version.ml.in $(MAKEFILE_LIST)
cat " $$ TMPFILE " > $@ ; \
$( REMOVE) " $$ TMPFILE "
$(BUILD_DIR) :
$( MKDIR_P) $( BUILD_DIR)
.PHONY : test_clean
test_clean :
$( REMOVE_DIR) $( TEST_BUILD_DIR)
.PHONY : clean
clean :
$( REMOVE) $( INFER_ALL_TARGETS)
@ -405,3 +445,4 @@ clean:
$( REMOVE) $( INFER_CLANG_FCP_MIRRORED_FILES)
$( REMOVE) mod_dep.dot
$( REMOVE) mod_dep.pdf
$( REMOVE) ffi/gen/*