diff --git a/Makefile b/Makefile index 209a8bb5e..be2b347d0 100644 --- a/Makefile +++ b/Makefile @@ -123,18 +123,24 @@ SRC_ML:=$(shell find * \( -name _build -or -name facebook-clang-plugins -or -pat fmt_all: parallel $(OCAMLFORMAT_EXE) --no-warn-error -i ::: $(SRC_ML) +# pre-building these avoids race conditions when building, eg src_build and test_build in parallel +.PHONY: src_build_common +src_build_common: + $(QUIET)$(call silent_on_success,Generating source dependencies,\ + $(MAKE) -C $(SRC_DIR) src_build_common) + .PHONY: src_build -src_build: +src_build: src_build_common $(QUIET)$(call silent_on_success,Building native Infer,\ $(MAKE) -C $(SRC_DIR) infer) .PHONY: byte -byte: +byte: src_build_common $(QUIET)$(call silent_on_success,Building byte Infer,\ $(MAKE) -C $(SRC_DIR) byte) .PHONY: test_build -test_build: +test_build: src_build_common $(QUIET)$(call silent_on_success,Testing Infer builds without warnings,\ $(MAKE) -C $(SRC_DIR) TEST=1 byte_no_install) # byte_no_install builds most of what toplevel needs, so it's more efficient to run the @@ -148,7 +154,7 @@ byte src_build test_build: fb-setup endif ifeq ($(BUILD_C_ANALYZERS),yes) -byte src_build test_build: clang_plugin +byte src_build src_build_common test_build: clang_plugin endif $(INFER_COMMAND_MANUALS): src_build Makefile @@ -313,7 +319,7 @@ check_missing_mli: test -f "$$x"i || echo Missing "$$x"i; done .PHONY: toplevel -toplevel: clang_plugin +toplevel: clang_plugin src_build_common $(QUIET)$(MAKE) -C $(SRC_DIR) toplevel .PHONY: inferScriptMode_test @@ -496,21 +502,29 @@ ifeq ($(IS_FACEBOOK_TREE),yes) $(QUIET)$(MAKE) -C facebook install endif -.PHONY: clean -clean: test_clean +# Nuke objects built from OCaml. Useful when changing the OCaml compiler, for instance. +.PHONY: ocaml_clean +ocaml_clean: ifeq ($(IS_RELEASE_TREE),no) ifeq ($(BUILD_C_ANALYZERS),yes) - $(QUIET)$(MAKE) -C $(FCP_DIR) clean $(QUIET)$(MAKE) -C $(FCP_DIR)/clang-ocaml clean endif endif $(QUIET)$(MAKE) -C $(SRC_DIR) clean + $(QUIET)$(MAKE) -C $(DEPENDENCIES_DIR)/ocamldot clean + +.PHONY: clean +clean: test_clean ocaml_clean +ifeq ($(IS_RELEASE_TREE),no) +ifeq ($(BUILD_C_ANALYZERS),yes) + $(QUIET)$(MAKE) -C $(FCP_DIR) clean +endif +endif $(QUIET)$(MAKE) -C $(ANNOTATIONS_DIR) clean $(QUIET)$(MAKE) -C $(MODELS_DIR) clean ifeq ($(IS_FACEBOOK_TREE),yes) $(QUIET)$(MAKE) -C facebook clean endif - $(QUIET)$(MAKE) -C $(DEPENDENCIES_DIR)/ocamldot clean find $(INFER_DIR)/tests \( -name '*.o' -o -name '*.o.sh' \) -delete $(QUIET)$(REMOVE_DIR) _build_logs $(MAN_DIR) diff --git a/infer/src/Makefile b/infer/src/Makefile index bc5941747..601e801dc 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -185,10 +185,16 @@ OCAML_ALL_SOURCES = $(OCAML_BASE_SOURCES) $(CLANG_ATDGEN_STUBS) $(CLANG_PLUGIN_M .PHONY: all all: infer +.PHONY: src_build_common +src_build_common: base/Version.ml $(OCAML_CONFIG_SOURCES) + +ifeq ($(BUILD_C_ANALYZERS),yes) +src_build_common: $(CLANG_BINIOU_DICT) +endif + # 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 $(OCAML_CONFIG_SOURCES) \ - $(MAKEFILE_LIST) +$(INFER_BUILD_DIR)/$(INFER_MAIN).native: src_build_common $(MAKEFILE_LIST) $(MKDIR_P) $(BASE_BUILD_DIR) $(OCAMLBUILD_CONFIG) -build-dir $(INFER_BUILD_DIR) \ $(INFER_CONFIG_TARGETS) @@ -215,12 +221,7 @@ endif .PHONY: infer infer: $(INFER_BIN).native -ifeq ($(BUILD_C_ANALYZERS),yes) -infer: $(CLANG_BINIOU_DICT) -endif - -$(INFER_BUILD_DIR)/$(INFER_MAIN).byte: base/Version.ml $(OCAML_CONFIG_SOURCES) \ - $(MAKEFILE_LIST) +$(INFER_BUILD_DIR)/$(INFER_MAIN).byte: src_build_common $(MAKEFILE_LIST) $(MKDIR_P) $(BASE_BUILD_DIR) $(OCAMLBUILD_CONFIG) -build-dir $(INFER_BUILD_DIR) \ $(INFER_CONFIG_TARGETS:.native=.byte) @@ -251,7 +252,7 @@ M= MFLAGS= .PHONY: module -module: base/Version.ml $(OCAML_ALL_SOURCES) +module: src_build_common $(OCAML_ALL_SOURCES) $(MKDIR_P) $(BASE_BUILD_DIR) $(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) \ $(MFLAGS) \ @@ -293,7 +294,7 @@ $(shell \ | awk 'BEGIN { FS = "/"; OFS = "/" } ; {$$NF=toupper(substr($$NF,1,1))substr($$NF,2); print $$0}') endef -toplevel.mlpack: base/Version.ml $(OCAML_CONFIG_SOURCES) $(MAKEFILE_LIST) +toplevel.mlpack: src_build_common $(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. @@ -332,11 +333,11 @@ $(CHECKCOPYRIGHT_BIN): $(CHECKCOPYRIGHT_MAIN).ml $(MAKEFILE_LIST) define gen_atdgen_rules # generate files using atdgen # parameters: -# 1. the .atd file to generate .ml{,i} files from -# 2. the base name of .ml{,i} files +# 1. the .atd file to generate .ml{,i} files from, e.g. foo.atd +# 2. the base name of .ml{,i} files, e.g. foo # 3. the type of files to generate: b, j, t, or v -$(2)_$(3).ml $(2)_$(3).mli: $(1) +$(2)_$(3).mli: $(1) $(ATDGEN) -$(3) $$< -o $(2) # the .ml depends on the corresponding .mli to avoid running atdgen