1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
open Fugue
open Filepath
open Types
let read_file_with f filename =
let lines = ref [] in
let chan = open_in filename in
try
while true do
let z = f (input_line chan) in
match z with
| None -> ()
| Some z' -> lines := z' :: !lines
done;
[]
with End_of_file ->
close_in chan;
List.rev !lines
let toKV line =
match String_utils.split ~limit:2 ':' line with
| [ k ] -> (String_utils.strip_spaces k, None)
| [ k; v ] -> (String_utils.strip_spaces k, Some (String_utils.strip_spaces v))
| _ -> assert false
let toKVeq line =
match String_utils.split ~limit:2 '=' line with
| [ k ] -> (String_utils.strip_spaces k, None)
| [ k; v ] -> (String_utils.strip_spaces k, Some (String_utils.strip_spaces v))
| _ -> assert false
let parseCSV value =
List.filter
(fun s -> String.length s > 0)
(List.map String_utils.strip_spaces (String_utils.split ',' value))
let to_include_path_options paths =
let ss = ref StringSet.empty in
List.concat
$ list_filter_map
(fun p ->
let ps = fp_to_string p in
if ps = "" || StringSet.mem ps !ss || not (Filesystem.exists p) then
None
else (
ss := StringSet.add ps !ss;
Some [ "-I"; ps ]))
paths
let showList sep f l = String.concat sep (List.map f l)
let isWindows = Sys.os_type = "Win32"
(* Platform-aware C library naming.
OCaml's convention uses dll*.so even on macOS for stub libraries. *)
let shared_lib_name clib_name =
if isWindows then clib_name ^ ".dll"
else "dll" ^ clib_name ^ ".so"
let static_lib_name clib_name =
if isWindows then clib_name ^ ".lib"
else "lib" ^ clib_name ^ ".a"
let to_exe_name mode build name =
let ext = extDP mode in
let ext2 =
match build with
| ByteCode -> ".byte"
| Native -> if Gconf.get_target_option_typed Gconf.Executable_as_obj then ".o" else ""
in
fn (name ^ ext ^ ext2 ^ if isWindows then ".exe" else "")
exception FileNotFoundInPaths of (filepath list * filename)
exception FilesNotFoundInPaths of (filepath list * filepath list)
let get_system_paths () =
let sep = if isWindows then ';' else ':' in
try List.map fp (String_utils.split sep (Sys.getenv "PATH"))
with Not_found ->
if isWindows then
let sysroot =
try Sys.getenv "SystemRoot"
with Not_found -> "C:\\Windows"
in
List.map fp [ sysroot ^ "\\System32" ]
else
List.map fp [ "/usr/bin"; "/usr/local/bin" ]
let find_in_paths paths name =
try List.find (fun p -> Filesystem.exists (p </> name)) paths
with Not_found -> raise (FileNotFoundInPaths (paths, name))
let find_choice_in_paths paths names =
try
List.find
(fun p ->
try
ignore (List.find (fun n -> Filesystem.exists (n p)) names);
true
with Not_found -> false)
paths
with Not_found ->
let sample_path = match paths with p :: _ -> p | [] -> fp "." in
raise (FilesNotFoundInPaths (paths, List.map (fun n -> n sample_path) names))
let exist_choice_in_paths paths names =
try
let _ = find_choice_in_paths paths names in
true
with FilesNotFoundInPaths _ -> false
let find_in_system_path name = find_in_paths (get_system_paths ()) name
let generateFile file f =
let buffer = Buffer.create 1024 in
f (Buffer.add_string buffer);
Filesystem.write_file file (Buffer.contents buffer)
let get_cpu_count () =
let read_command cmd =
try
let ic = Unix.open_process_in cmd in
let line = input_line ic in
let status = Unix.close_process_in ic in
match status with
| Unix.WEXITED 0 -> Some (int_of_string (String_utils.strip_spaces line))
| _ -> None
with _ -> None
in
let detected =
match Sys.os_type with
| "Unix" | "Cygwin" -> (
(* Try different commands in order of preference *)
match read_command "nproc 2>/dev/null" with
(* Linux *)
| Some n -> Some n
| None -> (
match read_command "sysctl -n hw.ncpu 2>/dev/null" with
(* macOS, BSD *)
| Some n -> Some n
| None -> (
match read_command "getconf _NPROCESSORS_ONLN 2>/dev/null" with
(* POSIX *)
| Some n -> Some n
| None -> None)))
| "Win32" -> (
(* Windows: use NUMBER_OF_PROCESSORS environment variable *)
try Some (int_of_string (Sys.getenv "NUMBER_OF_PROCESSORS")) with _ -> None)
| _ -> None (* Unknown OS *)
in
match detected with
| Some n when n > 0 && n <= 128 -> n (* Sanity check: reasonable CPU count *)
| _ -> 2 (* Default fallback *)
|