[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/InferUnit
/infer/bin/Typeprop /infer/bin/Typeprop
/infer/bin/infer /infer/bin/infer
/infer/lib/infer
/infer/bin/inferTraceBugs /infer/bin/inferTraceBugs
/infer/src/base/Version.ml /infer/src/base/Version.ml
/infer/models/java/models/ /infer/models/java/models/

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

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

@ -29,26 +29,7 @@ let fail_on_issue_epilogue () =
let () = let () =
set_env_for_clang_wrapper () ; set_env_for_clang_wrapper () ;
(* The infer executable in the bin directory is a symbolic link to the real binary in the lib let infer_py = Config.lib_dir // "python" // "infer.py" in
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 build_cmd = IList.rev Config.rest in let build_cmd = IList.rev Config.rest in
let in_buck_mode = match build_cmd with "buck" :: _ -> true | _ -> false in let in_buck_mode = match build_cmd with "buck" :: _ -> true | _ -> false in
let args_py = let args_py =

@ -21,6 +21,7 @@ type exe = Analyze | BuckCompilationDatabase | Clang | Interactive | Java | Prin
| Toplevel | Toplevel
(** Association list of executable (base)names to their [exe]s. *)
let exes = [ let exes = [
("InferBuckCompilationDatabase", BuckCompilationDatabase); ("InferBuckCompilationDatabase", BuckCompilationDatabase);
("InferAnalyze", Analyze); ("InferAnalyze", Analyze);
@ -32,16 +33,8 @@ let exes = [
("interactive", Interactive); ("interactive", Interactive);
] ]
let all_exes = IList.map snd exes
let frontend_exes = [Clang; Java] 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 = { type desc = {
long: string; short: string; meta: string; doc: string; spec: Arg.spec; 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 *) (** 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 _ -> []} ; add exes {long = "--"; short = ""; meta = ""; doc; spec; decode_json = fun _ -> []} ;
rest rest
let decode_inferconfig_to_argv path = let decode_inferconfig_to_argv current_exe path =
let json = match read_optional_json_file path with let json = match read_optional_json_file path with
| Ok json -> | Ok json ->
json json
@ -474,7 +467,7 @@ let prefix_before_rest args =
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 [] let curr_speclist = ref []
and full_speclist = ref [] and full_speclist = ref []
in 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 let all_args = match config_file with
| None -> env_cl_args | None -> env_cl_args
| Some path -> | 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 *) (* read .inferconfig first, as both env vars and command-line options overwrite it *)
json_args @ env_cl_args in json_args @ env_cl_args in
args_to_parse := Array.of_list (exe_name :: all_args); 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 type exe = Analyze | BuckCompilationDatabase | Clang | Interactive | Java | Print | StatsAggregator
| Toplevel | Toplevel
val current_exe : exe (** Association list of executable (base)names to their [exe]s. *)
val exes : (string * exe) list
val all_exes : exe list
val frontend_exes: exe list val frontend_exes: exe list
@ -104,15 +103,16 @@ val mk_rest :
?exes:exe list -> string -> ?exes:exe list -> string ->
string list ref string list ref
(** [parse env_var exe_usage] parses command line arguments as specified by preceding calls to the (** [parse env_var exe_usage exe] parses command line arguments as specified by preceding calls to
[mk_*] functions, and returns a function that prints the usage message and help text then exits. the [mk_*] functions, and returns a function that prints the usage message and help text then
The decoded values of the inferconfig file [config_file], if provided, and of the environment exits. [exe] is used to construct the help message appropriate for that executable. The decoded
variable [env_var] are prepended to [Sys.argv] before parsing. Therefore arguments passed on values of the inferconfig file [config_file], if provided, and of the environment variable
the command line supersede those specified in the environment variable, which themselves [env_var] are prepended to [Sys.argv] before parsing. Therefore arguments passed on the command
supersede those passed via the config file. WARNING: An argument will be interpreted as many line supersede those specified in the environment variable, which themselves supersede those
times as it appears in all of the config file, the environment variable, and the command passed via the config file. WARNING: An argument will be interpreted as many times as it
line. The [env_var] is set to the full set of options parsed. If [incomplete] is set, unknown appears in all of the config file, the environment variable, and the command line. The [env_var]
options are ignored, and [env_var] is not set. If [accept_unknown] is set, unknown options are is set to the full set of options parsed. If [incomplete] is set, unknown options are ignored,
treated the same as anonymous arguments. *) 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 -> 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 *) Unix.time *)
let initial_analysis_time = 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 = let bin_dir =
Filename.dirname Sys.executable_name Filename.dirname real_exe_name
let lib_dir = let lib_dir =
bin_dir // Filename.parent_dir_name // "lib" bin_dir // Filename.parent_dir_name // "lib"
@ -407,8 +432,9 @@ let resolve path =
(* Declare the phase 1 options *) (* Declare the phase 1 options *)
let inferconfig_home = let inferconfig_home =
let all_exes = IList.map snd CLOpt.exes in
CLOpt.mk_string_opt ~deprecated:["inferconfig_home"] ~long:"inferconfig-home" 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 = and project_root =
CLOpt.mk_string_opt ~deprecated:["project_root"; "-project_root"] ~long:"project-root" ~short:"pr" 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 *) (* 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 *) (* Define the values that depend on phase 1 options *)
@ -691,7 +717,7 @@ and cxx_experimental =
and debug, print_types, write_dotty = and debug, print_types, write_dotty =
let print_types = let print_types =
CLOpt.mk_bool ~deprecated:["print_types"] ~long:"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" "Print types in symbolic heaps"
and write_dotty = and write_dotty =
CLOpt.mk_bool ~deprecated:["dotty"] ~long:"write-dotty" CLOpt.mk_bool ~deprecated:["dotty"] ~long:"write-dotty"
@ -717,7 +743,7 @@ and dependencies =
and developer_mode = and developer_mode =
CLOpt.mk_bool ~deprecated:["developer_mode"] ~long:"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" "Show internal exceptions"
and disable_checks = and disable_checks =
@ -1351,7 +1377,8 @@ let post_parsing_initialization () =
let parse_args_and_return_usage_exit = let parse_args_and_return_usage_exit =
let 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 () ; post_parsing_initialization () ;
usage_exit usage_exit

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

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

Loading…
Cancel
Save