首页 文章

与ocamlbuild的可选依赖项

提问于
浏览
1

我有一个OCaml项目,目前使用OCamlMake构建 . 我对当前的构建系统不满意,因为它将所有构建工件保留在与源文件相同的目录中,此外还需要手动指定模块之间的依赖关系顺序 . 我想切换到不受这些问题影响的构建系统 . 我决定试试Oasis,但遇到了问题 .

问题产生于项目以非常具体的方式建造的事实 . 它支持几种不同的数据库后端(PostgreSQL,MySQL,SQLite) . 目前,要编译数据库后端,用户必须安装该后端所需的额外库,并通过设置环境变量来启用它 . 这是它在Makefile中的样子:

ifdef MYSQL_LIBDIR
   DB_CODE    += mysql_database.ml
   DB_AUXLIBS += $(MYSQL_LIBDIR)
   DB_LIBS    += mysql
endif

请注意,这也会将额外的模块添加到已编译模块的列表中 . 重要的一点是,从应用程序入口点和数据库后端模块可以访问的任何模块之间没有依赖关系(在模块导入的意义上) . 更确切地说,每个数据库后端模块都包含在启动模块时运行的顶级代码,并使用副作用向主应用程序注册自身 .

我不能让这个设置与Oasis一起工作 . 我将每个数据库后端模块声明为一个单独的库,可以使用标志进行编译:

Library mysql-backend
  Path          : .
  Build        $: flag(mysql)
  Install       : false
  BuildTools    : ocamlbuild
  BuildDepends  : main, mysql
  Modules       : Mysql_backend

但是,我无法想办法告诉Oasis将可选模块链接到可执行文件中 . 我试图通过修改 myocamlbuild.ml 文件找出一种方法,但失败了 . 我可以用描述hererule 函数来实现这个目的吗?

如果用 ocamlbuild 无法实现我描述的内容,是否有任何ither工具可以完成这项工作并避免OCamlMake的问题?

3 回答

  • 0

    好吧,我想这就解决了:https://github.com/links-lang/links/pull/77 :)

  • 1

    我看到了问题并开始研究它,然后才注意到Drup的答案 . 下面是一个独立的ocamlbuild解决方案,与Drup的解决方案基本相同 .

    open Ocamlbuild_plugin
    
    let enable_plugin () =
      let plugins = try string_list_of_file "plugin.config" with _ -> [] in
      dep ["ocaml"; "link_with_plugin"; "byte"]
        (List.map (fun p -> p^".cmo") plugins);
      dep ["ocaml"; "link_with_plugin"; "native"]
        (List.map (fun p -> p^".cmx") plugins);
      ()
    
    let () = dispatch begin
        function
        | Before_rules -> enable_plugin ()
        | _ -> ()
    end
    

    在ocamlbuild目标上使用标记 link_with_plugin 将使其依赖于文件 plugin.config 中列出其路径(没有扩展名)的任何模块 . 例如,如果您有插件 pluga.mlplugb.ml 和文件 main.ml ,则在 plugin.config 中编写 pluga plugb 并且 <main.{cmo,cmx}>: link_with_plugin 将链接主可执行文件中的两个插件模块 .

  • 1

    不幸的是,这超出了绿洲的能力 . 这个限制与 ocamlbuild 无关,只是因为 oasis 作者试图保持简单,并且没有提供可选的依赖项作为功能 .

    与往常一样,额外的间接水平可以解决您的问题 . 您需要的是一个配置脚本( configure ),它将为您生成 _oasis 文件,具体取决于用户提供的参数 .

    例如,在our project中,我们有一个类似的设置,即多个不同的后端,用户可以在配置阶段选择 --{enable,disable}-<feature> . 我们通过编写自己的 ./configure 脚本来生成 _oasis 文件,具体取决于配置 . 配置脚本只是将 _oasis 文件从 oasis 文件夹中描述的部分连接起来 .

    另一种解决方案是使用 m4 或仅使用 cpp ,并使用 _oasis.in 文件进行预处理 .

相关问题