Plugins Ocamlbuild插件:仅当目标已更改时才生成动态依赖项
我正在尝试编写一个ocamlbuild插件。目标是构建Qt应用程序(目前没有OCaml代码)。为了处理最后的链接阶段,我在.qtobjs文件(如.itarget)中编写了objs、moc、ui和rcs的列表,并在.qtpackages文件中编写了Qt lib的列表。应用于这些文件的规则解析这些列表,并在链接所有内容之前动态构建对象、MOC等 问题是我不想动态地构建那些没有改变的目标。请参见以下规则:Plugins Ocamlbuild插件:仅当目标已更改时才生成动态依赖项,plugins,hyperlink,ocamlbuild,Plugins,Hyperlink,Ocamlbuild,我正在尝试编写一个ocamlbuild插件。目标是构建Qt应用程序(目前没有OCaml代码)。为了处理最后的链接阶段,我在.qtobjs文件(如.itarget)中编写了objs、moc、ui和rcs的列表,并在.qtpackages文件中编写了Qt lib的列表。应用于这些文件的规则解析这些列表,并在链接所有内容之前动态构建对象、MOC等 问题是我不想动态地构建那些没有改变的目标。请参见以下规则: rule "Link a c++ executable that uses Qt." ~de
rule "Link a c++ executable that uses Qt."
~deps:["%.qtobjs"; "%.qtpackages"]
~prod:"%.cxxnative"
(fun env build ->
let dir = Pathname.dirname (env "%.qtobjs") in
let output = env "%.cxxnative" in
let objlist = pwd / (env "%.qtobjs") in
let liblist = pwd / (env "%.qtpackages") in
let packages = read_lines liblist in
let lflags = List.map (fun p -> "-l"^p) packages
@ find_all "lflags" in
let objs = List.map (fun o -> dir / o) (read_lines objlist) in
(* Here, I would like to forget the targets that have not changed *)
let objs_to_build = List.filter
(fun target ->
(* something to tell if "target" has to be rebuilt *))
objs in
(* This is where I build the dependencies : *)
let success_builds = build
(List.map (fun o -> [o])
objs_to_build) in
let objects = filter_map
(function
| Outcome.Good x when get_extension x = "opp" ->
Some (pwd / "_build" / (update_extension "o" x))
| Outcome.Good _ -> None
(* Because I don't want to link the ui.h file generated by uic *)
| Outcome.Bad exn -> raise exn)
success_builds in
let tags_objs = tags_of_pathname (env "%.qtobjs") ++ "link" in
let tags_packs = tags_of_pathname (env "%.qtpackages") in
Cmd (S [A (find_one "cxx"); T tags_objs; T tags_packs; Command.atomize lflags;
A "-o"; P output; Command.atomize objects]));
我不想在没有必要的时候称之为“构建”
注:函数
newer_than: Pathname.t -> Pathname.t -> bool
可以解决我的问题。问题解决了
对于那些感兴趣的人来说,问题在于编译规则:因为ocamlbuild已经使用了“.o”规则,所以我将其注册为正式生成“.opp”文件,但命令实际上编写了.o文件。因此,在重新编译时,ocamlbuild不知道对象文件已经存在
三种选择:
- 替换默认的“.o”规则(我甚至不知道这是否可行?)
- 生成“.opp”文件(但不太标准)
- 或者,如果.o文件存在,则将编译规则更改为do Nop:
if Pathname.exists (env "%.o") then Nop else Cmd (S [A ("c++"); A "-c"; A "-o"; P (env "%.o"); P (env "%.cpp")]));