Commit | Line | Data |
---|---|---|
d6ce1786 C |
1 | #!/usr/bin/env ocaml |
2 | ||
3 | (* ocamldep.wrapper <filename> ... <filename> - <ocamldep command> | |
4 | runs the <ocamldep command> in an environment where all of the | |
5 | <filenames> listed appear to exist. The files are created, if | |
6 | required, before the command is run, and destroyed afterwards. *) | |
7 | ||
8 | (* An earlier version of this script acquired a lock, so as to prevent | |
9 | multiple instances of this script from interfering with one another. | |
10 | However, this did not prevent interference between this script and | |
11 | some other process (e.g., the ocaml compiler) which creates files. | |
12 | So, the lock has been removed. My suggestion is to never use this | |
13 | script in a concurrent setting. If you wish to use parallel make, | |
14 | then you might be able to use a two-level Makefile approach: first, | |
15 | compute all dependencies in a sequential manner; then, construct all | |
16 | targets in a parallel manner. *) | |
17 | ||
18 | #load "unix.cma" | |
19 | open Printf | |
20 | ||
21 | (* Parse the command line. The arguments that precede "-" are understood | |
22 | as file names and stored in the list [xs]. The arguments that follow | |
23 | "-" are understood as a command and stored in [command]. *) | |
24 | ||
25 | let xs = | |
26 | ref [] | |
27 | ||
28 | let command = | |
29 | ref "" | |
30 | ||
31 | let verbose = | |
32 | ref false | |
33 | ||
34 | let rec loop accumulating i = | |
35 | if i = Array.length Sys.argv then | |
36 | () | |
37 | else if accumulating then | |
38 | (* [accumulating] is [true] as long as we have not found the "-" marker *) | |
39 | match Sys.argv.(i) with | |
40 | | "-v" -> | |
41 | verbose := true; | |
42 | loop true (i+1) | |
43 | | "-" -> | |
44 | (* We have found the marker. The next parameter should be the name of | |
45 | the raw [ocamldep] command. Copy it to the command (unquoted -- | |
46 | apparently some shells do not permit quoting a command name). *) | |
47 | let i = i + 1 in | |
48 | assert (i < Array.length Sys.argv); | |
49 | command := Sys.argv.(i); | |
50 | (* Stop accumulating file names. Copy the remaining arguments into | |
51 | the command. *) | |
52 | loop false (i+1) | |
53 | | _ -> | |
54 | (* Continue accumulating file names in [xs]. *) | |
55 | xs := Sys.argv.(i) :: !xs; | |
56 | loop true (i+1) | |
57 | else begin | |
58 | (* After we have found the "-" marker, the remaining arguments are | |
59 | copied (quoted) into the command. *) | |
60 | command := sprintf "%s %s" !command (Filename.quote Sys.argv.(i)); | |
61 | loop false (i+1) | |
62 | end | |
63 | ||
64 | let () = | |
65 | loop true 1 | |
66 | ||
67 | (* Create the required files if they don't exist, run the command, | |
68 | then destroy any files that we have created. *) | |
69 | ||
70 | let rec loop = function | |
71 | | [] -> | |
72 | if !verbose then | |
73 | fprintf stderr "ocamldep.wrapper: running %s\n" !command; | |
74 | Sys.command !command | |
75 | | x :: xs -> | |
76 | if Sys.file_exists x then | |
77 | loop xs | |
78 | else begin | |
79 | if !verbose then | |
80 | fprintf stderr "ocamldep.wrapper: creating fake %s\n" x; | |
81 | let c = open_out x in | |
82 | close_out c; | |
83 | let exitcode = loop xs in | |
84 | if Sys.file_exists x then begin | |
85 | try | |
86 | if !verbose then | |
87 | fprintf stderr "ocamldep.wrapper: removing fake %s..." x; | |
88 | Sys.remove x; | |
89 | if !verbose then | |
90 | fprintf stderr " ok\n" | |
91 | with Sys_error _ -> | |
92 | if !verbose then | |
93 | fprintf stderr " failed\n" | |
94 | end; | |
95 | exitcode | |
96 | end | |
97 | ||
98 | let () = | |
99 | exit (loop !xs) |