Fix native virt-ctrl on Windows.
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 8 Jan 2008 10:21:51 +0000 (10:21 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 8 Jan 2008 10:21:51 +0000 (10:21 +0000)
* virt-ctrl/Makefile.in, virt-ctrl/mingw-gcc-wrapper.ml: Wrapper
  around 'gcc' to fix native virt-ctrl builds on Windows/MinGW.
* .hgignore: Ignore *.exe files.

.hgignore
ChangeLog
virt-ctrl/Makefile.in
virt-ctrl/mingw-gcc-wrapper.ml [new file with mode: 0755]

index b7ad4a6..211b624 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -23,6 +23,7 @@ core.*
 *.a
 *.opt
 *.dll
+*.exe
 *~
 libvirt/libvirt_version.ml
 examples/list_domains
index 440e9d1..ba51e44 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-01-08  Richard Jones  <rjones@redhat.com>
+
+       Fix native virt-ctrl on Windows.
+       * virt-ctrl/Makefile.in, virt-ctrl/mingw-gcc-wrapper.ml: Wrapper
+         around 'gcc' to fix native virt-ctrl builds on Windows/MinGW.
+       * .hgignore: Ignore *.exe files.
+
 2008-01-07  Richard Jones  <rjones@redhat.com>
 
        Updated MANIFEST.
index c6966a8..26d6fe5 100644 (file)
@@ -72,10 +72,25 @@ virt-ctrl: $(OBJS)
        $(OCAMLC) $(OCAMLCINCS) $(OCAMLCFLAGS) $(OCAMLCLIBS) \
          ../libvirt/mllibvirt.cma gtkInit.cmo -o $@ $^
 
+host_os                = @host_os@
+
+ifneq ($(host_os),mingw32)
 virt-ctrl.opt: $(XOBJS)
-       $(OCAMLOPT) -verbose $(OCAMLOPTINCS) $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) \
-         -cclib "$(LDFLAGS)" \
+       $(OCAMLOPT) $(OCAMLOPTINCS) $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) \
+         $(patsubst %,-cclib %,$(LDFLAGS)) \
          ../libvirt/mllibvirt.cmxa gtkInit.cmx -o $@ $^
+else
+# On MinGW, use a hacked 'gcc' wrapper which understands the @...
+# syntax for extending the command line.
+gcc.exe: mingw-gcc-wrapper.ml
+       $(OCAMLC) unix.cma $< -o $@
+
+virt-ctrl.opt: $(XOBJS) gcc.exe
+       PATH=.:$$PATH \
+       $(OCAMLOPT) $(OCAMLOPTINCS) $(OCAMLOPTFLAGS) $(OCAMLOPTLIBS) \
+         $(patsubst %,-cclib %,$(LDFLAGS)) \
+         ../libvirt/mllibvirt.cmxa gtkInit.cmx -o $@ $(XOBJS)
+endif
 endif
 
 install:
diff --git a/virt-ctrl/mingw-gcc-wrapper.ml b/virt-ctrl/mingw-gcc-wrapper.ml
new file mode 100755 (executable)
index 0000000..21cdb8f
--- /dev/null
@@ -0,0 +1,70 @@
+(* Wrapper around 'gcc'.  On MinGW, this wrapper understands the '@...'\r
+ * syntax for extending the command line.\r
+ *)\r
+\r
+open Printf\r
+open Unix\r
+\r
+let (//) = Filename.concat\r
+\r
+(* Substitute any @... arguments with the file content. *)\r
+let rec input_all_lines chan =\r
+  try\r
+    let line = input_line chan in\r
+    line :: input_all_lines chan\r
+  with\r
+    End_of_file -> []\r
+\r
+let argv = Array.map (\r
+  fun arg ->\r
+    if arg.[0] = '@' then (\r
+      let chan = open_in (String.sub arg 1 (String.length arg - 1)) in\r
+      let lines = input_all_lines chan in\r
+      close_in chan;\r
+      lines\r
+    ) else\r
+      [arg]\r
+) Sys.argv\r
+\r
+let argv = Array.to_list argv\r
+let argv = List.flatten argv\r
+\r
+(* Find the real gcc.exe on $PATH, but ignore any '.' elements in the path.\r
+ * Note that on Windows, $PATH is split with ';' characters.\r
+ *)\r
+let rec split_find str sep f =\r
+  try\r
+    let i = String.index str sep in\r
+    let n = String.length str in\r
+    let str, str' = String.sub str 0 i, String.sub str (i+1) (n-i-1) in\r
+    match f str with\r
+    | None -> split_find str' sep f  (* not found, keep searching *)\r
+    | Some found -> found\r
+  with\r
+    Not_found ->\r
+      match f str with\r
+      | None -> raise Not_found (* not found at all *)\r
+      | Some found -> found\r
+\r
+let exists filename =\r
+  try access filename [F_OK]; true with Unix_error _ -> false\r
+\r
+let gcc =\r
+  split_find (Sys.getenv "PATH") ';'\r
+    (function\r
+     | "." -> None (* ignore current directory in path *)\r
+     | path ->\r
+       let gcc = path // "gcc.exe" in\r
+       if exists gcc then Some gcc else None)\r
+\r
+(* Finally execute the real gcc with the full argument list.\r
+ * Can't use execv here because then the parent process (ocamlopt) thinks\r
+ * that this process has finished and deletes all the temp files.  Stupid\r
+ * Windoze!\r
+ *)\r
+let _ =\r
+  let argv = List.map Filename.quote (List.tl argv) in\r
+  let cmd = String.concat " " (gcc :: argv) in\r
+  eprintf "mingw-gcc-wrapper: %s\n%!" cmd;\r
+  let r = Sys.command cmd in\r
+  exit r\r