From e01cab6d19eae07ecf1b6566ea7948545ef5e012 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Thu, 12 Jan 2017 05:00:09 -0800 Subject: [PATCH] [java] more verbose debug output, fix for non-Buck integrations Summary: Currently, if we don't find `-d` or `-classes_out` on the command line then we tell javac to redirect the compiled classes in some other directory, by default the initial working directory. But we don't detect when these arguments are hidden inside files (`foo` arguments on the javac command line) so the heuristic was incomplete. Look inside these files to better tell whether we need to make up an output directory or not. Reviewed By: jeremydubreil Differential Revision: D4397716 fbshipit-source-id: 30c5e4f --- infer/src/backend/infer.ml | 25 ++++++++++++++++++++++--- infer/src/base/Config.ml | 2 ++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/infer/src/backend/infer.ml b/infer/src/backend/infer.ml index a9bd184ed..e09d31405 100644 --- a/infer/src/backend/infer.ml +++ b/infer/src/backend/infer.ml @@ -140,11 +140,30 @@ let run_javac build_mode build_cmd = | _, Some jar -> (* fall back to java in PATH to avoid passing -jar to javac *) ("java", ["-jar"; jar]) in let cli_args, file_args = + let rec has_classes_out = function + | [] -> false + | ("-d" | "-classes_out")::_ -> true + | file_arg::tl when String.is_prefix file_arg ~prefix:"@" -> ( + let fname = String.slice file_arg 1 (String.length file_arg) in + match In_channel.read_lines fname with + | lines -> + (* crude but we only care about simple cases that will not involve trickiness, eg + unbalanced or escaped quotes such as "ending in\"" *) + let lines_without_quotes = + List.map ~f:(String.strip ~drop:(function '"' | '\'' -> true | _ -> false)) lines in + has_classes_out lines_without_quotes || has_classes_out tl + | exception _ -> + has_classes_out tl) + | _::tl -> + has_classes_out tl in let args = "-verbose" :: "-g" :: - if List.exists build_args ~f:(function "-d" | "-classes_out" -> true | _ -> false) - then build_args - else "-d" :: Config.javac_classes_out :: build_args in + (* Ensure that some form of "-d ..." is passed to javac. It's unclear whether this is strictly + needed but the tests break without this for now. See discussion in D4397716. *) + if has_classes_out build_args then + build_args + else + "-d" :: Config.javac_classes_out :: build_args in List.partition_tf args ~f:(fun arg -> (* As mandated by javac, argument files must not contain certain arguments. *) String.is_prefix ~prefix:"-J" arg || String.is_prefix ~prefix:"@" arg) in diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index ff56f431e..15e82bead 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1226,6 +1226,8 @@ let javac_classes_out = ref init_work_dir (* The "rest" args must appear after "--" on the command line, and hence after other args, so they are allowed to refer to the other arg variables. *) let rest = + (* BUG: these arguments will not be detected if put inside @argfiles, as supported by javac. See + Infer.run_javac for a version that looks inside argfiles, and discussion in D4397716. *) let classes_out_spec = Arg.String (fun classes_out -> javac_classes_out := classes_out ;