From beb29eb0af3ecd36c28a390b9b1ba79867b9c266 Mon Sep 17 00:00:00 2001 From: sneeker Date: Mon, 25 Jul 2022 11:49:47 +0000 Subject: [PATCH] fix(build): handle assembly and reject sources meowc cannot compile --- lib/build.ml | 17 +++++++++++++---- lib/compdb.ml | 4 ++-- lib/resolve.ml | 7 +++++++ lib/types.ml | 13 ++++++++----- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/lib/build.ml b/lib/build.ml index 94a37bf..e9d4272 100644 --- a/lib/build.ml +++ b/lib/build.ml @@ -43,6 +43,12 @@ let includes_of p (t : target) = let inherited = List.concat_map (fun (d : target) -> d.includes) (deps_of p t) in List.sort_uniq compare (t.includes @ inherited @ config_dir p) +(* A compiler only writes a depfile when it preprocesses, which for assembly + means .S and not .s. Asking for one that never appears would leave the action + permanently out of date. *) +let tracks_deps src = + match lang_of src with Asm -> Filename.extension src = ".S" | C | Cxx -> true + let compile_cmd p ~pic (t : target) src obj = let lang = lang_of src in let driver = match lang with Cxx -> p.tc.cxx | _ -> p.tc.cc in @@ -59,7 +65,8 @@ let compile_cmd p ~pic (t : target) src obj = @ List.concat_map (fun d -> [ "-D"; d ]) t.defines @ List.concat_map (fun d -> [ "-I"; d ]) (includes_of p t) in - Array.of_list (((driver :: flags) @ [ "-MMD"; "-MF"; obj ^ ".d" ]) @ [ "-c"; src; "-o"; obj ]) + let dep = if tracks_deps src then [ "-MMD"; "-MF"; obj ^ ".d" ] else [] in + Array.of_list (((driver :: flags) @ dep) @ [ "-c"; src; "-o"; obj ]) let link_libs p (t : target) = let deps = List.rev (deps_of p t) in @@ -116,10 +123,11 @@ let of_project p = (fun src -> let obj = obj_of p t src in let cmd = compile_cmd p ~pic t src obj in - let tag = if lang_of src = Cxx then "c++" else "cc" in + let tag = match lang_of src with Cxx -> "c++" | Asm -> "as" | C -> "cc" in + let depfile = if tracks_deps src then Some (obj ^ ".d") else None in add - (Graph.make ~id:!n ~tag ~label:src ~cmd ~outs:[ obj ] ~ins:[ src ] - ~depfile:(obj ^ ".d") ~ords:gen_headers ~rsp:(obj ^ ".rsp") ()); + (Graph.make ~id:!n ~tag ~label:src ~cmd ~outs:[ obj ] ~ins:[ src ] ?depfile + ~ords:gen_headers ~rsp:(obj ^ ".rsp") ()); obj) (all_srcs t) in @@ -142,6 +150,7 @@ let paint tag text = match tag with | "cc" -> Style.blue text | "c++" -> Style.blue text + | "as" -> Style.magenta text | "ar" -> Style.magenta text | "so" -> Style.cyan text | "ld" -> Style.green text diff --git a/lib/compdb.ml b/lib/compdb.ml index d438f5b..341312a 100644 --- a/lib/compdb.ml +++ b/lib/compdb.ml @@ -2,7 +2,7 @@ let render (b : Build.t) = let dir = Sys.getcwd () in let entries = Array.to_list b.g.Graph.nodes - |> List.filter (fun (n : Graph.node) -> n.tag = "cc" || n.tag = "c++") + |> List.filter (fun (n : Graph.node) -> List.mem n.tag [ "cc"; "c++"; "as" ]) |> List.map (fun (n : Graph.node) -> Printf.sprintf " {\n \"directory\": %s,\n \"file\": %s,\n \"output\": %s,\n \"arguments\": %s\n }" @@ -15,5 +15,5 @@ let render (b : Build.t) = let write b path = Fs.write path (render b); List.length - (List.filter (fun (n : Graph.node) -> n.Graph.tag = "cc" || n.Graph.tag = "c++") + (List.filter (fun (n : Graph.node) -> List.mem n.Graph.tag [ "cc"; "c++"; "as" ]) (Array.to_list b.Build.g.Graph.nodes)) diff --git a/lib/resolve.ml b/lib/resolve.ml index c96515a..8de7b97 100644 --- a/lib/resolve.ml +++ b/lib/resolve.ml @@ -134,6 +134,13 @@ let sources_of ~extra ((b : block), base) (t : target) = Diag.error ~span:b.nspan ~hint:(Printf.sprintf "no file matches %s" (String.concat " " pats)) "%s %s matched no sources" b.kind b.bname; + List.iter + (fun f -> + if lang_opt f = None then + Diag.error ~span:b.nspan + ~hint:("meowc compiles " ^ String.concat " " source_exts) + "%s %s lists %s, which is not a source meowc can compile" b.kind b.bname f) + files; let gen, real = List.partition (fun f -> List.mem f extra) files in { t with srcs = real; gen_srcs = gen } diff --git a/lib/types.ml b/lib/types.ml index fe0fb0d..532d3d4 100644 --- a/lib/types.ml +++ b/lib/types.ml @@ -77,10 +77,13 @@ let uniq_targets ts = let order p ts = uniq_targets (List.concat_map (fun t -> deps_of p t @ [ t ]) ts) -let lang_of path = - match String.lowercase_ascii (Filename.extension path) with - | ".cc" | ".cpp" | ".cxx" | ".c++" | ".mm" -> Cxx - | ".s" | ".asm" -> Asm - | _ -> C +let langs = + [ (".c", C); (".m", C); + (".cc", Cxx); (".cpp", Cxx); (".cxx", Cxx); (".c++", Cxx); (".mm", Cxx); + (".s", Asm); (".asm", Asm) ] + +let source_exts = List.map fst langs +let lang_opt path = List.assoc_opt (String.lowercase_ascii (Filename.extension path)) langs +let lang_of path = Option.value (lang_opt path) ~default:C let all_srcs t = t.srcs @ t.gen_srcs