diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d55b7637b..4f0f2f31e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,18 +21,12 @@ We welcome contributions via [pull requests on GitHub](https://github.com/facebo ### Development Dependencies -You'll want to install a few more dependencies to comfortably hack on the infer codebase. Using -opam: +You'll want to install a few more dependencies to comfortably hack on the infer codebase. Simply +run: ```sh -opam install ocp-indent merlin tuareg +make devsetup ``` -[Merlin](https://github.com/ocaml/merlin) provides OCaml and Reason support for several editors, -including [Atom](https://atom.io/), [Emacs](https://www.gnu.org/software/emacs/), and -[Vim](http://www.vim.org/). - -Run `opam user-setup install` to set up your terminal and editors to use this tooling. - ### Tips and Tricks - Build the code: `make -j`. diff --git a/Makefile b/Makefile index 2f54bd310..5be462749 100644 --- a/Makefile +++ b/Makefile @@ -540,6 +540,58 @@ opam.lock: opam $(QUIET)$(call silent_on_success,generating opam.lock,\ $(OPAM) lock --pkg $(INFER_PKG_OPAMLOCK) > opam.lock) +OPAM_DEV_DEPS = ocp-indent merlin tuareg + +.PHONY: devsetup +devsetup: Makefile.autoconf + $(QUIET)[ $(OPAM) != "no" ] || (echo 'No `opam` found, aborting setup.' >&2; exit 1) + $(QUIET)$(call silent_on_success,installing $(OPAM_DEV_DEPS),\ + OPAMSWITCH=$(OPAMSWITCH); $(OPAM) install --yes --no-checksum user-setup $(OPAM_DEV_DEPS)) + $(QUIET)echo '$(TERM_INFO)*** Running `opam config setup -a`$(TERM_RESET)' >&2 + $(QUIET)OPAMSWITCH=$(OPAMSWITCH); $(OPAM) config --yes setup -a + $(QUIET)echo '$(TERM_INFO)*** Running `opam user-setup`$(TERM_RESET)' >&2 + $(QUIET)OPAMSWITCH=$(OPAMSWITCH); OPAMYES=1; $(OPAM) user-setup install +# expand all occurrences of "~" in PATH and MANPATH + $(QUIET)infer_repo_is_in_path=$$(echo $${PATH//\~/$$HOME} | grep -q "$(ABSOLUTE_ROOT_DIR)"/infer/bin; echo $$?); \ + infer_repo_is_in_manpath=$$(echo $${MANPATH//\~/$$HOME} | grep -q "$(ABSOLUTE_ROOT_DIR)"/infer/man; echo $$?); \ + if [ "$$infer_repo_is_in_path" != "0" ] || [ "$$infer_repo_is_in_manpath" != "0" ]; then \ + shell_config_file=""; \ + if [ $$(basename "$(ORIG_SHELL)") = "bash" ]; then \ + if [ "$(PLATFORM)" = "Linux" ]; then \ + shell_config_file="$$HOME"/.bashrc; \ + else \ + shell_config_file="$$HOME"/.bash_profile; \ + fi; \ + elif [ $$(basename "$(ORIG_SHELL)") = "zsh" ]; then \ + shell_config_file="$$HOME"/.zshrc; \ + fi; \ + echo >&2; \ + echo '$(TERM_INFO)*** NOTE: `infer` is not in your PATH or MANPATH. If you are hacking on infer, you may$(TERM_RESET)' >&2; \ + echo '$(TERM_INFO)*** NOTE: want to make infer executables and manuals available in your terminal. Type$(TERM_RESET)' >&2; \ + echo '$(TERM_INFO)*** NOTE: the following commands to configure the current terminal and record the$(TERM_RESET)' >&2; \ + printf '$(TERM_INFO)*** NOTE: changes in your shell configuration file (%s):$(TERM_RESET)\n' "$$shell_config_file">&2; \ + echo >&2; \ + if [ "$$infer_repo_is_in_path" != "0" ]; then \ + printf '$(TERM_INFO) export PATH="%s/infer/bin":$$PATH$(TERM_RESET)\n' "$(ABSOLUTE_ROOT_DIR)" >&2; \ + fi; \ + if [ "$$infer_repo_is_in_manpath" != "0" ]; then \ + printf '$(TERM_INFO) export MANPATH="%s/infer/man":$$MANPATH$(TERM_RESET)\n' "$(ABSOLUTE_ROOT_DIR)" >&2; \ + fi; \ + if [ "$$infer_repo_is_in_path" != "0" ]; then \ + printf "$(TERM_INFO) echo 'export PATH=\"%s/infer/bin\":\$$PATH' >> \"$$shell_config_file\"\n" "$(ABSOLUTE_ROOT_DIR)" >&2; \ + fi; \ + if [ "$$infer_repo_is_in_manpath" != "0" ]; then \ + printf "$(TERM_INFO) echo 'export MANPATH=\"%s/infer/man\":\$$MANPATH' >> \"$$shell_config_file\"\n" "$(ABSOLUTE_ROOT_DIR)" >&2; \ + fi; \ + fi + $(QUIET)PATH=$(ORIG_SHELL_PATH); if [ "$$(ocamlc -where 2>/dev/null)" != "$$($(OCAMLC) -where)" ]; then \ + echo >&2; \ + echo '$(TERM_INFO)*** NOTE: The current shell is not set up for the right opam switch.$(TERM_RESET)' >&2; \ + echo '$(TERM_INFO)*** NOTE: Please run:$(TERM_RESET)' >&2; \ + echo >&2; \ + echo '$(TERM_INFO) eval $$(opam config env)$(TERM_RESET)' >&2; \ + fi + # print any variable for Makefile debugging print-%: $(QUIET)echo '$*=$($*)' diff --git a/Makefile.config b/Makefile.config index cb666908a..6dc626b15 100644 --- a/Makefile.config +++ b/Makefile.config @@ -5,8 +5,11 @@ # LICENSE file in the root directory of this source tree. An additional grant # of patent rights can be found in the PATENTS file in the same directory. +ORIG_SHELL = $(shell echo "$$SHELL") SHELL = bash +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 diff --git a/build-infer.sh b/build-infer.sh index 7b3576ad1..c646ce036 100755 --- a/build-infer.sh +++ b/build-infer.sh @@ -31,9 +31,9 @@ function usage() { echo echo " options:" echo " -h,--help show this message" + echo " --no-opam-lock do not use the opam.lock file and let opam resolve dependencies" echo " --only-setup-opam initialize opam, install the opam dependencies of infer, and exit" echo " --opam-switch specify the opam switch where to install infer (default: $INFER_OPAM_SWITCH_DEFAULT)" - echo " --no-opam-lock do not use the opam.lock file and let opam resolve dependencies" echo " -y,--yes automatically agree to everything" echo echo " examples:" @@ -125,6 +125,14 @@ check_installed () { fi } +opam_failed () { + command=$1 + echo + echo "*** ERROR: $command failed" >&2 + echo "*** ERROR: Try running `opam update` then try this script again" >&2 + exit 1 +} + setup_opam () { opam init --compiler=$OCAML_VERSION -j $NCPU --no-setup opam switch set -j $NCPU $INFER_OPAM_SWITCH --alias-of $OCAML_VERSION @@ -168,17 +176,11 @@ install_opam_deps() { echo "initializing opam... " >&2 check_installed opam -setup_opam +setup_opam || opam_failed 'opam setup' eval $(SHELL=bash opam config env --switch=$INFER_OPAM_SWITCH) echo >&2 echo "installing infer dependencies; this can take up to 30 minutes... " >&2 -install_opam_deps || ( \ - echo >&2; \ - echo '*** Failed to install opam dependencies' >&2; \ - echo '*** Updating opam then retrying' >&2; \ - opam update && \ - install_opam_deps \ -) +install_opam_deps || opam_failed 'installing opam dependencies' if [ "$ONLY_SETUP_OPAM" = "yes" ]; then exit 0 @@ -241,3 +243,9 @@ make -j $NCPU all || ( echo " $0 $ORIG_ARGS" >&2 echo >&2 exit 1) + +echo +echo "*** Success! Infer is now built in '$SCRIPT_PATH/infer/bin/'." +echo '*** Install infer on your system with `make install`.' +echo +echo '*** If you plan to hack on infer, check out CONTRIBUTING.md to setup your dev environment.' diff --git a/configure.ac b/configure.ac index d795a0601..293d5689a 100644 --- a/configure.ac +++ b/configure.ac @@ -202,7 +202,8 @@ AS_IF([test "$OPAM" != "no"], [ AC_MSG_CHECKING([current opam switch]) OPAMSWITCH=$("$OPAM" switch show) AC_MSG_RESULT([$OPAMSWITCH]) -]) +], [OPAMSWITCH=no]) +AC_SUBST([OPAMSWITCH]) if test "x$enable_java_analyzers" = "xyes"; then AC_CHECK_TOOL([JAVA], [java], [no])