From 7210e79c57e171d247e99fbd8895f75f3ac4fe91 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Tue, 28 Mar 2017 05:59:40 -0700 Subject: [PATCH] [make] fix Makefile bug in building models Summary: Nuking the specs then building the models was not a great idea: the models do not look at specs but only at some dummy marker files, eg infer/lib/specs/c_models, so they don't necessarily realize that they need to be rebuilt when the specs have been nuked! One easy workaround would be to also delete the marker files, but then we would *always* rebuild the models when building infer. Not good. The solution here is to nuke the specs and marker files only when the clang dependencies change, then rebuild all the models. Reviewed By: jberdine, jeremydubreil Differential Revision: D4781424 fbshipit-source-id: 2d2606e --- .gitignore | 1 + Makefile | 3 --- infer/models/Makefile | 23 +++++++++++++++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index d19f7fdba..5c4dac4f2 100644 --- a/.gitignore +++ b/.gitignore @@ -98,6 +98,7 @@ buck-out/ /infer/models/cpp/out/ /infer/models/objc/out/ /infer/lib/specs/c_models +/infer/lib/specs/clang_models /infer/lib/specs/cpp_models /infer/lib/specs/objc_models /infer/lib/specs/clean_models diff --git a/Makefile b/Makefile index 81880abfc..95b68fa08 100644 --- a/Makefile +++ b/Makefile @@ -120,9 +120,6 @@ infer: src_build ifeq ($(BUILD_JAVA_ANALYZERS),yes) $(QUIET)$(MAKE) -C $(ANNOTATIONS_DIR) endif -# Delete existing specs so that they are not used during the analysis of models. Infer may -# segfault in some cases otherwise. - $(QUIET)$(MAKE) -C $(MODELS_DIR) clean_specs $(QUIET)$(MAKE) -C $(MODELS_DIR) all .PHONY: clang_setup diff --git a/infer/models/Makefile b/infer/models/Makefile index 514aedfc0..8d9e0d8be 100644 --- a/infer/models/Makefile +++ b/infer/models/Makefile @@ -13,6 +13,8 @@ CPP_MODELS_DIR = cpp JAVA_MODELS_DIR = java OBJC_MODELS_DIR = objc +CLANG_MODELS_FILE = $(SPECS_LIB_DIR)/clang_models + CLANG_SUBDIRS = $(C_MODELS_DIR) $(CPP_MODELS_DIR) ifneq (no, $(XCODE_SELECT)) CLANG_SUBDIRS += $(OBJC_MODELS_DIR) @@ -29,12 +31,29 @@ endif .PHONY: java clang clean clean_specs $(CLANG_SUBDIRS) clean_specs: - $(REMOVE) $(SPECS_LIB_DIR)/*.specs + $(REMOVE) $(SPECS_LIB_DIR)/*.specs $(C_MODELS_FILE) $(CPP_MODELS_FILE) $(OBJC_MODELS_FILE) $(CLANG_SUBDIRS): $(QUIET)$(MAKE) -C $@ install -clang: $(CLANG_SUBDIRS) +# The clang deps have changed, so the models need to be rebuilt. If infer itself has changed, we +# need to nuke the previous specs files in case the serialization has changed, otherwise we might +# encounter a segfault reading them. +$(CLANG_MODELS_FILE): $(CLANG_DEPS_NO_MODELS) + $(QUIET)$(MAKE) clean_specs +# Since [CLANG_DEPS_NO_MODELS] is newer than [CLANG_MODELS_FILE], it is also newer than the +# previously built clang models, so they will all be rebuilt by the subdirs' Makefiles. + $(QUIET)$(MAKE) $(CLANG_SUBDIRS) +# Maintain the invariant that [CLANG_MODELS_FILE] is newer than the clang models. + $(QUIET)touch $@ + +clang: $(CLANG_MODELS_FILE) +# Run the sub-makes unconditionally since they know more about when they need to be +# rebuilt. For instance, they need to be rebuilt when their source files change, which is not +# taken into account by the dependencies of the $(CLANG_MODELS_FILE) target. If we rebuilt +# $(CLANG_MODELS_FILE) already, then the command below will be a no-op (so we don't rebuild +# the models twice). + $(QUIET)$(MAKE) $(CLANG_SUBDIRS) java: $(QUIET)$(MAKE) -C $@ install