[base] resolve links when guessing which executable we are running, move infer into bin/

Summary:
There's no reason for infer to be in lib/ anymore, move it to the same place as
the other binaries. Thus all binaries are in the same directory and Config.ml
can better know where things are.

Reviewed By: jberdine

Differential Revision: D4015958

fbshipit-source-id: c5e851f
master
Jules Villard 8 years ago committed by Facebook Github Bot
parent 31230299ea
commit 343556e0b2

1
.gitignore vendored

@ -71,7 +71,6 @@ buck-out/
/infer/bin/InferUnit
/infer/bin/Typeprop
/infer/bin/infer
/infer/lib/infer
/infer/bin/inferTraceBugs
/infer/src/base/Version.ml
/infer/models/java/models/

@ -29,11 +29,6 @@ endif
all: infer inferTraceBugs
$(INFER_BIN_SYMLINK):
($(REMOVE) $@ && \
cd $(@D) && \
$(LN_S) ../lib/$(@F) $(@F))
$(INFERTRACEBUGS_BIN_RELPATH):
($(REMOVE) $@ && \
cd $(@D) && \
@ -48,7 +43,7 @@ ifeq ($(BUILD_C_ANALYZERS),yes)
src_build: clang_plugin
endif
infer: $(INFER_BIN_SYMLINK) src_build
infer: src_build
ifeq ($(BUILD_JAVA_ANALYZERS),yes)
$(MAKE) -C $(ANNOTATIONS_DIR)
endif
@ -303,16 +298,13 @@ endif
$(DESTDIR)$(libdir)/infer/infer/lib/python/infer.py
$(INSTALL_PROGRAM) -C infer/lib/python/inferTraceBugs \
$(DESTDIR)$(libdir)/infer/infer/lib/python/inferTraceBugs
$(INSTALL_PROGRAM) -C $(INFER_BIN) $(DESTDIR)$(libdir)/infer/infer/lib/
$(INSTALL_PROGRAM) -C $(INFER_BIN) $(DESTDIR)$(libdir)/infer/infer/bin/
$(INSTALL_PROGRAM) -C $(INFERANALYZE_BIN) $(DESTDIR)$(libdir)/infer/infer/bin/
$(INSTALL_PROGRAM) -C $(INFERPRINT_BIN) $(DESTDIR)$(libdir)/infer/infer/bin/
$(INSTALL_PROGRAM) -C $(INFERSTATS_BIN) $(DESTDIR)$(libdir)/infer/infer/bin/
(cd $(DESTDIR)$(libdir)/infer/infer/bin/ && \
$(REMOVE) infer && \
$(LN_S) $(libdir)/infer/infer/lib/infer infer)
(cd $(DESTDIR)$(bindir)/ && \
$(REMOVE) infer && \
$(LN_S) $(libdir)/infer/infer/lib/infer infer)
$(LN_S) $(libdir)/infer/infer/bin/infer infer)
(cd $(DESTDIR)$(bindir)/ && \
$(REMOVE) inferTraceBugs && \
$(LN_S) $(libdir)/infer/infer/lib/python/inferTraceBugs inferTraceBugs)
@ -332,7 +324,7 @@ endif
$(MAKE) -C $(SRC_DIR) clean
$(MAKE) -C $(ANNOTATIONS_DIR) clean
$(MAKE) -C $(MODELS_DIR) clean
$(REMOVE) $(INFER_BIN_SYMLINK) $(INFERTRACEBUGS_BIN_RELPATH)
$(REMOVE) $(INFERTRACEBUGS_BIN_RELPATH)
ifeq ($(IS_FACEBOOK_TREE),yes)
$(MAKE) -C facebook clean
endif

@ -99,10 +99,8 @@ INFERSTATS_BIN = $(BIN_DIR)/InferStatsAggregator
INFERPRINT_BIN = $(BIN_DIR)/InferPrint
INFERUNIT_BIN = $(BIN_DIR)/InferUnit
INFER_BUCK_COMPILATION_DATABASE_BIN = $(BIN_DIR)/InferBuckCompilationDatabase
INFER_BIN = $(LIB_DIR)/infer
INFER_BIN = $(BIN_DIR)/infer
INFERTRACEBUGS_BIN = $(BIN_DIR)/inferTraceBugs
# paths relative to $(ROOT_DIR)
INFER_BIN_SYMLINK = infer/bin/infer
INFERTRACEBUGS_BIN_RELPATH = infer/bin/inferTraceBugs
ifeq ($(BUILD_JAVA_ANALYZERS),yes)

@ -29,26 +29,7 @@ let fail_on_issue_epilogue () =
let () =
set_env_for_clang_wrapper () ;
(* The infer executable in the bin directory is a symbolic link to the real binary in the lib
directory, so that the python script in the lib directory can be found relative to
it. Packaging may also create longer symlink chains to the real executable, hence the
recursion. *)
let real_exe =
let rec real_path path =
match Unix.readlink path with
| link when Filename.is_relative link ->
(* [path] is a relative symbolic link *)
real_path ((Filename.dirname path) // link)
| link ->
(* [path] is an absolute symbolic link *)
real_path link
| exception Unix.Unix_error(Unix.EINVAL, _, _) ->
(* [path] is not a symbolic link *)
path
in
real_path Sys.executable_name
in
let infer_py = (Filename.dirname real_exe) // "python" // "infer.py" in
let infer_py = Config.lib_dir // "python" // "infer.py" in
let build_cmd = IList.rev Config.rest in
let in_buck_mode = match build_cmd with "buck" :: _ -> true | _ -> false in
let args_py =

@ -21,6 +21,7 @@ type exe = Analyze | BuckCompilationDatabase | Clang | Interactive | Java | Prin
| Toplevel
(** Association list of executable (base)names to their [exe]s. *)
let exes = [
("InferBuckCompilationDatabase", BuckCompilationDatabase);
("InferAnalyze", Analyze);
@ -32,16 +33,8 @@ let exes = [
("interactive", Interactive);
]
let all_exes = IList.map snd exes
let frontend_exes = [Clang; Java]
let current_exe =
if !Sys.interactive then Interactive
else
try IList.assoc string_equal (Filename.basename Sys.executable_name) exes
with Not_found -> Toplevel
type desc = {
long: string; short: string; meta: string; doc: string; spec: Arg.spec;
(** how to go from an option in the json config file to a list of command-line options *)
@ -418,7 +411,7 @@ let mk_rest ?(exes=[]) doc =
add exes {long = "--"; short = ""; meta = ""; doc; spec; decode_json = fun _ -> []} ;
rest
let decode_inferconfig_to_argv path =
let decode_inferconfig_to_argv current_exe path =
let json = match read_optional_json_file path with
| Ok json ->
json
@ -474,7 +467,7 @@ let prefix_before_rest args =
prefix_before_rest_ [] args
let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file env_var exe_usage =
let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file env_var current_exe exe_usage =
let curr_speclist = ref []
and full_speclist = ref []
in
@ -585,7 +578,7 @@ let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file env_var exe_u
let all_args = match config_file with
| None -> env_cl_args
| Some path ->
let json_args = decode_inferconfig_to_argv path in
let json_args = decode_inferconfig_to_argv current_exe path in
(* read .inferconfig first, as both env vars and command-line options overwrite it *)
json_args @ env_cl_args in
args_to_parse := Array.of_list (exe_name :: all_args);

@ -14,9 +14,8 @@ open! Utils
type exe = Analyze | BuckCompilationDatabase | Clang | Interactive | Java | Print | StatsAggregator
| Toplevel
val current_exe : exe
val all_exes : exe list
(** Association list of executable (base)names to their [exe]s. *)
val exes : (string * exe) list
val frontend_exes: exe list
@ -104,15 +103,16 @@ val mk_rest :
?exes:exe list -> string ->
string list ref
(** [parse env_var exe_usage] parses command line arguments as specified by preceding calls to the
[mk_*] functions, and returns a function that prints the usage message and help text then exits.
The decoded values of the inferconfig file [config_file], if provided, and of the environment
variable [env_var] are prepended to [Sys.argv] before parsing. Therefore arguments passed on
the command line supersede those specified in the environment variable, which themselves
supersede those passed via the config file. WARNING: An argument will be interpreted as many
times as it appears in all of the config file, the environment variable, and the command
line. The [env_var] is set to the full set of options parsed. If [incomplete] is set, unknown
options are ignored, and [env_var] is not set. If [accept_unknown] is set, unknown options are
treated the same as anonymous arguments. *)
(** [parse env_var exe_usage exe] parses command line arguments as specified by preceding calls to
the [mk_*] functions, and returns a function that prints the usage message and help text then
exits. [exe] is used to construct the help message appropriate for that executable. The decoded
values of the inferconfig file [config_file], if provided, and of the environment variable
[env_var] are prepended to [Sys.argv] before parsing. Therefore arguments passed on the command
line supersede those specified in the environment variable, which themselves supersede those
passed via the config file. WARNING: An argument will be interpreted as many times as it
appears in all of the config file, the environment variable, and the command line. The [env_var]
is set to the full set of options parsed. If [incomplete] is set, unknown options are ignored,
and [env_var] is not set. If [accept_unknown] is set, unknown options are treated the same as
anonymous arguments. *)
val parse : ?incomplete:bool -> ?accept_unknown:bool -> ?config_file:string ->
string -> (exe -> Arg.usage_msg) -> (int -> 'a)
string -> exe -> (exe -> Arg.usage_msg) -> (int -> 'a)

@ -239,8 +239,33 @@ let version_string =
Unix.time *)
let initial_analysis_time = Unix.time ()
(* Resolve symlinks to get to the real executable. The real executable is located in [bin_dir]
below, which allows us to find [lib_dir], [models_dir], etc., relative to it. *)
let real_exe_name =
(* Recursively resolve symlinks until we get something that is not a link. Executables may be
(multiple levels of) symbolic links to the real binary directory, eg after `make install` or
packaging. *)
let rec real_path path =
match Unix.readlink path with
| link when Filename.is_relative link ->
(* [path] is a relative symbolic link *)
real_path ((Filename.dirname path) // link)
| link ->
(* [path] is an absolute symbolic link *)
real_path link
| exception Unix.Unix_error(Unix.EINVAL, _, _) ->
(* [path] is not a symbolic link *)
path in
real_path Sys.executable_name
let current_exe =
if !Sys.interactive then CLOpt.Interactive
else try IList.assoc string_equal (Filename.basename real_exe_name) CLOpt.exes
with Not_found -> CLOpt.Toplevel
let bin_dir =
Filename.dirname Sys.executable_name
Filename.dirname real_exe_name
let lib_dir =
bin_dir // Filename.parent_dir_name // "lib"
@ -407,8 +432,9 @@ let resolve path =
(* Declare the phase 1 options *)
let inferconfig_home =
let all_exes = IList.map snd CLOpt.exes in
CLOpt.mk_string_opt ~deprecated:["inferconfig_home"] ~long:"inferconfig-home"
~exes:CLOpt.all_exes ~meta:"dir" "Path to the .inferconfig file"
~exes:all_exes ~meta:"dir" "Path to the .inferconfig file"
and project_root =
CLOpt.mk_string_opt ~deprecated:["project_root"; "-project_root"] ~long:"project-root" ~short:"pr"
@ -420,7 +446,7 @@ and project_root =
(* Parse the phase 1 options, ignoring the rest *)
let _ = CLOpt.parse ~incomplete:true "INFER_ARGS" (fun _ -> "")
let _ = CLOpt.parse ~incomplete:true "INFER_ARGS" current_exe (fun _ -> "")
(* Define the values that depend on phase 1 options *)
@ -691,7 +717,7 @@ and cxx_experimental =
and debug, print_types, write_dotty =
let print_types =
CLOpt.mk_bool ~deprecated:["print_types"] ~long:"print-types"
~default:(CLOpt.current_exe = CLOpt.Clang)
~default:(current_exe = CLOpt.Clang)
"Print types in symbolic heaps"
and write_dotty =
CLOpt.mk_bool ~deprecated:["dotty"] ~long:"write-dotty"
@ -717,7 +743,7 @@ and dependencies =
and developer_mode =
CLOpt.mk_bool ~deprecated:["developer_mode"] ~long:"developer-mode"
~default:(CLOpt.current_exe = CLOpt.Print)
~default:(current_exe = CLOpt.Print)
"Show internal exceptions"
and disable_checks =
@ -1351,7 +1377,8 @@ let post_parsing_initialization () =
let parse_args_and_return_usage_exit =
let usage_exit =
CLOpt.parse ~accept_unknown:true ~config_file:inferconfig_path "INFER_ARGS" exe_usage in
CLOpt.parse ~accept_unknown:true ~config_file:inferconfig_path
"INFER_ARGS" current_exe exe_usage in
post_parsing_initialization () ;
usage_exit

@ -67,10 +67,10 @@ val buck_generated_folder : string
val buck_infer_deps_file_name : string
val captured_dir_name : string
val checks_disabled_by_default : string list
val report_condition_always_true_in_clang : bool
val clang_build_output_dir_name : string
val cpp_models_dir : string
val csl_analysis : bool
val current_exe : CommandLineOption.exe
val default_failure_name : string
val default_in_zip_results_dir : string
val dotty_output : string
@ -108,6 +108,7 @@ val patterns_suppress_warnings : pattern list
val perf_stats_prefix : string
val proc_stats_filename : string
val property_attributes : string
val report_condition_always_true_in_clang : bool
val report_nullable_inconsistency : bool
val reporting_stats_dir_name : string
val save_compact_summaries : bool

@ -17,7 +17,7 @@ module F = Format
(** Name of dir for logging the output in the specific executable *)
let log_dir_of_current_exe =
match CommandLineOption.current_exe with
match Config.current_exe with
| Analyze -> "analyze"
| BuckCompilationDatabase -> "buck_compilation_database"
| Clang -> "clang"
@ -37,7 +37,7 @@ let err_formatter = ref F.err_formatter
let set_log_file_identifier string_opt =
let should_setup_log_files =
match CommandLineOption.current_exe with
match Config.current_exe with
| Analyze
| Clang -> Config.debug_mode || Config.stats_mode
| BuckCompilationDatabase -> true

Loading…
Cancel
Save