You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
6.6 KiB
202 lines
6.6 KiB
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
#
|
|
# This source code is licensed under the MIT license found in the
|
|
# LICENSE file in the root directory of this source tree.
|
|
|
|
ORIG_SHELL = $(shell echo "$$SHELL")
|
|
SHELL = bash -e -o pipefail -u
|
|
|
|
ORIG_SHELL_PATH = $(shell printf "%s" "$$PATH")
|
|
|
|
# Make infer crash a bit more often to detect issues in the way we call infer within this repo, eg,
|
|
# using deprecated options.
|
|
export INFER_STRICT_MODE=1
|
|
|
|
include $(ROOT_DIR)/Makefile.autoconf
|
|
|
|
PLATFORM = $(shell uname)
|
|
|
|
COPY = cp -f
|
|
COPY_DIR = cp -Rf
|
|
REMOVE = rm -f
|
|
REMOVE_DIR = rm -rf
|
|
|
|
ABSOLUTE_ROOT_DIR = $(shell cd $(ROOT_DIR) && pwd)
|
|
|
|
DEPENDENCIES_DIR = $(ABSOLUTE_ROOT_DIR)/dependencies
|
|
DOCKER_DIR = $(ABSOLUTE_ROOT_DIR)/docker
|
|
EXAMPLES_DIR = $(ABSOLUTE_ROOT_DIR)/examples
|
|
INFER_DIR = $(ABSOLUTE_ROOT_DIR)/infer
|
|
FCP_DIR = $(ABSOLUTE_ROOT_DIR)/facebook-clang-plugins
|
|
M4_DIR = $(ABSOLUTE_ROOT_DIR)/m4
|
|
SCRIPT_DIR = $(ABSOLUTE_ROOT_DIR)/scripts
|
|
|
|
FCP_CLANG_OCAML_DIR = $(FCP_DIR)/clang-ocaml
|
|
|
|
ANNOTATIONS_DIR = $(INFER_DIR)/annotations
|
|
BIN_DIR = $(INFER_DIR)/bin
|
|
ETC_DIR = $(INFER_DIR)/etc
|
|
LIB_DIR = $(INFER_DIR)/lib
|
|
MAN_DIR = $(INFER_DIR)/man
|
|
MODELS_DIR = $(INFER_DIR)/models
|
|
JAVA_BUILTINS_DIR = $(MODELS_DIR)/java/builtins
|
|
JAVA_MODELS_DIR = $(MODELS_DIR)/java/src
|
|
SRC_DIR = $(INFER_DIR)/src
|
|
|
|
BUILD_DIR = $(INFER_DIR)/_build
|
|
|
|
JAVA_LIB_DIR = $(LIB_DIR)/java
|
|
SPECS_LIB_DIR = $(LIB_DIR)/specs
|
|
|
|
PYTHON_DIR = $(LIB_DIR)/python
|
|
PYTHON_LIB_DIR = $(PYTHON_DIR)/inferlib
|
|
|
|
INFER_BIN = $(BIN_DIR)/infer
|
|
INFER_COMMANDS = \
|
|
infer-analyze \
|
|
infer-capture \
|
|
infer-compile \
|
|
infer-explore \
|
|
infer-report \
|
|
infer-reportdiff \
|
|
infer-run \
|
|
|
|
INFERTOP_BIN = $(BIN_DIR)/infertop.bc.exe
|
|
INFERUNIT_BIN = $(BIN_DIR)/inferunit.bc.exe
|
|
CHECKCOPYRIGHT_BIN = $(BIN_DIR)/checkCopyright
|
|
|
|
INFER_CREATE_TRACEVIEW_LINKS = InferCreateTraceViewLinks
|
|
INFER_CREATE_TRACEVIEW_LINKS_BIN = $(BIN_DIR)/$(INFER_CREATE_TRACEVIEW_LINKS)
|
|
|
|
INFER_COMMAND_MANUALS = $(INFER_COMMANDS:%=$(MAN_DIR)/man1/%.1)
|
|
INFER_COMMAND_TEXT_MANUALS = $(INFER_COMMANDS:%=$(MAN_DIR)/man1/%.txt)
|
|
INFER_MANUAL = $(MAN_DIR)/man1/infer.1
|
|
INFER_GROFF_MANUALS = $(INFER_COMMAND_MANUALS) $(INFER_MANUAL)
|
|
INFER_GROFF_MANUALS_GZIPPED = $(INFER_GROFF_MANUALS:=.gz)
|
|
INFER_TEXT_MANUAL = $(MAN_DIR)/man1/infer.txt
|
|
INFER_FULL_TEXT_MANUAL = $(MAN_DIR)/man1/infer-full.txt
|
|
INFER_TEXT_MANUALS = $(INFER_COMMAND_TEXT_MANUALS) $(INFER_TEXT_MANUAL) $(INFER_FULL_TEXT_MANUAL)
|
|
INFER_MANUALS = $(INFER_GROFF_MANUALS) $(INFER_TEXT_MANUALS)
|
|
|
|
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
|
|
JAVA_HOME=$(USER_JAVA_HOME)
|
|
endif
|
|
|
|
ANDROID_JAR = $(LIB_DIR)/java/android/android-23.jar
|
|
GUAVA_JAR = $(DEPENDENCIES_DIR)/java/guava/guava-23.0.jar
|
|
INFER_ANNOTATIONS_JAR = $(ANNOTATIONS_DIR)/annotations.jar
|
|
JACKSON_JAR = $(DEPENDENCIES_DIR)/java/jackson/jackson-2.2.3.jar
|
|
JSR_305_JAR = $(DEPENDENCIES_DIR)/java/jsr-305/jsr305.jar
|
|
|
|
JAVA_MODELS_JAR = $(LIB_DIR)/java/models.jar
|
|
|
|
JAVA_DEPS_NO_MODELS = \
|
|
$(addprefix $(PYTHON_LIB_DIR)/, config.py issues.py source.py utils.py) \
|
|
$(ANDROID_JAR) $(GUAVA_JAR) $(JACKSON_JAR) $(JSR_305_JAR) $(INFER_ANNOTATIONS_JAR) \
|
|
$(INFER_BIN)
|
|
|
|
JAVA_DEPS = $(JAVA_DEPS_NO_MODELS) $(JAVA_MODELS_JAR)
|
|
|
|
# marker to keep track of when clang models have been rebuilt
|
|
MODELS_RESULTS_FILE = $(SPECS_LIB_DIR)/clang_models
|
|
|
|
CLANG_DEPS_NO_MODELS = \
|
|
$(addprefix $(PYTHON_LIB_DIR)/, \
|
|
config.py issues.py source.py utils.py) \
|
|
$(INFER_BIN)
|
|
|
|
CLANG_DEPS = $(CLANG_DEPS_NO_MODELS) $(MODELS_RESULTS_FILE)
|
|
|
|
ifeq ($(HAS_OBJC),yes)
|
|
XCODE_ISYSROOT = $(XCODE_BASE)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
|
|
endif
|
|
|
|
define copy_or_same_file
|
|
$(COPY) "$(1)" "$(2)" || diff -q "$(1)" "$(2)"
|
|
endef
|
|
|
|
INTERACTIVE = $(shell [ -t 0 ] && echo 1)
|
|
SILENT = $(findstring s,$(filter-out -%,$(firstword $(MAKEFLAGS))))
|
|
|
|
ifeq (1,$(INTERACTIVE))
|
|
TERM_ERROR = $(shell printf '\e[31;1m')
|
|
TERM_INFO = $(shell printf '\e[;1m')
|
|
TERM_SUCCESS = $(shell printf '\e[;2m')
|
|
TERM_RESET = $(shell printf '\e[0m')
|
|
endif
|
|
|
|
ifneq ($(VERBOSE),1)
|
|
# quiet
|
|
QUIET = @
|
|
endif
|
|
|
|
MAKE := $(MAKE) INTERACTIVE=$(INTERACTIVE)
|
|
|
|
# 99999 PIDs ought to be enough for anybody, but check if pid_max can be found just in case
|
|
MAX_PID_SIZE = \
|
|
$(shell PID_MAX=$$(cat /proc/sys/kernel/pid_max 2>/dev/null); echo $${\#PID_MAX} || echo 5)
|
|
|
|
# Arguments:
|
|
# $(1) is a string describing the command
|
|
# $(2) is the command to run
|
|
#
|
|
ifeq ($(VERBOSE),1)
|
|
define silent_on_success
|
|
$(2)
|
|
endef
|
|
else
|
|
# Run and time the command and redirect its stdout and stderr to files. Display info about the
|
|
# command only in case of error. Try to be as helpful as possible in the error case.
|
|
#
|
|
# The PID of the process is used in the names of the output files, and as a prefix for each error
|
|
# message so that it's possible to piece error messages together even when they are interleaved with
|
|
# other messages from concurrent `make` processes.
|
|
#
|
|
# Detect if we are already wrapped inside a silent_on_success call and try not to clutter the output
|
|
# too much in that case.
|
|
define silent_on_success
|
|
if [ -n "$${INSIDE_SILENT_ON_SUCCESS-}" ]; then \
|
|
echo '*** inner $(1)'; \
|
|
echo '*** inner command: $(2)'; \
|
|
echo '*** inner CWD: $(CURDIR)'; \
|
|
($(2)); \
|
|
exit $$?; \
|
|
fi; \
|
|
export INSIDE_SILENT_ON_SUCCESS=1; \
|
|
HASH="$$$$"; \
|
|
UNIX_START_DATE=$$(date +"%s"); \
|
|
HUMAN_START_DATE=$$(date +"%H:%M:%S"); \
|
|
if [ -z $(SILENT) ]; then \
|
|
printf '[%s][%$(MAX_PID_SIZE)s] $(TERM_INFO)%s...$(TERM_RESET)\n' \
|
|
"$$HUMAN_START_DATE" "$$HASH" "$(1)"; \
|
|
fi; \
|
|
$(MKDIR_P) $(ABSOLUTE_ROOT_DIR)/_build_logs; \
|
|
ERRCODE=0; \
|
|
($(2)) 1>$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.out \
|
|
2>$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.err \
|
|
|| ERRCODE=$$?; \
|
|
if [ $$ERRCODE != 0 ]; then \
|
|
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** ERROR '$(1)'$(TERM_RESET)" >&2; \
|
|
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** command: '$(2)'$(TERM_RESET)" >&2; \
|
|
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** CWD: '$(CURDIR)'$(TERM_RESET)" >&2; \
|
|
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** stdout:$(TERM_RESET)" >&2; \
|
|
sed -e "s/^\(.*\)$$/$(TERM_ERROR)[*ERROR**][$$HASH]$(TERM_RESET) \1/" \
|
|
$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.out; >&2; \
|
|
echo "$(TERM_ERROR)[*ERROR**][$$HASH] *** stderr:$(TERM_RESET)" >&2; \
|
|
sed -e "s/^\(.*\)$$/$(TERM_ERROR)[*ERROR**][$$HASH]$(TERM_RESET) \1/" \
|
|
$(ABSOLUTE_ROOT_DIR)/_build_logs/cmd-$$HASH.err; >&2; \
|
|
exit $$ERRCODE; \
|
|
elif [ -z $(SILENT) ]; then \
|
|
UNIX_END_DATE=$$(date +"%s"); \
|
|
printf '[%7ss][%$(MAX_PID_SIZE)s] $(TERM_SUCCESS)SUCCESS %s$(TERM_RESET)\n' \
|
|
"$$(($$UNIX_END_DATE - $$UNIX_START_DATE))" "$$HASH" "$(1)"; \
|
|
fi
|
|
endef
|
|
endif
|
|
|
|
# print any variable for Makefile debugging
|
|
print-%:
|
|
$(QUIET)echo '$*=$($*)'
|
|
|
|
TESTLOCK = $(INFER_DIR)/tests/testlock.py
|