From bce1a1ff2eea4a218271232d022cadc7b2cad380 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Wed, 14 Dec 2016 12:37:05 -0800 Subject: [PATCH] [make] make infer/src/Makefile less phony Reviewed By: jberdine Differential Revision: D4319515 fbshipit-source-id: 607022c --- .gitignore | 7 - Makefile | 112 ++++++--------- Makefile.config.in | 2 +- infer/bin/inferTraceBugs | 1 + infer/lib/wrappers/c++ | 1 + infer/lib/wrappers/cc | 1 + infer/lib/wrappers/clang | 1 + infer/lib/wrappers/clang++ | 1 + infer/lib/wrappers/g++ | 1 + infer/lib/wrappers/gcc | 1 + infer/models/Makefile | 20 +-- infer/models/c/Makefile | 20 +-- infer/models/cpp/Makefile | 20 +-- infer/models/objc/Makefile | 19 ++- infer/src/Makefile | 127 +++++++++++------- .../build_systems/clang_translation/Makefile | 20 +-- infer/tests/codetoanalyze/c/frontend/Makefile | 2 +- .../tests/codetoanalyze/cpp/frontend/Makefile | 2 +- .../codetoanalyze/objc/frontend/Makefile | 4 +- .../codetoanalyze/objcpp/frontend/Makefile | 2 +- scripts/infer_repl | 9 +- 21 files changed, 195 insertions(+), 178 deletions(-) create mode 120000 infer/bin/inferTraceBugs create mode 120000 infer/lib/wrappers/c++ create mode 120000 infer/lib/wrappers/cc create mode 120000 infer/lib/wrappers/clang create mode 120000 infer/lib/wrappers/clang++ create mode 120000 infer/lib/wrappers/g++ create mode 120000 infer/lib/wrappers/gcc diff --git a/.gitignore b/.gitignore index f71b3af8d..1a02c41a5 100644 --- a/.gitignore +++ b/.gitignore @@ -80,7 +80,6 @@ buck-out/ /infer/bin/InferUnit /infer/bin/Typeprop /infer/bin/infer -/infer/bin/inferTraceBugs /infer/src/base/Version.ml /infer/models/java/models/ /infer/models/java/models.jar @@ -93,12 +92,6 @@ buck-out/ /infer/lib/specs/cpp_models /infer/lib/specs/objc_models /infer/lib/specs/clean_models -/infer/lib/wrappers/c++ -/infer/lib/wrappers/cc -/infer/lib/wrappers/clang -/infer/lib/wrappers/clang++ -/infer/lib/wrappers/g++ -/infer/lib/wrappers/gcc /scripts/checkCopyright /infer/etc/clang_ast.dict /infer/src/toplevel.mlpack diff --git a/Makefile b/Makefile index 0869cbc19..32ef113c4 100644 --- a/Makefile +++ b/Makefile @@ -38,31 +38,14 @@ DIRECT_TESTS += objc_frontend_test objc_errors_test objc_linters_test objcpp_fro endif .PHONY: all -all: infer inferTraceBugs - -# executable names that should point to InferClang to trigger capture -INFERCLANG_WRAPPERS_BASENAMES = c++ cc clang clang++ g++ gcc -INFERCLANG_WRAPPERS_PATHS = $(foreach cc,$(INFERCLANG_WRAPPERS_BASENAMES),$(LIB_DIR)/wrappers/$(cc)) - -$(INFERCLANG_WRAPPERS_PATHS): Makefile - $(REMOVE) $@ && \ - cd $(@D) && \ - $(LN_S) ../../bin/InferClang $(@F) - -$(BIN_DIR): - $(MKDIR_P) $@ - -$(INFERTRACEBUGS_BIN_RELPATH): Makefile $(BIN_DIR) - $(REMOVE) $@ && \ - cd $(@D) && \ - $(LN_S) ../lib/python/$(@F) $(@F) +all: infer .PHONY: src_build src_build: ifeq ($(IS_FACEBOOK_TREE),yes) - $(MAKE) -C facebook + @$(MAKE) -C facebook endif - $(MAKE) -C $(SRC_DIR) infer + @$(MAKE) -C $(SRC_DIR) infer ifeq ($(BUILD_C_ANALYZERS),yes) src_build: clang_plugin endif @@ -70,31 +53,28 @@ endif .PHONY: infer infer: src_build ifeq ($(BUILD_JAVA_ANALYZERS),yes) - $(MAKE) -C $(ANNOTATIONS_DIR) -endif - $(MAKE) -C $(MODELS_DIR) all -ifeq ($(BUILD_C_ANALYZERS),yes) -infer: $(INFERCLANG_WRAPPERS_PATHS) + @$(MAKE) -C $(ANNOTATIONS_DIR) endif + @$(MAKE) -C $(MODELS_DIR) all .PHONY: clang_setup clang_setup: - export CC="$(CC)" CFLAGS="$(CFLAGS)"; \ + @export CC="$(CC)" CFLAGS="$(CFLAGS)"; \ export CXX="$(CXX)" CXXFLAGS="$(CXXFLAGS)"; \ export CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)"; \ - $(FCP_DIR)/clang/setup.sh $(INFER_FCP_SETUP_OPTS) + $(FCP_DIR)/clang/setup.sh $(INFER_FCP_SETUP_OPTS) > /dev/null .PHONY: clang_plugin clang_plugin: clang_setup ifeq ($(IS_RELEASE_TREE),no) - $(MAKE) -C $(FCP_DIR)/libtooling all \ + @$(MAKE) -C $(FCP_DIR)/libtooling all \ CC=$(CC) CXX=$(CXX) \ CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \ CPP="$(CPP)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" \ LOCAL_CLANG=$(CLANG_PREFIX)/bin/clang \ CLANG_PREFIX=$(CLANG_PREFIX) \ CLANG_INCLUDES=$(CLANG_INCLUDES) - $(MAKE) -C $(FCP_DIR)/clang-ocaml all \ + @$(MAKE) -C $(FCP_DIR)/clang-ocaml all \ build/clang_ast_proj.ml build/clang_ast_proj.mli \ CC=$(CC) CXX=$(CXX) \ CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" \ @@ -104,29 +84,16 @@ ifeq ($(IS_RELEASE_TREE),no) CLANG_INCLUDES=$(CLANG_INCLUDES) endif -.PHONY: inferTraceBugs -inferTraceBugs: $(INFERTRACEBUGS_BIN_RELPATH) - -.PHONY: test_this_build -test_this_build: clang_plugin -ifeq ($(IS_FACEBOOK_TREE),yes) - $(MAKE) -C facebook -endif - $(MAKE) -C $(SRC_DIR) test_build - -.PHONY: test_oss_build -test_oss_build: clang_plugin - $(MAKE) -C $(SRC_DIR) EXTRA_DEPS=opensource TEST_BUILD_DIR=$(BUILD_DIR)/opensource test_build - .PHONY: test_build -test_build: test_this_build +test_build: clang_plugin ifeq ($(IS_FACEBOOK_TREE),yes) -test_build: test_oss_build + @$(MAKE) -C facebook endif + @$(MAKE) -C $(SRC_DIR) test_build .PHONY: ocaml_unit_test -ocaml_unit_test: test_this_build - $(TEST_BUILD_DIR)/unit/inferunit.byte +ocaml_unit_test: test_build + $(call silent_on_success,$(TEST_BUILD_DIR)/unit/inferunit.byte) DIRECT_TESTS_REPLACE = $(patsubst %_frontend_test,%_frontend_replace,$(filter %_frontend_test,$(DIRECT_TESTS))) @@ -138,7 +105,7 @@ define gen_direct_test_rule $(1): infer ($(MAKE) -C \ $(INFER_DIR)/tests/codetoanalyze/$(shell printf $(1) | cut -f 1 -d _)/$(shell printf $(1) | cut -f 2 -d _) \ - $(shell printf $(1) | cut -f 3 -d _) \ + test \ 3>&1 1>&2- 2>&3- ) \ | grep -v "warning: ignoring old commands for target" \ | grep -v "warning: overriding commands for target" \ @@ -146,7 +113,7 @@ $(1): infer .PHONY: $(1)_clean $(1)_clean: - $(MAKE) -C \ + @$(MAKE) -C \ $(INFER_DIR)/tests/codetoanalyze/$(shell printf $(1) | cut -f 1 -d _)/$(shell printf $(1) | cut -f 2 -d _) \ clean endef @@ -161,11 +128,15 @@ direct_tests: $(DIRECT_TESTS) define gen_build_system_test_rule .PHONY: build_$(1)_test build_$(1)_test: infer - $(MAKE) -C $(INFER_DIR)/tests/build_systems/$(1) test + @($(MAKE) -C $(INFER_DIR)/tests/build_systems/$(1) test \ + 3>&1 1>&2- 2>&3- ) \ + | grep -v "warning: ignoring old commands for target" \ + | grep -v "warning: overriding commands for target" \ + ; exit $$$${PIPESTATUS[0]} .PHONY: build_$(1)_clean build_$(1)_clean: - $(MAKE) -C $(INFER_DIR)/tests/build_systems/$(1) clean + @$(MAKE) -C $(INFER_DIR)/tests/build_systems/$(1) clean endef $(foreach test,$(BUILD_SYSTEMS_TESTS), $(eval $(call gen_build_system_test_rule,$(test)))) @@ -199,17 +170,17 @@ check_missing_mli: test -f "$$x"i || echo Missing "$$x"i; done .PHONY: toplevel -toplevel: infer - $(MAKE) -C $(SRC_DIR) toplevel +toplevel: clang_plugin + @$(MAKE) -C $(SRC_DIR) toplevel .PHONY: inferScriptMode_test -inferScriptMode_test: toplevel +inferScriptMode_test: test_build $(call silent_on_success,\ INFER_REPL_BINARY=ocaml $(SCRIPT_DIR)/infer_repl $(INFER_DIR)/tests/repl/infer_batch_script.ml) .PHONY: checkCopyright checkCopyright: - $(MAKE) -C $(SRC_DIR) checkCopyright + @$(MAKE) -C $(SRC_DIR) checkCopyright .PHONY: run-test run-test: test_build ocaml_unit_test buck_test inferTraceBugs_test inferScriptMode_test checkCopyright @@ -224,7 +195,7 @@ else endif .PHONY: quick-test -quick-test: test_this_build ocaml_unit_test +quick-test: test_build ocaml_unit_test .PHONY: test-replace test-replace: @@ -239,7 +210,6 @@ test-replace: .PHONY: uninstall uninstall: $(REMOVE_DIR) $(DESTDIR)$(libdir)/infer/ - $(REMOVE) $(DESTDIR)$(bindir)/inferTraceBugs $(REMOVE) $(DESTDIR)$(bindir)/infer .PHONY: test_clean @@ -247,7 +217,7 @@ test_clean: $(foreach test,$(DIRECT_TESTS),$(test)_clean) \ $(foreach test,$(BUILD_SYSTEMS_TESTS),build_$(test)_clean) .PHONY: install -install: infer inferTraceBugs +install: infer # create directory structure test -d $(DESTDIR)$(bindir) || \ $(MKDIR_P) $(DESTDIR)$(bindir) @@ -300,10 +270,12 @@ ifeq ($(BUILD_C_ANALYZERS),yes) @for i in $$(find infer/lib/clang_wrappers/*); do \ $(INSTALL_PROGRAM) -C $$i $(DESTDIR)$(libdir)/infer/$$i; \ done +# only for files that point to InferClang (cd $(DESTDIR)$(libdir)/infer/infer/lib/wrappers/ && \ - $(REMOVE) $(INFERCLANG_WRAPPERS_BASENAMES) && \ - $(foreach cc,$(INFERCLANG_WRAPPERS_BASENAMES), \ - $(LN_S) ../../bin/InferClang $(cc);)) + $(foreach cc,$(shell find $(LIB_DIR)/wrappers -type l), \ + [ $(cc) -ef $(INFERCLANG_BIN) ] && \ + $(REMOVE) $(notdir $(cc)) && \ + $(LN_S) ../../bin/InferClang $(notdir $(cc));)) @for i in $$(find infer/lib/specs/*); do \ $(INSTALL_DATA) -C $$i $(DESTDIR)$(libdir)/infer/$$i; \ done @@ -349,26 +321,24 @@ endif $(LN_S) $(libdir)/infer/infer/lib/python/inferTraceBugs inferTraceBugs) ifeq ($(IS_FACEBOOK_TREE),yes) - $(MAKE) -C facebook install + @$(MAKE) -C facebook install endif .PHONY: clean clean: test_clean ifeq ($(IS_RELEASE_TREE),no) ifeq ($(BUILD_C_ANALYZERS),yes) - $(MAKE) -C $(FCP_DIR) clean - $(MAKE) -C $(FCP_DIR)/clang-ocaml clean - $(REMOVE) $(INFERCLANG_WRAPPERS_PATHS) + @$(MAKE) -C $(FCP_DIR) clean + @$(MAKE) -C $(FCP_DIR)/clang-ocaml clean endif endif - $(MAKE) -C $(SRC_DIR) clean - $(MAKE) -C $(ANNOTATIONS_DIR) clean - $(MAKE) -C $(MODELS_DIR) clean - $(REMOVE) $(INFERTRACEBUGS_BIN_RELPATH) + @$(MAKE) -C $(SRC_DIR) clean + @$(MAKE) -C $(ANNOTATIONS_DIR) clean + @$(MAKE) -C $(MODELS_DIR) clean ifeq ($(IS_FACEBOOK_TREE),yes) - $(MAKE) -C facebook clean + @$(MAKE) -C facebook clean endif - $(MAKE) -C $(DEPENDENCIES_DIR)/ocamldot clean + @$(MAKE) -C $(DEPENDENCIES_DIR)/ocamldot clean find $(INFER_DIR)/tests -name '*.o' -or -name '*.o.sh' -delete .PHONY: conf-clean diff --git a/Makefile.config.in b/Makefile.config.in index 4657b6474..fc9c596f8 100644 --- a/Makefile.config.in +++ b/Makefile.config.in @@ -61,7 +61,7 @@ REMOVE = rm -vf REMOVE_DIR = rm -rvf RSYNC_A = rsync -aq endif -COPY = cp -f -p +COPY = cp -f COPY_DIR = cp -Rf ABSOLUTE_ROOT_DIR = $(shell cd $(ROOT_DIR) && pwd) diff --git a/infer/bin/inferTraceBugs b/infer/bin/inferTraceBugs new file mode 120000 index 000000000..a602e4d98 --- /dev/null +++ b/infer/bin/inferTraceBugs @@ -0,0 +1 @@ +../lib/python/inferTraceBugs \ No newline at end of file diff --git a/infer/lib/wrappers/c++ b/infer/lib/wrappers/c++ new file mode 120000 index 000000000..a78cb23c5 --- /dev/null +++ b/infer/lib/wrappers/c++ @@ -0,0 +1 @@ +../../bin/InferClang \ No newline at end of file diff --git a/infer/lib/wrappers/cc b/infer/lib/wrappers/cc new file mode 120000 index 000000000..a78cb23c5 --- /dev/null +++ b/infer/lib/wrappers/cc @@ -0,0 +1 @@ +../../bin/InferClang \ No newline at end of file diff --git a/infer/lib/wrappers/clang b/infer/lib/wrappers/clang new file mode 120000 index 000000000..a78cb23c5 --- /dev/null +++ b/infer/lib/wrappers/clang @@ -0,0 +1 @@ +../../bin/InferClang \ No newline at end of file diff --git a/infer/lib/wrappers/clang++ b/infer/lib/wrappers/clang++ new file mode 120000 index 000000000..a78cb23c5 --- /dev/null +++ b/infer/lib/wrappers/clang++ @@ -0,0 +1 @@ +../../bin/InferClang \ No newline at end of file diff --git a/infer/lib/wrappers/g++ b/infer/lib/wrappers/g++ new file mode 120000 index 000000000..a78cb23c5 --- /dev/null +++ b/infer/lib/wrappers/g++ @@ -0,0 +1 @@ +../../bin/InferClang \ No newline at end of file diff --git a/infer/lib/wrappers/gcc b/infer/lib/wrappers/gcc new file mode 120000 index 000000000..a78cb23c5 --- /dev/null +++ b/infer/lib/wrappers/gcc @@ -0,0 +1 @@ +../../bin/InferClang \ No newline at end of file diff --git a/infer/models/Makefile b/infer/models/Makefile index 3a8aec38f..2a85d6454 100644 --- a/infer/models/Makefile +++ b/infer/models/Makefile @@ -26,24 +26,24 @@ ifeq ($(BUILD_JAVA_ANALYZERS),yes) all: java endif -.PHONY: java clang clean $(CLANG_SUBDIRS) +.PHONY: java clang clean clean_specs $(CLANG_SUBDIRS) clean_specs: $(REMOVE) $(SPECS_LIB_DIR)/*.specs $(CLANG_SUBDIRS): - $(MAKE) -C $@ install + @$(MAKE) -C $@ install -clang: clean_specs - $(MAKE) $(CLANG_SUBDIRS) +clang: + @$(MAKE) $(CLANG_SUBDIRS) -java: clean_specs - $(MAKE) -C $@ install +java: + @$(MAKE) -C $@ install clean: clean_specs - $(MAKE) -C $(JAVA_MODELS_DIR) clean - $(MAKE) -C $(C_MODELS_DIR) clean - $(MAKE) -C $(CPP_MODELS_DIR) clean + @$(MAKE) -C $(JAVA_MODELS_DIR) clean + @$(MAKE) -C $(C_MODELS_DIR) clean + @$(MAKE) -C $(CPP_MODELS_DIR) clean ifneq (no, $(XCODE_SELECT)) - $(MAKE) -C $(OBJC_MODELS_DIR) clean + @$(MAKE) -C $(OBJC_MODELS_DIR) clean endif diff --git a/infer/models/c/Makefile b/infer/models/c/Makefile index bf82ab56d..e9572d21f 100644 --- a/infer/models/c/Makefile +++ b/infer/models/c/Makefile @@ -10,20 +10,24 @@ include $(ROOT_DIR)/Makefile.config C_MODELS_FILE = $(SPECS_LIB_DIR)/c_models C_MODELS_SOURCES = $(shell find src/ -name "*.c") +INFER_RESULTS = out/report.json -all: $(C_MODELS_FILE) +all: install -$(C_MODELS_FILE): $(C_MODELS_SOURCES) $(CLANG_DEPS) +$(INFER_RESULTS): $(C_MODELS_SOURCES) $(CLANG_DEPS) # make clean in src/ in case $(CLANG_DEPS) have changed - $(MAKE) -C src clean - $(INFER_BIN) -o out/ --models-mode --no-failures-allowed -- $(MAKE) -C src - touch $(C_MODELS_FILE) + @$(MAKE) -C src clean + $(INFER_BIN) -o $(@D) --models-mode --no-failures-allowed -- $(MAKE) -C src + +$(C_MODELS_FILE): $(INFER_RESULTS) + @$(INSTALL_DATA) $(dir $(INFER_RESULTS))/specs/*.specs $(SPECS_LIB_DIR) + @touch $@ install: $(C_MODELS_FILE) - $(INSTALL_DATA) -C out/specs/*.specs $(SPECS_LIB_DIR) clean: - @rm -f $(C_MODELS_FILE) - $(MAKE) -C src clean + $(REMOVE) $(C_MODELS_FILE) + $(REMOVE_DIR) $(dir $(INFER_RESULTS)) + @$(MAKE) -C src clean .PHONY: all clean install diff --git a/infer/models/cpp/Makefile b/infer/models/cpp/Makefile index bb202e0f3..93a15f1b5 100644 --- a/infer/models/cpp/Makefile +++ b/infer/models/cpp/Makefile @@ -11,20 +11,24 @@ include $(ROOT_DIR)/Makefile.config CPP_MODELS_FILE = $(SPECS_LIB_DIR)/cpp_models CPP_MODELS_SOURCES = $(shell find src/ -name "*.cpp") C_MODELS_SOURCES = $(shell find src/c_src/ -name "*.c") +INFER_RESULTS = out/report.json -all: $(CPP_MODELS_FILE) +all: install -$(CPP_MODELS_FILE): $(CPP_MODELS_SOURCES) $(C_MODELS_SOURCES) $(CLANG_DEPS) +$(INFER_RESULTS): $(CPP_MODELS_SOURCES) $(C_MODELS_SOURCES) $(CLANG_DEPS) # make clean in src/ in case $(CLANG_DEPS) have changed - $(MAKE) -C src clean - $(INFER_BIN) -o out/ --models-mode --no-failures-allowed --cxx -- $(MAKE) -C src - touch $(CPP_MODELS_FILE) + @$(MAKE) -C src clean + $(INFER_BIN) -o $(@D) --models-mode --no-failures-allowed -- $(MAKE) -C src + +$(CPP_MODELS_FILE): $(INFER_RESULTS) + @$(INSTALL_DATA) $(dir $(INFER_RESULTS))/specs/*.specs $(SPECS_LIB_DIR) + @touch $@ install: $(CPP_MODELS_FILE) - $(INSTALL_DATA) -C out/specs/*.specs $(SPECS_LIB_DIR) clean: - @rm -f $(CPP_MODELS_FILE) - $(MAKE) -C src clean + $(REMOVE) $(CPP_MODELS_FILE) + $(REMOVE_DIR) $(dir $(INFER_RESULTS)) + @$(MAKE) -C src clean .PHONY: all clean install diff --git a/infer/models/objc/Makefile b/infer/models/objc/Makefile index 52611a866..85f40c04c 100644 --- a/infer/models/objc/Makefile +++ b/infer/models/objc/Makefile @@ -10,20 +10,25 @@ include $(ROOT_DIR)/Makefile.config OBJC_MODELS_FILE = $(SPECS_LIB_DIR)/objc_models OBJC_MODELS_SOURCES = $(shell find src/ -name "*.m" -or -name "*.c") +INFER_RESULTS = out/report.json -all: $(OBJC_MODELS_FILE) +all: install -$(OBJC_MODELS_FILE): $(OBJC_MODELS_SOURCES) $(CLANG_DEPS) +$(INFER_RESULTS): $(OBJC_MODELS_SOURCES) $(CLANG_DEPS) # make clean in src/ in case $(CLANG_DEPS) have changed - $(MAKE) -C src clean - $(INFER_BIN) -o out/ --models-mode --no-failures-allowed -- $(MAKE) -C src + @$(MAKE) -C src clean + $(INFER_BIN) -o $(@D) --models-mode --no-failures-allowed -- $(MAKE) -C src touch $(OBJC_MODELS_FILE) +$(OBJC_MODELS_FILE): $(INFER_RESULTS) + @$(INSTALL_DATA) $(dir $(INFER_RESULTS))/specs/*.specs $(SPECS_LIB_DIR) + @touch $@ + install: $(OBJC_MODELS_FILE) - $(INSTALL_DATA) -C out/specs/*.specs $(SPECS_LIB_DIR) clean: - @rm -f $(OBJC_MODELS_FILE) - $(MAKE) -C src clean + $(REMOVE) $(OBJC_MODELS_FILE) + $(REMOVE_DIR) $(dir $(INFER_RESULTS)) + @$(MAKE) -C src clean .PHONY: all clean install diff --git a/infer/src/Makefile b/infer/src/Makefile index 290673538..8c7903101 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -133,7 +133,6 @@ OCAMLBUILD_ALL = $(OCAMLBUILD_BASE) $(JAVA_OCAMLBUILD_OPTIONS) # list of ocamlbuild targets common to all build targets -- native version INFER_BASE_TARGETS = \ - $(C_STUBS_OBJ) \ $(INFER_MAIN).native \ $(INFERANALYZE_MAIN).native \ $(INFERPRINT_MAIN).native \ @@ -157,15 +156,34 @@ INFER_CONFIG_TARGETS += $(INFERCLANG_MAIN).native DEPENDENCIES += clang endif +OCAML_BASE_SOURCES = \ + $(wildcard $(DEPENDENCIES:=/[a-zA-Z]*.ml) $(DEPENDENCIES:=/[a-zA-Z]*.mli) \ + $(DEPENDENCIES:=/[a-zA-Z]*.mll) $(DEPENDENCIES:=/[a-zA-Z]*.mly) \ + $(DEPENDENCIES:=/[a-zA-Z]*.re) $(DEPENDENCIES:=/[a-zA-Z]*.rei)) \ + $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) +OCAML_SOURCES = $(OCAML_BASE_SOURCES) +ifeq ($(BUILD_C_ANALYZERS),yes) +OCAML_SOURCES += $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) +endif +OCAML_ALL_SOURCES = $(OCAML_BASE_SOURCES) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) + export OCAMLFIND_IGNORE_DUPS_IN=$(shell ocamlc -where)/compiler-libs .PHONY: all all: infer -.PHONY: infer -infer: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) +# 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_SOURCES) $(OCAMLBUILD_CONFIG) -build-dir $(INFER_BUILD_DIR) $(INFER_CONFIG_TARGETS) - $(INSTALL_PROGRAM) $(INFER_BUILD_DIR)/$(INFER_MAIN).native $(INFER_BIN) +# let make know that the target is up-to-date even if ocamlbuild cached it + @touch $@ + +$(BIN_DIR): Makefile + $(MKDIR_P) $@ + @touch $@ + +$(INFER_BIN): $(INFER_BUILD_DIR)/$(INFER_MAIN).native $(BIN_DIR) $(INSTALL_PROGRAM) $(INFER_BUILD_DIR)/$(INFERANALYZE_MAIN).native $(INFERANALYZE_BIN) $(INSTALL_PROGRAM) $(INFER_BUILD_DIR)/$(INFERPRINT_MAIN).native $(INFERPRINT_BIN) $(INSTALL_PROGRAM) $(INFER_BUILD_DIR)/$(INFERUNIT_MAIN).native $(INFERUNIT_BIN) @@ -174,16 +192,22 @@ ifeq ($(BUILD_JAVA_ANALYZERS),yes) endif ifeq ($(BUILD_C_ANALYZERS),yes) $(INSTALL_PROGRAM) $(INFER_BUILD_DIR)/$(INFERCLANG_MAIN).native $(INFERCLANG_BIN) - cd $(INFER_BUILD_DIR) && $(LN_S) -f InferClang InferClang++ && cd - endif + $(INSTALL_PROGRAM) $(INFER_BUILD_DIR)/$(INFER_MAIN).native $(INFER_BIN) + +.PHONY: infer +infer: $(INFER_BIN) ifeq ($(BUILD_C_ANALYZERS),yes) -infer: $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) $(CLANG_BINIOU_DICT) +infer: $(CLANG_BINIOU_DICT) endif -.PHONY: byte -byte: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) +$(INFER_BUILD_DIR)/$(INFER_MAIN).byte: base/Version.ml $(BUILD_DIR) $(OCAML_ALL_SOURCES) $(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) $(INFER_ALL_TARGETS:.native=.byte) + @touch $@ + +.PHONY: byte +byte: $(INFER_BUILD_DIR)/$(INFER_MAIN).byte # to build only the single module (and its dependencies) with extra flags execute: # make MFLAGS= M=.cm{o,x} module @@ -193,16 +217,19 @@ M= MFLAGS= .PHONY: module -module: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) +module: base/Version.ml $(BUILD_DIR) $(OCAML_ALL_SOURCES) $(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) \ $(MFLAGS) \ $(M) -.PHONY: test_build -test_build: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) +$(TEST_BUILD_DIR)/$(INFER_MAIN).byte: base/Version.ml $(BUILD_DIR) $(OCAML_ALL_SOURCES) toplevel.mlpack $(OCAMLBUILD_ALL) -build-dir $(TEST_BUILD_DIR) \ -cflags -warn-error,$(OCAML_FATAL_WARNINGS) \ - $(INFER_ALL_TARGETS:.native=.byte) + $(INFER_ALL_TARGETS:.native=.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 @@ -243,35 +270,42 @@ mod_dep.pdf: mod_dep.dot dsort: @ocamldep.opt -sort $(inc_flags) -ml-synonym .re -mli-synonym .rei $(ml_src_files) -pp refmt $(re_src_files) -roots_grep_regex:=$(foreach root,$(roots),-e $(root)$$) -dirs_find_regex:=$(foreach dir, $(DEPENDENCIES),-path "./$(dir)/*" -o) +define to_ocaml_module +$(shell \ + echo $(basename $(1)) \ + | awk 'BEGIN { FS = "/"; OFS = "/" } ; {$$NF=toupper(substr($$NF,1,1))substr($$NF,2); print $$0}') +endef -.PHONY: toplevel -toplevel: init $(STACKTREE_ATDGEN_STUBS) $(INFERPRINT_ATDGEN_STUBS) $(CLANG_ATDGEN_STUBS) $(INFER_CLANG_FCP_MIRRORED_FILES) - # We need to pack all 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 .mlpack file with source files. Steps: - # 1. find all interesting .re and .ml files - they need to be in one of - # directories listed in $(DEPENDENCIES) - # 2. remove './' from the beginning of each line - # 3. remove extension from all files - # 4. make first letter of filename uppercase to produce valid ocaml module - # 5. filter out root modules since they run code when loading the module. - find . \( -name "*.ml" -o -name "*.mly" -o -name "*.mll" -o -name "*.re" \) \ - \( $(dirs_find_regex) -false \) \ - -not \( -path "./unit/*" -o -path "./facebook/scripts/eradicate_stats.ml" -o -name ".#*" \) \ - | cut -c 3- \ - | rev | cut -f 2- -d '.' | rev \ - | awk 'BEGIN { FS = "/"; OFS = "/" } ; {$$NF=toupper(substr($$NF,1,1))substr($$NF,2); print $$0}' \ - | grep -v $(roots_grep_regex) > toplevel.mlpack +toplevel.mlpack: base/Version.ml $(OCAML_ALL_SOURCES) +# 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. +# 1. we filter out roots because they execute code upon loading +# 2. each source file is converted to a module by capitalizing its first letter +# 3. we `echo` each module individually to avoid too long a command line +# 4. prevent race conditions by using a temp file + $(eval $@_tmp := $(shell mktemp $@.tmp.XXXX)) + $(foreach module,\ + $(filter-out $(foreach root,$(roots),%/$(root)),\ + $(foreach source,\ + $(filter-out unit/% facebook/scripts/eradicate_stats.ml,$(OCAML_ALL_SOURCES)),\ + $(call to_ocaml_module,$(source)))),\ + $(shell echo $(module) >> $($@_tmp))) + mv $($@_tmp) $@ + +$(INFER_BUILD_DIR)/toplevel.cmo: toplevel.mlpack $(BUILD_DIR) $(OCAMLBUILD_ALL) -build-dir $(INFER_BUILD_DIR) toplevel.cmo + @touch $@ + +.PHONY: toplevel +toplevel: $(INFER_BUILD_DIR)/toplevel.cmo .PHONY: checkCopyright checkCopyright: $(CHECKCOPYRIGHT_BIN) -$(CHECKCOPYRIGHT_BIN): sanitize $(BUILD_DIR) $(CHECKCOPYRIGHT_MAIN).ml - rebuild -quiet -r -j $(NCPU) -build-dir $(INFER_BUILD_DIR) -pkgs core,str -tag thread -use-ocamlfind $(CHECKCOPYRIGHT_MAIN).native - $(INSTALL_PROGRAM) $(INFER_BUILD_DIR)/$(CHECKCOPYRIGHT_MAIN).native $(CHECKCOPYRIGHT_BIN) +$(CHECKCOPYRIGHT_BIN): $(BUILD_DIR) $(CHECKCOPYRIGHT_MAIN).ml + rebuild -quiet -r -j $(NCPU) -build-dir $(BUILD_DIR)/checkCopyright -pkgs core,str -tag thread -use-ocamlfind $(CHECKCOPYRIGHT_MAIN).native + $(INSTALL_PROGRAM) $(BUILD_DIR)/checkCopyright/$(CHECKCOPYRIGHT_MAIN).native $(CHECKCOPYRIGHT_BIN) define gen_atdgen_rules # generate files using atdgen @@ -293,8 +327,8 @@ $(foreach atd_type,j t,\ $(call gen_atdgen_rules,$(INFERPRINT_ATDGEN_STUB_ATD),$(INFERPRINT_ATDGEN_STUB_BASE),$(atd_type)))) $(foreach atd_type,j t,\ - $(eval \ - $(call gen_atdgen_rules,$(STACKTREE_ATDGEN_STUB_ATD),$(STACKTREE_ATDGEN_STUB_BASE),$(atd_type)))) + $(eval \ + $(call gen_atdgen_rules,$(STACKTREE_ATDGEN_STUB_ATD),$(STACKTREE_ATDGEN_STUB_BASE),$(atd_type)))) # rebuild the artifacts of the AST files whenever they're upated in FCP $(foreach atd_type,b j t v,\ @@ -318,18 +352,8 @@ $(CLANG_BINIOU_DICT): $(CLANG_ATDGEN_STUB_ATD) | sort | uniq \ > $@ -.PHONY: init -init: sanitize version $(BUILD_DIR) - -.PHONY: sanitize -sanitize: -ifneq ($(wildcard $(BUILD_DIR)/sanitize.sh),) - $(BUILD_DIR)/sanitize.sh -endif - -.PHONY: version -version: base/Version.ml.in Makefile - TMPFILE=$$(mktemp base/Version.ml.tmp.XXXX); \ +base/Version.ml: base/Version.ml.in Makefile + TMPFILE=$$(mktemp $@.tmp.XXXX); \ INFER_GIT_COMMIT=$$(git --work-tree=$(ROOT_DIR) --git-dir=$(ROOT_DIR)/.git rev-parse --short HEAD || printf "unknown"); \ INFER_GIT_BRANCH=$$(git --work-tree=$(ROOT_DIR) --git-dir=$(ROOT_DIR)/.git rev-parse --abbrev-ref HEAD || printf "unknown"); \ sed \ @@ -340,8 +364,7 @@ version: base/Version.ml.in Makefile -e "s|@INFER_GIT_COMMIT[@]|$$INFER_GIT_COMMIT|g" \ -e "s|@INFER_GIT_BRANCH[@]|$$INFER_GIT_BRANCH|g" \ $< > "$$TMPFILE"; \ - $(INSTALL_DATA) -C "$$TMPFILE" base/Version.ml; \ - rm -f "$$TMPFILE" + mv "$$TMPFILE" $@ $(BUILD_DIR): $(MKDIR_P) $(BUILD_DIR) @@ -352,6 +375,8 @@ test_clean: .PHONY: clean clean: + $(REMOVE) $(INFER_ALL_TARGETS) + $(REMOVE) toplevel.mlpack $(REMOVE_DIR) $(BUILD_DIR) $(REMOVE) $(ETC_DIR)/clang_ast.dict $(REMOVE) base/Version.ml diff --git a/infer/tests/build_systems/clang_translation/Makefile b/infer/tests/build_systems/clang_translation/Makefile index 0aad824ca..554777af2 100644 --- a/infer/tests/build_systems/clang_translation/Makefile +++ b/infer/tests/build_systems/clang_translation/Makefile @@ -27,21 +27,25 @@ compile: clang $(CLANG_OPTIONS) $(SOURCES) capture: + $(call silent_on_success,\ $(INFER_BIN) $(INFER_OPTIONS) --project-root $(ROOT) \ --icfg-dotty-outfile $(ROOT)/main.cpp.test.dot -- \ - clang $(CLANG_OPTIONS) $(ROOT)/main.cpp + clang $(CLANG_OPTIONS) $(ROOT)/main.cpp) + $(call silent_on_success,\ $(INFER_BIN) $(INFER_OPTIONS) --project-root $(SYM_ROOT) \ --icfg-dotty-outfile $(SYM_ROOT)/main_symlink.cpp.test.dot -- \ - clang $(CLANG_OPTIONS) $(SYM_ROOT)/main.cpp + clang $(CLANG_OPTIONS) $(SYM_ROOT)/main.cpp) - cd $(ROOT) && $(INFER_BIN) $(INFER_OPTIONS) \ - --icfg-dotty-outfile main_default_root.cpp.test.dot -- \ - clang $(CLANG_OPTIONS) main.cpp + cd $(ROOT) && \ + $(call silent_on_success,\ + $(INFER_BIN) $(INFER_OPTIONS) --icfg-dotty-outfile main_default_root.cpp.test.dot -- \ + clang $(CLANG_OPTIONS) main.cpp) - cd $(SYM_ROOT) && $(INFER_BIN) $(INFER_OPTIONS) \ - --icfg-dotty-outfile main_default_symlink.cpp.test.dot -- \ - clang $(CLANG_OPTIONS) main.cpp + cd $(SYM_ROOT) && \ + $(call silent_on_success,\ + $(INFER_BIN) $(INFER_OPTIONS) --icfg-dotty-outfile main_default_symlink.cpp.test.dot -- \ + clang $(CLANG_OPTIONS) main.cpp) # test_extra needs to be separate target. Otherwise commands from test # target in common Makefile won't run diff --git a/infer/tests/codetoanalyze/c/frontend/Makefile b/infer/tests/codetoanalyze/c/frontend/Makefile index c5d1e0bcb..010499b96 100644 --- a/infer/tests/codetoanalyze/c/frontend/Makefile +++ b/infer/tests/codetoanalyze/c/frontend/Makefile @@ -19,4 +19,4 @@ compile: clang $(CLANG_OPTIONS) $(SOURCES) capture: - $(INFER_BIN) -a capture --frontend-tests --cxx --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES) + $(call silent_on_success,$(INFER_BIN) -a capture --frontend-tests --cxx --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES)) diff --git a/infer/tests/codetoanalyze/cpp/frontend/Makefile b/infer/tests/codetoanalyze/cpp/frontend/Makefile index bf9bafed4..b24e44865 100644 --- a/infer/tests/codetoanalyze/cpp/frontend/Makefile +++ b/infer/tests/codetoanalyze/cpp/frontend/Makefile @@ -20,4 +20,4 @@ compile: clang $(CLANG_OPTIONS) $(SOURCES) capture: - $(INFER_BIN) -a capture --frontend-tests --cxx --headers --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES) + $(call silent_on_success,$(INFER_BIN) -a capture --frontend-tests --cxx --headers --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES)) diff --git a/infer/tests/codetoanalyze/objc/frontend/Makefile b/infer/tests/codetoanalyze/objc/frontend/Makefile index c8893b286..3e376ec39 100644 --- a/infer/tests/codetoanalyze/objc/frontend/Makefile +++ b/infer/tests/codetoanalyze/objc/frontend/Makefile @@ -88,5 +88,5 @@ compile: clang $(CLANG_OPTIONS) -fobjc-arc $(SOURCES_ARC) capture: - $(INFER_BIN) -a capture --cxx --frontend-tests --continue --reactive --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES_NOARC) - $(INFER_BIN) -a capture --cxx --frontend-tests --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) -fobjc-arc $(SOURCES_ARC) + $(call silent_on_success,$(INFER_BIN) -a capture --cxx --frontend-tests --continue --reactive --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES_NOARC)) + $(call silent_on_success,$(INFER_BIN) -a capture --cxx --frontend-tests --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) -fobjc-arc $(SOURCES_ARC)) diff --git a/infer/tests/codetoanalyze/objcpp/frontend/Makefile b/infer/tests/codetoanalyze/objcpp/frontend/Makefile index 973ec3cb7..935ee86a6 100644 --- a/infer/tests/codetoanalyze/objcpp/frontend/Makefile +++ b/infer/tests/codetoanalyze/objcpp/frontend/Makefile @@ -24,4 +24,4 @@ compile: clang $(CLANG_OPTIONS) $(SOURCES) capture: - $(INFER_BIN) -a capture --cxx --frontend-tests --continue --reactive --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES) + $(call silent_on_success,$(INFER_BIN) -a capture --cxx --frontend-tests --continue --reactive --project-root $(TESTS_DIR) -- clang $(CLANG_OPTIONS) $(SOURCES)) diff --git a/scripts/infer_repl b/scripts/infer_repl index 9500698e2..eda3511e3 100755 --- a/scripts/infer_repl +++ b/scripts/infer_repl @@ -2,7 +2,12 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -BUILD_DIR=$SCRIPT_DIR/../infer/_build/infer +# _build/infer is first so that it takes precedence. This way if someone explicitly builds the +# toplevel (`make toplevel`) they get the expected version of infer. The _build/test toplevel is +# built during `make test` which is probably run less often, hence why it doesn't take +# precedence. Of course this cannot be perfect so caution is advised. +TOPLEVEL_INCLUDES="-I $SCRIPT_DIR/../infer/_build/infer -I $SCRIPT_DIR/../infer/_build/test" + # to build new toplevel, run `make toplevel` # -init option is used only in interactive mode # in batch mode, scripts need to import toplevel_init themselves @@ -17,4 +22,4 @@ BUILD_DIR=$SCRIPT_DIR/../infer/_build/infer if [ -z "$INFER_REPL_BINARY" ]; then INFER_REPL_BINARY="utop" fi -$INFER_REPL_BINARY -init $SCRIPT_DIR/toplevel_init -I $BUILD_DIR -I $SCRIPT_DIR $@ +$INFER_REPL_BINARY -init $SCRIPT_DIR/toplevel_init $TOPLEVEL_INCLUDES -I $SCRIPT_DIR $@