summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Protzenko <Jonathan.Protzenko@ens-lyon.org>2012-04-02 15:13:59 +0000
committerJonathan Protzenko <Jonathan.Protzenko@ens-lyon.org>2012-04-02 15:13:59 +0000
commit4010b7dcc6ec3cd04c6d1c09a9f1041b68e79bca (patch)
treeda78211a59b76809494758ace33b3257179ee75e
parent22e3b040d485460ee5e57d1fe01d3c22951c1b2a (diff)
Followup fix to PR#5435. Implement the infamous '' hack for cmd.exe running bash -c.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@12305 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--ocamlbuild/command.ml18
-rw-r--r--ocamlbuild/command.mli2
-rw-r--r--ocamlbuild/options.ml4
-rw-r--r--ocamlbuild/shell.ml7
-rw-r--r--ocamlbuild/shell.mli6
5 files changed, 26 insertions, 11 deletions
diff --git a/ocamlbuild/command.ml b/ocamlbuild/command.ml
index c2791fb21..1ce80c974 100644
--- a/ocamlbuild/command.ml
+++ b/ocamlbuild/command.ml
@@ -125,29 +125,33 @@ let virtual_solver virtual_command =
failwith (Printf.sprintf "the solver for the virtual command %S \
has failed finding a valid command" virtual_command)
+(* On Windows, we need to also check for the ".exe" version of the file. *)
+let file_or_exe_exists file =
+ sys_file_exists file || Sys.os_type = "Win32" && sys_file_exists (file ^ ".exe")
let search_in_path cmd =
(* Try to find [cmd] in path [path]. *)
let try_path path =
- (* On Windows, we need to also check for the ".exe" version of the file. *)
- let exists file =
- sys_file_exists file || Sys.os_type = "Win32" && sys_file_exists (file ^ ".exe")
- in
(* Don't know why we're trying to be subtle here... *)
- if path = Filename.current_dir_name then exists cmd
- else exists (filename_concat path cmd)
+ if path = Filename.current_dir_name then file_or_exe_exists cmd
+ else file_or_exe_exists (filename_concat path cmd)
in
if Filename.is_implicit cmd then
let path = List.find try_path !*env_path in
(* We're not trying to append ".exe" here because all windows shells are
* capable of understanding the command without the ".exe" suffix. *)
filename_concat path cmd
- else cmd
+ else
+ cmd
(*** string_of_command_spec{,_with_calls *)
let rec string_of_command_spec_with_calls call_with_tags call_with_target resolve_virtuals spec =
let self = string_of_command_spec_with_calls call_with_tags call_with_target resolve_virtuals in
let b = Buffer.create 256 in
+ (* The best way to prevent bash from switching to its windows-style
+ * quote-handling is to prepend an empty string before the command name. *)
+ if Sys.os_type = "Win32" then
+ Buffer.add_string b "''";
let first = ref true in
let put_space () =
if !first then
diff --git a/ocamlbuild/command.mli b/ocamlbuild/command.mli
index 0cdc602c8..f54b8e8ac 100644
--- a/ocamlbuild/command.mli
+++ b/ocamlbuild/command.mli
@@ -44,3 +44,5 @@ val deps_of_tags : Tags.t -> pathname list
val dep : Tags.elt list -> pathname list -> unit
val pdep : Tags.elt list -> Tags.elt -> (string -> pathname list) -> unit
+
+val file_or_exe_exists: string -> bool
diff --git a/ocamlbuild/options.ml b/ocamlbuild/options.ml
index b0ca59d27..d17e0dc13 100644
--- a/ocamlbuild/options.ml
+++ b/ocamlbuild/options.ml
@@ -50,8 +50,8 @@ let mk_virtual_solvers =
if sys_file_exists !dir then
let long = filename_concat !dir cmd in
let long_opt = long ^ ".opt" in
- if sys_file_exists long_opt then A long_opt
- else if sys_file_exists long then A long
+ if file_or_exe_exists long_opt then A long_opt
+ else if file_or_exe_exists long then A long
else try let _ = search_in_path opt in a_opt
with Not_found -> a_cmd
else
diff --git a/ocamlbuild/shell.ml b/ocamlbuild/shell.ml
index c76d15458..3fbeb81aa 100644
--- a/ocamlbuild/shell.ml
+++ b/ocamlbuild/shell.ml
@@ -23,7 +23,12 @@ let is_simple_filename s =
| _ -> false in
loop 0
let quote_filename_if_needed s =
- if is_simple_filename s then s else Filename.quote s
+ if is_simple_filename s then s
+ (* We should probably be using [Filename.unix_quote] except that function
+ * isn't exported. Users on Windows will have to live with not being able to
+ * install OCaml into c:\o'caml. Too bad. *)
+ else if Sys.os_type = "Win32" then Printf.sprintf "'%s'" s
+ else Filename.quote s
let chdir dir =
reset_filesys_cache ();
Sys.chdir dir
diff --git a/ocamlbuild/shell.mli b/ocamlbuild/shell.mli
index d393c7b3e..2d867b032 100644
--- a/ocamlbuild/shell.mli
+++ b/ocamlbuild/shell.mli
@@ -9,10 +9,14 @@
(* *)
(***********************************************************************)
-
(* Original author: Nicolas Pouillard *)
+
val is_simple_filename : string -> bool
+
val quote_filename_if_needed : string -> string
+(** This will quote using Unix conventions, even on Windows, because commands are
+ * always run through bash -c on Windows. *)
+
val chdir : string -> unit
val rm : string -> unit
val rm_f : string -> unit