如何在我的dune项目中将包含路径标志传递给ocamlc/ocamlopt

如何在我的dune项目中将包含路径标志传递给ocamlc/ocamlopt,ocaml,nix,nixos,Ocaml,Nix,Nixos,我正在使用和编译使用。这个例子值得注意的是,它链接到两个C库:openssl和libev 初始尝试 这是我的shell.nix: with import <nixpkgs> { }; let spec = { buildInputs = with ocamlPackages; [ ocaml findlib dune # ocaml libs (and external library deps) cohttp-lwt-unix ope

我正在使用和编译使用。这个例子值得注意的是,它链接到两个C库:openssl和libev

初始尝试

这是我的shell.nix:

with import <nixpkgs> { };

let spec = {
  buildInputs = with ocamlPackages; [
    ocaml
    findlib
    dune

    # ocaml libs (and external library deps)
    cohttp-lwt-unix openssl libev
  ]);
};
in runCommand "dummy" spec ""
with import <nixpkgs> { };

with ocamlPackages;

buildDunePackage {
  pname = "dummy";
  version = "0";
  buildInputs = [
    cohttp-lwt-unix
  ];
}
以及
dune build server_example.exe的输出

...
/nix/store/3xwc1ip20b0p68sxqbjjll0va4pv5hbv-binutils-2.30/bin/ld: cannot find -lssl
/nix/store/3xwc1ip20b0p68sxqbjjll0va4pv5hbv-binutils-2.30/bin/ld: cannot find -lcrypto
/nix/store/3xwc1ip20b0p68sxqbjjll0va4pv5hbv-binutils-2.30/bin/ld: cannot find -lev
好吧,这并不奇怪,因为这些都在尼克松的非标准位置。我需要向dune调用的ocamlopt命令行添加相关路径,例如:
-I${openssl.out}/lib-I${libev}/lib

现在,openssl包含pkg配置文件,但将pkg配置添加到我的
shell.nix
中并没有明显的效果

第二次尝试,使用configurator

我曾经创建一个程序,将环境变量中的标志添加到dune可执行文件的构建标志中

shell.nix

with import <nixpkgs> { };

let spec = {
  buildInputs = with ocamlPackages; [
    ocaml
    findlib
    dune
    configurator

    # ocaml libs (and external library deps)
    cohttp-lwt-unix openssl libev
  ]);

  shellHook = ''
    export OCAML_FLAGS="-I ${openssl.out}/lib -I ${libev}/lib"
  '';
};
in runCommand "dummy" spec ""
形态/沙丘

(executable
 (name discover)
 (libraries dune.configurator))
config/discover.ml

open Sys
module C = Configurator.V1

let () =
  C.main ~name:"getflags" (fun _c ->
      let libs =
        match getenv_opt "OCAML_FLAGS" with
        | None -> []
        | Some flags -> C.Flags.extract_blank_separated_words flags
      in

      C.Flags.write_sexp "flags.sexp" libs)
编译现在成功了,但这种编写自定义程序以获取环境变量并将其放入flags参数的方法似乎很笨拙

在dune中是否有实现这一点的标准方法(使用
-I
向ocamlopt命令行添加路径)


如果没有,是否有更简单的方法从
dune
文件中读取环境变量?

使用
stdenv.mkDerivation
或(如上所述)
ocamlPackages.buildDunePackage
而不是
runCommand
。后者导致的环境在
NIX\u CFLAGS\u编译
NIX\u LDFLAGS
环境变量中不包含openssl和libev。使用
mkDerivation
会导致填充这些变量

一旦这些变量就位,通过
dune
的编译就会成功,可执行文件将链接到libssl和libev

此外,没有必要显式包含libev和openssl,因为它们被声明为通过cohttplwtunix传播的构建输入

shell.nix:

with import <nixpkgs> { };

let spec = {
  buildInputs = with ocamlPackages; [
    ocaml
    findlib
    dune

    # ocaml libs (and external library deps)
    cohttp-lwt-unix openssl libev
  ]);
};
in runCommand "dummy" spec ""
with import <nixpkgs> { };

with ocamlPackages;

buildDunePackage {
  pname = "dummy";
  version = "0";
  buildInputs = [
    cohttp-lwt-unix
  ];
}
与导入{};
用奥卡姆包装;
构建数据包{
pname=“dummy”;
version=“0”;
构建输入=[
cohttplwtunix
];
}

有没有不这样做的原因?标记不是静态的:
${openssl.dev}/lib
扩展到
/nix/store/$somehash openssl-$version/lib
,其中
$somehash
的更改频率可能比openssl版本更高。我可以直接传递它们,但它不雅观,并且需要随着时间的推移不断进行编辑。可能,让这更自动化的方法是将shell基于
buildDunePackage
,而不是
runCommand
。Nixpkgs手册的第1部分介绍了该功能。